diff --git a/src/kiwano-physics/World.cpp b/src/kiwano-physics/World.cpp index 8c47eee4..9814557c 100644 --- a/src/kiwano-physics/World.cpp +++ b/src/kiwano-physics/World.cpp @@ -68,13 +68,13 @@ namespace kiwano void BeginContact(b2Contact* contact) override { ContactBeginEvent evt(contact); - world_->Dispatch(evt); + world_->DispatchEvent(evt); } void EndContact(b2Contact* contact) override { ContactEndEvent evt(contact); - world_->Dispatch(evt); + world_->DispatchEvent(evt); } void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override { KGE_NOT_USED(contact); KGE_NOT_USED(oldManifold); } diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 324553ca..eb01716d 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -175,10 +175,10 @@ namespace kiwano return visible_in_rt_; } - void Actor::Dispatch(Event& evt) + bool Actor::DispatchEvent(Event& evt) { if (!visible_) - return; + return true; // Dispatch to children those are greater than 0 in Z-Order Actor* child = children_.last_item().get(); @@ -187,23 +187,29 @@ namespace kiwano if (child->GetZOrder() < 0) break; - child->Dispatch(evt); + if (!child->DispatchEvent(evt)) + return false; + child = child->prev_item().get(); } + if (!EventDispatcher::DispatchEvent(evt)) + return false; + HandleEvent(evt); while (child) { - child->Dispatch(evt); + if (!child->DispatchEvent(evt)) + return false; + child = child->prev_item().get(); } + return true; } void Actor::HandleEvent(Event& evt) { - EventDispatcher::Dispatch(evt); - if (responsible_) { if (evt.IsType()) @@ -218,7 +224,7 @@ namespace kiwano hover.pos = mouse_evt.pos; hover.left_btn_down = mouse_evt.left_btn_down; hover.right_btn_down = mouse_evt.right_btn_down; - EventDispatcher::Dispatch(hover); + EventDispatcher::DispatchEvent(hover); } else if (hover_ && !contains) { @@ -229,7 +235,7 @@ namespace kiwano out.pos = mouse_evt.pos; out.left_btn_down = mouse_evt.left_btn_down; out.right_btn_down = mouse_evt.right_btn_down; - EventDispatcher::Dispatch(out); + EventDispatcher::DispatchEvent(out); } } @@ -249,7 +255,7 @@ namespace kiwano click.left_btn_down = mouse_up_evt.left_btn_down; click.right_btn_down = mouse_up_evt.right_btn_down; click.button = mouse_up_evt.button; - EventDispatcher::Dispatch(click); + EventDispatcher::DispatchEvent(click); } } } diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index b2d9e935..e32057da 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -393,7 +393,9 @@ namespace kiwano /// \~chinese /// @brief 分发事件 - void Dispatch(Event& evt) override; + /// @param evt 事件 + /// @return 是否继续分发该事件 + virtual bool DispatchEvent(Event& evt); /// \~chinese /// @brief 设置默认锚点 diff --git a/src/kiwano/2d/Layer.cpp b/src/kiwano/2d/Layer.cpp index e379c96a..52f5f163 100644 --- a/src/kiwano/2d/Layer.cpp +++ b/src/kiwano/2d/Layer.cpp @@ -54,20 +54,16 @@ namespace kiwano area_.SetMaskTransform(transform); } - void Layer::Dispatch(Event& evt) + bool Layer::DispatchEvent(Event& evt) { if (!IsVisible()) - return; + return true; - if (!swallow_) + if (swallow_) { - for (auto child = GetAllChildren().rbegin(); child != GetAllChildren().rend(); ++child) - { - child->Dispatch(evt); - } + return EventDispatcher::DispatchEvent(evt); } - - EventDispatcher::Dispatch(evt); + return Actor::DispatchEvent(evt); } void Layer::Render(RenderContext& ctx) diff --git a/src/kiwano/2d/Layer.h b/src/kiwano/2d/Layer.h index 1047c695..0026a358 100644 --- a/src/kiwano/2d/Layer.h +++ b/src/kiwano/2d/Layer.h @@ -82,7 +82,7 @@ namespace kiwano /// @brief 获取图层区域 LayerArea const& GetArea() const; - void Dispatch(Event& evt) override; + bool DispatchEvent(Event& evt) override; protected: void Render(RenderContext& ctx) override; diff --git a/src/kiwano/core/EventDispatcher.cpp b/src/kiwano/core/EventDispatcher.cpp index 776e8398..74cec5ae 100644 --- a/src/kiwano/core/EventDispatcher.cpp +++ b/src/kiwano/core/EventDispatcher.cpp @@ -23,10 +23,10 @@ namespace kiwano { - void EventDispatcher::Dispatch(Event& evt) + bool EventDispatcher::DispatchEvent(Event& evt) { if (listeners_.empty()) - return; + return true; EventListenerPtr next; for (auto listener = listeners_.first_item(); listener; listener = next) @@ -34,15 +34,15 @@ namespace kiwano next = listener->next_item(); if (listener->IsRunning()) - { listener->Receive(evt); - } if (listener->IsRemoveable()) - { listeners_.remove(listener); - } + + if (listener->IsSwallowEnabled()) + return false; } + return true; } EventListener* EventDispatcher::AddListener(EventListenerPtr listener) diff --git a/src/kiwano/core/EventDispatcher.h b/src/kiwano/core/EventDispatcher.h index 56ab8e13..8e0edb5d 100644 --- a/src/kiwano/core/EventDispatcher.h +++ b/src/kiwano/core/EventDispatcher.h @@ -131,7 +131,8 @@ namespace kiwano /// \~chinese /// @brief 分发事件 /// @param evt 事件 - virtual void Dispatch(Event& evt); + /// @return 是否继续分发该事件 + bool DispatchEvent(Event& evt); private: Listeners listeners_; diff --git a/src/kiwano/core/EventListener.cpp b/src/kiwano/core/EventListener.cpp index c8fd0dc7..f0e422b3 100644 --- a/src/kiwano/core/EventListener.cpp +++ b/src/kiwano/core/EventListener.cpp @@ -28,21 +28,21 @@ namespace kiwano , callback_() , running_(true) , removeable_(false) + , swallow_(false) { } EventListener::EventListener(EventType type, Callback const& callback) - : type_(type) - , callback_(callback) - , running_(true) - , removeable_(false) + : EventListener(String(), type, callback) { } EventListener::EventListener(String const& name, EventType type, Callback const& callback) - : EventListener(type, callback) + : EventListener() { SetName(name); + SetEventType(type); + SetCallback(callback); } EventListener::~EventListener() diff --git a/src/kiwano/core/EventListener.h b/src/kiwano/core/EventListener.h index ec40bd11..a28425fe 100644 --- a/src/kiwano/core/EventListener.h +++ b/src/kiwano/core/EventListener.h @@ -115,6 +115,15 @@ namespace kiwano /// @brief 是否可移除 bool IsRemoveable() const; + /// \~chinese + /// @brief 是否开启消息吞没 + bool IsSwallowEnabled() const; + + /// \~chinese + /// @brief 设置消息吞没功能 + /// @param enabled 是否启用 + void SetSwallowEnabled(bool enabled); + /// \~chinese /// @brief 获取回调函数 const Callback& GetCallback() const; @@ -150,6 +159,7 @@ namespace kiwano private: bool running_; bool removeable_; + bool swallow_; EventType type_; Callback callback_; }; @@ -180,6 +190,16 @@ namespace kiwano return removeable_; } + inline bool EventListener::IsSwallowEnabled() const + { + return swallow_; + } + + inline void EventListener::SetSwallowEnabled(bool enabled) + { + swallow_ = enabled; + } + inline const EventListener::Callback& EventListener::GetCallback() const { return callback_; diff --git a/src/kiwano/platform/Director.cpp b/src/kiwano/platform/Director.cpp index ddda525d..463ada46 100644 --- a/src/kiwano/platform/Director.cpp +++ b/src/kiwano/platform/Director.cpp @@ -182,13 +182,13 @@ namespace kiwano void Director::HandleEvent(Event& evt) { if (current_stage_) - current_stage_->Dispatch(evt); + current_stage_->DispatchEvent(evt); if (next_stage_) - next_stage_->Dispatch(evt); + next_stage_->DispatchEvent(evt); if (debug_actor_) - debug_actor_->Dispatch(evt); + debug_actor_->DispatchEvent(evt); } }