Add component

This commit is contained in:
Nomango 2020-02-18 12:53:18 +08:00
parent f319f47d38
commit 9077c55b9c
19 changed files with 429 additions and 254 deletions

View File

@ -10,6 +10,7 @@
<ClInclude Include="..\..\src\kiwano\2d\action\ActionTween.h" /> <ClInclude Include="..\..\src\kiwano\2d\action\ActionTween.h" />
<ClInclude Include="..\..\src\kiwano\2d\action\Animation.h" /> <ClInclude Include="..\..\src\kiwano\2d\action\Animation.h" />
<ClInclude Include="..\..\src\kiwano\2d\Button.h" /> <ClInclude Include="..\..\src\kiwano\2d\Button.h" />
<ClInclude Include="..\..\src\kiwano\2d\Component.h" />
<ClInclude Include="..\..\src\kiwano\2d\Frame.h" /> <ClInclude Include="..\..\src\kiwano\2d\Frame.h" />
<ClInclude Include="..\..\src\kiwano\2d\GifSprite.h" /> <ClInclude Include="..\..\src\kiwano\2d\GifSprite.h" />
<ClInclude Include="..\..\src\kiwano\core\Any.h" /> <ClInclude Include="..\..\src\kiwano\core\Any.h" />
@ -111,6 +112,7 @@
<ClCompile Include="..\..\src\kiwano\2d\action\Animation.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\action\Animation.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Button.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\Button.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Component.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\DebugActor.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\DebugActor.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Frame.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\Frame.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\FrameSequence.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\FrameSequence.cpp" />

View File

@ -324,6 +324,9 @@
<ClInclude Include="..\..\src\kiwano\render\ShapeMaker.h"> <ClInclude Include="..\..\src\kiwano\render\ShapeMaker.h">
<Filter>render</Filter> <Filter>render</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\Component.h">
<Filter>2d</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp"> <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
@ -539,5 +542,8 @@
<ClCompile Include="..\..\src\kiwano\render\ShapeMaker.cpp"> <ClCompile Include="..\..\src\kiwano\render\ShapeMaker.cpp">
<Filter>render</Filter> <Filter>render</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\Component.cpp">
<Filter>2d</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -189,8 +189,14 @@ void ImGuiModule::UpdateMouseCursor()
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return; return;
static ImGuiMouseCursor last_cursor = ImGuiMouseCursor_None;
if (ImGui::GetMouseCursor() == last_cursor)
return;
last_cursor = ImGui::GetMouseCursor();
CursorType cursor = CursorType::Arrow; CursorType cursor = CursorType::Arrow;
switch (ImGui::GetMouseCursor()) switch (last_cursor)
{ {
case ImGuiMouseCursor_Arrow: case ImGuiMouseCursor_Arrow:
cursor = CursorType::Arrow; cursor = CursorType::Arrow;

View File

@ -199,11 +199,9 @@ bool Actor::DispatchEvent(Event* evt)
child = child->GetPrev(); child = child->GetPrev();
} }
if (!EventDispatcher::DispatchEvent(evt)) if (!HandleEvent(evt))
return false; return false;
HandleEvent(evt);
while (child) while (child)
{ {
if (!child->DispatchEvent(evt)) if (!child->DispatchEvent(evt))
@ -214,8 +212,22 @@ bool Actor::DispatchEvent(Event* evt)
return true; return true;
} }
void Actor::HandleEvent(Event* evt) bool Actor::HandleEvent(Event* evt)
{ {
if (!components_.IsEmpty())
{
ComponentPtr next;
for (auto component = components_.GetFirst(); component; component = next)
{
next = component->GetNext();
component->HandleEvent(evt);
}
}
if (!EventDispatcher::DispatchEvent(evt))
return false;
if (responsible_) if (responsible_)
{ {
if (evt->IsType<MouseMoveEvent>()) if (evt->IsType<MouseMoveEvent>())
@ -228,7 +240,7 @@ void Actor::HandleEvent(Event* evt)
MouseHoverEventPtr hover = new MouseHoverEvent; MouseHoverEventPtr hover = new MouseHoverEvent;
hover->pos = mouse_evt->pos; hover->pos = mouse_evt->pos;
EventDispatcher::DispatchEvent(hover.Get()); HandleEvent(hover.Get());
} }
else if (hover_ && !contains) else if (hover_ && !contains)
{ {
@ -237,7 +249,7 @@ void Actor::HandleEvent(Event* evt)
MouseOutEventPtr out = new MouseOutEvent; MouseOutEventPtr out = new MouseOutEvent;
out->pos = mouse_evt->pos; out->pos = mouse_evt->pos;
EventDispatcher::DispatchEvent(out.Get()); HandleEvent(out.Get());
} }
} }
@ -255,9 +267,10 @@ void Actor::HandleEvent(Event* evt)
MouseClickEventPtr click = new MouseClickEvent; MouseClickEventPtr click = new MouseClickEvent;
click->pos = mouse_up_evt->pos; click->pos = mouse_up_evt->pos;
click->button = mouse_up_evt->button; click->button = mouse_up_evt->button;
EventDispatcher::DispatchEvent(click.Get()); HandleEvent(click.Get());
} }
} }
return true;
} }
const Matrix3x2& Actor::GetTransformMatrix() const const Matrix3x2& Actor::GetTransformMatrix() const
@ -405,16 +418,6 @@ void Actor::SetAnchor(Vec2 const& anchor)
dirty_transform_ = true; dirty_transform_ = true;
} }
void Actor::SetWidth(float width)
{
SetSize(Size{ width, size_.y });
}
void Actor::SetHeight(float height)
{
SetSize(Size{ size_.x, height });
}
void Actor::SetSize(Size const& size) void Actor::SetSize(Size const& size)
{ {
if (size_ == size) if (size_ == size)
@ -454,21 +457,6 @@ void Actor::SetPosition(const Point& pos)
dirty_transform_ = true; dirty_transform_ = true;
} }
void Actor::SetPositionX(float x)
{
SetPosition(Point{ x, transform_.position.y });
}
void Actor::SetPositionY(float y)
{
SetPosition(Point{ transform_.position.x, y });
}
void Actor::Move(Vec2 const& v)
{
this->SetPosition(Point{ transform_.position.x + v.x, transform_.position.y + v.y });
}
void Actor::SetScale(Vec2 const& scale) void Actor::SetScale(Vec2 const& scale)
{ {
if (transform_.scale == scale) if (transform_.scale == scale)
@ -583,12 +571,12 @@ ActorPtr Actor::GetChild(String const& name) const
return nullptr; return nullptr;
} }
Actor::Children& Actor::GetAllChildren() ActorList& Actor::GetAllChildren()
{ {
return children_; return children_;
} }
Actor::Children const& Actor::GetAllChildren() const ActorList const& Actor::GetAllChildren() const
{ {
return children_; return children_;
} }
@ -601,6 +589,54 @@ void Actor::RemoveFromParent()
} }
} }
Component* Actor::AddComponent(ComponentPtr component)
{
return this->AddComponent(component.Get());
}
Component* Actor::AddComponent(Component* component)
{
KGE_ASSERT(component && "AddComponent failed, NULL pointer exception");
if (component)
{
components_.PushBack(component);
}
return component;
}
ComponentList& Actor::GetAllComponents()
{
return components_;
}
const ComponentList& Actor::GetAllComponents() const
{
return components_;
}
void Actor::RemoveComponents(String const& name)
{
if (!components_.IsEmpty())
{
ComponentPtr next;
for (auto component = components_.GetFirst(); component; component = next)
{
next = component->GetNext();
if (component->IsName(name))
{
components_.Remove(component);
}
}
}
}
void Actor::RemoveAllComponents()
{
components_.Clear();
}
void Actor::RemoveChild(ActorPtr child) void Actor::RemoveChild(ActorPtr child)
{ {
RemoveChild(child.Get()); RemoveChild(child.Get());

View File

@ -19,13 +19,13 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/2d/action/ActionManager.h>
#include <kiwano/core/EventDispatcher.h>
#include <kiwano/core/ObjectBase.h> #include <kiwano/core/ObjectBase.h>
#include <kiwano/core/Time.h> #include <kiwano/core/Time.h>
#include <kiwano/core/TimerManager.h> #include <kiwano/core/TimerManager.h>
#include <kiwano/core/IntrusiveList.h> #include <kiwano/core/EventDispatcher.h>
#include <kiwano/math/Math.h> #include <kiwano/math/Math.h>
#include <kiwano/2d/action/ActionManager.h>
#include <kiwano/2d/Component.h>
namespace kiwano namespace kiwano
{ {
@ -35,6 +35,11 @@ class RenderContext;
KGE_DECLARE_SMART_PTR(Actor); KGE_DECLARE_SMART_PTR(Actor);
/// \~chinese
/// @brief 角色列表
typedef IntrusiveList<ActorPtr> ActorList;
/** /**
* \~chinese * \~chinese
* \defgroup Actors * \defgroup Actors
@ -63,13 +68,9 @@ class KGE_API Actor
friend IntrusiveList<ActorPtr>; friend IntrusiveList<ActorPtr>;
public: public:
/// \~chinese
/// @brief 子成员列表
using Children = IntrusiveList<ActorPtr>;
/// \~chinese /// \~chinese
/// @brief 角色更新回调函数 /// @brief 角色更新回调函数
using UpdateCallback = Function<void(Duration)>; typedef Function<void(Duration)> UpdateCallback;
/// \~chinese /// \~chinese
/// @brief 创建角色 /// @brief 创建角色
@ -343,11 +344,11 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取全部子角色 /// @brief 获取全部子角色
Children& GetAllChildren(); ActorList& GetAllChildren();
/// \~chinese /// \~chinese
/// @brief 获取全部子角色 /// @brief 获取全部子角色
Children const& GetAllChildren() const; ActorList const& GetAllChildren() const;
/// \~chinese /// \~chinese
/// @brief 移除子角色 /// @brief 移除子角色
@ -369,6 +370,33 @@ public:
/// @brief 从父角色移除 /// @brief 从父角色移除
void RemoveFromParent(); void RemoveFromParent();
/// \~chinese
/// @brief 添加组件
/// @param component 组件
Component* AddComponent(ComponentPtr component);
/// \~chinese
/// @brief 添加组件
/// @param component 组件
Component* AddComponent(Component* component);
/// \~chinese
/// @brief 获取所有组件
ComponentList& GetAllComponents();
/// \~chinese
/// @brief 获取所有组件
const ComponentList& GetAllComponents() const;
/// \~chinese
/// @brief 移除组件
/// @param name 组件名称
void RemoveComponents(String const& name);
/// \~chinese
/// @brief 移除所有组件
void RemoveAllComponents();
/// \~chinese /// \~chinese
/// @brief 暂停角色更新 /// @brief 暂停角色更新
void PauseUpdating(); void PauseUpdating();
@ -446,7 +474,7 @@ protected:
/// \~chinese /// \~chinese
/// @brief 处理事件 /// @brief 处理事件
void HandleEvent(Event* evt); bool HandleEvent(Event* evt);
private: private:
bool visible_; bool visible_;
@ -464,7 +492,8 @@ private:
size_t hash_name_; size_t hash_name_;
Point anchor_; Point anchor_;
Size size_; Size size_;
Children children_; ActorList children_;
ComponentList components_;
UpdateCallback cb_update_; UpdateCallback cb_update_;
Transform transform_; Transform transform_;
@ -666,32 +695,57 @@ inline void Actor::ShowBorder(bool show)
inline void Actor::SetPosition(float x, float y) inline void Actor::SetPosition(float x, float y)
{ {
SetPosition(Point{ x, y }); this->SetPosition(Point(x, y));
}
inline void Actor::SetPositionX(float x)
{
this->SetPosition(Point(x, transform_.position.y));
}
inline void Actor::SetPositionY(float y)
{
this->SetPosition(Point(transform_.position.x, y));
}
inline void Actor::Move(Vec2 const& v)
{
this->SetPosition(transform_.position.x + v.x, transform_.position.y + v.y);
} }
inline void Actor::Move(float vx, float vy) inline void Actor::Move(float vx, float vy)
{ {
Move(Vec2{ vx, vy }); this->Move(Vec2(vx, vy));
} }
inline void Actor::SetScale(float scalex, float scaley) inline void Actor::SetScale(float scalex, float scaley)
{ {
SetScale(Vec2{ scalex, scaley }); this->SetScale(Vec2(scalex, scaley));
} }
inline void Actor::SetAnchor(float anchorx, float anchory) inline void Actor::SetAnchor(float anchorx, float anchory)
{ {
SetAnchor(Vec2{ anchorx, anchory }); this->SetAnchor(Vec2(anchorx, anchory));
} }
inline void Actor::SetSize(float width, float height) inline void Actor::SetSize(float width, float height)
{ {
SetSize(Size{ width, height }); this->SetSize(Size(width, height));
}
inline void Actor::SetWidth(float width)
{
this->SetSize(Size(width, size_.y));
}
inline void Actor::SetHeight(float height)
{
this->SetSize(Size(size_.x, height));
} }
inline void Actor::SetSkew(float skewx, float skewy) inline void Actor::SetSkew(float skewx, float skewy)
{ {
SetSkew(Vec2{ skewx, skewy }); this->SetSkew(Vec2(skewx, skewy));
} }
} // namespace kiwano } // namespace kiwano

View File

@ -24,13 +24,37 @@
namespace kiwano namespace kiwano
{ {
ButtonPtr Button::Create(ActorPtr actor, Callback const& click)
{
return Button::Create(actor, click, nullptr, nullptr, nullptr);
}
ButtonPtr Button::Create(ActorPtr actor, Callback const& click, Callback const& pressed, Callback const& mouse_over,
Callback const& mouse_out)
{
ButtonPtr ptr = new (std::nothrow) Button;
if (ptr)
{
ptr->BindActor(actor);
ptr->SetClickCallback(click);
ptr->SetPressedCallback(pressed);
ptr->SetMouseOverCallback(mouse_over);
ptr->SetMouseOutCallback(mouse_out);
}
return ptr;
}
Button::Button() Button::Button()
: enabled_(true) : enabled_(true)
, status_(Status::Normal) , status_(Status::Normal)
{ {
} }
Button::~Button() {} Button::~Button()
{
Unbind();
}
bool Button::IsEnable() const bool Button::IsEnable() const
{ {
@ -65,6 +89,11 @@ void Button::SetMouseOutCallback(const Callback& func)
mouse_out_callback_ = func; mouse_out_callback_ = func;
} }
Button::Status Button::GetStatus() const
{
return status_;
}
void Button::SetStatus(Status status) void Button::SetStatus(Status status)
{ {
if (status_ != status) if (status_ != status)
@ -76,7 +105,7 @@ void Button::SetStatus(Status status)
Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Arrow); Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Arrow);
if (mouse_out_callback_) if (mouse_out_callback_)
mouse_out_callback_(this); mouse_out_callback_(this, actor_);
} }
else if (status == Status::Hover) else if (status == Status::Hover)
{ {
@ -85,25 +114,20 @@ void Button::SetStatus(Status status)
if (old_status != Status::Pressed) if (old_status != Status::Pressed)
{ {
if (mouse_over_callback_) if (mouse_over_callback_)
mouse_over_callback_(this); mouse_over_callback_(this, actor_);
} }
} }
else if (status == Status::Pressed) else if (status == Status::Pressed)
{ {
if (pressed_callback_) if (pressed_callback_)
pressed_callback_(this); pressed_callback_(this, actor_);
} }
status_ = status; status_ = status;
} }
} }
Button::Status Button::GetStatus() const void Button::HandleEvent(Event* evt)
{
return status_;
}
void Button::UpdateStatus(Event* evt)
{ {
if (!enabled_) if (!enabled_)
return; return;
@ -127,78 +151,17 @@ void Button::UpdateStatus(Event* evt)
else if (evt->IsType<MouseClickEvent>()) else if (evt->IsType<MouseClickEvent>())
{ {
if (click_callback_) if (click_callback_)
click_callback_(this); click_callback_(this, actor_);
} }
} }
void Button::BindActor(Actor* actor) void Button::BindActor(Actor* actor)
{ {
actor->SetResponsible(true); Component::BindActor(actor);
if (actor)
EventListener::Callback handler = Closure(this, &Button::UpdateStatus);
actor->AddListener<MouseHoverEvent>(handler);
actor->AddListener<MouseOutEvent>(handler);
actor->AddListener<MouseDownEvent>(handler);
actor->AddListener<MouseUpEvent>(handler);
actor->AddListener<MouseClickEvent>(handler);
}
SpriteButton::SpriteButton()
{
BindActor(this);
}
SpriteButtonPtr SpriteButton::Create(Callback const& click)
{
SpriteButtonPtr ptr = new (std::nothrow) SpriteButton;
if (ptr)
{ {
ptr->SetClickCallback(click); actor->SetResponsible(true);
} }
return ptr;
}
SpriteButtonPtr SpriteButton::Create(Callback const& click, Callback const& pressed, Callback const& mouse_over,
Callback const& mouse_out)
{
SpriteButtonPtr ptr = new (std::nothrow) SpriteButton;
if (ptr)
{
ptr->SetClickCallback(click);
ptr->SetPressedCallback(pressed);
ptr->SetMouseOverCallback(mouse_over);
ptr->SetMouseOutCallback(mouse_out);
}
return ptr;
}
TextButton::TextButton()
{
BindActor(this);
}
TextButtonPtr TextButton::Create(Callback const& click)
{
TextButtonPtr ptr = new (std::nothrow) TextButton;
if (ptr)
{
ptr->SetClickCallback(click);
}
return ptr;
}
TextButtonPtr TextButton::Create(Callback const& click, Callback const& pressed, Callback const& mouse_over,
Callback const& mouse_out)
{
TextButtonPtr ptr = new (std::nothrow) TextButton;
if (ptr)
{
ptr->SetClickCallback(click);
ptr->SetPressedCallback(pressed);
ptr->SetMouseOverCallback(mouse_over);
ptr->SetMouseOutCallback(mouse_out);
}
return ptr;
} }
} // namespace kiwano } // namespace kiwano

View File

@ -19,25 +19,39 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/2d/Sprite.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/TextActor.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Button); KGE_DECLARE_SMART_PTR(Button);
KGE_DECLARE_SMART_PTR(SpriteButton);
KGE_DECLARE_SMART_PTR(TextButton);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Button : public virtual ObjectBase class KGE_API Button : public Component
{ {
public: public:
/// \~chinese /// \~chinese
/// @brief 按钮回调函数 /// @brief 按钮回调函数
using Callback = Function<void(Button* /* self */)>; using Callback = Function<void(Button* /* self */, Actor* /* target */)>;
/// \~chinese
/// @brief 创建按钮
/// @param actor 绑定的角色
/// @param click 按钮点击回调函数
static ButtonPtr Create(ActorPtr actor, Callback const& click);
/// \~chinese
/// @brief 创建按钮
/// @param actor 绑定的角色
/// @param click 按钮点击回调函数
/// @param pressed 按钮按下回调函数
/// @param mouse_over 按钮移入回调函数
/// @param mouse_out 按钮移出回调函数
static ButtonPtr Create(ActorPtr actor, Callback const& click, Callback const& pressed, Callback const& mouse_over,
Callback const& mouse_out);
Button(); Button();
@ -67,6 +81,15 @@ public:
/// @brief 设置鼠标移出按钮时的回调函数 /// @brief 设置鼠标移出按钮时的回调函数
void SetMouseOutCallback(const Callback& func); void SetMouseOutCallback(const Callback& func);
/// \~chinese
/// @brief 绑定到角色
void BindActor(ActorPtr actor);
/// \~chinese
/// @brief 绑定到角色
void BindActor(Actor* actor) override;
protected:
/// \~chinese /// \~chinese
/// @brief 按钮状态 /// @brief 按钮状态
enum class Status enum class Status
@ -76,22 +99,17 @@ public:
Pressed ///< 被按下 Pressed ///< 被按下
}; };
/// \~chinese
/// @brief 获取按钮状态
Status GetStatus() const;
/// \~chinese /// \~chinese
/// @brief 设置按钮状态 /// @brief 设置按钮状态
void SetStatus(Status status); void SetStatus(Status status);
/// \~chinese /// \~chinese
/// @brief 获取按钮状态 /// @brief 处理角色事件
Status GetStatus() const; void HandleEvent(Event* evt) override;
protected:
/// \~chinese
/// @brief 更新按钮状态
void UpdateStatus(Event* evt);
/// \~chinese
/// @brief 绑定到角色
void BindActor(Actor* actor);
private: private:
bool enabled_; bool enabled_;
@ -102,51 +120,9 @@ private:
Callback mouse_out_callback_; Callback mouse_out_callback_;
}; };
/// \~chinese inline void Button::BindActor(ActorPtr actor)
/// @brief 精灵按钮
class SpriteButton
: public Sprite
, public Button
{ {
public: this->BindActor(actor.Get());
SpriteButton(); }
/// \~chinese
/// @brief 创建精灵按钮
/// @param click 按钮点击回调函数
static SpriteButtonPtr Create(Callback const& click);
/// \~chinese
/// @brief 创建精灵按钮
/// @param click 按钮点击回调函数
/// @param pressed 按钮按下回调函数
/// @param mouse_over 按钮移入回调函数
/// @param mouse_out 按钮移出回调函数
static SpriteButtonPtr Create(Callback const& click, Callback const& pressed, Callback const& mouse_over,
Callback const& mouse_out);
};
/// \~chinese
/// @brief 文字按钮
class TextButton
: public TextActor
, public Button
{
public:
TextButton();
/// \~chinese
/// @brief 创建文字按钮
/// @param click 按钮点击回调函数
static TextButtonPtr Create(Callback const& click);
/// \~chinese
/// @brief 创建文字按钮
/// @param click 按钮点击回调函数
/// @param pressed 按钮按下回调函数
/// @param mouse_over 按钮移入回调函数
/// @param mouse_out 按钮移出回调函数
static TextButtonPtr Create(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out);
};
} // namespace kiwano } // namespace kiwano

View File

@ -0,0 +1,50 @@
// 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 <kiwano/2d/Component.h>
namespace kiwano
{
Component::Component()
: actor_(nullptr)
{
}
Component::~Component()
{
Unbind();
}
void Component::BindActor(Actor* actor)
{
if (actor_)
{
Unbind();
}
actor_ = actor;
}
void Component::Unbind()
{
actor_ = nullptr;
}
} // namespace kiwano

84
src/kiwano/2d/Component.h Normal file
View File

@ -0,0 +1,84 @@
// 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 <kiwano/core/ObjectBase.h>
#include <kiwano/core/IntrusiveList.h>
namespace kiwano
{
class Actor;
class Event;
KGE_DECLARE_SMART_PTR(Component);
/// \~chinese
/// @brief 组件列表
typedef IntrusiveList<ComponentPtr> ComponentList;
/**
* \~chinese
* @brief
*/
class KGE_API Component
: public virtual ObjectBase
, protected IntrusiveListValue<ComponentPtr>
{
friend class Actor;
friend IntrusiveList<ComponentPtr>;
public:
/// \~chinese
/// @brief 绑定到角色
virtual void BindActor(Actor* actor);
/// \~chinese
/// @brief 取消绑定到角色
virtual void Unbind();
/// \~chinese
/// @brief 获取绑定的角色
Actor* GetBoundActor() const;
protected:
Component();
virtual ~Component();
/// \~chinese
/// @brief 处理角色事件
virtual void HandleEvent(Event* evt);
protected:
Actor* actor_;
};
inline Actor* Component::GetBoundActor() const
{
return actor_;
}
inline void Component::HandleEvent(Event* event)
{
KGE_NOT_USED(event);
}
} // namespace kiwano

View File

@ -67,43 +67,6 @@ Size TextActor::GetSize() const
return Actor::GetSize(); return Actor::GetSize();
} }
void TextActor::SetFillColor(Color const& color)
{
BrushPtr brush = layout_->GetDefaultFillBrush();
if (brush)
{
brush->SetColor(color);
}
else
{
layout_->SetDefaultFillBrush(Brush::Create(color));
}
}
void TextActor::SetOutlineColor(Color const& outline_color)
{
BrushPtr brush = layout_->GetDefaultOutlineBrush();
if (brush)
{
brush->SetColor(outline_color);
}
else
{
layout_->SetDefaultOutlineBrush(Brush::Create(outline_color));
}
}
void TextActor::SetTextLayout(TextLayoutPtr layout)
{
KGE_ASSERT(layout && "TextLayout must not be nullptr");
if (layout_ != layout)
{
layout_ = layout;
ForceUpdateLayout();
}
}
void TextActor::SetText(String const& text) void TextActor::SetText(String const& text)
{ {
layout_->Reset(text, style_); layout_->Reset(text, style_);
@ -232,6 +195,41 @@ void TextActor::SetOutlineStrokeStyle(StrokeStylePtr stroke)
} }
} }
void TextActor::SetFillColor(Color const& color)
{
if (style_.fill_brush)
{
style_.fill_brush->SetColor(color);
}
else
{
SetFillBrush(Brush::Create(color));
}
}
void TextActor::SetOutlineColor(Color const& outline_color)
{
if (style_.outline_brush)
{
style_.outline_brush->SetColor(outline_color);
}
else
{
SetFillBrush(Brush::Create(outline_color));
}
}
void TextActor::SetTextLayout(TextLayoutPtr layout)
{
KGE_ASSERT(layout && "TextLayout must not be nullptr");
if (layout_ != layout)
{
layout_ = layout;
ForceUpdateLayout();
}
}
void TextActor::Update(Duration dt) void TextActor::Update(Duration dt)
{ {
this->UpdateDirtyLayout(); this->UpdateDirtyLayout();

View File

@ -33,6 +33,10 @@ class ActionManager;
KGE_DECLARE_SMART_PTR(Action); KGE_DECLARE_SMART_PTR(Action);
/// \~chinese
/// @brief 动画列表
typedef IntrusiveList<ActionPtr> ActionList;
/** /**
* \~chinese * \~chinese
* \defgroup Actions * \defgroup Actions

View File

@ -103,7 +103,7 @@ ActionPtr ActionManager::GetAction(String const& name)
return nullptr; return nullptr;
} }
const ActionManager::Actions& ActionManager::GetAllActions() const const ActionList& ActionManager::GetAllActions() const
{ {
return actions_; return actions_;
} }

View File

@ -35,10 +35,6 @@ namespace kiwano
class KGE_API ActionManager class KGE_API ActionManager
{ {
public: public:
/// \~chinese
/// @brief 动画列表
using Actions = IntrusiveList<ActionPtr>;
/// \~chinese /// \~chinese
/// @brief 添加动画 /// @brief 添加动画
Action* AddAction(ActionPtr action); Action* AddAction(ActionPtr action);
@ -66,7 +62,7 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取所有动画 /// @brief 获取所有动画
Actions const& GetAllActions() const; const ActionList& GetAllActions() const;
protected: protected:
/// \~chinese /// \~chinese
@ -74,7 +70,7 @@ protected:
void UpdateActions(Actor* target, Duration dt); void UpdateActions(Actor* target, Duration dt);
private: private:
Actions actions_; ActionList actions_;
}; };
/** @} */ /** @} */

View File

@ -73,33 +73,33 @@ EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callb
return AddListener(listener); return AddListener(listener);
} }
void EventDispatcher::StartListeners(String const& listener_name) void EventDispatcher::StartListeners(String const& name)
{ {
for (auto& listener : listeners_) for (auto& listener : listeners_)
{ {
if (listener.IsName(listener_name)) if (listener.IsName(name))
{ {
listener.Start(); listener.Start();
} }
} }
} }
void EventDispatcher::StopListeners(String const& listener_name) void EventDispatcher::StopListeners(String const& name)
{ {
for (auto& listener : listeners_) for (auto& listener : listeners_)
{ {
if (listener.IsName(listener_name)) if (listener.IsName(name))
{ {
listener.Stop(); listener.Stop();
} }
} }
} }
void EventDispatcher::RemoveListeners(String const& listener_name) void EventDispatcher::RemoveListeners(String const& name)
{ {
for (auto& listener : listeners_) for (auto& listener : listeners_)
{ {
if (listener.IsName(listener_name)) if (listener.IsName(name))
{ {
listener.Remove(); listener.Remove();
} }
@ -163,7 +163,7 @@ void EventDispatcher::RemoveAllListeners()
} }
} }
const EventDispatcher::Listeners& EventDispatcher::GetAllListeners() const const ListenerList& EventDispatcher::GetAllListeners() const
{ {
return listeners_; return listeners_;
} }

View File

@ -30,10 +30,6 @@ namespace kiwano
class KGE_API EventDispatcher class KGE_API EventDispatcher
{ {
public: public:
/// \~chinese
/// @brief 监听器列表
using Listeners = IntrusiveList<EventListenerPtr>;
/// \~chinese /// \~chinese
/// @brief 添加监听器 /// @brief 添加监听器
EventListener* AddListener(EventListenerPtr listener); EventListener* AddListener(EventListenerPtr listener);
@ -120,7 +116,7 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取所有监听器 /// @brief 获取所有监听器
const Listeners& GetAllListeners() const; const ListenerList& GetAllListeners() const;
/// \~chinese /// \~chinese
/// @brief 分发事件 /// @brief 分发事件
@ -129,6 +125,6 @@ public:
bool DispatchEvent(Event* evt); bool DispatchEvent(Event* evt);
private: private:
Listeners listeners_; ListenerList listeners_;
}; };
} // namespace kiwano } // namespace kiwano

View File

@ -34,6 +34,10 @@ class EventDispatcher;
KGE_DECLARE_SMART_PTR(EventListener); KGE_DECLARE_SMART_PTR(EventListener);
/// \~chinese
/// @brief 监听器列表
typedef IntrusiveList<EventListenerPtr> ListenerList;
/** /**
* \~chinese * \~chinese
* @brief * @brief

View File

@ -29,6 +29,10 @@ class TimerManager;
KGE_DECLARE_SMART_PTR(Timer); KGE_DECLARE_SMART_PTR(Timer);
/// \~chinese
/// @brief 定时器列表
typedef IntrusiveList<TimerPtr> TimerList;
/// \~chinese /// \~chinese
/// @brief 定时器 /// @brief 定时器
/// @details 定时器用于每隔一段时间执行一次回调函数,且可以指定执行总次数 /// @details 定时器用于每隔一段时间执行一次回调函数,且可以指定执行总次数

View File

@ -133,7 +133,7 @@ void TimerManager::RemoveAllTimers()
timers_.Clear(); timers_.Clear();
} }
const TimerManager::Timers& TimerManager::GetAllTimers() const const TimerList& TimerManager::GetAllTimers() const
{ {
return timers_; return timers_;
} }

View File

@ -30,10 +30,6 @@ namespace kiwano
class KGE_API TimerManager class KGE_API TimerManager
{ {
public: public:
/// \~chinese
/// @brief 定时器列表
using Timers = IntrusiveList<TimerPtr>;
/// \~chinese /// \~chinese
/// @brief 添加定时器 /// @brief 添加定时器
/// @param cb 回调函数 /// @param cb 回调函数
@ -79,7 +75,7 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取所有定时器 /// @brief 获取所有定时器
const Timers& GetAllTimers() const; const TimerList& GetAllTimers() const;
protected: protected:
/// \~chinese /// \~chinese
@ -87,6 +83,6 @@ protected:
void UpdateTimers(Duration dt); void UpdateTimers(Duration dt);
private: private:
Timers timers_; TimerList timers_;
}; };
} // namespace kiwano } // namespace kiwano