Tue, 06 Oct 2020 16:02:39 +0300
#191 Composer
* Blank panel now features scrollbars
--- a/Source/Gorgon/Property.h Sun Oct 04 11:36:11 2020 +0300 +++ b/Source/Gorgon/Property.h Tue Oct 06 16:02:39 2020 +0300 @@ -126,6 +126,12 @@ return *this; } + NumericProperty &operator =(const NumericProperty &other) { + (this->Object.*Setter_)(other.Get()); + + return *this; + } + template<class AC_, class O_, O_(C_::*G_)() const, void(C_::*S_)(const O_ &)> NumericProperty &operator =(const Property<AC_, O_, G_, S_> &prop) { (this->Object.*Setter_)((T_)(O_)prop);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Gorgon/Widgets/Composer.cpp Tue Oct 06 16:02:39 2020 +0300 @@ -0,0 +1,44 @@ +#include "Composer.h" + + +namespace Gorgon { namespace Widgets { + + bool Composer::Activate() { + if(!Focus()) + return false; + + FocusFirst(); + + return true; + } + + bool Composer::allowfocus() const { + for(auto &w : widgets) { + if(w.AllowFocus()) { + return true; + } + } + + return false; + } + + void Composer::focused() { + if(!HasFocusedWidget()) + FocusFirst(); + WidgetBase::focused(); + } + + void Composer::focuslost() { + RemoveFocus(); + WidgetBase::focuslost(); + } + + void Composer::focuschanged() { + if(HasFocusedWidget() && !IsFocused()) + Focus(); + else if(!HasFocusedWidget() && IsFocused()) + RemoveFocus(); + } + + +} }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Gorgon/Widgets/Composer.h Tue Oct 06 16:02:39 2020 +0300 @@ -0,0 +1,125 @@ +#pragma once + +#include "../UI/WidgetBase.h" +#include "../UI/WidgetContainer.h" + +namespace Gorgon { namespace Widgets { + + /** + * This object allows its users to compose widgets using other widgets. It is + * designed to be inherited. Derived classes can be use this object as a + * container, which allows widgets on top of it. However, container side is + * not public. Therefore, users of the derived widget cannot add more widgets + * to the derived widget. Widget Composer handles focus, keyboard and all + * necessary functions to build a widget container and a widget. It does not + * require any templates to build, however, you may request templates to use + * in widgets in the composer. This object does not support scrolling, however, + * you may place a panel in it to have that functionality. + */ + class Composer : public UI::WidgetBase, protected UI::WidgetContainer { + public: + ~Composer() { } + + using WidgetBase::Resize; + + using WidgetBase::Remove; + + using WidgetContainer::Remove; + + virtual bool Activate() override; + + virtual bool IsVisible() const override { + return base.IsVisible(); + } + + virtual Geometry::Size GetInteriorSize() const override { + return base.GetSize(); + } + + virtual Geometry::Size GetSize() const override { + return base.GetSize(); + } + + virtual bool ResizeInterior(Geometry::Size size) override { + Resize(size); + + return true; + } + + virtual void Resize(const Geometry::Size &size) override { + base.Resize(size); + } + + virtual Geometry::Point GetLocation() const override { + return base.GetLocation(); + } + + virtual void Move(const Geometry::Point &location) override { + base.Move(location); + } + + using WidgetBase::EnsureVisible; + + bool EnsureVisible(const UI::WidgetBase &widget) override { + return true; + } + + using WidgetBase::Enable; + using WidgetBase::Disable; + using WidgetBase::ToggleEnabled; + + virtual void SetEnabled(bool value) override { + if(value != IsEnabled()) { + enabled = value; + distributeparentenabled(value); + } + } + + virtual bool IsEnabled() const override { + return enabled; + } + + protected: + //ensure this object is derived + Composer() { + } + + virtual bool allowfocus() const override; + + virtual void focused() override; + + virtual void focuslost() override; + + virtual Layer &getlayer() override { + return base; + } + + void focuschanged() override; + + virtual void addto(Layer &layer) override { + layer.Add(base); + } + + virtual void removefrom(Layer &layer) override { + layer.Remove(base); + } + + virtual void setlayerorder(Layer &, int order) override { + base.PlaceBefore(order); + } + + private: + bool enabled = true; + + virtual void hide() override { + base.Hide(); + } + + virtual void show() override { + base.Show(); + } + + Layer base; + }; + +} }
--- a/Source/Gorgon/Widgets/Generator.cpp Sun Oct 04 11:36:11 2020 +0300 +++ b/Source/Gorgon/Widgets/Generator.cpp Tue Oct 06 16:02:39 2020 +0300 @@ -1078,24 +1078,71 @@ } UI::Template SimpleGenerator::BlankPanel() { - Geometry::Size defsize = {WidgetWidth * 2 + Spacing, BorderedWidgetHeight * 10 + Spacing * 9}; + Geometry::Size defsize = { + WidgetWidth * 2 + Spacing, + BorderedWidgetHeight * 10 + Spacing * 9}; UI::Template temp; temp.SetSpacing(Spacing); temp.SetSize(defsize); - temp.AddContainer(0, UI::ComponentCondition::Always) + auto &bg = temp.AddContainer(0, UI::ComponentCondition::Always) .AddIndex(1) - .SetClip(true) + ; + bg.SetClip(true); + + auto &vp = temp.AddContainer(1, UI::ComponentCondition::Always) + .AddIndex(2) + ; + vp.SetTag(UI::ComponentTemplate::ViewPortTag); + vp.SetSize(100, 100, UI::Dimension::Percent); + vp.SetAnchor(UI::Anchor::TopLeft, UI::Anchor::TopLeft, UI::Anchor::TopLeft); + vp.SetClip(true); + + auto &cont = temp.AddContainer(2, UI::ComponentCondition::Always); + cont.SetTag(UI::ComponentTemplate::ContentsTag); + cont.SetSize(0, 0, UI::Dimension::Percent); + cont.SetSizing(UI::ComponentTemplate::Fixed); + cont.SetPositioning(cont.Absolute); + cont.SetAnchor(UI::Anchor::TopLeft, UI::Anchor::TopLeft, UI::Anchor::TopLeft); + + auto &vst = operator[](Scrollbar_Vertical); + auto &hst = operator[](Scrollbar_Horizontal); + + temp.SetSize(temp.GetWidth()+vst.GetWidth()+Spacing, temp.GetHeight()); + + bg + .AddIndex(3) //VScroll + .AddIndex(4) //HScroll ; - auto &cont = temp.AddContainer(1, UI::ComponentCondition::Always); - cont.SetTag(UI::ComponentTemplate::ContentsTag); - cont.SetSize(0, 0, UI::Dimension::Percent); - cont.SetPositioning(cont.Absolute); - cont.SetAnchor(UI::Anchor::TopLeft, UI::Anchor::TopLeft, UI::Anchor::TopLeft); - cont.SetPosition(0, 0); + auto &vs = temp.AddPlaceholder(3, UI::ComponentCondition::VScroll); + vs.SetTemplate(vst); + vs.SetTag(UI::ComponentTemplate::VScrollTag); + vs.SetSize(vst.GetWidth(), {100, UI::Dimension::Percent}); + vs.SetSizing(UI::ComponentTemplate::Fixed); + vs.SetAnchor(UI::Anchor::TopRight, UI::Anchor::TopRight, UI::Anchor::TopLeft); + vs.SetMargin(Spacing, 0, 0, 0); + auto &hs = temp.AddPlaceholder(4, UI::ComponentCondition::HScroll); + hs.SetPositioning(UI::ComponentTemplate::Absolute); + hs.SetTemplate(hst); + hs.SetTag(UI::ComponentTemplate::HScrollTag); + hs.SetSize({100, UI::Dimension::Percent}, hst.GetHeight()); + hs.SetSizing(UI::ComponentTemplate::Fixed); + hs.SetAnchor(UI::Anchor::None, UI::Anchor::BottomCenter, UI::Anchor::BottomCenter); + hs.SetMargin(0, Spacing, vst.GetWidth()+Spacing, 0); + + { + auto &vp = temp.AddContainer(1, UI::ComponentCondition::HScroll) + .AddIndex(2) + ; + vp.SetTag(UI::ComponentTemplate::ViewPortTag); + vp.SetSize(100, 100, UI::Dimension::Percent); + vp.SetAnchor(UI::Anchor::TopLeft, UI::Anchor::TopLeft, UI::Anchor::TopLeft); + vp.SetClip(true); + vp.SetIndent(0, 0, 0, hst.GetHeight()+Spacing); + } return temp; }
--- a/Source/Gorgon/Widgets/Panel.h Sun Oct 04 11:36:11 2020 +0300 +++ b/Source/Gorgon/Widgets/Panel.h Tue Oct 06 16:02:39 2020 +0300 @@ -172,10 +172,8 @@ virtual void focused() override; - virtual void focuslost() override; - virtual Layer &getlayer() override; void focuschanged() override;
--- a/Source/Gorgon/Widgets/dir.cmake Sun Oct 04 11:36:11 2020 +0300 +++ b/Source/Gorgon/Widgets/dir.cmake Tue Oct 06 16:02:39 2020 +0300 @@ -6,6 +6,9 @@ Checkbox.cpp Common.h + Composer.h + Composer.cpp + Generator.h Generator.cpp @@ -31,4 +34,5 @@ Slider.h Scrollbar.h + )
--- a/Testing/Source/Manual/UI_Generate.cpp Sun Oct 04 11:36:11 2020 +0300 +++ b/Testing/Source/Manual/UI_Generate.cpp Tue Oct 06 16:02:39 2020 +0300 @@ -13,6 +13,7 @@ #include <Gorgon/Widgets/GeometryBoxes.h> #include <Gorgon/Widgets/Progressbar.h> #include <Gorgon/Widgets/Scrollbar.h> +#include <Gorgon/Widgets/Composer.h> #include <Gorgon/UI/RadioControl.h> #include <Gorgon/UI/Organizers/List.h> #include <Gorgon/Graphics/BlankImage.h> @@ -45,6 +46,20 @@ return max.substr(0, (max.length() - min.length()) * value + min.length()); } +class LabelInput : public Widgets::Composer { +public: + LabelInput() { + Resize(l.Size.Width, t.Size.Height); + Add(l); + Add(t); + l.Size.Width = t.Size.Width; + t.Location.X = l.Size.Width + Widgets::Registry::Active().GetSpacing(); + l.Location.Y = (t.Size.Height-l.Size.Height) / 2; + } + + Widgets::Label l; + Widgets::Textbox t; +}; int main() { basic_Application<UI::Window> app("uitest", "UI Generator Test", helptext, 1, 0x80); @@ -58,7 +73,7 @@ generator.Activate();*/ Widgets::Panel blank/*(Gorgon::Widgets::Registry::Panel_Blank)*/; - blank.SetHeight(600); + blank.SetHeight(300); Gorgon::Widgets::Button btn("Save Âj",Gorgon::Widgets::Registry::Button_Regular); Gorgon::Widgets::Button icnbtn("+", Gorgon::Widgets::Registry::Button_Icon); Gorgon::Widgets::Button icnbtn2("Âj", Gorgon::Widgets::Registry::Button_Icon); @@ -171,6 +186,13 @@ addme(blank, bar); addme(blank, scroll1); addme(blank, scroll2); + + LabelInput li; + li.l.Text = "Some input: "; + li.t = "hello"; + + addme(blank, li); + /*Widgets::Progressor<std::string, StringDiv, StringVal, Gorgon::TextualProperty> bar2; bar2.Maximum = "Hello world";