Преглед на файлове

Adding alignment and auto-sizing to UI controls.
Using these features in the particles sample.

Adam Blake преди 13 години
родител
ревизия
6a5cad10f4
променени са 8 файла, в които са добавени 223 реда и са изтрити 19 реда
  1. 43 2
      gameplay/src/AbsoluteLayout.cpp
  2. 95 2
      gameplay/src/Control.cpp
  3. 32 0
      gameplay/src/Control.h
  4. 1 1
      gameplay/src/Font.cpp
  5. 1 1
      gameplay/src/Font.h
  6. 10 0
      gameplay/src/Form.cpp
  7. 13 13
      gameplay/src/Theme.cpp
  8. 28 0
      gameplay/src/VerticalLayout.cpp

+ 43 - 2
gameplay/src/AbsoluteLayout.cpp

@@ -45,9 +45,50 @@ namespace gameplay
         unsigned int controlsCount = controls.size();
         for (unsigned int i = 0; i < controlsCount; i++)
         {
-            if (controls[i]->isDirty())
+            Control* control = controls[i];
+
+            if (control->_alignment != Control::ALIGN_TOP_LEFT ||
+                control->_autoWidth || control->_autoHeight)
+            {
+                Rectangle controlBounds = control->getBounds();
+                const Rectangle& containerBounds = container->getBounds();
+
+                if (control->_autoWidth)
+                {
+                    controlBounds.width = containerBounds.width;
+                }
+
+                if (control->_autoHeight)
+                {
+                    controlBounds.height = containerBounds.height;
+                }
+
+                // Vertical alignment
+                if ((control->_alignment & Control::ALIGN_BOTTOM) == Control::ALIGN_BOTTOM)
+                {
+                    controlBounds.y = containerBounds.height - controlBounds.height;
+                }
+                else if ((control->_alignment & Control::ALIGN_VCENTER) == Control::ALIGN_VCENTER)
+                {
+                    controlBounds.y = containerBounds.height / 2.0f - controlBounds.height / 2.0f;
+                }
+
+                // Horizontal alignment
+                if ((control->_alignment & Control::ALIGN_RIGHT) == Control::ALIGN_RIGHT)
+                {
+                    controlBounds.x = containerBounds.width - controlBounds.width;
+                }
+                else if ((control->_alignment & Control::ALIGN_HCENTER) == Control::ALIGN_HCENTER)
+                {
+                    controlBounds.x = containerBounds.width / 2.0f - controlBounds.width / 2.0f;
+                }
+
+                control->setBounds(controlBounds);
+            }
+
+            if (control->isDirty())
             {
-                controls[i]->update(container->getClip());
+                control->update(container->getClip());
             }
         }
     }

+ 95 - 2
gameplay/src/Control.cpp

@@ -36,10 +36,31 @@ namespace gameplay
     {
         _style = style;
 
+        _alignment = getAlignment(properties->getString("alignment"));
+        _autoWidth = properties->getBool("autoWidth");
+        _autoHeight = properties->getBool("autoHeight");
+
         Vector2 position;
         Vector2 size;
-        properties->getVector2("position", &position);
-        properties->getVector2("size", &size);
+        if (properties->exists("position"))
+        {
+            properties->getVector2("position", &position);
+        }
+        else
+        {
+            position.x = properties->getFloat("x");
+            position.y = properties->getFloat("y");
+        }
+        
+        if (properties->exists("size"))
+        {
+            properties->getVector2("size", &size);
+        }
+        else
+        {
+            size.x = properties->getFloat("width");
+            size.y = properties->getFloat("height");
+        }
         _bounds.set(position.x, position.y, size.x, size.y);
 
         _state = Control::getState(properties->getString("state"));
@@ -925,4 +946,76 @@ namespace gameplay
         _style = new Theme::Style(*_style);
         _styleOverridden = true;
     }
+
+    Control::Alignment Control::getAlignment(const char* alignment)
+    {
+        if (!alignment)
+        {
+            return Control::ALIGN_TOP_LEFT;
+        }
+
+        if (strcmp(alignment, "ALIGN_LEFT") == 0)
+        {
+            return Control::ALIGN_LEFT;
+        }
+        else if (strcmp(alignment, "ALIGN_HCENTER") == 0)
+        {
+            return Control::ALIGN_HCENTER;
+        }
+        else if (strcmp(alignment, "ALIGN_RIGHT") == 0)
+        {
+            return Control::ALIGN_RIGHT;
+        }
+        else if (strcmp(alignment, "ALIGN_TOP") == 0)
+        {
+            return Control::ALIGN_TOP;
+        }
+        else if (strcmp(alignment, "ALIGN_VCENTER") == 0)
+        {
+            return Control::ALIGN_VCENTER;
+        }
+        else if (strcmp(alignment, "ALIGN_BOTTOM") == 0)
+        {
+            return Control::ALIGN_BOTTOM;
+        }
+        else if (strcmp(alignment, "ALIGN_TOP_LEFT") == 0)
+        {
+            return Control::ALIGN_TOP_LEFT;
+        }
+        else if (strcmp(alignment, "ALIGN_VCENTER_LEFT") == 0)
+        {
+            return Control::ALIGN_VCENTER_LEFT;
+        }
+        else if (strcmp(alignment, "ALIGN_BOTTOM_LEFT") == 0)
+        {
+            return Control::ALIGN_BOTTOM_LEFT;
+        }
+        else if (strcmp(alignment, "ALIGN_TOP_HCENTER") == 0)
+        {
+            return Control::ALIGN_TOP_HCENTER;
+        }
+        else if (strcmp(alignment, "ALIGN_VCENTER_HCENTER") == 0)
+        {
+            return Control::ALIGN_VCENTER_HCENTER;
+        }
+        else if (strcmp(alignment, "ALIGN_BOTTOM_HCENTER") == 0)
+        {
+            return Control::ALIGN_BOTTOM_HCENTER;
+        }
+        else if (strcmp(alignment, "ALIGN_TOP_RIGHT") == 0)
+        {
+            return Control::ALIGN_TOP_RIGHT;
+        }
+        else if (strcmp(alignment, "ALIGN_VCENTER_RIGHT") == 0)
+        {
+            return Control::ALIGN_VCENTER_RIGHT;
+        }
+        else if (strcmp(alignment, "ALIGN_BOTTOM_RIGHT") == 0)
+        {
+            return Control::ALIGN_BOTTOM_RIGHT;
+        }
+
+        // Default.
+        return Control::ALIGN_TOP_LEFT;
+    }
 }

+ 32 - 0
gameplay/src/Control.h

@@ -53,6 +53,33 @@ public:
         DISABLED = 0x08,
     };
 
+    /**
+     * Defines the set of alignments for positioning controls and justifying text.
+     */
+    enum Alignment
+    {
+        // Specify horizontal alignment, use default vertical alignment (ALIGN_TOP).
+        ALIGN_LEFT = 0x01,
+        ALIGN_HCENTER = 0x02,
+        ALIGN_RIGHT = 0x04,
+    
+        // Specify vertical alignment, use default horizontal alignment (ALIGN_LEFT).
+        ALIGN_TOP = 0x10,
+        ALIGN_VCENTER = 0x20,
+        ALIGN_BOTTOM = 0x40,
+
+        // Specify both vertical and horizontal alignment.
+        ALIGN_TOP_LEFT = ALIGN_TOP | ALIGN_LEFT,
+        ALIGN_VCENTER_LEFT = ALIGN_VCENTER | ALIGN_LEFT,
+        ALIGN_BOTTOM_LEFT = ALIGN_BOTTOM | ALIGN_LEFT,
+        ALIGN_TOP_HCENTER = ALIGN_TOP | ALIGN_HCENTER,
+        ALIGN_VCENTER_HCENTER = ALIGN_VCENTER | ALIGN_HCENTER,
+        ALIGN_BOTTOM_HCENTER = ALIGN_BOTTOM | ALIGN_HCENTER,
+        ALIGN_TOP_RIGHT = ALIGN_TOP | ALIGN_RIGHT,
+        ALIGN_VCENTER_RIGHT = ALIGN_VCENTER | ALIGN_RIGHT,
+        ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT
+    };
+
     /**
      * A constant used for setting themed attributes on all control states simultaneously.
      */
@@ -709,6 +736,8 @@ protected:
      */
     void notifyListeners(Listener::EventType eventType);
 
+    static Alignment getAlignment(const char* alignment);
+
     std::string _id;
     State _state;           // Determines overlay used during draw().
     Rectangle _bounds;      // Position, relative to parent container's clipping window, and desired size.
@@ -717,6 +746,9 @@ protected:
     Rectangle _clip;        // Clipping window of this control's content, after clipping.
     bool _dirty;
     bool _consumeTouchEvents;
+    Alignment _alignment;
+    bool _autoWidth;
+    bool _autoHeight;
     Theme::Style* _style;
     std::map<Listener::EventType, std::list<Listener*>*>* _listeners;
 

+ 1 - 1
gameplay/src/Font.cpp

@@ -1568,7 +1568,7 @@ SpriteBatch* Font::getSpriteBatch()
     return _batch;
 }
 
-Font::Justify Font::getJustifyFromString(const char* justify)
+Font::Justify Font::getJustify(const char* justify)
 {
     if (!justify)
     {

+ 1 - 1
gameplay/src/Font.h

@@ -191,7 +191,7 @@ public:
 
     SpriteBatch* getSpriteBatch();
 
-    static Justify getJustifyFromString(const char* justify);
+    static Justify getJustify(const char* justify);
 
 
 private:

+ 10 - 0
gameplay/src/Form.cpp

@@ -84,6 +84,16 @@ namespace gameplay
         const char* styleName = formProperties->getString("style");
         form->initialize(theme->getStyle(styleName), formProperties);
 
+        if (form->_autoWidth)
+        {
+            form->_bounds.width = Game::getInstance()->getWidth();
+        }
+
+        if (form->_autoHeight)
+        {
+            form->_bounds.height = Game::getInstance()->getHeight();
+        }
+
         // Add all the controls to the form.
         form->addControls(theme, formProperties);
 

+ 13 - 13
gameplay/src/Theme.cpp

@@ -181,11 +181,11 @@ namespace gameplay
                             font = Font::create(fontPath);
                         }
                         unsigned int fontSize = innerSpace->getInt("fontSize");
-                        const char* alignmentString = innerSpace->getString("alignment");
-                        Font::Justify alignment = Font::ALIGN_TOP_LEFT;
-                        if (alignmentString)
+                        const char* textAlignmentString = innerSpace->getString("textAlignment");
+                        Font::Justify textAlignment = Font::ALIGN_TOP_LEFT;
+                        if (textAlignmentString)
                         {
-                            alignment = Font::getJustifyFromString(alignmentString);
+                            textAlignment = Font::getJustify(textAlignmentString);
                         }
                         bool rightToLeft = innerSpace->getBool("rightToLeft");
 
@@ -207,7 +207,7 @@ namespace gameplay
                         normal->setTextColor(textColor);
                         normal->setFont(font);
                         normal->setFontSize(fontSize);
-                        normal->setTextAlignment(alignment);
+                        normal->setTextAlignment(textAlignment);
                         normal->setTextRightToLeft(rightToLeft);
                         normal->setOpacity(opacity);
 
@@ -275,15 +275,15 @@ namespace gameplay
                             fontSize = normal->getFontSize();
                         }
 
-                        const char* alignmentString = innerSpace->getString("alignment");
-                        Font::Justify alignment;
-                        if (alignmentString)
+                        const char* textAlignmentString = innerSpace->getString("textAlignment");
+                        Font::Justify textAlignment;
+                        if (textAlignmentString)
                         {
-                            alignment = Font::getJustifyFromString(alignmentString);
+                            textAlignment = Font::getJustify(textAlignmentString);
                         }
                         else
                         {
-                            alignment = normal->getTextAlignment();
+                            textAlignment = normal->getTextAlignment();
                         }
 
                         bool rightToLeft;
@@ -335,7 +335,7 @@ namespace gameplay
                             focus->setTextColor(textColor);
                             focus->setFont(font);
                             focus->setFontSize(fontSize);
-                            focus->setTextAlignment(alignment);
+                            focus->setTextAlignment(textAlignment);
                             focus->setTextRightToLeft(rightToLeft);
                             focus->setOpacity(opacity);
 
@@ -350,7 +350,7 @@ namespace gameplay
                             active->setTextColor(textColor);
                             active->setFont(font);
                             active->setFontSize(fontSize);
-                            active->setTextAlignment(alignment);
+                            active->setTextAlignment(textAlignment);
                             active->setTextRightToLeft(rightToLeft);
                             active->setOpacity(opacity);
 
@@ -365,7 +365,7 @@ namespace gameplay
                             disabled->setTextColor(textColor);
                             disabled->setFont(font);
                             disabled->setFontSize(fontSize);
-                            disabled->setTextAlignment(alignment);
+                            disabled->setTextAlignment(textAlignment);
                             disabled->setTextRightToLeft(rightToLeft);
                             disabled->setOpacity(opacity);
 

+ 28 - 0
gameplay/src/VerticalLayout.cpp

@@ -69,6 +69,34 @@ namespace gameplay
         {
             Control* control = controls.at(i);
 
+            if (control->_alignment != Control::ALIGN_TOP_LEFT ||
+                control->_autoWidth || control->_autoHeight)
+            {
+                Rectangle controlBounds = control->getBounds();
+                const Rectangle& containerBounds = container->getBounds();
+
+                if (control->_autoWidth)
+                {
+                    controlBounds.width = containerBounds.width;
+                }
+
+                if (control->_autoHeight)
+                {
+                    controlBounds.height = containerBounds.height;
+                }
+
+                if ((control->_alignment & Control::ALIGN_RIGHT) == Control::ALIGN_RIGHT)
+                {
+                    controlBounds.x = containerBounds.width - controlBounds.width;
+                }
+                else if ((control->_alignment & Control::ALIGN_HCENTER) == Control::ALIGN_HCENTER)
+                {
+                    controlBounds.x = containerBounds.width / 2.0f - controlBounds.width / 2.0f;
+                }
+
+                control->setBounds(controlBounds);
+            }
+
             const Rectangle& bounds = control->getClipBounds();
             const Theme::Margin& margin = control->getMargin();