Skip to content

Commit

Permalink
gui split layout
Browse files Browse the repository at this point in the history
  • Loading branch information
malytomas committed Sep 18, 2023
1 parent e0105e5 commit 7fa55cb
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 2 deletions.
2 changes: 2 additions & 0 deletions sources/include/cage-engine/guiBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ namespace cage
[[nodiscard]] BuilderItem topColumn(bool flexibleBottom = false, Real horizontalAlign = GuiLayoutLineComponent().crossAlign);
[[nodiscard]] BuilderItem bottomColumn(bool flexibleTop = false, Real horizontalAlign = GuiLayoutLineComponent().crossAlign);
[[nodiscard]] BuilderItem middleColumn(bool flexibleEdges = false, Real horizontalAlign = GuiLayoutLineComponent().crossAlign);
[[nodiscard]] BuilderItem horizontalSplit(Real verticalAlign = GuiLayoutSplitComponent().crossAlign);
[[nodiscard]] BuilderItem verticalSplit(Real horizontalAlign = GuiLayoutSplitComponent().crossAlign);
[[nodiscard]] BuilderItem horizontalTable(uint32 rows = GuiLayoutTableComponent().sections, bool grid = GuiLayoutTableComponent().grid);
[[nodiscard]] BuilderItem verticalTable(uint32 columns = GuiLayoutTableComponent().sections, bool grid = GuiLayoutTableComponent().grid);
[[nodiscard]] BuilderItem alignment(Vec2 align = GuiLayoutAlignmentComponent().alignment);
Expand Down
2 changes: 1 addition & 1 deletion sources/include/cage-engine/guiComponents.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ namespace cage
bool vertical = false;
};

/* TODO
struct CAGE_ENGINE_API GuiLayoutSplitComponent
{
Real crossAlign = Real::Nan(); // applied to items individually in the secondary axis, nan = fill the space, 0 = left/top, 1 = right/bottom
bool vertical = false;
};

/* TODO
struct CAGE_ENGINE_API GuiLayoutFlowComponent
{
Real crossAlign = Real::Nan(); // applied to items individually in the secondary axis, nan = fill the space, 0 = left/top, 1 = right/bottom
Expand Down
2 changes: 1 addition & 1 deletion sources/libengine/gui/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#define GCHL_GUI_COMMON_COMPONENTS Parent, Image, ImageFormat, Text, TextFormat, Selection, WidgetState, SelectedItem, LayoutScrollbars, LayoutAlignment, ExplicitSize, Event, Tooltip, TooltipMarker
#define GCHL_GUI_WIDGET_COMPONENTS Label, Button, Input, TextArea, CheckBox, RadioBox, ComboBox, ProgressBar, SliderBar, ColorPicker, Panel, Spoiler
#define GCHL_GUI_LAYOUT_COMPONENTS LayoutLine, LayoutTable
#define GCHL_GUI_LAYOUT_COMPONENTS LayoutLine, LayoutSplit, LayoutTable

namespace cage
{
Expand Down
17 changes: 17 additions & 0 deletions sources/libengine/gui/guiBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,23 @@ namespace cage
return c;
}

BuilderItem GuiBuilder::horizontalSplit(Real verticalAlign)
{
BuilderItem c(this);
GuiLayoutSplitComponent &l = c->value<GuiLayoutSplitComponent>();
l.crossAlign = verticalAlign;
return c;
}

BuilderItem GuiBuilder::verticalSplit(Real horizontalAlign)
{
BuilderItem c(this);
GuiLayoutSplitComponent &l = c->value<GuiLayoutSplitComponent>();
l.crossAlign = horizontalAlign;
l.vertical = true;
return c;
}

BuilderItem GuiBuilder::horizontalTable(uint32 rows, bool grid)
{
BuilderItem c(this);
Expand Down
62 changes: 62 additions & 0 deletions sources/libengine/gui/layouts/split.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "../private.h"

namespace cage
{
namespace
{
struct SplitImpl : public LayoutItem
{
const GuiLayoutSplitComponent &data;

SplitImpl(HierarchyItem *hierarchy) : LayoutItem(hierarchy), data(GUI_REF_COMPONENT(LayoutSplit)) {}

void initialize() override
{
CAGE_ASSERT(!hierarchy->text);
CAGE_ASSERT(!hierarchy->image);
}

void findRequestedSize() override
{
hierarchy->requestedSize = Vec2();
for (const auto &c : hierarchy->children)
{
c->findRequestedSize();
hierarchy->requestedSize = max(hierarchy->requestedSize, c->requestedSize);
}
hierarchy->requestedSize[data.vertical] *= hierarchy->children.size();
CAGE_ASSERT(hierarchy->requestedSize.valid());
}

void findFinalPosition(const FinalPosition &update) override
{
if (hierarchy->children.empty())
return;
const uint32 h = data.vertical ? 1 : hierarchy->children.size();
const uint32 v = data.vertical ? hierarchy->children.size() : 1;
const Vec2 s = update.renderSize / Vec2(h, v);
CAGE_ASSERT(s.valid());
Real offset = 0;
for (const auto &c : hierarchy->children)
{
FinalPosition u(update);
u.renderSize = s;
u.renderPos[data.vertical] += offset;
if (data.crossAlign.valid())
{
u.renderSize[!data.vertical] = min(c->requestedSize[!data.vertical], u.renderSize[!data.vertical]);
u.renderPos[!data.vertical] += (update.renderSize[!data.vertical] - u.renderSize[!data.vertical]) * data.crossAlign;
}
c->findFinalPosition(u);
offset += s[data.vertical];
}
}
};
}

void LayoutSplitCreate(HierarchyItem *item)
{
CAGE_ASSERT(!item->item);
item->item = item->impl->memory->createHolder<SplitImpl>(item).cast<BaseItem>();
}
}

0 comments on commit 7fa55cb

Please sign in to comment.