Wed, 04 Mar 2020 03:23:54 +0200
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 ®ular; } - else { + else {*/ regularrenderer = ®ular; - } + //} - //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);