[Laszlo-checkins] r11215 - openlaszlo/trunk/WEB-INF/lps/lfc/services
bargull@openlaszlo.org
bargull at openlaszlo.org
Thu Sep 25 01:30:42 PDT 2008
Author: bargull
Date: 2008-09-25 01:30:40 -0700 (Thu, 25 Sep 2008)
New Revision: 11215
Modified:
openlaszlo/trunk/WEB-INF/lps/lfc/services/LzTrack.lzs
Log:
Change 20080924-bargull-aE9 by bargull at dell--p4--2-53 on 2008-09-24 21:30:55
in /home/Admin/src/svn/openlaszlo/trunk
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: services updates (part 2)
New Features: LPP-7050
Bugs Fixed:
Technical Reviewer: promanik
QA Reviewer: (pending)
Doc Reviewer: (pending)
Documentation:
Release Notes:
Details:
- add typing information
- make service classes "public final"
- add service schema (all Lz*Service classes have a static const field Lz*, which is published as lz.* in the lz-namespace)
- reindent lines if necessary
Tests:
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/services/LzTrack.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/services/LzTrack.lzs 2008-09-25 08:29:47 UTC (rev 11214)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/services/LzTrack.lzs 2008-09-25 08:30:40 UTC (rev 11215)
@@ -20,7 +20,7 @@
* the onmousedown events. When views are registered using the
* <classname>lz.Track</classname> service, they will receive events
* independent of the mouse button state.
- *
+ *
* </p>
* <p>
* In using lz.Track, views register with a particular group.
@@ -29,7 +29,7 @@
* the mouse position enters (<event>ontrackover</event>), leaves (<event>ontrackout</event>) or when the mouse
* button goes up (<event>ontrackup</event>).
* </p>
- *
+ *
* <h2>Example: a simple color picker</h2>
* <p>
* This simple color picker displays its color in a rectangle, then
@@ -41,7 +41,7 @@
* <!--
* <img src="images/lztrack/colorpicker.gif" width="131" height="42" />
* -->
- *
+ *
* <p>The code below defines the class "colorspot" which represents a
* tracked view. This class handles visual state changes triggered by
* the track events and sends an event to its parent when a new color is
@@ -52,13 +52,13 @@
* typical for a set of sibling views to share the same track group;
* however, tracked views that share the same trackgroup may be anywhere
* in view hierarchy.</p>
- *
+ *
* <example title="Using lz.Track to build a color chooser">
* <canvas height="60">
* <class name="colorspot" clickable="true"
* width="22" height="22" bgcolor="0x000000">
* <attribute name="mycolor"/>
- *
+ *
* <attribute name="trackgroup" type="string" value="${parent.trackgroup}"/>
* <view name="spot" bgcolor="${parent.mycolor}"
* x="2" y="2" width="18" height="18"/>
@@ -68,7 +68,7 @@
* <handler name="onmousetrackover">
* setAttribute('bgcolor', 0xdedede); // hilite: gray
* </handler>
- *
+ *
* <handler name="onmousetrackout">
* setAttribute('bgcolor', 0x000000); // normal: black
* </handler>
@@ -76,7 +76,7 @@
* parent.onnewcolor.sendEvent(this.spot.bgcolor);
* </handler>
* </class>
- *
+ *
* <view bgcolor="0x0000ff" width="20" height="20"
* onmousedown="this.colorpicker.setVisible(true); lz.Track.activate('mymenu');"
* onmouseup="this.colorpicker.setVisible(false); lz.Track.deactivate('mymenu');">
@@ -85,305 +85,314 @@
* <handler name="onnewcolor" args="newcolor">
* parent.setAttribute('bgcolor', newcolor);
* </handler>
- *
+ *
* <simplelayout axis="x"/>
* <colorspot mycolor="0x0000ff"/>
* <colorspot mycolor="0x00ff00"/>
* <colorspot mycolor="0xffff00"/>
* <colorspot mycolor="0xff0000"/>
* <colorspot mycolor="0x00ffff"/>
- *
+ *
* </view>
* </view>
* <text>Click on the square, then release the mouse button to select a new color.</text>
* <simplelayout axis="y" spacing="20"/>
* </canvas>
* </example>
- *
+ *
* @shortdesc Enables tracking mouse events over a group of views.
*/
-class LzTrackService extends LzEventable {
+public final class LzTrackService extends LzEventable {
-/**
- * @event onmousetrackover: sent when the mouse is over a view that is registered to
- * an active track group
- * @event onmousetrackout: sent when the mouse is leaves the visible area of a view
- * that was previously sent an 'ontrackover' event
- * @event onmousetrackup: sent when the mouse button is released over a view that
- * is registered to an active track group
- */
+ /**
+ * @event onmousetrackover: sent when the mouse is over a view that is registered to
+ * an active track group
+ * @event onmousetrackout: sent when the mouse is leaves the visible area of a view
+ * that was previously sent an 'ontrackover' event
+ * @event onmousetrackup: sent when the mouse button is released over a view that
+ * is registered to an active track group
+ */
-/** @access private */
-var __LZreg = new Object; // list of registered views (that will be tracked)
-/** @access private */
-var __LZactivegroups = null;
-/** @access private */
-var __LZtrackDel = null;
-/** @access private */
-var __LZoptimizeforaxis = 'x';
-/** @access private */
-var __LZmouseupDel = null;
+ /** @access private */
+ var __LZreg :Object = new Object; // list of registered views (that will be tracked)
+ /** @access private */
+ var __LZactivegroups :Array = null;
+ /** @access private */
+ var __LZtrackDel :LzDelegate = null;
+ /** @access private */
+ var __LZmouseupDel :LzDelegate = null;
+ /** @access private */
+ var __LZdestroydel :LzDelegate = null;
-/** @access private */
-var __LZlastmouseup = null;
-/** @access private */
-var __LZlasthit = null;
+ /** @access private */
+ var __LZlastmouseup :LzView = null;
-/** @access private */
-var __LZdestroydel:LzDelegate = null;
+ /**
+ * The track service. Also available as the global
+ * <code>lz.Track</code>.
+ *
+ * @type LzTrackService
+ * @keywords readonly
+ * @devnote this should be a public getter to enforce readonly
+ */
+ public static const LzTrack:LzTrackService;
-/** @access private */
-function LzTrackService (){
- super();
+ /** @access private
+ * @devnote AS3 does not allow private constructors, so we need the
+ * error
+ */
+ function LzTrackService () {
+ super();
+ // if (LzTrackService.LzTrack) {
+ // throw new Error("There can be only one LzTrack");
+ // }
- this.__LZtrackDel = new LzDelegate( this, "__LZtrack" );// called on idle
- this.__LZmouseupDel = new LzDelegate( this, "__LZmouseup", lz.GlobalMouse, 'onmouseup');// called on global mouseup
- this.__LZactivegroups = [];
-}
+ this.__LZtrackDel = new LzDelegate( this, "__LZtrack" );// called on idle
+ this.__LZmouseupDel = new LzDelegate( this, "__LZmouseup", lz.GlobalMouse, 'onmouseup');// called on global mouseup
+ this.__LZdestroydel = new LzDelegate( this, "__LZdestroyitem" );
+ this.__LZactivegroups = [];
+ }
+ // Create the singleton
+ LzTrackService.LzTrack = new LzTrackService();
-/**
- * register a view to be tracked by a particular track group
- * @param LzView v: a reference to the view to add to the track group
- * @param String group: the name of the track group
- * @access public
- * @devnote should we create a bounding rect for the views, or instead register a view
- * as a groups bounding rect.
- */
-function register ( v, group ){
- if (v == null || group == null) return;
- if (typeof(this.__LZreg[group]) == "undefined") {
- this.__LZreg[group] = [];
- // __LZlasthit means that onmousedownover has been sent to this view,
- // but not onmousedownout
- this.__LZreg[group].__LZlasthit = 0;
- }
- this.__LZreg[group].push( v );
+ /**
+ * register a view to be tracked by a particular track group
+ * @param LzView v: a reference to the view to add to the track group
+ * @param String group: the name of the track group
+ * @access public
+ * @devnote should we create a bounding rect for the views, or instead register a view
+ * as a groups bounding rect.
+ */
+ function register (v:LzView, group:String) :void {
+ if (v == null || group == null) return;
+ var reglist:Array = this.__LZreg[group];
+ if (! reglist) {
+ this.__LZreg[group] = reglist = [];
+ // __LZlasthit means that onmousedownover has been sent to this view,
+ // but not onmousedownout
+ reglist.__LZlasthit = null;
+ reglist.__LZactive = false;
+ }
+ reglist.push( v );
- // register for when the view is destroyed, so we can clean up after
- if (!this.__LZdestroydel) {
- this.__LZdestroydel = new LzDelegate( this, "__LZdestroyitem" );
+ // register for when the view is destroyed, so we can clean up after
+ this.__LZdestroydel.register(v, "ondestroy");
}
- this.__LZdestroydel.register(v, "ondestroy");
-}
-/**
- * unregister a view to be tracked by a particular track group
- * @param LzView v: a reference to the view to remove from the track group
- * @param String group: the name of the track group
- * @access public
- */
-function unregister ( v, group ){
- if (v == null || group == null) return;
- var reglist = this.__LZreg[group];
- if (reglist) {
- for (var i = 0; i < reglist.length; i++) {
- if (reglist[i] == v) {
- reglist.splice(i, 1);
+ /**
+ * unregister a view to be tracked by a particular track group
+ * @param LzView v: a reference to the view to remove from the track group
+ * @param String group: the name of the track group
+ * @access public
+ */
+ function unregister (v:LzView, group:String) :void {
+ if (v == null || group == null) return;
+ var reglist:Array = this.__LZreg[group];
+ if (reglist) {
+ for (var i:int = 0; i < reglist.length; i++) {
+ if (reglist[i] == v) {
+ reglist.splice(i, 1);
+ }
}
+ // Remove empty groups
+ if (reglist.length == 0) {
+ if (reglist.__LZactive) {
+ this.deactivate(group);
+ }
+ delete this.__LZreg[group];
+ }
}
- // Remove empty groups
- if (reglist.length == 0) {
- delete this.__LZreg[group];
+ this.__LZdestroydel.unregisterFrom(v.ondestroy);
+ }
+
+ /**
+ * called when a registered view is destroyed. We need to remove it from
+ * all track groups, so we don't leak memory
+ * @access private
+ */
+ function __LZdestroyitem (v:LzView) :void {
+ for (var group:String in this.__LZreg) {
+ this.unregister(v, group);
}
- }
- this.__LZdestroydel.unregisterFrom(v.ondestroy);
-}
-
-/**
- * called when a registered view is destroyed. We need to remove it from
- * all track groups, so we don't leak memory
- * @access private
- */
-function __LZdestroyitem (v){
- for (var i in this.__LZreg) {
- this.unregister(v, i);
}
-}
-/**
- * activate tracking for a particular group. Any number of groups can be tracked
- * simultaneously. This is useful for tracking mechanisms like menus.
- * @param String group: the name of the track group to activate
- */
-function activate ( group:String ){
- var agroups:Array = this.__LZactivegroups;
- if (agroups.length == 0) {
- // don't want to re-register, in case we are just switching active groups
- this.__LZtrackDel.register( lz.Idle, "onidle" );
- }
- // see if group is already active
- var reg:Object = this.__LZreg;
- for (var i:int = 0; i < agroups.length; ++i) {
- if (agroups[i] == reg[group]) {
- // nothing to do, group is already active
- return;
+ /**
+ * activate tracking for a particular group. Any number of groups can be tracked
+ * simultaneously. This is useful for tracking mechanisms like menus.
+ * @param String group: the name of the track group to activate
+ */
+ function activate (group:String) :void {
+ var reglist:Array = this.__LZreg[group];
+ if (reglist && ! reglist.__LZactive) {// see if group is already active
+ reglist.__LZactive = true;
+ var agroups:Array = this.__LZactivegroups;
+ if (agroups.length == 0) {
+ // don't want to re-register, in case we are just switching active groups
+ this.__LZtrackDel.register( lz.Idle, "onidle" );
+ }
+ // group was not active so put it onto activegroups array
+ agroups.push(reglist);
}
}
- // group was not active so put it onto activegroups array
- agroups.push(reg[group]);
-}
-/**
- * deactivate tracking for a particular group
- * @param String group: the name of the track group to deactivate
- */
-function deactivate ( group ) {
- var agroups:Array = this.__LZactivegroups;
- var reg:Object = this.__LZreg;
- for (var i:int = 0; i < agroups.length; ++i) {
- if (agroups[i] == reg[group]) {
- agroups.splice(i, 1);
- }
+ /**
+ * deactivate tracking for a particular group
+ * @param String group: the name of the track group to deactivate
+ */
+ function deactivate (group:String) :void {
+ var reglist:Array = this.__LZreg[group];
+ if (reglist && reglist.__LZactive) {
+ var agroups:Array = this.__LZactivegroups;
+ for (var i:int = 0; i < agroups.length; ++i) {
+ if (agroups[i] == reglist) {
+ agroups.splice(i, 1);
+ break;
+ }
+ }
+ if (agroups.length == 0) {
+ this.__LZtrackDel.unregisterAll();
+ }
+ reglist.__LZactive = false;
+ reglist.__LZlasthit = null;// should send ontrackmouseout ?
+ }
}
- if (agroups.length == 0) {
- this.__LZtrackDel.unregisterAll();
- }
- if (typeof(reg[group]) != "undefined") {
- reg[group].__LZlasthit = null; // should send ontrackmouseout ?
- }
-}
-/**
- * @access private
- * returns the topmost view (a or b)
- */
-function __LZtopview (a, b) {
- var btemp = b; var atemp=a;
- while (atemp.nodeLevel < btemp.nodeLevel) {
- btemp = btemp.immediateparent;
- if (btemp == a) // a is in b's parent chain
- return b; // child is always on top
+ /**
+ * @access private
+ * returns the topmost view (a or b)
+ */
+ function __LZtopview (a:LzView, b:LzView) :LzView {
+ var atemp:LzView = a;
+ var btemp:LzView = b;
+ while (atemp.nodeLevel < btemp.nodeLevel) {
+ btemp = btemp.immediateparent;
+ if (btemp == a) // a is in b's parent chain
+ return b; // child is always on top
+ }
+ while (btemp.nodeLevel < atemp.nodeLevel) {
+ atemp = atemp.immediateparent;
+ if (atemp == b) // b is in a's parent chain
+ return a; // child is always on top
+ }
+ // nodeLevel is equal
+ while (atemp.immediateparent != btemp.immediateparent) {
+ atemp = atemp.immediateparent;
+ btemp = btemp.immediateparent;
+ }
+ // a and b are siblings, check depth
+ return (atemp.getZ() > btemp.getZ()) ? a : b;
}
- while (btemp.nodeLevel < atemp.nodeLevel) {
- atemp = atemp.immediateparent;
- if (atemp == b) // b is in a's parent chain
- return a; // child is always on top
- }
- // nodeLevel is equal
- while (atemp.immediateparent != btemp.immediateparent) {
- atemp = atemp.immediateparent;
- btemp = btemp.immediateparent;
- }
- // a and b are siblings, check depth
- if (atemp.getZ() > btemp.getZ()) return a;
- else return b;
-}
-/**
- * @access private
- * return topmost view in an array of views
- */
-function __LZfindTopmost (vlist) {
- var top = vlist[0];
- for (var i=1; i < vlist.length; i++) {
- top = this.__LZtopview(top, vlist[i]);
+ /**
+ * @access private
+ * return topmost view in an array of views
+ */
+ function __LZfindTopmost (vlist:Array) :LzView {
+ var top:LzView = vlist[0];
+ for (var i:int = 1; i < vlist.length; i++) {
+ top = this.__LZtopview(top, vlist[i]);
+ }
+ return top;
}
- return top;
-}
+ /**
+ * @access private
+ * iterate through a trackgroup and add those views that are under the mouse to
+ * a hitlist.
+ */
+ function __LZtrackgroup (group:Array, hitlist:Array) :void {
+ //check mouse pos
-/**
- * @access private
- * iterate through a trackgroup and add those views that are under the mouse to
- * a hitlist.
- */
-function __LZtrackgroup (group,hitlist) {
- //check mouse pos
-
- // this will be slow on vertical menus because
- // the mouse_x will intersect with all menuitems if
- // if it intersects any menuitem. We should include
- // an optimise for axis attribute as part of a group.
- for (var i=0; i < group.length; i++) {
- var v = group[i];
- if ( v.visible ) { // dont check mouse if not visible
- var vx = v.getMouse('x');
- if (vx > 0 && vx < v.width) { // inside width
- var vy = v.getMouse('y');
- if (vy > 0 && vy < v.height) { // inside height
+ // this will be slow on vertical menus because
+ // the mouse_x will intersect with all menuitems if
+ // if it intersects any menuitem. We should include
+ // an optimise for axis attribute as part of a group.
+ for (var i:int = 0; i < group.length; i++) {
+ var v:LzView = group[i];
+ if (v.visible) { // dont check mouse if not visible
+ var vpos:Object = v.getMouse(null);
+ var vx:Number = vpos.x;
+ var vy:Number = vpos.y;
+ if (vx > 0 && vx < v.width // inside width
+ && vy > 0 && vy < v.height) { // inside height
hitlist.push(v);
}
- }
- }
+ }
+ }
}
-}
+ /**
+ * @access private
+ * called on idle when the mouse is down, sends events to topmost view
+ * NOTE: it would be good to have bounding rectangles on these groups
+ */
+ function __LZtrack (ignore:*) :void {
+ var foundviews:Array = [];
+ var agroups:Array = this.__LZactivegroups;
+ for (var i:int = 0; i < agroups.length; ++i) {
+ //would love to check to see if the mouse is within a group's
+ //bounding rect. this would significantly speed up menu tracking.
+ var thisgroup:Array = agroups[i];
-/**
- * @access private
- * called on idle when the mouse is down, sends events to topmost view
- * NOTE: it would be good to have bounding rectangles on these groups
- */
-function __LZtrack (ignore) {
- var foundviews = [];
- for (var i:int = 0; i < this.__LZactivegroups.length; ++i) {
- var hitlist =[];
- //would love to check to see if the mouse is within a group's
- //bounding rect. this would significantly speed up menu tracking.
- var thisgroup = this.__LZactivegroups[i];
+ // build a combined hitlist from all groups
+ var hitlist:Array = [];
+ this.__LZtrackgroup(thisgroup, hitlist);
- // build a combined hitlist from all groups
- if (thisgroup) this.__LZtrackgroup(thisgroup,hitlist);
-
- if ( !hitlist.length && thisgroup && thisgroup.__LZlasthit ) { // over no tracked views
- var onmtrackout:LzDeclaredEventClass = thisgroup.__LZlasthit.onmousetrackout;
- if (onmtrackout && onmtrackout.ready)
- onmtrackout.sendEvent(thisgroup.__LZlasthit);
- thisgroup.__LZlasthit = null;
- } else {
- var fd = this.__LZfindTopmost(hitlist);
- if ( fd && fd != thisgroup.__LZlasthit ) {
- if (thisgroup.__LZlasthit) {
- var onmtrackout:LzDeclaredEventClass = thisgroup.__LZlasthit.onmousetrackout;
- if (onmtrackout && onmtrackout.ready)
- onmtrackout.sendEvent( thisgroup.__LZlasthit );
- }
- // save this found value so that we can send the onmousetrackover
- // after ALL of the onmousetrackouts from all trackgroups are sent
+ var lhit:LzView = thisgroup.__LZlasthit;
+ if (hitlist.length) {
+ var fd:LzView = this.__LZfindTopmost(hitlist);
+ if (fd == lhit) continue;
+ // save this found value so that we can send the onmousetrackover
+ // after ALL of the onmousetrackouts from all trackgroups are sent
foundviews.push(fd);
- thisgroup.__LZlasthit = fd;
+ } else {
+ // over no tracked views
+ var fd:LzView = null;
}
+ if (lhit) {
+ var onmtrackout:LzDeclaredEventClass = lhit.onmousetrackout;
+ if (onmtrackout.ready)
+ onmtrackout.sendEvent(lhit);
+ }
+ thisgroup.__LZlasthit = fd;
}
- }
- var len = foundviews.length;
- if ( len ) {
- for (var i=0; i < len; i++) {
- var v = foundviews[i]
- if (v.onmousetrackover.ready) v.onmousetrackover.sendEvent( v );
+ for (var i:int = 0, len:int = foundviews.length; i < len; ++i) {
+ var v:LzView = foundviews[i]
+ if (v.onmousetrackover.ready)
+ v.onmousetrackover.sendEvent( v );
}
}
-}
-/**
- * @access private
- * called before mouseup event is sent
- */
-function __LZmouseup(ignore) {
- //Debug.info('lz.Track.__LZmouseup');
- for (var i:int = 0; i < this.__LZactivegroups.length; ++i) {
- var thisgroup = this.__LZactivegroups[i];
- //Debug.info('i', i, thisgroup, thisgroup.__LZlasthit, thisgroup.__LZlasthit.onmousetrackup);
- if (thisgroup && thisgroup.__LZlasthit) {
- var onmtrackup:LzDeclaredEventClass = thisgroup.__LZlasthit.onmousetrackup;
- if (onmtrackup && onmtrackup.ready) {
- if (this['__LZlastmouseup'] == thisgroup.__LZlasthit) {
- this.__LZlastmouseup = null;
- } else {
- onmtrackup.sendEvent(this.__LZlasthit);
- this.__LZlastmouseup = thisgroup.__LZlasthit;
+ /**
+ * @access private
+ * called before mouseup event is sent
+ */
+ function __LZmouseup (ignore:*) :void {
+ //Debug.info('lz.Track.__LZmouseup');
+ var agroups:Array = this.__LZactivegroups;
+ for (var i:int = 0; i < agroups.length; ++i) {
+ var lhit:LzView = agroups[i].__LZlasthit;
+ if (lhit) {
+ var onmtrackup:LzDeclaredEventClass = lhit.onmousetrackup;
+ if (onmtrackup.ready) {
+ if (this.__LZlastmouseup == lhit) {
+ this.__LZlastmouseup = null;
+ } else {
+ onmtrackup.sendEvent(lhit);
+ this.__LZlastmouseup = lhit;
+ }
}
}
}
}
-}
} // End of LzTrackService
lz.TrackService = LzTrackService; // publish
/**
- * lz.Track is a shortcut for <a href="LzTrackService.html">LzTrackService</a>.
+ * lz.Track is a shortcut for <a href="LzTrackService.html">LzTrackService.LzTrack</a>.
*/
-lz.Track = new LzTrackService();
+lz.Track = LzTrackService.LzTrack;
More information about the Laszlo-checkins
mailing list