/** * * Called whenever we need to change the highlighted selection while the dropDown is open * ComboBox overrides this behavior */ internal virtual void ChangeHighlightedSelection(int newIndex, bool scrollToTop = false) { // Store the selection in userProposedSelectedIndex because we // don't want to update selectedIndex until the dropdown closes ItemSelected(UserProposedSelectedIndex, false); UserProposedSelectedIndex = newIndex; ItemSelected(UserProposedSelectedIndex, true); float?topOffset = null; if (scrollToTop) { topOffset = 0f; } PositionIndexInView(UserProposedSelectedIndex, topOffset); IndexChangeEvent e = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE) { OldIndex = CaretIndex }; SetCurrentCaretIndex(UserProposedSelectedIndex); e.NewIndex = CaretIndex; DispatchEvent(e); }
/** * */ private void DispatchChangeEvent(int oldIndex, int newIndex) { var e = new IndexChangeEvent(Event.CHANGE) { OldIndex = oldIndex, NewIndex = newIndex, RelatedObject = GetChildAt(newIndex) }; DispatchEvent(e); }
public void SelectedIndexChangedTest(Event e) { IndexChangeEvent ice = (IndexChangeEvent)e; Debug.Log(string.Format("OldIndex: {0}, NewIndex: {1}", ice.OldIndex, ice.NewIndex)); }
/** * * Called whenever we need to change the highlighted selection while the dropDown is open * ComboBox overrides this behavior */ internal virtual void ChangeHighlightedSelection(int newIndex, bool scrollToTop = false) { // Store the selection in userProposedSelectedIndex because we // don't want to update selectedIndex until the dropdown closes ItemSelected(UserProposedSelectedIndex, false); UserProposedSelectedIndex = newIndex; ItemSelected(UserProposedSelectedIndex, true); float? topOffset = null; if (scrollToTop) topOffset = 0f; PositionIndexInView(UserProposedSelectedIndex, topOffset); IndexChangeEvent e = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE) {OldIndex = CaretIndex}; SetCurrentCaretIndex(UserProposedSelectedIndex); e.NewIndex = CaretIndex; DispatchEvent(e); }
/** * * The selection validation and commitment workhorse method. * Called to commit the pending selected index. This method dispatches * the "changing" event, and if the event is not cancelled, * commits the selection change and then dispatches the "change" * event. * * Returns true if the selection was committed, or false if the selection * was cancelled. */ protected virtual bool CommitSelection(bool dispatchChangedEvents /* = true*/) { // Step 1: make sure the proposed selected index is in range. var maxIndex = null != DataProvider ? DataProvider.Length - 1 : -1; var oldSelectedIndex = _selectedIndex; var oldCaretIndex = _caretIndex; IndexChangeEvent e; if (!AllowCustomSelectedItem || ProposedSelectedIndex != CUSTOM_SELECTED_ITEM) { if (ProposedSelectedIndex < NO_SELECTION) { ProposedSelectedIndex = NO_SELECTION; } if (ProposedSelectedIndex > maxIndex) { ProposedSelectedIndex = maxIndex; } if (_requireSelection && ProposedSelectedIndex == NO_SELECTION && null != DataProvider && DataProvider.Length > 0) { ProposedSelectedIndex = NO_PROPOSED_SELECTION; return(false); } } // Step 2: dispatch the "changing" event. If preventDefault() is called // on this event, the selection change will be cancelled. if (DispatchChangeAfterSelection) { e = new IndexChangeEvent(IndexChangeEvent.CHANGING, false, true) { OldIndex = _selectedIndex, NewIndex = ProposedSelectedIndex }; //if (!DispatchEvent(e)) if (e.DefaultPrevented) { // The event was cancelled. Cancel the selection change and return. ProposedSelectedIndex = NO_PROPOSED_SELECTION; return(false); } } // Step 3: commit the selection change and caret change _selectedIndex = ProposedSelectedIndex; ProposedSelectedIndex = NO_PROPOSED_SELECTION; if (oldSelectedIndex != NO_SELECTION) { ItemSelected(oldSelectedIndex, false); } if (_selectedIndex != NO_SELECTION && _selectedIndex != CUSTOM_SELECTED_ITEM) { ItemSelected(_selectedIndex, true); } SetCurrentCaretIndex(_selectedIndex); // Step 4: dispatch the "change" event and "caretChange" // events based on the dispatchChangeEvents parameter. Overrides may // chose to dispatch the change/caretChange events // themselves, in which case we wouldn't want to dispatch the event // here. if (dispatchChangedEvents) { // Dispatch the change event if (DispatchChangeAfterSelection) { e = new IndexChangeEvent(IndexChangeEvent.CHANGE) { OldIndex = oldSelectedIndex, NewIndex = _selectedIndex }; DispatchEvent(e); DispatchChangeAfterSelection = false; } else { DispatchEvent(new FrameworkEvent(FrameworkEvent.VALUE_COMMIT)); } //Dispatch the caretChange event e = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE) { OldIndex = oldCaretIndex, NewIndex = _caretIndex }; DispatchEvent(e); } return(true); }
protected override void CommitProperties() { IndexChangeEvent e; bool changedSelection = false; base.CommitProperties(); if (_dataProviderChanged) { _dataProviderChanged = false; DoingWholesaleChanges = false; if (_selectedIndex >= 0 && null != DataProvider && _selectedIndex < DataProvider.Length) { ItemSelected(_selectedIndex, true); } else if (_requireSelection) { ProposedSelectedIndex = 0; } else { SetSelectedIndex(-1, false); } } if (_requireSelectionChanged) { _requireSelectionChanged = false; if (_requireSelection && SelectedIndex == NO_SELECTION && null != DataProvider && DataProvider.Length > 0) { // Set the proposed selected index here to make sure // CommitSelection() is called below. ProposedSelectedIndex = 0; } } if (null != PendingSelectedItem) { if (null != DataProvider) { ProposedSelectedIndex = DataProvider.GetItemIndex(PendingSelectedItem); } if (AllowCustomSelectedItem && ProposedSelectedIndex == -1) { ProposedSelectedIndex = CUSTOM_SELECTED_ITEM; _selectedItem = PendingSelectedItem; } PendingSelectedItem = null; } if (ProposedSelectedIndex != NO_PROPOSED_SELECTION) { changedSelection = CommitSelection(true); } // If the selectedIndex has been adjusted to account for items that // have been added or removed, send out a "change" event // so any bindings to selectedIndex are updated correctly. if (SelectedIndexAdjusted) { SelectedIndexAdjusted = false; if (!changedSelection) { DispatchEvent(new FrameworkEvent(FrameworkEvent.VALUE_COMMIT)); } } if (CaretIndexAdjusted) { CaretIndexAdjusted = false; if (!changedSelection) { // Put the new caretIndex renderer into the // caret state and dispatch an "caretChange" // event to update any bindings. Additionally, update // the backing variable. ItemShowingCaret(_selectedIndex, true); _caretIndex = _selectedIndex; e = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE); e.OldIndex = _caretIndex; e.NewIndex = _caretIndex; DispatchEvent(e); } } if (_labelFieldOrFunctionChanged) { _labelFieldOrFunctionChanged = false; // Cycle through all instantiated renderers to push the correct text // in to the renderer by setting its label property if (null != DataGroup) { // if virtual layout, only loop through the indices in view // otherwise, loop through all of the item renderers /*if (null != Layout && Layout.UseVirtualLayout) * { * foreach (int itemIndex in DataGroup.GetItemIndicesInView()) * { * UpdateRendererLabelProperty(itemIndex); * } * } * else * {*/ var n = DataGroup.NumberOfContentChildren; for (var itemIndex = 0; itemIndex < n; itemIndex++) { UpdateRendererLabelProperty(itemIndex); } /*}*/ } } }
override protected void CreateChildren() { base.CreateChildren(); #region Controls Toolbar toolbar = new Toolbar(); AddChild(toolbar); Button button = new Button { Text = "Add data", SkinClass = typeof(ImageButtonSkin), Icon = ImageLoader.Instance.Load("Icons/add"), AutoRepeat = true }; button.ButtonDown += delegate { _dataProvider.AddItem("data " + _random.Next(1, 100)); }; toolbar.AddContentChild(button); button = new Button { Text = "Previous tab", SkinClass = typeof(ImageButtonSkin), Icon = ImageLoader.Instance.Load("Icons/previous") }; button.Click += delegate { _buttonBar.SelectedIndex--; _viewstack.Previous(); }; toolbar.AddContentChild(button); button = new Button { Text = "Next tab", SkinClass = typeof(ImageButtonSkin), Icon = ImageLoader.Instance.Load("Icons/next") }; button.Click += delegate { _buttonBar.SelectedIndex++; _viewstack.Next(); }; toolbar.AddContentChild(button); #endregion #region Scroller Scroller scroller = new Scroller { SkinClass = typeof(ScrollerSkin2), PercentWidth = 100, PercentHeight = 100 }; //scroller.SetStyle("horizontalScrollPolicy", ScrollPolicy.On); //scroller.SetStyle("verticalScrollPolicy", ScrollPolicy.On); AddChild(scroller); Group viewport = new Group { MouseEnabled = true, Layout = new VerticalLayout { HorizontalAlign = HorizontalAlign.Left, PaddingLeft = 10, PaddingRight = 10, PaddingTop = 10, PaddingBottom = 10, Gap = 10 } }; scroller.Viewport = viewport; #endregion List <object> source = new List <object> { "Failure", "Teaches", "Success", "One", "Two", "Three", "Four", "Five", "Six" }; _dataProvider = new ArrayList(source); viewport.AddChild(new Label { Text = "ButtonBar:" }); #region Button bar _buttonBar = new ButtonBar { DataProvider = new ArrayList(new List <object> { "List 1", "List 2", "List 3", "List 4", "List 5" }), SkinClass = typeof(ButtonBarSkin2), RequireSelection = true }; _buttonBar.AddEventListener(Event.CHANGE, delegate(Event e) { IndexChangeEvent ice = e as IndexChangeEvent; if (null != ice) { int newIndex = ice.NewIndex; //Debug.Log("Changed to: " + newIndex); _viewstack.SelectedIndex = newIndex; } }); viewport.AddChild(_buttonBar); #endregion #region ViewStack viewport.AddChild(new Label { Text = "ViewStack (having 5 lists as children):" }); _viewstack = new ViewStack { ResizeToContent = true }; viewport.AddChild(_viewstack); #endregion /* Factory is used for creating renderer instances */ var factory = new ItemRendererFactory <DefaultItemRenderer>(); /* LISTS */ #region List 1 List list = new List { Id = "list1", //Layout = new TileLayout { RequestedColumnCount = 4 }, Width = 200, Height = 200, DataProvider = _dataProvider, //ItemRenderer = new ItemRendererFactory <DefaultItemRenderer>(), /* ItemRendererFunction is used for switching between different factories, based on the supplied item */ ItemRendererFunction = delegate { return(factory); } }; _viewstack.AddChild(list); #endregion #region List 2 list = new List { Id = "list2", //Layout = new TileLayout { RequestedColumnCount = 3 }, Width = 200, Height = 245, DataProvider = _dataProvider, //ItemRenderer = new ItemRendererFactory <DefaultItemRenderer>(), ItemRendererFunction = delegate { return(factory); } }; _viewstack.AddChild(list); #endregion #region List 3 list = new List { Id = "list3", Width = 400, Height = 450, DataProvider = _dataProvider, SkinClass = typeof(ListSkin2), ItemRenderer = new ItemRendererFactory <BigItemRenderer>() }; _viewstack.AddChild(list); #endregion #region List 4 list = new List { Id = "list4", Width = 600, Height = 800, Layout = new TileLayout { HorizontalGap = 0, VerticalGap = 0, RequestedRowCount = 4, RequestedColumnCount = 3 }, DataProvider = _dataProvider, SkinClass = typeof(ListSkin2), ItemRenderer = new ItemRendererFactory <BigItemRenderer>() }; _viewstack.AddChild(list); #endregion #region List 5 (horizontal) list = new List { Id = "list5", Width = 800, Height = 100, Layout = new HorizontalLayout { Gap = 0, RequestedColumnCount = 3 }, DataProvider = _dataProvider, SkinClass = typeof(ListSkin2), ItemRenderer = new ItemRendererFactory <BigItemRenderer>() }; _viewstack.AddChild(list); #endregion #region Process renderer click AddEventListener(BigItemRenderer.ADD_BUTTON_CLICKED, delegate(Event e) { IItemRenderer itemRenderer = (IItemRenderer)e.Target; Alert.Show("Info", itemRenderer.Data.ToString(), AlertButtonFlag.Ok, new AlertOption(AlertOptionType.HeaderIcon, ImageLoader.Instance.Load("Icons/information"))); }); #endregion }
protected override bool CommitSelection(bool dispatchChangedEvents/* = true*/) { // Clear the flag so that we don't commit the selection again. _multipleSelectionChanged = false; var oldSelectedIndex = SelectedIndex; var oldCaretIndex = CaretIndex; _proposedSelectedIndices = _proposedSelectedIndices.FindAll(delegate (int index) { return (null != DataProvider) && (index >= 0) && (index < DataProvider.Length); }); // Ensure that multiple selection is allowed and that proposed // selected indices honors it. For example, in the single // selection case, proposedSelectedIndices should only be a // vector of 1 entry. If its not, we pare it down and select the // first item. if (!AllowMultipleSelection && !IsEmpty(_proposedSelectedIndices)) { var temp = new List<int> {_proposedSelectedIndices[0]}; _proposedSelectedIndices = temp; } // Keep ProposedSelectedIndex in-sync with multiple selection properties. if (!IsEmpty(_proposedSelectedIndices)) ProposedSelectedIndex = GetFirstItemValue(_proposedSelectedIndices); // Let ListBase handle the validating and commiting of the single-selection // properties. var retVal = base.CommitSelection(false); // If super.commitSelection returns a value of false, // the selection was cancelled, so return false and exit. if (!retVal) return false; // Now keep _proposedSelectedIndices in-sync with single selection // properties now that the single selection properties have been // comitted. if (SelectedIndex > NO_SELECTION) { if (null != _proposedSelectedIndices && _proposedSelectedIndices.IndexOf(SelectedIndex) == -1) _proposedSelectedIndices.Add(SelectedIndex); } // Validate and commit the multiple selection related properties. CommitMultipleSelection(); // Set the caretIndex based on the current selection SetCurrentCaretIndex(SelectedIndex); // And dispatch change and caretChange events so that all of // the bindings update correctly. if (dispatchChangedEvents && null != retVal) { IndexChangeEvent e; if (DispatchChangeAfterSelection) { e = new IndexChangeEvent(IndexChangeEvent.CHANGE) { OldIndex = oldSelectedIndex, NewIndex = SelectedIndex }; DispatchEvent(e); DispatchChangeAfterSelection = false; } else { DispatchEvent(new FrameworkEvent(FrameworkEvent.VALUE_COMMIT)); } e = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE) { OldIndex = oldCaretIndex, NewIndex = CaretIndex }; DispatchEvent(e); } return retVal; }
// ReSharper disable MemberCanBePrivate.Global protected void AdjustSelectionAndCaretUponNavigation(Event e) // ReSharper restore MemberCanBePrivate.Global { //Debug.Log("AdjustSelectionAndCaretUponNavigation"); KeyboardEvent ke = (KeyboardEvent) e; // Some unrecognized key stroke was entered, return. if (!NavigationUnitUtil.IsNavigationUnit(ke.KeyCode)) return; NavigationUnit navigationUnit = NavigationUnitUtil.GetNavigationUnit(ke.KeyCode); //Debug.Log("navigationUnit:" + navigationUnit); //Debug.Log("CaretIndex:" + CaretIndex); var proposedNewIndex = Layout.GetNavigationDestinationIndex(CaretIndex, navigationUnit, ArrowKeysWrapFocus); //Debug.Log("proposedNewIndex:" + proposedNewIndex); // Note that the KeyboardEvent is canceled even if the current selected or in focus index // doesn't change because we don't want another component to start handling these // events when the index reaches a limit. if (proposedNewIndex == -1) return; e.PreventDefault(); // Contiguous multi-selection action. Create the new selection // interval. if (_allowMultipleSelection && ke.Shift && null != SelectedIndices) { var startIndex = GetLastSelectedIndex(); var newInterval = new List<int>(); int i; if (startIndex <= proposedNewIndex) { for (i = startIndex; i <= proposedNewIndex; i++) { newInterval.Insert(0, i); } } else { for (i = startIndex; i >= proposedNewIndex; i--) { newInterval.Insert(0, i); } } SetSelectedIndices(newInterval, true); EnsureIndexIsVisible(proposedNewIndex); } // Entering the caret state with the Ctrl key down else if (ke.Control) { var oldCaretIndex = CaretIndex; SetCurrentCaretIndex(proposedNewIndex); var ice = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE) { OldIndex = oldCaretIndex, NewIndex = CaretIndex }; DispatchEvent(ice); EnsureIndexIsVisible(proposedNewIndex); } // Its just a new selection action, select the new index. else { SetSelectedIndex(proposedNewIndex, true); EnsureIndexIsVisible(proposedNewIndex); } }
override protected void AdjustSelection(int index, bool add/*=false*/) { int i; int curr; var newInterval = new List<int>(); IndexChangeEvent e; if (SelectedIndex == NO_SELECTION || DoingWholesaleChanges) { // The case where one item has been newly added and it needs to be // selected and careted because requireSelection is true. if (null != DataProvider && DataProvider.Length == 1 && RequireSelection) { newInterval.Add(0); _selectedIndices = newInterval; SelectedIndex = 0; ItemShowingCaret(0, true); // If the selection properties have been adjusted to account for items that // have been added or removed, send out a "valueCommit" event and // "caretChange" event so any bindings to them are updated correctly. DispatchEvent(new FrameworkEvent(FrameworkEvent.VALUE_COMMIT)); e = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE) {OldIndex = -1, NewIndex = CaretIndex}; DispatchEvent(e); } return; } // Ensure multiple and single selection are in-sync before adjusting // selection. Sometimes if selection has been changed before adding/removing // an item, we may not have handled selection via invalidation, so in those // cases, force a call to commitSelection() to validate and commit the selection. if ((null == SelectedIndices && SelectedIndex > NO_SELECTION) || (SelectedIndex > NO_SELECTION && null != SelectedIndices && SelectedIndices.IndexOf(SelectedIndex) == -1)) { CommitSelection(true); } // Handle the add or remove and adjust selection accordingly. if (add) { if (null != SelectedIndices) { for (i = 0; i < SelectedIndices.Count; i++) { curr = SelectedIndices[i]; // Adding an item above one of the selected items, // bump the selected item up. if (curr >= index) newInterval.Add(curr + 1); else newInterval.Add(curr); } } } else { // Quick check to see if we're removing the only selected item // in which case we need to honor requireSelection. if (null != SelectedIndices && !IsEmpty(SelectedIndices) && SelectedIndices.Count == 1 && index == SelectedIndex && RequireSelection) { //Removing the last item if (DataProvider.Length == 0) { newInterval = new List<int>(); } else if (index == 0) { // We can't just set selectedIndex to 0 directly // since the previous value was 0 and the new value is // 0, so the setter will return early. ProposedSelectedIndex = 0; InvalidateProperties(); return; } else { newInterval.Add(0); } } else if (null != SelectedIndices) { for (i = 0; i < SelectedIndices.Count; i++) { curr = SelectedIndices[i]; // Removing an item above one of the selected items, // bump the selected item down. if (curr > index) newInterval.Add(curr - 1); else if (curr < index) newInterval.Add(curr); } } } if (CaretIndex == SelectedIndex) { var oldIndex = CaretIndex; CaretIndex = GetFirstItemValue(newInterval); e = new IndexChangeEvent(IndexChangeEvent.CARET_CHANGE) {OldIndex = oldIndex, NewIndex = CaretIndex}; DispatchEvent(e); } else { ItemShowingCaret(CaretIndex, false); CaretIndexAdjusted = true; InvalidateProperties(); } var oldIndices = SelectedIndices; _selectedIndices = newInterval; SelectedIndex = GetFirstItemValue(newInterval); if (_selectedIndices != oldIndices) { SelectedIndexAdjusted = true; InvalidateProperties(); } }