Merge 4.x-dev

Wed, 04 Mar 2020 03:23:54 +0200

author
Luca Tonini
date
Wed, 04 Mar 2020 03:23:54 +0200
branch
4.x-dev
changeset 1365
afc2f826d120
parent 1364
fb60c0b2561d (current diff)
parent 1363
b98d42b2f8ae (diff)
child 1366
7eea05431e78

Merge

--- a/CMakeLists.txt	Wed Mar 04 03:16:03 2020 +0200
+++ b/CMakeLists.txt	Wed Mar 04 03:23:54 2020 +0200
@@ -152,6 +152,10 @@
 
 add_library(Gorgon STATIC ${All})
 
+if(MSVC)
+	target_compile_options(Gorgon PRIVATE "/MP")
+endif()
+
 set_property(TARGET Gorgon PROPERTY CXX_STANDARD 14)
 
 #if(WIN32)
--- a/Scripts/Compiler.cmake	Wed Mar 04 03:16:03 2020 +0200
+++ b/Scripts/Compiler.cmake	Wed Mar 04 03:23:54 2020 +0200
@@ -9,30 +9,30 @@
 IF(CMAKE_COMPILER_IS_GNUCXX)
 	EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
 	
-	IF(GCC_VERSION VERSION_LESS 4.8)
+	IF(GCC_VERSION VERSION_LESS 5)
 		IF(IGNORE_COMPILER_VERSION)
-			MESSAGE(STATUS "Gorgon Library requires GCC 4.8+")
+			MESSAGE(STATUS "Gorgon Library requires GCC 5+")
 		ELSE()
 			MESSAGE(STATUS "use cmake -DIGNORE_COMPILER_VERSION=ON to continue anyway")
-			MESSAGE(FATAL_ERROR "Gorgon Library requires GCC 4.8+")
+			MESSAGE(FATAL_ERROR "Gorgon Library requires GCC 5+")
 		ENDIF()
 	ENDIF()
 ELSEIF(MSVC)
 	IF(MSVC_VERSION VERSION_LESS 14)
 		IF(IGNORE_COMPILER_VERSION)
-			MESSAGE(STATUS "Gorgon Library requires Visual Studio 2015+")
+			MESSAGE(STATUS "Gorgon Library requires Visual Studio 2017+")
 		ELSE()
 			MESSAGE(STATUS "use cmake -DIGNORE_COMPILER_VERSION=ON to continue anyway")
-			MESSAGE(FATAL_ERROR "Gorgon Library requires Visual Studio 2015+")
+			MESSAGE(FATAL_ERROR "Gorgon Library requires Visual Studio 2017+")
 		ENDIF()
 	ENDIF()
 ELSE()
 	IF(IGNORE_COMPILER_VENDOR)
-		MESSAGE(STATUS "Unsupported compiler! Gorgon Library requires GCC 4.8+ OR Visual Studio 2015+")
+		MESSAGE(STATUS "Unsupported compiler! Gorgon Library requires GCC 4.8+ OR Visual Studio 2017+")
 		MESSAGE(STATUS "You may need to manually activate C++14 features")
 	ELSE()
 		MESSAGE(STATUS "use cmake -DIGNORE_COMPILER_VENDOR=ON to continue anyway")
-		MESSAGE(FATAL_ERROR "Unsupported compiler! Gorgon Library requires GCC 4.8+ OR Visual Studio 2015+")
+		MESSAGE(FATAL_ERROR "Unsupported compiler! Gorgon Library requires GCC 5+ OR Visual Studio 2017+")
 	ENDIF()
 ENDIF()
 
--- a/Source/Gorgon/Animation/Discrete.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Animation/Discrete.h	Wed Mar 04 03:23:54 2020 +0200
@@ -1,9 +1,9 @@
 #pragma once
-
-#include "../Animation.h"
-
-namespace Gorgon { namespace Animation {
-
+
+#include "../Animation.h"
+
+namespace Gorgon { namespace Animation {
+
 	// Represents an instance of a discrete animation made out of frames
 	class DiscreteAnimation : public virtual Base {
 	public:
@@ -19,6 +19,8 @@
 	/// This is the base class for a single frame in a discreet animation
 	class Frame {
 	public:
+        virtual ~Frame() { }
+        
 		/// Returns the duration of this frame
 		virtual unsigned GetDuration() const = 0;
 
@@ -85,4 +87,4 @@
 
 	protected:
 	};
-} }
\ No newline at end of file
+} }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Gorgon/Config.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -0,0 +1,18 @@
+#include "Config.h"
+
+#ifndef GORGON_WINDOWMANAGER_CLICK_THRESHOLD
+#   define GORGON_WINDOWMANAGER_CLICKTHRESHOLD 5
+#endif
+
+namespace Gorgon {
+    
+namespace WindowManager {
+    
+    
+    
+    int ClickThreshold = GORGON_WINDOWMANAGER_CLICKTHRESHOLD;
+    
+    
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Gorgon/Config.h	Wed Mar 04 03:23:54 2020 +0200
@@ -0,0 +1,24 @@
+#pragma once
+
+/** @defgroup config "Gorgon Configuration" 
+ * These variables control the behavior of Gorgon Library. Unless defined as constant they 
+ * can be changed. However, changing configuration on the fly might have unexpected 
+ * consequences. Therefore, it is advisable to adjust settings before initializing the
+ * library. When compiling Gorgon, the default values can be set by compiler definitions
+ * which also contains namespaces separated by underscore. Namespace and variable names
+ * should all be capitalized. For instance, if you want to modify ClickThreshold in
+ * WindowManager namespace, you should define GORGON_WINDOWMANAGER_CLICKTHRESHOLD.
+ */
+
+namespace Gorgon {
+
+namespace WindowManager {
+    
+    /// The maximum distance allowed for mouse to move between the press of the button and
+    /// the release for click event to register. Default value is 5.
+    extern int ClickThreshold;
+    
+}
+    
+    
+}
--- a/Source/Gorgon/Graphics/Bitmap.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Graphics/Bitmap.h	Wed Mar 04 03:23:54 2020 +0200
@@ -144,6 +144,9 @@
 
 		/// if used as animation, this object will not be deleted
 		virtual void DeleteAnimation() const override { }
+		
+		/// Bitmap cannot be controlled
+		virtual void SetController(Gorgon::Animation::ControllerBase &) override { }
 
 		/// Releases the image data. The image data returned by this function is moved out. Data is passed by value, thus
 		/// if it is not moved into a Containers::Image, it will be destroyed.
--- a/Source/Gorgon/Graphics/BlankImage.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Graphics/BlankImage.h	Wed Mar 04 03:23:54 2020 +0200
@@ -41,6 +41,8 @@
 		virtual void DeleteAnimation() const override {
 		}
 
+		virtual void SetController(Gorgon::Animation::ControllerBase &) override { }
+		
 		/// Returns the color of this blank image
 		RGBAf GetColor() const {
 			return color;
--- a/Source/Gorgon/Graphics/EmptyImage.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Graphics/EmptyImage.h	Wed Mar 04 03:23:54 2020 +0200
@@ -22,6 +22,8 @@
         }
 
 		void DeleteAnimation() const override { }
+		
+		virtual void SetController(Gorgon::Animation::ControllerBase &) override { }
 
 		virtual bool Progress(unsigned &leftover) override {
 			return true;
--- a/Source/Gorgon/Graphics/FreeType.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Graphics/FreeType.h	Wed Mar 04 03:23:54 2020 +0200
@@ -298,7 +298,7 @@
 
 		/// Width of a digit, if digits do not have the same width, maximum should be returned. For
 		/// practical reasons, this function is expected to consider arabic numerals.
-		virtual int GetDigitWidth() const override { return 0; }
+		virtual int GetDigitWidth() const override { return GetSize("0").Width; }
         
         /// Baseline point of glyphs from the top.
         virtual float GetBaseLine() const override { return baseline; }
--- a/Source/Gorgon/Layer.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Layer.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -155,8 +155,8 @@
 	}
 
     Layer::~Layer() {
-        for(auto &l : children)
-            Remove(l);
+        while(children.GetSize())
+            Remove(*children.First());
 
         for(auto &win : Window::Windows)
             win.deleting(this);
--- a/Source/Gorgon/Layer.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Layer.h	Wed Mar 04 03:23:54 2020 +0200
@@ -110,7 +110,8 @@
 			if(parent)
 				parent->Remove(this);
 			
-			children.Clear();
+            while(children.GetSize())
+                Remove(*children.First());
 			
 			Swap(other);
 			
@@ -329,6 +330,16 @@
 			bounds.Resize({width, height});
 		}
 
+		/// Resizes the layer to the given size
+		void SetWidth(int width) {
+			bounds.SetWidth(width);
+		}
+
+		/// Resizes the layer to the given size
+		void SetHeight(int height) {
+			bounds.SetHeight(height);
+		}
+
 		/// Sets the boundaries of this layer.
 		void SetBounds(const Geometry::Bounds &bounds) {
 			this->bounds=bounds;
--- a/Source/Gorgon/Scripting/Embedding.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Scripting/Embedding.h	Wed Mar 04 03:23:54 2020 +0200
@@ -1842,7 +1842,7 @@
 						}
 					),
 			   
-					new MappedOperator("and", "Combines two enumeration entries", 
+					new MappedOperator("with", "Combines two enumeration entries", 
 						this, this, this, 
 						[](E_ l, E_ r) -> E_ {
 							return (E_)((unsigned)l|(unsigned)r);
--- a/Source/Gorgon/Scripting/Reflection.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Scripting/Reflection.h	Wed Mar 04 03:23:54 2020 +0200
@@ -519,10 +519,6 @@
 						reference=true;
 						break;
 						
-					case ConstTag:
-						constant=true;
-						break;
-						
 					case ReadonlyTag:
 						readonly=true;
 						break;
@@ -1209,7 +1205,7 @@
 			virtual MemberType GetMemberType() const override { return StaticMember::RegularType; }
 			
 			virtual Data Get() const override {
-				Type *TypeType();
+				Type *TypeType( );
 				
 				return {TypeType(), dynamic_cast<const Type*>(this), true, true};
 			}
--- a/Source/Gorgon/TMP.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/TMP.h	Wed Mar 04 03:23:54 2020 +0200
@@ -212,7 +212,7 @@
 			using NewType = typename std::remove_const<typename Choose<std::is_reference<T_>::value, typename std::remove_reference<T_>::type*, T_>::Type>::type;
 			using CloneType = const typename Choose<std::is_reference<T_>::value, typename std::remove_reference<T_>::type*, T_>::Type* const;
 			
-			virtual RTTS *Duplicate() const {
+			virtual RTTS *Duplicate() const override {
 				return new RTT<T_>();
 			}
 			
--- a/Source/Gorgon/UI/ComponentStack.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/UI/ComponentStack.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -2,6 +2,7 @@
 
 #include "../Graphics/Font.h"
 #include "../Time.h"
+#include "../Config.h"
 
 #include "math.h"
 
@@ -63,6 +64,8 @@
 
             if(down_fn)
                 down_fn(ComponentTemplate::NoTag, location, btn);
+            
+            downlocation = location;
         });
         
         mouse.SetUp([this](Geometry::Point location, Input::Mouse::Button btn) {
@@ -73,7 +76,7 @@
                 }
             }
             
-            if(click_fn)
+            if(click_fn && downlocation.Distance(location) < WindowManager::ClickThreshold)
                 click_fn(ComponentTemplate::NoTag, location, btn);
             
             if(up_fn)
--- a/Source/Gorgon/UI/ComponentStack.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/UI/ComponentStack.h	Wed Mar 04 03:23:54 2020 +0200
@@ -16,10 +16,7 @@
         /// should handle instantiation as well
         explicit ComponentStack(const Template &temp, Geometry::Size size);
         
-        ComponentStack(ComponentStack &&) = default;
-        ComponentStack &operator =(ComponentStack &&) = default;
-        
-        ~ComponentStack() {
+        virtual ~ComponentStack() {
             for(auto &p : storage) {
                 delete p.second;
             }
@@ -591,6 +588,7 @@
         Graphics::Layer base;
         Input::Layer mouse;
         Input::Mouse::Button mousebuttonaccepted;
+        Geometry::Point downlocation;
         
         std::function<void(ComponentTemplate::Tag, Geometry::Point, Input::Mouse::Button)> down_fn;
         std::function<void(ComponentTemplate::Tag, Geometry::Point, Input::Mouse::Button)> click_fn;
--- a/Source/Gorgon/UI/WidgetBase.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/UI/WidgetBase.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -67,4 +67,16 @@
             boundschanged(); 
     }
     
+
+    void WidgetBase::focuslost() {
+        focus = false;
+        FocusEvent();
+    }
+
+
+    void WidgetBase::focused() {
+        focus = true;
+        FocusEvent();
+    }
+
 } }
--- a/Source/Gorgon/UI/WidgetBase.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/UI/WidgetBase.h	Wed Mar 04 03:23:54 2020 +0200
@@ -120,6 +120,17 @@
         /// trigger this event. Organizers use this event to rearrange widgets, 
         /// thus it is not advisable to remove all handlers from this event.
         Event<WidgetBase> BoundsChangedEvent = Event<WidgetBase>{*this};
+        
+        /// This is a debug feature
+        void setname(std::string value) {
+#ifndef NDEBUG
+            dbgname = value;
+#endif
+        }
+        
+#ifndef NDEBUG
+    std::string dbgname;
+#endif
 
     protected:
         /// Called when it is about to be added to the given container
@@ -155,10 +166,7 @@
         virtual bool allowfocus() const { return true; }
         
         /// This is called after the focus is transferred to this widget.
-        virtual void focused() {
-            focus = true;
-            FocusEvent();
-        }
+        virtual void focused();
         
         /// Should return true if the widget can loose the focus right now.
         /// Even if you return false, you still might be forced to loose
@@ -167,10 +175,7 @@
         
         /// This is called after the focus is lost. This is called even if
         /// focus removal is forced.
-        virtual void focuslost() {
-            focus = false;
-            FocusEvent();
-        }
+        virtual void focuslost();
         
         /// Call this function when the widget bounds is changed
         virtual void boundschanged();
--- a/Source/Gorgon/Widgets/Generator.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Widgets/Generator.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -48,6 +48,8 @@
                             break;
                         }
                     }
+                    
+                    delete buf;
                 }
             }
             catch(...) {
@@ -64,7 +66,7 @@
 
         RegularFont.SetGlyphRenderer(regular);
 
-        if(!regular.HasKerning()) {
+        /*if(!regular.HasKerning()) {
             auto &bmpfnt = *new Graphics::BitmapFont(regular.MoveOutBitmap());
             RegularFont.SetGlyphRenderer(bmpfnt);
             bmpfnt.AutoKern();
@@ -72,11 +74,13 @@
 
             delete &regular;
         }
-        else {
+        else {*/
             regularrenderer = &regular;
-        }
+        //}
         
-        //RegularFont.AlignRight();
+        WidgetWidth = regularrenderer->GetDigitWidth() * 8 + Border.Width * 2 + Border.Radius / 2 + Spacing;
+        BordedWidgetHeight = regularrenderer->GetHeight() + Border.Radius / 2 + Spacing;
+        WidgetHeight = regularrenderer->GetHeight();
     }
 
     SimpleGenerator::~SimpleGenerator() {
@@ -87,6 +91,12 @@
         drawables.DeleteAll();
     }
     
+    void SimpleGenerator::UpdateDimensions() {
+        WidgetWidth = regularrenderer->GetDigitWidth() * 8 + Border.Width * 2 + Border.Radius / 2 + Spacing;
+        BordedWidgetHeight = regularrenderer->GetHeight() + Border.Radius / 2 + Spacing;
+        WidgetHeight = regularrenderer->GetHeight();
+    }
+    
     Graphics::BitmapRectangleProvider &SimpleGenerator::NormalBorder() {
         static Graphics::BitmapRectangleProvider border = makeborder(Border.Color, Background.Regular);
         
@@ -168,15 +178,22 @@
         
         drawables.Add(bi);
 
-        Graphics::BitmapRectangleProvider ret = Graphics::Slice(bi, {int(off*2+Border.Radius), int(off*2+Border.Radius), int(bsize-off*2-Border.Radius), int(bsize-off*2-Border.Radius)});
+        Graphics::BitmapRectangleProvider ret = Graphics::Slice(bi, {
+            int(off*2+Border.Radius), 
+            int(off*2+Border.Radius), 
+            int(bsize-off*2-Border.Radius),
+            int(bsize-off*2-Border.Radius)
+        });
+        
         ret.Prepare();
         
         return ret;
     }
     
     
-    UI::Template SimpleGenerator::Button(Geometry::Size defsize) {
-
+    UI::Template SimpleGenerator::Button() {
+        Geometry::Size defsize = {WidgetWidth, BordedWidgetHeight};
+        
         UI::Template temp;
         temp.SetSize(defsize);
 
@@ -284,12 +301,12 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::IconButton(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::IconButton(Geometry::Size iconsize) {
         
         UI::Template temp;
-        temp.SetSize(defsize);
+        temp.SetSize(iconsize + Geometry::Size(16, 16));
         
-        auto bgsize = defsize - Geometry::Size(8, 8);
+        auto bgsize = iconsize + Geometry::Size(8, 8);
         
         {
             auto &bg = temp.AddContainer(0, UI::ComponentCondition::Always);
@@ -328,7 +345,7 @@
             auto c = Background.Regular;
             c.Blend(Background.Down);
             
-            auto &im = *new Graphics::BlankImage(defsize - bgsize, c);
+            auto &im = *new Graphics::BlankImage(bgsize, c);
             drawables.Add(im);
             
             bg.SetPadding(4);
@@ -394,7 +411,9 @@
         return temp;
     }
 
-    UI::Template SimpleGenerator::Checkbox(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::Checkbox() {
+        Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -611,7 +630,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::RadioButton(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::RadioButton() {
+        Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -786,7 +807,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::Label(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::Label() {
+        Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -858,7 +881,9 @@
         return temp;
     }
 
-    UI::Template SimpleGenerator::ErrorLabel(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::ErrorLabel() {
+        Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
+        
         UI::Template temp;
         temp.SetSize(defsize);
 
@@ -930,7 +955,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::BlankPanel(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::BlankPanel() {
+        Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 5, WidgetHeight * 10 + Spacing * 11};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -952,7 +979,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::Panel(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::Panel() {
+        Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 5 + Border.Width * 2 + Border.Radius + Spacing * 2, WidgetHeight * 10 + Spacing * 11 + Border.Width * 2 + Border.Radius + Spacing * 2};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -983,7 +1012,9 @@
     }
     
     //TODO: fix me
-    UI::Template SimpleGenerator::TopPanel(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::TopPanel() {
+        Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 5 + Border.Width * 2 + Border.Radius + Spacing * 2, WidgetHeight * 2 + Spacing * 3 + Border.Width * 2 + Border.Radius + Spacing * 2};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -1005,7 +1036,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::LeftPanel(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::LeftPanel() {
+        Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 5 + Border.Width * 2 + Border.Radius + Spacing * 2, WidgetHeight * 10 + Spacing * 11 + Border.Width * 2 + Border.Radius + Spacing * 2};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -1027,7 +1060,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::RightPanel(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::RightPanel() {
+        Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 5 + Border.Width * 2 + Border.Radius + Spacing * 2, WidgetHeight * 10 + Spacing * 11 + Border.Width * 2 + Border.Radius + Spacing * 2};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -1049,7 +1084,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::BottomPanel(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::BottomPanel() {
+        Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 5 + Border.Width * 2 + Border.Radius + Spacing * 2, WidgetHeight * 2 + Spacing * 3 + Border.Width * 2 + Border.Radius + Spacing * 2};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
@@ -1071,7 +1108,9 @@
         return temp;
     }
     
-    UI::Template SimpleGenerator::Inputbox(Geometry::Size defsize) {
+    UI::Template SimpleGenerator::Inputbox() {
+        Geometry::Size defsize = {WidgetWidth * 2 + Spacing, BordedWidgetHeight};
+        
         UI::Template temp;
         temp.SetSize(defsize);
         
--- a/Source/Gorgon/Widgets/Generator.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Widgets/Generator.h	Wed Mar 04 03:23:54 2020 +0200
@@ -7,113 +7,90 @@
 
 namespace Gorgon { namespace Widgets {
 
-	/**
-	 * Generators create templates for widgets. First setup a generator, then
-     * call specific generation functions.
-	 */
+    /**
+    * Generators create templates for widgets. First setup a generator, then
+    * call specific generation functions.
+    */
     class Generator {
     public:
-		virtual ~Generator() { }
+        virtual ~Generator() { }
         
-        /// Generates a button template with the given default size.
-        virtual UI::Template Button(Geometry::Size size) = 0;
+        /// Generates a button template
+        virtual UI::Template Button() = 0;
         
         /// Generates a button template with the given default size.
-        virtual UI::Template IconButton(Geometry::Size size) = 0;
+        virtual UI::Template IconButton(Geometry::Size iconsize) = 0;
         
-        virtual UI::Template Checkbox(Geometry::Size size) = 0;
         
-        virtual UI::Template RadioButton(Geometry::Size size) = 0;
+        virtual UI::Template Checkbox() = 0;
         
-        virtual UI::Template Label(Geometry::Size size) = 0;
-		
-        virtual UI::Template ErrorLabel(Geometry::Size size) = 0;
+        virtual UI::Template RadioButton() = 0;
+        
         
-        virtual UI::Template Panel(Geometry::Size size) = 0;
+        virtual UI::Template Label() = 0;
+        
+        virtual UI::Template ErrorLabel() = 0;
+        
         
-        virtual UI::Template TopPanel(Geometry::Size size) = 0;
+        virtual UI::Template Panel() = 0;
         
-        virtual UI::Template LeftPanel(Geometry::Size size) = 0;
+        virtual UI::Template TopPanel() = 0;
         
-        virtual UI::Template BottomPanel(Geometry::Size size) = 0;
+        virtual UI::Template LeftPanel() = 0;
         
-        virtual UI::Template RightPanel(Geometry::Size size) = 0;
+        virtual UI::Template BottomPanel() = 0;
+        
+        virtual UI::Template RightPanel() = 0;
         
-        virtual UI::Template BlankPanel(Geometry::Size size) = 0;
+        virtual UI::Template BlankPanel() = 0;
         
-        virtual UI::Template Inputbox(Geometry::Size size) = 0;
+        
+        virtual UI::Template Inputbox() = 0;
     };
     
     /**
-     * This class generates very simple templates. Hover and down states are marked
-     * with simple fore and background color changes. For background, hover and down
-     * state colors are blended with the regular color. Font is shared, thus any
-     * changes to it will effect existing templates too.
-     */
-	class SimpleGenerator : public Generator {
-	public:
-		/// Initializes the generator
-		explicit SimpleGenerator(int fontsize = 14, std::string fontname = "");
+    * This class generates very simple templates. Hover and down states are marked
+    * with simple fore and background color changes. For background, hover and down
+    * state colors are blended with the regular color. Font is shared, thus any
+    * changes to it will effect existing templates too.
+    */
+    class SimpleGenerator : public Generator {
+    public:
+        
+        /// Initializes the generator
+        explicit SimpleGenerator(int fontsize = 14, std::string fontname = "");
 
         
         virtual ~SimpleGenerator();
         
-        virtual UI::Template Button(
-            Geometry::Size size = {70, 32}
-        ) override;
+        virtual UI::Template Button() override;
+        
+        virtual UI::Template IconButton(Geometry::Size iconsize = {16, 16}) override;
+        
+        
+        virtual UI::Template Checkbox() override;
+        
+        virtual UI::Template RadioButton() override;
         
         
-        virtual UI::Template IconButton(
-            Geometry::Size size = {24, 24}
-        ) override;
-        
+        virtual UI::Template Label() override;
 
-        virtual UI::Template Checkbox(
-            Geometry::Size size = {166, 24}
-        ) override;
+        virtual UI::Template ErrorLabel() override;
         
-        virtual UI::Template RadioButton(
-            Geometry::Size size = {155, 24}
-        ) override;
+        virtual UI::Template BlankPanel() override;
         
-        virtual UI::Template Label(
-            Geometry::Size size = {155, 24}
-        ) override;
-
-
-		virtual UI::Template ErrorLabel(
-			Geometry::Size size = { 155, 24 }
-		) override;
-		
-	
+        virtual UI::Template Panel() override;
         
-        virtual UI::Template BlankPanel(
-            Geometry::Size size = {155, 300}
-        ) override;
+        virtual UI::Template TopPanel() override;
         
-        virtual UI::Template Panel(
-            Geometry::Size size = {155, 300}
-        ) override;
-        
-        virtual UI::Template TopPanel(
-            Geometry::Size size = {155, 300}
-        ) override;
+        virtual UI::Template LeftPanel() override;
         
-        virtual UI::Template LeftPanel(
-            Geometry::Size size = {155, 300}
-        ) override;
-        
-        virtual UI::Template RightPanel(
-            Geometry::Size size = {155, 300}
-        ) override;
+        virtual UI::Template RightPanel() override;
         
-        virtual UI::Template BottomPanel(
-            Geometry::Size size = {155, 300}
-        ) override;
+        virtual UI::Template BottomPanel() override;
         
-        virtual UI::Template Inputbox(
-            Geometry::Size size = {166, 32}
-        ) override;
+        
+        virtual UI::Template Inputbox() override;
         
         Graphics::BitmapRectangleProvider &NormalBorder();
         Graphics::BitmapRectangleProvider &PanelBorder();
@@ -121,16 +98,20 @@
         Graphics::BitmapRectangleProvider &HoverBorder();
         Graphics::BitmapRectangleProvider &DownBorder();
         
-		int Spacing      = 4;
-		int ObjectHeight = 15;
-		int ObjectBorder = 2;
+        int Spacing      = 4;
+        int ObjectHeight = 15;
+        int ObjectBorder = 2;
+        
+        /// This function will update default widget dimensions. Call this function after
+        /// setting up or changing borders, font size
+        void UpdateDimensions();
 
-		Graphics::StyledRenderer RegularFont;
+        Graphics::StyledRenderer RegularFont;
 
-		struct FocusInfo {
-			Graphics::RGBA	Color = {Graphics::Color::Charcoal, 0.7};
-			int				Width = 1;
-		} Focus;
+        struct FocusInfo {
+            Graphics::RGBA  Color = {Graphics::Color::Charcoal, 0.7};
+            int             Width = 1;
+        } Focus;
         
         struct BorderInfo {
             int Width             = 2;
@@ -153,17 +134,26 @@
             Graphics::RGBA Regular = Graphics::Color::Charcoal;
             Graphics::RGBA Hover   = Graphics::Color::Black;
             Graphics::RGBA Down    = Graphics::Color::Black;
-			Graphics::RGBA Error   = Graphics::Color::Red;
+            Graphics::RGBA Error   = Graphics::Color::Red;
         } Forecolor;
-		
-		
+        
+        
+        /// This is the width of a one cell widget
+        int WidgetWidth = 64;
+        
+        /// This is the height of a bordered widget
+        int BordedWidgetHeight = 32;
+        
+        /// This is the height of a non-bordered widget
+        int WidgetHeight = 24;
+
     private:
         Graphics::BitmapRectangleProvider makeborder(Graphics::RGBA border, Graphics::RGBA bg);
         
-		Graphics::GlyphRenderer *regularrenderer = nullptr;
-		Containers::Collection<Graphics::Drawable> drawables;
-		Containers::Collection<Graphics::AnimationProvider> providers;
-
-	};
+        Graphics::GlyphRenderer *regularrenderer = nullptr;
+        Containers::Collection<Graphics::Drawable> drawables;
+        Containers::Collection<Graphics::AnimationProvider> providers;
+        
+    };
 
 }}
--- a/Source/Gorgon/Widgets/RadioButtons.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Widgets/RadioButtons.h	Wed Mar 04 03:23:54 2020 +0200
@@ -6,162 +6,157 @@
 #include "../UI/RadioControl.h"
 #include "../Property.h"
 #include "Checkbox.h"
+#include "../UI/WidgetContainer.h"
 
 namespace Gorgon { namespace Widgets {
     
     template<class T_, class W_ = Checkbox>
-    class RadioButtons : public UI::WidgetBase, protected UI::RadioControl<T_, W_> {
+    class RadioButtons : public UI::WidgetBase, protected UI::RadioControl<T_, W_>, protected UI::WidgetContainer {
     public:
-		explicit RadioButtons(const UI::Template &temp) : temp(temp) { }
+        explicit RadioButtons(const UI::Template &temp) : temp(temp) { }
 
         ~RadioButtons() {
-			this->elements.Destroy();
-		}
-		
-		using WidgetBase::Move;
-
-		using WidgetBase::Resize;
-
-		virtual void Move(Geometry::Point value) override {
-			location = value;
-
-			if(HasParent())
-				this->PlaceIn(GetParent(), location, spacing);
-		}
-
-
-		virtual Geometry::Point GetLocation() const override {
-			return location;
-		}
-
-		
-		virtual void Resize(Geometry::Size size) override {
-			size.Height -= spacing * (this->elements.GetSize() - 1);
-
-			if(size.Height < 0)
-				size.Height = 0;
-
-			size.Height /= this->elements.GetSize();
-
-			for(auto p : this->elements) {
-				p.second.Resize(size);
-			}
-
-			this->PlaceIn(GetParent(), location, spacing);
-		}
+            this->elements.Destroy();
+        }
+        
+        /// Radio buttons height is automatically adjusted. Only width will be used.
+        virtual void Resize(Geometry::Size size) override {
+            for(auto p : this->elements) {
+                p.second.SetWidth(size.Width);
+            }
+            
+            contents.SetWidth(size.Width);
+        }
 
 
-		virtual Geometry::Size GetSize() const override {
-			int h = 0;
-			int maxw = 0;
-			for(auto p : this->elements) {
-				if(h != 0)
-					h += spacing;
-
-				auto s = p.second.GetSize();
+        virtual bool Activate() override {
+            return false;
+        }
 
-				h += s.Height;
-
-				if(s.Width > maxw)
-					maxw = s.Width;
-			}
-
-			return {maxw, h};
-		}
-
+        void SetSpacing(int value) {
+            if(spacing == value)
+                return;
 
-		virtual bool Activate() override {
-			return false;
-		}
-
-		void SetSpacing(int value) {
-			if(spacing == value)
-				return;
-
-			spacing = value;
+            spacing = value;
+            
+            int total = spacing * (this->elements.GetSize() - 1);
+            
+            for(auto p : this->elements) {
+                total += p.second.GetHeight();
+            }
+            
+            if(total < 0) total = 0;
+            
+            SetHeight(total);
+            
+            this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
+        }
 
-			if(HasParent())
-				this->PlaceIn(GetParent(), location, spacing);
-		}
+        void Add(const T_ value) {
+            Add(value, String::From(value));
+        }
 
-		void Add(const T_ value) {
-            auto &c = *new W_(temp, String::From(value));
-			UI::RadioControl<T_, W_>::Add(value, c);
-            
-            if(!IsVisible())
-                c.Hide();
-		}
-
-		void Add(const T_ value, std::string text) {
+        void Add(const T_ value, std::string text) {
             auto &c = *new W_(temp, text);
             UI::RadioControl<T_, W_>::Add(value, c);
             
-            if(!IsVisible())
-                c.Hide();
+            if(GetWidth() < c.GetWidth())
+                SetWidth(c.GetWidth());
+            
+            contents.SetHeight(GetHeight() + c.GetHeight() + spacing);
+            
+            if(IsVisible())
+                this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
+            
+            boundschanged();
+            childboundschanged(&c);
+        }
+        
+        Geometry::Size GetInteriorSize() const override {
+            return GetSize();
+        }
+        
+        bool ResizeInterior(Geometry::Size size) override {
+            Resize(size);
+            
+            return size == GetSize();
+        }
+        
+        Geometry::Point GetLocation() const override {
+            return contents.GetLocation();
+        }
+        
+        Geometry::Size GetSize() const override {
+            return contents.GetSize();
+        }
+        
+        bool IsVisible() const override {
+            return contents.IsVisible();
         }
 
-		using UI::RadioControl<T_, W_>::ChangedEvent;
+        using WidgetBase::Resize;
+
+        using WidgetBase::Move;
+        
+        void Move(Geometry::Point location) override {
+            contents.Move(location);
+        }
+        
+        /// Assigns a new value to the radio control. If the specified value exists
+        /// in the, it will be selected, if not, nothing will be selected.
+        RadioButtons &operator =(const T_ value) {
+            Set(value);
+        }
+
+        using UI::RadioControl<T_, W_>::ChangedEvent;
 
         using UI::RadioControl<T_, W_>::Exists;
 
         using UI::RadioControl<T_, W_>::Get;
 
         using UI::RadioControl<T_, W_>::Set;
+        
+        using WidgetBase::IsVisible;
 
-	protected:
-		virtual void addto(Layer &layer) override { }
-
-
-		virtual void removefrom(Layer &layer) override { }
+    protected:
+        virtual void addto(Layer &layer) override { 
+            layer.Add(contents);
+        }
 
 
-		virtual void setlayerorder(Layer &layer, int order) override {
-			if(!HasParent()) 
-				return;
-
-			for(auto p : this->elements) {
-				GetParent().ChangeZorder(p.second, order);
-                order++;
-			}
-		}
+        virtual void removefrom(Layer &layer) override { 
+            layer.Remove(contents);
+        }
 
 
-		virtual bool allowfocus() const override {
-			return false;
-		}
-
-
-		virtual bool addingto(UI::WidgetContainer &container) override {
-			this->PlaceIn(container, location, spacing);
-
-			return true;
-		}
+        virtual void setlayerorder(Layer &, int order) override {
+            contents.PlaceBefore(order);
+        }
 
 
-		virtual bool removingfrom() override {
-			for(auto p : this->elements) {
-				p.second.Remove();
-			}
+        virtual bool allowfocus() const override {
+            return false;
+        }
+        
+        Gorgon::Layer &getlayer() override {
+            return contents;
+        }
 
-			return true;
-		}
 
-		Geometry::Point location = {0, 0};
-		int spacing = 4;
-		const UI::Template &temp;
+        Geometry::Point location = {0, 0};
+        int spacing = 4;
+        const UI::Template &temp;
         
     private:
         virtual void show() override {
-            for(auto p : this->elements) {
-                p.second.Show();
-            }
+            contents.Show();
         }
         
         virtual void hide() override {
-            for(auto p : this->elements) {
-                p.second.Hide();
-            }
+            contents.Hide();
         }
-	};
+        
+        Gorgon::Graphics::Layer contents;
+    };
     
 } }
--- a/Source/Gorgon/Window.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Window.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -6,6 +6,8 @@
 #include "GL/FrameBuffer.h"
 #include "Input/DnD.h"
 
+#include "Config.h"
+
 
 namespace Gorgon {
 
@@ -124,7 +126,7 @@
 					down.Clear();
 			}
 			else {
-				if(mousedownlocation.Distance(location) <= ClickThreshold) {
+				if(mousedownlocation.Distance(location) <= WindowManager::ClickThreshold) {
 					MouseHandler handler;
 					Layer::propagate_mouseevent(Input::Mouse::EventType::Click, location, button, 1, handler);
 				}
@@ -205,6 +207,4 @@
         iswmpointer = true;
         ShowPointer();
     }
-
-	int Window::ClickThreshold = 5;
 }
--- a/Source/Gorgon/Window.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/Window.h	Wed Mar 04 03:23:54 2020 +0200
@@ -399,10 +399,6 @@
 
 		/// List of currently created windows
 		static const Containers::Collection<Window> &Windows;
-
-        /// If the mouse is moved more than this value during a mouse down/up sequence, it will not 
-        /// register as a click operation. Default is 5px.
-		static int ClickThreshold;
         
         /// These functions are used internally
 		void mouse_down(Geometry::Point location, Input::Mouse::Button button);
--- a/Source/Gorgon/WindowManager/DWM/Input.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/WindowManager/DWM/Input.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -411,19 +411,19 @@
 		int y = int(lParam>>16);
 
 		switch(message) {
-		case WM_LBUTTONDOWN:
+		case WM_LBUTTONUP:
 			data->parent->mouse_up({x, y}, Input::Mouse::Button::Left);
 			break;
 
-		case WM_RBUTTONDOWN:
+		case WM_RBUTTONUP:
 			data->parent->mouse_up({x, y}, Input::Mouse::Button::Right);
 			break;
 
-		case WM_MBUTTONDOWN:
+		case WM_MBUTTONUP:
 			data->parent->mouse_up({x, y}, Input::Mouse::Button::Middle);
 			break;
 
-		case WM_XBUTTONDOWN:
+		case WM_XBUTTONUP:
 
 			switch(GET_XBUTTON_WPARAM(wParam)) {
 			case 1:
--- a/Source/Gorgon/WindowManager/X11/Input.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/WindowManager/X11/Input.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -7,6 +7,10 @@
     int min = 0;
     int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
     int mid;
+    
+    if(keysym == 13 || keysym == 10) {
+        return keysym;
+    }
 
     /* first check for Latin-1 characters (1:1 mapping) */
     if ((keysym >= 0x0020 && keysym <= 0x007e) ||
@@ -379,7 +383,7 @@
                     Input::Keyboard::Char c = keysym2ucs(key);
                     
                     if(c != 0xfffd) {
-                        if( (c>=0x20 || c == '\t' || c =='\n') && (c < 0x7f || c > 0x9f)) { //exclude c0 & c1 but keep enter and tab
+                        if( (c>=0x20 || c == '\t' || c ==13) && (c < 0x7f || c > 0x9f)) { //exclude c0 & c1 but keep enter and tab
                             wind.CharacterEvent(c);
                         }
                     }
--- a/Source/Gorgon/WindowManager/X11/Window.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/WindowManager/X11/Window.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -338,6 +338,10 @@
 
     
     void Window::Close() {
+        //already closed
+        if(data->handle == 0)
+            return;
+        
         XDestroyWindow(WindowManager::display, data->handle);
         data->handle = 0;
         
--- a/Source/Gorgon/WindowManager/X11/X11Keysym.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/WindowManager/X11/X11Keysym.h	Wed Mar 04 03:23:54 2020 +0200
@@ -816,6 +816,8 @@
   { 0x13bd, 0x0153 }, /*                          oe œ LATIN SMALL LIGATURE OE */
   { 0x13be, 0x0178 }, /*                  Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
   { 0x20ac, 0x20ac }, /*                    EuroSign € EURO SIGN */
+  { 0xff09, 0x0009 }, /*                    Tab */
+  { 0xff0d, 0x000d }, /*                    Enter */
 };
 
 long keysym2ucs(KeySym keysym);
--- a/Source/Gorgon/dir.cmake	Wed Mar 04 03:16:03 2020 +0200
+++ b/Source/Gorgon/dir.cmake	Wed Mar 04 03:23:54 2020 +0200
@@ -18,6 +18,8 @@
 	Utils
 	WindowManager
 	Any.h
+	Config.h
+	Config.cpp
 	Enum.h
 	Event.h
 	DataExchange.h
--- a/Testing/Source/Manual/GraphicsHelper.h	Wed Mar 04 03:16:03 2020 +0200
+++ b/Testing/Source/Manual/GraphicsHelper.h	Wed Mar 04 03:23:54 2020 +0200
@@ -82,6 +82,8 @@
                     break;
                 }
             }
+            
+            delete buf;
         }
         
         if(!found)
@@ -104,7 +106,7 @@
 				  , 500, 10, wind.GetWidth()-505
 		);*/
 
-		wind.KeyEvent.Register([](Input::Key key, bool state) {
+		wind.KeyEvent.Register([this](Input::Key key, bool state) {
 			if(!state && (key == 27 || key == 65307))
 				exit(0);
 
--- a/Testing/Source/Manual/UI_Generate.cpp	Wed Mar 04 03:16:03 2020 +0200
+++ b/Testing/Source/Manual/UI_Generate.cpp	Wed Mar 04 03:23:54 2020 +0200
@@ -33,19 +33,18 @@
 int main() {
     basic_Application<UI::Window> app("uitest", "UI Generator Test", helptext, 1, 0x80);
     
-    Graphics::Layer l, l2;
-    
-    app.wind.Add(l);
-    app.wind.Add(l2);
-    
-    l2.SetColor(Gorgon::Graphics::Color::Pink);
-    l2.Resize({ 200,200 });
-    
-    l2.Move(400, 400);
     Widgets::SimpleGenerator gen(15);
     gen.Border.Radius=4;
+    gen.UpdateDimensions();
 
     auto btntemp = gen.Button();
+    auto radtemp = gen.RadioButton();
+    auto chktemp = gen.Checkbox();
+    auto icobtntemp = gen.IconButton();
+    auto lbltemp = gen.Label();
+    auto pnltemp = gen.BlankPanel();
+    auto pnltemp2 = gen.Panel();
+    
 
     Widgets::Button btn(btntemp, "Helloo...", []() { std::cout<<"Hello..."<<std::endl; });
     btn.Move(5,5);
@@ -58,12 +57,11 @@
     btn2.Move({5, btn.GetSize().Height + 10});
     app.wind.Add(btn2);
     
-    auto radtemp = gen.RadioButton();
     std::cout<<"Height: "<<gen.RegularFont.GetGlyphRenderer().GetSize('A').Height<<std::endl;
     
     Widgets::RadioButtons<int> rad(radtemp);
     
-    rad.Add(0, "Americano");
+    rad.Add(0, "Ájmericano");
     rad.Add(1, "Latte");
     rad.Add(2);
 
@@ -74,7 +72,6 @@
         std::cout<<"Changed to "<<val<<std::endl;
     });
 
-    auto chktemp = gen.Checkbox();
     
 
     Widgets::Checkbox chk(chktemp, "Sugar", [](bool state) {
@@ -92,7 +89,6 @@
 
     chk.Move(rad.GetLocation() + Gorgon::Geometry::Point(0, rad.GetSize().Height + 4));
 
-    auto icobtntemp = gen.IconButton();
     Widgets::Button ib(icobtntemp);
     auto ico = Graphics::BlankImage({16, 16}, Graphics::Color::Black);
     //ico.Prepare();
@@ -100,8 +96,6 @@
     ib.Move(chk.GetLocation() + Gorgon::Geometry::Point(0, chk.GetSize().Height + 4));
     app.wind.Add(ib);
     
-    auto pnltemp = gen.BlankPanel();
-    auto pnltemp2 = gen.Panel();
     
     Widgets::Panel pnl(pnltemp);
     pnl.Resize(300, 300);
@@ -113,7 +107,6 @@
     Widgets::Button increase(btntemp);
     Widgets::Button decrease(btntemp);
 
-    auto lbltemp = gen.Label();
 
     mainpanel.Add(sub);
     sub.Move(5, 0);
@@ -161,7 +154,9 @@
     auto inptemp = gen.Inputbox();
     Widgets::Pointbox inp(inptemp);
     inp={5, 2};
-    pnl.Add(inp);
+    //pnl.Add(inp);
+    app.wind.Add(inp);
+    inp.Move(5, 80);
     inp.SelectAll();
     
     pnl.Add(lbl);

mercurial