Update Window & ImGuiModule
This commit is contained in:
parent
88d61df5c0
commit
831c6c83e9
|
|
@ -13,6 +13,7 @@
|
|||
<ClInclude Include="..\..\src\kiwano\2d\Frame.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\2d\GifSprite.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\common.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\Director.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\event\Event.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\event\EventType.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\event\KeyEvent.h" />
|
||||
|
|
@ -55,7 +56,6 @@
|
|||
<ClInclude Include="..\..\src\kiwano\math\scalar.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\math\Vec2.hpp" />
|
||||
<ClInclude Include="..\..\src\kiwano\platform\Application.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\platform\Director.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\platform\FileSystem.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\platform\Input.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp" />
|
||||
|
|
@ -111,6 +111,7 @@
|
|||
<ClCompile Include="..\..\src\kiwano\2d\Transition.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\core\AsyncTask.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\core\Component.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\core\Director.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\core\EventDispatcher.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\core\EventListener.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\core\event\Event.cpp" />
|
||||
|
|
@ -126,7 +127,6 @@
|
|||
<ClCompile Include="..\..\src\kiwano\core\TimerManager.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\core\time.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\platform\Application.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\platform\Director.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\platform\Input.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" />
|
||||
|
|
|
|||
|
|
@ -231,9 +231,6 @@
|
|||
<ClInclude Include="..\..\src\kiwano\platform\Window.h">
|
||||
<Filter>platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\platform\Director.h">
|
||||
<Filter>platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\2d\TextActor.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -282,6 +279,9 @@
|
|||
<ClInclude Include="..\..\src\kiwano\renderer\RenderContext.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\core\Director.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
|
||||
|
|
@ -440,9 +440,6 @@
|
|||
<ClCompile Include="..\..\src\kiwano\platform\Window.cpp">
|
||||
<Filter>platform</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\kiwano\platform\Director.cpp">
|
||||
<Filter>platform</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -479,5 +476,8 @@
|
|||
<ClCompile Include="..\..\src\kiwano\renderer\RenderContext.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\kiwano\core\Director.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -35,14 +35,18 @@ namespace kiwano
|
|||
|
||||
void ImGuiLayer::OnRender(RenderContext& ctx)
|
||||
{
|
||||
PrepareToRender(ctx);
|
||||
for (const auto& pipeline : pipelines_)
|
||||
{
|
||||
pipeline.second();
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiLayer::AddItem(ImGuiPipeline const& item, String const& name)
|
||||
bool ImGuiLayer::CheckVisibility(RenderContext& ctx) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGuiLayer::AddItem(String const& name, ImGuiPipeline const& item)
|
||||
{
|
||||
pipelines_.insert(std::make_pair(name, item));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ namespace kiwano
|
|||
|
||||
/// \~chinese
|
||||
/// @brief Ìí¼Ó ImGui ÔªËØ
|
||||
/// @param item ¹ÜµÀ
|
||||
/// @param name ÔªËØÃû³Æ
|
||||
void AddItem(ImGuiPipeline const& item, String const& name);
|
||||
/// @param item ¹ÜµÀ
|
||||
void AddItem(String const& name, ImGuiPipeline const& item);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief ÒÆ³ý ImGui ÔªËØ
|
||||
|
|
@ -62,6 +62,8 @@ namespace kiwano
|
|||
public:
|
||||
void OnRender(RenderContext& ctx) override;
|
||||
|
||||
bool CheckVisibility(RenderContext& ctx) const override;
|
||||
|
||||
private:
|
||||
Map<String, ImGuiPipeline> pipelines_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,32 +1,20 @@
|
|||
// Copyright (C) 2019 Nomango
|
||||
|
||||
#include <kiwano/core/common.h>
|
||||
#include <kiwano/core/event/KeyEvent.h>
|
||||
#include <kiwano/core/event/MouseEvent.h>
|
||||
#include <kiwano/platform/Window.h>
|
||||
#include <kiwano/platform/Input.h>
|
||||
#include <kiwano/renderer/Renderer.h>
|
||||
#include <kiwano-imgui/ImGuiModule.h>
|
||||
#include <kiwano-imgui/imgui_impl.h>
|
||||
|
||||
#include <XInput.h>
|
||||
#pragma comment(lib, "xinput")
|
||||
|
||||
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
# define WM_MOUSEHWHEEL 0x020E
|
||||
#endif
|
||||
|
||||
#ifndef DBT_DEVNODES_CHANGED
|
||||
# define DBT_DEVNODES_CHANGED 0x0007
|
||||
#endif
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
namespace imgui
|
||||
{
|
||||
ImGuiModule::ImGuiModule()
|
||||
: has_gamepad_(false)
|
||||
, want_update_has_gamepad_(false)
|
||||
, target_window_(nullptr)
|
||||
: target_window_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -36,55 +24,17 @@ namespace kiwano
|
|||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// Setup Platform/Renderer bindings
|
||||
Init(Window::instance().GetHandle());
|
||||
|
||||
target_window_ = Renderer::instance().GetTargetWindow();
|
||||
}
|
||||
|
||||
void ImGuiModule::DestroyComponent()
|
||||
{
|
||||
ImGui_Impl_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
void ImGuiModule::OnUpdate(Duration dt)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup time step
|
||||
io.DeltaTime = dt.Seconds();
|
||||
|
||||
// Read keyboard modifiers inputs
|
||||
io.KeyCtrl = Input::instance().IsDown(KeyCode::Ctrl);
|
||||
io.KeyShift = Input::instance().IsDown(KeyCode::Shift);
|
||||
io.KeyAlt = Input::instance().IsDown(KeyCode::Alt);
|
||||
io.KeySuper = false;
|
||||
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
|
||||
|
||||
// Update OS mouse position
|
||||
UpdateMousePos();
|
||||
|
||||
// Update OS mouse cursor with the cursor requested by imgui
|
||||
UpdateMouseCursor();
|
||||
|
||||
// Update game controllers (if enabled and available)
|
||||
UpdateGamepads();
|
||||
}
|
||||
|
||||
void ImGuiModule::Init(HWND hwnd)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
io.BackendPlatformName = "imgui_impl_win32";
|
||||
io.ImeWindowHandle = hwnd;
|
||||
io.ImeWindowHandle = target_window_;
|
||||
|
||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_Tab] = KeyCode::Tab;
|
||||
|
|
@ -104,7 +54,34 @@ namespace kiwano
|
|||
io.KeyMap[ImGuiKey_Y] = KeyCode::Y;
|
||||
io.KeyMap[ImGuiKey_Z] = KeyCode::Z;
|
||||
|
||||
ImGui_Impl_Init(&Renderer::instance());
|
||||
ImGui_Impl_Init(Renderer::instance());
|
||||
}
|
||||
|
||||
void ImGuiModule::DestroyComponent()
|
||||
{
|
||||
ImGui_Impl_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
void ImGuiModule::OnUpdate(Duration dt)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup time step
|
||||
io.DeltaTime = dt.Seconds();
|
||||
|
||||
// Read keyboard modifiers inputs
|
||||
io.KeyCtrl = Input::instance().IsDown(KeyCode::Ctrl);
|
||||
io.KeyShift = Input::instance().IsDown(KeyCode::Shift);
|
||||
io.KeyAlt = Input::instance().IsDown(KeyCode::Alt);
|
||||
io.KeySuper = Input::instance().IsDown(KeyCode::Super);
|
||||
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the HandleEvent function below.
|
||||
|
||||
// Update OS mouse position
|
||||
UpdateMousePos();
|
||||
|
||||
// Update OS mouse cursor with the cursor requested by imgui
|
||||
UpdateMouseCursor();
|
||||
}
|
||||
|
||||
void ImGuiModule::BeforeRender()
|
||||
|
|
@ -117,89 +94,56 @@ namespace kiwano
|
|||
Render();
|
||||
}
|
||||
|
||||
void ImGuiModule::HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
|
||||
void ImGuiModule::HandleEvent(Event* evt)
|
||||
{
|
||||
if (ImGui::GetCurrentContext() == NULL)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
if (evt->IsType<MouseEvent>())
|
||||
{
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||
{
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; }
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
|
||||
::SetCapture(hwnd);
|
||||
|
||||
io.MouseDown[button] = true;
|
||||
break;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||
if (msg == WM_MBUTTONUP) { button = 2; }
|
||||
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; }
|
||||
io.MouseDown[button] = false;
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
|
||||
::ReleaseCapture();
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA;
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEHWHEEL:
|
||||
{
|
||||
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA;
|
||||
break;
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
if (wparam < 256)
|
||||
io.KeysDown[wparam] = 1;
|
||||
break;
|
||||
}
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
if (wparam < 256)
|
||||
io.KeysDown[wparam] = 0;
|
||||
break;
|
||||
}
|
||||
case WM_CHAR:
|
||||
{
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
io.AddInputCharacter((uint32_t)wparam);
|
||||
break;
|
||||
}
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
if (LOWORD(lparam) == HTCLIENT)
|
||||
if (evt->IsType<MouseDownEvent>())
|
||||
{
|
||||
UpdateMouseCursor();
|
||||
int button = dynamic_cast<MouseDownEvent*>(evt)->button;
|
||||
int index = 0;
|
||||
if (button == MouseButton::Left) index = 0;
|
||||
else if (button == MouseButton::Right) index = 1;
|
||||
else if (button == MouseButton::Middle) index = 2;
|
||||
io.MouseDown[index] = true;
|
||||
}
|
||||
else if (evt->IsType<MouseUpEvent>())
|
||||
{
|
||||
int button = dynamic_cast<MouseUpEvent*>(evt)->button;
|
||||
int index = 0;
|
||||
if (button == MouseButton::Left) index = 0;
|
||||
else if (button == MouseButton::Right) index = 1;
|
||||
else if (button == MouseButton::Middle) index = 2;
|
||||
io.MouseDown[index] = false;
|
||||
}
|
||||
else if (evt->IsType<MouseWheelEvent>())
|
||||
{
|
||||
float wheel = dynamic_cast<MouseWheelEvent*>(evt)->wheel;
|
||||
io.MouseWheel += wheel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_DEVICECHANGE:
|
||||
else if (evt->IsType<KeyEvent>())
|
||||
{
|
||||
if ((uint32_t)wparam == DBT_DEVNODES_CHANGED)
|
||||
want_update_has_gamepad_ = true;
|
||||
break;
|
||||
}
|
||||
if (evt->IsType<KeyDownEvent>())
|
||||
{
|
||||
int key = dynamic_cast<KeyDownEvent*>(evt)->code;
|
||||
io.KeysDown[key] = true;
|
||||
}
|
||||
else if (evt->IsType<KeyUpEvent>())
|
||||
{
|
||||
int key = dynamic_cast<KeyUpEvent*>(evt)->code;
|
||||
io.KeysDown[key] = false;
|
||||
}
|
||||
else if (evt->IsType<KeyCharEvent>())
|
||||
{
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
char ch = dynamic_cast<KeyCharEvent*>(evt)->value;
|
||||
io.AddInputCharacter(static_cast<ImWchar>(ch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,50 +204,6 @@ namespace kiwano
|
|||
|
||||
Window::instance().SetCursor(cursor);
|
||||
}
|
||||
void ImGuiModule::UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
|
||||
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
||||
if (want_update_has_gamepad_)
|
||||
{
|
||||
XINPUT_CAPABILITIES caps;
|
||||
has_gamepad_ = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS);
|
||||
want_update_has_gamepad_ = false;
|
||||
}
|
||||
|
||||
XINPUT_STATE xinput_state;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
if (has_gamepad_ && XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
|
||||
{
|
||||
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
|
||||
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
|
||||
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
|
||||
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
|
||||
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
|
||||
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
|
||||
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
|
||||
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
|
||||
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
|
||||
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
|
||||
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
||||
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,13 +49,11 @@ namespace kiwano
|
|||
|
||||
void AfterRender() override;
|
||||
|
||||
void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override;
|
||||
void HandleEvent(Event* evt) override;
|
||||
|
||||
void OnUpdate(Duration dt) override;
|
||||
|
||||
private:
|
||||
void Init(HWND hwnd);
|
||||
|
||||
void NewFrame();
|
||||
|
||||
void Render();
|
||||
|
|
@ -64,12 +62,8 @@ namespace kiwano
|
|||
|
||||
void UpdateMouseCursor();
|
||||
|
||||
void UpdateGamepads();
|
||||
|
||||
private:
|
||||
bool has_gamepad_;
|
||||
bool want_update_has_gamepad_;
|
||||
HWND target_window_;
|
||||
WindowHandle target_window_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <kiwano-imgui/imgui_impl_dx11.h>
|
||||
|
||||
inline bool ImGui_Impl_Init(::kiwano::Renderer* renderer) { return ImGui_ImplDX11_Init(renderer->GetD3DDeviceResources()->GetDevice(), renderer->GetD3DDeviceResources()->GetDeviceContext()); }
|
||||
inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX11_Init(renderer.GetD3DDeviceResources()->GetDevice(), renderer.GetD3DDeviceResources()->GetDeviceContext()); }
|
||||
inline void ImGui_Impl_Shutdown() { ImGui_ImplDX11_Shutdown(); }
|
||||
inline void ImGui_Impl_NewFrame() { ImGui_ImplDX11_NewFrame(); }
|
||||
inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX11_RenderDrawData(draw_data); }
|
||||
|
|
@ -20,7 +20,7 @@ inline bool ImGui_Impl_CreateDeviceObjects() { return ImGui_ImplDX11_Cre
|
|||
|
||||
#include <kiwano-imgui/imgui_impl_dx10.h>
|
||||
|
||||
inline bool ImGui_Impl_Init(::kiwano::Renderer* renderer) { return ImGui_ImplDX10_Init(renderer->GetD3DDeviceResources()->GetDevice()); }
|
||||
inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX10_Init(renderer.GetD3DDeviceResources()->GetDevice()); }
|
||||
inline void ImGui_Impl_Shutdown() { ImGui_ImplDX10_Shutdown(); }
|
||||
inline void ImGui_Impl_NewFrame() { ImGui_ImplDX10_NewFrame(); }
|
||||
inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX10_RenderDrawData(draw_data); }
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ namespace kiwano
|
|||
{
|
||||
namespace physics
|
||||
{
|
||||
KGE_DECLARE_SMART_PTR(ContactBeginEvent);
|
||||
KGE_DECLARE_SMART_PTR(ContactEndEvent);
|
||||
|
||||
/**
|
||||
* \addtogroup Events
|
||||
* @{
|
||||
|
|
|
|||
|
|
@ -67,14 +67,14 @@ namespace kiwano
|
|||
|
||||
void BeginContact(b2Contact* contact) override
|
||||
{
|
||||
ContactBeginEvent evt(contact);
|
||||
world_->DispatchEvent(evt);
|
||||
ContactBeginEventPtr evt = new ContactBeginEvent(contact);
|
||||
world_->DispatchEvent(evt.get());
|
||||
}
|
||||
|
||||
void EndContact(b2Contact* contact) override
|
||||
{
|
||||
ContactEndEvent evt(contact);
|
||||
world_->DispatchEvent(evt);
|
||||
ContactEndEventPtr evt = new ContactEndEvent(contact);
|
||||
world_->DispatchEvent(evt.get());
|
||||
}
|
||||
|
||||
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override { KGE_NOT_USED(contact); KGE_NOT_USED(oldManifold); }
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ namespace kiwano
|
|||
|
||||
if (children_.empty())
|
||||
{
|
||||
if (CheckVisibilty(ctx))
|
||||
if (CheckVisibility(ctx))
|
||||
{
|
||||
PrepareToRender(ctx);
|
||||
OnRender(ctx);
|
||||
|
|
@ -116,7 +116,7 @@ namespace kiwano
|
|||
child = child->next_item().get();
|
||||
}
|
||||
|
||||
if (CheckVisibilty(ctx))
|
||||
if (CheckVisibility(ctx))
|
||||
{
|
||||
PrepareToRender(ctx);
|
||||
OnRender(ctx);
|
||||
|
|
@ -157,7 +157,7 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
bool Actor::CheckVisibilty(RenderContext& ctx) const
|
||||
bool Actor::CheckVisibility(RenderContext& ctx) const
|
||||
{
|
||||
if (dirty_visibility_)
|
||||
{
|
||||
|
|
@ -175,7 +175,7 @@ namespace kiwano
|
|||
return visible_in_rt_;
|
||||
}
|
||||
|
||||
bool Actor::DispatchEvent(Event& evt)
|
||||
bool Actor::DispatchEvent(Event* evt)
|
||||
{
|
||||
if (!visible_)
|
||||
return true;
|
||||
|
|
@ -208,54 +208,48 @@ namespace kiwano
|
|||
return true;
|
||||
}
|
||||
|
||||
void Actor::HandleEvent(Event& evt)
|
||||
void Actor::HandleEvent(Event* evt)
|
||||
{
|
||||
if (responsible_)
|
||||
{
|
||||
if (evt.IsType<MouseMoveEvent>())
|
||||
if (evt->IsType<MouseMoveEvent>())
|
||||
{
|
||||
auto& mouse_evt = evt.SafeCast<MouseMoveEvent>();
|
||||
bool contains = ContainsPoint(mouse_evt.pos);
|
||||
auto mouse_evt = dynamic_cast<MouseMoveEvent*>(evt);
|
||||
bool contains = ContainsPoint(mouse_evt->pos);
|
||||
if (!hover_ && contains)
|
||||
{
|
||||
hover_ = true;
|
||||
|
||||
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;
|
||||
EventDispatcher::DispatchEvent(hover);
|
||||
MouseHoverEventPtr hover = new MouseHoverEvent;
|
||||
hover->pos = mouse_evt->pos;
|
||||
EventDispatcher::DispatchEvent(hover.get());
|
||||
}
|
||||
else if (hover_ && !contains)
|
||||
{
|
||||
hover_ = false;
|
||||
pressed_ = false;
|
||||
|
||||
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;
|
||||
EventDispatcher::DispatchEvent(out);
|
||||
MouseOutEventPtr out = new MouseOutEvent;
|
||||
out->pos = mouse_evt->pos;
|
||||
EventDispatcher::DispatchEvent(out.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (evt.IsType<MouseDownEvent>() && hover_)
|
||||
if (evt->IsType<MouseDownEvent>() && hover_)
|
||||
{
|
||||
pressed_ = true;
|
||||
}
|
||||
|
||||
if (evt.IsType<MouseUpEvent>() && pressed_)
|
||||
if (evt->IsType<MouseUpEvent>() && pressed_)
|
||||
{
|
||||
pressed_ = false;
|
||||
|
||||
auto& mouse_up_evt = evt.SafeCast<MouseUpEvent>();
|
||||
auto mouse_up_evt = dynamic_cast<MouseUpEvent*>(evt);
|
||||
|
||||
MouseClickEvent 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.button = mouse_up_evt.button;
|
||||
EventDispatcher::DispatchEvent(click);
|
||||
MouseClickEventPtr click = new MouseClickEvent;
|
||||
click->pos = mouse_up_evt->pos;
|
||||
click->button = mouse_up_evt->button;
|
||||
EventDispatcher::DispatchEvent(click.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ namespace kiwano
|
|||
/// @brief 分发事件
|
||||
/// @param evt 事件
|
||||
/// @return 是否继续分发该事件
|
||||
virtual bool DispatchEvent(Event& evt);
|
||||
virtual bool DispatchEvent(Event* evt);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置默认锚点
|
||||
|
|
@ -416,10 +416,10 @@ namespace kiwano
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 检查是否在渲染上下文的视区内
|
||||
virtual bool CheckVisibilty(RenderContext& ctx) const;
|
||||
virtual bool CheckVisibility(RenderContext& ctx) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 渲染前初始化渲染上下文状态,仅当 CheckVisibilty 返回真时调用该函数
|
||||
/// @brief 渲染前初始化渲染上下文状态,仅当 CheckVisibility 返回真时调用该函数
|
||||
virtual void PrepareToRender(RenderContext& ctx);
|
||||
|
||||
/// \~chinese
|
||||
|
|
@ -440,7 +440,7 @@ namespace kiwano
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 处理事件
|
||||
void HandleEvent(Event& evt);
|
||||
void HandleEvent(Event* evt);
|
||||
|
||||
private:
|
||||
bool visible_;
|
||||
|
|
|
|||
|
|
@ -130,28 +130,28 @@ namespace kiwano
|
|||
return status_;
|
||||
}
|
||||
|
||||
void Button::UpdateStatus(Event& evt)
|
||||
void Button::UpdateStatus(Event* evt)
|
||||
{
|
||||
if (!enabled_)
|
||||
return;
|
||||
|
||||
if (evt.IsType<MouseHoverEvent>())
|
||||
if (evt->IsType<MouseHoverEvent>())
|
||||
{
|
||||
SetStatus(Status::Hover);
|
||||
}
|
||||
else if (evt.IsType<MouseOutEvent>())
|
||||
else if (evt->IsType<MouseOutEvent>())
|
||||
{
|
||||
SetStatus(Status::Normal);
|
||||
}
|
||||
else if (evt.IsType<MouseDownEvent>() && status_ == Status::Hover)
|
||||
else if (evt->IsType<MouseDownEvent>() && status_ == Status::Hover)
|
||||
{
|
||||
SetStatus(Status::Pressed);
|
||||
}
|
||||
else if (evt.IsType<MouseUpEvent>() && status_ == Status::Pressed)
|
||||
else if (evt->IsType<MouseUpEvent>() && status_ == Status::Pressed)
|
||||
{
|
||||
SetStatus(Status::Hover);
|
||||
}
|
||||
else if (evt.IsType<MouseClickEvent>())
|
||||
else if (evt->IsType<MouseClickEvent>())
|
||||
{
|
||||
if (click_callback_)
|
||||
click_callback_(this);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ namespace kiwano
|
|||
protected:
|
||||
/// \~chinese
|
||||
/// @brief 更新按钮状态
|
||||
void UpdateStatus(Event& evt);
|
||||
void UpdateStatus(Event* evt);
|
||||
|
||||
private:
|
||||
bool enabled_;
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ namespace kiwano
|
|||
style.fill_brush = fill_brush;
|
||||
debug_text_.SetStyle(style);
|
||||
|
||||
AddListener<MouseHoverEvent>([=](Event&) { SetOpacity(0.4f); });
|
||||
AddListener<MouseOutEvent>([=](Event&) { SetOpacity(1.f); });
|
||||
AddListener<MouseHoverEvent>([=](Event*) { SetOpacity(0.4f); });
|
||||
AddListener<MouseOutEvent>([=](Event*) { SetOpacity(1.f); });
|
||||
}
|
||||
|
||||
DebugActor::~DebugActor()
|
||||
|
|
@ -139,7 +139,7 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
bool DebugActor::CheckVisibilty(RenderContext& ctx) const
|
||||
bool DebugActor::CheckVisibility(RenderContext& ctx) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace kiwano
|
|||
void OnUpdate(Duration dt) override;
|
||||
|
||||
protected:
|
||||
bool CheckVisibilty(RenderContext& ctx) const override;
|
||||
bool CheckVisibility(RenderContext& ctx) const override;
|
||||
|
||||
private:
|
||||
std::locale comma_locale_;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace kiwano
|
|||
|
||||
void GifSprite::OnRender(RenderContext& ctx)
|
||||
{
|
||||
if (frame_to_render_ && CheckVisibilty(ctx))
|
||||
if (frame_to_render_ && CheckVisibility(ctx))
|
||||
{
|
||||
PrepareToRender(ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ namespace kiwano
|
|||
area_.SetMaskTransform(transform);
|
||||
}
|
||||
|
||||
bool Layer::DispatchEvent(Event& evt)
|
||||
bool Layer::DispatchEvent(Event* evt)
|
||||
{
|
||||
if (!IsVisible())
|
||||
return true;
|
||||
|
|
@ -75,7 +75,7 @@ namespace kiwano
|
|||
ctx.PopLayer();
|
||||
}
|
||||
|
||||
bool Layer::CheckVisibilty(RenderContext& ctx) const
|
||||
bool Layer::CheckVisibility(RenderContext& ctx) const
|
||||
{
|
||||
// Do not need to render Layer
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -82,12 +82,12 @@ namespace kiwano
|
|||
/// @brief 获取图层区域
|
||||
LayerArea const& GetArea() const;
|
||||
|
||||
bool DispatchEvent(Event& evt) override;
|
||||
bool DispatchEvent(Event* evt) override;
|
||||
|
||||
protected:
|
||||
void Render(RenderContext& ctx) override;
|
||||
|
||||
bool CheckVisibilty(RenderContext& ctx) const override;
|
||||
bool CheckVisibility(RenderContext& ctx) const override;
|
||||
|
||||
private:
|
||||
bool swallow_;
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@ namespace kiwano
|
|||
ctx.FillGeometry(geo_);
|
||||
}
|
||||
|
||||
bool ShapeActor::CheckVisibilty(RenderContext& ctx) const
|
||||
bool ShapeActor::CheckVisibility(RenderContext& ctx) const
|
||||
{
|
||||
return geo_.IsValid() && Actor::CheckVisibilty(ctx);
|
||||
return geo_.IsValid() && Actor::CheckVisibility(ctx);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ namespace kiwano
|
|||
void OnRender(RenderContext& ctx) override;
|
||||
|
||||
protected:
|
||||
bool CheckVisibilty(RenderContext& ctx) const override;
|
||||
bool CheckVisibility(RenderContext& ctx) const override;
|
||||
|
||||
private:
|
||||
BrushPtr fill_brush_;
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ namespace kiwano
|
|||
ctx.DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds());
|
||||
}
|
||||
|
||||
bool Sprite::CheckVisibilty(RenderContext& ctx) const
|
||||
bool Sprite::CheckVisibility(RenderContext& ctx) const
|
||||
{
|
||||
return frame_ && frame_->IsValid() && Actor::CheckVisibilty(ctx);
|
||||
return frame_ && frame_->IsValid() && Actor::CheckVisibility(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ namespace kiwano
|
|||
void OnRender(RenderContext& ctx) override;
|
||||
|
||||
protected:
|
||||
bool CheckVisibilty(RenderContext& ctx) const override;
|
||||
bool CheckVisibility(RenderContext& ctx) const override;
|
||||
|
||||
private:
|
||||
FramePtr frame_;
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
bool TextActor::CheckVisibilty(RenderContext& ctx) const
|
||||
bool TextActor::CheckVisibility(RenderContext& ctx) const
|
||||
{
|
||||
return text_layout_.IsValid() && Actor::CheckVisibilty(ctx);
|
||||
return text_layout_.IsValid() && Actor::CheckVisibility(ctx);
|
||||
}
|
||||
|
||||
void TextActor::SetFillColor(Color const& color)
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ namespace kiwano
|
|||
void OnUpdate(Duration dt) override;
|
||||
|
||||
protected:
|
||||
bool CheckVisibilty(RenderContext& ctx) const override;
|
||||
bool CheckVisibility(RenderContext& ctx) const override;
|
||||
|
||||
private:
|
||||
bool show_underline_;
|
||||
|
|
|
|||
|
|
@ -119,11 +119,7 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 事件处理
|
||||
/// @param evt 事件
|
||||
virtual void HandleEvent(Event& evt) {}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 处理 Windows 消息
|
||||
virtual void HandleMessage(HWND, UINT32, WPARAM, LPARAM) {}
|
||||
virtual void HandleEvent(Event* evt) {}
|
||||
|
||||
public:
|
||||
static const int flag;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/platform/Director.h>
|
||||
#include <kiwano/core/Director.h>
|
||||
#include <kiwano/2d/Actor.h>
|
||||
#include <kiwano/2d/Stage.h>
|
||||
#include <kiwano/2d/Transition.h>
|
||||
|
|
@ -179,7 +179,7 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
void Director::HandleEvent(Event& evt)
|
||||
void Director::HandleEvent(Event* evt)
|
||||
{
|
||||
if (current_stage_)
|
||||
current_stage_->DispatchEvent(evt);
|
||||
|
|
@ -108,7 +108,7 @@ namespace kiwano
|
|||
|
||||
void OnRender(RenderContext& ctx) override;
|
||||
|
||||
void HandleEvent(Event& evt) override;
|
||||
void HandleEvent(Event* evt) override;
|
||||
|
||||
private:
|
||||
Director();
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
bool EventDispatcher::DispatchEvent(Event& evt)
|
||||
bool EventDispatcher::DispatchEvent(Event* evt)
|
||||
{
|
||||
if (listeners_.empty())
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ namespace kiwano
|
|||
/// @brief 分发事件
|
||||
/// @param evt 事件
|
||||
/// @return 是否继续分发该事件
|
||||
bool DispatchEvent(Event& evt);
|
||||
bool DispatchEvent(Event* evt);
|
||||
|
||||
private:
|
||||
Listeners listeners_;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace kiwano
|
|||
public:
|
||||
/// \~chinese
|
||||
/// @brief 监听器回调函数
|
||||
using Callback = Function<void(Event&)>;
|
||||
using Callback = Function<void(Event*)>;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 构造空监听器
|
||||
|
|
@ -154,7 +154,7 @@ namespace kiwano
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 接收消息
|
||||
void Receive(Event& evt);
|
||||
void Receive(Event* evt);
|
||||
|
||||
private:
|
||||
bool running_;
|
||||
|
|
@ -220,9 +220,11 @@ namespace kiwano
|
|||
type_ = type;
|
||||
}
|
||||
|
||||
inline void EventListener::Receive(Event& evt)
|
||||
inline void EventListener::Receive(Event* evt)
|
||||
{
|
||||
if (type_ == evt.GetType() && callback_)
|
||||
KGE_ASSERT(evt != nullptr);
|
||||
|
||||
if (type_ == evt->GetType() && callback_)
|
||||
{
|
||||
callback_(evt);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,15 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <kiwano/core/event/EventType.h>
|
||||
#include <kiwano/math/math.h>
|
||||
#include <kiwano/core/SmartPtr.hpp>
|
||||
#include <kiwano/core/keys.h>
|
||||
#include <kiwano/core/event/EventType.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
KGE_DECLARE_SMART_PTR(Event);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* \defgroup Events 事件
|
||||
|
|
@ -38,6 +41,7 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 事件
|
||||
class KGE_API Event
|
||||
: public RefCounter
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
|
|
@ -66,7 +70,7 @@ namespace kiwano
|
|||
typename _Ty,
|
||||
typename = typename std::enable_if<std::is_base_of<Event, _Ty>::value, int>::type
|
||||
>
|
||||
const _Ty& SafeCast() const;
|
||||
const _Ty* SafeCast() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 安全转换为其他类型事件
|
||||
|
|
@ -75,7 +79,7 @@ namespace kiwano
|
|||
typename _Ty,
|
||||
typename = typename std::enable_if<std::is_base_of<Event, _Ty>::value, int>::type
|
||||
>
|
||||
_Ty& SafeCast();
|
||||
_Ty* SafeCast();
|
||||
|
||||
private:
|
||||
const EventType type_;
|
||||
|
|
@ -93,9 +97,9 @@ namespace kiwano
|
|||
template <typename _Ty, typename = typename std::enable_if<IsEvent<_Ty>::value, int>::type>
|
||||
struct IsEventType
|
||||
{
|
||||
inline bool operator()(const Event& evt) const
|
||||
inline bool operator()(const Event* evt) const
|
||||
{
|
||||
return evt.GetType() == KGE_EVENT(_Ty);
|
||||
return evt->GetType() == KGE_EVENT(_Ty);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -109,21 +113,21 @@ namespace kiwano
|
|||
template <typename _Ty, typename>
|
||||
inline bool Event::IsType() const
|
||||
{
|
||||
return kiwano::IsEventType<_Ty>()(*this);
|
||||
return kiwano::IsEventType<_Ty>()(this);
|
||||
}
|
||||
|
||||
template <typename _Ty, typename>
|
||||
inline const _Ty& Event::SafeCast() const
|
||||
inline const _Ty* Event::SafeCast() const
|
||||
{
|
||||
return const_cast<Event*>(this)->SafeCast<_Ty>();
|
||||
}
|
||||
|
||||
template <typename _Ty, typename>
|
||||
inline _Ty* Event::SafeCast()
|
||||
{
|
||||
if (!IsType<_Ty>())
|
||||
throw std::bad_cast();
|
||||
return dynamic_cast<const _Ty&>(*this);
|
||||
}
|
||||
|
||||
template <typename _Ty, typename>
|
||||
inline _Ty& Event::SafeCast()
|
||||
{
|
||||
return const_cast<_Ty&>(const_cast<const Event*>(this)->SafeCast<_Ty>());
|
||||
return dynamic_cast<_Ty*>(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,26 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
|
||||
KeyEvent::KeyEvent(const EventType& type)
|
||||
: Event(type)
|
||||
{
|
||||
}
|
||||
|
||||
KeyDownEvent::KeyDownEvent()
|
||||
: Event(KGE_EVENT(KeyDownEvent))
|
||||
: KeyEvent(KGE_EVENT(KeyDownEvent))
|
||||
, code(0)
|
||||
{
|
||||
}
|
||||
|
||||
KeyUpEvent::KeyUpEvent()
|
||||
: Event(KGE_EVENT(KeyUpEvent))
|
||||
: KeyEvent(KGE_EVENT(KeyUpEvent))
|
||||
, code(0)
|
||||
{
|
||||
}
|
||||
|
||||
KeyCharEvent::KeyCharEvent()
|
||||
: Event(KGE_EVENT(KeyCharEvent))
|
||||
: KeyEvent(KGE_EVENT(KeyCharEvent))
|
||||
, value()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
KGE_DECLARE_SMART_PTR(KeyEvent);
|
||||
KGE_DECLARE_SMART_PTR(KeyDownEvent);
|
||||
KGE_DECLARE_SMART_PTR(KeyUpEvent);
|
||||
KGE_DECLARE_SMART_PTR(KeyCharEvent);
|
||||
|
||||
/**
|
||||
* \addtogroup Events
|
||||
* @{
|
||||
|
|
@ -34,12 +39,14 @@ namespace kiwano
|
|||
class KGE_API KeyEvent
|
||||
: public Event
|
||||
{
|
||||
public:
|
||||
KeyEvent(const EventType& type);
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 键盘按下事件
|
||||
class KGE_API KeyDownEvent
|
||||
: public Event
|
||||
: public KeyEvent
|
||||
{
|
||||
public:
|
||||
KeyCode::Value code; ///< 键值
|
||||
|
|
@ -50,7 +57,7 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 键盘抬起事件
|
||||
class KGE_API KeyUpEvent
|
||||
: public Event
|
||||
: public KeyEvent
|
||||
{
|
||||
public:
|
||||
KeyCode::Value code; ///< 键值
|
||||
|
|
@ -61,7 +68,7 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 键盘字符事件
|
||||
class KGE_API KeyCharEvent
|
||||
: public Event
|
||||
: public KeyEvent
|
||||
{
|
||||
public:
|
||||
char value; ///< 字符
|
||||
|
|
@ -74,11 +81,11 @@ namespace kiwano
|
|||
template <>
|
||||
struct IsEventType<KeyEvent>
|
||||
{
|
||||
inline bool operator()(const Event& evt) const
|
||||
inline bool operator()(const Event* evt) const
|
||||
{
|
||||
return evt.GetType() == KGE_EVENT(KeyDownEvent)
|
||||
|| evt.GetType() == KGE_EVENT(KeyUpEvent)
|
||||
|| evt.GetType() == KGE_EVENT(KeyCharEvent);
|
||||
return evt->GetType() == KGE_EVENT(KeyDownEvent)
|
||||
|| evt->GetType() == KGE_EVENT(KeyUpEvent)
|
||||
|| evt->GetType() == KGE_EVENT(KeyCharEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ namespace kiwano
|
|||
MouseEvent::MouseEvent(EventType const& type)
|
||||
: Event(type)
|
||||
, pos()
|
||||
, left_btn_down(false)
|
||||
, right_btn_down(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,15 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
KGE_DECLARE_SMART_PTR(MouseEvent);
|
||||
KGE_DECLARE_SMART_PTR(MouseMoveEvent);
|
||||
KGE_DECLARE_SMART_PTR(MouseDownEvent);
|
||||
KGE_DECLARE_SMART_PTR(MouseUpEvent);
|
||||
KGE_DECLARE_SMART_PTR(MouseClickEvent);
|
||||
KGE_DECLARE_SMART_PTR(MouseHoverEvent);
|
||||
KGE_DECLARE_SMART_PTR(MouseOutEvent);
|
||||
KGE_DECLARE_SMART_PTR(MouseWheelEvent);
|
||||
|
||||
/**
|
||||
* \addtogroup Events
|
||||
* @{
|
||||
|
|
@ -37,8 +46,6 @@ namespace kiwano
|
|||
{
|
||||
public:
|
||||
Point pos; ///< 報炎了崔
|
||||
bool left_btn_down; ///< 鼠标左键是否按下
|
||||
bool right_btn_down; ///< 鼠标右键是否按下
|
||||
|
||||
MouseEvent(EventType const& type);
|
||||
};
|
||||
|
|
@ -119,15 +126,15 @@ namespace kiwano
|
|||
template <>
|
||||
struct IsEventType<MouseEvent>
|
||||
{
|
||||
inline bool operator()(const Event& evt) const
|
||||
inline bool operator()(const Event* evt) const
|
||||
{
|
||||
return evt.GetType() == KGE_EVENT(MouseMoveEvent)
|
||||
|| evt.GetType() == KGE_EVENT(MouseDownEvent)
|
||||
|| evt.GetType() == KGE_EVENT(MouseUpEvent)
|
||||
|| evt.GetType() == KGE_EVENT(MouseClickEvent)
|
||||
|| evt.GetType() == KGE_EVENT(MouseHoverEvent)
|
||||
|| evt.GetType() == KGE_EVENT(MouseOutEvent)
|
||||
|| evt.GetType() == KGE_EVENT(MouseWheelEvent);
|
||||
return evt->GetType() == KGE_EVENT(MouseMoveEvent)
|
||||
|| evt->GetType() == KGE_EVENT(MouseDownEvent)
|
||||
|| evt->GetType() == KGE_EVENT(MouseUpEvent)
|
||||
|| evt->GetType() == KGE_EVENT(MouseClickEvent)
|
||||
|| evt->GetType() == KGE_EVENT(MouseHoverEvent)
|
||||
|| evt->GetType() == KGE_EVENT(MouseOutEvent)
|
||||
|| evt->GetType() == KGE_EVENT(MouseWheelEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,34 +2,40 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
|
||||
WindowEvent::WindowEvent(const EventType& type)
|
||||
: Event(type)
|
||||
{
|
||||
}
|
||||
|
||||
WindowMovedEvent::WindowMovedEvent()
|
||||
: Event(KGE_EVENT(WindowMovedEvent))
|
||||
: WindowEvent(KGE_EVENT(WindowMovedEvent))
|
||||
, x(0)
|
||||
, y(0)
|
||||
{
|
||||
}
|
||||
|
||||
WindowResizedEvent::WindowResizedEvent()
|
||||
: Event(KGE_EVENT(WindowResizedEvent))
|
||||
: WindowEvent(KGE_EVENT(WindowResizedEvent))
|
||||
, width(0)
|
||||
, height(0)
|
||||
{
|
||||
}
|
||||
|
||||
WindowFocusChangedEvent::WindowFocusChangedEvent()
|
||||
: Event(KGE_EVENT(WindowFocusChangedEvent))
|
||||
: WindowEvent(KGE_EVENT(WindowFocusChangedEvent))
|
||||
, focus(false)
|
||||
{
|
||||
}
|
||||
|
||||
WindowTitleChangedEvent::WindowTitleChangedEvent()
|
||||
: Event(KGE_EVENT(WindowTitleChangedEvent))
|
||||
: WindowEvent(KGE_EVENT(WindowTitleChangedEvent))
|
||||
, title()
|
||||
{
|
||||
}
|
||||
|
||||
WindowClosedEvent::WindowClosedEvent()
|
||||
: Event(KGE_EVENT(WindowClosedEvent))
|
||||
: WindowEvent(KGE_EVENT(WindowClosedEvent))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
KGE_DECLARE_SMART_PTR(WindowEvent);
|
||||
KGE_DECLARE_SMART_PTR(WindowMovedEvent);
|
||||
KGE_DECLARE_SMART_PTR(WindowResizedEvent);
|
||||
KGE_DECLARE_SMART_PTR(WindowFocusChangedEvent);
|
||||
KGE_DECLARE_SMART_PTR(WindowTitleChangedEvent);
|
||||
KGE_DECLARE_SMART_PTR(WindowClosedEvent);
|
||||
|
||||
/**
|
||||
* \addtogroup Events
|
||||
* @{
|
||||
|
|
@ -33,12 +40,14 @@ namespace kiwano
|
|||
class KGE_API WindowEvent
|
||||
: public Event
|
||||
{
|
||||
public:
|
||||
WindowEvent(const EventType& type);
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 窗口移动事件
|
||||
class KGE_API WindowMovedEvent
|
||||
: public Event
|
||||
: public WindowEvent
|
||||
{
|
||||
public:
|
||||
int x; ///< 窗口左上角 x 坐标
|
||||
|
|
@ -50,11 +59,11 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 窗口大小变化事件
|
||||
class KGE_API WindowResizedEvent
|
||||
: public Event
|
||||
: public WindowEvent
|
||||
{
|
||||
public:
|
||||
int width; ///< 窗口宽度
|
||||
int height; ///< 窗口高度
|
||||
uint32_t width; ///< ´°¿Ú¿í¶È
|
||||
uint32_t height; ///< ´°¿Ú¸ß¶È
|
||||
|
||||
WindowResizedEvent();
|
||||
};
|
||||
|
|
@ -62,7 +71,7 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 窗口焦点变化事件
|
||||
class KGE_API WindowFocusChangedEvent
|
||||
: public Event
|
||||
: public WindowEvent
|
||||
{
|
||||
public:
|
||||
bool focus; ///< 是否获取到焦点
|
||||
|
|
@ -73,7 +82,7 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 窗口标题更改事件
|
||||
class KGE_API WindowTitleChangedEvent
|
||||
: public Event
|
||||
: public WindowEvent
|
||||
{
|
||||
public:
|
||||
String title; ///< 标题
|
||||
|
|
@ -84,7 +93,7 @@ namespace kiwano
|
|||
/// \~chinese
|
||||
/// @brief 窗口关闭事件
|
||||
class KGE_API WindowClosedEvent
|
||||
: public Event
|
||||
: public WindowEvent
|
||||
{
|
||||
public:
|
||||
WindowClosedEvent();
|
||||
|
|
@ -95,13 +104,13 @@ namespace kiwano
|
|||
template <>
|
||||
struct IsEventType<WindowEvent>
|
||||
{
|
||||
inline bool operator()(const Event& evt) const
|
||||
inline bool operator()(const Event* evt) const
|
||||
{
|
||||
return evt.GetType() == KGE_EVENT(WindowMovedEvent)
|
||||
|| evt.GetType() == KGE_EVENT(WindowResizedEvent)
|
||||
|| evt.GetType() == KGE_EVENT(WindowFocusChangedEvent)
|
||||
|| evt.GetType() == KGE_EVENT(WindowTitleChangedEvent)
|
||||
|| evt.GetType() == KGE_EVENT(WindowClosedEvent);
|
||||
return evt->GetType() == KGE_EVENT(WindowMovedEvent)
|
||||
|| evt->GetType() == KGE_EVENT(WindowResizedEvent)
|
||||
|| evt->GetType() == KGE_EVENT(WindowFocusChangedEvent)
|
||||
|| evt->GetType() == KGE_EVENT(WindowTitleChangedEvent)
|
||||
|| evt->GetType() == KGE_EVENT(WindowClosedEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ namespace kiwano
|
|||
Tab = VK_TAB, ///< TAB¼ü
|
||||
Delete = VK_DELETE, ///< ɾ³ý¼ü
|
||||
Back = VK_BACK, ///< Í˸ñ¼ü
|
||||
Super = VK_LWIN, ///< Cmd/Super/Windows¼ü
|
||||
|
||||
A = 0x41, ///< A¼ü
|
||||
B, ///< B¼ü
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#include <kiwano/core/TimerManager.h>
|
||||
#include <kiwano/core/AsyncTask.h>
|
||||
#include <kiwano/core/Resource.h>
|
||||
#include <kiwano/core/Director.h>
|
||||
|
||||
|
||||
//
|
||||
|
|
@ -112,7 +113,6 @@
|
|||
#include <kiwano/platform/FileSystem.h>
|
||||
#include <kiwano/platform/Input.h>
|
||||
#include <kiwano/platform/Window.h>
|
||||
#include <kiwano/platform/Director.h>
|
||||
#include <kiwano/platform/Application.h>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,19 +19,13 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/platform/Application.h>
|
||||
#include <kiwano/platform/Input.h>
|
||||
#include <kiwano/platform/Director.h>
|
||||
#include <kiwano/core/Director.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/renderer/TextureCache.h>
|
||||
#include <kiwano/utils/ResourceCache.h>
|
||||
|
||||
#include <windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM
|
||||
#include <imm.h> // ImmAssociateContext
|
||||
|
||||
#pragma comment(lib, "imm32.lib")
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
namespace
|
||||
|
|
@ -62,12 +56,8 @@ namespace kiwano
|
|||
namespace kiwano
|
||||
{
|
||||
Application::Application()
|
||||
: end_(true)
|
||||
, inited_(false)
|
||||
, time_scale_(1.f)
|
||||
: time_scale_(1.f)
|
||||
{
|
||||
::CoInitialize(nullptr);
|
||||
|
||||
Use(&Renderer::instance());
|
||||
Use(&Input::instance());
|
||||
Use(&Director::instance());
|
||||
|
|
@ -76,13 +66,11 @@ namespace kiwano
|
|||
Application::~Application()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
::CoUninitialize();
|
||||
}
|
||||
|
||||
void Application::Init(const Config& config)
|
||||
void Application::Run(const Config& config)
|
||||
{
|
||||
Window::instance().Init(config.window, Application::WndProc);
|
||||
Window::instance().Init(config.window);
|
||||
Renderer::instance().Init(config.render);
|
||||
|
||||
// Setup all components
|
||||
|
|
@ -100,33 +88,24 @@ namespace kiwano
|
|||
// Everything is ready
|
||||
OnReady();
|
||||
|
||||
HWND hwnd = Window::instance().GetHandle();
|
||||
last_update_time_ = Time::Now();
|
||||
|
||||
// disable imm
|
||||
::ImmAssociateContext(hwnd, nullptr);
|
||||
|
||||
// use Application instance in message loop
|
||||
::SetWindowLongPtr(hwnd, GWLP_USERDATA, LONG_PTR(this));
|
||||
|
||||
inited_ = true;
|
||||
}
|
||||
|
||||
void Application::Run()
|
||||
{
|
||||
KGE_ASSERT(inited_ && "Calling Application::Run before Application::Init");
|
||||
|
||||
end_ = false;
|
||||
|
||||
Window::instance().Prepare();
|
||||
while (!end_)
|
||||
Window& window = Window::instance();
|
||||
while (!window.ShouldClose())
|
||||
{
|
||||
Window::instance().PollEvents();
|
||||
while (EventPtr evt = window.PollEvent())
|
||||
{
|
||||
DispatchEvent(evt.get());
|
||||
}
|
||||
|
||||
Update();
|
||||
Render();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::Quit()
|
||||
{
|
||||
end_ = true;
|
||||
Window::instance().Destroy();
|
||||
}
|
||||
|
||||
void Application::Destroy()
|
||||
|
|
@ -136,18 +115,11 @@ namespace kiwano
|
|||
ResourceCache::instance().Clear();
|
||||
TextureCache::instance().Clear();
|
||||
|
||||
if (inited_)
|
||||
for (auto iter = comps_.rbegin(); iter != comps_.rend(); ++iter)
|
||||
{
|
||||
inited_ = false;
|
||||
|
||||
for (auto iter = comps_.rbegin(); iter != comps_.rend(); ++iter)
|
||||
{
|
||||
(*iter)->DestroyComponent();
|
||||
}
|
||||
comps_.clear();
|
||||
(*iter)->DestroyComponent();
|
||||
}
|
||||
|
||||
Window::instance().Destroy();
|
||||
comps_.clear();
|
||||
}
|
||||
|
||||
void Application::Use(ComponentBase* component)
|
||||
|
|
@ -210,11 +182,10 @@ namespace kiwano
|
|||
|
||||
// Updating
|
||||
{
|
||||
static auto last = Time::Now();
|
||||
const Time now = Time::Now();
|
||||
const Duration dt = (now - last_update_time_) * time_scale_;
|
||||
|
||||
const auto now = Time::Now();
|
||||
const auto dt = (now - last) * time_scale_;
|
||||
last = now;
|
||||
last_update_time_ = now;
|
||||
|
||||
for (auto c : update_comps_)
|
||||
{
|
||||
|
|
@ -251,7 +222,7 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
void Application::DispatchEvent(Event& evt)
|
||||
void Application::DispatchEvent(Event* evt)
|
||||
{
|
||||
for (auto c : event_comps_)
|
||||
{
|
||||
|
|
@ -264,215 +235,4 @@ namespace kiwano
|
|||
std::lock_guard<std::mutex> lock(perform_mutex_);
|
||||
functions_to_perform_.push(func);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
Application* app = reinterpret_cast<Application*>(static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA)));
|
||||
if (app == nullptr)
|
||||
{
|
||||
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
// Handle Message
|
||||
for (auto c : app->event_comps_)
|
||||
{
|
||||
c->HandleMessage(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_PAINT:
|
||||
{
|
||||
app->Update();
|
||||
app->Render();
|
||||
|
||||
::InvalidateRect(hwnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
bool down = msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN;
|
||||
if (down)
|
||||
{
|
||||
KeyDownEvent evt;
|
||||
evt.code = static_cast<int>(wparam);
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyUpEvent evt;
|
||||
evt.code = static_cast<int>(wparam);
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
{
|
||||
KeyCharEvent evt;
|
||||
evt.value = static_cast<char>(wparam);
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
//case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
//case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
//case WM_RBUTTONDBLCLK:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
MouseUpEvent 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;
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
|
||||
{
|
||||
KGE_SYS_LOG(L"Window minimized");
|
||||
}
|
||||
else
|
||||
{
|
||||
// KGE_SYS_LOG(L"Window resized");
|
||||
|
||||
Window::instance().UpdateWindowRect();
|
||||
|
||||
WindowResizedEvent evt;
|
||||
evt.width = LOWORD(lparam);
|
||||
evt.height = HIWORD(lparam);
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOVE:
|
||||
{
|
||||
int x = (int)(short)LOWORD(lparam);
|
||||
int y = (int)(short)HIWORD(lparam);
|
||||
|
||||
WindowMovedEvent evt;
|
||||
evt.x = x;
|
||||
evt.y = y;
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
bool active = (LOWORD(wparam) != WA_INACTIVE);
|
||||
|
||||
Window::instance().SetActive(active);
|
||||
|
||||
WindowFocusChangedEvent evt;
|
||||
evt.focus = active;
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETTEXT:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window title changed");
|
||||
|
||||
WindowTitleChangedEvent evt;
|
||||
evt.title = reinterpret_cast<const wchar_t*>(lparam);
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETICON:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window icon changed");
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
KGE_SYS_LOG(L"The display resolution has changed");
|
||||
|
||||
::InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
Window::instance().UpdateCursor();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window is closing");
|
||||
|
||||
if (!app->OnClosing())
|
||||
{
|
||||
WindowClosedEvent evt;
|
||||
app->DispatchEvent(evt);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window was destroyed");
|
||||
|
||||
app->Quit();
|
||||
app->OnDestroy();
|
||||
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,15 +80,6 @@ namespace kiwano
|
|||
|
||||
virtual ~Application();
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 初始化应用程序
|
||||
* @details 初始化所有功能组件后执行 OnReady 函数
|
||||
* @param config 初始化配置
|
||||
* @attention 应在使用其他功能前执行初始化,否则可能引发异常
|
||||
*/
|
||||
void Init(Config const& config = Config());
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 初始化完成处理
|
||||
|
|
@ -96,14 +87,6 @@ namespace kiwano
|
|||
*/
|
||||
virtual void OnReady() {}
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 窗口关闭处理
|
||||
* @details 重载该函数以处理用户关闭应用程序窗口时的行为
|
||||
* @return 返回 true 则正常关闭窗口,否则阻止窗口关闭
|
||||
*/
|
||||
virtual bool OnClosing() { return true; }
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 应用程序销毁处理
|
||||
|
|
@ -114,9 +97,11 @@ namespace kiwano
|
|||
/**
|
||||
* \~chinese
|
||||
* @brief 启动应用程序
|
||||
* @details 初始化所有功能组件后执行 OnReady 函数
|
||||
* @param config 初始化配置
|
||||
* @note 该函数是阻塞的,应用程序结束时函数返回
|
||||
*/
|
||||
void Run();
|
||||
void Run(Config const& config = Config());
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
|
|
@ -152,7 +137,7 @@ namespace kiwano
|
|||
* @details 将事件分发给所有事件功能组件
|
||||
* @param evt 事件
|
||||
*/
|
||||
void DispatchEvent(Event& evt);
|
||||
void DispatchEvent(Event* evt);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
|
|
@ -167,13 +152,9 @@ namespace kiwano
|
|||
|
||||
void Update();
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND, UINT32, WPARAM, LPARAM);
|
||||
|
||||
private:
|
||||
bool end_;
|
||||
bool inited_;
|
||||
float time_scale_;
|
||||
|
||||
float time_scale_;
|
||||
Time last_update_time_;
|
||||
Vector<ComponentBase*> comps_;
|
||||
Vector<RenderComponent*> render_comps_;
|
||||
Vector<UpdateComponent*> update_comps_;
|
||||
|
|
|
|||
|
|
@ -20,24 +20,73 @@
|
|||
|
||||
#include <kiwano/platform/Input.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM
|
||||
#include <kiwano/core/event/KeyEvent.h>
|
||||
#include <kiwano/core/event/MouseEvent.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
Input::Input()
|
||||
: want_update_(false)
|
||||
, mouse_pos_x_(0.f)
|
||||
, mouse_pos_y_(0.f)
|
||||
, keys_{}
|
||||
, keys_pressed_{}
|
||||
, keys_released_{}
|
||||
{
|
||||
ZeroMemory(keys_, sizeof(keys_));
|
||||
ZeroMemory(keys_pressed_, sizeof(keys_pressed_));
|
||||
ZeroMemory(keys_released_, sizeof(keys_released_));
|
||||
}
|
||||
|
||||
Input::~Input()
|
||||
{
|
||||
}
|
||||
|
||||
void Input::AfterUpdate()
|
||||
{
|
||||
if (want_update_)
|
||||
{
|
||||
want_update_ = false;
|
||||
|
||||
keys_pressed_.fill(false);
|
||||
keys_released_.fill(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool Input::IsDown(int key_or_btn) const
|
||||
{
|
||||
KGE_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
if (key_or_btn >= 0 && key_or_btn < KEY_NUM)
|
||||
return keys_[key_or_btn];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::WasPressed(int key_or_btn) const
|
||||
{
|
||||
KGE_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
if (key_or_btn >= 0 && key_or_btn < KEY_NUM)
|
||||
return keys_pressed_[key_or_btn];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::WasReleased(int key_or_btn) const
|
||||
{
|
||||
KGE_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
if (key_or_btn >= 0 && key_or_btn < KEY_NUM)
|
||||
return keys_released_[key_or_btn];
|
||||
return false;
|
||||
}
|
||||
|
||||
float Input::GetMouseX() const
|
||||
{
|
||||
return mouse_pos_.x;
|
||||
}
|
||||
|
||||
float Input::GetMouseY() const
|
||||
{
|
||||
return mouse_pos_.y;
|
||||
}
|
||||
|
||||
Point Input::GetMousePos() const
|
||||
{
|
||||
return mouse_pos_;
|
||||
}
|
||||
|
||||
void Input::UpdateKey(int key, bool down)
|
||||
{
|
||||
if (down && !keys_[key])
|
||||
|
|
@ -50,94 +99,38 @@ namespace kiwano
|
|||
want_update_ = true;
|
||||
}
|
||||
|
||||
void Input::UpdateMousePos(float x, float y)
|
||||
void Input::UpdateMousePos(const Point& pos)
|
||||
{
|
||||
mouse_pos_x_ = x;
|
||||
mouse_pos_y_ = y;
|
||||
mouse_pos_ = pos;
|
||||
}
|
||||
|
||||
void Input::AfterUpdate()
|
||||
void Input::HandleEvent(Event* evt)
|
||||
{
|
||||
if (want_update_)
|
||||
if (evt->IsType<MouseEvent>())
|
||||
{
|
||||
want_update_ = false;
|
||||
|
||||
ZeroMemory(keys_pressed_, sizeof(keys_pressed_));
|
||||
ZeroMemory(keys_released_, sizeof(keys_released_));
|
||||
if (evt->IsType<MouseMoveEvent>())
|
||||
{
|
||||
UpdateMousePos(dynamic_cast<MouseMoveEvent*>(evt)->pos);
|
||||
}
|
||||
else if (evt->IsType<MouseDownEvent>())
|
||||
{
|
||||
UpdateKey(dynamic_cast<MouseDownEvent*>(evt)->button, true);
|
||||
}
|
||||
else if (evt->IsType<MouseUpEvent>())
|
||||
{
|
||||
UpdateKey(dynamic_cast<MouseUpEvent*>(evt)->button, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Input::HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
else if (evt->IsType<KeyEvent>())
|
||||
{
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
//case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
//case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
//case WM_RBUTTONDBLCLK:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) { UpdateKey(VK_LBUTTON, (msg == WM_LBUTTONDOWN) ? true : false); }
|
||||
else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONUP) { UpdateKey(VK_RBUTTON, (msg == WM_RBUTTONDOWN) ? true : false); }
|
||||
else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONUP) { UpdateKey(VK_MBUTTON, (msg == WM_MBUTTONDOWN) ? true : false); }
|
||||
else if (msg == WM_MOUSEMOVE) { UpdateMousePos(static_cast<float>(GET_X_LPARAM(lparam)), static_cast<float>(GET_Y_LPARAM(lparam))); }
|
||||
|
||||
break;
|
||||
if (evt->IsType<KeyDownEvent>())
|
||||
{
|
||||
UpdateKey(dynamic_cast<KeyDownEvent*>(evt)->code, true);
|
||||
}
|
||||
else if (evt->IsType<KeyUpEvent>())
|
||||
{
|
||||
UpdateKey(dynamic_cast<KeyUpEvent*>(evt)->code, false);
|
||||
}
|
||||
}
|
||||
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
bool down = msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN;
|
||||
UpdateKey((int)wparam, down);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Input::IsDown(int key_or_btn)
|
||||
{
|
||||
KGE_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
if (key_or_btn >= 0 && key_or_btn < KEY_NUM)
|
||||
return keys_[key_or_btn];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::WasPressed(int key_or_btn)
|
||||
{
|
||||
KGE_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
if (key_or_btn >= 0 && key_or_btn < KEY_NUM)
|
||||
return keys_pressed_[key_or_btn];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::WasReleased(int key_or_btn)
|
||||
{
|
||||
KGE_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
if (key_or_btn >= 0 && key_or_btn < KEY_NUM)
|
||||
return keys_released_[key_or_btn];
|
||||
return false;
|
||||
}
|
||||
|
||||
float Input::GetMouseX()
|
||||
{
|
||||
return mouse_pos_x_;
|
||||
}
|
||||
|
||||
float Input::GetMouseY()
|
||||
{
|
||||
return mouse_pos_y_;
|
||||
}
|
||||
|
||||
Point Input::GetMousePos()
|
||||
{
|
||||
return Point{ mouse_pos_x_, mouse_pos_y_ };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#pragma once
|
||||
#include <kiwano/macros.h>
|
||||
#include <kiwano/core/common.h>
|
||||
#include <kiwano/math/math.h>
|
||||
#include <kiwano/core/keys.h>
|
||||
#include <kiwano/core/common.h>
|
||||
#include <kiwano/core/event/Event.h>
|
||||
#include <kiwano/core/Component.h>
|
||||
|
||||
namespace kiwano
|
||||
|
|
@ -46,7 +46,7 @@ namespace kiwano
|
|||
* @return 頁倦屎瓜梓和
|
||||
* @see kiwano::KeyCode kiwano::MouseButton
|
||||
*/
|
||||
bool IsDown(int key_or_btn);
|
||||
bool IsDown(int key_or_btn) const;
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
|
|
@ -55,7 +55,7 @@ namespace kiwano
|
|||
* @return 頁倦胡瓜泣似
|
||||
* @see kiwano::KeyCode kiwano::MouseButton
|
||||
*/
|
||||
bool WasPressed(int key_or_btn);
|
||||
bool WasPressed(int key_or_btn) const;
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
|
|
@ -64,28 +64,28 @@ namespace kiwano
|
|||
* @return 頁倦胡箕軟
|
||||
* @see kiwano::KeyCode kiwano::MouseButton
|
||||
*/
|
||||
bool WasReleased(int key_or_btn);
|
||||
bool WasReleased(int key_or_btn) const;
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 資誼報炎 x 恫炎
|
||||
* @return 報炎 x 恫炎
|
||||
*/
|
||||
float GetMouseX();
|
||||
float GetMouseX() const;
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 資誼報炎 y 恫炎
|
||||
* @return 報炎 y 恫炎
|
||||
*/
|
||||
float GetMouseY();
|
||||
float GetMouseY() const;
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 資誼報炎恫炎
|
||||
* @return 報炎恫炎
|
||||
*/
|
||||
Point GetMousePos();
|
||||
Point GetMousePos() const;
|
||||
|
||||
public:
|
||||
void SetupComponent() override {}
|
||||
|
|
@ -94,25 +94,24 @@ namespace kiwano
|
|||
|
||||
void AfterUpdate() override;
|
||||
|
||||
void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override;
|
||||
|
||||
void UpdateKey(int, bool);
|
||||
|
||||
void UpdateMousePos(float, float);
|
||||
void HandleEvent(Event* evt) override;
|
||||
|
||||
private:
|
||||
Input();
|
||||
|
||||
~Input();
|
||||
|
||||
void UpdateKey(int, bool);
|
||||
|
||||
void UpdateMousePos(const Point& pos);
|
||||
|
||||
private:
|
||||
static const int KEY_NUM = 256;
|
||||
|
||||
bool want_update_;
|
||||
bool keys_[KEY_NUM];
|
||||
bool keys_pressed_[KEY_NUM];
|
||||
bool keys_released_[KEY_NUM];
|
||||
float mouse_pos_x_;
|
||||
float mouse_pos_y_;
|
||||
Point mouse_pos_;
|
||||
std::array<bool, KEY_NUM> keys_;
|
||||
std::array<bool, KEY_NUM> keys_pressed_;
|
||||
std::array<bool, KEY_NUM> keys_released_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,14 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/platform/Window.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/platform/Application.h>
|
||||
#include <kiwano/core/event/MouseEvent.h>
|
||||
#include <kiwano/core/event/KeyEvent.h>
|
||||
#include <kiwano/core/event/WindowEvent.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
|
||||
#include <imm.h> // ImmAssociateContext
|
||||
#pragma comment(lib, "imm32.lib")
|
||||
|
||||
#define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
|
||||
#define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
|
||||
|
|
@ -65,19 +71,19 @@ namespace kiwano
|
|||
{
|
||||
}
|
||||
|
||||
void Window::Init(WindowConfig const& config, WNDPROC proc)
|
||||
void Window::Init(WindowConfig const& config)
|
||||
{
|
||||
HINSTANCE hinst = GetModuleHandleW(nullptr);
|
||||
WNDCLASSEX wcex = { 0 };
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.lpszClassName = KGE_WND_CLASS_NAME;
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */;
|
||||
wcex.lpfnWndProc = proc;
|
||||
wcex.lpfnWndProc = Window::WndProc;
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = sizeof(LONG_PTR);
|
||||
wcex.hInstance = hinst;
|
||||
wcex.hbrBackground = nullptr;
|
||||
wcex.hbrBackground = (HBRUSH)(::GetStockObject(BLACK_BRUSH));
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.hCursor = ::LoadCursorW(hinst, IDC_ARROW);
|
||||
|
||||
|
|
@ -155,18 +161,18 @@ namespace kiwano
|
|||
{
|
||||
::UnregisterClass(KGE_WND_CLASS_NAME, hinst);
|
||||
win32::ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(handle_, &rc);
|
||||
width_ = rc.right - rc.left;
|
||||
height_ = rc.bottom - rc.top;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::Prepare()
|
||||
{
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
|
||||
// disable imm
|
||||
::ImmAssociateContext(handle_, nullptr);
|
||||
|
||||
// use Application instance in message loop
|
||||
::SetWindowLongPtr(handle_, GWLP_USERDATA, LONG_PTR(this));
|
||||
|
||||
::ShowWindow(handle_, SW_SHOWNORMAL);
|
||||
::UpdateWindow(handle_);
|
||||
|
||||
|
|
@ -176,15 +182,22 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
void Window::PollEvents()
|
||||
EventPtr Window::PollEvent()
|
||||
{
|
||||
static MSG msg = {};
|
||||
|
||||
if (::GetMessageW(&msg, nullptr, 0, 0))
|
||||
MSG msg;
|
||||
while (::PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
EventPtr evt;
|
||||
if (!event_queue_.empty())
|
||||
{
|
||||
evt = event_queue_.front();
|
||||
event_queue_.pop();
|
||||
}
|
||||
return evt;
|
||||
}
|
||||
|
||||
String Window::GetTitle() const
|
||||
|
|
@ -293,7 +306,12 @@ namespace kiwano
|
|||
::SetWindowLongPtr(handle_, GWL_STYLE, GetWindowStyle());
|
||||
::SetWindowPos(handle_, HWND_NOTOPMOST, left, top, win_width, win_height, SWP_DRAWFRAME | SWP_FRAMECHANGED);
|
||||
|
||||
UpdateWindowRect();
|
||||
// Update window rect
|
||||
RECT rc;
|
||||
::GetClientRect(handle_, &rc);
|
||||
|
||||
width_ = static_cast<uint32_t>(rc.right - rc.left);
|
||||
height_ = static_cast<uint32_t>(rc.bottom - rc.top);
|
||||
}
|
||||
|
||||
::ShowWindow(handle_, SW_SHOWNORMAL);
|
||||
|
|
@ -305,28 +323,46 @@ namespace kiwano
|
|||
mouse_cursor_ = cursor;
|
||||
}
|
||||
|
||||
HWND Window::GetHandle() const
|
||||
WindowHandle Window::GetHandle() const
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
bool Window::ShouldClose()
|
||||
{
|
||||
return handle_ == nullptr;
|
||||
}
|
||||
|
||||
void Window::PushEvent(EventPtr evt)
|
||||
{
|
||||
event_queue_.push(evt);
|
||||
}
|
||||
|
||||
void Window::Destroy()
|
||||
{
|
||||
if (is_fullscreen_)
|
||||
RestoreResolution(device_name_);
|
||||
|
||||
if (device_name_)
|
||||
{
|
||||
delete[] device_name_;
|
||||
device_name_ = nullptr;
|
||||
}
|
||||
|
||||
if (handle_)
|
||||
{
|
||||
::DestroyWindow(handle_);
|
||||
handle_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(KGE_WIN32)
|
||||
|
||||
DWORD Window::GetWindowStyle() const
|
||||
{
|
||||
return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (resizable_ ? (WINDOW_RESIZABLE_STYLE) : (WINDOW_FIXED_STYLE));
|
||||
}
|
||||
|
||||
void Window::UpdateWindowRect()
|
||||
{
|
||||
if (!handle_)
|
||||
return;
|
||||
|
||||
RECT rc;
|
||||
::GetClientRect(handle_, &rc);
|
||||
|
||||
width_ = rc.right - rc.left;
|
||||
height_ = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
void Window::UpdateCursor()
|
||||
{
|
||||
LPTSTR win32_cursor = IDC_ARROW;
|
||||
|
|
@ -368,22 +404,185 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
void Window::Destroy()
|
||||
LRESULT CALLBACK Window::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (is_fullscreen_)
|
||||
RestoreResolution(device_name_);
|
||||
|
||||
if (device_name_)
|
||||
Window* window = reinterpret_cast<Window*>(static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA)));
|
||||
if (window == nullptr)
|
||||
{
|
||||
delete[] device_name_;
|
||||
device_name_ = nullptr;
|
||||
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
if (handle_)
|
||||
switch (msg)
|
||||
{
|
||||
::DestroyWindow(handle_);
|
||||
handle_ = nullptr;
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
KeyDownEventPtr evt = new KeyDownEvent;
|
||||
evt->code = static_cast<int>(wparam);
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
KeyUpEventPtr evt = new KeyUpEvent;
|
||||
evt->code = static_cast<int>(wparam);
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
{
|
||||
KeyCharEventPtr evt = new KeyCharEvent;
|
||||
evt->value = static_cast<char>(wparam);
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||
{
|
||||
MouseDownEventPtr evt = new MouseDownEvent;
|
||||
evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam)));
|
||||
|
||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { evt->button = MouseButton::Left; }
|
||||
else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { evt->button = MouseButton::Right; }
|
||||
else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { evt->button = MouseButton::Middle; }
|
||||
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
MouseUpEventPtr evt = new MouseUpEvent;
|
||||
evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam)));
|
||||
|
||||
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; }
|
||||
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
MouseMoveEventPtr evt = new MouseMoveEvent;
|
||||
evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam)));
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
MouseWheelEventPtr evt = new MouseWheelEvent;
|
||||
evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam)));
|
||||
evt->wheel = GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA;
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
|
||||
{
|
||||
KGE_SYS_LOG(L"Window minimized");
|
||||
}
|
||||
else
|
||||
{
|
||||
// KGE_SYS_LOG(L"Window resized");
|
||||
|
||||
window->width_ = ((uint32_t)(short)LOWORD(lparam));
|
||||
window->height_ = ((uint32_t)(short)HIWORD(lparam));
|
||||
|
||||
WindowResizedEventPtr evt = new WindowResizedEvent;
|
||||
evt->width = window->width_;
|
||||
evt->height = window->height_;
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOVE:
|
||||
{
|
||||
int x = ((int)(short)LOWORD(lparam));
|
||||
int y = ((int)(short)HIWORD(lparam));
|
||||
|
||||
WindowMovedEventPtr evt = new WindowMovedEvent;
|
||||
evt->x = x;
|
||||
evt->y = y;
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
bool active = (LOWORD(wparam) != WA_INACTIVE);
|
||||
|
||||
window->SetActive(active);
|
||||
|
||||
WindowFocusChangedEventPtr evt = new WindowFocusChangedEvent;
|
||||
evt->focus = active;
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETTEXT:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window title changed");
|
||||
|
||||
WindowTitleChangedEventPtr evt = new WindowTitleChangedEvent;
|
||||
evt->title.assign(reinterpret_cast<const wchar_t*>(lparam));
|
||||
window->PushEvent(evt);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETICON:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window icon changed");
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
KGE_SYS_LOG(L"The display resolution has changed");
|
||||
|
||||
::InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
window->UpdateCursor();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window is closing");
|
||||
|
||||
WindowClosedEventPtr evt = new WindowClosedEvent;
|
||||
window->PushEvent(evt);
|
||||
window->Destroy();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
KGE_SYS_LOG(L"Window was destroyed");
|
||||
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
@ -441,4 +640,6 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@
|
|||
|
||||
#pragma once
|
||||
#include <kiwano/macros.h>
|
||||
#include <kiwano/core/common.h>
|
||||
#include <kiwano/math/math.h>
|
||||
#include <kiwano/core/common.h>
|
||||
#include <kiwano/core/event/Event.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
|
@ -74,6 +75,10 @@ namespace kiwano
|
|||
);
|
||||
};
|
||||
|
||||
#if defined(KGE_WIN32)
|
||||
typedef HWND WindowHandle;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
|
|
@ -85,6 +90,13 @@ namespace kiwano
|
|||
friend Singleton<Window>;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 初始化窗口
|
||||
* @param config 窗口设置
|
||||
*/
|
||||
void Init(WindowConfig const& config);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief ťńČĄ´°żÚąęĚâ
|
||||
|
|
@ -151,39 +163,56 @@ namespace kiwano
|
|||
*/
|
||||
void SetCursor(CursorType cursor);
|
||||
|
||||
#ifdef KGE_WIN32
|
||||
public:
|
||||
void Init(WindowConfig const& config, WNDPROC proc);
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 轮询窗口事件
|
||||
* @return 返回事件队列中的第一个事件并将其从队列中移除,若事件队列为空则返回空指针
|
||||
*/
|
||||
EventPtr PollEvent();
|
||||
|
||||
void Prepare();
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 获取窗口句柄
|
||||
*/
|
||||
WindowHandle GetHandle() const;
|
||||
|
||||
void PollEvents();
|
||||
|
||||
HWND GetHandle() const;
|
||||
|
||||
DWORD GetWindowStyle() const;
|
||||
|
||||
void UpdateWindowRect();
|
||||
|
||||
void UpdateCursor();
|
||||
|
||||
void SetActive(bool actived);
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 是否需要关闭
|
||||
*/
|
||||
bool ShouldClose();
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 销毁窗口
|
||||
*/
|
||||
void Destroy();
|
||||
#endif
|
||||
|
||||
private:
|
||||
Window();
|
||||
|
||||
~Window();
|
||||
|
||||
void PushEvent(EventPtr evt);
|
||||
|
||||
#if defined(KGE_WIN32)
|
||||
DWORD GetWindowStyle() const;
|
||||
|
||||
void UpdateCursor();
|
||||
|
||||
void SetActive(bool actived);
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND, UINT32, WPARAM, LPARAM);
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool resizable_;
|
||||
bool is_fullscreen_;
|
||||
HWND handle_;
|
||||
int width_;
|
||||
int height_;
|
||||
wchar_t* device_name_;
|
||||
CursorType mouse_cursor_;
|
||||
bool resizable_;
|
||||
bool is_fullscreen_;
|
||||
WindowHandle handle_;
|
||||
uint32_t width_;
|
||||
uint32_t height_;
|
||||
wchar_t* device_name_;
|
||||
CursorType mouse_cursor_;
|
||||
std::queue<EventPtr> event_queue_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
#include <kiwano/renderer/Renderer.h>
|
||||
#include <kiwano/renderer/GeometrySink.h>
|
||||
#include <kiwano/core/event/WindowEvent.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/platform/Window.h>
|
||||
#include <kiwano/platform/FileSystem.h>
|
||||
|
||||
namespace kiwano
|
||||
|
|
@ -33,7 +33,7 @@ namespace kiwano
|
|||
}
|
||||
|
||||
Renderer::Renderer()
|
||||
: hwnd_(nullptr)
|
||||
: target_window_(nullptr)
|
||||
, vsync_(true)
|
||||
, clear_color_(Color::Black)
|
||||
{
|
||||
|
|
@ -53,19 +53,21 @@ namespace kiwano
|
|||
{
|
||||
KGE_SYS_LOG(L"Creating device resources");
|
||||
|
||||
hwnd_ = Window::instance().GetHandle();
|
||||
win32::ThrowIfFailed(::CoInitialize(nullptr));
|
||||
|
||||
target_window_ = Window::instance().GetHandle();
|
||||
output_size_ = Window::instance().GetSize();
|
||||
|
||||
d2d_res_ = nullptr;
|
||||
d3d_res_ = nullptr;
|
||||
drawing_state_block_ = nullptr;
|
||||
|
||||
HRESULT hr = hwnd_ ? S_OK : E_FAIL;
|
||||
HRESULT hr = target_window_ ? S_OK : E_FAIL;
|
||||
|
||||
// Direct3D device resources
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ID3DDeviceResources::Create(&d3d_res_, hwnd_);
|
||||
hr = ID3DDeviceResources::Create(&d3d_res_, target_window_);
|
||||
|
||||
// Direct2D device resources
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -136,6 +138,8 @@ namespace kiwano
|
|||
drawing_state_block_.reset();
|
||||
d2d_res_.reset();
|
||||
d3d_res_.reset();
|
||||
|
||||
::CoUninitialize();
|
||||
}
|
||||
|
||||
void Renderer::BeforeRender()
|
||||
|
|
@ -171,18 +175,12 @@ namespace kiwano
|
|||
win32::ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
|
||||
void Renderer::HandleEvent(Event* evt)
|
||||
{
|
||||
switch (msg)
|
||||
if (evt->IsType<WindowResizedEvent>())
|
||||
{
|
||||
case WM_SIZE:
|
||||
{
|
||||
uint32_t width = LOWORD(lparam);
|
||||
uint32_t height = HIWORD(lparam);
|
||||
|
||||
ResizeTarget(width, height);
|
||||
break;
|
||||
}
|
||||
auto window_evt = dynamic_cast<WindowResizedEvent*>(evt);
|
||||
ResizeTarget(window_evt->width, window_evt->height);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <kiwano/renderer/GifImage.h>
|
||||
#include <kiwano/renderer/Font.h>
|
||||
#include <kiwano/renderer/TextStyle.hpp>
|
||||
#include <kiwano/platform/Window.h>
|
||||
|
||||
#if defined(KGE_USE_DIRECTX10)
|
||||
# include "win32/D3D10DeviceResources.h"
|
||||
|
|
@ -278,7 +279,7 @@ namespace kiwano
|
|||
public:
|
||||
/// \~chinese
|
||||
/// @brief 获取目标窗口
|
||||
HWND GetTargetWindow() const;
|
||||
WindowHandle GetTargetWindow() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取渲染输出大小
|
||||
|
|
@ -303,7 +304,7 @@ namespace kiwano
|
|||
|
||||
void AfterRender() override;
|
||||
|
||||
void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override;
|
||||
void HandleEvent(Event* evt) override;
|
||||
|
||||
private:
|
||||
Renderer();
|
||||
|
|
@ -315,10 +316,10 @@ namespace kiwano
|
|||
void ResizeTarget(uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
bool vsync_;
|
||||
HWND hwnd_;
|
||||
Color clear_color_;
|
||||
Size output_size_;
|
||||
bool vsync_;
|
||||
WindowHandle target_window_;
|
||||
Color clear_color_;
|
||||
Size output_size_;
|
||||
|
||||
ComPtr<ID2DDeviceResources> d2d_res_;
|
||||
ComPtr<ID3DDeviceResources> d3d_res_;
|
||||
|
|
@ -330,7 +331,7 @@ namespace kiwano
|
|||
|
||||
/** @} */
|
||||
|
||||
inline HWND Renderer::GetTargetWindow() const { return hwnd_; }
|
||||
inline WindowHandle Renderer::GetTargetWindow() const { return target_window_; }
|
||||
|
||||
inline Size const& Renderer::GetOutputSize() const { return output_size_; }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue