layout refactoring

This commit is contained in:
BlackMATov
2020-04-15 21:45:47 +07:00
parent cdd3007476
commit eda66d3dd5
14 changed files with 723 additions and 487 deletions

View File

@@ -14,23 +14,31 @@ namespace e2d
public:
class dirty final {};
public:
ENUM_HPP_CLASS_DECL(haligns, u8,
(left)
(center)
(right)
(space_around)
(space_evenly)
(space_between))
ENUM_HPP_CLASS_DECL(valigns, u8,
(top)
(center)
(bottom)
(space_around)
(space_evenly)
(space_between))
ENUM_HPP_CLASS_DECL(directions, u8,
(ltr)
(rtl))
ENUM_HPP_CLASS_DECL(align_modes, u8,
(flex_start)
(center)
(flex_end)
(space_between)
(space_around))
ENUM_HPP_CLASS_DECL(justify_modes, u8,
(flex_start)
(center)
(flex_end)
(space_between)
(space_around)
(space_evenly))
ENUM_HPP_CLASS_DECL(flex_wraps, u8,
(no_wrap)
(wrap)
(wrap_reversed))
ENUM_HPP_CLASS_DECL(flex_directions, u8,
(row)
(row_reversed)
(column)
@@ -38,37 +46,38 @@ namespace e2d
public:
layout() = default;
layout& halign(haligns value) noexcept;
[[nodiscard]] haligns halign() const noexcept;
layout& valign(valigns value) noexcept;
[[nodiscard]] valigns valign() const noexcept;
layout& direction(directions value) noexcept;
[[nodiscard]] directions direction() const noexcept;
public:
layout& size(const v2f& value) noexcept;
[[nodiscard]] const v2f& size() const noexcept;
layout& margin(const v2f& value) noexcept;
[[nodiscard]] const v2f& margin() const noexcept;
layout& align_items(align_modes value) noexcept;
[[nodiscard]] align_modes align_items() const noexcept;
layout& padding(const v2f& value) noexcept;
[[nodiscard]] const v2f& padding() const noexcept;
layout& align_content(align_modes value) noexcept;
[[nodiscard]] align_modes align_content() const noexcept;
layout& justify_content(justify_modes value) noexcept;
[[nodiscard]] justify_modes justify_content() const noexcept;
layout& flex_wrap(flex_wraps value) noexcept;
[[nodiscard]] flex_wraps flex_wrap() const noexcept;
layout& flex_direction(flex_directions value) noexcept;
[[nodiscard]] flex_directions flex_direction() const noexcept;
private:
haligns halign_ = haligns::center;
valigns valign_ = valigns::center;
directions direction_ = directions::row;
private:
v2f size_ = v2f::zero();
v2f margin_ = v2f::zero();
v2f padding_ = v2f::zero();
directions direction_ = directions::ltr;
align_modes align_items_ = align_modes::flex_start;
align_modes align_content_ = align_modes::flex_start;
justify_modes justify_content_ = justify_modes::flex_start;
flex_wraps flex_wrap_ = flex_wraps::no_wrap;
flex_directions flex_direction_ = flex_directions::row;
};
}
ENUM_HPP_REGISTER_TRAITS(e2d::layout::haligns)
ENUM_HPP_REGISTER_TRAITS(e2d::layout::valigns)
ENUM_HPP_REGISTER_TRAITS(e2d::layout::directions)
ENUM_HPP_REGISTER_TRAITS(e2d::layout::align_modes)
ENUM_HPP_REGISTER_TRAITS(e2d::layout::justify_modes)
ENUM_HPP_REGISTER_TRAITS(e2d::layout::flex_wraps)
ENUM_HPP_REGISTER_TRAITS(e2d::layout::flex_directions)
namespace e2d
{
@@ -109,30 +118,11 @@ namespace e2d
static const char* title;
void operator()(gcomponent<layout>& c) const;
void operator()(gcomponent<layout>& c, gizmos_context& ctx) const;
};
}
namespace e2d
{
inline layout& layout::halign(haligns value) noexcept {
halign_ = value;
return *this;
}
inline layout::haligns layout::halign() const noexcept {
return halign_;
}
inline layout& layout::valign(valigns value) noexcept {
valign_ = value;
return *this;
}
inline layout::valigns layout::valign() const noexcept {
return valign_;
}
inline layout& layout::direction(directions value) noexcept {
direction_ = value;
return *this;
@@ -142,31 +132,49 @@ namespace e2d
return direction_;
}
inline layout& layout::size(const v2f& value) noexcept {
size_ = value;
inline layout& layout::align_items(align_modes value) noexcept {
align_items_ = value;
return *this;
}
inline const v2f& layout::size() const noexcept {
return size_;
inline layout::align_modes layout::align_items() const noexcept {
return align_items_;
}
inline layout& layout::margin(const v2f& value) noexcept {
margin_ = value;
inline layout& layout::align_content(align_modes value) noexcept {
align_content_ = value;
return *this;
}
inline const v2f& layout::margin() const noexcept {
return margin_;
inline layout::align_modes layout::align_content() const noexcept {
return align_content_;
}
inline layout& layout::padding(const v2f& value) noexcept {
padding_ = value;
inline layout& layout::justify_content(justify_modes value) noexcept {
justify_content_ = value;
return *this;
}
inline const v2f& layout::padding() const noexcept {
return padding_;
inline layout::justify_modes layout::justify_content() const noexcept {
return justify_content_;
}
inline layout& layout::flex_wrap(flex_wraps value) noexcept {
flex_wrap_ = value;
return *this;
}
inline layout::flex_wraps layout::flex_wrap() const noexcept {
return flex_wrap_;
}
inline layout& layout::flex_direction(flex_directions value) noexcept {
flex_direction_ = value;
return *this;
}
inline layout::flex_directions layout::flex_direction() const noexcept {
return flex_direction_;
}
}
@@ -176,13 +184,12 @@ namespace e2d::layouts
gcomponent<layout> unmark_dirty(gcomponent<layout> self);
bool is_dirty(const const_gcomponent<layout>& self) noexcept;
gcomponent<layout> change_halign(gcomponent<layout> self, layout::haligns value);
gcomponent<layout> change_valign(gcomponent<layout> self, layout::valigns value);
gcomponent<layout> change_direction(gcomponent<layout> self, layout::directions value);
gcomponent<layout> change_size(gcomponent<layout> self, const v2f& value);
gcomponent<layout> change_margin(gcomponent<layout> self, const v2f& value);
gcomponent<layout> change_padding(gcomponent<layout> self, const v2f& value);
gcomponent<layout> change_align_items(gcomponent<layout> self, layout::align_modes value);
gcomponent<layout> change_align_content(gcomponent<layout> self, layout::align_modes value);
gcomponent<layout> change_justify_content(gcomponent<layout> self, layout::justify_modes value);
gcomponent<layout> change_flex_wrap(gcomponent<layout> self, layout::flex_wraps value);
gcomponent<layout> change_flex_direction(gcomponent<layout> self, layout::flex_directions value);
gcomponent<layout> find_parent_layout(const_gcomponent<layout> self) noexcept;
}

View File

@@ -11,17 +11,23 @@
namespace e2d
{
class widget final {
public:
class dirty final {};
public:
widget() = default;
widget& size(const v2f& value) noexcept;
[[nodiscard]] const v2f& size() const noexcept;
widget& pivot(const v2f& value) noexcept;
[[nodiscard]] const v2f& pivot() const noexcept;
widget& margin(const v2f& value) noexcept;
[[nodiscard]] const v2f& margin() const noexcept;
widget& padding(const v2f& value) noexcept;
[[nodiscard]] const v2f& padding() const noexcept;
private:
v2f size_ = v2f::zero();
v2f pivot_ = v2f::unit() * 0.5f;
v2f margin_ = v2f::zero();
v2f padding_ = v2f::zero();
};
}
@@ -40,6 +46,20 @@ namespace e2d
asset_dependencies& dependencies,
const collect_context& ctx) const;
};
template <>
class factory_loader<widget::dirty> final : factory_loader<> {
public:
static const char* schema_source;
bool operator()(
widget::dirty& component,
const fill_context& ctx) const;
bool operator()(
asset_dependencies& dependencies,
const collect_context& ctx) const;
};
}
namespace e2d
@@ -50,6 +70,7 @@ namespace e2d
static const char* title;
void operator()(gcomponent<widget>& c) const;
void operator()(gcomponent<widget>& c, gizmos_context& ctx) const;
};
}
@@ -64,12 +85,34 @@ namespace e2d
return size_;
}
inline widget& widget::pivot(const v2f& value) noexcept {
pivot_ = value;
inline widget& widget::margin(const v2f& value) noexcept {
margin_ = value;
return *this;
}
inline const v2f& widget::pivot() const noexcept {
return pivot_;
inline const v2f& widget::margin() const noexcept {
return margin_;
}
inline widget& widget::padding(const v2f& value) noexcept {
padding_ = value;
return *this;
}
inline const v2f& widget::padding() const noexcept {
return padding_;
}
}
namespace e2d::widgets
{
gcomponent<widget> mark_dirty(gcomponent<widget> self);
gcomponent<widget> unmark_dirty(gcomponent<widget> self);
bool is_dirty(const const_gcomponent<widget>& self) noexcept;
gcomponent<widget> change_size(gcomponent<widget> self, const v2f& value);
gcomponent<widget> change_margin(gcomponent<widget> self, const v2f& value);
gcomponent<widget> change_padding(gcomponent<widget> self, const v2f& value);
gcomponent<layout> find_parent_layout(const_gcomponent<widget> self) noexcept;
}

View File

@@ -1,4 +1,5 @@
{
"prototype" : "widget_prefab.json",
"components" : {
"named" : {
"name" : "layout"

View File

@@ -0,0 +1,9 @@
{
"components" : {
"named" : {
"name" : "widget"
},
"widget" : {},
"widget.dirty" : {}
}
}

View File

@@ -15,14 +15,16 @@
"prototype" : "../prefabs/layout_prefab.json",
"components" : {
"layout" : {
"size" : [400,200],
"halign" : "space_evenly"
"justify_content" : "space_evenly"
},
"widget" : {
"size" : [400,200]
}
},
"children" : [{
"prototype" : "../prefabs/layout_prefab.json",
"prototype" : "../prefabs/widget_prefab.json",
"components" : {
"layout" : {
"widget" : {
"size" : [66,113]
}
},
@@ -35,9 +37,9 @@
}
}]
},{
"prototype" : "../prefabs/layout_prefab.json",
"prototype" : "../prefabs/widget_prefab.json",
"components" : {
"layout" : {
"widget" : {
"size" : [66,113]
}
},
@@ -50,9 +52,9 @@
}
}]
},{
"prototype" : "../prefabs/layout_prefab.json",
"prototype" : "../prefabs/widget_prefab.json",
"components" : {
"layout" : {
"widget" : {
"size" : [66,113]
}
},

View File

@@ -9,47 +9,59 @@ local layout = {
---@type boolean
dirty = false,
---@type layout_haligns
halign = layout.haligns.center,
---@type layout_valigns
valign = layout.valigns.center,
---@type layout_directions
direction = layout.directions.row,
direction = layout.directions.ltr,
---@type v2f
size = v2f.zero(),
---@type layout_align_modes
align_items = layout.align_modes.flex_start,
---@type v2f
margin = v2f.zero(),
---@type layout_align_modes
align_conten = layout.align_modes.flex_start,
---@type v2f
padding = v2f.zero()
}
---@type layout_justify_modes
justify_content = layout.justify_modes.flex_start,
---@class layout_haligns
layout.haligns = {
left = "left",
center = "center",
right = "right",
space_around = "space_around",
space_evenly = "space_evenly",
space_between = "space_between"
}
---@type layout_flex_wraps
flex_wrap = layout.flex_wraps.no_wrap,
---@class layout_valigns
layout.valigns = {
top = "top",
center = "center",
bottom = "bottom",
space_around = "space_around",
space_evenly = "space_evenly",
space_between = "space_between"
---@type layout_flex_directions
flex_direction = layout.flex_directions.row
}
---@class layout_directions
layout.directions = {
ltr = "ltr",
rtl = "rtl"
}
---@class layout_align_modes
layout.align_modes = {
flex_start = "flex_start",
center = "center",
flex_end = "flex_end",
space_between = "space_between",
space_around = "space_around"
}
---@class layout_justify_modes
layout.justify_modes = {
flex_start = "flex_start",
center = "center",
flex_end = "flex_end",
space_between = "space_between",
space_around = "space_around",
space_evenly = "space_evenly"
}
---@class layout_flex_wraps
layout.flex_wraps = {
no_wrap = "no_wrap",
wrap = "wrap",
wrap_reversed = "wrap_reversed"
}
---@class layout_flex_directions
layout.flex_directions = {
row = "row",
row_reversed = "row_reversed",
column = "column",

View File

@@ -6,11 +6,17 @@ local widget = {
---@type boolean
disabled = false,
---@type boolean
dirty = false,
---@type v2f
size = v2f.zero(),
---@type v2f
pivot = v2f.unit() * 0.5
margin = v2f.zero(),
---@type v2f
padding = v2f.zero()
}
---@overload fun(self: widget)

View File

@@ -67,22 +67,6 @@ namespace e2d::bindings::high
}
),
"halign", sol::property(
[](const gcomponent<layout>& c) -> layout::haligns {
return c->halign();
},
[](gcomponent<layout>& c, layout::haligns v){
layouts::change_halign(c, v);
}),
"valign", sol::property(
[](const gcomponent<layout>& c) -> layout::valigns {
return c->valign();
},
[](gcomponent<layout>& c, layout::valigns v){
layouts::change_valign(c, v);
}),
"direction", sol::property(
[](const gcomponent<layout>& c) -> layout::directions {
return c->direction();
@@ -91,63 +75,95 @@ namespace e2d::bindings::high
layouts::change_direction(c, v);
}),
"size", sol::property(
[](const gcomponent<layout>& c) -> v2f {
return c->size();
"align_items", sol::property(
[](const gcomponent<layout>& c) -> layout::align_modes {
return c->align_items();
},
[](gcomponent<layout>& c, const v2f& v){
layouts::change_size(c, v);
[](gcomponent<layout>& c, layout::align_modes v){
layouts::change_align_items(c, v);
}),
"margin", sol::property(
[](const gcomponent<layout>& c) -> v2f {
return c->margin();
"align_content", sol::property(
[](const gcomponent<layout>& c) -> layout::align_modes {
return c->align_content();
},
[](gcomponent<layout>& c, const v2f& v){
layouts::change_margin(c, v);
[](gcomponent<layout>& c, layout::align_modes v){
layouts::change_align_content(c, v);
}),
"padding", sol::property(
[](const gcomponent<layout>& c) -> v2f {
return c->padding();
"justify_content", sol::property(
[](const gcomponent<layout>& c) -> layout::justify_modes {
return c->justify_content();
},
[](gcomponent<layout>& c, const v2f& v){
layouts::change_padding(c, v);
[](gcomponent<layout>& c, layout::justify_modes v){
layouts::change_justify_content(c, v);
}),
"flex_wrap", sol::property(
[](const gcomponent<layout>& c) -> layout::flex_wraps {
return c->flex_wrap();
},
[](gcomponent<layout>& c, layout::flex_wraps v){
layouts::change_flex_wrap(c, v);
}),
"flex_direction", sol::property(
[](const gcomponent<layout>& c) -> layout::flex_directions {
return c->flex_direction();
},
[](gcomponent<layout>& c, layout::flex_directions v){
layouts::change_flex_direction(c, v);
})
);
#define LAYOUT_HALIGN_PAIR(x) {#x, layout::haligns::x},
l["layout"].get_or_create<sol::table>()
.new_enum<layout::haligns>("haligns", {
LAYOUT_HALIGN_PAIR(left)
LAYOUT_HALIGN_PAIR(center)
LAYOUT_HALIGN_PAIR(right)
LAYOUT_HALIGN_PAIR(space_around)
LAYOUT_HALIGN_PAIR(space_evenly)
LAYOUT_HALIGN_PAIR(space_between)
});
#undef LAYOUT_HALIGN_PAIR
#define LAYOUT_VALIGN_PAIR(x) {#x, layout::valigns::x},
l["layout"].get_or_create<sol::table>()
.new_enum<layout::valigns>("valigns", {
LAYOUT_VALIGN_PAIR(top)
LAYOUT_VALIGN_PAIR(center)
LAYOUT_VALIGN_PAIR(bottom)
LAYOUT_VALIGN_PAIR(space_around)
LAYOUT_VALIGN_PAIR(space_evenly)
LAYOUT_VALIGN_PAIR(space_between)
});
#undef LAYOUT_VALIGN_PAIR
#define LAYOUT_DIRECTION_PAIR(x) {#x, layout::directions::x},
l["layout"].get_or_create<sol::table>()
.new_enum<layout::directions>("directions", {
LAYOUT_DIRECTION_PAIR(row)
LAYOUT_DIRECTION_PAIR(row_reversed)
LAYOUT_DIRECTION_PAIR(column)
LAYOUT_DIRECTION_PAIR(column_reversed)
LAYOUT_DIRECTION_PAIR(ltr)
LAYOUT_DIRECTION_PAIR(rtl)
});
#undef LAYOUT_DIRECTION_PAIR
#define LAYOUT_ALIGN_MODE_PAIR(x) {#x, layout::align_modes::x},
l["layout"].get_or_create<sol::table>()
.new_enum<layout::align_modes>("align_modes", {
LAYOUT_ALIGN_MODE_PAIR(flex_start)
LAYOUT_ALIGN_MODE_PAIR(center)
LAYOUT_ALIGN_MODE_PAIR(flex_end)
LAYOUT_ALIGN_MODE_PAIR(space_between)
LAYOUT_ALIGN_MODE_PAIR(space_around)
});
#undef LAYOUT_ALIGN_MODE_PAIR
#define LAYOUT_JUSTIFY_MODE_PAIR(x) {#x, layout::justify_modes::x},
l["layout"].get_or_create<sol::table>()
.new_enum<layout::justify_modes>("justify_modes", {
LAYOUT_JUSTIFY_MODE_PAIR(flex_start)
LAYOUT_JUSTIFY_MODE_PAIR(center)
LAYOUT_JUSTIFY_MODE_PAIR(flex_end)
LAYOUT_JUSTIFY_MODE_PAIR(space_between)
LAYOUT_JUSTIFY_MODE_PAIR(space_around)
LAYOUT_JUSTIFY_MODE_PAIR(space_evenly)
});
#undef LAYOUT_JUSTIFY_MODE_PAIR
#define LAYOUT_FLEX_WRAP_PAIR(x) {#x, layout::flex_wraps::x},
l["layout"].get_or_create<sol::table>()
.new_enum<layout::flex_wraps>("flex_wraps", {
LAYOUT_FLEX_WRAP_PAIR(no_wrap)
LAYOUT_FLEX_WRAP_PAIR(wrap)
LAYOUT_FLEX_WRAP_PAIR(wrap_reversed)
});
#undef LAYOUT_FLEX_WRAP_PAIR
#define LAYOUT_FLEX_DIRECTION_PAIR(x) {#x, layout::flex_directions::x},
l["layout"].get_or_create<sol::table>()
.new_enum<layout::flex_directions>("flex_directions", {
LAYOUT_FLEX_DIRECTION_PAIR(row)
LAYOUT_FLEX_DIRECTION_PAIR(row_reversed)
LAYOUT_FLEX_DIRECTION_PAIR(column)
LAYOUT_FLEX_DIRECTION_PAIR(column_reversed)
});
#undef LAYOUT_FLEX_DIRECTION_PAIR
}
}

View File

@@ -50,20 +50,41 @@ namespace e2d::bindings::high
}
),
"dirty", sol::property(
[](const gcomponent<widget>& c) -> bool {
return widgets::is_dirty(c);
},
[](gcomponent<widget>& c, bool yesno){
if ( yesno ) {
widgets::mark_dirty(c);
} else {
widgets::unmark_dirty(c);
}
}
),
"size", sol::property(
[](const gcomponent<widget>& c) -> v2f {
return c->size();
},
[](gcomponent<widget>& c, const v2f& v){
c->size(v);
widgets::change_size(c, v);
}),
"pivot", sol::property(
"margin", sol::property(
[](const gcomponent<widget>& c) -> v2f {
return c->pivot();
return c->margin();
},
[](gcomponent<widget>& c, const v2f& v){
c->pivot(v);
widgets::change_margin(c, v);
}),
"padding", sol::property(
[](const gcomponent<widget>& c) -> v2f {
return c->padding();
},
[](gcomponent<widget>& c, const v2f& v){
widgets::change_padding(c, v);
})
);
}

View File

@@ -15,37 +15,51 @@ namespace e2d
"required" : [],
"additionalProperties" : false,
"properties" : {
"halign" : { "$ref": "#/definitions/haligns" },
"valign" : { "$ref": "#/definitions/valigns" },
"direction" : { "$ref": "#/definitions/directions" },
"size" : { "$ref": "#/common_definitions/v2" },
"margin" : { "$ref": "#/common_definitions/v2" },
"padding" : { "$ref": "#/common_definitions/v2" }
"align_items" : { "$ref": "#/definitions/align_modes" },
"align_content" : { "$ref": "#/definitions/align_modes" },
"justify_content" : { "$ref": "#/definitions/justify_modes" },
"flex_wrap" : { "$ref": "#/definitions/flex_wraps" },
"flex_direction" : { "$ref": "#/definitions/flex_directions" }
},
"definitions" : {
"haligns" : {
"type" : "string",
"enum" : [
"left",
"center",
"right",
"space_around",
"space_evenly",
"space_between"
]
},
"valigns" : {
"type" : "string",
"enum" : [
"top",
"center",
"bottom",
"space_around",
"space_evenly",
"space_between"
]
},
"directions" : {
"type" : "string",
"enum" : [
"ltr",
"rtl"
]
},
"align_modes" : {
"type" : "string",
"enum" : [
"flex_start",
"center",
"flex_end",
"space_between",
"space_around"
]
},
"justify_modes" : {
"type" : "string",
"enum" : [
"flex_start",
"center",
"flex_end",
"space_between",
"space_around",
"space_evenly"
]
},
"flex_wraps" : {
"type" : "string",
"enum" : [
"no_wrap",
"wrap",
"wrap_reversed"
]
},
"flex_directions" : {
"type" : "string",
"enum" : [
"row",
@@ -61,24 +75,6 @@ namespace e2d
layout& component,
const fill_context& ctx) const
{
if ( ctx.root.HasMember("halign") ) {
layout::haligns halign = component.halign();
if ( !json_utils::try_parse_value(ctx.root["halign"], halign) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'halign' property");
return false;
}
component.halign(halign);
}
if ( ctx.root.HasMember("valign") ) {
layout::valigns valign = component.valign();
if ( !json_utils::try_parse_value(ctx.root["valign"], valign) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'valign' property");
return false;
}
component.valign(valign);
}
if ( ctx.root.HasMember("direction") ) {
layout::directions direction = component.direction();
if ( !json_utils::try_parse_value(ctx.root["direction"], direction) ) {
@@ -88,31 +84,49 @@ namespace e2d
component.direction(direction);
}
if ( ctx.root.HasMember("size") ) {
v2f size = component.size();
if ( !json_utils::try_parse_value(ctx.root["size"], size) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'size' property");
if ( ctx.root.HasMember("align_items") ) {
layout::align_modes align_items = component.align_items();
if ( !json_utils::try_parse_value(ctx.root["align_items"], align_items) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'align_items' property");
return false;
}
component.size(size);
component.align_items(align_items);
}
if ( ctx.root.HasMember("margin") ) {
v2f margin = component.margin();
if ( !json_utils::try_parse_value(ctx.root["margin"], margin) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'margin' property");
if ( ctx.root.HasMember("align_content") ) {
layout::align_modes align_content = component.align_content();
if ( !json_utils::try_parse_value(ctx.root["align_content"], align_content) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'align_content' property");
return false;
}
component.margin(margin);
component.align_content(align_content);
}
if ( ctx.root.HasMember("padding") ) {
v2f padding = component.padding();
if ( !json_utils::try_parse_value(ctx.root["padding"], padding) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'padding' property");
if ( ctx.root.HasMember("justify_content") ) {
layout::justify_modes justify_content = component.justify_content();
if ( !json_utils::try_parse_value(ctx.root["justify_content"], justify_content) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'justify_content' property");
return false;
}
component.padding(padding);
component.justify_content(justify_content);
}
if ( ctx.root.HasMember("flex_wrap") ) {
layout::flex_wraps flex_wrap = component.flex_wrap();
if ( !json_utils::try_parse_value(ctx.root["flex_wrap"], flex_wrap) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'flex_wrap' property");
return false;
}
component.flex_wrap(flex_wrap);
}
if ( ctx.root.HasMember("flex_direction") ) {
layout::flex_directions flex_direction = component.flex_direction();
if ( !json_utils::try_parse_value(ctx.root["flex_direction"], flex_direction) ) {
the<debug>().error("LAYOUT: Incorrect formatting of 'flex_direction' property");
return false;
}
component.flex_direction(flex_direction);
}
return true;
@@ -170,66 +184,40 @@ namespace e2d
ImGui::Separator();
if ( layout::haligns halign = c->halign();
imgui_utils::show_enum_combo_box("halign", &halign) )
{
layouts::change_halign(c, halign);
}
if ( layout::valigns valign = c->valign();
imgui_utils::show_enum_combo_box("valign", &valign) )
{
layouts::change_valign(c, valign);
}
if ( layout::directions direction = c->direction();
imgui_utils::show_enum_combo_box("direction", &direction) )
{
layouts::change_direction(c, direction);
}
if ( v2f size = c->size();
ImGui::DragFloat2("size", size.data(), 1.f) )
if ( layout::align_modes align_items = c->align_items();
imgui_utils::show_enum_combo_box("align_items", &align_items) )
{
layouts::change_size(c, size);
layouts::change_align_items(c, align_items);
}
if ( v2f margin = c->margin();
ImGui::DragFloat2("margin", margin.data(), 1.f) )
if ( layout::align_modes align_content = c->align_content();
imgui_utils::show_enum_combo_box("align_content", &align_content) )
{
layouts::change_margin(c, margin);
layouts::change_align_content(c, align_content);
}
if ( v2f padding = c->padding();
ImGui::DragFloat2("padding", padding.data(), 1.f) )
if ( layout::justify_modes justify_content = c->justify_content();
imgui_utils::show_enum_combo_box("justify_content", &justify_content) )
{
layouts::change_padding(c, padding);
layouts::change_justify_content(c, justify_content);
}
}
void component_inspector<layout>::operator()(
gcomponent<layout>& c,
gizmos_context& ctx) const
{
ctx.draw_wire_rect(
c->size() * 0.5f,
c->size(),
ctx.selected() ? color32(255,255,255) : color32(127,127,127));
if ( layout::flex_wraps flex_wrap = c->flex_wrap();
imgui_utils::show_enum_combo_box("flex_wrap", &flex_wrap) )
{
layouts::change_flex_wrap(c, flex_wrap);
}
if ( ctx.selected() ) {
if ( c->margin() != v2f::zero() ) {
ctx.draw_wire_rect(
c->size() * 0.5f,
c->size() + c->margin() * 2.f,
ctx.selected() ? color32(255,255,255) : color32(127,127,127));
}
if ( c->padding() != v2f::zero() ) {
ctx.draw_wire_rect(
c->size() * 0.5f,
c->size() - c->padding() * 2.f,
ctx.selected() ? color32(255,255,255) : color32(127,127,127));
}
if ( layout::flex_directions flex_direction = c->flex_direction();
imgui_utils::show_enum_combo_box("flex_direction", &flex_direction) )
{
layouts::change_flex_direction(c, flex_direction);
}
}
}
@@ -254,20 +242,6 @@ namespace e2d::layouts
return self.owner().component<layout::dirty>().exists();
}
gcomponent<layout> change_halign(gcomponent<layout> self, layout::haligns value) {
if ( self ) {
self->halign(value);
}
return mark_dirty(self);
}
gcomponent<layout> change_valign(gcomponent<layout> self, layout::valigns value) {
if ( self ) {
self->valign(value);
}
return mark_dirty(self);
}
gcomponent<layout> change_direction(gcomponent<layout> self, layout::directions value) {
if ( self ) {
self->direction(value);
@@ -275,27 +249,38 @@ namespace e2d::layouts
return mark_dirty(self);
}
gcomponent<layout> change_size(gcomponent<layout> self, const v2f& value) {
gcomponent<layout> change_align_items(gcomponent<layout> self, layout::align_modes value) {
if ( self ) {
self->size(value);
self->align_items(value);
}
mark_dirty(find_parent_layout(self));
return mark_dirty(self);
}
gcomponent<layout> change_margin(gcomponent<layout> self, const v2f& value) {
gcomponent<layout> change_align_content(gcomponent<layout> self, layout::align_modes value) {
if ( self ) {
self->margin(value);
self->align_content(value);
}
mark_dirty(find_parent_layout(self));
return mark_dirty(self);
}
gcomponent<layout> change_padding(gcomponent<layout> self, const v2f& value) {
gcomponent<layout> change_justify_content(gcomponent<layout> self, layout::justify_modes value) {
if ( self ) {
self->padding(value);
self->justify_content(value);
}
return mark_dirty(self);
}
gcomponent<layout> change_flex_wrap(gcomponent<layout> self, layout::flex_wraps value) {
if ( self ) {
self->flex_wrap(value);
}
return mark_dirty(self);
}
gcomponent<layout> change_flex_direction(gcomponent<layout> self, layout::flex_directions value) {
if ( self ) {
self->flex_direction(value);
}
mark_dirty(find_parent_layout(self));
return mark_dirty(self);
}

View File

@@ -6,6 +6,9 @@
#include <enduro2d/high/components/widget.hpp>
#include <enduro2d/high/components/actor.hpp>
#include <enduro2d/high/components/layout.hpp>
namespace e2d
{
const char* factory_loader<widget>::schema_source = R"json({
@@ -14,7 +17,8 @@ namespace e2d
"additionalProperties" : false,
"properties" : {
"size" : { "$ref": "#/common_definitions/v2" },
"pivot" : { "$ref": "#/common_definitions/v2" }
"margin" : { "$ref": "#/common_definitions/v2" },
"padding" : { "$ref": "#/common_definitions/v2" }
}
})json";
@@ -31,13 +35,22 @@ namespace e2d
component.size(size);
}
if ( ctx.root.HasMember("pivot") ) {
v2f pivot = component.pivot();
if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) {
the<debug>().error("WIDGET: Incorrect formatting of 'pivot' property");
if ( ctx.root.HasMember("margin") ) {
v2f margin = component.margin();
if ( !json_utils::try_parse_value(ctx.root["margin"], margin) ) {
the<debug>().error("WIDGET: Incorrect formatting of 'margin' property");
return false;
}
component.pivot(pivot);
component.margin(margin);
}
if ( ctx.root.HasMember("padding") ) {
v2f padding = component.padding();
if ( !json_utils::try_parse_value(ctx.root["padding"], padding) ) {
the<debug>().error("WIDGET: Incorrect formatting of 'padding' property");
return false;
}
component.padding(padding);
}
return true;
@@ -52,21 +65,143 @@ namespace e2d
}
}
namespace e2d
{
const char* factory_loader<widget::dirty>::schema_source = R"json({
"type" : "object",
"required" : [],
"additionalProperties" : false,
"properties" : {}
})json";
bool factory_loader<widget::dirty>::operator()(
widget::dirty& component,
const fill_context& ctx) const
{
E2D_UNUSED(component, ctx);
return true;
}
bool factory_loader<widget::dirty>::operator()(
asset_dependencies& dependencies,
const collect_context& ctx) const
{
E2D_UNUSED(dependencies, ctx);
return true;
}
}
namespace e2d
{
const char* component_inspector<widget>::title = ICON_FA_VECTOR_SQUARE " widget";
void component_inspector<widget>::operator()(gcomponent<widget>& c) const {
if ( bool dirty = c.owner().component<widget::dirty>().exists();
ImGui::Checkbox("dirty", &dirty) )
{
if ( dirty ) {
widgets::mark_dirty(c);
} else {
widgets::unmark_dirty(c);
}
}
ImGui::Separator();
if ( v2f size = c->size();
ImGui::DragFloat2("size", size.data(), 1.f) )
{
c->size(size);
widgets::change_size(c, size);
}
if ( v2f pivot = c->pivot();
ImGui::DragFloat2("pivot", pivot.data(), 0.01f) )
if ( v2f margin = c->margin();
ImGui::DragFloat2("margin", margin.data(), 1.f) )
{
c->pivot(pivot);
widgets::change_margin(c, margin);
}
if ( v2f padding = c->padding();
ImGui::DragFloat2("padding", padding.data(), 1.f) )
{
widgets::change_padding(c, padding);
}
}
void component_inspector<widget>::operator()(
gcomponent<widget>& c,
gizmos_context& ctx) const
{
const color32 white_c{255,255,255};
const color32 gray_c{255,255,255,127};
ctx.draw_wire_rect(
c->size() * 0.5f,
c->size(),
ctx.selected() ? white_c : gray_c);
if ( ctx.selected() ) {
if ( c->margin() != v2f::zero() ) {
ctx.draw_wire_rect(
c->size() * 0.5f,
c->size() + c->margin() * 2.f,
ctx.selected() ? white_c : gray_c);
}
if ( c->padding() != v2f::zero() ) {
ctx.draw_wire_rect(
c->size() * 0.5f,
c->size() - c->padding() * 2.f,
ctx.selected() ? white_c : gray_c);
}
}
}
}
namespace e2d::widgets
{
gcomponent<widget> mark_dirty(gcomponent<widget> self) {
if ( self ) {
self.owner().component<widget::dirty>().ensure();
}
return self;
}
gcomponent<widget> unmark_dirty(gcomponent<widget> self) {
if ( self ) {
self.owner().component<widget::dirty>().remove();
}
return self;
}
bool is_dirty(const const_gcomponent<widget>& self) noexcept {
return self.owner().component<widget::dirty>().exists();
}
gcomponent<widget> change_size(gcomponent<widget> self, const v2f& value) {
if ( self ) {
self->size(value);
}
return mark_dirty(self);
}
gcomponent<widget> change_margin(gcomponent<widget> self, const v2f& value) {
if ( self ) {
self->margin(value);
}
return mark_dirty(self);
}
gcomponent<widget> change_padding(gcomponent<widget> self, const v2f& value) {
if ( self ) {
self->padding(value);
}
return mark_dirty(self);
}
gcomponent<layout> find_parent_layout(const_gcomponent<widget> self) noexcept {
const_gcomponent<actor> self_actor = self.owner().component<actor>();
return self_actor
? nodes::find_component_from_parents<layout>(self_actor->node())
: gcomponent<layout>();
}
}

View File

@@ -214,6 +214,7 @@ namespace e2d
.register_component<touchable>("touchable")
.register_component<events<touchable_events::event>>("touchable.events")
.register_component<widget>("widget")
.register_component<widget::dirty>("widget.dirty")
;
safe_module_initialize<inspector>()
@@ -241,6 +242,7 @@ namespace e2d
.register_component<touchable>("touchable")
//.register_component<events<touchable_events::event>>("touchable.events")
.register_component<widget>("widget")
//.register_component<widget::dirty>("widget.dirty")
;
safe_module_initialize<luasol>();

View File

@@ -9,6 +9,7 @@
#include <enduro2d/high/components/actor.hpp>
#include <enduro2d/high/components/disabled.hpp>
#include <enduro2d/high/components/layout.hpp>
#include <enduro2d/high/components/widget.hpp>
#include <3rdparty/yoga/Yoga.h>
@@ -21,153 +22,119 @@ namespace
node_ptr as_item{YGNodeNew(), YGNodeFree};
node_ptr as_root{YGNodeNew(), YGNodeFree};
};
}
namespace
{
using namespace e2d;
void update_yogo_node(const yogo_node& yn, const layout& l, const actor& a) {
switch ( l.direction() ) {
case layout::directions::row:
YGNodeStyleSetFlexDirection(yn.as_root.get(), YGFlexDirectionRow);
break;
case layout::directions::row_reversed:
YGNodeStyleSetFlexDirection(yn.as_root.get(), YGFlexDirectionRowReverse);
break;
case layout::directions::column:
YGNodeStyleSetFlexDirection(yn.as_root.get(), YGFlexDirectionColumn);
break;
case layout::directions::column_reversed:
YGNodeStyleSetFlexDirection(yn.as_root.get(), YGFlexDirectionColumnReverse);
break;
YGDirection convert_to_yogo_direction(layout::directions direction) noexcept {
switch ( direction ) {
case layout::directions::ltr:
return YGDirectionLTR;
case layout::directions::rtl:
return YGDirectionRTL;
default:
E2D_ASSERT_MSG(false, "unexpected layout direction");
break;
return YGDirectionLTR;
}
}
switch ( l.direction() ) {
case layout::directions::row:
case layout::directions::row_reversed:
switch ( l.halign() ) {
case layout::haligns::left:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifyFlexStart);
break;
case layout::haligns::center:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifyCenter);
break;
case layout::haligns::right:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifyFlexEnd);
break;
case layout::haligns::space_around:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifySpaceAround);
break;
case layout::haligns::space_evenly:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifySpaceEvenly);
break;
case layout::haligns::space_between:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifySpaceBetween);
break;
default:
E2D_ASSERT_MSG(false, "unexpected layout halign");
break;
}
switch ( l.valign() ) {
case layout::valigns::top:
case layout::valigns::space_between:
YGNodeStyleSetAlignItems(yn.as_root.get(), YGAlignFlexEnd);
break;
case layout::valigns::center:
case layout::valigns::space_around:
case layout::valigns::space_evenly:
YGNodeStyleSetAlignItems(yn.as_root.get(), YGAlignCenter);
break;
case layout::valigns::bottom:
YGNodeStyleSetAlignItems(yn.as_root.get(), YGAlignFlexStart);
break;
default:
E2D_ASSERT_MSG(false, "unexpected layout valign");
break;
}
break;
case layout::directions::column:
case layout::directions::column_reversed:
switch ( l.valign() ) {
case layout::valigns::top:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifyFlexEnd);
break;
case layout::valigns::center:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifyCenter);
break;
case layout::valigns::bottom:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifyFlexStart);
break;
case layout::valigns::space_around:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifySpaceAround);
break;
case layout::valigns::space_evenly:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifySpaceEvenly);
break;
case layout::valigns::space_between:
YGNodeStyleSetJustifyContent(yn.as_root.get(), YGJustifySpaceBetween);
break;
default:
E2D_ASSERT_MSG(false, "unexpected layout valign");
break;
}
switch ( l.halign() ) {
case layout::haligns::left:
case layout::haligns::space_between:
YGNodeStyleSetAlignItems(yn.as_root.get(), YGAlignFlexStart);
break;
case layout::haligns::center:
case layout::haligns::space_around:
case layout::haligns::space_evenly:
YGNodeStyleSetAlignItems(yn.as_root.get(), YGAlignCenter);
break;
case layout::haligns::right:
YGNodeStyleSetAlignItems(yn.as_root.get(), YGAlignFlexEnd);
break;
default:
E2D_ASSERT_MSG(false, "unexpected layout halign");
break;
}
break;
YGAlign convert_to_yogo_align(layout::align_modes align_mode) noexcept {
switch ( align_mode ) {
case layout::align_modes::flex_start:
return YGAlignFlexStart;
case layout::align_modes::center:
return YGAlignCenter;
case layout::align_modes::flex_end:
return YGAlignFlexEnd;
case layout::align_modes::space_between:
return YGAlignSpaceBetween;
case layout::align_modes::space_around:
return YGAlignSpaceAround;
default:
E2D_ASSERT_MSG(false, "unexpected layout mode");
break;
E2D_ASSERT_MSG(false, "unexpected layout align mode");
return YGAlignFlexStart;
}
}
{
YGNodeStyleSetWidth(yn.as_root.get(), l.size().x);
YGNodeStyleSetHeight(yn.as_root.get(), l.size().y);
YGNodeStyleSetPadding(yn.as_root.get(), YGEdgeHorizontal, l.padding().x);
YGNodeStyleSetPadding(yn.as_root.get(), YGEdgeVertical, l.padding().y);
YGJustify convert_to_yogo_justify(layout::justify_modes justify_mode) noexcept {
switch ( justify_mode ) {
case layout::justify_modes::flex_start:
return YGJustifyFlexStart;
case layout::justify_modes::center:
return YGJustifyCenter;
case layout::justify_modes::flex_end:
return YGJustifyFlexEnd;
case layout::justify_modes::space_between:
return YGJustifySpaceBetween;
case layout::justify_modes::space_around:
return YGJustifySpaceAround;
case layout::justify_modes::space_evenly:
return YGJustifySpaceEvenly;
default:
E2D_ASSERT_MSG(false, "unexpected layout justify mode");
return YGJustifyFlexStart;
}
}
{
const v2f& scale = a.node()
? a.node()->scale()
: v2f::unit();
YGNodeStyleSetWidth(yn.as_item.get(), l.size().x * scale.x);
YGNodeStyleSetHeight(yn.as_item.get(), l.size().y * scale.y);
YGNodeStyleSetMargin(yn.as_item.get(), YGEdgeHorizontal, l.margin().x * scale.x);
YGNodeStyleSetMargin(yn.as_item.get(), YGEdgeVertical, l.margin().y * scale.y);
YGWrap convert_to_yogo_flex_wrap(layout::flex_wraps flex_wrap) noexcept {
switch ( flex_wrap ) {
case layout::flex_wraps::no_wrap:
return YGWrapNoWrap;
case layout::flex_wraps::wrap:
return YGWrapWrap;
case layout::flex_wraps::wrap_reversed:
return YGWrapWrapReverse;
default:
E2D_ASSERT_MSG(false, "unexpected layout flex wrap");
return YGWrapNoWrap;
}
}
YGFlexDirection convert_to_yogo_flex_direction(layout::flex_directions flex_direction) noexcept {
switch ( flex_direction ) {
case layout::flex_directions::row:
return YGFlexDirectionRow;
case layout::flex_directions::row_reversed:
return YGFlexDirectionRowReverse;
case layout::flex_directions::column:
return YGFlexDirectionColumn;
case layout::flex_directions::column_reversed:
return YGFlexDirectionColumnReverse;
default:
E2D_ASSERT_MSG(false, "unexpected layout flex direction");
return YGFlexDirectionRow;
}
}
void update_yogo_layout(const yogo_node& yn, const layout& l, const widget& w) {
YGNodeStyleSetWidth(yn.as_root.get(), w.size().x);
YGNodeStyleSetHeight(yn.as_root.get(), w.size().y);
YGNodeStyleSetPadding(yn.as_root.get(), YGEdgeHorizontal, w.padding().x);
YGNodeStyleSetPadding(yn.as_root.get(), YGEdgeVertical, w.padding().y);
YGNodeStyleSetAlignItems(yn.as_root.get(), convert_to_yogo_align(l.align_items()));
YGNodeStyleSetAlignContent(yn.as_root.get(), convert_to_yogo_align(l.align_content()));
YGNodeStyleSetJustifyContent(yn.as_root.get(), convert_to_yogo_justify(l.justify_content()));
YGNodeStyleSetFlexWrap(yn.as_root.get(), convert_to_yogo_flex_wrap(l.flex_wrap()));
YGNodeStyleSetFlexDirection(yn.as_root.get(), convert_to_yogo_flex_direction(l.flex_direction()));
}
void update_yogo_widget(const yogo_node& yn, const widget& w, const actor& a) {
const v2f& scale = a.node()
? a.node()->scale()
: v2f::unit();
YGNodeStyleSetWidth(yn.as_item.get(), w.size().x * scale.x);
YGNodeStyleSetHeight(yn.as_item.get(), w.size().y * scale.y);
YGNodeStyleSetMargin(yn.as_item.get(), YGEdgeHorizontal, w.margin().x * scale.x);
YGNodeStyleSetMargin(yn.as_item.get(), YGEdgeVertical, w.margin().y * scale.y);
}
}
namespace
{
using namespace e2d;
void process_yogo_nodes(ecs::registry& owner) {
void update_yogo_nodes(ecs::registry& owner) {
ecsex::remove_all_components_with_disposer<yogo_node>(
owner,
[](ecs::entity e, const yogo_node&){
@@ -175,65 +142,65 @@ namespace
a && a->node() && a->node()->owner() )
{
gcomponent<layout> l{a->node()->owner()};
gcomponent<widget> w{a->node()->owner()};
layouts::mark_dirty(l);
layouts::mark_dirty(layouts::find_parent_layout(l));
layouts::mark_dirty(widgets::find_parent_layout(w));
}
},
!ecs::exists_all<
}, !ecs::exists_all<
actor,
layout>() ||
ecs::exists_any<
widget>()
|| ecs::exists_any<
disabled<actor>,
disabled<layout>>());
disabled<widget>>());
owner.for_joined_components<layout, actor>([](
owner.for_joined_components<widget, actor>([](
ecs::entity e,
const layout&,
const widget&,
const actor& a)
{
e.ensure_component<yogo_node>();
if ( a.node() && a.node()->owner() ) {
gcomponent<layout> l{a.node()->owner()};
gcomponent<widget> w{a.node()->owner()};
layouts::mark_dirty(l);
layouts::mark_dirty(layouts::find_parent_layout(l));
layouts::mark_dirty(widgets::find_parent_layout(w));
}
},
!ecs::exists_any<
}, !ecs::exists_any<
yogo_node,
disabled<actor>,
disabled<layout>>());
disabled<widget>>());
}
void process_dirty_layouts(ecs::registry& owner) {
owner.for_joined_components<layout::dirty, yogo_node, layout, actor>([](
void update_dirty_layouts(ecs::registry& owner) {
owner.for_joined_components<layout::dirty, yogo_node, layout, widget, actor>([](
const ecs::const_entity&,
const layout::dirty&,
const yogo_node& root_yn,
const layout& root_l,
const widget& root_w,
const actor& root_a)
{
update_yogo_node(root_yn, root_l, root_a);
});
static thread_local vector<gcomponent<widget>> item_ws;
E2D_DEFER([](){ item_ws.clear(); });
owner.for_joined_components<layout::dirty, yogo_node, actor>([](
const ecs::const_entity&,
const layout::dirty&,
const yogo_node& root_yn,
const actor& root_a)
{
static thread_local vector<gcomponent<layout>> items;
E2D_DEFER([](){ items.clear(); });
nodes::extract_components_from_children<layout>(
nodes::extract_components_from_children<widget>(
root_a.node(),
std::back_inserter(items));
std::back_inserter(item_ws));
E2D_DEFER([&root_yn](){
YGNodeRemoveAllChildren(root_yn.as_root.get());
});
for ( const auto& item : items ) {
if ( const auto& item_yn = item.owner().component<yogo_node>() ) {
update_yogo_layout(root_yn, root_l, root_w);
for ( const auto& item_w : item_ws ) {
const_gcomponent<actor> item_a{item_w.owner()};
const_gcomponent<yogo_node> item_yn{item_w.owner()};
if ( item_a && item_yn ) {
update_yogo_widget(
*item_yn,
*item_w,
*item_a);
YGNodeInsertChild(
root_yn.as_root.get(),
item_yn->as_item.get(),
@@ -245,11 +212,11 @@ namespace
root_yn.as_root.get(),
YGUndefined,
YGUndefined,
YGDirectionLTR);
convert_to_yogo_direction(root_l.direction()));
for ( const auto& item : items ) {
gcomponent<actor> item_a = item.owner().component<actor>();
const_gcomponent<yogo_node> item_yn = item.owner().component<yogo_node>();
for ( const auto& item_w : item_ws ) {
gcomponent<actor> item_a{item_w.owner()};
const_gcomponent<yogo_node> item_yn{item_w.owner()};
if ( item_a && item_a->node() && item_yn && item_yn->as_item ) {
item_a->node()->translation(v2f(
YGNodeLayoutGetLeft(item_yn->as_item.get()),
@@ -274,8 +241,8 @@ namespace e2d
~internal_state() noexcept = default;
void process_update(ecs::registry& owner) {
process_yogo_nodes(owner);
process_dirty_layouts(owner);
update_yogo_nodes(owner);
update_dirty_layouts(owner);
}
};

View File

@@ -6,6 +6,36 @@
#include <enduro2d/high/systems/widget_system.hpp>
#include <enduro2d/high/components/actor.hpp>
#include <enduro2d/high/components/disabled.hpp>
#include <enduro2d/high/components/layout.hpp>
#include <enduro2d/high/components/widget.hpp>
namespace
{
using namespace e2d;
void update_dirty_widgets(ecs::registry& owner) {
owner.for_joined_components<widget::dirty, widget, actor>([](
const ecs::const_entity&,
const widget::dirty&,
const widget&,
const actor& a)
{
if ( a.node() && a.node()->owner() ) {
gcomponent<layout> l{a.node()->owner()};
gcomponent<widget> w{a.node()->owner()};
layouts::mark_dirty(l);
layouts::mark_dirty(widgets::find_parent_layout(w));
}
}, !ecs::exists_any<
disabled<actor>,
disabled<widget>>());
owner.remove_all_components<widget::dirty>();
}
}
namespace e2d
{
//
@@ -18,7 +48,7 @@ namespace e2d
~internal_state() noexcept = default;
void process_update(ecs::registry& owner) {
E2D_UNUSED(owner);
update_dirty_widgets(owner);
}
};