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