#134 Layer extender request 4.x-dev

Tue, 10 Nov 2020 07:35:14 +0200

author
cemkalyoncu
date
Tue, 10 Nov 2020 07:35:14 +0200
branch
4.x-dev
changeset 1484
6a0de0bd14ad
parent 1483
4dbbdae925b4
child 1485
8a2a17aa0f93

#134 Layer extender request

Source/Gorgon/Layer.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/LayerAdapter.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/LayerAdapter.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Widget.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/WidgetContainer.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Window.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/dir.cmake file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Composer.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Composer.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Dropdown.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Listbox.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Panel.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Panel.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/RadioButtons.h file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/Layer.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Layer.h	Tue Nov 10 07:35:14 2020 +0200
@@ -229,11 +229,24 @@
 			return *parent;
 		}
 
-		const Layer &GetTopLevel() const {
-			if(!parent) return *this;
+		/// Returns the top level layer that contains this layer.
+		Layer &GetTopLevel() const {
+			if(!parent) 
+                return const_cast<Layer &>(*this);
 
 			return parent->GetTopLevel();
 		}
+		
+		/// Translates the given location to the top level
+		virtual Geometry::Point TranslateToTopLevel(Geometry::Point location = {0, 0}) const {
+            const Layer *cur = this;
+            while(cur->HasParent()) {
+                location += cur->GetLocation();
+                cur = &cur->GetParent();
+            }
+            
+            return location;
+        }
 
 		Layer &GetTopLevel() {
 			if(!parent) return *this;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Gorgon/UI/LayerAdapter.cpp	Tue Nov 10 07:35:14 2020 +0200
@@ -0,0 +1,16 @@
+#include "LayerAdapter.h"
+#include "Window.h"
+
+
+namespace Gorgon { namespace UI {
+
+    ExtenderRequestResponse LayerAdapter::RequestExtender(const Layer &self) {
+        auto toplevel = dynamic_cast<Window *>(&self.GetTopLevel());
+
+        if(toplevel)
+            return toplevel->RequestExtender(self);
+        else
+            return {false, this, self.GetLocation()};
+    }
+
+} }
--- a/Source/Gorgon/UI/LayerAdapter.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/UI/LayerAdapter.h	Tue Nov 10 07:35:14 2020 +0200
@@ -52,6 +52,8 @@
             return *base;
         }
         
+        virtual ExtenderRequestResponse RequestExtender(const Gorgon::Layer &self) override;
+        
     protected:
         virtual Gorgon::Layer &getlayer() override {
             return *base;
--- a/Source/Gorgon/UI/Widget.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/UI/Widget.h	Tue Nov 10 07:35:14 2020 +0200
@@ -39,8 +39,6 @@
         
         Widget(Widget &&) = default;
         
-        Widget& operator =(Widget &&) = default;
-        
         virtual ~Widget() { }
         
         /// Moves this widget to the given position.
@@ -144,6 +142,21 @@
         /// Returns the parent of this widget, throws if it does not have
         /// a parent.
         WidgetContainer &GetParent() const;
+        
+        /// Sets floating status of this widget. Floating widgets will not
+        /// be moved or resized by organizers.
+        virtual void SetIsFloating(bool value) {
+            if(floating != value)
+                boundschanged();
+                
+            floating = value;
+        }
+        
+        /// Returns floating status of this widget. Floating widgets will not
+        /// be moved or resized by organizers.
+        bool IsFloating() const {
+            return floating;
+        }
 
         /// This function should be called whenever a key is pressed or released.
         virtual bool KeyEvent(Input::Key, float) { return false; }
@@ -230,6 +243,7 @@
         bool visible = true;
         bool enabled = true;
         bool focus   = false;
+        bool floating= false;
         
         /// Never call this function
         virtual void hide() = 0;
--- a/Source/Gorgon/UI/WidgetContainer.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/UI/WidgetContainer.h	Tue Nov 10 07:35:14 2020 +0200
@@ -9,6 +9,21 @@
 
 namespace Gorgon { namespace UI {
     
+    class WidgetContainer;
+    
+    /// This structure is used to transfer extender request response
+    struct ExtenderRequestResponse {
+        /// If the coordinates are properly translated. This is internally
+        /// used to perform step by step transformation
+        bool Transformed = false;
+        
+        /// If the extender is provided by the request
+        WidgetContainer *Extender = nullptr;
+        
+        /// Coordinates of the given point in the extender container
+        Geometry::Point CoordinatesInExtender = {0, 0};
+    };
+    
     /**
     * This class is the base class for all widget containers.
     * All widgets require a layer to be placed on, to allow
@@ -366,6 +381,8 @@
         /// operating system.
         virtual bool CharacterEvent(Char c) { return distributecharevent(c); }
         
+        /// This function will return a container that will act as an extender.
+        virtual ExtenderRequestResponse RequestExtender(const Gorgon::Layer &self) = 0;
 
     protected:
         /// This container is sorted by the focus order
--- a/Source/Gorgon/UI/Window.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/UI/Window.h	Tue Nov 10 07:35:14 2020 +0200
@@ -100,6 +100,10 @@
             return true;
         }
         
+        virtual ExtenderRequestResponse RequestExtender(const Gorgon::Layer &self) override {
+            return {true, &adapter, self.TranslateToTopLevel()};
+        }
+        
         using WidgetContainer::Add;
         using Gorgon::Window::Add;
         using Gorgon::Window::KeyEvent;
@@ -147,6 +151,7 @@
         Graphics::Layer *layerinit() {
             auto l = new Graphics::Layer;
             Add(l);
+            adapter.SetLayer(*l);
             return l;
         }
 
@@ -158,10 +163,10 @@
             
             Gorgon::Window::added(l);
         }
-        
 
     private:
         bool quiting = false;
+        LayerAdapter adapter;
         Graphics::Layer *extenderlayer = layerinit();
 
         decltype(KeyEvent)::Token inputtoken = keyinit(); //to initialize token after window got constructed
--- a/Source/Gorgon/UI/dir.cmake	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/UI/dir.cmake	Tue Nov 10 07:35:14 2020 +0200
@@ -6,6 +6,7 @@
 	Dimension.h
 	Helpers.h
 	LayerAdapter.h
+	LayerAdapter.cpp
 	Organizers
 	RadioControl.h
 	Template.h
--- a/Source/Gorgon/Widgets/Composer.cpp	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Widgets/Composer.cpp	Tue Nov 10 07:35:14 2020 +0200
@@ -67,4 +67,22 @@
             boundschanged();
     }
 
+
+        UI::ExtenderRequestResponse Composer::RequestExtender(const Layer &self) {
+            if(HasParent()) {
+                auto
+                ans = GetParent().RequestExtender(self);
+
+                if(ans.Extender) {
+                    if(!ans.Transformed)
+                        ans.CoordinatesInExtender += GetLocation();
+
+                    return ans;
+                }
+            }
+
+            return {
+                false, this, self.GetLocation()};
+        }
+
 } }
--- a/Source/Gorgon/Widgets/Composer.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Widgets/Composer.h	Tue Nov 10 07:35:14 2020 +0200
@@ -84,6 +84,9 @@
         /// This function should be called whenever a character is received from
         /// operating system.
         virtual bool CharacterEvent(Char c) override { return distributecharevent(c); }
+        
+        
+        virtual UI::ExtenderRequestResponse RequestExtender(const Gorgon::Layer &self) override;
 
     protected:
         //ensure this object is derived
--- a/Source/Gorgon/Widgets/Dropdown.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Widgets/Dropdown.h	Tue Nov 10 07:35:14 2020 +0200
@@ -130,6 +130,7 @@
             this->list.ChangedEvent.Register([this]() {
                 if(this->list.HasSelectedItem()) {
                     TW_(this->list.GetSelectedItem(), *this);
+                    this->Close();
                 }
                 else {
                     this->SetText("");
@@ -141,7 +142,7 @@
         template <class ...A_>
         explicit SingleSelectionDropdown(const UI::Template &temp, A_&& ... elms) : SingleSelectionDropdown(temp)
         {
-            this->ist.Add(std::forward<A_>(elms)...);
+            this->list.Add(std::forward<A_>(elms)...);
         }
         
         virtual void Refresh() override {
--- a/Source/Gorgon/Widgets/Listbox.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Widgets/Listbox.h	Tue Nov 10 07:35:14 2020 +0200
@@ -1546,6 +1546,8 @@
         virtual long GetCount() const override {
             return this->STR_::getsize();
         }
+        
+        
 
     protected:
         ListboxBase()
@@ -1783,15 +1785,20 @@
             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);
+            if(key == Keycodes::Space) {
+                if(contents.HasFocusedWidget() && state != 0) {
+                    auto w = dynamic_cast<W_*>(&contents.GetFocus());
+                    if(w) {
+                        this->sel_toggled(indexes.count(w) ? indexes[w] : -1, *w);
+                    }
                 }
+                
+                return true;
             }
 
             return false;
         }
+        
     protected:
         ListboxWidgetBase(const UI::Template &temp) : 
             ComponentStackWidget(temp, { 
--- a/Source/Gorgon/Widgets/Panel.cpp	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Widgets/Panel.cpp	Tue Nov 10 07:35:14 2020 +0200
@@ -487,6 +487,26 @@
         
         return hscroller;
     }
-    
+
+
+    UI::ExtenderRequestResponse Panel::RequestExtender(const Layer &self) {
+        if(HasParent()) {
+            auto ans = GetParent().RequestExtender(self);
+
+            if(ans.Extender) {
+                if(!ans.Transformed) {
+                    Geometry::Point offset = stack.TagBounds(UI::ComponentTemplate::ContentsTag).TopLeft();
+                    
+                    ans.CoordinatesInExtender += GetLocation() + offset;
+                }
+
+                return ans;
+            }
+        }
+
+        return {false, this, self.GetLocation()};
+    }
+
+
 } }
 
--- a/Source/Gorgon/Widgets/Panel.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Widgets/Panel.h	Tue Nov 10 07:35:14 2020 +0200
@@ -170,6 +170,8 @@
             return ComponentStackWidget::IsEnabled();
         }
         
+        virtual UI::ExtenderRequestResponse RequestExtender(const Gorgon::Layer &self) override;
+        
     protected:
         virtual bool allowfocus() const override;
         
@@ -233,3 +235,4 @@
     };
     
 } }
+
--- a/Source/Gorgon/Widgets/RadioButtons.h	Sat Nov 07 11:19:23 2020 +0200
+++ b/Source/Gorgon/Widgets/RadioButtons.h	Tue Nov 10 07:35:14 2020 +0200
@@ -17,7 +17,7 @@
      * widget might cause unexpected behavior. All other container functionality should work as intended.
      */
     template<class T_, class W_ = Checkbox>
-    class RadioButtons : public UI::Widget, protected UI::RadioControl<T_, W_>, public UI::WidgetContainer {
+    class RadioButtons : public UI::Widget, protected UI::RadioControl<T_, W_>, protected UI::WidgetContainer {
         friend class UI::WidgetContainer;
     public:
         explicit RadioButtons(const UI::Template &temp) : temp(temp) { 
@@ -311,6 +311,22 @@
             this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
         }
 
+        UI::ExtenderRequestResponse RequestExtender(const Layer &self) override {
+            if(HasParent()) {
+                auto ans = GetParent().RequestExtender(self);
+
+                if(ans.Extender) {
+                    if(!ans.Transformed) {
+                        ans.CoordinatesInExtender += GetLocation();
+                    }
+
+                    return ans;
+                }
+            }
+            
+            return {false, this, self.GetLocation()};
+        }
+
         Geometry::Point location = {0, 0};
         int spacing = 4;
         const UI::Template &temp;

mercurial