Thanks for the code sample, Benjamin. I'll take a look and see if I can find any good tips in there.
On May 26, 2006, at 12:48 PM, Benjamin Shine wrote: > We coped with a similar problem in the rich text editor; we needed > to preserve the selected text before the text area loses focus, > which is parallel to making your mouseover-widget disappear when > you mouse off. I think. This might help; it's how we handle the > preserve-selection-on-mouseout behavior in the rich text editor in > laszlo mail. The code below is the core of how we do it, and it's > all in context at: > http://svn.openlaszlo.org/openlaszlo/trunk/lps/components/incubator/ > rich-text/richtexteditarea.lzx > > (I think this implementation falls under the rubric of "For various > reasons, this line of thinking proved nearly impossible to sort > out," as you say.) > > > <!--- Forget the selection if we lose focus to a focusable widget, > but > keep the selection if we lose focus to a non-focusable > widget, like > the toolbar buttons. > @param view s: the view which is gaining the selection > --> > <method event="onblur" args="s"> > this._fieldhasfocus = false; > // If we're blurring and the focus is going to anything > *but* the toolbar > // widgets, set _ssel and _esel to nothing. > // Semantically, we want to get rid of the selection if > we lose focus. > if (s != null) { > // We're really giving focus to something else, so, > forget > // about whatever was selected while this component > still had focus. > // It seems to "feel" right to me to move the > cursor to the end of > // the text. > this._ssel = this._esel = this.getText().length; > } > </method> > > > <!--- If the mouse down is over me or any of my children, > remember that, > so we can listen for an onmouseup anywhere. A mouseup > after a mousedown > indicates that the selection has changed. > @param view who: the element being moused down on > --> > <method event="onmousedown" reference="LzGlobalMouse" > args="who"><![CDATA[ > if ((who != null) && (this._containsView(who))) { > // the mouse went down on a child of me > // Debug.write("mousedown on child of me"); > this._mousedownorigin = who; > } else if ((who == null) && (inp.containsPt > (this.getMouse("x"), this.getMouse("y")))) { > // the mouse went down on me > // Debug.write("mousedown on me"); > this._mousedownorigin = this; > } else { > // the mouse went down on someone other than me; > i'm not interested. > this._mousedownorigin = null; > } > ]]> > </method> > > > <!--- Listen for global mouse up. > We're only interested in global mouse up if the editor > has focus. > If the editor does have focus, > is there a mousedown/mouseup pair in progress? > @param view who: the current mousedown element (ben shine) > --> > <method event="onmouseup" reference="LzGlobalMouse" > args="who"> > if (this._fieldhasfocus) { > // Debug.write("onmouseup, field has focus, who is > ", who); > > if (this._mousedownorigin != null) { > // We have focus, and there _is_ a mousedown/ > mouseup pair in progress. > if (this._mousedownorigin == this) { > > // The mouse click started on the richtext > editor. > > // If the mouse click also ended on the > rich text editor, > // it's just a caret move. > if (inp.containsPt(this.getMouse("x"), > this.getMouse("y"))) { > this._caretmove(); > } else { > // If the mouseclick ended anywhere but > the rich text editor, > // it's a lost mousedown. > this._handleLostMouseDown(); > } > } else { > // We have focus, and there's a mousedown/ > mouseup pair in progress, > // and it started on one of the subviews of > the RTE. > // Debug.write("lost mousedown, origin was > ", this._mousedownorigin); > } > > } else { > // We have focus, but there's no mousedown/ > mouseup pair in progress. > // Therefore, do nothing. > // Debug.write("No mousedown origin. The > mousedown didn't start on an RTE component."); > } > } > > // Clear the mousedown attribute; a mouseup means that > whatever > // the mousedown was, it's gone now. > this._mousedownorigin = null; > </method> > > ... > <!--- > Handle the case where a mouse drag began on the RTE but > the mouse up > was not on the RTE. > @keywords private > --> > <method name="_handleLostMouseDown"> > var selstart = this._field.getSelectionPosition(); > var selend = selstart + this._field.getSelectionSize(); > this.setCurrentFormat( this.getTextFormat(selstart, > selend), true); > </method> > > <!--- Restore last selection region. > Note: this must be called from a delegate in an idle event > *after* flash completes the "frame" in which the > selection or focus > changed. > @keywords private --> > <method name="_restoreSelection"> > //-------------------------------------------------------- > ---- > // FIXME [2005-08-16 pkang]: Need to know in which > direction > // selection was done so as to not make scrollbar jump. > //-------------------------------------------------------- > ---- > this._shouldresettoolbar = false; > this.setSelection(this._ssel, this._esel); > this._shouldresettoolbar = true; > </method> > > > On May 26, 2006, at 10:08 AM, Neil Mix wrote: > >> Thanks Benjamin. That's some good stuff. Way beyond me, I >> think. ;) >> >> Here's a little more info about the problem I'm facing. It's >> pretty unique and edge-casey, but maybe you'll find it interesting. >> >> I'm prototyping a graphical widget that appears when you mouse >> over the album art on a song slide. I want to make the widget >> disappear when you mouse away. Typically, this would be as easy >> as catching an onmouseout and hiding the widget. And flash >> supports that, even when you mouse off the canvas -- you still get >> an onmouseout (yet the reported mouse coordinates are still within >> the bounds of the object). >> >> Here's the trick: this widget contains buttons that also receive >> mouse events. Those buttons (of course) have hover effects and >> various states, and clicking them may cause other objects to >> appear above the buttons. The net result is that my widget may >> never receive a mouseout event, because one of the buttons >> contained within it may instead receive the mouseout. >> >> What I've ended up doing is attaching event handlers to >> LzGlobalMouse to catch all onmouseover/onmouseout events and check >> to see whether or not the current mouse position is within the >> bounds of the the widget. This is by far the easiest and most >> fullproof algorithm. (Alternative would be to catch onmouseout of >> the contained buttons directly, and then try to determine why a >> button received a mouseout, and whether the event is worthy of >> hiding the container widget or not. For various reasons, this >> line of thinking proved nearly impossible to sort out.) >> >> As I've thought about it, I've wondered if what I need is extra >> info in the mouseout event that tells me which object is going to >> receive the subsequent mouseover (or null if no object is going to >> get mouseover). For example, something like: >> >> <method event="onmousemove" reference="LzGlobalMouse" >> args="who,where"> >> // "who" is the object that received the mouseout event >> // "where" is the object that the mouse has entered, or null >> // if no object receives mouse events at the new location >> >> if(who_is_the_widget_or_its_child()) { >> keep_visible(); >> } else { >> make_invisible(); >> } >> </method> >> >> I suppose I could implement this by setting a timer during >> onmouseout to check what the subsequent onmouseover value is. The >> only problem is that I don't know what contractual guarantees the >> runtime provides with regard to mouse events and their proximity >> time-wise. If a mouseout occurs, is any subsequent mouseover >> guaranteed to happen before the next onidle? Is it possible for >> multiple mouseout/mouseover combos to happen before the next onidle? >> >> On May 26, 2006, at 12:43 AM, Benjamin Shine wrote: >> >>> You might try applying a predictive tracking algorithm: something >>> like watching every mouse move, guessing where the mouse is >>> going, then setting a timer to see if you get another mouse move >>> event. You could get into math like evaluating the rate of travel >>> of the mouse pointer towards a boundary of the app; moving >>> rapidly toward the border would predict that the border will be >>> crossed; moving towards the border but decelerating would predict >>> that the border won't be crossed. >>> >>> Patrick Baudisch, at Microsoft Research, has been doing some >>> really nice CHI work with user studies on this sort of thing. I >>> recommend checking out his work. It might not be exactly what you >>> need, but it's *cool*, and could get you a "+5 nifty!" rating if >>> you applied it to Pandora. >>> http://www.patrickbaudisch.com/publications/index.html >>> >>> Joe Laviola at Brown has been doing some work with this: >>> http://www.cs.brown.edu/people/jjl/ptracking/ptracking.html >>> >>> Is your app in a javascript wrapper, though? Seems like there >>> ought to be a clever way of noticing a mouse-enter in DHTML, and >>> sending a message to the laszlo app to let it know it's lost the >>> pointer. >>> >>> Please let us know what you learn. >>> >>> On May 25, 2006, at 9:38 AM, Neil Mix wrote: >>> >>>> I'd like to have some way of knowing that the mouse is no longer >>>> above the canvas, i.e. the Flash app is no longer able to receive >>>> mouse events. Is this possible at all? What I'm seeing is that >>>> the >>>> last moused-over object will receive a mouseout event, but the >>>> getMouse() coords returned are the last known location of the mouse >>>> before it left the canvas (which makes sense). >>>> >>>> I'm guessing I'm out of luck here, but I thought I'd check with the >>>> experts first. It's OK by me if the solution involves using Flash >>>> native or deeply private LZX stuff. >>>> >>>> TIA, -Neil >>>> _______________________________________________ >>>> Laszlo-dev mailing list >>>> [email protected] >>>> http://www.openlaszlo.org/mailman/listinfo/laszlo-dev >>> >>> benjamin shine >>> software engineer >>> [EMAIL PROTECTED] >>> >>> >>> >> > > benjamin shine > software engineer > [EMAIL PROTECTED] > > > _______________________________________________ Laszlo-dev mailing list [email protected] http://www.openlaszlo.org/mailman/listinfo/laszlo-dev
