mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
basic touchable event classes
This commit is contained in:
@@ -8,12 +8,20 @@
|
||||
|
||||
#include "_components.hpp"
|
||||
|
||||
namespace e2d::touchable_events
|
||||
{
|
||||
class input_evt;
|
||||
class mouse_evt;
|
||||
class touch_evt;
|
||||
|
||||
using event = std::variant<std::monostate,
|
||||
mouse_evt,
|
||||
touch_evt>;
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class touchable final {
|
||||
public:
|
||||
class touched final {};
|
||||
class under_mouse final {};
|
||||
public:
|
||||
touchable() = default;
|
||||
|
||||
@@ -23,12 +31,12 @@ namespace e2d
|
||||
[[nodiscard]] bool bubbling() const noexcept;
|
||||
[[nodiscard]] bool capturing() const noexcept;
|
||||
private:
|
||||
enum flag_masks : u32 {
|
||||
enum flag_masks : u8 {
|
||||
fm_bubbling = 1u << 0,
|
||||
fm_capturing = 1u << 1,
|
||||
};
|
||||
private:
|
||||
u32 flags_{
|
||||
std::underlying_type_t<flag_masks> flags_{
|
||||
fm_bubbling |
|
||||
fm_capturing};
|
||||
};
|
||||
@@ -51,26 +59,12 @@ namespace e2d
|
||||
};
|
||||
|
||||
template <>
|
||||
class factory_loader<touchable::touched> final : factory_loader<> {
|
||||
class factory_loader<events<touchable_events::event>> final : factory_loader<> {
|
||||
public:
|
||||
static const char* schema_source;
|
||||
|
||||
bool operator()(
|
||||
touchable::touched& component,
|
||||
const fill_context& ctx) const;
|
||||
|
||||
bool operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
class factory_loader<touchable::under_mouse> final : factory_loader<> {
|
||||
public:
|
||||
static const char* schema_source;
|
||||
|
||||
bool operator()(
|
||||
touchable::under_mouse& component,
|
||||
events<touchable_events::event>& component,
|
||||
const fill_context& ctx) const;
|
||||
|
||||
bool operator()(
|
||||
@@ -90,6 +84,82 @@ namespace e2d
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d::touchable_events
|
||||
{
|
||||
class input_evt {
|
||||
public:
|
||||
input_evt(gobject target, bool bubbling, bool capturing)
|
||||
: target_(target)
|
||||
, bubbling_(bubbling)
|
||||
, capturing_(capturing) {}
|
||||
|
||||
[[nodiscard]] gobject target() const noexcept {
|
||||
return target_;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool bubbling() const noexcept {
|
||||
return bubbling_;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool capturing() const noexcept {
|
||||
return capturing_;
|
||||
}
|
||||
private:
|
||||
gobject target_;
|
||||
bool bubbling_ = true;
|
||||
bool capturing_ = true;
|
||||
};
|
||||
|
||||
class mouse_evt final : public input_evt {
|
||||
public:
|
||||
ENUM_HPP_CLASS_DECL(types, u8,
|
||||
(pressed)
|
||||
(released))
|
||||
public:
|
||||
mouse_evt(gobject target, types type, mouse_button button)
|
||||
: input_evt(target, true, true)
|
||||
, type_(type)
|
||||
, button_(button) {}
|
||||
|
||||
[[nodiscard]] types type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
[[nodiscard]] mouse_button button() const noexcept {
|
||||
return button_;
|
||||
}
|
||||
private:
|
||||
types type_ = types::pressed;
|
||||
mouse_button button_ = mouse_button::left;
|
||||
};
|
||||
|
||||
class touch_evt final : public input_evt {
|
||||
public:
|
||||
ENUM_HPP_CLASS_DECL(types, u8,
|
||||
(pressed)
|
||||
(released))
|
||||
public:
|
||||
touch_evt(gobject target, types type, u32 finger)
|
||||
: input_evt(target, true, true)
|
||||
, type_(type)
|
||||
, finger_(finger) {}
|
||||
|
||||
[[nodiscard]] types type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 finger() const noexcept {
|
||||
return finger_;
|
||||
}
|
||||
private:
|
||||
types type_ = types::pressed;
|
||||
u32 finger_ = 0u;
|
||||
};
|
||||
}
|
||||
|
||||
ENUM_HPP_REGISTER_TRAITS(e2d::touchable_events::mouse_evt::types)
|
||||
ENUM_HPP_REGISTER_TRAITS(e2d::touchable_events::touch_evt::types)
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
inline touchable& touchable::bubbling(bool value) noexcept {
|
||||
|
||||
@@ -6,12 +6,6 @@ local touchable = {
|
||||
---@type boolean
|
||||
disabled = false,
|
||||
|
||||
---@type boolean
|
||||
touched = false,
|
||||
|
||||
---@type boolean
|
||||
under_mouse = false,
|
||||
|
||||
---@type boolean
|
||||
bubbling = true,
|
||||
|
||||
@@ -27,5 +21,61 @@ function touchable.enable(self) end
|
||||
---@param self touchable
|
||||
function touchable.disable(self) end
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
--
|
||||
-- events
|
||||
--
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
--
|
||||
-- input_evt
|
||||
--
|
||||
|
||||
---@class touchable_input_evt
|
||||
touchable.input_evt = {
|
||||
---@type gobject
|
||||
target = nil,
|
||||
|
||||
---@type boolean
|
||||
bubbling = true,
|
||||
|
||||
---@type boolean
|
||||
capturing = true
|
||||
}
|
||||
|
||||
--
|
||||
-- mouse_evt
|
||||
--
|
||||
|
||||
---@class touchable_mouse_evt : touchable_input_evt
|
||||
touchable.mouse_evt = {
|
||||
---@type string
|
||||
type = "pressed",
|
||||
|
||||
---@type string
|
||||
button = "left"
|
||||
}
|
||||
|
||||
--
|
||||
-- touch_evt
|
||||
--
|
||||
|
||||
---@class touchable_touch_evt : touchable_input_evt
|
||||
touchable.touch_evt = {
|
||||
---@type string
|
||||
type = "pressed",
|
||||
|
||||
---@type integer
|
||||
finger = 0
|
||||
}
|
||||
|
||||
---@alias touchable_event touchable_mouse_evt | touchable_touch_evt
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
--
|
||||
-- globals
|
||||
--
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
---@type touchable
|
||||
_G.touchable = _G.touchable or touchable
|
||||
|
||||
@@ -50,32 +50,6 @@ namespace e2d::bindings::high
|
||||
}
|
||||
),
|
||||
|
||||
"touched", sol::property(
|
||||
[](const gcomponent<touchable>& c) -> bool {
|
||||
return c.owner().component<touchable::touched>().exists();
|
||||
},
|
||||
[](gcomponent<touchable>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<touchable::touched>().ensure();
|
||||
} else {
|
||||
c.owner().component<touchable::touched>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"under_mouse", sol::property(
|
||||
[](const gcomponent<touchable>& c) -> bool {
|
||||
return c.owner().component<touchable::under_mouse>().exists();
|
||||
},
|
||||
[](gcomponent<touchable>& c, bool yesno){
|
||||
if ( yesno ) {
|
||||
c.owner().component<touchable::under_mouse>().ensure();
|
||||
} else {
|
||||
c.owner().component<touchable::under_mouse>().remove();
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
"bubbling", sol::property(
|
||||
[](const gcomponent<touchable>& c) -> bool {
|
||||
return c->bubbling();
|
||||
@@ -92,5 +66,61 @@ namespace e2d::bindings::high
|
||||
c->capturing(v);
|
||||
})
|
||||
);
|
||||
|
||||
//
|
||||
// events
|
||||
//
|
||||
|
||||
l["touchable"].get_or_create<sol::table>()
|
||||
.new_usertype<touchable_events::input_evt>("input_evt",
|
||||
sol::no_constructor,
|
||||
|
||||
"target", sol::property(
|
||||
[](const touchable_events::input_evt& c) -> gobject {
|
||||
return c.target();
|
||||
}),
|
||||
|
||||
"bubbling", sol::property(
|
||||
[](const touchable_events::input_evt& c) -> bool {
|
||||
return c.bubbling();
|
||||
}),
|
||||
|
||||
"capturing", sol::property(
|
||||
[](const touchable_events::input_evt& c) -> bool {
|
||||
return c.capturing();
|
||||
})
|
||||
);
|
||||
|
||||
l["touchable"].get_or_create<sol::table>()
|
||||
.new_usertype<touchable_events::mouse_evt>("mouse_evt",
|
||||
sol::no_constructor,
|
||||
sol::base_classes, sol::bases<touchable_events::input_evt>(),
|
||||
|
||||
"type", sol::property(
|
||||
[](const touchable_events::mouse_evt& c) -> str {
|
||||
return str(enum_hpp::to_string_or_throw(c.type()));
|
||||
}),
|
||||
|
||||
"button", sol::property(
|
||||
[](const touchable_events::mouse_evt& c) -> str {
|
||||
return str(enum_hpp::to_string_or_throw(c.button()));
|
||||
})
|
||||
);
|
||||
|
||||
l["touchable"].get_or_create<sol::table>()
|
||||
.new_usertype<touchable_events::touch_evt>("touch_evt",
|
||||
sol::no_constructor,
|
||||
sol::base_classes, sol::bases<touchable_events::input_evt>(),
|
||||
|
||||
"type", sol::property(
|
||||
[](const touchable_events::touch_evt& c) -> str {
|
||||
return str(enum_hpp::to_string_or_throw(c.type()));
|
||||
}),
|
||||
|
||||
"finger", sol::property(
|
||||
[](const touchable_events::touch_evt& c) -> u32 {
|
||||
return c.finger();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,7 +698,7 @@ namespace e2d
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"commands" : { "$ref": "#/definitions/events" }
|
||||
"events" : { "$ref": "#/definitions/events" }
|
||||
},
|
||||
"definitions" : {
|
||||
"events" : {
|
||||
|
||||
@@ -54,48 +54,22 @@ namespace e2d
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
const char* factory_loader<touchable::touched>::schema_source = R"json({
|
||||
const char* factory_loader<events<touchable_events::event>>::schema_source = R"json({
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {}
|
||||
})json";
|
||||
|
||||
bool factory_loader<touchable::touched>::operator()(
|
||||
touchable::touched& component,
|
||||
bool factory_loader<events<touchable_events::event>>::operator()(
|
||||
events<touchable_events::event>& component,
|
||||
const fill_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(component, ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool factory_loader<touchable::touched>::operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(dependencies, ctx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
const char* factory_loader<touchable::under_mouse>::schema_source = R"json({
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {}
|
||||
})json";
|
||||
|
||||
bool factory_loader<touchable::under_mouse>::operator()(
|
||||
touchable::under_mouse& component,
|
||||
const fill_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(component, ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool factory_loader<touchable::under_mouse>::operator()(
|
||||
bool factory_loader<events<touchable_events::event>>::operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const
|
||||
{
|
||||
@@ -109,28 +83,6 @@ namespace e2d
|
||||
const char* component_inspector<touchable>::title = ICON_FA_FINGERPRINT " touchable";
|
||||
|
||||
void component_inspector<touchable>::operator()(gcomponent<touchable>& c) const {
|
||||
if ( bool touched = c.owner().component<touchable::touched>().exists();
|
||||
ImGui::Checkbox("touched", &touched) )
|
||||
{
|
||||
if ( touched ) {
|
||||
c.owner().component<touchable::touched>().ensure();
|
||||
} else {
|
||||
c.owner().component<touchable::touched>().remove();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if ( bool under_mouse = c.owner().component<touchable::under_mouse>().exists();
|
||||
ImGui::Checkbox("under_mouse", &under_mouse) )
|
||||
{
|
||||
if ( under_mouse ) {
|
||||
c.owner().component<touchable::under_mouse>().ensure();
|
||||
} else {
|
||||
c.owner().component<touchable::under_mouse>().remove();
|
||||
}
|
||||
}
|
||||
|
||||
if ( bool bubbling = c->bubbling();
|
||||
ImGui::Checkbox("bubbling", &bubbling) )
|
||||
{
|
||||
|
||||
@@ -261,8 +261,7 @@ namespace e2d
|
||||
.register_component<commands<spine_player_commands::command>>("spine_player.commands")
|
||||
.register_component<sprite_renderer>("sprite_renderer")
|
||||
.register_component<touchable>("touchable")
|
||||
.register_component<touchable::touched>("touchable.touched")
|
||||
.register_component<touchable::under_mouse>("touchable.under_mouse")
|
||||
.register_component<events<touchable_events::event>>("touchable.events")
|
||||
;
|
||||
|
||||
safe_module_initialize<inspector>()
|
||||
@@ -287,8 +286,7 @@ namespace e2d
|
||||
//.register_component<commands<spine_player_commands::command>>("spine_player.commands")
|
||||
.register_component<sprite_renderer>("sprite_renderer")
|
||||
.register_component<touchable>("touchable")
|
||||
//.register_component<touchable::touched>("touchable.touched")
|
||||
//.register_component<touchable::under_mouse>("touchable.under_mouse")
|
||||
//.register_component<events<touchable_events::event>>("touchable.events")
|
||||
;
|
||||
|
||||
safe_module_initialize<luasol>();
|
||||
|
||||
@@ -31,10 +31,8 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
const camera& cam = cam_e.get_component<camera>();
|
||||
if ( cam.target() ) {
|
||||
return false;
|
||||
}
|
||||
const camera& cam =
|
||||
cam_e.get_component<camera>();
|
||||
|
||||
camera_vp_ =
|
||||
cam.view() *
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <enduro2d/high/components/disabled.hpp>
|
||||
#include <enduro2d/high/components/events.hpp>
|
||||
#include <enduro2d/high/components/spine_player.hpp>
|
||||
#include <enduro2d/high/components/touchable.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -77,6 +78,32 @@ namespace
|
||||
}
|
||||
}, !ecs::exists<disabled<behaviour>>());
|
||||
}
|
||||
|
||||
void process_touchable_events(ecs::registry& owner) {
|
||||
systems::for_extracted_components<events<touchable_events::event>, behaviour, actor>(owner,
|
||||
[](ecs::entity e, const events<touchable_events::event>& es, behaviour& b, actor& a){
|
||||
if ( !a.node() || !a.node()->owner() ) {
|
||||
return;
|
||||
}
|
||||
for ( const touchable_events::event& evt : es.get() ) {
|
||||
behaviours::call_result r = behaviours::call_result::success;
|
||||
std::visit(utils::overloaded {
|
||||
[](std::monostate){},
|
||||
[&b,&a,&r](const touchable_events::mouse_evt& e){
|
||||
r = behaviours::call_meta_method(
|
||||
b, "on_event", a.node()->owner(), "touchable.mouse_evt", e);
|
||||
},
|
||||
[&b,&a,&r](const touchable_events::touch_evt& e){
|
||||
r = behaviours::call_meta_method(
|
||||
b, "on_event", a.node()->owner(), "touchable.touch_evt", e);
|
||||
}
|
||||
}, evt);
|
||||
if ( r == behaviours::call_result::failed ) {
|
||||
e.assign_component<disabled<behaviour>>();
|
||||
}
|
||||
}
|
||||
}, !ecs::exists<disabled<behaviour>>());
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
@@ -111,6 +138,7 @@ namespace e2d
|
||||
|
||||
void process_events(ecs::registry& owner) {
|
||||
process_spine_player_events(owner);
|
||||
process_touchable_events(owner);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user