From 09bc22de656d7f8d45ae33d9f8e37a61a1abd34a Mon Sep 17 00:00:00 2001 From: Nomango Date: Wed, 13 Nov 2019 11:22:21 +0800 Subject: [PATCH] refactoring Event distribution mechanism --- .../kiwano-physics/kiwano-physics.vcxproj | 4 +- .../kiwano-physics.vcxproj.filters | 4 +- projects/kiwano/kiwano.vcxproj | 3 +- projects/kiwano/kiwano.vcxproj.filters | 9 +- src/kiwano-audio/AudioEngine.h | 1 + src/kiwano-audio/Sound.h | 2 +- src/kiwano-physics/ContactEvent.cpp | 65 +++++ src/kiwano-physics/ContactEvent.h | 62 ++++ src/kiwano-physics/ContactListener.cpp | 158 ---------- src/kiwano-physics/ContactListener.h | 141 --------- src/kiwano-physics/World.cpp | 17 +- src/kiwano-physics/World.h | 2 - src/kiwano-physics/kiwano-physics.h | 2 +- src/kiwano/2d/Actor.cpp | 47 +-- src/kiwano/2d/Actor.h | 2 +- src/kiwano/2d/DebugActor.cpp | 4 +- src/kiwano/2d/Layer.cpp | 73 +++-- src/kiwano/2d/Layer.h | 8 +- src/kiwano/base/Component.h | 8 +- src/kiwano/base/Director.cpp | 2 +- src/kiwano/base/Director.h | 2 +- src/kiwano/base/Event.cpp | 134 +++++++++ src/kiwano/base/Event.h | 272 ++++++++++++++++++ src/kiwano/base/Event.hpp | 181 ------------ src/kiwano/base/EventDispatcher.cpp | 20 +- src/kiwano/base/EventDispatcher.h | 18 +- src/kiwano/base/EventListener.cpp | 14 +- src/kiwano/base/EventListener.h | 66 ++++- src/kiwano/base/Library.h | 3 +- src/kiwano/kiwano.h | 2 +- src/kiwano/platform/Application.cpp | 115 +++++--- src/kiwano/platform/Application.h | 4 +- src/kiwano/ui/Button.cpp | 23 +- src/kiwano/ui/Button.h | 2 +- 34 files changed, 831 insertions(+), 639 deletions(-) create mode 100644 src/kiwano-physics/ContactEvent.cpp create mode 100644 src/kiwano-physics/ContactEvent.h delete mode 100644 src/kiwano-physics/ContactListener.cpp delete mode 100644 src/kiwano-physics/ContactListener.h create mode 100644 src/kiwano/base/Event.cpp create mode 100644 src/kiwano/base/Event.h delete mode 100644 src/kiwano/base/Event.hpp diff --git a/projects/kiwano-physics/kiwano-physics.vcxproj b/projects/kiwano-physics/kiwano-physics.vcxproj index dac0da27..cc69700c 100644 --- a/projects/kiwano-physics/kiwano-physics.vcxproj +++ b/projects/kiwano-physics/kiwano-physics.vcxproj @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/projects/kiwano-physics/kiwano-physics.vcxproj.filters b/projects/kiwano-physics/kiwano-physics.vcxproj.filters index 2a808fb3..a927a9b3 100644 --- a/projects/kiwano-physics/kiwano-physics.vcxproj.filters +++ b/projects/kiwano-physics/kiwano-physics.vcxproj.filters @@ -9,7 +9,7 @@ - + @@ -18,6 +18,6 @@ - + \ No newline at end of file diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index 6fec72a7..2782d80d 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -12,6 +12,7 @@ + @@ -43,7 +44,6 @@ - @@ -116,6 +116,7 @@ + diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index 9b71bc4f..9f60577e 100644 --- a/projects/kiwano/kiwano.vcxproj.filters +++ b/projects/kiwano/kiwano.vcxproj.filters @@ -66,9 +66,6 @@ base - - base - base @@ -303,6 +300,9 @@ base + + base + @@ -482,5 +482,8 @@ base + + base + \ No newline at end of file diff --git a/src/kiwano-audio/AudioEngine.h b/src/kiwano-audio/AudioEngine.h index ecc4548b..4bbd313d 100644 --- a/src/kiwano-audio/AudioEngine.h +++ b/src/kiwano-audio/AudioEngine.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace kiwano { diff --git a/src/kiwano-audio/Sound.h b/src/kiwano-audio/Sound.h index 42ca5650..5cc66646 100644 --- a/src/kiwano-audio/Sound.h +++ b/src/kiwano-audio/Sound.h @@ -22,8 +22,8 @@ #include #include #include -#include #include +#include namespace kiwano { diff --git a/src/kiwano-physics/ContactEvent.cpp b/src/kiwano-physics/ContactEvent.cpp new file mode 100644 index 00000000..108134a7 --- /dev/null +++ b/src/kiwano-physics/ContactEvent.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2018-2019 Kiwano - Nomango +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include + +namespace kiwano +{ + namespace event + { + EventType event::ContactBegin = EventType(L"ContactBegin"); + EventType event::ContactEnd = EventType(L"ContactEnd"); + } + + namespace physics + { + + ContactBeginEvent::ContactBeginEvent() + : Event(event::ContactBegin) + , body_a(nullptr) + , body_b(nullptr) + { + } + + ContactBeginEvent::ContactBeginEvent(Contact const& contact) + : ContactBeginEvent() + { + this->contact = contact; + body_a = this->contact.GetFixtureA().GetBody(); + body_b = this->contact.GetFixtureB().GetBody(); + } + + ContactEndEvent::ContactEndEvent() + : Event(event::ContactEnd) + , body_a(nullptr) + , body_b(nullptr) + { + } + + ContactEndEvent::ContactEndEvent(Contact const& contact) + : ContactEndEvent() + { + this->contact = contact; + body_a = this->contact.GetFixtureA().GetBody(); + body_b = this->contact.GetFixtureB().GetBody(); + } + +} +} diff --git a/src/kiwano-physics/ContactEvent.h b/src/kiwano-physics/ContactEvent.h new file mode 100644 index 00000000..ba2488f4 --- /dev/null +++ b/src/kiwano-physics/ContactEvent.h @@ -0,0 +1,62 @@ +// Copyright (c) 2018-2019 Kiwano - Nomango +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +#include +#include + +namespace kiwano +{ + namespace physics + { + // 接触开始事件 + class KGE_API ContactBeginEvent + : public Event + { + public: + Contact contact; + Body* body_a; + Body* body_b; + + ContactBeginEvent(); + ContactBeginEvent(Contact const& contact); + }; + + // 接触结束事件 + class KGE_API ContactEndEvent + : public Event + { + public: + Contact contact; + Body* body_a; + Body* body_b; + + ContactEndEvent(); + ContactEndEvent(Contact const& contact); + }; + + } + + namespace event + { + extern EventType ContactBegin; // 接触开始 + extern EventType ContactEnd; // 接触结束 + } +} diff --git a/src/kiwano-physics/ContactListener.cpp b/src/kiwano-physics/ContactListener.cpp deleted file mode 100644 index 12ec7da6..00000000 --- a/src/kiwano-physics/ContactListener.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2018-2019 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include -#include -#include - -namespace kiwano -{ - namespace physics - { - ContactListener::ContactListener() - : running_(true) - { - } - - ContactListener::~ContactListener() - { - } - - - ContactCallbackListener::ContactCallbackListener() - { - } - - ContactCallbackListener::~ContactCallbackListener() - { - } - - - ContactListener* ContactDispatcher::AddContactListener(ContactListenerPtr listener) - { - return AddContactListener(listener.get()); - } - - ContactListener* ContactDispatcher::AddContactListener(ContactListener* listener) - { - KGE_ASSERT(listener && "AddListener failed, NULL pointer exception"); - - if (listener) - { - listeners_.push_back(listener); - } - return listener; - } - - void ContactDispatcher::StartContactListeners(String const& listener_name) - { - for (auto listener : listeners_) - { - if (listener->IsName(listener_name)) - { - listener->Start(); - } - } - } - - void ContactDispatcher::StopContactListeners(String const& listener_name) - { - for (auto listener : listeners_) - { - if (listener->IsName(listener_name)) - { - listener->Stop(); - } - } - } - - void ContactDispatcher::RemoveContactListeners(String const& listener_name) - { - ContactListenerPtr next; - for (auto listener = listeners_.first_item(); listener; listener = next) - { - next = listener->next_item(); - - if (listener->IsName(listener_name)) - { - listeners_.remove(listener); - } - } - } - - void ContactDispatcher::StartAllContactListeners() - { - for (auto listener : listeners_) - { - listener->Start(); - } - } - - void ContactDispatcher::StopAllContactListeners() - { - for (auto listener : listeners_) - { - listener->Stop(); - } - } - - void ContactDispatcher::RemoveAllContactListeners() - { - listeners_.clear(); - } - - void ContactDispatcher::OnContactBegin(b2Contact* b2contact) - { - if (listeners_.empty()) - return; - - Contact contact(b2contact); - ContactListenerPtr next; - for (auto listener = listeners_.first_item(); listener; listener = next) - { - next = listener->next_item(); - - if (listener->IsRunning()) - { - listener->OnContactBegin(contact); - } - } - } - - void ContactDispatcher::OnContactEnd(b2Contact* b2contact) - { - if (listeners_.empty()) - return; - - Contact contact(b2contact); - ContactListenerPtr next; - for (auto listener = listeners_.first_item(); listener; listener = next) - { - next = listener->next_item(); - - if (listener->IsRunning()) - { - listener->OnContactEnd(contact); - } - } - } - - } -} diff --git a/src/kiwano-physics/ContactListener.h b/src/kiwano-physics/ContactListener.h deleted file mode 100644 index 1223e8d3..00000000 --- a/src/kiwano-physics/ContactListener.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2018-2019 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#pragma once -#include - -namespace kiwano -{ - namespace physics - { - class ContactDispatcher; - - KGE_DECLARE_SMART_PTR(ContactListener); - - // 接触监听器 - class KGE_API ContactListener - : public ObjectBase - , protected IntrusiveListItem - { - friend IntrusiveList; - friend class ContactDispatcher; - - public: - ContactListener(); - virtual ~ContactListener(); - - // 接触开始 - virtual void OnContactBegin(Contact contact) { KGE_NOT_USED(contact); } - - // 接触结束 - virtual void OnContactEnd(Contact contact) { KGE_NOT_USED(contact); } - - inline void Start() { running_ = true; } - inline void Stop() { running_ = true; } - inline bool IsRunning() const { return running_; } - - protected: - bool running_; - }; - - - KGE_DECLARE_SMART_PTR(ContactCallbackListener); - - // 接触回调监听器 - class KGE_API ContactCallbackListener - : public ContactListener - { - friend IntrusiveList; - friend class ContactDispatcher; - - public: - using ContactBeginCallback = Function; - using ContactEndCallback = Function; - - ContactCallbackListener(); - virtual ~ContactCallbackListener(); - - // 接触开始回调 - void SetCallbackOnContactBegin(ContactBeginCallback const& cb) { begin_ = cb; } - ContactBeginCallback GetCallbackOnContactBegin() const { return begin_; } - - // 接触结束回调 - void SetCallbackOnContactEnd(ContactEndCallback const& cb) { end_ = cb; } - ContactEndCallback GetCallbackOnContactEnd() const { return end_; } - - void OnContactBegin(Contact contact) override { if (begin_) begin_(contact); } - void OnContactEnd(Contact contact) override { if (end_) end_(contact); } - - protected: - ContactBeginCallback begin_; - ContactEndCallback end_; - }; - - - // 接触分发器 - class KGE_API ContactDispatcher - { - public: - using Listeners = IntrusiveList; - - // 添加监听器 - ContactListener* AddContactListener( - ContactListenerPtr listener - ); - - // 添加监听器 - ContactListener* AddContactListener( - ContactListener* listener - ); - - // 启动监听器 - void StartContactListeners( - String const& listener_name - ); - - // 停止监听器 - void StopContactListeners( - String const& listener_name - ); - - // 移除监听器 - void RemoveContactListeners( - String const& listener_name - ); - - // 启动所有监听器 - void StartAllContactListeners(); - - // 停止所有监听器 - void StopAllContactListeners(); - - // 移除所有监听器 - void RemoveAllContactListeners(); - - protected: - void OnContactBegin(b2Contact* contact); - - void OnContactEnd(b2Contact* contact); - - private: - Listeners listeners_; - }; - } -} diff --git a/src/kiwano-physics/World.cpp b/src/kiwano-physics/World.cpp index ea9a3226..9a808a16 100644 --- a/src/kiwano-physics/World.cpp +++ b/src/kiwano-physics/World.cpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #include "World.h" +#include namespace kiwano { @@ -64,8 +65,18 @@ namespace kiwano { } - void BeginContact(b2Contact* contact) override { world_->OnContactBegin(contact); } - void EndContact(b2Contact* contact) override { world_->OnContactEnd(contact); } + void BeginContact(b2Contact* contact) override + { + ContactBeginEvent evt(contact); + world_->Dispatch(&evt); + } + + void EndContact(b2Contact* contact) override + { + ContactEndEvent evt(contact); + world_->Dispatch(&evt); + } + void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override { KGE_NOT_USED(contact); KGE_NOT_USED(oldManifold); } void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) override { KGE_NOT_USED(contact); KGE_NOT_USED(impulse); } }; @@ -102,8 +113,6 @@ namespace kiwano contact_listener_ = nullptr; } - RemoveAllContactListeners(); - // Make sure b2World was destroyed after b2Body RemoveAllChildren(); RemoveAllBodies(); diff --git a/src/kiwano-physics/World.h b/src/kiwano-physics/World.h index 74fd7c8d..51bab4fb 100644 --- a/src/kiwano-physics/World.h +++ b/src/kiwano-physics/World.h @@ -21,7 +21,6 @@ #pragma once #include #include -#include namespace kiwano { @@ -30,7 +29,6 @@ namespace kiwano // 物理世界 class KGE_API World : public Stage - , public ContactDispatcher { friend class Body; friend class Joint; diff --git a/src/kiwano-physics/kiwano-physics.h b/src/kiwano-physics/kiwano-physics.h index 58f9cf29..fcc446d2 100644 --- a/src/kiwano-physics/kiwano-physics.h +++ b/src/kiwano-physics/kiwano-physics.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 100520c7..9319a8d4 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -155,7 +155,7 @@ namespace kiwano return visible_in_rt_; } - void Actor::Dispatch(Event& evt) + void Actor::Dispatch(Event* evt) { if (!visible_) return; @@ -167,21 +167,25 @@ namespace kiwano child->Dispatch(evt); } - if (responsible_ && MouseEvent::Check(evt.type)) + if (responsible_) { - if (evt.type == Event::MouseMove) + if (evt->type == event::MouseMove) { - if (!evt.target && ContainsPoint(Point{ evt.mouse.x, evt.mouse.y })) + auto mouse_evt = evt->SafeCast(); + if (!mouse_evt->target && ContainsPoint(mouse_evt->pos)) { - evt.target = this; + mouse_evt->target = this; if (!hover_) { hover_ = true; - Event hover = evt; - hover.type = Event::MouseHover; - EventDispatcher::Dispatch(hover); + MouseHoverEvent hover; + hover.pos = mouse_evt->pos; + hover.left_btn_down = mouse_evt->left_btn_down; + hover.right_btn_down = mouse_evt->right_btn_down; + hover.target = this; + EventDispatcher::Dispatch(&hover); } } else if (hover_) @@ -189,27 +193,34 @@ namespace kiwano hover_ = false; pressed_ = false; - Event out = evt; + MouseOutEvent out; + out.pos = mouse_evt->pos; + out.left_btn_down = mouse_evt->left_btn_down; + out.right_btn_down = mouse_evt->right_btn_down; out.target = this; - out.type = Event::MouseOut; - EventDispatcher::Dispatch(out); + EventDispatcher::Dispatch(&out); } } - if (evt.type == Event::MouseBtnDown && hover_) + if (evt->type == event::MouseDown && hover_) { pressed_ = true; - evt.target = this; + evt->SafeCast()->target = this; } - if (evt.type == Event::MouseBtnUp && pressed_) + if (evt->type == event::MouseUp && pressed_) { pressed_ = false; - evt.target = this; - Event click = evt; - click.type = Event::Click; - EventDispatcher::Dispatch(click); + auto mouse_up_evt = evt->SafeCast(); + mouse_up_evt->target = this; + + MouseOutEvent click; + click.pos = mouse_up_evt->pos; + click.left_btn_down = mouse_up_evt->left_btn_down; + click.right_btn_down = mouse_up_evt->right_btn_down; + click.target = this; + EventDispatcher::Dispatch(&click); } } diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index 74b4fdba..b1e6cbab 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -365,7 +365,7 @@ namespace kiwano void ShowBorder(bool show); // 事件分发 - void Dispatch(Event& evt) override; + void Dispatch(Event* evt) override; // 设置默认锚点 static void SetDefaultAnchor( diff --git a/src/kiwano/2d/DebugActor.cpp b/src/kiwano/2d/DebugActor.cpp index 65dc2900..e6f33be9 100644 --- a/src/kiwano/2d/DebugActor.cpp +++ b/src/kiwano/2d/DebugActor.cpp @@ -66,8 +66,8 @@ namespace kiwano style.line_spacing = 20.f; debug_text_->SetStyle(style); - AddListener(Event::MouseHover, [=](const Event&) { SetOpacity(0.4f); }); - AddListener(Event::MouseOut, [=](const Event&) { SetOpacity(1.f); }); + AddListener(event::MouseHover, [=](Event*) { SetOpacity(0.4f); }); + AddListener(event::MouseOut, [=](Event*) { SetOpacity(1.f); }); } DebugActor::~DebugActor() diff --git a/src/kiwano/2d/Layer.cpp b/src/kiwano/2d/Layer.cpp index 8a01bc63..270c50a7 100644 --- a/src/kiwano/2d/Layer.cpp +++ b/src/kiwano/2d/Layer.cpp @@ -29,14 +29,14 @@ namespace kiwano { auto handler = Closure(this, &Layer::HandleMessages); - AddListener(Event::MouseBtnDown, handler); - AddListener(Event::MouseBtnUp, handler); - AddListener(Event::MouseMove, handler); - AddListener(Event::MouseWheel, handler); + AddListener(event::MouseDown, handler); + AddListener(event::MouseUp, handler); + AddListener(event::MouseMove, handler); + AddListener(event::MouseWheel, handler); - AddListener(Event::KeyDown, handler); - AddListener(Event::KeyUp, handler); - AddListener(Event::Char, handler); + AddListener(event::KeyDown, handler); + AddListener(event::KeyUp, handler); + AddListener(event::KeyChar, handler); } Layer::~Layer() @@ -64,7 +64,7 @@ namespace kiwano area_.SetMaskTransform(transform); } - void Layer::Dispatch(Event& evt) + void Layer::Dispatch(Event* evt) { if (!IsVisible()) return; @@ -91,31 +91,42 @@ namespace kiwano rt->PopLayer(); } - void Layer::HandleMessages(Event const& evt) + void Layer::HandleMessages(Event* evt) { - switch (evt.type) + if (evt->type == event::MouseDown) { - case Event::MouseBtnDown: - OnMouseButtonDown(evt.mouse.button, Point{ evt.mouse.x, evt.mouse.y }); - break; - case Event::MouseBtnUp: - OnMouseButtonUp(evt.mouse.button, Point{ evt.mouse.x, evt.mouse.y }); - break; - case Event::MouseMove: - OnMouseMoved(Point{ evt.mouse.x, evt.mouse.y }); - break; - case Event::MouseWheel: - OnMouseWheel(evt.mouse.wheel); - break; - case Event::KeyDown: - OnKeyDown(evt.key.code); - break; - case Event::KeyUp: - OnKeyUp(evt.key.code); - break; - case Event::Char: - OnChar(evt.key.c); - break; + auto real_evt = evt->SafeCast(); + OnMouseButtonDown(real_evt->button, real_evt->pos); + } + else if (evt->type == event::MouseUp) + { + auto real_evt = evt->SafeCast(); + OnMouseButtonUp(real_evt->button, real_evt->pos); + } + else if (evt->type == event::MouseMove) + { + auto real_evt = evt->SafeCast(); + OnMouseMoved(real_evt->pos); + } + else if (evt->type == event::MouseWheel) + { + auto real_evt = evt->SafeCast(); + OnMouseWheel(real_evt->wheel); + } + else if (evt->type == event::KeyDown) + { + auto real_evt = evt->SafeCast(); + OnKeyDown(real_evt->code); + } + else if (evt->type == event::KeyUp) + { + auto real_evt = evt->SafeCast(); + OnKeyUp(real_evt->code); + } + else if (evt->type == event::KeyChar) + { + auto real_evt = evt->SafeCast(); + OnChar(real_evt->value); } } diff --git a/src/kiwano/2d/Layer.h b/src/kiwano/2d/Layer.h index 5f4716c0..fa06e350 100644 --- a/src/kiwano/2d/Layer.h +++ b/src/kiwano/2d/Layer.h @@ -34,8 +34,8 @@ namespace kiwano virtual ~Layer(); // 重载下列函数以获取图层事件 - virtual void OnMouseButtonDown(int btn, Point const& p) {} - virtual void OnMouseButtonUp(int btn, Point const& p) {} + virtual void OnMouseButtonDown(MouseButton::Value btn, Point const& p) {} + virtual void OnMouseButtonUp(MouseButton::Value btn, Point const& p) {} virtual void OnMouseMoved(Point const& p) {} virtual void OnMouseWheel(float wheel) {} virtual void OnKeyDown(int key) {} @@ -67,12 +67,12 @@ namespace kiwano inline LayerArea const& GetArea() const { return area_; } public: - void Dispatch(Event& evt) override; + void Dispatch(Event* evt) override; protected: void Render(RenderTarget* rt) override; - void HandleMessages(Event const& evt); + void HandleMessages(Event* evt); protected: bool swallow_; diff --git a/src/kiwano/base/Component.h b/src/kiwano/base/Component.h index c76e0e8d..de531a91 100644 --- a/src/kiwano/base/Component.h +++ b/src/kiwano/base/Component.h @@ -21,10 +21,12 @@ #pragma once #include #include -#include namespace kiwano { + class RenderTarget; + class Event; + // 基础组件 class KGE_API ComponentBase { @@ -42,8 +44,6 @@ namespace kiwano }; - class RenderTarget; - // 渲染支持组件 class KGE_API RenderComponent : public virtual ComponentBase @@ -85,7 +85,7 @@ namespace kiwano : public virtual ComponentBase { public: - virtual void HandleEvent(Event&) {} + virtual void HandleEvent(Event*) {} virtual void HandleMessage(HWND, UINT32, WPARAM, LPARAM) {} diff --git a/src/kiwano/base/Director.cpp b/src/kiwano/base/Director.cpp index ac6d5ab1..d60ddad7 100644 --- a/src/kiwano/base/Director.cpp +++ b/src/kiwano/base/Director.cpp @@ -180,7 +180,7 @@ namespace kiwano } } - void Director::HandleEvent(Event& evt) + void Director::HandleEvent(Event* evt) { if (debug_actor_) debug_actor_->Dispatch(evt); diff --git a/src/kiwano/base/Director.h b/src/kiwano/base/Director.h index 56ca957a..7a338472 100644 --- a/src/kiwano/base/Director.h +++ b/src/kiwano/base/Director.h @@ -72,7 +72,7 @@ namespace kiwano void OnRender(RenderTarget* rt) override; - void HandleEvent(Event& evt) override; + void HandleEvent(Event* evt) override; protected: Director(); diff --git a/src/kiwano/base/Event.cpp b/src/kiwano/base/Event.cpp new file mode 100644 index 00000000..09e6d544 --- /dev/null +++ b/src/kiwano/base/Event.cpp @@ -0,0 +1,134 @@ +#include + +namespace kiwano +{ + EventType event::MouseMove = EventType(L"MouseMove"); + EventType event::MouseDown = EventType(L"MouseBtnDown"); + EventType event::MouseUp = EventType(L"MouseBtnUp"); + EventType event::MouseWheel = EventType(L"MouseWheel"); + EventType event::MouseHover = EventType(L"MouseHover"); + EventType event::MouseOut = EventType(L"MouseOut"); + EventType event::MouseClick = EventType(L"MouseClick"); + + EventType event::KeyDown = EventType(L"KeyDown"); + EventType event::KeyUp = EventType(L"KeyUp"); + EventType event::KeyChar = EventType(L"KeyChar"); + + EventType event::WindowMoved = EventType(L"WindowMoved"); + EventType event::WindowResized = EventType(L"WindowResized"); + EventType event::WindowFocusChanged = EventType(L"WindowFocusChanged"); + EventType event::WindowTitleChanged = EventType(L"WindowTitleChanged"); + EventType event::WindowClosed = EventType(L"WindowClosed"); + + + Event::Event(EventType const& type) + : type(type) + { + } + + Event::~Event() + { + } + + MouseEvent::MouseEvent(EventType const& type) + : Event(type) + , pos() + , left_btn_down(false) + , right_btn_down(false) + , target(nullptr) + { + } + + MouseMoveEvent::MouseMoveEvent() + : MouseEvent(event::MouseMove) + , button(0) + { + } + + MouseDownEvent::MouseDownEvent() + : MouseEvent(event::MouseDown) + , button(0) + { + } + + MouseUpEvent::MouseUpEvent() + : MouseEvent(event::MouseUp) + , button(0) + { + } + + MouseClickEvent::MouseClickEvent() + : MouseEvent(event::MouseClick) + , button(0) + { + } + + MouseHoverEvent::MouseHoverEvent() + : MouseEvent(event::MouseHover) + { + } + + MouseOutEvent::MouseOutEvent() + : MouseEvent(event::MouseOut) + { + } + + MouseWheelEvent::MouseWheelEvent() + : MouseEvent(event::MouseWheel) + , wheel(0.f) + { + } + + KeyDownEvent::KeyDownEvent() + : Event(event::KeyDown) + , code(0) + , count(0) + { + } + + KeyUpEvent::KeyUpEvent() + : Event(event::KeyUp) + , code(0) + , count(0) + { + } + + KeyCharEvent::KeyCharEvent() + : Event(event::KeyChar) + , value() + , count(0) + { + } + + WindowMovedEvent::WindowMovedEvent() + : Event(event::WindowMoved) + , x(0) + , y(0) + { + } + + WindowResizedEvent::WindowResizedEvent() + : Event(event::WindowResized) + , width(0) + , height(0) + { + } + + WindowFocusChangedEvent::WindowFocusChangedEvent() + : Event(event::WindowFocusChanged) + , focus(false) + { + } + + WindowTitleChangedEvent::WindowTitleChangedEvent() + : Event(event::WindowTitleChanged) + , title() + { + } + + WindowClosedEvent::WindowClosedEvent() + : Event(event::WindowClosed) + { + } + +} diff --git a/src/kiwano/base/Event.h b/src/kiwano/base/Event.h new file mode 100644 index 00000000..77688fa0 --- /dev/null +++ b/src/kiwano/base/Event.h @@ -0,0 +1,272 @@ +// Copyright (c) 2016-2018 Kiwano - Nomango +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +#include +#include +#include + +namespace kiwano +{ + class Actor; + + // 事件类型 + struct EventType + { + inline EventType() : hash(0), type() + { + } + + inline EventType(String const& type) : hash(0), type(type) + { + hash = type.hash(); + } + + inline bool operator==(const EventType& rhs) const + { + return hash == rhs.hash && type == rhs.type; + } + + size_t hash; + String type; + }; + + + // 事件 + class KGE_API Event + { + public: + const EventType type; + + Event(EventType const& type); + virtual ~Event(); + + template < + typename _Ty, + typename = typename std::enable_if::value, int>::type + > + inline const _Ty* SafeCast() const + { + const _Ty* ptr = dynamic_cast(this); + if (ptr) + { + return ptr; + } + return nullptr; + } + + template < + typename _Ty, + typename = typename std::enable_if::value, int>::type + > + inline _Ty* SafeCast() + { + return const_cast<_Ty*>(const_cast(this)->SafeCast<_Ty>()); + } + }; + + // 鼠标事件 + class KGE_API MouseEvent + : public Event + { + public: + Point pos; + bool left_btn_down; // 左键是否按下 + bool right_btn_down; // 右键是否按下 + Actor* target; + + MouseEvent(EventType const& type); + }; + + // 鼠标移动事件 + class KGE_API MouseMoveEvent + : public MouseEvent + { + public: + MouseButton::Value button; + + MouseMoveEvent(); + }; + + // 鼠标按键按下事件 + class KGE_API MouseDownEvent + : public MouseEvent + { + public: + MouseButton::Value button; + + MouseDownEvent(); + }; + + // 鼠标按键抬起事件 + class KGE_API MouseUpEvent + : public MouseEvent + { + public: + MouseButton::Value button; + + MouseUpEvent(); + }; + + // 鼠标点击事件 + class KGE_API MouseClickEvent + : public MouseEvent + { + public: + MouseButton::Value button; + + MouseClickEvent(); + }; + + // 鼠标移入事件 + class KGE_API MouseHoverEvent + : public MouseEvent + { + public: + MouseHoverEvent(); + }; + + // 鼠标移出事件 + class KGE_API MouseOutEvent + : public MouseEvent + { + public: + MouseOutEvent(); + }; + + // 鼠标滚轮事件 + class KGE_API MouseWheelEvent + : public MouseEvent + { + public: + float wheel; + + MouseWheelEvent(); + }; + + // 键盘按下事件 + class KGE_API KeyDownEvent + : public Event + { + public: + KeyCode::Value code; + int count; + + KeyDownEvent(); + }; + + // 键盘抬起事件 + class KGE_API KeyUpEvent + : public Event + { + public: + KeyCode::Value code; + int count; + + KeyUpEvent(); + }; + + // 键盘字符事件 + class KGE_API KeyCharEvent + : public Event + { + public: + char value; + int count; + + KeyCharEvent(); + }; + + // 窗口移动事件 + class KGE_API WindowMovedEvent + : public Event + { + public: + int x; + int y; + + WindowMovedEvent(); + }; + + // 窗口大小变化事件 + class KGE_API WindowResizedEvent + : public Event + { + public: + int width; + int height; + + WindowResizedEvent(); + }; + + // 窗口焦点变化事件 + class KGE_API WindowFocusChangedEvent + : public Event + { + public: + bool focus; + + WindowFocusChangedEvent(); + }; + + // 窗口标题更改事件 + class KGE_API WindowTitleChangedEvent + : public Event + { + public: + String title; + + WindowTitleChangedEvent(); + }; + + // 窗口关闭事件 + class KGE_API WindowClosedEvent + : public Event + { + public: + WindowClosedEvent(); + }; + + + namespace event + { + // 鼠标事件 + extern EventType MouseMove; // 移动 + extern EventType MouseDown; // 鼠标按下 + extern EventType MouseUp; // 鼠标抬起 + extern EventType MouseWheel; // 滚轮滚动 + extern EventType MouseHover; // 鼠标移入 + extern EventType MouseOut; // 鼠标移出 + extern EventType MouseClick; // 鼠标点击 + + // 按键事件 + extern EventType KeyDown; // 按键按下 + extern EventType KeyUp; // 按键抬起 + extern EventType KeyChar; // 输出字符 + + // 窗口消息 + extern EventType WindowMoved; // 窗口移动 + extern EventType WindowResized; // 窗口大小变化 + extern EventType WindowFocusChanged; // 获得或失去焦点 + extern EventType WindowTitleChanged; // 标题变化 + extern EventType WindowClosed; // 窗口被关闭 + } + +} diff --git a/src/kiwano/base/Event.hpp b/src/kiwano/base/Event.hpp deleted file mode 100644 index 154699c0..00000000 --- a/src/kiwano/base/Event.hpp +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2016-2018 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#pragma once -#include - -namespace kiwano -{ - // 事件类型 - typedef int EventType; - - // 鼠标事件 - struct MouseEvent - { - float x; - float y; - bool left_btn_down; // 左键是否按下 - bool right_btn_down; // 右键是否按下 - - union - { - struct // Events::MouseDown | Events::MouseUp | Events::MouseClick - { - MouseButton::Value button; - }; - - struct // Events::MouseWheel - { - float wheel; - }; - }; - - static bool Check(EventType type); - }; - - // 键盘事件 - struct KeyboardEvent - { - int count; - union - { - struct // Events::KeyDown | Events::KeyUp - { - KeyCode::Value code; - }; - - struct // Events::Char - { - char c; - }; - }; - - static bool Check(EventType type); - }; - - // 窗口事件 - struct WindowEvent - { - union - { - struct // Events::WindowMoved - { - int x; - int y; - }; - - struct // Events::WindowResized - { - int width; - int height; - }; - - struct // Events::WindowFocusChanged - { - bool focus; - }; - - struct // Events::WindowTitleChanged - { - const wchar_t* title; - }; - }; - - static bool Check(EventType type); - }; - - // 自定义事件 - struct CustomEvent - { - void* data; - }; - - class Actor; - - // 事件 - struct KGE_API Event - { - enum Type : EventType - { - First, - - // 鼠标事件 - MouseFirst, - MouseMove, // 移动 - MouseBtnDown, // 鼠标按下 - MouseBtnUp, // 鼠标抬起 - MouseWheel, // 滚轮滚动 - MouseHover, // 鼠标移入 - MouseOut, // 鼠标移出 - Click, // 鼠标点击 - MouseLast, - - // 按键事件 - KeyFirst, - KeyDown, // 按键按下 - KeyUp, // 按键抬起 - Char, // 输出字符 - KeyLast, - - // 窗口消息 - WindowFirst, - WindowMoved, // 窗口移动 - WindowResized, // 窗口大小变化 - WindowFocusChanged, // 获得或失去焦点 - WindowTitleChanged, // 标题变化 - WindowClosed, // 窗口被关闭 - WindowLast, - - Last - }; - - int type; - Actor* target; - - union - { - MouseEvent mouse; - KeyboardEvent key; - WindowEvent window; - CustomEvent custom; - }; - - Event(EventType type = Type::First) : type(type), target(nullptr) {} - }; - - - // Check-functions - - inline bool MouseEvent::Check(EventType type) - { - return type > Event::MouseFirst && type < Event::MouseLast; - } - - inline bool KeyboardEvent::Check(EventType type) - { - return type > Event::KeyFirst && type < Event::KeyLast; - } - - inline bool WindowEvent::Check(EventType type) - { - return type > Event::WindowFirst && type < Event::WindowLast; - } - -} diff --git a/src/kiwano/base/EventDispatcher.cpp b/src/kiwano/base/EventDispatcher.cpp index ee5d6673..e9a04d2a 100644 --- a/src/kiwano/base/EventDispatcher.cpp +++ b/src/kiwano/base/EventDispatcher.cpp @@ -23,7 +23,7 @@ namespace kiwano { - void EventDispatcher::Dispatch(Event& evt) + void EventDispatcher::Dispatch(Event* evt) { if (listeners_.empty()) return; @@ -33,7 +33,7 @@ namespace kiwano { next = listener->next_item(); - if (listener->IsRunning() && listener->type_ == evt.type) + if (listener->IsRunning() && listener->type_ == evt->type) { listener->callback_(evt); } @@ -56,9 +56,15 @@ namespace kiwano return listener; } - EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callback callback, String const& name) + EventListener* EventDispatcher::AddListener(String const& name, EventType type, EventListener::Callback callback) { - EventListenerPtr listener = new EventListener(type, callback, name); + EventListenerPtr listener = new EventListener(name, type, callback); + return AddListener(listener); + } + + EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callback callback) + { + EventListenerPtr listener = new EventListener(type, callback); return AddListener(listener); } @@ -98,7 +104,7 @@ namespace kiwano } } - void EventDispatcher::StartListeners(uint32_t type) + void EventDispatcher::StartListeners(const EventType& type) { for (auto listener = listeners_.first_item(); listener; listener = listener->next_item()) { @@ -109,7 +115,7 @@ namespace kiwano } } - void EventDispatcher::StopListeners(uint32_t type) + void EventDispatcher::StopListeners(const EventType& type) { for (auto listener = listeners_.first_item(); listener; listener = listener->next_item()) { @@ -120,7 +126,7 @@ namespace kiwano } } - void EventDispatcher::RemoveListeners(uint32_t type) + void EventDispatcher::RemoveListeners(const EventType& type) { EventListenerPtr next; for (auto listener = listeners_.first_item(); listener; listener = next) diff --git a/src/kiwano/base/EventDispatcher.h b/src/kiwano/base/EventDispatcher.h index 31f83298..971aa300 100644 --- a/src/kiwano/base/EventDispatcher.h +++ b/src/kiwano/base/EventDispatcher.h @@ -40,9 +40,15 @@ namespace kiwano // 添加监听器 EventListener* AddListener( + String const& name, EventType type, - EventListener::Callback callback, - String const& name = L"" + EventListener::Callback callback + ); + + // 添加监听器 + EventListener* AddListener( + EventType type, + EventListener::Callback callback ); // 启动监听器 @@ -62,20 +68,20 @@ namespace kiwano // 启动监听器 void StartListeners( - uint32_t type + const EventType& type ); // 停止监听器 void StopListeners( - uint32_t type + const EventType& type ); // 移除监听器 void RemoveListeners( - uint32_t type + const EventType& type ); - virtual void Dispatch(Event& evt); + virtual void Dispatch(Event* evt); protected: Listeners listeners_; diff --git a/src/kiwano/base/EventListener.cpp b/src/kiwano/base/EventListener.cpp index e8ffcb6b..f856c94d 100644 --- a/src/kiwano/base/EventListener.cpp +++ b/src/kiwano/base/EventListener.cpp @@ -23,10 +23,22 @@ namespace kiwano { - EventListener::EventListener(EventType type, Callback const & callback, String const & name) + EventListener::EventListener() + : type_() + , callback_() + , running_(true) + { + } + + EventListener::EventListener(EventType type, Callback const& callback) : type_(type) , callback_(callback) , running_(true) + { + } + + EventListener::EventListener(String const& name, EventType type, Callback const& callback) + : EventListener(type, callback) { SetName(name); } diff --git a/src/kiwano/base/EventListener.h b/src/kiwano/base/EventListener.h index 42317aae..41612061 100644 --- a/src/kiwano/base/EventListener.h +++ b/src/kiwano/base/EventListener.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include namespace kiwano { @@ -39,25 +39,77 @@ namespace kiwano friend IntrusiveList; public: - using Callback = Function; + using Callback = Function; + + EventListener(); EventListener( EventType type, - Callback const& callback, - String const& name = L"" + Callback const& callback + ); + + EventListener( + String const& name, + EventType type, + Callback const& callback ); virtual ~EventListener(); - inline void Start() { running_ = true; } + void Start(); - inline void Stop() { running_ = true; } + void Stop(); - inline bool IsRunning() const { return running_; } + bool IsRunning() const; + + Callback GetCallback() const; + + void SetCallback(Callback const& cb); + + EventType const& GetEventType() const; + + void SetEventType(EventType const& type); protected: bool running_; EventType type_; Callback callback_; }; + + + inline void EventListener::Start() + { + running_ = true; + } + + inline void EventListener::Stop() + { + running_ = false; + } + + inline bool EventListener::IsRunning() const + { + return running_; + } + + inline EventListener::Callback EventListener::GetCallback() const + { + return callback_; + } + + inline void EventListener::SetCallback(Callback const& cb) + { + callback_ = cb; + } + + inline EventType const& EventListener::GetEventType() const + { + return type_; + } + + inline void EventListener::SetEventType(EventType const& type) + { + type_ = type; + } + } diff --git a/src/kiwano/base/Library.h b/src/kiwano/base/Library.h index 9e1cf034..e6b9f140 100644 --- a/src/kiwano/base/Library.h +++ b/src/kiwano/base/Library.h @@ -20,8 +20,7 @@ #pragma once #include -#include -#include +#include namespace kiwano { diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 9db500d8..1b4030d9 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -82,7 +82,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index b88b3694..4a61c8b7 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -261,7 +261,7 @@ namespace kiwano } } - void Application::DispatchEvent(Event& evt) + void Application::DispatchEvent(Event* evt) { for (auto c : event_comps_) { @@ -307,21 +307,29 @@ namespace kiwano case WM_SYSKEYUP: { bool down = msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN; - Event evt(down ? Event::KeyDown : Event::KeyUp); - evt.key.code = static_cast(wparam); - evt.key.count = static_cast(lparam & 0xFF); - - app->DispatchEvent(evt); + if (down) + { + KeyDownEvent evt; + evt.code = static_cast(wparam); + evt.count = static_cast(lparam & 0xFF); + app->DispatchEvent(&evt); + } + else + { + KeyUpEvent evt; + evt.code = static_cast(wparam); + evt.count = static_cast(lparam & 0xFF); + app->DispatchEvent(&evt); + } } break; case WM_CHAR: { - Event evt(Event::Char); - evt.key.c = static_cast(wparam); - evt.key.count = static_cast(lparam & 0xFF); - - app->DispatchEvent(evt); + KeyCharEvent evt; + evt.value = static_cast(wparam); + evt.count = static_cast(lparam & 0xFF); + app->DispatchEvent(&evt); } break; @@ -337,23 +345,44 @@ namespace kiwano case WM_MOUSEMOVE: case WM_MOUSEWHEEL: { - Event evt; + auto UpdateMouseData = [&](MouseEvent* evt) + { + evt->pos = Point(static_cast(GET_X_LPARAM(lparam)), static_cast(GET_Y_LPARAM(lparam))); + evt->left_btn_down = !!(wparam & MK_LBUTTON); + evt->left_btn_down = !!(wparam & MK_RBUTTON); + }; - evt.mouse.x = static_cast(GET_X_LPARAM(lparam)); - evt.mouse.y = static_cast(GET_Y_LPARAM(lparam)); - evt.mouse.left_btn_down = !!(wparam & MK_LBUTTON); - evt.mouse.left_btn_down = !!(wparam & MK_RBUTTON); - - if (msg == WM_MOUSEMOVE) { evt.type = Event::MouseMove; } - else if (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN) { evt.type = Event::MouseBtnDown; } - else if (msg == WM_LBUTTONUP || msg == WM_RBUTTONUP || msg == WM_MBUTTONUP) { evt.type = Event::MouseBtnUp; } - else if (msg == WM_MOUSEWHEEL) { evt.type = Event::MouseWheel; evt.mouse.wheel = GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; } - - if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) { evt.mouse.button = MouseButton::Left; } - else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONUP) { evt.mouse.button = MouseButton::Right; } - else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONUP) { evt.mouse.button = MouseButton::Middle; } - - app->DispatchEvent(evt); + if (msg == WM_MOUSEMOVE) + { + MouseMoveEvent evt; + UpdateMouseData(&evt); + app->DispatchEvent(&evt); + } + else if (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN) + { + MouseDownEvent evt; + UpdateMouseData(&evt); + if (msg == WM_LBUTTONDOWN) { evt.button = MouseButton::Left; } + else if (msg == WM_RBUTTONDOWN) { evt.button = MouseButton::Right; } + else if (msg == WM_MBUTTONDOWN) { evt.button = MouseButton::Middle; } + app->DispatchEvent(&evt); + } + else if (msg == WM_LBUTTONUP || msg == WM_RBUTTONUP || msg == WM_MBUTTONUP) + { + MouseDownEvent evt; + UpdateMouseData(&evt); + if (msg == WM_LBUTTONUP) { evt.button = MouseButton::Left; } + else if (msg == WM_RBUTTONUP) { evt.button = MouseButton::Right; } + else if (msg == WM_MBUTTONUP) { evt.button = MouseButton::Middle; } + app->DispatchEvent(&evt); + } + else if (msg == WM_MOUSEWHEEL) + { + MouseWheelEvent evt; + UpdateMouseData(&evt); + evt.wheel = GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; + app->DispatchEvent(&evt); + } } break; @@ -369,10 +398,10 @@ namespace kiwano Window::GetInstance()->UpdateWindowRect(); - Event evt(Event::WindowResized); - evt.window.width = LOWORD(lparam); - evt.window.height = HIWORD(lparam); - app->DispatchEvent(evt); + WindowResizedEvent evt; + evt.width = LOWORD(lparam); + evt.height = HIWORD(lparam); + app->DispatchEvent(&evt); } } break; @@ -382,10 +411,10 @@ namespace kiwano int x = (int)(short)LOWORD(lparam); int y = (int)(short)HIWORD(lparam); - Event evt(Event::WindowMoved); - evt.window.x = x; - evt.window.y = y; - app->DispatchEvent(evt); + WindowMovedEvent evt; + evt.x = x; + evt.y = y; + app->DispatchEvent(&evt); } break; @@ -395,9 +424,9 @@ namespace kiwano Window::GetInstance()->SetActive(active); - Event evt(Event::WindowFocusChanged); - evt.window.focus = active; - app->DispatchEvent(evt); + WindowFocusChangedEvent evt; + evt.focus = active; + app->DispatchEvent(&evt); } break; @@ -405,9 +434,9 @@ namespace kiwano { // KGE_LOG(L"Window title changed"); - Event evt(Event::WindowTitleChanged); - evt.window.title = reinterpret_cast(lparam); - app->DispatchEvent(evt); + WindowTitleChangedEvent evt; + evt.title = reinterpret_cast(lparam); + app->DispatchEvent(&evt); } break; @@ -437,8 +466,8 @@ namespace kiwano if (!app->OnClosing()) { - Event evt(Event::WindowClosed); - app->DispatchEvent(evt); + WindowClosedEvent evt; + app->DispatchEvent(&evt); return 0; } } diff --git a/src/kiwano/platform/Application.h b/src/kiwano/platform/Application.h index f1224b39..501f1bd3 100644 --- a/src/kiwano/platform/Application.h +++ b/src/kiwano/platform/Application.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -91,7 +91,7 @@ namespace kiwano ); // 分发事件 - void DispatchEvent(Event& evt); + void DispatchEvent(Event* evt); // 在 Kiwano 主线程中执行函数 // 当在其他线程调用 Kiwano 函数时使用 diff --git a/src/kiwano/ui/Button.cpp b/src/kiwano/ui/Button.cpp index 35d3a7c3..5aa6191b 100644 --- a/src/kiwano/ui/Button.cpp +++ b/src/kiwano/ui/Button.cpp @@ -32,10 +32,10 @@ namespace kiwano { SetResponsible(true); - AddListener(Event::MouseHover, Closure(this, &Button::UpdateStatus)); - AddListener(Event::MouseOut, Closure(this, &Button::UpdateStatus)); - AddListener(Event::MouseBtnDown, Closure(this, &Button::UpdateStatus)); - AddListener(Event::MouseBtnUp, Closure(this, &Button::UpdateStatus)); + AddListener(event::MouseHover, Closure(this, &Button::UpdateStatus)); + AddListener(event::MouseOut, Closure(this, &Button::UpdateStatus)); + AddListener(event::MouseDown, Closure(this, &Button::UpdateStatus)); + AddListener(event::MouseUp, Closure(this, &Button::UpdateStatus)); } Button::Button(const Callback& click) @@ -103,13 +103,14 @@ namespace kiwano } } - void Button::UpdateStatus(Event const& evt) + void Button::UpdateStatus(Event* evt) { - KGE_ASSERT(MouseEvent::Check(evt.type)); + auto mouse_evt = evt->SafeCast(); + KGE_ASSERT(mouse_evt); - if (enabled_ && (evt.target == this)) + if (enabled_ && (mouse_evt->target == this)) { - if (evt.type == Event::MouseHover) + if (evt->type == event::MouseHover) { SetStatus(Status::Hover); Window::GetInstance()->SetCursor(CursorType::Hand); @@ -117,7 +118,7 @@ namespace kiwano if (mouse_over_callback_) mouse_over_callback_(); } - else if (evt.type == Event::MouseOut) + else if (evt->type == event::MouseOut) { SetStatus(Status::Normal); Window::GetInstance()->SetCursor(CursorType::Arrow); @@ -125,14 +126,14 @@ namespace kiwano if (mouse_out_callback_) mouse_out_callback_(); } - else if (evt.type == Event::MouseBtnDown && status_ == Status::Hover) + else if (evt->type == event::MouseDown && status_ == Status::Hover) { SetStatus(Status::Pressed); if (pressed_callback_) pressed_callback_(); } - else if (evt.type == Event::MouseBtnUp && status_ == Status::Pressed) + else if (evt->type == event::MouseUp && status_ == Status::Pressed) { SetStatus(Status::Hover); diff --git a/src/kiwano/ui/Button.h b/src/kiwano/ui/Button.h index 29e0c67c..28e16537 100644 --- a/src/kiwano/ui/Button.h +++ b/src/kiwano/ui/Button.h @@ -84,7 +84,7 @@ namespace kiwano Status status ); - void UpdateStatus(Event const& evt); + void UpdateStatus(Event* evt); private: bool enabled_;