Selaa lähdekoodia

Add layout flex scale to UIElement. Prevent layout updates while loading attributes.

PrimitiveWaste 11 vuotta sitten
vanhempi
sitoutus
283d0d196b

+ 3 - 0
Source/Engine/LuaScript/pkgs/UI/UIElement.pkg

@@ -125,6 +125,7 @@ class UIElement : public Animatable
     void SetLayoutMode(LayoutMode mode);
     void SetLayoutSpacing(int spacing);
     void SetLayoutBorder(const IntRect& border);
+	void SetLayoutFlexScale(const Vector2& scale);
     void SetIndent(int indent);
     void SetIndentSpacing(int indentSpacing);
     void UpdateLayout();
@@ -190,6 +191,7 @@ class UIElement : public Animatable
     LayoutMode GetLayoutMode() const;
     int GetLayoutSpacing() const;
     const IntRect& GetLayoutBorder() const;
+	const Vector2& GetLayoutFlexScale() const;
     unsigned GetNumChildren(bool recursive = false) const;
     int GetDragButtonCombo() const;
     unsigned GetDragButtonCount() const;
@@ -263,6 +265,7 @@ class UIElement : public Animatable
     tolua_property__get_set LayoutMode layoutMode;
     tolua_property__get_set int layoutSpacing;
     tolua_property__get_set IntRect& layoutBorder;
+	tolua_property__get_set Vector2& layoutFlexScale;
     tolua_readonly tolua_property__get_set unsigned numChildren;
     tolua_property__get_set UIElement* parent;
     tolua_readonly tolua_property__get_set UIElement* root;

+ 2 - 0
Source/Engine/Script/APITemplates.h

@@ -1112,6 +1112,8 @@ template <class T> void RegisterUIElement(asIScriptEngine* engine, const char* c
         engine->RegisterObjectMethod(className, "int get_layoutSpacing() const", asMETHOD(T, GetLayoutSpacing), asCALL_THISCALL);
         engine->RegisterObjectMethod(className, "void set_layoutBorder(const IntRect&)", asMETHOD(T, SetLayoutBorder), asCALL_THISCALL);
         engine->RegisterObjectMethod(className, "const IntRect& get_layoutBorder() const", asMETHOD(T, GetLayoutBorder), asCALL_THISCALL);
+        engine->RegisterObjectMethod(className, "void set_layoutFlexScale(const Vector2&)", asMETHOD(T, SetLayoutFlexScale), asCALL_THISCALL);
+        engine->RegisterObjectMethod(className, "const Vector2& get_layoutFlexScale() const", asMETHOD(T, GetLayoutFlexScale), asCALL_THISCALL);
         engine->RegisterObjectMethod(className, "void set_indent(int)", asMETHOD(T, SetIndent), asCALL_THISCALL);
         engine->RegisterObjectMethod(className, "int get_indent() const", asMETHOD(T, GetIndent), asCALL_THISCALL);
         engine->RegisterObjectMethod(className, "void set_indentSpacing(int)", asMETHOD(T, SetIndentSpacing), asCALL_THISCALL);

+ 21 - 5
Source/Engine/UI/UIElement.cpp

@@ -129,6 +129,7 @@ UIElement::UIElement(Context* context) :
     layoutMode_(LM_FREE),
     layoutSpacing_(0),
     layoutBorder_(IntRect::ZERO),
+    layoutFlexScale_(Vector2::ONE),
     resizeNestingLevel_(0),
     layoutNestingLevel_(0),
     layoutMinSize_(0),
@@ -198,6 +199,7 @@ void UIElement::RegisterObject(Context* context)
     ENUM_ACCESSOR_ATTRIBUTE(UIElement, "Layout Mode", GetLayoutMode, SetLayoutMode, LayoutMode, layoutModes, LM_FREE, AM_FILE);
     ACCESSOR_ATTRIBUTE(UIElement, VAR_INT, "Layout Spacing", GetLayoutSpacing, SetLayoutSpacing, int, 0, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_INTRECT, "Layout Border", GetLayoutBorder, SetLayoutBorder, IntRect, IntRect::ZERO, AM_FILE);
+    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_VECTOR2, "Layout Flex Scale", GetLayoutFlexScale, SetLayoutFlexScale, Vector2, Vector2::ONE, AM_FILE);
     ACCESSOR_ATTRIBUTE(UIElement, VAR_INT, "Indent", GetIndent, SetIndent, int, 0, AM_FILE);
     ACCESSOR_ATTRIBUTE(UIElement, VAR_INT, "Indent Spacing", GetIndentSpacing, SetIndentSpacing, int, 16, AM_FILE);
     ATTRIBUTE(UIElement, VAR_VARIANTMAP, "Variables", vars_, Variant::emptyVariantMap, AM_FILE);
@@ -249,6 +251,9 @@ bool UIElement::LoadXML(const XMLElement& source, XMLFile* styleFile, bool setIn
         }
     }
 
+    // Prevent updates while loading attributes
+    DisableLayoutUpdate();
+
     // Then load rest of the attributes from the source
     if (!Animatable::LoadXML(source, setInstanceDefault))
         return false;
@@ -297,6 +302,9 @@ bool UIElement::LoadXML(const XMLElement& source, XMLFile* styleFile, bool setIn
 
     ApplyAttributes();
 
+    EnableLayoutUpdate();
+    UpdateLayout();
+
     return true;
 }
 
@@ -1004,6 +1012,11 @@ void UIElement::SetLayoutBorder(const IntRect& border)
     UpdateLayout();
 }
 
+void UIElement::SetLayoutFlexScale(const Vector2& scale)
+{
+    layoutFlexScale_ = Vector2(Max(scale.x_, 0.0f), Max(scale.y_, 0.0f));
+}
+
 void UIElement::SetIndent(int indent)
 {
     indent_ = indent;
@@ -1034,6 +1047,7 @@ void UIElement::UpdateLayout()
     PODVector<int> sizes;
     PODVector<int> minSizes;
     PODVector<int> maxSizes;
+    PODVector<float> flexScales;
 
     int baseIndentWidth = GetIndentWidth();
 
@@ -1050,10 +1064,11 @@ void UIElement::UpdateLayout()
             sizes.Push(children_[i]->GetWidth() + indent);
             minSizes.Push(children_[i]->GetMinWidth() + indent);
             maxSizes.Push(children_[i]->GetMaxWidth() + indent);
+            flexScales.Push(children_[i]->GetLayoutFlexScale().x_);
             minChildHeight = Max(minChildHeight, children_[i]->GetMinHeight());
         }
 
-        CalculateLayout(positions, sizes, minSizes, maxSizes, GetWidth(), layoutBorder_.left_, layoutBorder_.right_, layoutSpacing_);
+        CalculateLayout(positions, sizes, minSizes, maxSizes, flexScales, GetWidth(), layoutBorder_.left_, layoutBorder_.right_, layoutSpacing_);
 
         int width = Max(GetWidth(), CalculateLayoutParentSize(sizes, layoutBorder_.left_, layoutBorder_.right_, layoutSpacing_));
         int height = Max(GetHeight(), minChildHeight + layoutBorder_.top_ + layoutBorder_.bottom_);
@@ -1091,10 +1106,11 @@ void UIElement::UpdateLayout()
             sizes.Push(children_[i]->GetHeight());
             minSizes.Push(children_[i]->GetMinHeight());
             maxSizes.Push(children_[i]->GetMaxHeight());
+            flexScales.Push(children_[i]->GetLayoutFlexScale().y_);
             minChildWidth = Max(minChildWidth, children_[i]->GetMinWidth() + children_[i]->GetIndentWidth());
         }
 
-        CalculateLayout(positions, sizes, minSizes, maxSizes, GetHeight(), layoutBorder_.top_, layoutBorder_.bottom_, layoutSpacing_);
+        CalculateLayout(positions, sizes, minSizes, maxSizes, flexScales, GetHeight(), layoutBorder_.top_, layoutBorder_.bottom_, layoutSpacing_);
 
         int height = Max(GetHeight(), CalculateLayoutParentSize(sizes, layoutBorder_.top_, layoutBorder_.bottom_, layoutSpacing_));
         int width = Max(GetWidth(), minChildWidth + layoutBorder_.left_ + layoutBorder_.right_);
@@ -1843,7 +1859,7 @@ int UIElement::CalculateLayoutParentSize(const PODVector<int>& sizes, int begin,
 }
 
 void UIElement::CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes, const PODVector<int>& minSizes,
-        const PODVector<int>& maxSizes, int targetSize, int begin, int end, int spacing)
+        const PODVector<int>& maxSizes, const PODVector<float>& flexScales, int targetSize, int begin, int end, int spacing)
 {
     int numChildren = sizes.Size();
     if (!numChildren)
@@ -1859,7 +1875,7 @@ void UIElement::CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes
     // Initial pass
     for (int i = 0; i < numChildren; ++i)
     {
-        int targetSize = targetChildSize;
+        int targetSize = (int)(targetChildSize * flexScales[i]);
         if (remainder)
         {
             acc += add;
@@ -1905,7 +1921,7 @@ void UIElement::CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes
         for (int i = 0; i < numResizable; ++i)
         {
             unsigned index = resizable[i];
-            int targetSize = sizes[index] + errorPerChild;
+            int targetSize = sizes[index] + errorPerChild * flexScales[i];
             if (remainder)
             {
                 acc += add;

+ 7 - 1
Source/Engine/UI/UIElement.h

@@ -287,6 +287,8 @@ public:
     void SetLayoutSpacing(int spacing);
     /// Set layout border.
     void SetLayoutBorder(const IntRect& border);
+    /// Set layout flex scale.
+    void SetLayoutFlexScale(const Vector2& scale);
     /// Set horizontal indentation.
     void SetIndent(int indent);
     /// Set indent spacing (number of pixels per indentation level).
@@ -415,6 +417,8 @@ public:
     int GetLayoutSpacing() const { return layoutSpacing_; }
     /// Return layout border.
     const IntRect& GetLayoutBorder() const { return layoutBorder_; }
+    /// Return layout flex scale.
+    const Vector2& GetLayoutFlexScale() const { return layoutFlexScale_; }
     /// Return number of child elements.
     unsigned GetNumChildren(bool recursive = false) const;
     /// Return child element by index.
@@ -548,6 +552,8 @@ protected:
     int layoutSpacing_;
     /// Layout borders.
     IntRect layoutBorder_;
+    /// Layout flex scale.
+    Vector2 layoutFlexScale_;
     /// Resize nesting level to prevent multiple events and endless loop.
     unsigned resizeNestingLevel_;
     /// Layout update nesting level to prevent endless loop.
@@ -579,7 +585,7 @@ private:
     /// Calculate layout width for resizing the parent element.
     int CalculateLayoutParentSize(const PODVector<int>& sizes, int begin, int end, int spacing);
     /// Calculate child widths/positions in the layout.
-    void CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes, const PODVector<int>& minSizes, const PODVector<int>& maxSizes, int targetWidth, int begin, int end, int spacing);
+    void CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes, const PODVector<int>& minSizes, const PODVector<int>& maxSizes, const PODVector<float>& flexScales, int targetWidth, int begin, int end, int spacing);
     /// Get child element constant position in a layout.
     IntVector2 GetLayoutChildPosition(UIElement* child);
     /// Detach from parent.