//////////////////////////////////////////////////////////////////////////////////////////////////// // NoesisGUI - http://www.noesisengine.com // Copyright (c) 2013 Noesis Technologies S.L. All Rights Reserved. //////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef __GUI_SELECTOR_H__ #define __GUI_SELECTOR_H__ #include #include #include namespace Noesis { class PropertyPath; template class Nullable; struct PathElement; template class UICollection; typedef UICollection SelectedItemsCollection; //////////////////////////////////////////////////////////////////////////////////////////////////// /// Provides data for the Selector.SelectionChanged event. //////////////////////////////////////////////////////////////////////////////////////////////////// struct SelectionChangedEventArgs: public RoutedEventArgs { typedef Vector> ItemList; ItemList addedItems; ItemList removedItems; SelectionChangedEventArgs(BaseComponent* source); }; typedef Delegate SelectionChangedEventHandler; NS_WARNING_PUSH NS_MSVC_WARNING_DISABLE(4251 4275) //////////////////////////////////////////////////////////////////////////////////////////////////// /// Represents a control that allows a user to select items from among its child elements. /// /// Selector is an ItemsControl, which means it can contain a collection of objects of any type /// (such as string, image, or panel). For more information, see the ItemsControl class. /// /// http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.aspx //////////////////////////////////////////////////////////////////////////////////////////////////// class NS_GUI_CORE_API Selector: public ItemsControl { public: Selector(); virtual ~Selector() = 0; /// Gets or sets a value that indicates whether an item is selected //@{ static bool GetIsSelected(DependencyObject* element); static void SetIsSelected(DependencyObject* element, bool value); //@} /// Gets a value that indicates whether the keyboard focus is within the Selector static bool GetIsSelectionActive(UIElement* element); /// Gets or sets a value that indicates whether a Selector should keep the SelectedItem /// synchronized with the current item in the Items property. /// Returns true if the *SelectedItem* is always synchronized with the current item in the /// ItemCollection; false if the *SelectedItem* is never synchronized with the current item; /// or null if the *SelectedItem* is synchronized with the current item only if the Selector /// uses a CollectionView. The default value is null //@{ const Nullable& GetIsSynchronizedWithCurrentItem() const; void SetIsSynchronizedWithCurrentItem(const Nullable& value); //@} /// Gets or sets the index of the first item in the current selection or returns negative one /// (-1) if the selection is empty //@{ int32_t GetSelectedIndex() const; void SetSelectedIndex(int32_t index); //@} /// Gets or sets the first item in the current selection or returns null if the selection is /// empty //@{ Noesis::BaseComponent* GetSelectedItem() const; void SetSelectedItem(Noesis::BaseComponent* item); //@} /// Gets or sets the value of the *SelectedItem*, obtained by using *SelectedValuePath* //@{ Noesis::BaseComponent* GetSelectedValue() const; void SetSelectedValue(Noesis::BaseComponent* selectedValue); //@} /// Gets or sets the path that is used to get the *SelectedValue* from the *SelectedItem* //@{ const char* GetSelectedValuePath() const; void SetSelectedValuePath(const char* selectedValuePath); //@} /// Occurs when the selection of a Selector changes UIElement::RoutedEvent_ SelectionChanged(); public: /// Dependency Properties //@{ static const DependencyProperty* IsSelectedProperty; // Attached static const DependencyProperty* IsSelectionActiveProperty; // Attached static const DependencyProperty* IsSynchronizedWithCurrentItemProperty; static const DependencyProperty* SelectedIndexProperty; static const DependencyProperty* SelectedItemProperty; static const DependencyProperty* SelectedValueProperty; static const DependencyProperty* SelectedValuePathProperty; //@} /// Routed events //@{ static const RoutedEvent* SelectedEvent; // Attached static const RoutedEvent* SelectionChangedEvent; static const RoutedEvent* UnselectedEvent; // Attached //@} protected: // Called when the selection changes virtual void OnSelectionChanged(const SelectionChangedEventArgs& args); /// From ItemsControl //@{ void OnItemsSourceChanged(BaseComponent* oldSource, BaseComponent* newSource) override; void OnCurrentItemChanged() override; void OnItemsChanged(const NotifyCollectionChangedEventArgs& args) override; void OnContainersGenerated() override; void ClearContainerForItemOverride(DependencyObject* container, BaseComponent* item) const override; //@} /// From Control //@{ void OnIsFocusEngagedChanged(bool engaged) override; //@} /// From UIElement //@{ void OnGotFocus(const RoutedEventArgs& e) override; void OnIsKeyboardFocusWithinChanged(const DependencyPropertyChangedEventArgs& e) override; //@} /// From DependencyObject //@{ bool OnPropertyChanged(const DependencyPropertyChangedEventArgs& args) override; //@} SelectedItemsCollection* GetInternalSelectedItems() const; typedef Vector IndicesVector; const IndicesVector& GetInternalSelectedIndices() const; void InternalSelectAll(); void InternalUnselectAll(); void InternalSelectRange(int32_t start, int32_t end); virtual bool IsMultiSelectEnabled() const; protected: static const DependencyProperty* InternalSelectedItemsProperty; enum { IsUpdatingSelection = ItemsControl::LastFlag * 2, IsSynchronizingCurrent = IsUpdatingSelection * 2, IsSelectingItem = IsSynchronizingCurrent * 2, LastFlag = IsSelectingItem }; private: void SynchronizeWithCurrent(int32_t currentIndex); BaseComponent* SelectItem(BaseComponent* selectedValue); void UpdateSelectedValue(BaseComponent* selectedItem); void TryFocusSelected(); void UpdateSingleSelectedList(SelectionChangedEventArgs& e, BaseComponent* selectedItem, int32_t selectedIndex); void UpdateSingleSelectedAndRaiseEvent(const SelectionChangedEventArgs& e, int32_t selectedIndex); void UpdateSingleSelectedAndRaiseEvent(const SelectionChangedEventArgs& e, BaseComponent* selectedItem, int32_t selectedIndex, bool raiseSelectionChanged = true); void OnItemSelected(SelectionChangedEventArgs& e, BaseComponent* item, int32_t index); void OnItemUnselected(SelectionChangedEventArgs& e, BaseComponent* item, int32_t index); void OnSelectedIndexChanged(int32_t oldIndex, int32_t newIndex); void OnSelectedItemChanged(BaseComponent* oldItem, BaseComponent* newItem); void OnSelectedItemsChanged(BaseComponent* sender, const NotifyCollectionChangedEventArgs& e); void OnSelectedItemAdded(SelectionChangedEventArgs& args, BaseComponent* item, int32_t index); void OnSelectedItemRemoved(SelectionChangedEventArgs& args, BaseComponent* item, int32_t index, int32_t& selectedIndex); static bool CoerceSelectedValue(const DependencyObject* object, const void* value, void* coercedValue); private: friend class ListBoxTest; // Used to resolve SelectedValuePath Ptr mPath; // Selected items indices IndicesVector mSelectedIndices; NS_DECLARE_REFLECTION(Selector, ItemsControl) }; NS_WARNING_POP } #include #endif