Fri, 04 Dec 2020 12:40:22 +0200
* ComponentStack autosize support
--- a/Source/Gorgon/Containers/Collection.h Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/Containers/Collection.h Fri Dec 04 12:40:22 2020 +0200 @@ -379,7 +379,7 @@ /// this method moves the given object in the collection in front of the reference void MoveBefore(long index, long before) { if(before == -1) - before = list.size(); + before = (long)list.size(); if(index>=list.size()) throw std::out_of_range("Invalid location"); if(before>list.size())
--- a/Source/Gorgon/Graphics/FreeType.cpp Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/Graphics/FreeType.cpp Fri Dec 04 12:40:22 2020 +0200 @@ -526,7 +526,7 @@ } bool FreeType::Exists(Glyph g) const { - int c = glyphmap.count(g); + int c = (int)glyphmap.count(g); return c != 0; } @@ -1098,7 +1098,7 @@ loadglyphs('f', true); loadglyphs('j', true); - if(glyphmap.count(0xc2)) { + if(glyphmap.count(0xc2)) { c[0] = 0xc2; } else @@ -1126,6 +1126,6 @@ maxy = g.offset.Y + g.images.regular->GetHeight(); } - return {miny + baseline, maxy - miny}; + return {miny + (int)baseline, maxy - miny}; } } }
--- a/Source/Gorgon/Layer.h Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/Layer.h Fri Dec 04 12:40:22 2020 +0200 @@ -354,13 +354,13 @@ } /// Sets the boundaries of this layer. - void SetBounds(const Geometry::Bounds &bounds) { + virtual void SetBounds(const Geometry::Bounds &bounds) { this->bounds=bounds; } /// Returns the size of the layer Geometry::Size GetSize() const { - return bounds.GetSize(); + return GetBounds().GetSize(); } /// Returns the size of the layer. If any dimension size is @@ -391,31 +391,31 @@ /// Returns the width of the layer int GetWidth() const { - return bounds.Width(); + return GetBounds().Width(); } /// Returns the height of the layer int GetHeight() const { - return bounds.Height(); + return GetBounds().Height(); } /// Returns the current location of the layer Geometry::Point GetLocation() const { - return bounds.TopLeft(); + return GetBounds().TopLeft(); } /// Returns the current location of the layer int GetLeft() const { - return bounds.Left; + return GetBounds().Left; } /// Returns the current location of the layer int GetTop() const { - return bounds.Top; + return GetBounds().Top; } /// Returns the boundaries of the layer - Geometry::Bounds GetBounds() const { + virtual Geometry::Bounds GetBounds() const { return bounds; }
--- a/Source/Gorgon/UI/ComponentStack.cpp Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/UI/ComponentStack.cpp Fri Dec 04 12:40:22 2020 +0200 @@ -2138,6 +2138,12 @@ if(stacksizes[0]) { //initial states get(0).size = size; + + if(autosize.first) + get(0).size.Width = 0; + if(autosize.second) + get(0).size.Height = 0; + get(0).location = {0,0}; get(0).parent = -1; @@ -2172,7 +2178,25 @@ } //start the update from the root - update(get(0), value, -1); + update(get(0), value, -1, autosize.first ? size.Width : -1, autosize.first || autosize.second); + + if(autosize.first || autosize.second) { + auto sz = size; + + if(autosize.first && get(0).size.Width >= 0) + sz.Width = get(0).size.Width; + + if(autosize.second && get(0).size.Height >= 0) + sz.Height = get(0).size.Height; + + + //second run to get everything into proper size + update(get(0), value, -1); + + Layer::Resize(sz); + mouse.Resize(sz); + } + } //update is complete @@ -2198,7 +2222,7 @@ } //location depends on the container location - void ComponentStack::update(Component &parent, const std::array<float, 4> &value, int ind, int textwidth) { + void ComponentStack::update(Component &parent, const std::array<float, 4> &value, int ind, int textwidth, bool autosize) { //get the template const ComponentTemplate &ctemp = parent.GetTemplate(); @@ -2212,11 +2236,11 @@ parent.innersize = parent.size - cont.GetBorderSize(); //if sizing is fixed and the size is 0 and clipping is on, nothing can be displayed - if(cont.GetClip() && cont.GetHorizontalSizing() == cont.Fixed && parent.innersize.Width <= 0) + if(cont.GetClip() && cont.GetHorizontalSizing() == cont.Fixed && parent.innersize.Width <= 0 && !autosize) return; //if sizing is fixed and the size is 0 and clipping is on, nothing can be displayed - if(cont.GetClip() && cont.GetVerticalSizing() == cont.Fixed && parent.innersize.Height <= 0) + if(cont.GetClip() && cont.GetVerticalSizing() == cont.Fixed && parent.innersize.Height <= 0 && !autosize) return; //this function will loop through all components, including the repeats and calls the given @@ -2587,7 +2611,10 @@ //**** Automatic sizing - if((temp.GetHorizontalSizing() != temp.Fixed || temp.GetVerticalSizing() != temp.Fixed) + if( + (temp.GetHorizontalSizing() != temp.Fixed || temp.GetVerticalSizing() != temp.Fixed) || + (parent.size.Width == 0 && autosize && temp.GetType() == ComponentType::Container && temp.GetSize().Width.IsRelative()) || + (parent.size.Height == 0 && autosize && temp.GetType() == ComponentType::Container && temp.GetSize().Height.IsRelative()) ) { auto &st = *storage[&temp]; @@ -2600,19 +2627,19 @@ finalpass = true; if(!size.Width.IsRelative() || stage==final) { - int textwidth = -1; + int tw = -1; //set the dimensions that are not fixed to 0. - if(temp.GetHorizontalSizing() != ComponentTemplate::Fixed) { - textwidth = comp.size.Width; + if(parent.size.Width == 0 || temp.GetHorizontalSizing() != ComponentTemplate::Fixed) { + tw = comp.size.Width ? comp.size.Width : textwidth; comp.size.Width = 0; } - if(temp.GetVerticalSizing() != ComponentTemplate::Fixed) + if(parent.size.Height == 0 || temp.GetVerticalSizing() != ComponentTemplate::Fixed) comp.size.Height = 0; //do an update - update(comp, val, index, textwidth); + update(comp, val, index, tw, true); } } else if(temp.GetType() == ComponentType::Graphics) { @@ -3261,7 +3288,9 @@ ; r += m.Right; - + if(comp.anchtoparent && IsCenter(comp.GetTemplate().GetMyAnchor())) + r += m.Left; + if(w < r) w = r; }); @@ -3285,6 +3314,8 @@ ; b += m.Bottom; + if(comp.anchtoparent && IsMiddle(comp.GetTemplate().GetMyAnchor())) + b += m.Top; if(h < b) { h = b;
--- a/Source/Gorgon/UI/ComponentStack.h Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/UI/ComponentStack.h Fri Dec 04 12:40:22 2020 +0200 @@ -252,6 +252,20 @@ } } + virtual void SetBounds(const Geometry::Bounds &bounds) override { + Resize(bounds.GetSize()); + + Layer::Move(bounds.TopLeft()); + } + + virtual Geometry::Bounds GetBounds() const override { + if(updaterequired) { + const_cast<ComponentStack*>(this)->update(); + } + + return Layer::GetBounds(); + } + /// Returns the template used by this stack const Template &GetTemplate() const { return temp; @@ -400,18 +414,35 @@ /// Removes the fixed size for a set tagged component void RemoveTagSize(ComponentTemplate::Tag tag) { tagsizes.erase(tag); + Update(); } /// Enables text wrapping on a specific tag, default is enabled. void EnableTagWrap(ComponentTemplate::Tag tag) { tagnowrap.erase(tag); + Update(); } /// Disables text wrapping on a specific tag, default is enabled. void DisableTagWrap(ComponentTemplate::Tag tag) { tagnowrap.insert(tag); } + + /// Sets whether the ComponentStack should be autosized. Autosize + /// uses the set size for text width. + void SetAutoSize(bool horizontal, bool vertical) { + if(autosize == std::make_pair(horizontal, vertical)) + return; + + autosize = {horizontal, vertical}; + Update(); + } + /** @name Events + * These are events that can be handled + * + * @{ + */ /// Sets a function to be called before update check void SetFrameEvent(std::function<void()> handler) { @@ -453,6 +484,8 @@ render_fn = std::function<void()>(); } + /// @} + /** @name Mouse Events * These function will allow handling mouse events. If the mouse event is originating from a * substack, it will have a tag other than NoTag. If the tag for the substack is set NoTag, @@ -553,7 +586,7 @@ /// @} - + /// This event is fired when condition is changed. Event<ComponentStack> ConditionChanged; @@ -588,7 +621,7 @@ void update(); ///updates a specific container component - void update(Component &parent, const std::array<float, 4> &value, int ind, int textwidth = -1); + void update(Component &parent, const std::array<float, 4> &value, int ind, int textwidth = -1, bool autosize = false); ///renders the given component, rendering will use parent layer if the component does not have its own layer. Index is for ///repeated components, it is the index of the repeat to be rendered. Unlike Layer::Render function, this function does not @@ -676,7 +709,7 @@ ///Dictates the speed which values reach to the target value. valuespeed = 0 disables animation std::array<float, 4> valuespeed = {{0.f, 0.f, 0.f, 0.f}}; - ///?? + ///Get value returns the target value if set the to true bool returntarget = false; ///Number of elements in each stack @@ -690,6 +723,9 @@ ///Whether component stack will be handling the mouse events bool handlingmouse = false; + + ///When set, component stack will resize itself to fit components. + std::pair<bool, bool> autosize = {false, false}; ///Size of the component stack Geometry::Size size;
--- a/Source/Gorgon/UI/Organizers/Flow.h Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/UI/Organizers/Flow.h Fri Dec 04 12:40:22 2020 +0200 @@ -103,7 +103,7 @@ /// Returns the number of breaks at the given index. int BreakCount(int index) const { - return breaks.count(index); + return (int)breaks.count(index); } /// Removes all breaks in the organizer
--- a/Source/Gorgon/UI/Template.cpp Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/UI/Template.cpp Fri Dec 04 12:40:22 2020 +0200 @@ -349,7 +349,37 @@ * */ - PlaceholderTemplate& Template::AddPlaceholder(int index, ComponentCondition from, ComponentCondition to){ + + + + Template::Template(Template &&other) : + ChangedEvent(std::move(other.ChangedEvent)), + Name(std::move(other.Name)), + components(std::move(other.components)), + tokens(std::move(other.tokens)), + durations(std::move(other.durations)), + xsizing(std::move(other.xsizing)), + ysizing(std::move(other.ysizing)), + size(std::move(other.size)), + additional(std::move(other.additional)), + spacing(std::move(other.spacing)), + unitwidth(std::move(other.unitwidth)), + resizehandlesize(std::move(other.resizehandlesize)) + { + auto token = tokens.begin(); + for(auto &c : components) { + c.ChangedEvent.Unregister(*token); + token++; + } + tokens.clear(); + for(auto &c : components) { + tokens.push_back( + c.ChangedEvent.Register(ChangedEvent, &Event<Template>::operator ()) + ); + } + } + + PlaceholderTemplate& Template::AddPlaceholder(int index, ComponentCondition from, ComponentCondition to){ auto obj = new PlaceholderTemplate(); components.Add(obj);
--- a/Source/Gorgon/UI/Template.h Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/UI/Template.h Fri Dec 04 12:40:22 2020 +0200 @@ -411,9 +411,10 @@ Template() { } - Template(Template &&) = default; + //Move constructor. Moving is only allowed on construction + Template(Template &&other); - Template &operator =(Template &&) = default; + Template &operator =(Template &&) = delete; /// Destructor ~Template() { @@ -632,6 +633,8 @@ int spacing = 4; int unitwidth = 25; int resizehandlesize = -1; + + //Do not forget to update move constructor! }; /// Defines an object according to the Box Model.
--- a/Source/Gorgon/Widgets/Generator.cpp Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/Widgets/Generator.cpp Fri Dec 04 12:40:22 2020 +0200 @@ -163,12 +163,17 @@ void SimpleGenerator::UpdateBorders(bool smooth) { Border.Width = (int)std::max(std::round(regularrenderer->GetLineThickness()*2.6f), 1.f); - ShapeBorder = std::max(regularrenderer->GetLineThickness()*2.6f, 1.f); + ShapeBorder = std::max((regularrenderer->GetLineThickness()+ObjectHeight/18.f)*1.3f, 1.f); //limit the thickness after 2. if(Border.Width > 2) { Border.Width = (int)std::max(std::round(regularrenderer->GetLineThickness()*2.4f), 1.f); - ShapeBorder = std::max(regularrenderer->GetLineThickness()*2.4f, 1.f); + } + if(ShapeBorder > 2.f) { + ShapeBorder = std::max((regularrenderer->GetLineThickness()+ObjectHeight/18.f)*1.2f, 1.f); + + if(ShapeBorder < 2.f) + ShapeBorder = 2.f; } ObjectBorder = Border.Width; @@ -594,7 +599,6 @@ auto setupborder = [&](auto &anim, UI::ComponentCondition condition) { auto &bg = temp.AddContainer(1, condition); bg.Background.SetAnimation(anim); - bg.SetSize(100, 100, UI::Dimension::Percent); bg.SetPositioning(UI::ComponentTemplate::Absolute); }; @@ -607,7 +611,6 @@ .AddIndex(3) //clip .AddIndex(4) //focus ; - boxed.SetSize(100, 100, UI::Dimension::Percent); boxed.SetBorderSize(Border.Width); boxed.SetPadding(std::max(Border.Radius / 2, Focus.Spacing)); boxed.SetPositioning(UI::ComponentTemplate::Absolute); @@ -617,18 +620,15 @@ ; clip.SetClip(true); clip.SetPadding(Focus.Spacing + Focus.Width); - clip.SetSize(100, 100, UI::Dimension::Percent); //Contents auto &content = temp.AddContainer(5, UI::ComponentCondition::Always) .AddIndex(6) //icon .AddIndex(7) //text ; - content.SetSize(100, 100, UI::Dimension::Percent); - content.SetSize(100, 100, UI::Dimension::Percent); - content.SetSizing(UI::ComponentTemplate::Automatic); content.SetPositioning(UI::ComponentTemplate::Absolute); content.SetAnchor(UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter); + content.SetSizing(UI::ComponentTemplate::Automatic); //Icon container auto &iconcont = temp.AddContainer(6, UI::ComponentCondition::Icon1IsSet) @@ -655,7 +655,6 @@ txt.SetColor(color); txt.SetAnchor(UI::Anchor::MiddleRight, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft); txt.SetDataEffect(UI::ComponentTemplate::Text); - txt.SetSize(100, 100, UI::Dimension::Percent); txt.SetSizing(UI::ComponentTemplate::ShrinkOnly); }; @@ -842,12 +841,12 @@ //these coordinates are designed to look good across many different //sizes covering a wide range Geometry::PointList<Geometry::Pointf> tick ={ - {ShapeBorder*2.4f, ObjectHeight/2.f}, - {ObjectHeight*0.45f, ObjectHeight-ShapeBorder*2.4f}, - {ObjectHeight-ShapeBorder*2.4f, ShapeBorder*2.4f} + {ShapeBorder*2.2f, ObjectHeight/2.f}, + {ObjectHeight*0.45f, ObjectHeight-ShapeBorder*2.2f}, + {ObjectHeight-ShapeBorder*2.4f, ShapeBorder*2.2f} }; - if(ObjectHeight - ShapeBorder*4.8f < 3) { + if(ObjectHeight - ShapeBorder*4.6f < 3) { CGI::Polyfill(*icon, Geometry::PointList<Geometry::Pointf>{ {ObjectBorder*2.f, ObjectBorder*2.f}, {ObjectHeight - ObjectBorder*2.f, ObjectBorder*2.f}, @@ -1020,7 +1019,7 @@ state2.SetPositioning(UI::ComponentTemplate::Absolute); state2.SetAnchor(UI::Anchor::None, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft); - float outer_r = ObjectHeight / 2.f - 0.5; + float outer_r = ObjectHeight / 2.f - 0.5f; int borderstart_r = int(ceil(outer_r - ObjectBorder)); float inner_r = std::max(outer_r - ObjectBorder - std::max(Spacing / 2.f, 1.5f), 1.5f); @@ -1753,8 +1752,8 @@ Geometry::PointList<Geometry::Pointf> border; float off = 0; - float w = icon->GetWidth(); - float h = icon->GetHeight()-off; + float w = (float)icon->GetWidth(); + float h = (float)icon->GetHeight()-off; if(upwards) { border = { @@ -1953,7 +1952,7 @@ icon->Clear(); - float off = ObjectBorder; + float off = (float)ObjectBorder; float s = float(bs); float mid = s/2.f;
--- a/Source/Gorgon/Widgets/Listbox.h Sun Nov 29 16:21:07 2020 +0200 +++ b/Source/Gorgon/Widgets/Listbox.h Fri Dec 04 12:40:22 2020 +0200 @@ -520,7 +520,7 @@ auto end() { auto &me = dynamic_cast<F_ &>(l); - return ItemIterator(me, l.selected, l.selected.size()); + return ItemIterator(me, l.selected, (long)l.selected.size()); } auto begin() const { @@ -530,7 +530,7 @@ auto end() const { auto &me = dynamic_cast<F_ &>(l); - return ConstItemIterator(me, l.selected, l.selected.size()); + return ConstItemIterator(me, l.selected, (long)l.selected.size()); } private: @@ -1222,7 +1222,7 @@ virtual ~LBSTR_STLVector() {} long getsize() const { - return storage.size(); + return (long)storage.size(); } T_ &getelm(long index) {
--- a/Testing/Source/Manual/UI_Component.cpp Sun Nov 29 16:21:07 2020 +0200 +++ b/Testing/Source/Manual/UI_Component.cpp Fri Dec 04 12:40:22 2020 +0200 @@ -1260,7 +1260,7 @@ cont2.SetAnchor(Gorgon::UI::Anchor::None, Gorgon::UI::Anchor::TopLeft, Gorgon::UI::Anchor::TopLeft); cont2.SetPosition(0, 0, Gorgon::UI::Dimension::Percent); cont2.SetValueModification(Gorgon::UI::ComponentTemplate::ModifyPosition); - cont2.SetValueRange(0, 0.2, 0.8); + cont2.SetValueRange(0, 0.2f, 0.8f); @@ -1369,7 +1369,7 @@ cont2.SetPosition(0, 0, Gorgon::UI::Dimension::Percent); cont2.SetValueModification(Gorgon::UI::ComponentTemplate::ModifyPosition); cont2.SetValueOrdering(3, 0, 0, 0); - cont2.SetValueRange(0, 0.2, 0.8); + cont2.SetValueRange(0, 0.2f, 0.8f); auto &stack = *new ComponentStack(temp); @@ -2198,7 +2198,7 @@ layer.Add(stack); - stack.SetValue(0.2, 0.5); + stack.SetValue(0.2f, 0.5f); auto b = stack.TagBounds(Gorgon::UI::ComponentTemplate::LeftTag); @@ -2229,7 +2229,7 @@ layer.Add(stack); - stack.SetValue(0.2, 0.5); + stack.SetValue(0.2f, 0.5f); auto b = stack.TagBounds(Gorgon::UI::ComponentTemplate::LeftTag); @@ -2777,6 +2777,7 @@ , stack}; } + TestData test_anchacc(Layer &layer) { auto &temp = *new Template; temp.SetSize(60, 60); @@ -2809,7 +2810,6 @@ return {"Anchoring accuracy", "Size 10x20, 10x19 and 10x20 objects on a 60x60 white background, second could be 0 or 1px from the top, first and third should be touching to the top.", stack}; } - TestData test_ignored(Layer &layer) { auto &temp = *new Template; temp.SetSize(60, 60); @@ -2846,6 +2846,434 @@ } +TestData test_autosizedstack(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(60, 60); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always); + cont1.AddIndex(1); + cont1.Background.SetAnimation(whiteimg()); + cont1.SetClip(true); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetSize(20, 20); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + auto s = stack.GetSize(); + + return {"Autosized stack simple", String::Concat((s.operator ==({20, 20}) ? "Passed" : "Failed"), ". Size = ", s, ". Size 20x20 white background."), stack}; +} + +TestData test_autosizedstack_double(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(60, 60); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always) + .AddIndex(1) + .AddIndex(2) + ; + cont1.Background.SetAnimation(whiteimg()); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetSize(20, 20); + cont2.Background.SetAnimation(greenimg()); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont2.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + + auto &cont3 = temp.AddContainer(2, Gorgon::UI::ComponentCondition::Always); + cont3.SetSize(20, 20); + cont3.Background.SetAnimation(redimg()); + cont3.SetAnchor(Gorgon::UI::Anchor::BottomRight, Gorgon::UI::Anchor::TopLeft, Gorgon::UI::Anchor::TopLeft); + cont3.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont3.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + + auto s = stack.GetSize(); + + return {"Autosized stack double", String::Concat((s.operator ==({40, 40}) ? "Passed" : "Failed"), ". Size = ", s, ". Size 40x40 white background with 20x20 green at top left, red at bottom right."), stack}; +} + +TestData test_autosizedstack_padding(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(20, 20); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always) + .AddIndex(1) + .AddIndex(2) + ; + cont1.Background.SetAnimation(whiteimg()); + cont1.SetPadding(10); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetSize(20, 20); + cont2.Background.SetAnimation(greenimg()); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont2.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + + auto &cont3 = temp.AddContainer(2, Gorgon::UI::ComponentCondition::Always); + cont3.SetSize(20, 20); + cont3.Background.SetAnimation(redimg()); + cont3.SetAnchor(Gorgon::UI::Anchor::BottomRight, Gorgon::UI::Anchor::TopLeft, Gorgon::UI::Anchor::TopLeft); + cont3.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont3.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + cont3.SetPosition(10, 10); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + + auto s = stack.GetSize(); + + return {"Autosized stack padding", String::Concat((s.operator ==({70, 70}) ? "Passed" : "Failed"), ". Size = ", s, ". Size 70x70 white background with 20x20 green at top left, red at bottom right. green and red should not touch"), stack}; +} + +TestData test_autosizedstack_border(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(20, 20); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always) + .AddIndex(1) + .AddIndex(2) + ; + cont1.Background.SetAnimation(whiteimg()); + cont1.SetBorderSize(10); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetSize(20, 20); + cont2.Background.SetAnimation(greenimg()); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont2.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + + auto &cont3 = temp.AddContainer(2, Gorgon::UI::ComponentCondition::Always); + cont3.SetSize(20, 20); + cont3.Background.SetAnimation(redimg()); + cont3.SetAnchor(Gorgon::UI::Anchor::BottomRight, Gorgon::UI::Anchor::TopLeft, Gorgon::UI::Anchor::TopLeft); + cont3.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont3.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + cont3.SetPosition(10, 10); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + + auto s = stack.GetSize(); + + return {"Autosized stack border", String::Concat((s.operator ==({70, 70}) ? "Passed" : "Failed"), ". Size = ", s, ". Size 70x70 white background with 20x20 green at top left, red at bottom right. green and red should not touch"), stack}; +} + +TestData test_autosizedstack_nested(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(10, 10); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always) + .AddIndex(3) + ; + cont1.Background.SetAnimation(whiteimg()); + cont1.SetPadding(10); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetSize(20, 20); + cont2.Background.SetAnimation(greenimg()); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont2.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + + auto &cont3 = temp.AddContainer(2, Gorgon::UI::ComponentCondition::Always); + cont3.SetSize(20, 20); + cont3.Background.SetAnimation(redimg()); + cont3.SetAnchor(Gorgon::UI::Anchor::BottomRight, Gorgon::UI::Anchor::TopLeft, Gorgon::UI::Anchor::TopLeft); + cont3.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont3.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + + auto &cont4 = temp.AddContainer(3, Gorgon::UI::ComponentCondition::Always) + .AddIndex(1) + .AddIndex(2) + ; + cont4.SetPositioning(Gorgon::UI::ComponentTemplate::Absolute); + cont4.Background.SetAnimation(yellowimg()); + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + + auto s = stack.GetSize(); + + return {"Autosized stack nested", String::Concat((s.operator ==({60, 60}) ? "Passed" : "Failed"), ". Size = ", s, ". Size 60x60 white background with 20x20 green at top left, red at bottom right, yellow at other corners."), stack}; +} + +TestData test_autosizedstack_text(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(100, 60); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always); + cont1.AddIndex(1); + cont1.Background.SetAnimation(whiteimg()); + cont1.SetPadding(10); + + static Graphics::BitmapFont fnt; + fnt.SetGlyphSpacing(10); + fnt.AddGlyph('1', greenimg1x2()); + fnt.AddGlyph('2', greenimg2x2()); + fnt.SetLineGap(25); + fnt.SetBaseline(20); + fnt.SetHeight(20); + + auto &cont2 = temp.AddTextholder(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetRenderer(fnt); + cont2.SetText("12"); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Automatic); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + auto s = stack.GetSize(); + + return {"Autosized stack text", String::Concat((s.operator ==({70, 45}) ? "Passed" : "Failed"), ". Size = ", s, ". Two green rectangles on 70x45 white background."), stack}; +} + +TestData test_autosizedstack_textnested(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(100, 60); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always); + cont1.AddIndex(1); + cont1.Background.SetAnimation(whiteimg()); + cont1.SetPadding(10); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.AddIndex(2); + + static Graphics::BitmapFont fnt; + fnt.SetGlyphSpacing(10); + fnt.AddGlyph('1', greenimg1x2()); + fnt.AddGlyph('2', greenimg2x2()); + fnt.SetLineGap(25); + fnt.SetBaseline(20); + fnt.SetHeight(20); + + auto &cont3 = temp.AddTextholder(2, Gorgon::UI::ComponentCondition::Always); + cont3.SetRenderer(fnt); + cont3.SetText("12"); + cont3.SetSizing(Gorgon::UI::ComponentTemplate::Automatic); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + auto s = stack.GetSize(); + + return {"Autosized stack nested text", String::Concat((s.operator ==({70, 45}) ? "Passed" : "Failed"), ". Size = ", s, ". Two green rectangles on 70x45 white background."), stack}; +} + +TestData test_autosizedstack_textnested_sister(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(100, 60); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always); + cont1.AddIndex(1); + cont1.AddIndex(3); + cont1.Background.SetAnimation(whiteimg()); + cont1.SetPadding(10); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.AddIndex(2); + + static Graphics::BitmapFont fnt; + fnt.SetGlyphSpacing(10); + fnt.AddGlyph('1', greenimg1x2()); + fnt.AddGlyph('2', greenimg2x2()); + fnt.SetLineGap(25); + fnt.SetBaseline(20); + fnt.SetHeight(20); + + auto &cont3 = temp.AddTextholder(2, Gorgon::UI::ComponentCondition::Always); + cont3.SetRenderer(fnt); + cont3.SetText("12"); + cont3.SetSizing(Gorgon::UI::ComponentTemplate::Automatic); + + auto &cont4 = temp.AddContainer(3, Gorgon::UI::ComponentCondition::Always); + cont4.SetSize(100, 100, Gorgon::UI::Dimension::Percent); + cont4.SetPositioning(Gorgon::UI::ComponentTemplate::Absolute); + cont4.Background.SetAnimation(yellowimg()); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + auto s = stack.GetSize(); + + return {"Autosized stack nested text with a sister", String::Concat((s.operator ==({70, 45}) ? "Passed" : "Failed"), ". Size = ", s, ". Two green rectangles on 70x45 white background overlayed by a 50x25 yellow rectangle."), stack}; +} + +TestData test_autosizedstack_textdoublenested(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(100, 60); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always); + cont1.AddIndex(1); + cont1.Background.SetAnimation(whiteimg()); + cont1.SetPadding(5); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.AddIndex(2); + cont2.SetPadding(5); + + auto &cont3 = temp.AddContainer(2, Gorgon::UI::ComponentCondition::Always); + cont3.AddIndex(3); + cont3.SetPadding(5); + + static Graphics::BitmapFont fnt; + fnt.SetGlyphSpacing(10); + fnt.AddGlyph('1', greenimg1x2()); + fnt.AddGlyph('2', greenimg2x2()); + fnt.SetLineGap(25); + fnt.SetBaseline(20); + fnt.SetHeight(20); + + auto &text = temp.AddTextholder(3, Gorgon::UI::ComponentCondition::Always); + text.SetRenderer(fnt); + text.SetText("12"); + text.SetSizing(Gorgon::UI::ComponentTemplate::Automatic); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + auto s = stack.GetSize(); + + return {"Autosized stack double nested text", String::Concat((s.operator ==({80, 55}) ? "Passed" : "Failed"), ". Size = ", s, ". Two green rectangles on 80x55 white background."), stack}; +} + +TestData test_autosizedstack_clip(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(60, 60); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always); + cont1.AddIndex(1); + cont1.Background.SetAnimation(whiteimg()); + cont1.SetClip(true); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetSize(20, 20); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + auto s = stack.GetSize(); + + return {"Autosized stack clipping", String::Concat((s.operator ==({20, 20}) ? "Passed" : "Failed"), ". Size = ", s, ". Size 20x20 white background."), stack}; +} + +TestData test_autosizedstack_complex(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(100, 60); + + auto &cont0 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always); + cont0.AddIndex(1); + cont0.AddIndex(2); + cont0.Background.SetAnimation(whiteimg()); + + auto &cont1 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont1.SetPositioning(Gorgon::UI::ComponentTemplate::Absolute); + + auto &cont2 = temp.AddContainer(2, Gorgon::UI::ComponentCondition::Always); + cont2.AddIndex(3); + cont2.AddIndex(4); + cont2.SetPadding(3); + cont2.SetBorderSize(2); + cont2.SetPositioning(Gorgon::UI::ComponentTemplate::Absolute); + + auto &cont3 = temp.AddContainer(3, Gorgon::UI::ComponentCondition::Always); + cont3.AddIndex(5); + cont3.SetPadding(5); + cont3.SetClip(true); + + auto &cont5 = temp.AddContainer(5, Gorgon::UI::ComponentCondition::Always); + cont5.AddIndex(6); + cont5.AddIndex(7); + cont5.SetSizing(Gorgon::UI::ComponentTemplate::Automatic); + cont5.SetPositioning(Gorgon::UI::ComponentTemplate::Absolute); + cont5.SetAnchor(UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter); + + auto &cont6 = temp.AddContainer(6, Gorgon::UI::ComponentCondition::Icon1IsSet); + + static Graphics::BitmapFont fnt; + fnt.SetGlyphSpacing(10); + fnt.AddGlyph('1', greenimg1x2()); + fnt.AddGlyph('2', greenimg2x2()); + fnt.SetLineGap(25); + fnt.SetBaseline(20); + fnt.SetHeight(20); + + auto &text = temp.AddTextholder(7, Gorgon::UI::ComponentCondition::Always); + text.SetRenderer(fnt); + text.SetText("12"); + //text.SetSizing(Gorgon::UI::ComponentTemplate::Automatic); + + auto &cont4 = temp.AddContainer(4, Gorgon::UI::ComponentCondition::Always); + cont4.SetPadding(5); + cont4.SetPositioning(Gorgon::UI::ComponentTemplate::Absolute); + + + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + auto s = stack.GetSize(); + + return {"Autosized stack complex", String::Concat((s.operator ==({70, 45}) ? "Passed" : "Failed"), ". Size = ", s, ". Two green rectangles on 70x45 white background."), stack}; +} + +TestData test_autosizedstack_center(Layer &layer) { + auto &temp = *new Template; + temp.SetSize(30, 30); + + auto &cont1 = temp.AddContainer(0, Gorgon::UI::ComponentCondition::Always) + .AddIndex(1) + .AddIndex(2) + ; + cont1.Background.SetAnimation(whiteimg()); + cont1.SetPadding(10, 20); + + auto &cont2 = temp.AddContainer(1, Gorgon::UI::ComponentCondition::Always); + cont2.SetSize(20, 30); + cont2.Background.SetAnimation(greenimg()); + cont2.SetSizing(Gorgon::UI::ComponentTemplate::Fixed); + cont2.SetPositioning(Gorgon::UI::ComponentTemplate::Relative); + cont2.SetAnchor(UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter); + + auto &stack = *new ComponentStack(temp); + stack.SetAutoSize(true, true); + + layer.Add(stack); + + auto s = stack.GetSize(); + + return {"Autosized stack center aligned", String::Concat((s.operator ==({40, 70}) ? "Passed" : "Failed"), ". Size = ", s, ". Size 40x70 white background with 20x30 green at center"), stack}; +} std::vector<std::function<TestData(Layer &)>> tests = { //BEGIN layout @@ -2974,9 +3402,26 @@ &test_autosize_cont_text, //END + //BEGIN Autosized stack + &test_autosizedstack, + &test_autosizedstack_double, + &test_autosizedstack_padding, + &test_autosizedstack_border, + &test_autosizedstack_nested, + &test_autosizedstack_text, + &test_autosizedstack_textnested, + &test_autosizedstack_textnested_sister, + &test_autosizedstack_textdoublenested, + &test_autosizedstack_clip, + &test_autosizedstack_complex, + &test_autosizedstack_center, + //END + /* + //BEGIN Extra &test_anchacc, &test_ignored, - + //END + */ }; //END tests
--- a/Testing/Source/Manual/UI_Generate.cpp Sun Nov 29 16:21:07 2020 +0200 +++ b/Testing/Source/Manual/UI_Generate.cpp Fri Dec 04 12:40:22 2020 +0200 @@ -93,7 +93,7 @@ ///Blank Panel & elements with Registry & Regulars /*Widgets::SimpleGenerator generator; generator.Density = 5; - generator.Init(9); + generator.Init(16, "freesans"); generator.UpdateBorders(); generator.Border.Width = 2; generator.Border.Radius = 4;