diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj
index 5263f3e8..4bd46c9f 100644
--- a/projects/kiwano/kiwano.vcxproj
+++ b/projects/kiwano/kiwano.vcxproj
@@ -23,6 +23,7 @@
+
@@ -150,6 +151,7 @@
+
diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters
index 823c4b29..ff452122 100644
--- a/projects/kiwano/kiwano.vcxproj.filters
+++ b/projects/kiwano/kiwano.vcxproj.filters
@@ -393,6 +393,9 @@
2d\transition
+
+ base\component
+
@@ -647,6 +650,9 @@
2d\transition
+
+ base\component
+
diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp
index ebdfb9ee..caa9dfad 100644
--- a/src/kiwano/2d/Actor.cpp
+++ b/src/kiwano/2d/Actor.cpp
@@ -44,9 +44,6 @@ Actor::Actor()
, visible_(true)
, visible_in_rt_(true)
, update_pausing_(false)
- , hover_(false)
- , pressed_(false)
- , responsible_(false)
, cascade_opacity_(true)
, show_border_(false)
, evt_dispatch_enabled_(true)
@@ -225,8 +222,8 @@ void Actor::SetEventDispatchEnabled(bool enabled)
void Actor::DoSerialize(Serializer* serializer) const
{
ObjectBase::DoSerialize(serializer);
- (*serializer) << visible_ << update_pausing_ << cascade_opacity_ << responsible_ << z_order_ << opacity_ << anchor_
- << size_ << transform_;
+ (*serializer) << visible_ << update_pausing_ << cascade_opacity_ << z_order_ << opacity_ << anchor_ << size_
+ << transform_;
}
void Actor::DoDeserialize(Deserializer* deserializer)
@@ -235,8 +232,8 @@ void Actor::DoDeserialize(Deserializer* deserializer)
float opacity = 1.0f;
Transform transform;
- (*deserializer) >> visible_ >> update_pausing_ >> cascade_opacity_ >> responsible_ >> z_order_ >> opacity >> anchor_
- >> size_ >> transform;
+ (*deserializer) >> visible_ >> update_pausing_ >> cascade_opacity_ >> z_order_ >> opacity >> anchor_ >> size_
+ >> transform;
SetOpacity(opacity);
SetTransform(transform);
@@ -248,49 +245,6 @@ bool Actor::HandleEvent(Event* evt)
if (!EventDispatcher::DispatchEvent(evt))
return false;
-
- if (responsible_)
- {
- if (evt->IsType())
- {
- auto mouse_evt = dynamic_cast(evt);
- bool contains = ContainsPoint(mouse_evt->pos);
- if (!hover_ && contains)
- {
- hover_ = true;
-
- MouseHoverEventPtr hover = new MouseHoverEvent;
- hover->pos = mouse_evt->pos;
- HandleEvent(hover.Get());
- }
- else if (hover_ && !contains)
- {
- hover_ = false;
- pressed_ = false;
-
- MouseOutEventPtr out = new MouseOutEvent;
- out->pos = mouse_evt->pos;
- HandleEvent(out.Get());
- }
- }
-
- if (evt->IsType() && hover_)
- {
- pressed_ = true;
- }
-
- if (evt->IsType() && pressed_)
- {
- pressed_ = false;
-
- auto mouse_up_evt = dynamic_cast(evt);
-
- MouseClickEventPtr click = new MouseClickEvent;
- click->pos = mouse_up_evt->pos;
- click->button = mouse_up_evt->button;
- HandleEvent(click.Get());
- }
- }
return true;
}
@@ -660,11 +614,6 @@ void Actor::RemoveAllChildren()
children_.Clear();
}
-void Actor::SetResponsible(bool enable)
-{
- responsible_ = enable;
-}
-
bool Actor::ContainsPoint(const Point& point) const
{
if (size_.x == 0.f || size_.y == 0.f)
diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h
index 90d79a7a..324c6d24 100644
--- a/src/kiwano/2d/Actor.h
+++ b/src/kiwano/2d/Actor.h
@@ -98,10 +98,6 @@ public:
/// @brief 获取显示状态
bool IsVisible() const;
- /// \~chinese
- /// @brief 获取响应状态
- bool IsResponsible() const;
-
/// \~chinese
/// @brief 是否启用级联透明度
bool IsCascadeOpacityEnabled() const;
@@ -334,11 +330,6 @@ public:
/// @brief 设置 Z 轴顺序,默认为 0
void SetZOrder(int zorder);
- /// \~chinese
- /// @brief 设置角色是否可响应,默认为 false
- /// @details 可响应的角色会收到鼠标的 Hover | Out | Click 消息
- void SetResponsible(bool enable);
-
/// \~chinese
/// @brief 添加子角色
void AddChild(ActorPtr child);
@@ -425,6 +416,11 @@ public:
/// @return 是否继续分发该事件
virtual bool DispatchEvent(Event* evt);
+ /// \~chinese
+ /// @brief 处理事件且不分发
+ /// @param evt 事件
+ bool HandleEvent(Event* evt);
+
/// \~chinese
/// @brief 开启或关闭事件分发功能
/// @param enabled 是否开启
@@ -483,10 +479,6 @@ protected:
/// @brief 设置节点所在舞台
void SetStage(Stage* stage);
- /// \~chinese
- /// @brief 处理事件
- bool HandleEvent(Event* evt);
-
/// \~chinese
/// @brief 设置物理身体
void SetPhysicBody(physics::PhysicBody* body);
@@ -498,9 +490,6 @@ private:
bool update_pausing_;
bool cascade_opacity_;
bool show_border_;
- bool hover_;
- bool pressed_;
- bool responsible_;
bool evt_dispatch_enabled_;
mutable bool visible_in_rt_;
@@ -549,11 +538,6 @@ inline bool Actor::IsVisible() const
return visible_;
}
-inline bool Actor::IsResponsible() const
-{
- return responsible_;
-}
-
inline bool Actor::IsCascadeOpacityEnabled() const
{
return cascade_opacity_;
diff --git a/src/kiwano/2d/DebugActor.cpp b/src/kiwano/2d/DebugActor.cpp
index 5c0cf791..361f061e 100644
--- a/src/kiwano/2d/DebugActor.cpp
+++ b/src/kiwano/2d/DebugActor.cpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#pragma comment(lib, "psapi.lib")
@@ -49,9 +50,11 @@ DebugActor::DebugActor()
{
SetName("kiwano-debug-actor");
SetPosition(Point{ 10, 10 });
- SetResponsible(true);
SetCascadeOpacityEnabled(true);
+ MouseSensorPtr sensor = new MouseSensor;
+ this->AddComponent(sensor);
+
comma_locale_ = std::locale(std::locale(), new comma_numpunct);
background_brush_ = MakePtr();
diff --git a/src/kiwano/base/component/Button.cpp b/src/kiwano/base/component/Button.cpp
index d7f803f4..c7314b88 100644
--- a/src/kiwano/base/component/Button.cpp
+++ b/src/kiwano/base/component/Button.cpp
@@ -24,7 +24,6 @@ namespace kiwano
{
ButtonBase::ButtonBase()
- : status_(Status::Normal)
{
SetName("__KGE_BUTTON__");
}
@@ -33,41 +32,25 @@ ButtonBase::~ButtonBase()
{
}
-void ButtonBase::InitComponent(Actor* actor)
-{
- Component::InitComponent(actor);
- if (actor)
- {
- actor->SetResponsible(true);
- }
-}
-
-void ButtonBase::DestroyComponent()
-{
- Component::DestroyComponent();
-}
-
void ButtonBase::HandleEvent(kiwano::Event* evt)
{
+ MouseSensor::HandleEvent(evt);
+
if (evt->IsType())
{
OnEvent(Event::MouseEntered);
- status_ = Status::Hover;
}
else if (evt->IsType())
{
OnEvent(Event::MouseExited);
- status_ = Status::Normal;
}
- else if (evt->IsType() && status_ == Status::Hover)
+ else if (evt->IsType() && this->IsHovering())
{
OnEvent(Event::Pressed);
- status_ = Status::Pressed;
}
- else if (evt->IsType() && status_ == Status::Pressed)
+ else if (evt->IsType() && this->IsPressing())
{
OnEvent(Event::Released);
- status_ = Status::Hover;
}
else if (evt->IsType())
{
diff --git a/src/kiwano/base/component/Button.h b/src/kiwano/base/component/Button.h
index 8adebf37..5a616c02 100644
--- a/src/kiwano/base/component/Button.h
+++ b/src/kiwano/base/component/Button.h
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include
+#include
namespace kiwano
{
@@ -35,7 +35,7 @@ KGE_DECLARE_SMART_PTR(Button);
* \~chinese
* @brief 基础按钮组件
*/
-class KGE_API ButtonBase : public Component
+class KGE_API ButtonBase : public MouseSensor
{
public:
/// \~chinese
@@ -58,25 +58,9 @@ public:
virtual void OnEvent(Event evt) = 0;
protected:
- /// \~chinese
- /// @brief 初始化组件
- void InitComponent(Actor* actor) override;
-
- /// \~chinese
- /// @brief 销毁组件
- void DestroyComponent() override;
-
/// \~chinese
/// @brief 处理角色事件
void HandleEvent(kiwano::Event* evt) override;
-
-private:
- enum class Status
- {
- Normal,
- Hover,
- Pressed
- } status_;
};
/**
diff --git a/src/kiwano/base/component/ComponentManager.cpp b/src/kiwano/base/component/ComponentManager.cpp
index a0d3dbb7..392c4b43 100644
--- a/src/kiwano/base/component/ComponentManager.cpp
+++ b/src/kiwano/base/component/ComponentManager.cpp
@@ -124,14 +124,11 @@ void ComponentManager::Update(Duration dt)
{
if (!components_.empty())
{
- if (!components_.empty())
+ for (auto& p : components_)
{
- for (auto& p : components_)
+ if (p.second->IsEnable())
{
- if (p.second->IsEnable())
- {
- p.second->OnUpdate(dt);
- }
+ p.second->OnUpdate(dt);
}
}
}
@@ -141,14 +138,11 @@ void ComponentManager::Render(RenderContext& ctx)
{
if (!components_.empty())
{
- if (!components_.empty())
+ for (auto& p : components_)
{
- for (auto& p : components_)
+ if (p.second->IsEnable())
{
- if (p.second->IsEnable())
- {
- p.second->OnRender(ctx);
- }
+ p.second->OnRender(ctx);
}
}
}
@@ -158,14 +152,11 @@ void ComponentManager::DispatchToComponents(Event* evt)
{
if (!components_.empty())
{
- if (!components_.empty())
+ for (auto& p : components_)
{
- for (auto& p : components_)
+ if (p.second->IsEnable())
{
- if (p.second->IsEnable())
- {
- p.second->HandleEvent(evt);
- }
+ p.second->HandleEvent(evt);
}
}
}
diff --git a/src/kiwano/base/component/MouseSensor.cpp b/src/kiwano/base/component/MouseSensor.cpp
new file mode 100644
index 00000000..5da183d2
--- /dev/null
+++ b/src/kiwano/base/component/MouseSensor.cpp
@@ -0,0 +1,78 @@
+// 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.
+
+#include
+#include
+
+namespace kiwano
+{
+MouseSensor::MouseSensor()
+ : hover_(false)
+ , pressed_(false)
+{
+}
+
+MouseSensor::~MouseSensor() {}
+
+void MouseSensor::HandleEvent(Event* evt)
+{
+ Actor* target = GetBoundActor();
+ if (evt->IsType())
+ {
+ auto mouse_evt = dynamic_cast(evt);
+ bool contains = target->ContainsPoint(mouse_evt->pos);
+ if (!hover_ && contains)
+ {
+ hover_ = true;
+
+ MouseHoverEventPtr hover = new MouseHoverEvent;
+ hover->pos = mouse_evt->pos;
+ target->HandleEvent(hover.Get());
+ }
+ else if (hover_ && !contains)
+ {
+ hover_ = false;
+ pressed_ = false;
+
+ MouseOutEventPtr out = new MouseOutEvent;
+ out->pos = mouse_evt->pos;
+ target->HandleEvent(out.Get());
+ }
+ }
+
+ if (evt->IsType() && hover_)
+ {
+ pressed_ = true;
+ }
+
+ if (evt->IsType() && pressed_)
+ {
+ pressed_ = false;
+
+ auto mouse_up_evt = dynamic_cast(evt);
+
+ MouseClickEventPtr click = new MouseClickEvent;
+ click->pos = mouse_up_evt->pos;
+ click->button = mouse_up_evt->button;
+ target->HandleEvent(click.Get());
+ }
+}
+
+} // namespace kiwano
diff --git a/src/kiwano/base/component/MouseSensor.h b/src/kiwano/base/component/MouseSensor.h
new file mode 100644
index 00000000..ce366ed8
--- /dev/null
+++ b/src/kiwano/base/component/MouseSensor.h
@@ -0,0 +1,77 @@
+// 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
+
+namespace kiwano
+{
+
+KGE_DECLARE_SMART_PTR(MouseSensor);
+
+/**
+ * \addtogroup Component
+ * @{
+ */
+
+/**
+ * \~chinese
+ * @brief 鼠标传感器
+ * @details 该组件使角色会收到鼠标的 Hover | Out | Click 消息
+ */
+class KGE_API MouseSensor : public Component
+{
+public:
+ MouseSensor();
+
+ virtual ~MouseSensor();
+
+ /// \~chinese
+ /// @brief 鼠标是否正悬于角色上
+ bool IsHovering() const;
+
+ /// \~chinese
+ /// @brief 鼠标是否正按于角色上
+ bool IsPressing() const;
+
+protected:
+ /// \~chinese
+ /// @brief 处理角色事件
+ void HandleEvent(Event* evt) override;
+
+private:
+ bool hover_;
+ bool pressed_;
+};
+
+/** @} */
+
+inline bool MouseSensor::IsHovering() const
+{
+ return hover_;
+}
+
+inline bool MouseSensor::IsPressing() const
+{
+ return pressed_;
+}
+
+} // namespace kiwano
diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h
index 4b7c65b2..111fbecd 100644
--- a/src/kiwano/kiwano.h
+++ b/src/kiwano/kiwano.h
@@ -49,18 +49,6 @@
#include
#include
-//
-// base
-//
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
//
// event
@@ -73,6 +61,19 @@
#include
#include
+//
+// base
+//
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
//
// renderer
//