Quellcode durchsuchen

Added clear() to UI, which removes all UI elements except cursor.
Added layoutHorizontal() & layoutVertical() to UIElement.

Lasse Öörni vor 15 Jahren
Ursprung
Commit
f638f5cbf9

+ 2 - 0
Engine/Engine/RegisterTemplates.h

@@ -395,6 +395,8 @@ template <class T> void registerUIElement(asIScriptEngine* engine, const char* c
     engine->RegisterObjectMethod(className, "void addChild(UIElement@+)", asMETHOD(T, addChild), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void removeChild(UIElement@+)", asMETHOD(T, removeChild), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void removeAllChildren()", asMETHOD(T, removeAllChildren), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void layoutHorizontal(int, const IntRect& in, bool, bool)", asMETHOD(T, layoutHorizontal), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void layoutVertical(int, const IntRect& in, bool, bool)", asMETHOD(T, layoutVertical), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const string& getName() const", asMETHOD(T, getName), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const IntVector2& getPosition() const", asMETHOD(T, getPosition), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const IntVector2& getSize() const", asMETHOD(T, getSize), asCALL_THISCALL);

+ 1 - 0
Engine/Engine/RegisterUI.cpp

@@ -269,6 +269,7 @@ static void registerUI(asIScriptEngine* engine)
     engine->RegisterObjectMethod("UI", "void setCursor(Cursor@+)", asMETHOD(UI, setCursor), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "void setFocusElement(UIElement@+)", asMETHOD(UI, setFocusElement), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "void bringToFront(UIElement@+)", asMETHOD(UI, bringToFront), asCALL_THISCALL);
+    engine->RegisterObjectMethod("UI", "void clear()", asMETHOD(UI, clear), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "UIElement@ createElement(const string& in, const string& in)", asFUNCTION(UICreateElement), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("UI", "UIElement@ loadLayout(XMLFile@+)", asFUNCTION(UILoadLayout), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("UI", "UIElement@ loadLayout(XMLFile@+, XMLFile@+)", asFUNCTION(UILoadLayoutWithStyle), asCALL_CDECL_OBJLAST);

+ 7 - 0
Engine/UI/UI.cpp

@@ -159,6 +159,13 @@ void UI::bringToFront(UIElement* element)
     ptr->setPriority(maxPriority);
 }
 
+void UI::clear()
+{
+    mRootElement->removeAllChildren();
+    if (mCursor)
+        mRootElement->addChild(mCursor);
+}
+
 void UI::update(float timeStep)
 {
     PROFILE(UI_Update);

+ 2 - 0
Engine/UI/UI.h

@@ -50,6 +50,8 @@ public:
     void setFocusElement(UIElement* element);
     //! Bring an UI element to front
     void bringToFront(UIElement* element);
+    //! Clear the UI (excluding the cursor)
+    void clear();
     //! Update the UI
     void update(float timeStep);
     //! Render the UI

+ 64 - 0
Engine/UI/UIElement.cpp

@@ -446,6 +446,52 @@ void UIElement::removeAllChildren()
     }
 }
 
+void UIElement::layoutHorizontal(int spacing, const IntRect& border, bool expand, bool contract)
+{
+    IntVector2 currentPos(border.mLeft, border.mTop);
+    IntVector2 neededSize(IntVector2::sZero);
+    for (unsigned i = 0; i < mChildren.size(); ++i)
+    {
+        UIElement* child = mChildren[i];
+        child->setHorizontalAlignment(HA_LEFT);
+        if (child->getVerticalAlignment() == HA_CENTER)
+            child->setPosition(currentPos.mX, 0);
+        else
+            child->setPosition(currentPos);
+        currentPos.mX += child->getWidth() + spacing;
+        if (child->getHeight() + border.mTop + border.mBottom > neededSize.mY)
+            neededSize.mY = child->getHeight() + border.mTop + border.mBottom;
+    }
+    currentPos.mX -= spacing;
+    if (currentPos.mX + border.mRight > neededSize.mX)
+        neededSize.mX = currentPos.mX + border.mRight;
+    
+    adjustSize(neededSize, expand, contract);
+}
+
+void UIElement::layoutVertical(int spacing, const IntRect& border, bool expand, bool contract)
+{
+    IntVector2 currentPos(border.mLeft, border.mTop);
+    IntVector2 neededSize(IntVector2::sZero);
+    for (unsigned i = 0; i < mChildren.size(); ++i)
+    {
+        UIElement* child = mChildren[i];
+        child->setVerticalAlignment(VA_TOP);
+        if (child->getHorizontalAlignment() == HA_CENTER)
+            child->setPosition(0, currentPos.mY);
+        else
+            child->setPosition(currentPos);
+        currentPos.mY += child->getHeight() + spacing;
+        if (child->getWidth() + border.mLeft + border.mRight > neededSize.mX)
+            neededSize.mX = child->getWidth() + border.mLeft + border.mRight;
+    }
+    currentPos.mY -= spacing;
+    if (currentPos.mY + border.mBottom > neededSize.mY)
+        neededSize.mY = currentPos.mY + border.mBottom;
+    
+    adjustSize(neededSize, expand, contract);
+}
+
 std::vector<UIElement*> UIElement::getChildren(bool recursive) const
 {
     if (!recursive)
@@ -603,3 +649,21 @@ void UIElement::getChildrenRecursive(std::vector<UIElement*>& dest) const
         (*i)->getChildrenRecursive(dest);
     }
 }
+
+void UIElement::adjustSize(const IntVector2& neededSize, bool expand, bool contract)
+{
+    if (expand)
+    {
+        if (getWidth() < neededSize.mX)
+            setWidth(neededSize.mX);
+        if (getHeight() < neededSize.mY)
+            setHeight(neededSize.mY);
+    }
+    if (contract)
+    {
+        if (getWidth() > neededSize.mX)
+            setWidth(neededSize.mX);
+        if (getHeight() > neededSize.mY)
+            setHeight(neededSize.mY);
+    }
+}

+ 6 - 0
Engine/UI/UIElement.h

@@ -155,6 +155,10 @@ public:
     void removeChild(UIElement* element);
     //! Remove all child elements
     void removeAllChildren();
+    //! Layout child elements horizontally. Expand/contract the element optionally
+    void layoutHorizontal(int spacing = 0, const IntRect& border = IntRect::sZero, bool expand = true, bool contract = true);
+    //! Layout child elements vertically. Expand/contract the element optionally
+    void layoutVertical(int spacing = 0, const IntRect& border = IntRect::sZero, bool expand = true, bool contract = true);
     
     //! Return name
     const std::string& getName() const { return mName; }
@@ -264,6 +268,8 @@ protected:
 private:
     //! Return child elements recursively
     void getChildrenRecursive(std::vector<UIElement*>& dest) const;
+    //! Adjust size after laying out the child elements
+    void adjustSize(const IntVector2& neededSize, bool expand, bool contract);
     
     //! Position
     IntVector2 mPosition;

+ 2 - 1
Examples/Test/Application.cpp

@@ -205,7 +205,8 @@ void Application::init()
     ui->setCursor(cursor);
     
     //XMLFile* uiLayout = mCache->getResource<XMLFile>("UI/TestLayout.xml");
-    //uiRoot->addChild(ui->loadLayout(uiLayout, uiStyle));
+    //SharedPtr<UIElement> layoutElement = ui->loadLayout(uiLayout, uiStyle);
+    //uiRoot->addChild(layoutElement);
     
     mScene = mEngine->createScene();
     PhysicsWorld* world = mScene->getExtension<PhysicsWorld>();