* Design for multiselect listbox 4.x-dev

Mon, 19 Oct 2020 21:20:35 +0300

author
cemkalyoncu
date
Mon, 19 Oct 2020 21:20:35 +0300
branch
4.x-dev
changeset 1468
e92d177503af
parent 1467
95953026a195
child 1469
5c0962155ba0

* Design for multiselect listbox

Source/Gorgon/Widgets/Listbox.h file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/Widgets/Listbox.h	Mon Oct 19 10:57:40 2020 +0300
+++ b/Source/Gorgon/Widgets/Listbox.h	Mon Oct 19 21:20:35 2020 +0300
@@ -403,6 +403,148 @@
             W_ *selected = nullptr;
         };
         
+        //This class allows single selection. The selected item will
+        //follow the focus by default. If desired, this can be changed
+        template<class T_, class W_, class F_>
+        class LBSELTR_Multi {
+        public:
+            
+            /*
+            ClearSelection
+            SetSelection(...)
+            AddToSelection(...)
+            IsSelected
+            GetSelectionCount
+            Selection -> subclass allows for(auto item : list.Selection)
+            SelectedIndexes -> subclass allows for(auto index : list.SelectedIndexes)
+            RemoveFromSelection
+            SelectionStrategy(Click toggles/Ctrl select)
+            SelectAll
+            */
+            
+            
+            Event<LBSELTR_Multi, long> ChangedEvent = Event<LBSELTR_Multi, long, bool>{this};
+            
+        protected:
+            LBSELTR_Multi() {
+            }
+            
+            virtual ~LBSELTR_Multi() { }
+            
+            void sel_clicked(long index, W_ &w) {
+                if(focusindex == index)
+                    return;
+                
+                if(dynamic_cast<UI::Widget*>(this)->IsFocused())
+                    w.Focus();
+                
+                focusindex = index;
+                
+                dynamic_cast<UI::Widget*>(this)->Focus();
+            }
+            
+            void sel_toggled(long index, W_ &w) {
+                /*if(selectedindex == index || focusonly)
+                    return;
+                
+                if(selected)
+                    selected->SetSelected(false);
+                
+                w.SetSelected(true);
+                selectedindex = index;
+                selected = &w;
+                
+                ChangedEvent(index);*/
+            }
+            
+            void sel_apply(long index, W_ &w, const T_ &) {
+                if(index == focusindex) {
+                    w.Focus();
+                }
+                else if(w.IsFocused()) {
+                    w.Defocus();
+                }
+                
+                /*if(index == selectedindex) {
+                    w.SetSelected(true);
+                    selected = &w;
+                }
+                else {
+                    w.SetSelected(false);
+                    
+                    if(&w == selected)
+                        selected = nullptr;
+                }*/
+            }
+            
+            void sel_prepare(W_ &w) {
+                w.ClickEvent.Register([&w, this] {
+                    sel_clicked(dynamic_cast<F_*>(this)->getindex(w), w);
+                });
+                w.ToggleEvent.Register([&w, this] {
+                    sel_toggled(dynamic_cast<F_*>(this)->getindex(w), w);
+                });
+            }
+            
+            void sel_insert(long index, long count) { 
+                if(index <= focusindex)
+                    focusindex += count;
+                
+                //update selection
+            }
+            
+            void sel_move(long index, long target) { 
+                //move triggers apply to both indexes
+                
+                if(index == focusindex) {
+                    focusindex = target;
+                }
+                else if(index > focusindex && target <= focusindex) {
+                    focusindex++;
+                }
+                else if(index < focusindex && target > focusindex) {
+                    focusindex--;
+                }
+                
+                //update selection
+            }
+            
+            void sel_remove(long index, long count) { 
+                //removed items will be repurposed using apply,
+                if(index <= focusindex) {
+                    if(index+count > focusindex) {
+                        focusindex = -1;
+                        ChangedEvent(-1);
+                    }
+                    else {
+                        focusindex -= count;
+                    }
+                }
+                
+                //update selection
+            }
+            
+            void sel_destroy(W_ &w) {
+                //update selection
+                
+                if(w.IsFocused()) {
+                    focusindex = -1;
+                    w.RemoveFocus();
+                }
+            }
+            
+            void reapplyfocus() {
+                if(focusindex != -1) {
+                    auto w = dynamic_cast<F_*>(this)->getrepresentation(focusindex);
+                    if(w)
+                        w->Focus();
+                }
+            }
+            
+            long focusindex = -1;
+            std::set<long> selected;
+        };
+        
         template<class T_, class W_, class S_, class F_>
         class LBSTR_STLVector {
         public:
@@ -758,12 +900,10 @@
             Refresh();
         }
         
-        
-        /// Scrolls the contents an additional amount.
+        /// Scrolls the contents an additional amount of items.
         void ScrollBy(float y) {
             ScrollTo(ScrollOffset() + y);
         }
-
         
         /// Returns the current scroll offset.
         float ScrollOffset() const {
@@ -1018,6 +1158,12 @@
             return false;
         }
         
+        SimpleListbox &operator =(const T_ value) {
+            this->SetSelection(value);
+            
+            return *this;
+        }
+        
         using Base::ComponentStackWidget::Widget::Remove;
         using internal::LBSTR_STLVector<T_, ListItem, std::vector<T_>, SimpleListbox<T_>>::Remove;
     };

mercurial