#139: Keyboard handling 4.x-dev

Sat, 31 Oct 2020 16:15:47 +0200

author
cemkalyoncu
date
Sat, 31 Oct 2020 16:15:47 +0200
branch
4.x-dev
changeset 1476
e9317f02166d
parent 1475
e829b6db7a5d
child 1477
06d418851b00

#139: Keyboard handling

Source/Gorgon/Time.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Listbox.h file | annotate | diff | comparison | revisions
Testing/Source/Manual/UI_Generate.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/Time.h	Fri Oct 30 20:44:22 2020 +0200
+++ b/Source/Gorgon/Time.h	Sat Oct 31 16:15:47 2020 +0200
@@ -225,7 +225,7 @@
 		};
 		
         /// Output stream operator overload 
-        std::ostream &operator << (std::ostream &out, const Date &date) {
+        inline std::ostream &operator << (std::ostream &out, const Date &date) {
             if(timezone)
                 out<<date.ISODateTime(timezone);
             else
--- a/Source/Gorgon/Widgets/Listbox.h	Fri Oct 30 20:44:22 2020 +0200
+++ b/Source/Gorgon/Widgets/Listbox.h	Sat Oct 31 16:15:47 2020 +0200
@@ -170,11 +170,44 @@
                     
                     if(elm)
                         elm->SetSelected(true);
+                    
+                    selected = elm;
                 }
                 
                 selectedindex = index;
                 ChangedEvent(selectedindex);
             }
+
+            /// Sets the index of the focused element. If set to -1, nothing is
+            /// focused
+            void SetFocusIndex(long value) {
+                if(focusindex == value)
+                    return;
+                
+                if(focusonly) {
+                    SetSelectedIndex(value);
+                    return;
+                }
+                
+                if(value != -1) {
+                    auto w = dynamic_cast<F_*>(this)->getrepresentation(value);
+                    if(w)
+                        w->Focus();
+                }
+                else {
+                    auto w = dynamic_cast<F_*>(this)->getrepresentation(focusindex);
+                    if(w)
+                        w->Defocus();
+                }
+                
+                focusindex = value;
+            }
+            
+            /// Returns the index of the focused element. If nothing is focused,
+            /// returns -1.
+            long GetFocusIndex() const {
+                return focusindex;
+            }
             
             void RemoveSelection() {
                 SetSelectedIndex(-1);
@@ -469,7 +502,7 @@
                 }
 
             protected:
-                ItemIterator_(F1_ &list, const std::vector<long> &inds, long offset = 0): list(&list), inds(&inds), offset(offset) {
+                ItemIterator_(F1_ &list, const std::vector<long> &inds, long offset = 0): list(&list), offset(offset), inds(&inds) {
                 }
 
                 /// Satisfies the needs of Iterator
@@ -582,6 +615,32 @@
                 return event;
             }
             
+            /// Returns the index of the focused element. If nothing is focused,
+            /// returns -1.
+            long GetFocusIndex() const {
+                return focusindex;
+            }
+            
+            /// Sets the index of the focused element. If set to -1, nothing is
+            /// focused
+            void SetFocusIndex(long value) {
+                if(focusindex == value)
+                    return;
+                
+                if(value != -1) {
+                    auto w = dynamic_cast<F_*>(this)->getrepresentation(value);
+                    if(w)
+                        w->Focus();
+                }
+                else {
+                    auto w = dynamic_cast<F_*>(this)->getrepresentation(focusindex);
+                    if(w)
+                        w->Defocus();
+                }
+                
+                focusindex = value;
+            }
+            
             /// Removes all items from the selection
             void ClearSelection() {
                 if(event == Once) {
@@ -788,8 +847,8 @@
                 dynamic_cast<UI::Widget*>(this)->Focus();
             }
             
-            void sel_toggled(long index, W_ &w) {
-                if(method == Toggle) {
+            void sel_toggled(long index, W_ &w, bool forcetoggle = true) {
+                if(method == Toggle || forcetoggle) {
                     auto item = std::lower_bound(selected.begin(), selected.end(), index);
                     
                     if(item != selected.end() && *item == index) {
@@ -849,7 +908,7 @@
                     sel_clicked(dynamic_cast<F_*>(this)->getindex(w), w);
                 });
                 w.ToggleEvent.Register([&w, this] {
-                    sel_toggled(dynamic_cast<F_*>(this)->getindex(w), w);
+                    sel_toggled(dynamic_cast<F_*>(this)->getindex(w), w, false);
                 });
             }
             
@@ -1297,6 +1356,7 @@
                     maxdisplay = b.Height() / (float(totalh) / c);
                 
                 scroller->Range = maxdisplay;
+                scroller->LargeChange = maxdisplay * 0.8f;
             }
         }
         
@@ -1439,7 +1499,19 @@
                 EnsureVisible(index);
         }
         
-        bool KeyEvent(Input::Key key, float amout) override {
+        bool KeyEvent(Input::Key key, float state) override {
+            namespace Keycodes = Input::Keyboard::Keycodes;
+            
+            if(repeater.KeyEvent(key, state))
+                return true;
+            
+            if(key == Keycodes::Space && contents.HasFocusedWidget() && state != 0) {
+                auto w = dynamic_cast<W_*>(&contents.GetFocus());
+                if(w) {
+                    this->sel_toggled(indexes.count(w) ? indexes[w] : -1, *w);
+                }
+            }
+
             return false;
         }
         
@@ -1472,6 +1544,49 @@
             
             contents.SetLayer(stack.GetLayerOf(stack.IndexOfTag(UI::ComponentTemplate::ContentsTag)));
             stack.AddCondition(UI::ComponentCondition::VScroll);
+            
+            repeater.Register(Input::Keyboard::Keycodes::Up);
+            repeater.Register(Input::Keyboard::Keycodes::Down);
+            repeater.Register(Input::Keyboard::Keycodes::PageUp);
+            repeater.Register(Input::Keyboard::Keycodes::PageDown);
+            
+            
+            repeater.Repeat.Register([this](Input::Key key) {
+                namespace Keycodes = Input::Keyboard::Keycodes;
+                using Input::Keyboard::Modifier;
+                
+                long org = this->GetFocusIndex();
+                long ind = org;
+                
+                switch(key) {
+                case Keycodes::Down:
+                    ind++;
+                    break;
+                    
+                case Keycodes::Up:
+                    ind--;
+                    break;
+                    
+                case Keycodes::PageDown:
+                    ind += long(floor(maxdisplay));
+                    break;
+                    
+                case Keycodes::PageUp:
+                    ind -= long(floor(maxdisplay));
+                    break;
+                }
+                
+                if(ind < 0)
+                    ind = 0;
+                if(ind >= this->GetCount())
+                    ind = this->GetCount() - 1;
+                
+                if(ind != org) {
+                    this->SetFocusIndex(ind);
+                    EnsureVisible(ind);
+                }
+
+            });
         }
         
         ~ListboxBase() {
@@ -1592,6 +1707,8 @@
         int scrolldist  = 5;
         bool isscrolling = false;
         float maxdisplay = 0; //maximum elements that can be displayed
+        
+        Input::KeyRepeater repeater;
     };
     
     /**
--- a/Testing/Source/Manual/UI_Generate.cpp	Fri Oct 30 20:44:22 2020 +0200
+++ b/Testing/Source/Manual/UI_Generate.cpp	Sat Oct 31 16:15:47 2020 +0200
@@ -165,27 +165,28 @@
         std::cout << "size f changed " << sizef.GetText();
     });
     
-    Widgets::MultiListbox<std::string> list;
-    list.SetSelectionMethod(list.UseCtrl);
-    list.SetEventMethod(list.Once);
+    Widgets::SimpleListbox<std::string> list;
+    /*list.SetSelectionMethod(list.UseCtrl);
+    list.SetEventMethod(list.Once);*/
+    list.SetSelectionFollowsFocus(false);
     list.Add("5");
     list.Add("Âj");
     list.Add("9");
     list.Add("Hello", "World", "You", "are", "welcome", "to", "use", "the", "Gorgon", "Library");
-    list.AddToSelection(3);
-    list.AddToSelection(1, 4);
+    //list.AddToSelection(3);
+    //list.AddToSelection(1, 4);
     list.Insert(2, "!");
     list.Remove(2);
     list.MoveBefore(2, 5);
     list.SetOverscroll(2);
-    list.InvertSelection();
-    list.ChangedEvent.Register([&list](long index, bool state) {
+    //list.InvertSelection();
+    /*list.ChangedEvent.Register([&list](long index, bool state) {
         const auto &l = list;
         for(auto s : l.Selection)
             std::cout<<s<<std::endl;
 
         std::cout<<index<<": "<<(state ? "true" : "false")<<std::endl;
-    });
+    });*/
     list.EnsureVisible(11);
     list.EnsureVisible(1);
     

mercurial