diff --git a/headers/enduro2d/high/_all.hpp b/headers/enduro2d/high/_all.hpp index e5cb7372..534af63b 100644 --- a/headers/enduro2d/high/_all.hpp +++ b/headers/enduro2d/high/_all.hpp @@ -45,6 +45,7 @@ #include "components/spine_player.hpp" #include "components/sprite_renderer.hpp" #include "components/touchable.hpp" +#include "components/widget.hpp" #include "systems/camera_system.hpp" #include "systems/flipbook_system.hpp" diff --git a/headers/enduro2d/high/_high.hpp b/headers/enduro2d/high/_high.hpp index 593b6f48..417213fb 100644 --- a/headers/enduro2d/high/_high.hpp +++ b/headers/enduro2d/high/_high.hpp @@ -65,6 +65,7 @@ namespace e2d class spine_player; class sprite_renderer; class touchable; + class widget; class camera_system; class flipbook_system; diff --git a/headers/enduro2d/high/components/widget.hpp b/headers/enduro2d/high/components/widget.hpp new file mode 100644 index 00000000..02f43a12 --- /dev/null +++ b/headers/enduro2d/high/components/widget.hpp @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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: + widget() = default; + + widget& size(const v2f& value) noexcept; + [[nodiscard]] const v2f& size() const noexcept; + + widget& pivot(const v2f& value) noexcept; + [[nodiscard]] const v2f& pivot() const noexcept; + private: + v2f size_ = v2f::zero(); + v2f pivot_ = v2f::unit() * 0.5f; + }; +} + +namespace e2d +{ + template <> + class factory_loader 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; + }; +} + +namespace e2d +{ + template <> + class component_inspector final : component_inspector<> { + public: + static const char* title; + + void operator()(gcomponent& c) 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::pivot(const v2f& value) noexcept { + pivot_ = value; + return *this; + } + + inline const v2f& widget::pivot() const noexcept { + return pivot_; + } +} diff --git a/headers/enduro2d/high/systems/widget_system.hpp b/headers/enduro2d/high/systems/widget_system.hpp new file mode 100644 index 00000000..8abcaa82 --- /dev/null +++ b/headers/enduro2d/high/systems/widget_system.hpp @@ -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> { + public: + widget_system(); + ~widget_system() noexcept final; + + void process( + ecs::registry& owner, + const ecs::after& trigger) override; + private: + class internal_state; + std::unique_ptr state_; + }; +} diff --git a/samples/bin/library/scripts/emmy/components/widget.lua b/samples/bin/library/scripts/emmy/components/widget.lua new file mode 100644 index 00000000..43ee40ef --- /dev/null +++ b/samples/bin/library/scripts/emmy/components/widget.lua @@ -0,0 +1,25 @@ +---@class widget +local widget = { + ---@type boolean + enabled = true, + + ---@type boolean + disabled = false, + + ---@type v2f + size = v2f.zero(), + + ---@type v2f + pivot = v2f.unit() * 0.5 +} + +---@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 diff --git a/samples/bin/library/scripts/emmy/high/gobject.lua b/samples/bin/library/scripts/emmy/high/gobject.lua index bfddd716..9b21314d 100644 --- a/samples/bin/library/scripts/emmy/high/gobject.lua +++ b/samples/bin/library/scripts/emmy/high/gobject.lua @@ -52,7 +52,10 @@ local gobject = { sprite_renderer = nil, ---@type touchable - touchable = nil + touchable = nil, + + ---@type widget + widget = nil } ---@param self gobject diff --git a/sources/enduro2d/high/bindings/high_binds/_high_binds.hpp b/sources/enduro2d/high/bindings/high_binds/_high_binds.hpp index e4dfeb30..73bb1638 100644 --- a/sources/enduro2d/high/bindings/high_binds/_high_binds.hpp +++ b/sources/enduro2d/high/bindings/high_binds/_high_binds.hpp @@ -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); } } diff --git a/sources/enduro2d/high/bindings/high_binds/components/widget_binds.cpp b/sources/enduro2d/high/bindings/high_binds/components/widget_binds.cpp new file mode 100644 index 00000000..ec9b755f --- /dev/null +++ b/sources/enduro2d/high/bindings/high_binds/components/widget_binds.cpp @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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 +#include +#include + +namespace e2d::bindings::high +{ + void bind_widget(sol::state& l) { + l.new_usertype>("widget", + sol::no_constructor, + + "enable", [](gcomponent& c){ + c.owner().component>().remove(); + }, + + "disable", [](gcomponent& c){ + c.owner().component>().ensure(); + }, + + "enabled", sol::property( + [](const gcomponent& c) -> bool { + return !c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().remove(); + } else { + c.owner().component>().ensure(); + } + } + ), + + "disabled", sol::property( + [](const gcomponent& c) -> bool { + return c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().ensure(); + } else { + c.owner().component>().remove(); + } + } + ), + + "size", sol::property( + [](const gcomponent& c) -> v2f { + return c->size(); + }, + [](gcomponent& c, const v2f& v){ + c->size(v); + }), + + "pivot", sol::property( + [](const gcomponent& c) -> v2f { + return c->pivot(); + }, + [](gcomponent& c, const v2f& v){ + c->pivot(v); + }) + ); + } +} diff --git a/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp b/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp index 3d6b7346..9335afc7 100644 --- a/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp +++ b/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace e2d::bindings::high { @@ -54,7 +55,8 @@ namespace e2d::bindings::high "scene", sol::property([](gobject& go){ return component_wrapper{go}; }), "spine_player", sol::property([](gobject& go){ return component_wrapper{go}; }), "sprite_renderer", sol::property([](gobject& go){ return component_wrapper{go}; }), - "touchable", sol::property([](gobject& go){ return component_wrapper{go}; }) + "touchable", sol::property([](gobject& go){ return component_wrapper{go}; }), + "widget", sol::property([](gobject& go){ return component_wrapper{go}; }) ); } } diff --git a/sources/enduro2d/high/components/widget.cpp b/sources/enduro2d/high/components/widget.cpp new file mode 100644 index 00000000..cb83b56b --- /dev/null +++ b/sources/enduro2d/high/components/widget.cpp @@ -0,0 +1,72 @@ +/******************************************************************************* + * 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 + +namespace e2d +{ + const char* factory_loader::schema_source = R"json({ + "type" : "object", + "required" : [], + "additionalProperties" : false, + "properties" : { + "size" : { "$ref": "#/common_definitions/v2" }, + "pivot" : { "$ref": "#/common_definitions/v2" } + } + })json"; + + bool factory_loader::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().error("WIDGET: Incorrect formatting of 'size' property"); + return false; + } + component.size(size); + } + + if ( ctx.root.HasMember("pivot") ) { + v2f pivot = component.pivot(); + if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) { + the().error("WIDGET: Incorrect formatting of 'pivot' property"); + return false; + } + component.pivot(pivot); + } + + return true; + } + + bool factory_loader::operator()( + asset_dependencies& dependencies, + const collect_context& ctx) const + { + E2D_UNUSED(dependencies, ctx); + return true; + } +} + +namespace e2d +{ + const char* component_inspector::title = ICON_FA_VECTOR_SQUARE " widget"; + + void component_inspector::operator()(gcomponent& c) const { + if ( v2f size = c->size(); + ImGui::DragFloat2("size", size.data(), 1.f) ) + { + c->size(size); + } + + if ( v2f pivot = c->pivot(); + ImGui::DragFloat2("pivot", pivot.data(), 0.01f) ) + { + c->pivot(pivot); + } + } +} diff --git a/sources/enduro2d/high/starter.cpp b/sources/enduro2d/high/starter.cpp index 67fae25f..6133af8a 100644 --- a/sources/enduro2d/high/starter.cpp +++ b/sources/enduro2d/high/starter.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include namespace @@ -81,6 +83,8 @@ namespace .add_system()) .feature(ecs::feature() .add_system()) + .feature(ecs::feature() + .add_system()) .feature(ecs::feature() .add_system()); return !application_ || application_->initialize(); @@ -209,6 +213,7 @@ namespace e2d .register_component("sprite_renderer") .register_component("touchable") .register_component>("touchable.events") + .register_component("widget") ; safe_module_initialize() @@ -235,6 +240,7 @@ namespace e2d .register_component("sprite_renderer") .register_component("touchable") //.register_component>("touchable.events") + .register_component("widget") ; safe_module_initialize(); diff --git a/sources/enduro2d/high/systems/widget_system.cpp b/sources/enduro2d/high/systems/widget_system.cpp new file mode 100644 index 00000000..a57255cf --- /dev/null +++ b/sources/enduro2d/high/systems/widget_system.cpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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 + +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) { + E2D_UNUSED(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& trigger) + { + E2D_UNUSED(trigger); + E2D_PROFILER_SCOPE("widget_system.process_update"); + state_->process_update(owner); + } +}