Эх сурвалжийг харах

make ui elements json configurable

Kolja Strohm 5 сар өмнө
parent
commit
ab9217cde3

+ 13 - 1
FactoryCraft/FactoryCraft.vcxproj

@@ -206,7 +206,13 @@
     <ClInclude Include="GrowingPlant.h" />
     <ClInclude Include="TypeRegistry.h" />
     <ClInclude Include="UIController.h" />
+    <ClInclude Include="UICraftingGrid.h" />
     <ClInclude Include="UIDialog.h" />
+    <ClInclude Include="UIDialogElement.h" />
+    <ClInclude Include="UIElement.h" />
+    <ClInclude Include="UIInventory.h" />
+    <ClInclude Include="UIReference.h" />
+    <ClInclude Include="UIText.h" />
     <ClInclude Include="WorldGenerator.h" />
     <ClInclude Include="WorldLoader.h" />
     <ClInclude Include="WormCaveGenerator.h" />
@@ -318,7 +324,13 @@
     <ClCompile Include="GrowingPlant.cpp" />
     <ClCompile Include="TypeRegistry.cpp" />
     <ClCompile Include="UIController.cpp" />
+    <ClCompile Include="UICraftingGrid.cpp" />
     <ClCompile Include="UIDialog.cpp" />
+    <ClCompile Include="UIDialogElement.cpp" />
+    <ClCompile Include="UIelement.cpp" />
+    <ClCompile Include="UIInventory.cpp" />
+    <ClCompile Include="UIReference.cpp" />
+    <ClCompile Include="UIText.cpp" />
     <ClCompile Include="WorldGenerator.cpp" />
     <ClCompile Include="WorldLoader.cpp" />
     <ClCompile Include="WormCaveGenerator.cpp" />
@@ -331,7 +343,7 @@
       <OutputFile>$(RemoteProjectDir)/$(TargetName)$(TargetExt)</OutputFile>
     </Link>
     <ClCompile>
-      <CppLanguageStandard>c++20</CppLanguageStandard>
+      <CppLanguageStandard>c++23</CppLanguageStandard>
       <AdditionalIncludeDirectories>../../../Framework/debug;../../../Network/debug/Network;../../../KsgScript/debug/KsgScript</AdditionalIncludeDirectories>
       <ObjectFileName>%(filename).o</ObjectFileName>
     </ClCompile>

+ 39 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -115,6 +115,9 @@
     <Filter Include="drops\implementations">
       <UniqueIdentifier>{591cb52f-39d0-4c28-a756-069e7b868f1c}</UniqueIdentifier>
     </Filter>
+    <Filter Include="UI\UIElements">
+      <UniqueIdentifier>{b000db10-bafc-49f7-b4a3-c4c26e82ca6b}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Chunk.h">
@@ -459,6 +462,24 @@
     <ClInclude Include="BlockReplacementDrop.h">
       <Filter>drops\implementations</Filter>
     </ClInclude>
+    <ClInclude Include="UIText.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="UIInventory.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="UIDialogElement.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="UICraftingGrid.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="UIElement.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="UIReference.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -791,5 +812,23 @@
     <ClCompile Include="BlockReplacementDrop.cpp">
       <Filter>drops\implementations</Filter>
     </ClCompile>
+    <ClCompile Include="UICraftingGrid.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="UIDialogElement.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="UIInventory.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="UIText.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="UIelement.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="UIReference.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 3 - 4
FactoryCraft/Recipie.cpp

@@ -5,6 +5,7 @@
 #include "CraftingStorage.h"
 #include "Game.h"
 #include "Item.h"
+#include "UIElement.h"
 
 RecipieInput::RecipieInput()
     : ReferenceCounter(),
@@ -391,8 +392,7 @@ Framework::JSON::JSONObject* UnshapedRecipieFactory::toJsonObject(
 JSONObjectValidationBuilder* UnshapedRecipieFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
 {
-    return RecipieFactory::addToValidator(
-        builder->withRequiredArray("inputs")
+    return RecipieFactory::addToValidator(builder->withRequiredArray("inputs")
             ->addAcceptedTypeInArray(
                 Game::INSTANCE->zTypeRegistry()->getValidator<RecipieInput>())
             ->finishArray());
@@ -587,8 +587,7 @@ Framework::JSON::JSONObject* ShapedRecipieFactory::toJsonObject(
 JSONObjectValidationBuilder* ShapedRecipieFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
 {
-    return RecipieFactory::addToValidator(
-        builder->withRequiredArray("inputs")
+    return RecipieFactory::addToValidator(builder->withRequiredArray("inputs")
             ->addAcceptedObjectInArray()
             ->withRequiredNumber("x")
             ->whichIsGreaterOrEqual(0.0)

+ 13 - 0
FactoryCraft/TypeRegistry.cpp

@@ -33,6 +33,11 @@
 #include "SpecificItemDrop.h"
 #include "TreeSeblingBlock.h"
 #include "TreeTemplate.h"
+#include "UICraftingGrid.h"
+#include "UIDialogElement.h"
+#include "UIInventory.h"
+#include "UIReference.h"
+#include "UIText.h"
 
 TypeRegistry::TypeRegistry()
     : ReferenceCounter()
@@ -147,6 +152,14 @@ TypeRegistry::TypeRegistry()
 
     // inventories
     registerType(new ItemSlotFactory());
+
+    // UI Elements
+    registerSubType(new UITargetReferenceFactory());
+    registerSubType(new UITActorReferenceFactory());
+    registerSubType(new UITextElementFactory());
+    registerSubType(new UIInventoryElementFactory());
+    registerSubType(new UIDialogElementFactory());
+    registerSubType(new UICraftingGridElementFactory());
 }
 
 void TypeRegistry::writeSyntaxInfo(Framework::Text folderPath) const

+ 140 - 0
FactoryCraft/UICraftingGrid.cpp

@@ -0,0 +1,140 @@
+#include "UICraftingGrid.h"
+
+#include "UIReference.h"
+
+UICraftingGrid::UICraftingGrid()
+    : UIElement(),
+      rowSize(0),
+      colSize(0),
+      numOutputSlots(0),
+      target(0)
+{}
+
+UICraftingGrid::~UICraftingGrid()
+{
+    if (target)
+    {
+        target->release();
+    }
+}
+
+void UICraftingGrid::setRowSize(int rowSize)
+{
+    this->rowSize = rowSize;
+}
+
+int UICraftingGrid::getRowSize() const
+{
+    return rowSize;
+}
+
+void UICraftingGrid::setColSize(int colSize)
+{
+    this->colSize = colSize;
+}
+
+int UICraftingGrid::getColSize() const
+{
+    return colSize;
+}
+
+void UICraftingGrid::setNumOutputSlots(int numOutputSlots)
+{
+    this->numOutputSlots = numOutputSlots;
+}
+
+int UICraftingGrid::getNumOutputSlots() const
+{
+    return numOutputSlots;
+}
+
+void UICraftingGrid::setTarget(UIReference* target)
+{
+    if (this->target)
+    {
+        this->target->release();
+    }
+    this->target = target;
+}
+
+UIReference* UICraftingGrid::zTarget() const
+{
+    return target;
+}
+
+Framework::XML::Element* UICraftingGrid::toUIML(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    Framework::XML::Element* result = UIElement::toUIML(zTarget, zActor);
+    result->setName("craftingGrid");
+    result->setAttribute("rowSize", rowSize);
+    result->setAttribute("colSize", colSize);
+    result->setAttribute("numOutputSlots", numOutputSlots);
+    if (target)
+    {
+        result->setAttribute("target", target->getReferenceId(zTarget, zActor));
+    }
+    return result;
+}
+
+UICraftingGridElementFactory::UICraftingGridElementFactory()
+    : UIElementFactory<UICraftingGrid>()
+{}
+
+JSONObjectValidationBuilder* UICraftingGridElementFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return UIElementFactory<UICraftingGrid>::addToValidator(builder)
+        ->withRequiredNumber("rowSize")
+        ->whichIsGreaterThen(0)
+        ->finishNumber()
+        ->withRequiredNumber("colSize")
+        ->whichIsGreaterThen(0)
+        ->finishNumber()
+        ->withRequiredNumber("numOutputSlots")
+        ->whichIsGreaterThen(0)
+        ->finishNumber()
+        ->withRequiredAttribute("target",
+            Game::INSTANCE->zTypeRegistry()->getValidator<UIReference>());
+}
+
+UICraftingGrid* UICraftingGridElementFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    UICraftingGrid* result = UIElementFactory<UICraftingGrid>::fromJson(zJson);
+    result->setRowSize((int)zJson->zValue("rowSize")->asNumber()->getNumber());
+    result->setColSize((int)zJson->zValue("colSize")->asNumber()->getNumber());
+    result->setNumOutputSlots(
+        (int)zJson->zValue("numOutputSlots")->asNumber()->getNumber());
+    result->setTarget(Game::INSTANCE->zTypeRegistry()->fromJson<UIReference>(
+        zJson->zValue("target")->asObject()));
+    return result;
+}
+
+Framework::JSON::JSONObject* UICraftingGridElementFactory::toJsonObject(
+    UICraftingGrid* zObject) const
+{
+    Framework::JSON::JSONObject* result
+        = UIElementFactory<UICraftingGrid>::toJsonObject(zObject);
+    result->addValue(
+        "rowSize", new Framework::JSON::JSONNumber(zObject->getRowSize()));
+    result->addValue(
+        "colSize", new Framework::JSON::JSONNumber(zObject->getColSize()));
+    result->addValue("numOutputSlots",
+        new Framework::JSON::JSONNumber(zObject->getNumOutputSlots()));
+    result->addValue("target",
+        Game::INSTANCE->zTypeRegistry()->toJson<UIReference>(
+            zObject->zTarget()));
+    return result;
+}
+
+UICraftingGrid* UICraftingGridElementFactory::createElement(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new UICraftingGrid();
+}
+
+const char* UICraftingGridElementFactory::getTypeToken() const
+{
+    return "craftingGrid";
+}

+ 44 - 0
FactoryCraft/UICraftingGrid.h

@@ -0,0 +1,44 @@
+#pragma once
+
+#include <Either.h>
+
+#include "UIElement.h"
+
+class UIReference;
+
+class UICraftingGrid : public UIElement
+{
+private:
+    int rowSize;
+    int colSize;
+    int numOutputSlots;
+    UIReference* target;
+
+public:
+    UICraftingGrid();
+    ~UICraftingGrid();
+    void setRowSize(int rowSize);
+    int getRowSize() const;
+    void setColSize(int colSize);
+    int getColSize() const;
+    void setNumOutputSlots(int numOutputSlots);
+    int getNumOutputSlots() const;
+    void setTarget(UIReference* target);
+    UIReference* zTarget() const;
+    Framework::XML::Element* toUIML(Framework::Either<Block*, Entity*> zTarget,
+        Entity* zActor) const override;
+};
+
+class UICraftingGridElementFactory : public UIElementFactory<UICraftingGrid>
+{
+public:
+    UICraftingGridElementFactory();
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    UICraftingGrid* fromJson(Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        UICraftingGrid* zObject) const override;
+    UICraftingGrid* createElement(
+        Framework::JSON::JSONObject* zJson) const override;
+    const char* getTypeToken() const override;
+};

+ 112 - 0
FactoryCraft/UIDialogElement.cpp

@@ -0,0 +1,112 @@
+#include "UIDialogElement.h"
+
+#include "UIReference.h"
+
+UIDialogElement::UIDialogElement()
+    : UIContainerElement(),
+      notifyOnClose(0)
+{}
+
+UIDialogElement::~UIDialogElement()
+{
+    if (notifyOnClose)
+    {
+        notifyOnClose->release();
+    }
+}
+
+void UIDialogElement::setTitle(const Framework::Text& title)
+{
+    this->title = title;
+}
+
+const Framework::Text& UIDialogElement::getTitle() const
+{
+    return title;
+}
+
+void UIDialogElement::setNotifyOnClose(UIReference* notifyOnClose)
+{
+    if (this->notifyOnClose)
+    {
+        this->notifyOnClose->release();
+    }
+    this->notifyOnClose = notifyOnClose;
+}
+
+UIReference* UIDialogElement::zNotifyOnClose() const
+{
+    return notifyOnClose;
+}
+
+Framework::XML::Element* UIDialogElement::toUIML(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    Framework::XML::Element* result
+        = UIContainerElement::toUIML(zTarget, zActor);
+    result->setName("dialog");
+    result->setAttribute("title", title);
+    if (notifyOnClose)
+    {
+        result->setAttribute(
+            "notifyOnClose", notifyOnClose->getReferenceId(zTarget, zActor));
+    }
+    return result;
+}
+
+UIDialogElementFactory::UIDialogElementFactory()
+    : UIContainerElementFactory<UIDialogElement>()
+{}
+
+JSONObjectValidationBuilder* UIDialogElementFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return UIContainerElementFactory::addToValidator(builder)
+        ->withRequiredString("title")
+        ->finishString()
+        ->withRequiredAttribute("notifyOnClose",
+            Game::INSTANCE->zTypeRegistry()->getValidator<UIReference>(),
+            false,
+            true);
+}
+
+UIDialogElement* UIDialogElementFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    UIDialogElement* result = UIContainerElementFactory::fromJson(zJson);
+    result->setTitle(zJson->zValue("title")->asString()->getString());
+    if (zJson->hasValue("notifyOnClose"))
+    {
+        result->setNotifyOnClose(
+            Game::INSTANCE->zTypeRegistry()->fromJson<UIReference>(
+                zJson->zValue("notifyOnClose")));
+    }
+    return result;
+}
+
+Framework::JSON::JSONObject* UIDialogElementFactory::toJsonObject(
+    UIDialogElement* zObject) const
+{
+    Framework::JSON::JSONObject* result
+        = UIContainerElementFactory::toJsonObject(zObject);
+    result->addValue(
+        "title", new Framework::JSON::JSONString(zObject->getTitle()));
+    if (zObject->zNotifyOnClose())
+    {
+        result->addValue("notifyOnClose",
+            Game::INSTANCE->zTypeRegistry()->toJson<UIReference>(
+                zObject->zNotifyOnClose()));
+    }
+    return result;
+}
+
+UIDialogElement* UIDialogElementFactory::createElement(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new UIDialogElement();
+}
+
+const char* UIDialogElementFactory::getTypeToken() const
+{
+    return "dialog";
+}

+ 37 - 0
FactoryCraft/UIDialogElement.h

@@ -0,0 +1,37 @@
+#pragma once
+
+#include "UIElement.h"
+
+class UIReference;
+
+class UIDialogElement : public UIContainerElement
+{
+private:
+    Framework::Text title;
+    UIReference* notifyOnClose;
+
+public:
+    UIDialogElement();
+    ~UIDialogElement();
+    void setTitle(const Framework::Text& title);
+    const Framework::Text& getTitle() const;
+    void setNotifyOnClose(UIReference* notifyOnClose);
+    UIReference* zNotifyOnClose() const;
+    Framework::XML::Element* toUIML(Framework::Either<Block*, Entity*> zTarget,
+        Entity* zActor) const override;
+};
+
+class UIDialogElementFactory : public UIContainerElementFactory<UIDialogElement>
+{
+public:
+    UIDialogElementFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    UIDialogElement* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        UIDialogElement* zObject) const override;
+    UIDialogElement* createElement(
+        Framework::JSON::JSONObject* zJson) const override;
+    const char* getTypeToken() const override;
+};

+ 188 - 0
FactoryCraft/UIElement.cpp

@@ -0,0 +1,188 @@
+#include "UIElement.h"
+
+UIElement::UIElement()
+    : Framework::ReferenceCounter(),
+      marginLeft(0),
+      marginRight(0),
+      marginTop(0),
+      marginBottom(0),
+      width(0),
+      height(0)
+{}
+
+void UIElement::setId(const Framework::Text& id)
+{
+    this->id = id;
+}
+
+const Framework::Text& UIElement::getId() const
+{
+    return id;
+}
+
+void UIElement::setMarginLeft(int marginLeft)
+{
+    this->marginLeft = marginLeft;
+}
+
+int UIElement::getMarginLeft() const
+{
+    return marginLeft;
+}
+
+void UIElement::setMarginRight(int marginRight)
+{
+    this->marginRight = marginRight;
+}
+
+int UIElement::getMarginRight() const
+{
+    return marginRight;
+}
+
+void UIElement::setMarginTop(int marginTop)
+{
+    this->marginTop = marginTop;
+}
+
+int UIElement::getMarginTop() const
+{
+    return marginTop;
+}
+
+void UIElement::setMarginBottom(int marginBottom)
+{
+    this->marginBottom = marginBottom;
+}
+
+int UIElement::getMarginBottom() const
+{
+    return marginBottom;
+}
+
+void UIElement::setWidth(int width)
+{
+    this->width = width;
+}
+
+int UIElement::getWidth() const
+{
+    return width;
+}
+
+void UIElement::setHeight(int height)
+{
+    this->height = height;
+}
+
+int UIElement::getHeight() const
+{
+    return height;
+}
+
+void UIElement::setAlignLeft(const Framework::Text& alignLeft)
+{
+    this->alignLeft = alignLeft;
+}
+
+const Framework::Text& UIElement::getAlignLeft() const
+{
+    return alignLeft;
+}
+
+void UIElement::setAlignRight(const Framework::Text& alignRight)
+{
+    this->alignRight = alignRight;
+}
+
+const Framework::Text& UIElement::getAlignRight() const
+{
+    return alignRight;
+}
+
+void UIElement::setAlignTop(const Framework::Text& alignTop)
+{
+    this->alignTop = alignTop;
+}
+
+const Framework::Text& UIElement::getAlignTop() const
+{
+    return alignTop;
+}
+
+void UIElement::setAlignBottom(const Framework::Text& alignBottom)
+{
+    this->alignBottom = alignBottom;
+}
+
+const Framework::Text& UIElement::getAlignBottom() const
+{
+    return alignBottom;
+}
+
+Framework::XML::Element* UIElement::toUIML(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    Framework::XML::Element* result = new Framework::XML::Element();
+    result->setAttribute("id", id);
+    if (marginLeft != 0)
+    {
+        result->setAttribute("marginLeft", Framework::Text(marginLeft));
+    }
+    if (marginRight != 0)
+    {
+        result->setAttribute("marginRight", Framework::Text(marginRight));
+    }
+    if (marginTop != 0)
+    {
+        result->setAttribute("marginTop", Framework::Text(marginTop));
+    }
+    if (marginBottom != 0)
+    {
+        result->setAttribute("marginBottom", Framework::Text(marginBottom));
+    }
+    result->setAttribute("width", Framework::Text(width));
+    result->setAttribute("height", Framework::Text(height));
+    if (alignLeft.getLength() > 0)
+    {
+        result->setAttribute("alignLeft", alignLeft);
+    }
+    if (alignRight.getLength() > 0)
+    {
+        result->setAttribute("alignRight", alignRight);
+    }
+    if (alignTop.getLength() > 0)
+    {
+        result->setAttribute("alignTop", alignTop);
+    }
+    if (alignBottom.getLength() > 0)
+    {
+        result->setAttribute("alignBottom", alignBottom);
+    }
+    return result;
+}
+
+UIContainerElement::UIContainerElement()
+    : UIElement()
+{}
+
+void UIContainerElement::addChild(UIElement* child)
+{
+    children.add(child);
+}
+
+const Framework::RCArray<UIElement>& UIContainerElement::getChildren() const
+{
+    return children;
+}
+
+Framework::XML::Element* UIContainerElement::toUIML(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    Framework::XML::Element* result = UIElement::toUIML(zTarget, zActor);
+    for (UIElement* child : children)
+    {
+        result->addChild(child->toUIML(zTarget, zActor));
+    }
+    return result;
+}

+ 214 - 0
FactoryCraft/UIElement.h

@@ -0,0 +1,214 @@
+#pragma once
+
+#include <Array.h>
+#include <Either.h>
+#include <ReferenceCounter.h>
+
+#include "Game.h"
+#include "TypeRegistry.h"
+
+class Block;
+class Entity;
+
+class UIElement : public virtual Framework::ReferenceCounter
+{
+private:
+    Framework::Text id;
+    int marginLeft;
+    int marginRight;
+    int marginTop;
+    int marginBottom;
+    int width;
+    int height;
+    Framework::Text alignLeft;
+    Framework::Text alignRight;
+    Framework::Text alignTop;
+    Framework::Text alignBottom;
+
+public:
+    UIElement();
+    void setId(const Framework::Text& id);
+    const Framework::Text& getId() const;
+    void setMarginLeft(int marginLeft);
+    int getMarginLeft() const;
+    void setMarginRight(int marginRight);
+    int getMarginRight() const;
+    void setMarginTop(int marginTop);
+    int getMarginTop() const;
+    void setMarginBottom(int marginBottom);
+    int getMarginBottom() const;
+    void setWidth(int width);
+    int getWidth() const;
+    void setHeight(int height);
+    int getHeight() const;
+    void setAlignLeft(const Framework::Text& alignLeft);
+    const Framework::Text& getAlignLeft() const;
+    void setAlignRight(const Framework::Text& alignRight);
+    const Framework::Text& getAlignRight() const;
+    void setAlignTop(const Framework::Text& alignTop);
+    const Framework::Text& getAlignTop() const;
+    void setAlignBottom(const Framework::Text& alignBottom);
+    const Framework::Text& getAlignBottom() const;
+    virtual Framework::XML::Element* toUIML(
+        Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const;
+};
+
+class UIContainerElement : public UIElement
+{
+private:
+    Framework::RCArray<UIElement> children;
+
+public:
+    UIContainerElement();
+    void addChild(UIElement* child);
+    const Framework::RCArray<UIElement>& getChildren() const;
+    virtual Framework::XML::Element* toUIML(
+        Framework::Either<Block*, Entity*> zTarget,
+        Entity* zActor) const override;
+};
+
+template<class T> class UIElementFactory : public SubTypeFactory<UIElement, T>
+{
+public:
+    UIElementFactory()
+        : SubTypeFactory<UIElement, T>()
+    {}
+
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder->withRequiredString("id")
+            ->finishString()
+            ->withRequiredNumber("marginLeft")
+            ->withDefault(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("marginRight")
+            ->withDefault(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("marginTop")
+            ->withDefault(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("marginBottom")
+            ->withDefault(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("width")
+            ->finishNumber()
+            ->withRequiredNumber("height")
+            ->finishNumber()
+            ->withRequiredString("alignLeft")
+            ->withDefault("")
+            ->finishString()
+            ->withRequiredString("alignRight")
+            ->withDefault("")
+            ->finishString()
+            ->withRequiredString("alignTop")
+            ->withDefault("")
+            ->finishString()
+            ->withRequiredString("alignBottom")
+            ->withDefault("")
+            ->finishString();
+    }
+
+    virtual T* fromJson(Framework::JSON::JSONObject* zJson) const override
+    {
+        T* result = createElement(zJson);
+        result->setId(zJson->zValue("id")->asString()->getString());
+        result->setMarginLeft(
+            (int)zJson->zValue("marginLeft")->asNumber()->getNumber());
+        result->setMarginRight(
+            (int)zJson->zValue("marginRight")->asNumber()->getNumber());
+        result->setMarginTop(
+            (int)zJson->zValue("marginTop")->asNumber()->getNumber());
+        result->setMarginBottom(
+            (int)zJson->zValue("marginBottom")->asNumber()->getNumber());
+        result->setWidth((int)zJson->zValue("width")->asNumber()->getNumber());
+        result->setHeight(
+            (int)zJson->zValue("height")->asNumber()->getNumber());
+        result->setAlignLeft(
+            zJson->zValue("alignLeft")->asString()->getString());
+        result->setAlignRight(
+            zJson->zValue("alignRight")->asString()->getString());
+        result->setAlignTop(zJson->zValue("alignTop")->asString()->getString());
+        result->setAlignBottom(
+            zJson->zValue("alignBottom")->asString()->getString());
+        return result;
+    }
+
+    virtual Framework::JSON::JSONObject* toJsonObject(T* zObject) const override
+    {
+        Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+        result->addValue(
+            "id", new Framework::JSON::JSONString(zObject->getId()));
+        result->addValue("marginLeft",
+            new Framework::JSON::JSONNumber(zObject->getMarginLeft()));
+        result->addValue("marginRight",
+            new Framework::JSON::JSONNumber(zObject->getMarginRight()));
+        result->addValue("marginTop",
+            new Framework::JSON::JSONNumber(zObject->getMarginTop()));
+        result->addValue("marginBottom",
+            new Framework::JSON::JSONNumber(zObject->getMarginBottom()));
+        result->addValue(
+            "width", new Framework::JSON::JSONNumber(zObject->getWidth()));
+        result->addValue(
+            "height", new Framework::JSON::JSONNumber(zObject->getHeight()));
+        result->addValue("alignLeft",
+            new Framework::JSON::JSONString(zObject->getAlignLeft()));
+        result->addValue("alignRight",
+            new Framework::JSON::JSONString(zObject->getAlignRight()));
+        result->addValue("alignTop",
+            new Framework::JSON::JSONString(zObject->getAlignTop()));
+        result->addValue("alignBottom",
+            new Framework::JSON::JSONString(zObject->getAlignBottom()));
+        return result;
+    }
+
+protected:
+    virtual T* createElement(Framework::JSON::JSONObject* zJson) const = 0;
+};
+
+template<class T> class UIContainerElementFactory : public UIElementFactory<T>
+{
+public:
+    UIContainerElementFactory()
+        : UIElementFactory<T>()
+    {}
+
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return UIElementFactory<T>::addToValidator(builder)
+            ->withRequiredArray("children")
+            ->addAcceptedTypeInArray(
+                Game::INSTANCE->zTypeRegistry()->getValidator<UIElement>())
+            ->finishArray();
+    }
+
+    virtual T* fromJson(Framework::JSON::JSONObject* zJson) const override
+    {
+        T* result = UIElementFactory<T>::fromJson(zJson);
+        Framework::JSON::JSONArray* childrenJson
+            = zJson->zValue("children")->asArray();
+        for (Framework::JSON::JSONValue* childJson : *childrenJson)
+        {
+            result->addChild(
+                Game::INSTANCE->zTypeRegistry()->fromJson<UIElement>(
+                    childJson->asObject()));
+        }
+        return result;
+    }
+
+    virtual Framework::JSON::JSONObject* toJsonObject(T* zObject) const override
+    {
+        Framework::JSON::JSONObject* result
+            = UIElementFactory<T>::toJsonObject(zObject);
+        Framework::JSON::JSONArray* childrenJson
+            = new Framework::JSON::JSONArray();
+        for (UIElement* child : zObject->getChildren())
+        {
+            childrenJson->addValue(
+                Game::INSTANCE->zTypeRegistry()->toJson<UIElement>(child));
+        }
+        result->addValue("children", childrenJson);
+        return result;
+    }
+};

+ 152 - 0
FactoryCraft/UIInventory.cpp

@@ -0,0 +1,152 @@
+#include "UIInventory.h"
+
+#include "UIReference.h"
+
+UIInventoryElement::UIInventoryElement()
+    : UIElement(),
+      reference(nullptr),
+      rowSize(0),
+      numSlots(0)
+{}
+
+UIInventoryElement::~UIInventoryElement()
+{
+    if (reference)
+    {
+        reference->release();
+    }
+}
+
+void UIInventoryElement::setReference(UIReference* reference)
+{
+    if (this->reference)
+    {
+        this->reference->release();
+    }
+    this->reference = reference;
+}
+
+UIReference* UIInventoryElement::zReference() const
+{
+    return reference;
+}
+
+void UIInventoryElement::setRowSize(int rowSize)
+{
+    this->rowSize = rowSize;
+}
+
+int UIInventoryElement::getRowSize() const
+{
+    return rowSize;
+}
+
+void UIInventoryElement::setNumSlots(int numSlots)
+{
+    this->numSlots = numSlots;
+}
+
+int UIInventoryElement::getNumSlots() const
+{
+    return numSlots;
+}
+
+void UIInventoryElement::setSlotNameFilter(
+    const Framework::Text& slotNameFilter)
+{
+    this->slotNameFilter = slotNameFilter;
+}
+
+const Framework::Text& UIInventoryElement::getSlotNameFilter() const
+{
+    return slotNameFilter;
+}
+
+Framework::XML::Element* UIInventoryElement::toUIML(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    Framework::XML::Element* result = UIElement::toUIML(zTarget, zActor);
+    result->setName("inventory");
+    if (reference)
+    {
+        result->setAttribute(
+            "target", reference->getReferenceId(zTarget, zActor));
+    }
+    result->setAttribute("rowSize", rowSize);
+    result->setAttribute("numSlots", numSlots);
+    if (slotNameFilter.getLength())
+    {
+        result->setAttribute("slotNameFilter", slotNameFilter);
+    }
+    return result;
+}
+
+UIInventoryElementFactory::UIInventoryElementFactory()
+    : UIElementFactory<UIInventoryElement>()
+{}
+
+JSONObjectValidationBuilder* UIInventoryElementFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return UIElementFactory<UIInventoryElement>::addToValidator(builder)
+        ->withRequiredAttribute("reference",
+            Game::INSTANCE->zTypeRegistry()->getValidator<UIReference>())
+        ->withRequiredNumber("rowSize")
+        ->whichIsGreaterThen(0)
+        ->finishNumber()
+        ->withRequiredNumber("numSlots")
+        ->whichIsGreaterThen(0)
+        ->finishNumber()
+        ->withRequiredString("slotNameFilter")
+        ->whichIsOptional()
+        ->finishString();
+}
+
+UIInventoryElement* UIInventoryElementFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    UIInventoryElement* result
+        = UIElementFactory<UIInventoryElement>::fromJson(zJson);
+    result->setReference(Game::INSTANCE->zTypeRegistry()->fromJson<UIReference>(
+        zJson->zValue("reference")->asObject()));
+    result->setRowSize((int)zJson->zValue("rowSize")->asNumber()->getNumber());
+    result->setNumSlots(
+        (int)zJson->zValue("numSlots")->asNumber()->getNumber());
+    if (zJson->hasValue("slotNameFilter"))
+    {
+        result->setSlotNameFilter(
+            zJson->zValue("slotNameFilter")->asString()->getString());
+    }
+    return result;
+}
+
+Framework::JSON::JSONObject* UIInventoryElementFactory::toJsonObject(
+    UIInventoryElement* zObject) const
+{
+    Framework::JSON::JSONObject* result
+        = UIElementFactory<UIInventoryElement>::toJsonObject(zObject);
+    result->addValue("reference",
+        Game::INSTANCE->zTypeRegistry()->toJson<UIReference>(
+            zObject->zReference()));
+    result->addValue(
+        "rowSize", new Framework::JSON::JSONNumber(zObject->getRowSize()));
+    result->addValue(
+        "numSlots", new Framework::JSON::JSONNumber(zObject->getNumSlots()));
+    if (zObject->getSlotNameFilter().getLength() > 0)
+    {
+        result->addValue("slotNameFilter",
+            new Framework::JSON::JSONString(zObject->getSlotNameFilter()));
+    }
+    return result;
+}
+
+UIInventoryElement* UIInventoryElementFactory::createElement(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new UIInventoryElement();
+}
+
+const char* UIInventoryElementFactory::getTypeToken() const
+{
+    return "inventory";
+}

+ 43 - 0
FactoryCraft/UIInventory.h

@@ -0,0 +1,43 @@
+#pragma once
+
+#include "UIElement.h"
+
+class UIReference;
+
+class UIInventoryElement : public UIElement
+{
+private:
+    UIReference* reference;
+    int rowSize;
+    int numSlots;
+    Framework::Text slotNameFilter;
+
+public:
+    UIInventoryElement();
+    ~UIInventoryElement();
+    void setReference(UIReference* reference);
+    UIReference* zReference() const;
+    void setRowSize(int rowSize);
+    int getRowSize() const;
+    void setNumSlots(int numSlots);
+    int getNumSlots() const;
+    void setSlotNameFilter(const Framework::Text& slotNameFilter);
+    const Framework::Text& getSlotNameFilter() const;
+    Framework::XML::Element* toUIML(Framework::Either<Block*, Entity*> zTarget,
+        Entity* zActor) const override;
+};
+
+class UIInventoryElementFactory : public UIElementFactory<UIInventoryElement>
+{
+public:
+    UIInventoryElementFactory();
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    UIInventoryElement* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        UIInventoryElement* zObject) const override;
+    UIInventoryElement* createElement(
+        Framework::JSON::JSONObject* zJson) const override;
+    const char* getTypeToken() const override;
+};

+ 94 - 0
FactoryCraft/UIReference.cpp

@@ -0,0 +1,94 @@
+#include "UIReference.h"
+
+#include "Block.h"
+#include "Entity.h"
+
+UIReference::UIReference()
+    : Framework::ReferenceCounter()
+{}
+
+UITargetReference::UITargetReference()
+    : UIReference()
+{}
+
+Framework::Text UITargetReference::getReferenceId(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    Framework::Text result("");
+    if (zTarget.isA())
+    {
+        result.append() << zTarget.getA()->getDimensionId() << ","
+                        << zTarget.getA()->getPos().x << ","
+                        << zTarget.getA()->getPos().y << ","
+                        << zTarget.getA()->getPos().z;
+    }
+    else
+    {
+        result.append() << zTarget.getB()->getId();
+    }
+    return result;
+}
+
+UITActorReference::UITActorReference()
+    : UIReference()
+{}
+
+Framework::Text UITActorReference::getReferenceId(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    return Framework::Text(zActor->getId());
+}
+
+UITargetReferenceFactory::UITargetReferenceFactory()
+    : SubTypeFactory<UIReference, UITargetReference>()
+{}
+
+JSONObjectValidationBuilder* UITargetReferenceFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder;
+}
+
+UITargetReference* UITargetReferenceFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new UITargetReference();
+}
+
+Framework::JSON::JSONObject* UITargetReferenceFactory::toJsonObject(
+    UITargetReference* zObject) const
+{
+    return new Framework::JSON::JSONObject();
+}
+
+const char* UITargetReferenceFactory::getTypeToken() const
+{
+    return "target";
+}
+
+UITActorReferenceFactory::UITActorReferenceFactory()
+    : SubTypeFactory<UIReference, UITActorReference>()
+{}
+
+JSONObjectValidationBuilder* UITActorReferenceFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder;
+}
+
+UITActorReference* UITActorReferenceFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new UITActorReference();
+}
+
+Framework::JSON::JSONObject* UITActorReferenceFactory::toJsonObject(
+    UITActorReference* zObject) const
+{
+    return new Framework::JSON::JSONObject();
+}
+
+const char* UITActorReferenceFactory::getTypeToken() const
+{
+    return "actor";
+}

+ 65 - 0
FactoryCraft/UIReference.h

@@ -0,0 +1,65 @@
+#pragma once
+
+#include <Either.h>
+#include <ReferenceCounter.h>
+#include <Text.h>
+
+#include "TypeRegistry.h"
+
+class Block;
+class Entity;
+
+class UIReference : public Framework::ReferenceCounter
+{
+public:
+    UIReference();
+    virtual Framework::Text getReferenceId(
+        Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+        = 0;
+};
+
+class UITargetReference : public UIReference
+{
+public:
+    UITargetReference();
+    virtual Framework::Text getReferenceId(
+        Framework::Either<Block*, Entity*> zTarget,
+        Entity* zActor) const override;
+};
+
+class UITActorReference : public UIReference
+{
+public:
+    UITActorReference();
+    virtual Framework::Text getReferenceId(
+        Framework::Either<Block*, Entity*> zTarget,
+        Entity* zActor) const override;
+};
+
+class UITargetReferenceFactory
+    : public SubTypeFactory<UIReference, UITargetReference>
+{
+public:
+    UITargetReferenceFactory();
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    UITargetReference* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        UITargetReference* zObject) const override;
+    const char* getTypeToken() const override;
+};
+
+class UITActorReferenceFactory
+    : public SubTypeFactory<UIReference, UITActorReference>
+{
+public:
+    UITActorReferenceFactory();
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    UITActorReference* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        UITActorReference* zObject) const override;
+    const char* getTypeToken() const override;
+};

+ 65 - 0
FactoryCraft/UIText.cpp

@@ -0,0 +1,65 @@
+#include "UIText.h"
+
+UITextElement::UITextElement()
+    : UIElement()
+{}
+
+void UITextElement::setText(const Framework::Text& text)
+{
+    this->text = text;
+}
+
+const Framework::Text& UITextElement::getText() const
+{
+    return text;
+}
+
+Framework::XML::Element* UITextElement::toUIML(
+    Framework::Either<Block*, Entity*> zTarget, Entity* zActor) const
+{
+    Framework::XML::Element* result = UIElement::toUIML(zTarget, zActor);
+    result->setName("text");
+    result->setText(text);
+    return result;
+}
+
+UITextElementFactory::UITextElementFactory()
+    : UIElementFactory()
+{}
+
+JSONObjectValidationBuilder* UITextElementFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return UIElementFactory::addToValidator(builder)
+        ->withRequiredString("text")
+        ->finishString();
+}
+
+UITextElement* UITextElementFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    UITextElement* result = UIElementFactory::fromJson(zJson);
+    result->setText(zJson->zValue("text")->asString()->getString());
+    return result;
+}
+
+Framework::JSON::JSONObject* UITextElementFactory::toJsonObject(
+    UITextElement* zObject) const
+{
+    Framework::JSON::JSONObject* result
+        = UIElementFactory::toJsonObject(zObject);
+    result->addValue(
+        "text", new Framework::JSON::JSONString(zObject->getText()));
+    return result;
+}
+
+UITextElement* UITextElementFactory::createElement(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new UITextElement();
+}
+
+const char* UITextElementFactory::getTypeToken() const
+{
+    return "text";
+}

+ 31 - 0
FactoryCraft/UIText.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include "UIElement.h"
+
+class UITextElement : public UIElement
+{
+private:
+    Framework::Text text;
+
+public:
+    UITextElement();
+    void setText(const Framework::Text& text);
+    const Framework::Text& getText() const;
+    virtual Framework::XML::Element* toUIML(
+        Framework::Either<Block*, Entity*> zTarget,
+        Entity* zActor) const override;
+};
+
+class UITextElementFactory : public UIElementFactory<UITextElement>
+{
+public:
+    UITextElementFactory();
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    UITextElement* fromJson(Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        UITextElement* zObject) const override;
+    UITextElement* createElement(
+        Framework::JSON::JSONObject* zJson) const override;
+    const char* getTypeToken() const override;
+};

+ 13 - 1
Windows Version/Windows Version.vcxproj

@@ -115,7 +115,7 @@
       <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp20</LanguageStandard>
+      <LanguageStandard>stdcpplatest</LanguageStandard>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
@@ -263,7 +263,13 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClCompile Include="..\FactoryCraft\GrowingPlant.cpp" />
     <ClCompile Include="..\FactoryCraft\TypeRegistry.cpp" />
     <ClCompile Include="..\FactoryCraft\UIController.cpp" />
+    <ClCompile Include="..\FactoryCraft\UICraftingGrid.cpp" />
     <ClCompile Include="..\FactoryCraft\UIDialog.cpp" />
+    <ClCompile Include="..\FactoryCraft\UIDialogElement.cpp" />
+    <ClCompile Include="..\FactoryCraft\UIElement.cpp" />
+    <ClCompile Include="..\FactoryCraft\UIInventory.cpp" />
+    <ClCompile Include="..\FactoryCraft\UIReference.cpp" />
+    <ClCompile Include="..\FactoryCraft\UIText.cpp" />
     <ClCompile Include="..\FactoryCraft\WorldGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\WorldLoader.cpp" />
     <ClCompile Include="..\FactoryCraft\WormCaveGenerator.cpp" />
@@ -380,7 +386,13 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClInclude Include="..\FactoryCraft\GrowingPlant.h" />
     <ClInclude Include="..\FactoryCraft\TypeRegistry.h" />
     <ClInclude Include="..\FactoryCraft\UIController.h" />
+    <ClInclude Include="..\FactoryCraft\UICraftingGrid.h" />
     <ClInclude Include="..\FactoryCraft\UIDialog.h" />
+    <ClInclude Include="..\FactoryCraft\UIDialogElement.h" />
+    <ClInclude Include="..\FactoryCraft\UIElement.h" />
+    <ClInclude Include="..\FactoryCraft\UIInventory.h" />
+    <ClInclude Include="..\FactoryCraft\UIReference.h" />
+    <ClInclude Include="..\FactoryCraft\UIText.h" />
     <ClInclude Include="..\FactoryCraft\WorldGenerator.h" />
     <ClInclude Include="..\FactoryCraft\WorldLoader.h" />
     <ClInclude Include="..\FactoryCraft\WormCaveGenerator.h" />

+ 39 - 0
Windows Version/Windows Version.vcxproj.filters

@@ -115,6 +115,9 @@
     <Filter Include="drops\implementations">
       <UniqueIdentifier>{d4e7dadf-eb55-4257-ad1b-90d18018a9fe}</UniqueIdentifier>
     </Filter>
+    <Filter Include="UI\UIElements">
+      <UniqueIdentifier>{327469e3-2704-4e52-b31a-2e3823386ad9}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\FactoryCraft\Server.cpp">
@@ -444,6 +447,24 @@
     <ClCompile Include="..\FactoryCraft\BlockReplacementDrop.cpp">
       <Filter>drops\implementations</Filter>
     </ClCompile>
+    <ClCompile Include="..\FactoryCraft\UICraftingGrid.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\UIDialogElement.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\UIInventory.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\UIText.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\UIElement.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\UIReference.cpp">
+      <Filter>UI\UIElements</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\FactoryCraft\Chunk.h">
@@ -791,5 +812,23 @@
     <ClInclude Include="..\FactoryCraft\BlockReplacementDrop.h">
       <Filter>drops\implementations</Filter>
     </ClInclude>
+    <ClInclude Include="..\FactoryCraft\UICraftingGrid.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\UIDialogElement.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\UIInventory.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\UIText.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\UIElement.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\UIReference.h">
+      <Filter>UI\UIElements</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>