refactoring Event distribution mechanism

This commit is contained in:
Nomango 2019-11-13 11:22:21 +08:00
parent 48d85a1e97
commit 09bc22de65
34 changed files with 831 additions and 639 deletions

View File

@ -13,7 +13,7 @@
<ItemGroup>
<ClInclude Include="..\..\src\kiwano-physics\Body.h" />
<ClInclude Include="..\..\src\kiwano-physics\Contact.h" />
<ClInclude Include="..\..\src\kiwano-physics\ContactListener.h" />
<ClInclude Include="..\..\src\kiwano-physics\ContactEvent.h" />
<ClInclude Include="..\..\src\kiwano-physics\Fixture.h" />
<ClInclude Include="..\..\src\kiwano-physics\helper.h" />
<ClInclude Include="..\..\src\kiwano-physics\Joint.h" />
@ -24,7 +24,7 @@
<ItemGroup>
<ClCompile Include="..\..\src\kiwano-physics\Body.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Contact.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\ContactListener.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\ContactEvent.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Fixture.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Joint.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Shape.cpp" />

View File

@ -9,7 +9,7 @@
<ClInclude Include="..\..\src\kiwano-physics\helper.h" />
<ClInclude Include="..\..\src\kiwano-physics\Fixture.h" />
<ClInclude Include="..\..\src\kiwano-physics\Contact.h" />
<ClInclude Include="..\..\src\kiwano-physics\ContactListener.h" />
<ClInclude Include="..\..\src\kiwano-physics\ContactEvent.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano-physics\Body.cpp" />
@ -18,6 +18,6 @@
<ClCompile Include="..\..\src\kiwano-physics\Shape.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Fixture.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Contact.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\ContactListener.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\ContactEvent.cpp" />
</ItemGroup>
</Project>

View File

@ -12,6 +12,7 @@
<ClInclude Include="..\..\src\kiwano\2d\Frame.h" />
<ClInclude Include="..\..\src\kiwano\2d\GifSprite.h" />
<ClInclude Include="..\..\src\kiwano\base\Director.h" />
<ClInclude Include="..\..\src\kiwano\base\Event.h" />
<ClInclude Include="..\..\src\kiwano\base\Library.h" />
<ClInclude Include="..\..\src\kiwano\base\win32\ComPtr.hpp" />
<ClInclude Include="..\..\src\kiwano\base\win32\helper.h" />
@ -43,7 +44,6 @@
<ClInclude Include="..\..\src\kiwano\2d\Transition.h" />
<ClInclude Include="..\..\src\kiwano\base\AsyncTask.h" />
<ClInclude Include="..\..\src\kiwano\base\Component.h" />
<ClInclude Include="..\..\src\kiwano\base\Event.hpp" />
<ClInclude Include="..\..\src\kiwano\base\EventDispatcher.h" />
<ClInclude Include="..\..\src\kiwano\base\EventListener.h" />
<ClInclude Include="..\..\src\kiwano\base\Input.h" />
@ -116,6 +116,7 @@
<ClCompile Include="..\..\src\kiwano\2d\Transition.cpp" />
<ClCompile Include="..\..\src\kiwano\base\AsyncTask.cpp" />
<ClCompile Include="..\..\src\kiwano\base\Component.cpp" />
<ClCompile Include="..\..\src\kiwano\base\Event.cpp" />
<ClCompile Include="..\..\src\kiwano\base\EventDispatcher.cpp" />
<ClCompile Include="..\..\src\kiwano\base\EventListener.cpp" />
<ClCompile Include="..\..\src\kiwano\base\Input.cpp" />

View File

@ -66,9 +66,6 @@
<ClInclude Include="..\..\src\kiwano\base\Component.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\base\Event.hpp">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\base\EventDispatcher.h">
<Filter>base</Filter>
</ClInclude>
@ -303,6 +300,9 @@
<ClInclude Include="..\..\src\kiwano\base\Library.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\base\Event.h">
<Filter>base</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp">
@ -482,5 +482,8 @@
<ClCompile Include="..\..\src\kiwano\base\Library.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\base\Event.cpp">
<Filter>base</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -23,6 +23,7 @@
#include <kiwano/base/Component.h>
#include <kiwano/base/win32/ComPtr.hpp>
#include <kiwano-audio/Transcoder.h>
#include <xaudio2.h>
namespace kiwano
{

View File

@ -22,8 +22,8 @@
#include <kiwano/core/intrusive_ptr.hpp>
#include <kiwano/base/ObjectBase.h>
#include <kiwano/base/Resource.h>
#include <xaudio2.h>
#include <kiwano-audio/Transcoder.h>
#include <xaudio2.h>
namespace kiwano
{

View File

@ -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 <kiwano-physics/ContactEvent.h>
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();
}
}
}

View File

@ -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 <kiwano-physics/Contact.h>
#include <kiwano-physics/Body.h>
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; // 接触结束
}
}

View File

@ -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 <kiwano-physics/ContactListener.h>
#include <kiwano-physics/Body.h>
#include <kiwano-physics/World.h>
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);
}
}
}
}
}

View File

@ -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 <kiwano-physics/Contact.h>
namespace kiwano
{
namespace physics
{
class ContactDispatcher;
KGE_DECLARE_SMART_PTR(ContactListener);
// 接触监听器
class KGE_API ContactListener
: public ObjectBase
, protected IntrusiveListItem<ContactListenerPtr>
{
friend IntrusiveList<ContactListenerPtr>;
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<ContactListenerPtr>;
friend class ContactDispatcher;
public:
using ContactBeginCallback = Function<void(Contact)>;
using ContactEndCallback = Function<void(Contact)>;
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<ContactListenerPtr>;
// 添加监听器
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_;
};
}
}

View File

@ -19,6 +19,7 @@
// THE SOFTWARE.
#include "World.h"
#include <kiwano-physics/ContactEvent.h>
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();

View File

@ -21,7 +21,6 @@
#pragma once
#include <kiwano-physics/Body.h>
#include <kiwano-physics/Joint.h>
#include <kiwano-physics/ContactListener.h>
namespace kiwano
{
@ -30,7 +29,6 @@ namespace kiwano
// 物理世界
class KGE_API World
: public Stage
, public ContactDispatcher
{
friend class Body;
friend class Joint;

View File

@ -23,7 +23,7 @@
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Contact.h>
#include <kiwano-physics/ContactListener.h>
#include <kiwano-physics/ContactEvent.h>
#include <kiwano-physics/Body.h>
#include <kiwano-physics/Joint.h>
#include <kiwano-physics/World.h>

View File

@ -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<MouseMoveEvent>();
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<MouseDownEvent>()->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<MouseUpEvent>();
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);
}
}

View File

@ -365,7 +365,7 @@ namespace kiwano
void ShowBorder(bool show);
// 事件分发
void Dispatch(Event& evt) override;
void Dispatch(Event* evt) override;
// 设置默认锚点
static void SetDefaultAnchor(

View File

@ -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()

View File

@ -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<MouseDownEvent>();
OnMouseButtonDown(real_evt->button, real_evt->pos);
}
else if (evt->type == event::MouseUp)
{
auto real_evt = evt->SafeCast<MouseUpEvent>();
OnMouseButtonUp(real_evt->button, real_evt->pos);
}
else if (evt->type == event::MouseMove)
{
auto real_evt = evt->SafeCast<MouseMoveEvent>();
OnMouseMoved(real_evt->pos);
}
else if (evt->type == event::MouseWheel)
{
auto real_evt = evt->SafeCast<MouseWheelEvent>();
OnMouseWheel(real_evt->wheel);
}
else if (evt->type == event::KeyDown)
{
auto real_evt = evt->SafeCast<KeyDownEvent>();
OnKeyDown(real_evt->code);
}
else if (evt->type == event::KeyUp)
{
auto real_evt = evt->SafeCast<KeyUpEvent>();
OnKeyUp(real_evt->code);
}
else if (evt->type == event::KeyChar)
{
auto real_evt = evt->SafeCast<KeyCharEvent>();
OnChar(real_evt->value);
}
}

View File

@ -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_;

View File

@ -21,10 +21,12 @@
#pragma once
#include <kiwano/macros.h>
#include <kiwano/base/time.h>
#include <kiwano/base/Event.hpp>
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) {}

View File

@ -180,7 +180,7 @@ namespace kiwano
}
}
void Director::HandleEvent(Event& evt)
void Director::HandleEvent(Event* evt)
{
if (debug_actor_)
debug_actor_->Dispatch(evt);

View File

@ -72,7 +72,7 @@ namespace kiwano
void OnRender(RenderTarget* rt) override;
void HandleEvent(Event& evt) override;
void HandleEvent(Event* evt) override;
protected:
Director();

134
src/kiwano/base/Event.cpp Normal file
View File

@ -0,0 +1,134 @@
#include <kiwano/base/Event.h>
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)
{
}
}

272
src/kiwano/base/Event.h Normal file
View File

@ -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 <kiwano/core/core.h>
#include <kiwano/math/math.h>
#include <kiwano/base/keys.hpp>
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<std::is_base_of<Event, _Ty>::value, int>::type
>
inline const _Ty* SafeCast() const
{
const _Ty* ptr = dynamic_cast<const _Ty*>(this);
if (ptr)
{
return ptr;
}
return nullptr;
}
template <
typename _Ty,
typename = typename std::enable_if<std::is_base_of<Event, _Ty>::value, int>::type
>
inline _Ty* SafeCast()
{
return const_cast<_Ty*>(const_cast<const Event*>(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; // 窗口被关闭
}
}

View File

@ -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 <kiwano/base/keys.hpp>
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;
}
}

View File

@ -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)

View File

@ -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_;

View File

@ -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);
}

View File

@ -22,7 +22,7 @@
#include <kiwano/core/core.h>
#include <kiwano/base/SmartPtr.hpp>
#include <kiwano/base/ObjectBase.h>
#include <kiwano/base/Event.hpp>
#include <kiwano/base/Event.h>
namespace kiwano
{
@ -39,25 +39,77 @@ namespace kiwano
friend IntrusiveList<EventListenerPtr>;
public:
using Callback = Function<void(Event const&)>;
using Callback = Function<void(Event*)>;
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;
}
}

View File

@ -20,8 +20,7 @@
#pragma once
#include <kiwano/macros.h>
#include <kiwano/base/time.h>
#include <kiwano/base/Event.hpp>
#include <kiwano/core/core.h>
namespace kiwano
{

View File

@ -82,7 +82,7 @@
#include <kiwano/base/Logger.h>
#include <kiwano/base/SmartPtr.hpp>
#include <kiwano/base/ObjectBase.h>
#include <kiwano/base/Event.hpp>
#include <kiwano/base/Event.h>
#include <kiwano/base/EventListener.h>
#include <kiwano/base/EventDispatcher.h>
#include <kiwano/base/Timer.h>

View File

@ -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<int>(wparam);
evt.key.count = static_cast<int>(lparam & 0xFF);
app->DispatchEvent(evt);
if (down)
{
KeyDownEvent evt;
evt.code = static_cast<int>(wparam);
evt.count = static_cast<int>(lparam & 0xFF);
app->DispatchEvent(&evt);
}
else
{
KeyUpEvent evt;
evt.code = static_cast<int>(wparam);
evt.count = static_cast<int>(lparam & 0xFF);
app->DispatchEvent(&evt);
}
}
break;
case WM_CHAR:
{
Event evt(Event::Char);
evt.key.c = static_cast<char>(wparam);
evt.key.count = static_cast<int>(lparam & 0xFF);
app->DispatchEvent(evt);
KeyCharEvent evt;
evt.value = static_cast<char>(wparam);
evt.count = static_cast<int>(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<float>(GET_X_LPARAM(lparam)), static_cast<float>(GET_Y_LPARAM(lparam)));
evt->left_btn_down = !!(wparam & MK_LBUTTON);
evt->left_btn_down = !!(wparam & MK_RBUTTON);
};
evt.mouse.x = static_cast<float>(GET_X_LPARAM(lparam));
evt.mouse.y = static_cast<float>(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<const wchar_t*>(lparam);
app->DispatchEvent(evt);
WindowTitleChangedEvent evt;
evt.title = reinterpret_cast<const wchar_t*>(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;
}
}

View File

@ -22,7 +22,7 @@
#include <kiwano/core/core.h>
#include <kiwano/base/time.h>
#include <kiwano/base/Component.h>
#include <kiwano/base/Event.hpp>
#include <kiwano/base/Event.h>
#include <kiwano/base/Window.h>
#include <kiwano/renderer/Renderer.h>
@ -91,7 +91,7 @@ namespace kiwano
);
// 分发事件
void DispatchEvent(Event& evt);
void DispatchEvent(Event* evt);
// 在 Kiwano 主线程中执行函数
// 当在其他线程调用 Kiwano 函数时使用

View File

@ -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<MouseEvent>();
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);

View File

@ -84,7 +84,7 @@ namespace kiwano
Status status
);
void UpdateStatus(Event const& evt);
void UpdateStatus(Event* evt);
private:
bool enabled_;