mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 08:15:38 +07:00
Merge pull request #120 from enduro2d/feature/widget_size
Feature/widget size
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
#include "components/spine_player.hpp"
|
||||
#include "components/sprite_renderer.hpp"
|
||||
#include "components/touchable.hpp"
|
||||
#include "components/widget.hpp"
|
||||
|
||||
#include "resources/atlas.hpp"
|
||||
#include "resources/flipbook.hpp"
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace e2d
|
||||
class spine_player;
|
||||
class sprite_renderer;
|
||||
class touchable;
|
||||
class widget;
|
||||
|
||||
class atlas;
|
||||
class flipbook;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
118
headers/enduro2d/high/components/widget.hpp
Normal file
118
headers/enduro2d/high/components/widget.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "_components.hpp"
|
||||
|
||||
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& 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 margin_ = v2f::zero();
|
||||
v2f padding_ = v2f::zero();
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template <>
|
||||
class factory_loader<widget> final : factory_loader<> {
|
||||
public:
|
||||
static const char* schema_source;
|
||||
|
||||
bool operator()(
|
||||
widget& component,
|
||||
const fill_context& ctx) const;
|
||||
|
||||
bool operator()(
|
||||
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
|
||||
{
|
||||
template <>
|
||||
class component_inspector<widget> final : component_inspector<> {
|
||||
public:
|
||||
static const char* title;
|
||||
|
||||
void operator()(gcomponent<widget>& c) const;
|
||||
void operator()(gcomponent<widget>& c, gizmos_context& ctx) const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
inline widget& widget::size(const v2f& value) noexcept {
|
||||
size_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const v2f& widget::size() const noexcept {
|
||||
return size_;
|
||||
}
|
||||
|
||||
inline widget& widget::margin(const v2f& value) noexcept {
|
||||
margin_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -94,6 +94,12 @@ namespace e2d
|
||||
|
||||
gobject owner() const noexcept;
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
template < typename U >
|
||||
gcomponent<U> component() noexcept;
|
||||
|
||||
template < typename U >
|
||||
const_gcomponent<U> component() const noexcept;
|
||||
private:
|
||||
gobject owner_;
|
||||
};
|
||||
@@ -116,6 +122,9 @@ namespace e2d
|
||||
|
||||
gobject owner() const noexcept;
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
template < typename U >
|
||||
const_gcomponent<U> component() const noexcept;
|
||||
private:
|
||||
gobject owner_;
|
||||
};
|
||||
@@ -239,6 +248,18 @@ namespace e2d
|
||||
gcomponent<T>::operator bool() const noexcept {
|
||||
return exists();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
template < typename U >
|
||||
gcomponent<U> gcomponent<T>::component() noexcept {
|
||||
return owner_.component<U>();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
template < typename U >
|
||||
const_gcomponent<U> gcomponent<T>::component() const noexcept {
|
||||
return owner_.component<U>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
@@ -294,4 +315,10 @@ namespace e2d
|
||||
const_gcomponent<T>::operator bool() const noexcept {
|
||||
return exists();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
template < typename U >
|
||||
const_gcomponent<U> const_gcomponent<T>::component() const noexcept {
|
||||
return owner_.component<U>();
|
||||
}
|
||||
}
|
||||
|
||||
26
headers/enduro2d/high/systems/widget_system.hpp
Normal file
26
headers/enduro2d/high/systems/widget_system.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "_systems.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class widget_system final
|
||||
: public ecs::system<ecs::after<systems::update_event>> {
|
||||
public:
|
||||
widget_system();
|
||||
~widget_system() noexcept final;
|
||||
|
||||
void process(
|
||||
ecs::registry& owner,
|
||||
const ecs::after<systems::update_event>& trigger) override;
|
||||
private:
|
||||
class internal_state;
|
||||
std::unique_ptr<internal_state> state_;
|
||||
};
|
||||
}
|
||||
@@ -24,12 +24,15 @@ namespace e2d
|
||||
const ecs::registry& registry() const noexcept;
|
||||
|
||||
gobject instantiate();
|
||||
gobject instantiate(const prefab& prefab);
|
||||
gobject instantiate(const t2f& transform);
|
||||
|
||||
gobject instantiate(const node_iptr& parent);
|
||||
gobject instantiate(const prefab& prefab, const node_iptr& parent);
|
||||
|
||||
gobject instantiate(const node_iptr& parent, const t2f& transform);
|
||||
|
||||
gobject instantiate(const prefab& prefab);
|
||||
gobject instantiate(const prefab& prefab, const t2f& transform);
|
||||
|
||||
gobject instantiate(const prefab& prefab, const node_iptr& parent);
|
||||
gobject instantiate(const prefab& prefab, const node_iptr& parent, const t2f& transform);
|
||||
|
||||
void destroy_instance(gobject inst) noexcept;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"prototype" : "widget_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "layout"
|
||||
|
||||
9
samples/bin/library/prefabs/widget_prefab.json
Normal file
9
samples/bin/library/prefabs/widget_prefab.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "widget"
|
||||
},
|
||||
"widget" : {},
|
||||
"widget.dirty" : {}
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
|
||||
31
samples/bin/library/scripts/emmy/components/widget.lua
Normal file
31
samples/bin/library/scripts/emmy/components/widget.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
---@class widget
|
||||
local widget = {
|
||||
---@type boolean
|
||||
enabled = true,
|
||||
|
||||
---@type boolean
|
||||
disabled = false,
|
||||
|
||||
---@type boolean
|
||||
dirty = false,
|
||||
|
||||
---@type v2f
|
||||
size = v2f.zero(),
|
||||
|
||||
---@type v2f
|
||||
margin = v2f.zero(),
|
||||
|
||||
---@type v2f
|
||||
padding = v2f.zero()
|
||||
}
|
||||
|
||||
---@overload fun(self: widget)
|
||||
---@param self widget
|
||||
function widget.enable(self) end
|
||||
|
||||
---@overload fun(self: widget)
|
||||
---@param self widget
|
||||
function widget.disable(self) end
|
||||
|
||||
---@type widget
|
||||
_G.widget = _G.widget or widget
|
||||
@@ -52,7 +52,10 @@ local gobject = {
|
||||
sprite_renderer = nil,
|
||||
|
||||
---@type touchable
|
||||
touchable = nil
|
||||
touchable = nil,
|
||||
|
||||
---@type widget
|
||||
widget = nil
|
||||
}
|
||||
|
||||
---@param self gobject
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
local world = {
|
||||
}
|
||||
|
||||
---@overload fun(): gobject
|
||||
---@overload fun(transform: t2f): gobject
|
||||
---@overload fun(parent: node): gobject
|
||||
---@overload fun(parent: node, transform: t2f): gobject
|
||||
---@overload fun(prefab: prefab): gobject
|
||||
---@overload fun(prefab: prefab, transform: t2f): gobject
|
||||
---@overload fun(prefab: prefab, parent: node): gobject
|
||||
---@overload fun(prefab: prefab, parent: node, transform: t2f): gobject
|
||||
---@return gobject
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace e2d::bindings::high
|
||||
void bind_spine_player(sol::state& l);
|
||||
void bind_sprite_renderer(sol::state& l);
|
||||
void bind_touchable(sol::state& l);
|
||||
void bind_widget(sol::state& l);
|
||||
}
|
||||
|
||||
namespace e2d::bindings
|
||||
@@ -59,5 +60,6 @@ namespace e2d::bindings
|
||||
high::bind_spine_player(l);
|
||||
high::bind_sprite_renderer(l);
|
||||
high::bind_touchable(l);
|
||||
high::bind_widget(l);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,35 +17,35 @@ namespace e2d::bindings::high
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<behaviour>& c){
|
||||
c.owner().component<disabled<behaviour>>().remove();
|
||||
c.component<disabled<behaviour>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<behaviour>& c){
|
||||
c.owner().component<disabled<behaviour>>().ensure();
|
||||
c.component<disabled<behaviour>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<behaviour>& c) -> bool {
|
||||
return !c.owner().component<disabled<behaviour>>().exists();
|
||||
return !c.component<disabled<behaviour>>().exists();
|
||||
},
|
||||
[](gcomponent<behaviour>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<behaviour>>().remove();
|
||||
c.component<disabled<behaviour>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<behaviour>>().ensure();
|
||||
c.component<disabled<behaviour>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<behaviour>& c) -> bool {
|
||||
return c.owner().component<disabled<behaviour>>().exists();
|
||||
return c.component<disabled<behaviour>>().exists();
|
||||
},
|
||||
[](gcomponent<behaviour>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<behaviour>>().ensure();
|
||||
c.component<disabled<behaviour>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<behaviour>>().remove();
|
||||
c.component<disabled<behaviour>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
@@ -17,61 +17,61 @@ namespace e2d::bindings::high
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<camera>& c){
|
||||
c.owner().component<disabled<camera>>().remove();
|
||||
c.component<disabled<camera>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<camera>& c){
|
||||
c.owner().component<disabled<camera>>().ensure();
|
||||
c.component<disabled<camera>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<camera>& c) -> bool {
|
||||
return !c.owner().component<disabled<camera>>().exists();
|
||||
return !c.component<disabled<camera>>().exists();
|
||||
},
|
||||
[](gcomponent<camera>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<camera>>().remove();
|
||||
c.component<disabled<camera>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<camera>>().ensure();
|
||||
c.component<disabled<camera>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<camera>& c) -> bool {
|
||||
return c.owner().component<disabled<camera>>().exists();
|
||||
return c.component<disabled<camera>>().exists();
|
||||
},
|
||||
[](gcomponent<camera>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<camera>>().ensure();
|
||||
c.component<disabled<camera>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<camera>>().remove();
|
||||
c.component<disabled<camera>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"input", sol::property(
|
||||
[](const gcomponent<camera>& c) -> bool {
|
||||
return c.owner().component<camera::input>().exists();
|
||||
return c.component<camera::input>().exists();
|
||||
},
|
||||
[](gcomponent<camera>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<camera::input>().ensure();
|
||||
c.component<camera::input>().ensure();
|
||||
} else {
|
||||
c.owner().component<camera::input>().remove();
|
||||
c.component<camera::input>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"gizmos", sol::property(
|
||||
[](const gcomponent<camera>& c) -> bool {
|
||||
return c.owner().component<camera::gizmos>().exists();
|
||||
return c.component<camera::gizmos>().exists();
|
||||
},
|
||||
[](gcomponent<camera>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<camera::gizmos>().ensure();
|
||||
c.component<camera::gizmos>().ensure();
|
||||
} else {
|
||||
c.owner().component<camera::gizmos>().remove();
|
||||
c.component<camera::gizmos>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
@@ -19,35 +19,35 @@ namespace
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<rect_collider>& c){
|
||||
c.owner().component<disabled<rect_collider>>().remove();
|
||||
c.component<disabled<rect_collider>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<rect_collider>& c){
|
||||
c.owner().component<disabled<rect_collider>>().ensure();
|
||||
c.component<disabled<rect_collider>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<rect_collider>& c) -> bool {
|
||||
return !c.owner().component<disabled<rect_collider>>().exists();
|
||||
return !c.component<disabled<rect_collider>>().exists();
|
||||
},
|
||||
[](gcomponent<rect_collider>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<rect_collider>>().remove();
|
||||
c.component<disabled<rect_collider>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<rect_collider>>().ensure();
|
||||
c.component<disabled<rect_collider>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<rect_collider>& c) -> bool {
|
||||
return c.owner().component<disabled<rect_collider>>().exists();
|
||||
return c.component<disabled<rect_collider>>().exists();
|
||||
},
|
||||
[](gcomponent<rect_collider>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<rect_collider>>().ensure();
|
||||
c.component<disabled<rect_collider>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<rect_collider>>().remove();
|
||||
c.component<disabled<rect_collider>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
@@ -75,35 +75,35 @@ namespace
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<circle_collider>& c){
|
||||
c.owner().component<disabled<circle_collider>>().remove();
|
||||
c.component<disabled<circle_collider>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<circle_collider>& c){
|
||||
c.owner().component<disabled<circle_collider>>().ensure();
|
||||
c.component<disabled<circle_collider>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<circle_collider>& c) -> bool {
|
||||
return !c.owner().component<disabled<circle_collider>>().exists();
|
||||
return !c.component<disabled<circle_collider>>().exists();
|
||||
},
|
||||
[](gcomponent<circle_collider>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<circle_collider>>().remove();
|
||||
c.component<disabled<circle_collider>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<circle_collider>>().ensure();
|
||||
c.component<disabled<circle_collider>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<circle_collider>& c) -> bool {
|
||||
return c.owner().component<disabled<circle_collider>>().exists();
|
||||
return c.component<disabled<circle_collider>>().exists();
|
||||
},
|
||||
[](gcomponent<circle_collider>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<circle_collider>>().ensure();
|
||||
c.component<disabled<circle_collider>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<circle_collider>>().remove();
|
||||
c.component<disabled<circle_collider>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
@@ -131,35 +131,35 @@ namespace
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<polygon_collider>& c){
|
||||
c.owner().component<disabled<polygon_collider>>().remove();
|
||||
c.component<disabled<polygon_collider>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<polygon_collider>& c){
|
||||
c.owner().component<disabled<polygon_collider>>().ensure();
|
||||
c.component<disabled<polygon_collider>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<polygon_collider>& c) -> bool {
|
||||
return !c.owner().component<disabled<polygon_collider>>().exists();
|
||||
return !c.component<disabled<polygon_collider>>().exists();
|
||||
},
|
||||
[](gcomponent<polygon_collider>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<polygon_collider>>().remove();
|
||||
c.component<disabled<polygon_collider>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<polygon_collider>>().ensure();
|
||||
c.component<disabled<polygon_collider>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<polygon_collider>& c) -> bool {
|
||||
return c.owner().component<disabled<polygon_collider>>().exists();
|
||||
return c.component<disabled<polygon_collider>>().exists();
|
||||
},
|
||||
[](gcomponent<polygon_collider>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<polygon_collider>>().ensure();
|
||||
c.component<disabled<polygon_collider>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<polygon_collider>>().remove();
|
||||
c.component<disabled<polygon_collider>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
@@ -17,24 +17,24 @@ namespace e2d::bindings::high
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<layout>& c){
|
||||
c.owner().component<disabled<layout>>().remove();
|
||||
c.component<disabled<layout>>().remove();
|
||||
layouts::mark_dirty(c);
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<layout>& c){
|
||||
c.owner().component<disabled<layout>>().ensure();
|
||||
c.component<disabled<layout>>().ensure();
|
||||
layouts::mark_dirty(c);
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<layout>& c) -> bool {
|
||||
return !c.owner().component<disabled<layout>>().exists();
|
||||
return !c.component<disabled<layout>>().exists();
|
||||
},
|
||||
[](gcomponent<layout>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<layout>>().remove();
|
||||
c.component<disabled<layout>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<layout>>().ensure();
|
||||
c.component<disabled<layout>>().ensure();
|
||||
}
|
||||
layouts::mark_dirty(c);
|
||||
}
|
||||
@@ -42,13 +42,13 @@ namespace e2d::bindings::high
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<layout>& c) -> bool {
|
||||
return c.owner().component<disabled<layout>>().exists();
|
||||
return c.component<disabled<layout>>().exists();
|
||||
},
|
||||
[](gcomponent<layout>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<layout>>().ensure();
|
||||
c.component<disabled<layout>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<layout>>().remove();
|
||||
c.component<disabled<layout>>().remove();
|
||||
}
|
||||
layouts::mark_dirty(c);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,35 +17,35 @@ namespace e2d::bindings::high
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<renderer>& c){
|
||||
c.owner().component<disabled<renderer>>().remove();
|
||||
c.component<disabled<renderer>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<renderer>& c){
|
||||
c.owner().component<disabled<renderer>>().ensure();
|
||||
c.component<disabled<renderer>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<renderer>& c) -> bool {
|
||||
return !c.owner().component<disabled<renderer>>().exists();
|
||||
return !c.component<disabled<renderer>>().exists();
|
||||
},
|
||||
[](gcomponent<renderer>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<renderer>>().remove();
|
||||
c.component<disabled<renderer>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<renderer>>().ensure();
|
||||
c.component<disabled<renderer>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<renderer>& c) -> bool {
|
||||
return c.owner().component<disabled<renderer>>().exists();
|
||||
return c.component<disabled<renderer>>().exists();
|
||||
},
|
||||
[](gcomponent<renderer>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<renderer>>().ensure();
|
||||
c.component<disabled<renderer>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<renderer>>().remove();
|
||||
c.component<disabled<renderer>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
@@ -17,35 +17,35 @@ namespace e2d::bindings::high
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<scene>& c){
|
||||
c.owner().component<disabled<scene>>().remove();
|
||||
c.component<disabled<scene>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<scene>& c){
|
||||
c.owner().component<disabled<scene>>().ensure();
|
||||
c.component<disabled<scene>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<scene>& c) -> bool {
|
||||
return !c.owner().component<disabled<scene>>().exists();
|
||||
return !c.component<disabled<scene>>().exists();
|
||||
},
|
||||
[](gcomponent<scene>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<scene>>().remove();
|
||||
c.component<disabled<scene>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<scene>>().ensure();
|
||||
c.component<disabled<scene>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<scene>& c) -> bool {
|
||||
return c.owner().component<disabled<scene>>().exists();
|
||||
return c.component<disabled<scene>>().exists();
|
||||
},
|
||||
[](gcomponent<scene>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<scene>>().ensure();
|
||||
c.component<disabled<scene>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<scene>>().remove();
|
||||
c.component<disabled<scene>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
@@ -17,35 +17,35 @@ namespace e2d::bindings::high
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<touchable>& c){
|
||||
c.owner().component<disabled<touchable>>().remove();
|
||||
c.component<disabled<touchable>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<touchable>& c){
|
||||
c.owner().component<disabled<touchable>>().ensure();
|
||||
c.component<disabled<touchable>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<touchable>& c) -> bool {
|
||||
return !c.owner().component<disabled<touchable>>().exists();
|
||||
return !c.component<disabled<touchable>>().exists();
|
||||
},
|
||||
[](gcomponent<touchable>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<touchable>>().remove();
|
||||
c.component<disabled<touchable>>().remove();
|
||||
} else {
|
||||
c.owner().component<disabled<touchable>>().ensure();
|
||||
c.component<disabled<touchable>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<touchable>& c) -> bool {
|
||||
return c.owner().component<disabled<touchable>>().exists();
|
||||
return c.component<disabled<touchable>>().exists();
|
||||
},
|
||||
[](gcomponent<touchable>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<disabled<touchable>>().ensure();
|
||||
c.component<disabled<touchable>>().ensure();
|
||||
} else {
|
||||
c.owner().component<disabled<touchable>>().remove();
|
||||
c.component<disabled<touchable>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../_high_binds.hpp"
|
||||
|
||||
#include <enduro2d/high/gobject.hpp>
|
||||
#include <enduro2d/high/components/disabled.hpp>
|
||||
#include <enduro2d/high/components/widget.hpp>
|
||||
|
||||
namespace e2d::bindings::high
|
||||
{
|
||||
void bind_widget(sol::state& l) {
|
||||
l.new_usertype<gcomponent<widget>>("widget",
|
||||
sol::no_constructor,
|
||||
|
||||
"enable", [](gcomponent<widget>& c){
|
||||
c.component<disabled<widget>>().remove();
|
||||
},
|
||||
|
||||
"disable", [](gcomponent<widget>& c){
|
||||
c.component<disabled<widget>>().ensure();
|
||||
},
|
||||
|
||||
"enabled", sol::property(
|
||||
[](const gcomponent<widget>& c) -> bool {
|
||||
return !c.component<disabled<widget>>().exists();
|
||||
},
|
||||
[](gcomponent<widget>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.component<disabled<widget>>().remove();
|
||||
} else {
|
||||
c.component<disabled<widget>>().ensure();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"disabled", sol::property(
|
||||
[](const gcomponent<widget>& c) -> bool {
|
||||
return c.component<disabled<widget>>().exists();
|
||||
},
|
||||
[](gcomponent<widget>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.component<disabled<widget>>().ensure();
|
||||
} else {
|
||||
c.component<disabled<widget>>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"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){
|
||||
widgets::change_size(c, v);
|
||||
}),
|
||||
|
||||
"margin", sol::property(
|
||||
[](const gcomponent<widget>& c) -> v2f {
|
||||
return c->margin();
|
||||
},
|
||||
[](gcomponent<widget>& c, const v2f& 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);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <enduro2d/high/components/spine_player.hpp>
|
||||
#include <enduro2d/high/components/sprite_renderer.hpp>
|
||||
#include <enduro2d/high/components/touchable.hpp>
|
||||
#include <enduro2d/high/components/widget.hpp>
|
||||
|
||||
namespace e2d::bindings::high
|
||||
{
|
||||
@@ -54,7 +55,8 @@ namespace e2d::bindings::high
|
||||
"scene", sol::property([](gobject& go){ return component_wrapper<scene>{go}; }),
|
||||
"spine_player", sol::property([](gobject& go){ return component_wrapper<spine_player>{go}; }),
|
||||
"sprite_renderer", sol::property([](gobject& go){ return component_wrapper<sprite_renderer>{go}; }),
|
||||
"touchable", sol::property([](gobject& go){ return component_wrapper<touchable>{go}; })
|
||||
"touchable", sol::property([](gobject& go){ return component_wrapper<touchable>{go}; }),
|
||||
"widget", sol::property([](gobject& go){ return component_wrapper<widget>{go}; })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,24 @@ namespace e2d::bindings::high
|
||||
sol::no_constructor,
|
||||
|
||||
"instantiate", sol::overload(
|
||||
[](world& w) -> gobject {
|
||||
return w.instantiate();
|
||||
},
|
||||
[](world& w, const t2f& transform) -> gobject {
|
||||
return w.instantiate(transform);
|
||||
},
|
||||
[](world& w, const node_iptr& parent) -> gobject {
|
||||
return w.instantiate(parent);
|
||||
},
|
||||
[](world& w, const node_iptr& parent, const t2f& transform) -> gobject {
|
||||
return w.instantiate(parent, transform);
|
||||
},
|
||||
[](world& w, const prefab& prefab) -> gobject {
|
||||
return w.instantiate(prefab);
|
||||
},
|
||||
[](world& w, const prefab& prefab, const t2f& transform) -> gobject {
|
||||
return w.instantiate(prefab, transform);
|
||||
},
|
||||
[](world& w, const prefab& prefab, const node_iptr& parent) -> gobject {
|
||||
return w.instantiate(prefab, parent);
|
||||
},
|
||||
|
||||
@@ -185,25 +185,25 @@ namespace e2d
|
||||
const char* component_inspector<camera>::title = ICON_FA_VIDEO " camera";
|
||||
|
||||
void component_inspector<camera>::operator()(gcomponent<camera>& c) const {
|
||||
if ( bool input = c.owner().component<camera::input>().exists();
|
||||
if ( bool input = c.component<camera::input>().exists();
|
||||
ImGui::Checkbox("input", &input) )
|
||||
{
|
||||
if ( input ) {
|
||||
c.owner().component<camera::input>().ensure();
|
||||
c.component<camera::input>().ensure();
|
||||
} else {
|
||||
c.owner().component<camera::input>().remove();
|
||||
c.component<camera::input>().remove();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if ( bool gizmos = c.owner().component<camera::gizmos>().exists();
|
||||
if ( bool gizmos = c.component<camera::gizmos>().exists();
|
||||
ImGui::Checkbox("gizmos", &gizmos) )
|
||||
{
|
||||
if ( gizmos ) {
|
||||
c.owner().component<camera::gizmos>().ensure();
|
||||
c.component<camera::gizmos>().ensure();
|
||||
} else {
|
||||
c.owner().component<camera::gizmos>().remove();
|
||||
c.component<camera::gizmos>().remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace e2d
|
||||
const char* component_inspector<label>::title = ICON_FA_PARAGRAPH " label";
|
||||
|
||||
void component_inspector<label>::operator()(gcomponent<label>& c) const {
|
||||
if ( bool dirty = c.owner().component<label::dirty>().exists();
|
||||
if ( bool dirty = c.component<label::dirty>().exists();
|
||||
ImGui::Checkbox("dirty", &dirty) )
|
||||
{
|
||||
if ( dirty ) {
|
||||
@@ -337,20 +337,20 @@ namespace e2d::labels
|
||||
{
|
||||
gcomponent<label> mark_dirty(gcomponent<label> self) {
|
||||
if ( self ) {
|
||||
self.owner().component<label::dirty>().ensure();
|
||||
self.component<label::dirty>().ensure();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
gcomponent<label> unmark_dirty(gcomponent<label> self) {
|
||||
if ( self ) {
|
||||
self.owner().component<label::dirty>().remove();
|
||||
self.component<label::dirty>().remove();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
bool is_dirty(const const_gcomponent<label>& self) noexcept {
|
||||
return self.owner().component<label::dirty>().exists();
|
||||
return self.component<label::dirty>().exists();
|
||||
}
|
||||
|
||||
gcomponent<label> change_text(gcomponent<label> self, str value) {
|
||||
|
||||
@@ -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;
|
||||
@@ -158,7 +172,7 @@ namespace e2d
|
||||
const char* component_inspector<layout>::title = ICON_FA_BARS " layout";
|
||||
|
||||
void component_inspector<layout>::operator()(gcomponent<layout>& c) const {
|
||||
if ( bool dirty = c.owner().component<layout::dirty>().exists();
|
||||
if ( bool dirty = c.component<layout::dirty>().exists();
|
||||
ImGui::Checkbox("dirty", &dirty) )
|
||||
{
|
||||
if ( dirty ) {
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,34 +226,20 @@ namespace e2d::layouts
|
||||
{
|
||||
gcomponent<layout> mark_dirty(gcomponent<layout> self) {
|
||||
if ( self ) {
|
||||
self.owner().component<layout::dirty>().ensure();
|
||||
self.component<layout::dirty>().ensure();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
gcomponent<layout> unmark_dirty(gcomponent<layout> self) {
|
||||
if ( self ) {
|
||||
self.owner().component<layout::dirty>().remove();
|
||||
self.component<layout::dirty>().remove();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
bool is_dirty(const const_gcomponent<layout>& self) noexcept {
|
||||
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);
|
||||
return self.component<layout::dirty>().exists();
|
||||
}
|
||||
|
||||
gcomponent<layout> change_direction(gcomponent<layout> self, layout::directions value) {
|
||||
@@ -275,32 +249,43 @@ 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);
|
||||
}
|
||||
|
||||
gcomponent<layout> find_parent_layout(const_gcomponent<layout> self) noexcept {
|
||||
const_gcomponent<actor> self_actor = self.owner().component<actor>();
|
||||
const_gcomponent<actor> self_actor = self.component<actor>();
|
||||
return self_actor
|
||||
? nodes::find_component_from_parents<layout>(self_actor->node())
|
||||
: gcomponent<layout>();
|
||||
|
||||
207
sources/enduro2d/high/components/widget.cpp
Normal file
207
sources/enduro2d/high/components/widget.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#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({
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"size" : { "$ref": "#/common_definitions/v2" },
|
||||
"margin" : { "$ref": "#/common_definitions/v2" },
|
||||
"padding" : { "$ref": "#/common_definitions/v2" }
|
||||
}
|
||||
})json";
|
||||
|
||||
bool factory_loader<widget>::operator()(
|
||||
widget& component,
|
||||
const fill_context& ctx) const
|
||||
{
|
||||
if ( ctx.root.HasMember("size") ) {
|
||||
v2f size = component.size();
|
||||
if ( !json_utils::try_parse_value(ctx.root["size"], size) ) {
|
||||
the<debug>().error("WIDGET: Incorrect formatting of 'size' property");
|
||||
return false;
|
||||
}
|
||||
component.size(size);
|
||||
}
|
||||
|
||||
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.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;
|
||||
}
|
||||
|
||||
bool factory_loader<widget>::operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(dependencies, ctx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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.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) )
|
||||
{
|
||||
widgets::change_size(c, size);
|
||||
}
|
||||
|
||||
if ( v2f margin = c->margin();
|
||||
ImGui::DragFloat2("margin", margin.data(), 1.f) )
|
||||
{
|
||||
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.component<widget::dirty>().ensure();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
gcomponent<widget> unmark_dirty(gcomponent<widget> self) {
|
||||
if ( self ) {
|
||||
self.component<widget::dirty>().remove();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
bool is_dirty(const const_gcomponent<widget>& self) noexcept {
|
||||
return self.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.component<actor>();
|
||||
return self_actor
|
||||
? nodes::find_component_from_parents<layout>(self_actor->node())
|
||||
: gcomponent<layout>();
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,9 @@ namespace e2d
|
||||
}
|
||||
|
||||
node_iptr node::create(const t2f& transform) {
|
||||
node_iptr n = create();
|
||||
n->transform(transform);
|
||||
return n;
|
||||
node_iptr child = create();
|
||||
child->transform(transform);
|
||||
return child;
|
||||
}
|
||||
|
||||
node_iptr node::create(const node_iptr& parent) {
|
||||
@@ -35,9 +35,9 @@ namespace e2d
|
||||
}
|
||||
|
||||
node_iptr node::create(const node_iptr& parent, const t2f& transform) {
|
||||
node_iptr n = create(parent);
|
||||
n->transform(transform);
|
||||
return n;
|
||||
node_iptr child = create(parent);
|
||||
child->transform(transform);
|
||||
return child;
|
||||
}
|
||||
|
||||
node_iptr node::create(gobject owner) {
|
||||
@@ -45,9 +45,9 @@ namespace e2d
|
||||
}
|
||||
|
||||
node_iptr node::create(gobject owner, const t2f& transform) {
|
||||
node_iptr n = create(owner);
|
||||
n->transform(transform);
|
||||
return n;
|
||||
node_iptr child = create(std::move(owner));
|
||||
child->transform(transform);
|
||||
return child;
|
||||
}
|
||||
|
||||
node_iptr node::create(gobject owner, const node_iptr& parent) {
|
||||
@@ -59,9 +59,9 @@ namespace e2d
|
||||
}
|
||||
|
||||
node_iptr node::create(gobject owner, const node_iptr& parent, const t2f& transform) {
|
||||
node_iptr n = create(owner, parent);
|
||||
n->transform(transform);
|
||||
return n;
|
||||
node_iptr child = create(std::move(owner), parent);
|
||||
child->transform(transform);
|
||||
return child;
|
||||
}
|
||||
|
||||
void node::owner(gobject owner) noexcept {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <enduro2d/high/components/spine_player.hpp>
|
||||
#include <enduro2d/high/components/sprite_renderer.hpp>
|
||||
#include <enduro2d/high/components/touchable.hpp>
|
||||
#include <enduro2d/high/components/widget.hpp>
|
||||
|
||||
#include <enduro2d/high/systems/camera_system.hpp>
|
||||
#include <enduro2d/high/systems/flipbook_system.hpp>
|
||||
@@ -41,6 +42,7 @@
|
||||
#include <enduro2d/high/systems/script_system.hpp>
|
||||
#include <enduro2d/high/systems/spine_system.hpp>
|
||||
#include <enduro2d/high/systems/touch_system.hpp>
|
||||
#include <enduro2d/high/systems/widget_system.hpp>
|
||||
#include <enduro2d/high/systems/world_system.hpp>
|
||||
|
||||
namespace
|
||||
@@ -81,6 +83,8 @@ namespace
|
||||
.add_system<spine_system>())
|
||||
.feature<struct touch_feature>(ecs::feature()
|
||||
.add_system<touch_system>())
|
||||
.feature<struct widget_feature>(ecs::feature()
|
||||
.add_system<widget_system>())
|
||||
.feature<struct world_feature>(ecs::feature()
|
||||
.add_system<world_system>());
|
||||
return !application_ || application_->initialize();
|
||||
@@ -209,6 +213,8 @@ namespace e2d
|
||||
.register_component<sprite_renderer>("sprite_renderer")
|
||||
.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>()
|
||||
@@ -235,6 +241,8 @@ namespace e2d
|
||||
.register_component<sprite_renderer>("sprite_renderer")
|
||||
.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>();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace
|
||||
// parents
|
||||
//
|
||||
|
||||
static thread_local std::vector<const_gcomponent<touchable>> parents;
|
||||
static thread_local std::vector<gcomponent<touchable>> parents;
|
||||
E2D_DEFER([](){ parents.clear(); });
|
||||
|
||||
nodes::extract_components_from_parents<touchable>(
|
||||
@@ -102,7 +102,7 @@ namespace
|
||||
disabled<touchable>
|
||||
>()(iter->owner().raw_entity());
|
||||
if ( !parent_disabled ) {
|
||||
iter->owner().component<events<touchable_events::event>>().ensure().add(event);
|
||||
iter->component<events<touchable_events::event>>().ensure().add(event);
|
||||
if ( !(*iter)->bubbling() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
71
sources/enduro2d/high/systems/widget_system.cpp
Normal file
71
sources/enduro2d/high/systems/widget_system.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#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
|
||||
{
|
||||
//
|
||||
// widget_system::internal_state
|
||||
//
|
||||
|
||||
class widget_system::internal_state final : private noncopyable {
|
||||
public:
|
||||
internal_state() = default;
|
||||
~internal_state() noexcept = default;
|
||||
|
||||
void process_update(ecs::registry& owner) {
|
||||
update_dirty_widgets(owner);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// widget_system
|
||||
//
|
||||
|
||||
widget_system::widget_system()
|
||||
: state_(new internal_state()) {}
|
||||
widget_system::~widget_system() noexcept = default;
|
||||
|
||||
void widget_system::process(
|
||||
ecs::registry& owner,
|
||||
const ecs::after<systems::update_event>& trigger)
|
||||
{
|
||||
E2D_UNUSED(trigger);
|
||||
E2D_PROFILER_SCOPE("widget_system.process_update");
|
||||
state_->process_update(owner);
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ namespace
|
||||
|
||||
if ( inst_n ) {
|
||||
inst_n->remove_from_parent();
|
||||
while ( node_iptr child = inst_n->first_child() ) {
|
||||
while ( const node_iptr& child = inst_n->first_child() ) {
|
||||
delete_instance(child->owner());
|
||||
}
|
||||
}
|
||||
@@ -85,60 +85,49 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
gobject new_instance(world& world, const prefab& prefab) {
|
||||
gobject inst;
|
||||
ecs::entity ent = world.registry().create_entity(prefab.prototype());
|
||||
|
||||
try {
|
||||
inst = gobject{make_intrusive<gobject_state>(world, ent)};
|
||||
} catch (...) {
|
||||
gobject new_instance(world& world, const prefab& root_prefab) {
|
||||
ecs::entity ent = world.registry().create_entity(root_prefab.prototype());
|
||||
auto ent_defer = make_error_defer([&ent](){
|
||||
ent.destroy();
|
||||
throw;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
auto n = node::create(inst);
|
||||
gcomponent<actor> inst_a{inst};
|
||||
if ( inst_a && inst_a->node() ) {
|
||||
n->transform(inst_a->node()->transform());
|
||||
gobject root_i(make_intrusive<gobject_state>(world, ent));
|
||||
E2D_ERROR_DEFER([&root_i](){
|
||||
delete_instance(root_i);
|
||||
});
|
||||
|
||||
ent_defer.dismiss();
|
||||
|
||||
{
|
||||
gcomponent<actor> root_a{root_i};
|
||||
node_iptr new_root_node = node::create(root_i);
|
||||
if ( root_a && root_a->node() ) {
|
||||
new_root_node->transform(root_a->node()->transform());
|
||||
}
|
||||
inst_a.assign(std::move(n));
|
||||
} catch (...) {
|
||||
delete_instance(inst);
|
||||
throw;
|
||||
root_a.ensure().node(new_root_node);
|
||||
}
|
||||
|
||||
try {
|
||||
gcomponent<behaviour> inst_b{inst};
|
||||
if ( inst_b && inst_b->script() ) {
|
||||
const behaviours::fill_result r = behaviours::fill_meta_table(*inst_b);
|
||||
{
|
||||
gcomponent<behaviour> root_b{root_i};
|
||||
if ( root_b && root_b->script() ) {
|
||||
const behaviours::fill_result r = behaviours::fill_meta_table(*root_b);
|
||||
if ( r == behaviours::fill_result::failed ) {
|
||||
inst.component<disabled<behaviour>>().ensure();
|
||||
root_i.component<disabled<behaviour>>().ensure();
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
delete_instance(inst);
|
||||
throw;
|
||||
}
|
||||
|
||||
try {
|
||||
for ( const auto& child_prefab : prefab.children() ) {
|
||||
auto child = new_instance(world, child_prefab);
|
||||
try {
|
||||
gcomponent<actor> inst_a{inst};
|
||||
gcomponent<actor> child_a{child};
|
||||
inst_a->node()->add_child(child_a->node());
|
||||
} catch (...) {
|
||||
delete_instance(child);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
delete_instance(inst);
|
||||
throw;
|
||||
for ( const prefab& child_prefab : root_prefab.children() ) {
|
||||
gobject child_i = new_instance(world, child_prefab);
|
||||
E2D_ERROR_DEFER([&child_i](){
|
||||
delete_instance(child_i);
|
||||
});
|
||||
gcomponent<actor> root_a{root_i};
|
||||
gcomponent<actor> child_a{child_i};
|
||||
root_a->node()->add_child(child_a->node());
|
||||
}
|
||||
|
||||
return inst;
|
||||
return root_i;
|
||||
}
|
||||
|
||||
void shutdown_instance(gobject& inst) noexcept {
|
||||
@@ -188,57 +177,64 @@ namespace e2d
|
||||
}
|
||||
|
||||
gobject world::instantiate() {
|
||||
return instantiate(nullptr);
|
||||
return instantiate(prefab(), nullptr);
|
||||
}
|
||||
|
||||
gobject world::instantiate(const prefab& prefab) {
|
||||
return instantiate(prefab, nullptr);
|
||||
gobject world::instantiate(const t2f& transform) {
|
||||
return instantiate(prefab(), nullptr, transform);
|
||||
}
|
||||
|
||||
gobject world::instantiate(const node_iptr& parent) {
|
||||
return instantiate(prefab(), parent);
|
||||
}
|
||||
|
||||
gobject world::instantiate(const node_iptr& parent, const t2f& transform) {
|
||||
return instantiate(prefab(), parent, transform);
|
||||
}
|
||||
|
||||
gobject world::instantiate(const prefab& prefab) {
|
||||
return instantiate(prefab, nullptr);
|
||||
}
|
||||
|
||||
gobject world::instantiate(const prefab& prefab, const t2f& transform) {
|
||||
return instantiate(prefab, nullptr, transform);
|
||||
}
|
||||
|
||||
gobject world::instantiate(const prefab& prefab, const node_iptr& parent) {
|
||||
E2D_PROFILER_SCOPE("world.instantiate");
|
||||
|
||||
gobject inst = new_instance(*this, prefab);
|
||||
|
||||
if ( parent ) {
|
||||
parent->add_child(inst.component<actor>()->node());
|
||||
}
|
||||
|
||||
try {
|
||||
start_instance(inst);
|
||||
} catch (...) {
|
||||
E2D_ERROR_DEFER([inst](){
|
||||
delete_instance(inst);
|
||||
throw;
|
||||
});
|
||||
|
||||
if ( const node_iptr& node = inst.component<actor>()->node() ) {
|
||||
if ( parent ) {
|
||||
parent->add_child(node);
|
||||
}
|
||||
}
|
||||
|
||||
start_instance(inst);
|
||||
return inst;
|
||||
}
|
||||
|
||||
gobject world::instantiate(const node_iptr& parent, const t2f& transform) {
|
||||
return instantiate(prefab(), parent, transform);
|
||||
}
|
||||
|
||||
gobject world::instantiate(const prefab& prefab, const node_iptr& parent, const t2f& transform) {
|
||||
E2D_PROFILER_SCOPE("world.instantiate");
|
||||
|
||||
gobject inst = new_instance(*this, prefab);
|
||||
inst.component<actor>()->node()->transform(transform);
|
||||
|
||||
if ( parent ) {
|
||||
parent->add_child(inst.component<actor>()->node());
|
||||
}
|
||||
|
||||
try {
|
||||
start_instance(inst);
|
||||
} catch (...) {
|
||||
E2D_ERROR_DEFER([inst](){
|
||||
delete_instance(inst);
|
||||
throw;
|
||||
});
|
||||
|
||||
if ( const node_iptr& node = inst.component<actor>()->node() ) {
|
||||
node->transform(transform);
|
||||
|
||||
if ( parent ) {
|
||||
parent->add_child(node);
|
||||
}
|
||||
}
|
||||
|
||||
start_instance(inst);
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user