'Have you solved Piotr's problem? We should first understand what it takes to solve his problem before going further into these kinds of changes.'
tbh, I kinda lost track of the details of that. My original understanding was that it was related to double-dispatch of change event. But that was because change event was the binding event, and not the model changes, so I had put efforts in to dispatch more 'change' events to get binding to work. Model changes for selection were being redispatched as 'change'. Now, 'change' should only be dispatched alongside a subset of model changes (and only represent the interaction changes a user made). So if that is working correctly, I hope it is fixed. Will wait to hear... On Sat, Dec 22, 2018 at 6:29 PM Alex Harui <[email protected]> wrote: > Ah, the shared model problem. > > I'm not afraid of some "radical" changes. The main constraint is if we > have time to do it. But better to change all dozens of beads now instead > of 100's later when we have lots of apps in production on them. In some > ways, we are only now finding out what more sophisticated apps need, so I'm > not surprised to see some of these issues arise. > > The fundamental pattern we are discussing about EventDispatcher is a > communication issue. Royale has lots of beads, Flex didn't, so > communicating between all of these pieces is new territory. Seems like > there are several choices: > > 1) Any bead that can be "shared" must dispatch events from itself. > Strands choose which events to re-dispatch out of the component. This is, > I think, what we've done most in the code base. The main downsides are the > re-dispatch, and the usability of knowing which beads are shared, or else > all model beads have to dispatch from themselves. > 2) All beads should dispatch off the strand. This is pretty > straightforward except when beads are shared. The options around sharing > are (at minimum): > A) Beads are never shared. We should stop sharing the beads that are > currently shared and have a "proxy" bead that gets a reference to the model > bead and proxies all APIs to the original bead > B) Beads are shared. Beads that expect sharing keep a list of > strands. I don't like this too much. Beads would have to be planned to be > shared. > C) Beads that expect sharing ignore any subsequent setting of the > strand so they only dispatch off the original strand which is hopefully > always the top-level component (TLC). Any other placing of the bead on the > strand is ignored and the secondary strand that was ignored should have a > reference back to the TLC and should listen to the TLC. There is still > some upfront planning in that I don’t' think we want all strands to check > if they've already been set. But it might be most acceptable in that there > is still only one strand to dispatch from, instead of multiple in 2B. The > other weird thing is that the second strand doesn't have a model on its > strand, just a reference to the model from the base class. That would mean > that the recommended pattern for accessing the model is "(strand as > IStrandWithModel).model" and not "strand.getBeadByType(IBeadModel)" > > I'd be up for trying 2C. Other ideas, like not having a strand at all, > but some other concept like subscribers, is a bit too radical for me. IMO, > strand, beads, and MVC are common enough and work often enough that it > wouldn't be PAYG to have the base implementations have code to handle > sharing "just-in-case" they are shared. > > Then we can see how 1 compares to 2C in terms of code size, performance, > etc. > > Have you solved Piotr's problem? We should first understand what it takes > to solve his problem before going further into these kinds of changes. > > My 2 cents, > -Alex > > > > > On 12/21/18, 8:47 PM, "Greg Dove" <[email protected]> wrote: > > I don't need to assign the external dispatcher, because it is already > available as _strand inside model, is that what you mean? I missed > seeing > the wood for the trees there. > I guess I was looking at it from the outside-in via the controller > which > seemed to be first to start adding listeners to the model, and not > thinking > about the model as having the 'external dispatcher' (_strand) reference > already, so that's a good thing to have my eyes opened about :). > Thanks! > > In terms of IEventDispatcher-ness, what I was trying to do here was to > make > something that worked within what I understood to be the 'current > conventions'. In order to do that I actually wanted the API surface to > be > the same, because I assumed that those conventions were 'how we do > things > around here' (the existing code is all I have to determine this, and I > did > not follow the rules the first time, so I was trying to both 'follow > the > rules' and make improvements). I think a lot of existing code which > involves adding listeners to the model should continue to work with the > type of approach I used (making allowance for the change from > 'selectedIndexChanged' to 'selectionChanged' etc) . > > But changing the events in the model all to something like > _strand.dispatchEvent('selectionChange') definitely could work too, > and the > model need not be an IEventDispatcher at all, as I mentioned > previously - I > had just considered that approach as 'too radical' when I thought about > what appeared to be the current conventions. It's clearer now to me > that > you are not afraid to change those :). > > That will require scouring all the code that currently adds listeners > to > the model and finding ways to ensure it explicitly listens to the top > level > component (the one that is being supported for binding) instead, and > making > sure that the current strand which represents that does not change > inside > the model if the model gets shared (as it does for example in > combobox). > Probably the first strand assigned could be considered the dispatcher, > and > kept as a reference I guess. But I won't have more time to spend on > this > probably for a couple of weeks now. I think what I did so far is an > improvement for now at least, and a partial transition towards what you > suggest (within Jewel, anyway). Hopefully when Piotr can test what he > is > using it for, it will help with the issues he was seeing. > fwiw I haven't seen binding event loops or any issues like that yet > either. > > > > > On Sat, Dec 22, 2018 at 3:26 PM Alex Harui <[email protected]> > wrote: > > > I'm sorry, I'm just not getting it. If you want to dispatch off the > host, > > just use the strand. I still don't see the need to encapsulate an > > EventDispatcher and wire it up to the API surfaces. > > > > We should pick a dispatch "convention" for beads. Either they > dispatch > > off themselves and other folks have to listen to the beads or they > should > > dispatch off the strand. I agree that the latter sounds more > efficient. > > I tried to remember of there was some situation where dispatching > off the > > strand would cause trouble like loops or too much traffic or > collisions > > with events from other beads, but none came to mind. > > > > Thanks, > > -Alex > > > > On 12/20/18, 11:47 PM, "Greg Dove" <[email protected]> wrote: > > > > The main purpose for that is to avoid using the model itself as > the > > dispatcher. It could still extend EventDispatcher, but the > methods > > would > > still need overriding to use the host component as the dispatcher > > instead > > of 'this'. By using the host component as the primary > dispatcher, it > > avoids > > pointless redispatching of cloned events from the model. And the > extra > > event creation overhead associated with that. > > I know this is all UI stuff and probably that is not critical, > but I > > can't > > assume how many of these will get used in what ways. > > The model could be completely non-IEventispatcher and always > have an > > external IEventDispatcher provided, but that seemed too radical > > compared > > to existing code and the ancestor interfaces etc. > > > > The main thing I think is that it works (so far anyway). And I > think > > it is > > close to what we discussed. > > > > But I will see if it solves the issue that Piotr was seeing. > > > > > > On Fri, Dec 21, 2018 at 8:14 PM Alex Harui > <[email protected]> > > wrote: > > > > > Looks reasonable. Can you explain why ArrayListSelectionModel > > should not > > > extend EventDispatcher and encapsulate one instead? Isn't > > encapsulation > > > more code to run? > > > > > > -Alex > > > > > > On 12/20/18, 10:26 PM, "[email protected]" < > [email protected]> > > wrote: > > > > > > This is an automated email from the ASF dual-hosted git > > repository. > > > > > > gregdove pushed a commit to branch > > > bugfix/issue_353_double_dispatch_of_change_event_in_Jewel_List > > > 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%7Cb8dc9a70eab44dee7f2e08d667c88139%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636810508217157168&sdata=1b%2BYXsV1OFOxDNpnj9TIRqHU0feOnf3EAXb0kX4COQ0%3D&reserved=0 > > > > > > commit 448228023f841dd838a94ba3fee2db1c629bf964 > > > Author: greg-dove <[email protected]> > > > AuthorDate: Fri Dec 21 19:25:43 2018 +1300 > > > > > > Cumulative updates to migrate to 'selectionChanged' for > > bindings > > > Fixes a some issues with add/remove/update beads for > > > dataprovider/item changes. Added extra test display to Tour de > Jewel > > for > > > this. > > > --- > > > .../src/main/royale/ListPlayGround.mxml | 9 > ++ > > > .../royale/org/apache/royale/jewel/ComboBox.as | 9 > +- > > > .../royale/org/apache/royale/jewel/DropDownList.as | 8 > +- > > > .../main/royale/org/apache/royale/jewel/List.as | 9 > +- > > > .../jewel/beads/controllers/ComboBoxController.as | 20 > +++- > > > .../beads/controllers/DropDownListController.as | 43 > ++++--- > > > .../ListSingleSelectionMouseController.as | 42 > > ++++--- > > > .../beads/controls/DispatchChangeOnStartup.as | 41 > ++----- > > > .../jewel/beads/controls/combobox/SearchFilter.as | 6 > +- > > > .../AddListItemRendererForArrayListData.as | 18 > ++- > > > .../RemoveListItemRendererForArrayListData.as | 23 > ++-- > > > .../UpdateListItemRendererForArrayListData.as | 21 > ++-- > > > .../jewel/beads/models/ArrayListSelectionModel.as | 127 > > > +++++++++++++++------ > > > .../royale/jewel/beads/models/ComboBoxModel.as | 30 > ++--- > > > .../jewel/beads/models/IDropDownListModel.as | 1 - > > > .../jewel/beads/models/IJewelSelectionModel.as | 3 > +- > > > .../royale/jewel/beads/views/ComboBoxView.as | 14 > ++- > > > .../royale/jewel/beads/views/DropDownListView.as | 2 > +- > > > .../apache/royale/jewel/beads/views/ListView.as | 6 > +- > > > 19 files changed, 271 insertions(+), 161 deletions(-) > > > > > > diff --git > > > > a/examples/royale/TourDeJewel/src/main/royale/ListPlayGround.mxml > > > > b/examples/royale/TourDeJewel/src/main/royale/ListPlayGround.mxml > > > index baad8a6..620b9a2 100644 > > > --- > > a/examples/royale/TourDeJewel/src/main/royale/ListPlayGround.mxml > > > +++ > > b/examples/royale/TourDeJewel/src/main/royale/ListPlayGround.mxml > > > @@ -109,6 +109,12 @@ limitations under the License. > > > } > > > return intro + evaluated; > > > } > > > + > > > + public function > > > describeIconItem(iconObject:Object):String{ > > > + const iconVO:IconListVO = > iconObject > > as > > > IconListVO; > > > + if (!iconVO) return '[Nothing > > Selected]'; > > > + return 'label:\'' + > iconVO.label + > > '\', > > > icon:\'' + iconVO.icon + '\''; > > > + } > > > ]]> > > > </fx:Script> > > > > > > @@ -165,6 +171,9 @@ limitations under the License. > > > <j:Button > > text="Remove > > > first item" click="removeItemAt()"/> > > > <j:Button > > text="Update > > > first item" click="updateFirstItem()"/> > > > <j:Button > > text="Remove all > > > data" click="removeAllData()"/> > > > + <j:Label > > html="{'Selected > > > Index: ' + iconList.selectedIndex}"/> > > > + <j:Label > > html="Selected > > > Item description:"/> > > > + <j:Label > > > html="{describeIconItem(iconList.selectedItem)}"/> > > > </j:VGroup> > > > </j:HGroup> > > > </j:Card> > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/ComboBox.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/ComboBox.as > > > index a479008..faf4872 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/ComboBox.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/ComboBox.as > > > @@ -19,14 +19,10 @@ > > > package org.apache.royale.jewel > > > { > > > import org.apache.royale.core.StyledUIBase; > > > - import org.apache.royale.core.IComboBoxModel; > > > import org.apache.royale.core.ISelectionModel; > > > import org.apache.royale.core.IDataProviderModel; > > > import org.apache.royale.core.IListPresentationModel; > > > - import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > import > > org.apache.royale.jewel.beads.models.ListPresentationModel; > > > - import org.apache.royale.events.IEventDispatcher; > > > - import org.apache.royale.events.Event; > > > > > > //-------------------------------------- > > > // Events > > > @@ -119,7 +115,7 @@ package org.apache.royale.jewel > > > IDataProviderModel(model).dataProvider > = > > value; > > > } > > > > > > - [Bindable("change")] > > > + [Bindable("selectionChanged")] > > > /** > > > * The index of the currently selected item. > > Changing > > > this item changes > > > * the selectedItem value. > > > @@ -142,7 +138,7 @@ package org.apache.royale.jewel > > > ISelectionModel(model).selectedIndex = > value; > > > } > > > > > > - [Bindable("change")] > > > + [Bindable("selectionChanged")] > > > /** > > > * The item currently selected. Changing this > value > > also > > > * changes the selectedIndex property. > > > @@ -180,5 +176,6 @@ package org.apache.royale.jewel > > > } > > > return presModel; > > > } > > > + > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/DropDownList.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/DropDownList.as > > > index 7d2b171..951bafd 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/DropDownList.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/DropDownList.as > > > @@ -179,7 +179,7 @@ package org.apache.royale.jewel > > > // } > > > // } > > > > > > - [Bindable("change")] > > > + [Bindable("selectionChanged")] > > > /** > > > * The index of the currently selected item. > Changing > > this > > > value > > > * also changes the selectedItem property. > > > @@ -216,7 +216,7 @@ package org.apache.royale.jewel > > > } > > > } > > > > > > - [Bindable("change")] > > > + [Bindable("selectionChanged")] > > > /** > > > * The item currently selected. Changing this > value > > also > > > * changes the selectedIndex property. > > > @@ -297,13 +297,9 @@ package org.apache.royale.jewel > > > var ddModel:IDropDownListModel = model as > > > IDropDownListModel; > > > if (ddModel) { > > > index -= ddModel.offset; > > > - > ddModel.setProcessingInteractiveChange(true); > > > } > > > > > > model.selectedIndex = index; > > > - > > > - if (ddModel) > > > - > ddModel.setProcessingInteractiveChange(false); > > > } > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/List.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/List.as > > > index 14fb311..ad495e5 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/List.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/List.as > > > @@ -24,9 +24,6 @@ package org.apache.royale.jewel > > > import org.apache.royale.core.IDataProviderModel; > > > import org.apache.royale.core.IListPresentationModel; > > > import > > org.apache.royale.jewel.beads.models.ListPresentationModel; > > > - import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > - import org.apache.royale.events.IEventDispatcher; > > > - import org.apache.royale.events.Event; > > > > > > COMPILE::JS > > > { > > > @@ -140,7 +137,7 @@ package org.apache.royale.jewel > > > * @productversion Royale 0.9.4 > > > * @royaleignorecoercion > > > org.apache.royale.core.ISelectionModel > > > */ > > > - [Bindable("change")] > > > + [Bindable("selectionChanged")] > > > public function get selectedIndex():int > > > { > > > return > ISelectionModel(model).selectedIndex; > > > @@ -201,7 +198,7 @@ package org.apache.royale.jewel > > > * @productversion Royale 0.9.4 > > > * @royaleignorecoercion > > > org.apache.royale.core.ISelectionModel > > > */ > > > - [Bindable("change")] > > > + [Bindable("selectionChanged")] > > > public function get selectedItem():Object > > > { > > > return > ISelectionModel(model).selectedItem; > > > @@ -232,5 +229,7 @@ package org.apache.royale.jewel > > > } > > > return presModel; > > > } > > > + > > > + > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as > > > index cf187c3..b1fe20d 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as > > > @@ -18,7 +18,9 @@ > > > > > > > > > //////////////////////////////////////////////////////////////////////////////// > > > package org.apache.royale.jewel.beads.controllers > > > { > > > - COMPILE::SWF > > > +import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > + > > > +COMPILE::SWF > > > { > > > import flash.utils.setTimeout; > > > } > > > @@ -83,6 +85,13 @@ package > > org.apache.royale.jewel.beads.controllers > > > } else { > > > > > > IEventDispatcher(_strand).addEventListener("viewChanged", > > finishSetup); > > > } > > > + if (model is IJewelSelectionModel) { > > > + IJewelSelectionModel(model).dispatcher = > > > IEventDispatcher(value); > > > + } > > > + else { > > > + > > > IEventDispatcher(model).addEventListener('dataProviderChanged', > > > modelChangeHandler); > > > + > > > IEventDispatcher(model).addEventListener('selectionChanged', > > > modelChangeHandler); > > > + } > > > } > > > > > > /** > > > @@ -124,6 +133,11 @@ package > > org.apache.royale.jewel.beads.controllers > > > list = (popup.view as > > ComboBoxPopUpView).list; > > > > list.addEventListener(MouseEvent.MOUSE_DOWN, > > > handleControlMouseDown); > > > list.addEventListener(Event.CHANGE, > > changeHandler); > > > + if (model is IJewelSelectionModel) { > > > + //don't let the pop-up's list > take > > over as > > > primary dispatcher > > > + //it needs to stay with the > ComboBox > > (for > > > selection bindings to work) > > > + IJewelSelectionModel(model).dispatcher = > > > IEventDispatcher(_strand); > > > + } > > > } > > > > > > private var popup:ComboBoxPopUp; > > > @@ -180,5 +194,9 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > > > IEventDispatcher(_strand).dispatchEvent(new > > > Event(Event.CHANGE)); > > > } > > > + > > > + protected function > modelChangeHandler(event:Event):void{ > > > + IEventDispatcher(_strand).dispatchEvent(new > > > Event(event.type)); > > > + } > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/DropDownListController.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/DropDownListController.as > > > index 62d4896..1bddf92 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/DropDownListController.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/DropDownListController.as > > > @@ -20,7 +20,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > { > > > // import flash.display.DisplayObject; > > > // import flash.geom.Point; > > > - > > > + > > > import org.apache.royale.core.IBeadController; > > > import org.apache.royale.core.IStrand; > > > import org.apache.royale.events.Event; > > > @@ -29,7 +29,8 @@ package > > org.apache.royale.jewel.beads.controllers > > > import org.apache.royale.events.ItemClickedEvent; > > > import org.apache.royale.events.ItemRemovedEvent; > > > import > > org.apache.royale.jewel.beads.models.DropDownListModel; > > > - import > org.apache.royale.jewel.beads.views.DropDownListView; > > > +import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > +import > org.apache.royale.jewel.beads.views.DropDownListView; > > > > > > /** > > > * The DropDownListController class is the > controller for > > > @@ -39,7 +40,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > * This controller watches for the click event and > > displays the > > > * dropdown/popup, and watches the dropdown/popup for > > change > > > events > > > * and updates the selection model accordingly. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -49,7 +50,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > { > > > /** > > > * Constructor. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -58,10 +59,10 @@ package > > org.apache.royale.jewel.beads.controllers > > > public function DropDownListController() > > > { > > > } > > > - > > > + > > > /** > > > * The model. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -71,7 +72,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > > /** > > > * The view. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -82,11 +83,12 @@ package > > org.apache.royale.jewel.beads.controllers > > > private var _strand:IStrand; > > > /** > > > * @copy org.apache.royale.core.IBead#strand > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > * @productversion Royale 0.9.4 > > > + * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > */ > > > public function set strand(value:IStrand):void > > > { > > > @@ -94,7 +96,14 @@ package > > org.apache.royale.jewel.beads.controllers > > > model = > value.getBeadByType(DropDownListModel) as > > > DropDownListModel; > > > > > IEventDispatcher(_strand).addEventListener("itemAdded", > > > handleItemAdded); > > > > > > IEventDispatcher(_strand).addEventListener("itemRemoved", > > > handleItemRemoved); > > > - > > > > > > //IEventDispatcher(value).addEventListener(org.apache.royale.events.MouseEvent.CLICK, > > > clickHandler); > > > + if (model is IJewelSelectionModel) { > > > + IJewelSelectionModel(model).dispatcher = > > > IEventDispatcher(value); > > > + } > > > + else { > > > + > > > IEventDispatcher(model).addEventListener('selectionChanged', > > > modelChangeHandler); > > > + > > > IEventDispatcher(model).addEventListener('dataProviderChanged', > > > modelChangeHandler); > > > + } > > > + > > > } > > > > > > /** > > > @@ -104,7 +113,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > { > > > > > > IEventDispatcher(event.item).addEventListener("itemClicked", > > > selectedHandler); > > > } > > > - > > > + > > > /** > > > * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > */ > > > @@ -119,7 +128,11 @@ package > > org.apache.royale.jewel.beads.controllers > > > model.selectedItem = event.data; > > > view.host.dispatchEvent(new > Event(Event.CHANGE)); > > > } > > > - > > > + > > > + protected function > > modelChangeHandler(event:Event):void{ > > > + > IEventDispatcher(_strand).dispatchEvent(new > > > Event(event.type)); > > > + } > > > + > > > // private function > > > clickHandler(event:org.apache.royale.events.MouseEvent):void > > > // { > > > // var viewBead:IDropDownListView = > > > _strand.getBeadByType(IDropDownListView) as IDropDownListView; > > > @@ -137,16 +150,16 @@ package > > org.apache.royale.jewel.beads.controllers > > > // > > > > IEventDispatcher(viewBead.popUp).addEventListener(Event.CHANGE, > > > changeHandler); > > > // > > > > > > IUIBase(_strand).topMostEventDispatcher.addEventListener(org.apache.royale.events.MouseEvent.CLICK, > > > dismissHandler); > > > // } > > > - > > > + > > > // private function > > > dismissHandler(event:org.apache.royale.events.MouseEvent):void > > > // { > > > // if (event.target == _strand) return; > > > - > > > + > > > // > > > > > > IUIBase(_strand).topMostEventDispatcher.removeEventListener(org.apache.royale.events.MouseEvent.CLICK, > > > dismissHandler); > > > // var viewBead:IDropDownListView = > > > _strand.getBeadByType(IDropDownListView) as IDropDownListView; > > > // viewBead.popUpVisible = false; > > > // } > > > - > > > + > > > // private function > changeHandler(event:Event):void > > > // { > > > // var viewBead:IDropDownListView = > > > _strand.getBeadByType(IDropDownListView) as IDropDownListView; > > > @@ -156,6 +169,6 @@ package > > org.apache.royale.jewel.beads.controllers > > > // selectionModel.selectedIndex = > > > popUpModel.selectedIndex; > > > // > IEventDispatcher(_strand).dispatchEvent(new > > > Event(Event.CHANGE)); > > > // } > > > - > > > + > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListSingleSelectionMouseContro > > > ller.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListSingleSelectionMouseContro > > > ller.as > > > index c19ce5f..604b55e 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListSingleSelectionMouseContro > > > ller.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListSingleSelectionMouseContro > > > ller.as > > > @@ -30,8 +30,9 @@ package > > org.apache.royale.jewel.beads.controllers > > > import org.apache.royale.events.ItemClickedEvent; > > > import org.apache.royale.events.ItemRemovedEvent; > > > import org.apache.royale.html.beads.IListView; > > > +import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > > > > - /** > > > +/** > > > * The ListSingleSelectionMouseController class is a > > controller > > > for > > > * org.apache.royale.jewel.List. Controllers > > > * watch for events from the interactive portions of > a > > View and > > > @@ -40,7 +41,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > * and updates an ISelectionModel (which only > supports > > single > > > * selection). Other controller/model pairs would > support > > > * various kinds of multiple selection. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -50,7 +51,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > { > > > /** > > > * Constructor. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -59,10 +60,10 @@ package > > org.apache.royale.jewel.beads.controllers > > > public function > ListSingleSelectionMouseController() > > > { > > > } > > > - > > > + > > > /** > > > * The model. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -72,7 +73,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > > /** > > > * The view. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -82,7 +83,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > > /** > > > * The parent of the item renderers. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -91,10 +92,10 @@ package > > org.apache.royale.jewel.beads.controllers > > > protected var dataGroup:IItemRendererParent; > > > > > > private var _strand:IStrand; > > > - > > > + > > > /** > > > * @copy org.apache.royale.core.IBead#strand > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -110,8 +111,15 @@ package > > org.apache.royale.jewel.beads.controllers > > > listView = > value.getBeadByType(IListView) as > > > IListView; > > > > > > IEventDispatcher(_strand).addEventListener("itemAdded", > > handleItemAdded); > > > > > > IEventDispatcher(_strand).addEventListener("itemRemoved", > > > handleItemRemoved); > > > + if (listModel is IJewelSelectionModel) > { > > > + > IJewelSelectionModel(listModel).dispatcher = > > > IEventDispatcher(value); > > > + } > > > + else { > > > + > > > > IEventDispatcher(listModel).addEventListener('selectionChanged', > > > modelChangeHandler); > > > + > > > > IEventDispatcher(listModel).addEventListener('dataProviderChanged', > > > modelChangeHandler); > > > + } > > > } > > > - > > > + > > > /** > > > * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > */ > > > @@ -121,7 +129,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > > IEventDispatcher(event.item).addEventListener("itemRollOver", > > > rolloverHandler); > > > > > > IEventDispatcher(event.item).addEventListener("itemRollOut", > > > rolloutHandler); > > > } > > > - > > > + > > > /** > > > * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > */ > > > @@ -131,14 +139,18 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > > > IEventDispatcher(event.item).removeEventListener("itemRollOver", > > > rolloverHandler); > > > > > > IEventDispatcher(event.item).removeEventListener("itemRollOut", > > > rolloutHandler); > > > } > > > - > > > + > > > protected function > > > selectedHandler(event:ItemClickedEvent):void > > > { > > > listModel.selectedIndex = event.index; > > > listModel.selectedItem = event.data; > > > listView.host.dispatchEvent(new > > Event(Event.CHANGE)); > > > } > > > - > > > + > > > + protected function > modelChangeHandler(event:Event):void{ > > > + IEventDispatcher(_strand).dispatchEvent(new > > > Event(event.type)); > > > + } > > > + > > > /** > > > * @royaleemitcoercion > > > org.apache.royale.core.ISelectableItemRenderer > > > * @royaleignorecoercion > > org.apache.royale.core.IRollOverModel > > > @@ -150,7 +162,7 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > IRollOverModel(listModel).rollOverIndex = > > > renderer.index; > > > } > > > } > > > - > > > + > > > /** > > > * @royaleemitcoercion > > > org.apache.royale.core.ISelectableItemRenderer > > > * @royaleignorecoercion > > org.apache.royale.core.IRollOverModel > > > @@ -164,6 +176,6 @@ package > > org.apache.royale.jewel.beads.controllers > > > > > IRollOverModel(listModel).rollOverIndex = > > > -1; > > > } > > > } > > > - > > > + > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/DispatchChangeOnStartup.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/DispatchChangeOnStartup.as > > > index cf6ef81..94529e4 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/DispatchChangeOnStartup.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/DispatchChangeOnStartup.as > > > @@ -22,11 +22,11 @@ package > > org.apache.royale.jewel.beads.controls > > > import org.apache.royale.core.IStrand; > > > import org.apache.royale.events.IEventDispatcher; > > > import org.apache.royale.events.Event; > > > - import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > + import org.apache.royale.core.ISelectionModel; > > > > > > /** > > > * The DispatchChangeOnStartup bead class is a > specialty > > bead > > > that can be used > > > - * with components that implements > IJewelSelectionModel and > > uses > > > dataProvider > > > + * with components that implements ISelectionModel > and uses > > > dataProvider > > > * to dispatch a CHANGE event when the component is > > initialized > > > * > > > * @langversion 3.0 > > > @@ -63,12 +63,12 @@ package > > org.apache.royale.jewel.beads.controls > > > public function set strand(value:IStrand):void > > > { > > > _strand = value; > > > - > > > IEventDispatcher(_strand).addEventListener('beadsAdded', > > onBeadsAdded); > > > + > > > IEventDispatcher(_strand).addEventListener('beadsAdded', > > listenToModel); > > > } > > > > > > - > > > /** > > > - * adjust the way the model behaves for > dispatching > > > change events > > > + * listen for the startup selectionChanged > Event > > that > > > occurs when dataprovider is assigned > > > + * and there is a preselected index, fire a > change > > event > > > * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > @@ -76,37 +76,20 @@ package > > org.apache.royale.jewel.beads.controls > > > * @productversion Royale 0.9.4 > > > * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > */ > > > - private function onBeadsAdded(event:Event):void > > > + private function > listenToModel(event:Event):void > > > { > > > - > > > IEventDispatcher(_strand).removeEventListener('beadsAdded', > > onBeadsAdded); > > > - const model:IJewelSelectionModel = > > > _strand.getBeadByType(IJewelSelectionModel) as > IJewelSelectionModel; > > > + > > > IEventDispatcher(_strand).removeEventListener('beadsAdded', > > listenToModel); > > > + const model:ISelectionModel = > > > _strand.getBeadByType(ISelectionModel) as ISelectionModel; > > > if (model) { > > > - > > > > IEventDispatcher(model).addEventListener('dataProviderChanged', > > onChange); > > > - > > > > IEventDispatcher(model).addEventListener('selectedItemChanged', > > onChange); > > > - > > > > IEventDispatcher(model).addEventListener('selectedIndexChanged', > > onChange); > > > - } else { > > > - //for now > > > - throw new > > Error('DispatchChangeOnStartup > > > bead is not yet compatible with the component it is being > applied > > to'); > > > + > > > IEventDispatcher(model).addEventListener('selectionChanged', > > onChange); > > > } > > > } > > > > > > - private var _sawDataProviderChange:Boolean; > > > private function onChange(event:Event):void{ > > > - if (event.type == > 'dataProviderChanged') { > > > - _sawDataProviderChange = true; > > > - return; > > > - } > > > - //event here is normal change event > > > - if (!_sawDataProviderChange) { > > > - //wait for a change event after > > > dataProviderChange? needs review, maybe not > > > - return; > > > - } > > > - const model:IJewelSelectionModel = > > > _strand.getBeadByType(IJewelSelectionModel) as > IJewelSelectionModel; > > > - > > > > IEventDispatcher(model).removeEventListener('dataProviderChanged', > > > onChange); > > > - > > > > IEventDispatcher(model).removeEventListener('selectedItemChanged', > > > onChange); > > > - > > > > IEventDispatcher(model).removeEventListener('selectedIndexChanged', > > > onChange); > > > + const model:ISelectionModel = > > > _strand.getBeadByType(ISelectionModel) as ISelectionModel; > > > + > > > > IEventDispatcher(model).removeEventListener('selectionChanged', > > onChange); > > > + > IEventDispatcher(_strand).dispatchEvent(new > > > Event('change')); > > > > > > - IEventDispatcher(_strand).dispatchEvent(new > > > Event("change")); > > > } > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/combobox/SearchFilter.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/combobox/SearchFilter.as > > > index dbf444c..7ac6b59 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/combobox/SearchFilter.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/combobox/SearchFilter.as > > > @@ -115,7 +115,7 @@ package > > > org.apache.royale.jewel.beads.controls.combobox > > > { > > > const inputBase:TextInputBase = > event.target > > as > > > TextInputBase; > > > //keyup can include other things like > tab > > > navigation > > > - IComboBoxView > > > + > > > if (!inputBase) { > > > //if (popUpVisible) > > > event.target.parent.view.popUpVisible = false; > > > return; > > > @@ -153,10 +153,10 @@ package > > > org.apache.royale.jewel.beads.controls.combobox > > > ir.visible = false; > > > } > > > } > > > - if (count == 1) { > > > + /* if (count == 1) { > > > //select lastActive if there is only one > that > > matches? > > > > > > - } > > > + }*/ > > > } > > > > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/AddListItemRendererForArrayListData.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/AddListItemRendererForArrayListData.as > > > index 36311b8..498cf62 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/AddListItemRendererForArrayListData.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/AddListItemRendererForArrayListData.as > > > @@ -75,7 +75,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > _strand = value; > > > > > > IEventDispatcher(value).addEventListener("initComplete", > > initComplete); > > > } > > > - > > > + > > > /** > > > * finish setup > > > * > > > @@ -87,16 +87,16 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > protected function > initComplete(event:Event):void > > > { > > > > > > IEventDispatcher(_strand).removeEventListener("initComplete", > > initComplete); > > > - > > > + > > > _dataProviderModel = > > > _strand.getBeadByType(ISelectionModel) as ISelectionModel; > > > labelField = > _dataProviderModel.labelField; > > > > > > - > > > dataProviderModel.addEventListener("dataProviderChanged", > > > dataProviderChangeHandler); > > > + > > > dataProviderModel.addEventListener("dataProviderChanged", > > > dataProviderChangeHandler); > > > > > > // invoke now in case > "dataProviderChanged" > > has > > > already been dispatched. > > > dataProviderChangeHandler(null); > > > } > > > - > > > + > > > private var dp:IEventDispatcher; > > > /** > > > * @private > > > @@ -110,7 +110,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > dp = dataProviderModel.dataProvider as > > > IEventDispatcher; > > > if (!dp) > > > return; > > > - > > > + > > > // listen for individual items being > added > > in the > > > future. > > > > > dp.addEventListener(CollectionEvent.ITEM_ADDED, > > > handleItemAdded); > > > } > > > @@ -124,6 +124,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > * @productversion Royale 0.9.4 > > > * @royaleignorecoercion > > > org.apache.royale.core.ISelectableItemRenderer > > > * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > + * @royaleignorecoercion > > > org.apache.royale.core.ISelectionModel > > > */ > > > protected function > > > handleItemAdded(event:CollectionEvent):void > > > { > > > @@ -131,7 +132,8 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > var ir:ISelectableItemRenderer = > > > itemRendererFactory.createItemRenderer(itemRendererParent) as > > > ISelectableItemRenderer; > > > > > > fillRenderer(event.index, event.item, ir, > > > presentationModel); > > > - > > > + > > > + > > > // update the index values in the > > itemRenderers to > > > correspond to their shifted positions. > > > var n:int = > > itemRendererParent.numItemRenderers; > > > for (var i:int = event.index; i < n; > i++) > > > @@ -139,6 +141,10 @@ package > > > org.apache.royale.jewel.beads.itemRenderers > > > ir = > > > itemRendererParent.getItemRendererAt(i) as > ISelectableItemRenderer; > > > ir.index = i; > > > } > > > + //adjust the model's selectedIndex, if > applicable > > > + if (event.index <= > > > ISelectionModel(_dataProviderModel).selectedIndex) { > > > + > > ISelectionModel(_dataProviderModel).selectedIndex = > > > ISelectionModel(_dataProviderModel).selectedIndex + 1; > > > + } > > > > > > (_strand as > > IEventDispatcher).dispatchEvent(new > > > Event("layoutNeeded")); > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/RemoveListItemRendererForArrayListData.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/RemoveListItemRendererForArrayListData.as > > > index d591553..eec8ea5 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/RemoveListItemRendererForArrayListData.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/RemoveListItemRendererForArrayListData.as > > > @@ -32,7 +32,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > import org.apache.royale.html.beads.IListView; > > > > > > /** > > > - * Handles the removal of an itemRenderer in a List > > component > > > once the corresponding > > > + * Handles the removal of an itemRenderer in a List > > component > > > once the corresponding > > > * datum has been removed from the IDataProviderModel. > > > * > > > * @langversion 3.0 > > > @@ -69,7 +69,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > _strand = value; > > > > > > IEventDispatcher(value).addEventListener("initComplete", > > initComplete); > > > } > > > - > > > + > > > /** > > > * finish setup > > > * > > > @@ -81,14 +81,14 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > protected function > initComplete(event:Event):void > > > { > > > > > > IEventDispatcher(_strand).removeEventListener("initComplete", > > initComplete); > > > - > > > + > > > _dataProviderModel = > > > _strand.getBeadByType(ISelectionModel) as ISelectionModel; > > > - > > > dataProviderModel.addEventListener("dataProviderChanged", > > > dataProviderChangeHandler); > > > - > > > + > > > dataProviderModel.addEventListener("dataProviderChanged", > > > dataProviderChangeHandler); > > > + > > > // invoke now in case > "dataProviderChanged" > > has > > > already been dispatched. > > > dataProviderChangeHandler(null); > > > } > > > - > > > + > > > private var dp:IEventDispatcher; > > > /** > > > * @private > > > @@ -102,7 +102,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > dp = dataProviderModel.dataProvider as > > > IEventDispatcher; > > > if (!dp) > > > return; > > > - > > > + > > > // listen for individual items being > removed > > in > > > the future. > > > > > dp.addEventListener(CollectionEvent.ITEM_REMOVED, > > > handleItemRemoved); > > > } > > > @@ -116,12 +116,13 @@ package > > > org.apache.royale.jewel.beads.itemRenderers > > > * @productversion Royale 0.9.4 > > > * @royaleignorecoercion > > > org.apache.royale.core.ISelectableItemRenderer > > > * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > + * @royaleignorecoercion > > > org.apache.royale.core.ISelectionModel > > > */ > > > protected function > > > handleItemRemoved(event:CollectionEvent):void > > > { > > > var ir:ISelectableItemRenderer = > > > itemRendererParent.getItemRendererAt(event.index) as > > > ISelectableItemRenderer; > > > > itemRendererParent.removeItemRenderer(ir); > > > - > > > + > > > // adjust the itemRenderers' index to > adjust > > for > > > the shift > > > var n:int = > > itemRendererParent.numItemRenderers; > > > for (var i:int = event.index; i < n; > i++) > > > @@ -129,6 +130,12 @@ package > > > org.apache.royale.jewel.beads.itemRenderers > > > ir = > > > itemRendererParent.getItemRendererAt(i) as > ISelectableItemRenderer; > > > ir.index = i; > > > } > > > + //adjust the model's selectedIndex, if > > applicable > > > + if (event.index < > > > ISelectionModel(_dataProviderModel).selectedIndex) { > > > + > > ISelectionModel(_dataProviderModel).selectedIndex = > > > ISelectionModel(_dataProviderModel).selectedIndex - 1; > > > + } else if (event.index == > > > ISelectionModel(_dataProviderModel).selectedIndex) { > > > + > > ISelectionModel(_dataProviderModel).selectedIndex = > > > -1; > > > + } > > > > > > (_strand as > > IEventDispatcher).dispatchEvent(new > > > Event("layoutNeeded")); > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/UpdateListItemRendererForArrayListData.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/UpdateListItemRendererForArrayListData.as > > > index 245eea4..2f511dd 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/UpdateListItemRendererForArrayListData.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/itemRenderers/UpdateListItemRendererForArrayListData.as > > > @@ -31,7 +31,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > import org.apache.royale.html.beads.IListView; > > > > > > /** > > > - * Handles the update of an itemRenderer in a List > > component once > > > the corresponding > > > + * Handles the update of an itemRenderer in a List > > component once > > > the corresponding > > > * datum has been updated from the IDataProviderModel. > > > * > > > * @langversion 3.0 > > > @@ -71,7 +71,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > _strand = value; > > > > > > IEventDispatcher(value).addEventListener("initComplete", > > initComplete); > > > } > > > - > > > + > > > /** > > > * finish setup > > > * > > > @@ -84,16 +84,16 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > protected function > initComplete(event:Event):void > > > { > > > > > > IEventDispatcher(_strand).removeEventListener("initComplete", > > initComplete); > > > - > > > + > > > _dataProviderModel = > > > _strand.getBeadByType(ISelectionModel) as ISelectionModel; > > > labelField = > _dataProviderModel.labelField; > > > > > > - > > > dataProviderModel.addEventListener("dataProviderChanged", > > > dataProviderChangeHandler); > > > + > > > dataProviderModel.addEventListener("dataProviderChanged", > > > dataProviderChangeHandler); > > > > > > // invoke now in case > "dataProviderChanged" > > has > > > already been dispatched. > > > dataProviderChangeHandler(null); > > > } > > > - > > > + > > > private var dp:IEventDispatcher; > > > /** > > > * @private > > > @@ -108,7 +108,7 @@ package > > org.apache.royale.jewel.beads.itemRenderers > > > dp = dataProviderModel.dataProvider as > > > IEventDispatcher; > > > if (!dp) > > > return; > > > - > > > + > > > // listen for individual items being > updated > > in > > > the future. > > > > > dp.addEventListener(CollectionEvent.ITEM_UPDATED, > > > handleItemUpdated); > > > } > > > @@ -121,13 +121,20 @@ package > > > org.apache.royale.jewel.beads.itemRenderers > > > * @playerversion AIR 2.6 > > > * @productversion Royale 0.9.4 > > > * @royaleignorecoercion > > > org.apache.royale.events.IEventDispatcher > > > + * @royaleignorecoercion > > > org.apache.royale.core.ISelectionModel > > > */ > > > protected function > > > handleItemUpdated(event:CollectionEvent):void > > > { > > > var ir:ISelectableItemRenderer = > > > itemRendererParent.getItemRendererAt(event.index) as > > > ISelectableItemRenderer; > > > - > > > + > > > setData(ir, event.item, event.index); > > > > > > + if (event.index == > > > ISelectionModel(_dataProviderModel).selectedIndex) { > > > + //manually trigger a selection > > change, > > > even if there was actually none. > > > + //This causes selection-based > > bindings to > > > work > > > + > > > IEventDispatcher(_dataProviderModel).dispatchEvent(new > > > Event('selectionChanged')); > > > + } > > > + > > > (_strand as > > IEventDispatcher).dispatchEvent(new > > > Event("layoutNeeded")); > > > } > > > > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ArrayListSelectionModel.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ArrayListSelectionModel.as > > > index 3da08ee..74c10b3 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ArrayListSelectionModel.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ArrayListSelectionModel.as > > > @@ -20,10 +20,15 @@ package > org.apache.royale.jewel.beads.models > > > { > > > import org.apache.royale.collections.IArrayList; > > > import org.apache.royale.core.IRollOverModel; > > > - import org.apache.royale.core.ISelectionModel; > > > import org.apache.royale.core.IStrand; > > > import org.apache.royale.events.Event; > > > import org.apache.royale.events.EventDispatcher; > > > + import org.apache.royale.events.IEventDispatcher; > > > + import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > + > > > + COMPILE::SWF{ > > > + import flash.events.Event; > > > + } > > > > > > /** > > > * The ArrayListSelectionModel class is a selection > model > > for > > > @@ -35,7 +40,7 @@ package > org.apache.royale.jewel.beads.models > > > * @playerversion AIR 2.6 > > > * @productversion Royale 0.9.4 > > > */ > > > - public class ArrayListSelectionModel extends > EventDispatcher > > > implements IJewelSelectionModel, IRollOverModel > > > + public class ArrayListSelectionModel implements > > > IJewelSelectionModel, IRollOverModel > > > { > > > /** > > > * Constructor. > > > @@ -49,10 +54,65 @@ package > org.apache.royale.jewel.beads.models > > > { > > > } > > > > > > - private var > _dispatchChangeOnDataChange:Boolean; > > > - public function set > > > dispatchChangeOnDataProviderChange(value:Boolean):void{ > > > - _dispatchChangeOnDataChange = value; > > > + //IJewelSelectionModel > > > + private var _dispatcher:IEventDispatcher; > > > + private function getDispatcher():IEventDispatcher > { > > > + if (!_dispatcher) _dispatcher = new > > > EventDispatcher(this) as IEventDispatcher; > > > + return _dispatcher; > > > + } > > > + public function set > > dispatcher(value:IEventDispatcher):void{ > > > + _dispatcher = value; > > > + } > > > + > > > + //IEventDispatcher JS > > > + COMPILE::JS > > > + public function addEventListener(type:String, > > > handler:Function, opt_capture:Boolean = false, > > opt_handlerScope:Object = > > > null):void{ > > > + getDispatcher().addEventListener(type, > > handler, > > > opt_capture, opt_handlerScope); > > > } > > > + COMPILE::JS > > > + public function > removeEventListener(type:String, > > > handler:Function, opt_capture:Boolean = false, > > opt_handlerScope:Object = > > > null):void{ > > > + > getDispatcher().removeEventListener(type, > > handler, > > > opt_capture, opt_handlerScope); > > > + } > > > + > > > + COMPILE::JS > > > + public function > dispatchEvent(event:Object):Boolean{ > > > + return > getDispatcher().dispatchEvent(event); > > > + } > > > + > > > + > > > + > > > + //IEventDispatcher SWF > > > + COMPILE::SWF > > > + public function addEventListener(type:String, > > > listener:Function, useCapture:Boolean = false, priority:int = > 0, > > > useWeakReference:Boolean = false):void { > > > + getDispatcher().addEventListener(type, > > listener, > > > useCapture, priority, useWeakReference); > > > + } > > > + COMPILE::SWF > > > + public function > removeEventListener(type:String, > > > listener:Function, useCapture:Boolean = false):void{ > > > + > getDispatcher().removeEventListener(type, > > > listener, useCapture); > > > + } > > > + > > > + COMPILE::SWF > > > + public function > > > dispatchEvent(event:flash.events.Event):Boolean{ > > > + return > getDispatcher().dispatchEvent(event); > > > + } > > > + > > > + COMPILE::SWF > > > + public function willTrigger(type:String):Boolean{ > > > + return getDispatcher().willTrigger(type); > > > + } > > > + > > > + //IEventDispatcher (shared) > > > + public function > hasEventListener(type:String):Boolean{ > > > + return getDispatcher().hasEventListener(type); > > > + } > > > + > > > + /** > > > + * @private > > > + */ > > > + protected function > > dispatchChange(eventName:String):void{ > > > + dispatchEvent(new > > > org.apache.royale.events.Event(eventName)); > > > + } > > > + > > > > > > private var _strand:IStrand; > > > > > > @@ -69,17 +129,9 @@ package > org.apache.royale.jewel.beads.models > > > _strand = value; > > > } > > > > > > - private var _processingInteractiveChange:Boolean = > > false; > > > - public function > > > setProcessingInteractiveChange(value:Boolean):void{ > > > - _processingInteractiveChange = value; > > > - } > > > - protected function get > > processingInteractiveChange():Boolean{ > > > - return _processingInteractiveChange; > > > - } > > > > > > private var _dataProvider:IArrayList; > > > > > > - [Bindable("dataProviderChanged")] > > > /** > > > * @copy > > org.apache.royale.core.ISelectionModel#dataProvider > > > * > > > @@ -127,11 +179,10 @@ package > > org.apache.royale.jewel.beads.models > > > _selectedIndex = -1; > > > } > > > > > > - dispatchEvent(new > Event("dataProviderChanged")); > > > - if (itemChanged) > > > - dispatchEvent(new > Event("selectedItemChanged")); > > > - if (oldIndex != _selectedIndex) > > > - dispatchEvent(new > > Event("selectedIndexChanged")); > > > + dispatchChange("dataProviderChanged"); > > > + if (itemChanged || oldIndex != > > _selectedIndex) { > > > + dispatchChange("selectionChanged"); > > > + } > > > } > > > > > > private var _selectedIndex:int = -1; > > > @@ -158,7 +209,7 @@ package > org.apache.royale.jewel.beads.models > > > { > > > if (value != _labelField) { > > > _labelField = value; > > > - dispatchEvent(new > > > Event("labelFieldChanged")); > > > + dispatchChange("labelFieldChanged"); > > > } > > > } > > > > > > @@ -186,7 +237,6 @@ package > org.apache.royale.jewel.beads.models > > > } > > > if (value == _selectedIndex) return; > > > > > > - const oldItem:Object = _selectedItem; > > > _selectedIndex = value < _dataProvider.length > ? > > value : > > > _dataProvider.length - 1; > > > if (_selectedIndex != -1) { > > > _selectedItem = > > > _dataProvider.getItemAt(_selectedIndex); > > > @@ -194,9 +244,7 @@ package > org.apache.royale.jewel.beads.models > > > _selectedItem = null; > > > } > > > > > > - if ( oldItem != _selectedItem) > > > - dispatchEvent(new > Event("selectedItemChanged")); > > > - dispatchEvent(new > Event("selectedIndexChanged")); > > > + dispatchChange("selectionChanged"); > > > } > > > > > > /** > > > @@ -219,7 +267,7 @@ package > org.apache.royale.jewel.beads.models > > > { > > > if (value != _rollOverIndex) { > > > _rollOverIndex = value; > > > - dispatchEvent(new > > > Event("rollOverIndexChanged")); > > > + dispatchChange("rollOverIndexChanged"); > > > } > > > } > > > > > > @@ -243,22 +291,26 @@ package > > org.apache.royale.jewel.beads.models > > > */ > > > public function set > selectedItem(value:Object):void > > > { > > > - if (value == _selectedItem) return; > > > - _selectedItem = value; > > > - if (_dataProvider) { > > > - const indexChanged:Boolean = > _selectedIndex != > > > (_selectedIndex = _dataProvider.getItemIndex(value)); > > > - > > > - dispatchEvent(new > Event("selectedItemChanged")); > > > - if (indexChanged) > > > - dispatchEvent(new > > Event("selectedIndexChanged")); > > > - } > > > + if (value == _selectedItem) { > > > + if (_dataProvider) { > > > + if (_selectedIndex != > > > (_selectedIndex = _dataProvider.getItemIndex(value))) { > > > + > dispatchChange("selectionChanged"); > > > + } > > > + } > > > + } else { > > > + _selectedItem = value; > > > + if (_dataProvider) { > > > + _selectedIndex = > > > _dataProvider.getItemIndex(value); > > > + dispatchChange("selectionChanged"); > > > + } > > > + } > > > } > > > > > > private var _selectedString:String; > > > > > > /** > > > * An alternative to selectedItem for strongly > typing > > the > > > - * the selectedItem if the Array is an Array of > > Strings. > > > + * the selectedItem if the dataProvider is an > > ArrayList of > > > Strings. > > > * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > @@ -277,6 +329,7 @@ package > org.apache.royale.jewel.beads.models > > > { > > > _selectedString = value; > > > var n:int = _dataProvider.length; > > > + var oldIndex:int = _selectedIndex; > > > for (var i:int = 0; i < n; i++) > > > { > > > if > > (String(_dataProvider.getItemAt(i)) == > > > value) > > > @@ -285,8 +338,10 @@ package > org.apache.royale.jewel.beads.models > > > break; > > > } > > > } > > > - dispatchEvent(new > > Event("selectedItemChanged")); > > > - dispatchEvent(new > > Event("selectedIndexChanged")); > > > + if (_selectedIndex != oldIndex) { > > > + dispatchChange("selectionChanged"); > > > + } > > > + > > > } > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ComboBoxModel.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ComboBoxModel.as > > > index 9d3f097..11757f0 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ComboBoxModel.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/ComboBoxModel.as > > > @@ -22,11 +22,11 @@ package > org.apache.royale.jewel.beads.models > > > import org.apache.royale.core.IBead; > > > import org.apache.royale.core.IComboBoxModel; > > > import org.apache.royale.events.Event; > > > - > > > + > > > /** > > > - * The ComboBoxModel class bead extends > > > org.apache.royale.jewel.beads.models.ArrayListSelectionModel > > > + * The ComboBoxModel class bead extends > > > org.apache.royale.jewel.beads.models.ArrayListSelectionModel > > > * and adds the text being displayed by the > > > org.apache.royale.jewel.ComboBox's input field. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -36,7 +36,7 @@ package > org.apache.royale.jewel.beads.models > > > { > > > /** > > > * constructor. > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -47,12 +47,12 @@ package > org.apache.royale.jewel.beads.models > > > } > > > > > > private var _text:String; > > > - > > > + > > > /** > > > * The string to display in the > > > org.apache.royale.html.ComboBox input field. > > > - * > > > + * > > > * @copy > org.apache.royale.core.IComboBoxModel#text > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -62,23 +62,23 @@ package > org.apache.royale.jewel.beads.models > > > { > > > return _text; > > > } > > > - > > > + > > > public function set text(value:String):void > > > { > > > if (value != _text) > > > { > > > _text = value; > > > - dispatchEvent(new > > Event("textChange")); > > > + dispatchChange("textChange"); > > > } > > > } > > > - > > > + > > > private var _html:String; > > > - > > > + > > > /** > > > * The HTML string to display in the > > > org.apache.royale.html.ComboBox input field. > > > - * > > > + * > > > * @copy > org.apache.royale.core.IComboBoxModel#html > > > - * > > > + * > > > * @langversion 3.0 > > > * @playerversion Flash 10.2 > > > * @playerversion AIR 2.6 > > > @@ -88,13 +88,13 @@ package > org.apache.royale.jewel.beads.models > > > { > > > return _html; > > > } > > > - > > > + > > > public function set html(value:String):void > > > { > > > if (value != _html) > > > { > > > _html = value; > > > - dispatchEvent(new > > Event("htmlChange")); > > > + dispatchChange("htmlChange"); > > > } > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IDropDownListModel.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IDropDownListModel.as > > > index 43c75b3..eec3c8d 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IDropDownListModel.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IDropDownListModel.as > > > @@ -30,6 +30,5 @@ package > org.apache.royale.jewel.beads.models > > > { > > > > > > function get offset():int; > > > - function > > setProcessingInteractiveChange(value:Boolean):void; > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IJewelSelectionModel.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IJewelSelectionModel.as > > > index 62903df..9a0cadd 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IJewelSelectionModel.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/models/IJewelSelectionModel.as > > > @@ -20,6 +20,7 @@ package > org.apache.royale.jewel.beads.models > > > { > > > > > > import org.apache.royale.core.ISelectionModel; > > > + import org.apache.royale.events.IEventDispatcher > > > > > > /** > > > * The IJewelSelectionModel interface is a simple > > extension to > > > core ISelectionModel > > > @@ -31,6 +32,6 @@ package > org.apache.royale.jewel.beads.models > > > */ > > > public interface IJewelSelectionModel extends > > ISelectionModel > > > { > > > - function set > > > dispatchChangeOnDataProviderChange(value:Boolean):void > > > + function set > dispatcher(value:IEventDispatcher):void; > > > } > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as > > > index cb029ea..b54e12b 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as > > > @@ -18,7 +18,9 @@ > > > > > > > > > //////////////////////////////////////////////////////////////////////////////// > > > package org.apache.royale.jewel.beads.views > > > { > > > - COMPILE::SWF > > > +import > > org.apache.royale.jewel.beads.models.IJewelSelectionModel; > > > + > > > +COMPILE::SWF > > > { > > > import flash.utils.setTimeout; > > > } > > > @@ -138,8 +140,14 @@ package > org.apache.royale.jewel.beads.views > > > host.addElement(_button); > > > > > > model = > > _strand.getBeadByType(IComboBoxModel) as > > > IComboBoxModel; > > > - > > model.addEventListener("selectedIndexChanged", > > > handleItemChange); > > > - > model.addEventListener("selectedItemChanged", > > > handleItemChange); > > > + > > > + if (model is IJewelSelectionModel) { > > > + //do this here as well as in > the > > > controller, > > > + //to cover possible variation > in the > > order > > > of bead instantiation > > > + //this avoids the need to > redispatch > > new > > > event clones at the component level in the controller > > > + IJewelSelectionModel(model).dispatcher = > > > IEventDispatcher(value); > > > + } > > > + > model.addEventListener("selectionChanged", > > > handleItemChange); > > > > model.addEventListener("dataProviderChanged", > > > itemChangeAction); > > > > > > > > > IEventDispatcher(_strand).addEventListener("sizeChanged", > > handleSizeChange); > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/DropDownListView.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/DropDownListView.as > > > index 36cd549..a43aba0 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/DropDownListView.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/DropDownListView.as > > > @@ -101,7 +101,7 @@ COMPILE::JS > > > override protected function > > > handleInitComplete(event:Event):void > > > { > > > model = > > _strand.getBeadByType(ISelectionModel) as > > > ISelectionModel; > > > - > > model.addEventListener("selectedIndexChanged", > > > selectionChangeHandler); > > > + > model.addEventListener("selectionChanged", > > > selectionChangeHandler); > > > > > > super.handleInitComplete(event); > > > } > > > diff --git > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as > > > index 3f6ab5d..e64912d 100644 > > > --- > > > > > > a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as > > > +++ > > > > > > b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as > > > @@ -89,7 +89,7 @@ package > org.apache.royale.jewel.beads.views > > > override protected function > > > handleInitComplete(event:Event):void > > > { > > > listModel = > > _strand.getBeadByType(ISelectionModel) > > > as ISelectionModel; > > > - > > listModel.addEventListener("selectedIndexChanged", > > > selectionChangeHandler); > > > + > > listModel.addEventListener("selectionChanged", > > > selectionChangeHandler); > > > > > listModel.addEventListener("rollOverIndexChanged", > > > rollOverIndexChangeHandler); > > > > > > IEventDispatcher(_strand).addEventListener("itemsCreated", > > > itemsCreatedHandler); > > > > > > @@ -187,7 +187,7 @@ package > org.apache.royale.jewel.beads.views > > > super.handleInitComplete(event); > > > > > > listModel = > > _strand.getBeadByType(ISelectionModel) > > > as ISelectionModel; > > > - > > listModel.addEventListener("selectedIndexChanged", > > > selectionChangeHandler); > > > + > > listModel.addEventListener("selectionChanged", > > > selectionChangeHandler); > > > > > listModel.addEventListener("rollOverIndexChanged", > > > rollOverIndexChangeHandler); > > > } > > > > > > @@ -220,7 +220,7 @@ package > org.apache.royale.jewel.beads.views > > > ir = > > > > dataGroup.getItemRendererAt(IRollOverModel(listModel).rollOverIndex) > > as > > > ISelectableItemRenderer; > > > if(ir) > > > ir.hovered = true; > > > - > > > + > > > lastRollOverIndex = > > > IRollOverModel(listModel).rollOverIndex; > > > } > > > } > > > > > > > > > > > > > > > > > > > > >
