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

Reply via email to