Actually after thinking about this some more, MenuItemRenderer should have its own controller. The standard ItemRendererMouseController only needs to dispatch a single click event. MenuItemRendererMouseController could dispatch all these other events. This seems more PAYG...
Regarding “over” events on mobile, I think finger dragging would trigger “over” events there. > On Sep 14, 2018, at 8:44 AM, Alex Harui <[email protected]> wrote: > > Sure, there can/should be "item*" events as higher-level semantic events for > each mouse event and touch gesture. Bonus if you can make that PAYG since > mobile devices will rarely leverage "over" events. The semantic meaning is > that the mouse event was not used for any other interaction in the renderer > and thus can be used by a selection controller in the List. > > My 2 cents, > -Alex > > On 9/13/18, 2:22 PM, "Harbs" <[email protected]> wrote: > > What about itemMouseOver? I think we’d need that too. It seems like > mousing down on a menu and moving over a sub-menu should pop open the submenu. > >> On Sep 14, 2018, at 12:15 AM, Alex Harui <[email protected]> wrote: >> >> Yes please. It sounds like you are already set up with some test cases. >> >> Thanks, >> -Alex >> >> On 9/13/18, 2:12 PM, "Harbs" <[email protected] >> <mailto:[email protected]>> wrote: >> >> OK. It sounds like you have a good plan. >> >> I’m fine with dispatching itemMouseDown, itemMouseUp and itemClick. That >> makes sense and should solve the problem. >> >> Do you want me to work on implementing that? >> >>> On Sep 14, 2018, at 12:09 AM, Alex Harui <[email protected]> wrote: >>> >>> Different controllers will have different behaviors. Menu behavior is in >>> fact one of the reasons I wanted to do beads and have replacable component >>> logic. In your standard List, you "must" mouseDown and mouseUp on the same >>> renderer to generate a Click that changes selection. However, in many >>> menus, you can mouseDown on the MenuBar and without releasing the mouse >>> button, drag down the menu to an item and release (MouseUp) and that item >>> will be selected from the menu. Outlook's menubar on my Mac seems to work >>> this way. So, some people will want mouseUp to change selection, others >>> will want click to change selection. Royale should offer choices. >>> >>> But changing selection is a higher-level event. The lowest level events >>> are mouseDown/mouseUp/click. In between is the "ITEM_CLICK" event and in >>> theor, ITEM_MOUSEDOWN and ITEM_MOUSEUP. It is up to the controllers to >>> interpret a lower-level event and then dispatch a higher-level event. It >>> seems "illogical" to me that an ITEM_CLICK would be dispatched from a >>> mouseUp handler. ITEM_CLICK (and ITEM_MOUSEUP if there is such a things) >>> is meant to indicate that an event happened on the renderer that should be >>> interpreted by the controller. Some parts of a renderer may not dispatch >>> ITEM_CLICK (for example, in some Trees, clcking on expand/collapse icons >>> don't change selection. >>> >>> Then the MenuController and ListSelectionController should be interpreting >>> ITEM_CLICK and ITEM_MOUSEUP and deciding what to do. So maybe the answer >>> is that the renderer's mouseUp controller dispatches ITEM_MOUSEUP, and Menu >>> changes selection on ITEM_CLICK or ITEM_MOUSEUP. >>> >>> Separately, whether setTimeout or requestAnimationFrame, the more deferred >>> work and asynchronicity we put in the framework, the more trouble we will >>> give our users IMO. Starting such a trend has the danger of making >>> application code use more and more >>> callLater/setTimeout/requestAnimationFrame calls as well. We should not >>> defer work unless we have to, and I don't think we have to in this case. >>> Making things rely on timing creates the potential for timing issues. >>> >>> My 2 cents, >>> -Alex >>> >>> On 9/13/18, 1:50 PM, "Harbs" <[email protected] >>> <mailto:[email protected]> <mailto:[email protected] >>> <mailto:[email protected]>>> wrote: >>> >>> That article was not what I was referring to. Like I said I couldn’t find >>> it. I’m working from memory. >>> >>>> I'm still surprised the fix isn't to not dispatch ITEM_CLICK on MouseUp. >>>> UP doesn't guarantee CLICK, IMO. You could mouse down in one renderer >>>> and mouse up in another renderer. In some interaction models that does >>>> change selection, but I don't think CLICK is the right semantic. >>> >>> I don’t understand you. Are you saying that mousing down on one renderer >>> and mousing up on another should fire an itemClick? That seems wrong to me. >>> An itemClick should be both mouse down and mouse up on the same item. Click >>> does that very nicely. >>> >>>> Further, I would like to discourage use of setTimeout in the framework. >>>> The framework has little control over the behavior of application event >>>> handlers. >>> >>> I would generally agree with you. But in this case, we’re handling the >>> dismissal of a menu. I don’t see the harm here. If you have another >>> proposal, I’m open to hear… >>> >>> We can also use requestAnimationFrame() to delay the execution until after >>> click. That will be guaranteed to be before the next draw of the screen, so >>> it might be better than setTimeout() which will probably be later. >>> >>> Thanks, >>> Harbs >>> >>>> On Sep 13, 2018, at 11:20 PM, Alex Harui <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>> I didn't see anywhere in the article where it guaranteed that both up and >>>> click are sequential in the queue. Sharing the heap isn't the issue here. >>>> >>>> I'm still surprised the fix isn't to not dispatch ITEM_CLICK on MouseUp. >>>> UP doesn't guarantee CLICK, IMO. You could mouse down in one renderer >>>> and mouse up in another renderer. In some interaction models that does >>>> change selection, but I don't think CLICK is the right semantic. >>>> >>>> Further, I would like to discourage use of setTimeout in the framework. >>>> The framework has little control over the behavior of application event >>>> handlers. With many browsers having immediate screen updates (as opposed >>>> to Flash's deferred rendering), postponing work with setTimeout can result >>>> in unexpected behavior, and can result in callLater "wars" where more and >>>> more code has to keep deferring work with setTimeout because some lower >>>> layer also used setTimeout. Deferring work should be the option of the >>>> application developer as much as possible. >>>> >>>> My 2 cents, >>>> -Alex >>>> >>>> On 9/13/18, 11:36 AM, "Harbs" <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>> I once read that the way setTimeout works is that it’s added to the next >>>> event loop. That would mean that both mouseup and click would be executed >>>> in the current event loop and the setTimout would be delayed to the next >>>> one (i..e between 4ms and 10ms later). >>>> >>>> I can’t find the article at the moment, but my understanding is that this >>>> is a safe way to guarantee later execution in all browsers. >>>> >>>> The MDN doc has a decent explanation.[1] Both mouseup and click would be >>>> on the same heap. >>>> >>>> Harbs >>>> >>>> [1]https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FJavaScript%2FEventLoop&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=WlXgm2G0O5%2FneGMCkXVql3nKNLXtlD1ZMxeXVms3a%2Fk%3D&reserved=0 >>>> >>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FJavaScript%2FEventLoop&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=WlXgm2G0O5%2FneGMCkXVql3nKNLXtlD1ZMxeXVms3a%2Fk%3D&reserved=0> >>>> >>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FJavaScript%2FEventLoop&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=WlXgm2G0O5%2FneGMCkXVql3nKNLXtlD1ZMxeXVms3a%2Fk%3D&reserved=0 >>>> >>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FJavaScript%2FEventLoop&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=WlXgm2G0O5%2FneGMCkXVql3nKNLXtlD1ZMxeXVms3a%2Fk%3D&reserved=0>> >>>>> On Sep 13, 2018, at 6:54 PM, Alex Harui <[email protected] >>>>> <mailto:[email protected]> <mailto:[email protected] >>>>> <mailto:[email protected]>>> wrote: >>>>> >>>>> Is setTimeout guaranteed to run after the CLICK event? >>>>> >>>>> On 9/13/18, 6:14 AM, "[email protected] <mailto:[email protected]> >>>>> <mailto:[email protected] <mailto:[email protected]>> >>>>> <mailto:[email protected] <mailto:[email protected]> >>>>> <mailto:[email protected] <mailto:[email protected]>>>" <[email protected] >>>>> <mailto:[email protected]><mailto:[email protected] >>>>> <mailto:[email protected]>> <mailto:[email protected] >>>>> <mailto:[email protected]> <mailto:[email protected] >>>>> <mailto:[email protected]>>>> wrote: >>>>> >>>>> This is an automated email from the ASF dual-hosted git repository. >>>>> >>>>> harbs pushed a commit to branch develop >>>>> in repository >>>>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0 >>>>> >>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0><https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0 >>>>> >>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0>><https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0 >>>>> >>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0><https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0 >>>>> >>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfb60650ae1ab445e42a208d619bf04c0%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636724705541473946&sdata=jjONJRkIS9RJImEu8p92y3HpBkrQeRqOZChFg6jJw%2FQ%3D&reserved=0>>> >>>>> >>>>> >>>>> The following commit(s) were added to refs/heads/develop by this push: >>>>> new e1ec25e I think this fixes Menu >>>>> e1ec25e is described below >>>>> >>>>> commit e1ec25e0d8b1e59bfbb1e3d0cf856fe9dfb4dc5e >>>>> Author: Harbs <[email protected] <mailto:[email protected]> >>>>> <mailto:[email protected] <mailto:[email protected]>> >>>>> <mailto:[email protected] <mailto:[email protected]> >>>>> <mailto:[email protected] <mailto:[email protected]>>>> >>>>> AuthorDate: Thu Sep 13 16:14:03 2018 +0300 >>>>> >>>>> I think this fixes Menu >>>>> --- >>>>> .../projects/Basic/src/main/resources/defaults.css | 1 + >>>>> .../controllers/ItemRendererMouseController.as | 1 - >>>>> .../controllers/MenuSelectionMouseController.as | 33 >>>>> ++++++++++++++-------- >>>>> 3 files changed, 23 insertions(+), 12 deletions(-) >>>>> >>>>> diff --git a/frameworks/projects/Basic/src/main/resources/defaults.css >>>>> b/frameworks/projects/Basic/src/main/resources/defaults.css >>>>> index f88da20..15cb4e6 100644 >>>>> --- a/frameworks/projects/Basic/src/main/resources/defaults.css >>>>> +++ b/frameworks/projects/Basic/src/main/resources/defaults.css >>>>> @@ -545,6 +545,7 @@ Panel >>>>> IBeadModel: >>>>> ClassReference("org.apache.royale.html.beads.models.PanelModel"); >>>>> IBeadView: ClassReference("org.apache.royale.html.beads.PanelView"); >>>>> IPanelLayout: >>>>> ClassReference("org.apache.royale.html.beads.layouts.VerticalFlexLayout"); >>>>> + IPanelContentArea: ClassReference("org.apache.royale.html.Container"); >>>>> >>>>> background-color: #FFFFFF; >>>>> border: 1px solid #333333 >>>>> diff --git >>>>> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as >>>>> >>>>> b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as >>>>> index f408a71..6073264 100644 >>>>> --- >>>>> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as >>>>> +++ >>>>> b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as >>>>> @@ -92,7 +92,6 @@ COMPILE::JS { >>>>> goog.events.listen(element, >>>>> goog.events.EventType.MOUSEOUT, this.handleMouseOut); >>>>> goog.events.listen(element, >>>>> goog.events.EventType.MOUSEDOWN, this.handleMouseDown); >>>>> goog.events.listen(element, >>>>> goog.events.EventType.CLICK, this.handleMouseUp); >>>>> - goog.events.listen(element, >>>>> goog.events.EventType.MOUSEUP, this.handleMouseUp); >>>>> } >>>>> } >>>>> >>>>> diff --git >>>>> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MenuSelectionMouseController.as >>>>> >>>>> b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MenuSelectionMouseController.as >>>>> index 5f986bb..6a09a52 100644 >>>>> --- >>>>> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MenuSelectionMouseController.as >>>>> +++ >>>>> b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MenuSelectionMouseController.as >>>>> @@ -127,6 +127,8 @@ package org.apache.royale.html.beads.controllers >>>>> * @playerversion Flash 10.2 >>>>> * @playerversion AIR 2.6 >>>>> * @productversion Royale 0.9 >>>>> + * @royaleignorecoercion org.apache.royale.core.UIBase >>>>> + * @royaleignorecoercion org.apache.royale.core.IUIBase >>>>> */ >>>>> protected function hideOpenMenus():void >>>>> { >>>>> @@ -137,8 +139,9 @@ package org.apache.royale.html.beads.controllers >>>>> if (menu.parent != null) { >>>>> var >>>>> controller:MenuSelectionMouseController = >>>>> menu.getBeadByType(MenuSelectionMouseController) as >>>>> MenuSelectionMouseController; >>>>> controller.removeClickOutHandler(menu); >>>>> - var host:IPopUpHost = UIUtils.findPopUpHost(_strand >>>>> as IUIBase); >>>>> - host.popUpParent.removeElement(menu); >>>>> + var host:IPopUpHost = UIUtils.findPopUpHost(menu as >>>>> IUIBase); >>>>> + if(host) >>>>> + >>>>> host.popUpParent.removeElement(menu); >>>>> } >>>>> } >>>>> MenuModel.clearMenuList(); >>>>> @@ -163,6 +166,8 @@ package org.apache.royale.html.beads.controllers >>>>> * @playerversion Flash 10.2 >>>>> * @playerversion AIR 2.6 >>>>> * @productversion Royale 0.9 >>>>> + * @royaleignorecoercion org.apache.royale.core.IUIBase >>>>> + * @royaleignorecoercion >>>>> org.apache.royale.events.IEventDispatcher >>>>> */ >>>>> public function removeClickOutHandler(menu:Object):void >>>>> { >>>>> @@ -191,23 +196,29 @@ package org.apache.royale.html.beads.controllers >>>>> >>>>> /** >>>>> * @royaleignorecoercion HTMLElement >>>>> + * @royaleignorecoercion org.apache.royale.core.IUIBase >>>>> * @private >>>>> */ >>>>> COMPILE::JS >>>>> protected function hideMenu_internal(event:BrowserEvent):void >>>>> { >>>>> var menu:IMenu = _strand as IMenu; >>>>> + var menuElem:HTMLElement = (_strand as IUIBase).element >>>>> as HTMLElement; >>>>> + var menuBarElement:HTMLElement; >>>>> if (menu.parentMenuBar) >>>>> { >>>>> - var menuBarElement:HTMLElement = (menu.parentMenuBar as >>>>> IUIBase).element as HTMLElement; >>>>> - var target:HTMLElement = event.target as HTMLElement; >>>>> - while (target != null) >>>>> - { >>>>> - if (target == menuBarElement) return; >>>>> - target = target.parentNode as HTMLElement; >>>>> - } >>>>> - } >>>>> - hideOpenMenus(); >>>>> + menuBarElement = (menu.parentMenuBar as IUIBase).element >>>>> as HTMLElement; >>>>> + } >>>>> + var target:HTMLElement = event.target as HTMLElement; >>>>> + while (target != null) >>>>> + { >>>>> + var comp:IUIBase = target["royale_wrapper"]; >>>>> + if(comp && (comp is IMenu || comp == >>>>> menu.parentMenuBar) ) return; >>>>> + // if (target == menuElem || (menuBarElement && >>>>> target == menuBarElement) ) return; >>>>> + target = target.parentNode as HTMLElement; >>>>> + } >>>>> + >>>>> + setTimeout(hideOpenMenus); >>>>> } >>>>> } >>>>> } >>>>> \ No newline at end of file > > >
