diff --git a/project/Box2DSample/main.cpp b/project/Box2DSample/main.cpp
index d51a78e1..39837069 100644
--- a/project/Box2DSample/main.cpp
+++ b/project/Box2DSample/main.cpp
@@ -132,10 +132,7 @@ class MainScene
public:
MainScene()
{
- // 修改场景大小, 并设置可响应状态, 使场景可以
- // 接收到鼠标 Click 消息
- auto size = Window::Instance().GetSize();
- SetSize(size);
+ // 设置可响应状态, 使场景可以接收到鼠标 Click 消息
SetResponsible(true);
// 添加消息监听
@@ -144,7 +141,7 @@ public:
// 创建物理世界
world_ = new b2World(b2Vec2(0, 10));
- BoardPtr board = new Board(world_, Size(GetWidth() - 100, 20), Point(size.x / 2, size.y - 50));
+ BoardPtr board = new Board(world_, Size(GetWidth() - 100, 20), Point(GetWidth() / 2, GetHeight() - 50));
AddChild(board);
CirclePtr circle = new Circle(world_, Point(320, 240));
@@ -208,7 +205,9 @@ int main()
try
{
Application app;
- app.Init();
+
+ Options options(L"Box2D Demo");
+ app.Init(options);
ScenePtr scene = new MainScene;
app.EnterScene(scene);
diff --git a/project/Easy2D/Easy2D.vcxproj b/project/Easy2D/Easy2D.vcxproj
index 48fc5fed..ef302934 100644
--- a/project/Easy2D/Easy2D.vcxproj
+++ b/project/Easy2D/Easy2D.vcxproj
@@ -7,19 +7,23 @@
+
+
+
+
+
+
+
+
-
-
-
-
@@ -29,24 +33,20 @@
-
+
-
-
+
-
-
-
@@ -63,6 +63,7 @@
+
@@ -101,6 +102,7 @@
+
@@ -119,7 +121,6 @@
-
diff --git a/project/Easy2D/Easy2D.vcxproj.filters b/project/Easy2D/Easy2D.vcxproj.filters
index 1e8ff355..9e431f3b 100644
--- a/project/Easy2D/Easy2D.vcxproj.filters
+++ b/project/Easy2D/Easy2D.vcxproj.filters
@@ -19,6 +19,9 @@
{836608a6-7443-48f9-8acd-18d3ba664348}
+
+ {86e2d0f2-a9d0-4456-b6a5-d480228bbf82}
+
@@ -40,9 +43,6 @@
core
-
- core
-
core
@@ -100,9 +100,6 @@
ui
-
- core
-
core
@@ -121,9 +118,6 @@
core
-
- core
-
utils
@@ -154,9 +148,6 @@
core
-
- core
-
core
@@ -178,27 +169,12 @@
core
-
- core
-
-
- core
-
-
- core
-
core
core
-
- core
-
-
- core
-
core
@@ -244,7 +220,33 @@
audio
-
+
+ core
+
+
+
+
+ common
+
+
+ common
+
+
+ common
+
+
+ common
+
+
+ common
+
+
+ common
+
+
+ common
+
+
core
@@ -297,9 +299,6 @@
core
-
- math
-
utils
@@ -393,5 +392,8 @@
audio
+
+ core
+
\ No newline at end of file
diff --git a/project/ImGuiSample/ImGuiSample.vcxproj b/project/ImGuiSample/ImGuiSample.vcxproj
index 6e9bad0c..144cccaa 100644
--- a/project/ImGuiSample/ImGuiSample.vcxproj
+++ b/project/ImGuiSample/ImGuiSample.vcxproj
@@ -136,8 +136,9 @@
-
-
+
+
+
@@ -147,8 +148,10 @@
-
-
+
+
+
+
diff --git a/project/ImGuiSample/ImGuiSample.vcxproj.filters b/project/ImGuiSample/ImGuiSample.vcxproj.filters
index aa603c21..a89be911 100644
--- a/project/ImGuiSample/ImGuiSample.vcxproj.filters
+++ b/project/ImGuiSample/ImGuiSample.vcxproj.filters
@@ -2,8 +2,6 @@
-
-
imgui
@@ -16,10 +14,17 @@
imgui
+
+ easy2d-imgui
+
+
+ easy2d-imgui
+
+
+ easy2d-imgui
+
-
-
imgui
@@ -38,10 +43,25 @@
imgui
+
+ easy2d-imgui
+
+
+ easy2d-imgui
+
+
+ easy2d-imgui
+
+
+ easy2d-imgui
+
{24ae99cd-ee12-481f-bb03-d8be40d99342}
+
+ {37f1585a-e992-454a-8cac-e9a6142b08b6}
+
\ No newline at end of file
diff --git a/project/ImGuiSample/easy2d-imgui/ImGuiLayer.cpp b/project/ImGuiSample/easy2d-imgui/ImGuiLayer.cpp
new file mode 100644
index 00000000..166a8617
--- /dev/null
+++ b/project/ImGuiSample/easy2d-imgui/ImGuiLayer.cpp
@@ -0,0 +1,165 @@
+// Copyright (C) 2019 Nomango
+
+#include "easy2d-imgui.h"
+
+namespace easy2d
+{
+ namespace
+ {
+ Map mouse_buttons =
+ {
+ { MouseButton::Left, 0 },
+ { MouseButton::Right, 1 },
+ { MouseButton::Middle, 2 }
+ };
+ }
+
+ ImGuiLayer::ImGuiLayer()
+ {
+ target_window_ = Renderer::Instance().GetTargetWindow();
+ }
+
+ ImGuiLayer::~ImGuiLayer()
+ {
+ }
+
+ void ImGuiLayer::OnMouseButtonDown(int btn, Point const & p)
+ {
+ if (!ImGui::IsAnyMouseDown() && ::GetCapture() == nullptr)
+ ::SetCapture(target_window_);
+
+ E2D_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
+ ImGui::GetIO().MouseDown[mouse_buttons[btn]] = true;
+ }
+
+ void ImGuiLayer::OnMouseButtonUp(int btn, Point const & p)
+ {
+ E2D_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
+ ImGui::GetIO().MouseDown[mouse_buttons[btn]] = false;
+
+ if (!ImGui::IsAnyMouseDown() && ::GetCapture() == target_window_)
+ ::ReleaseCapture();
+ }
+
+ void ImGuiLayer::OnMouseWheel(float wheel)
+ {
+ ImGui::GetIO().MouseWheel += wheel;
+ }
+
+ void ImGuiLayer::OnKeyDown(int key)
+ {
+ E2D_ASSERT(key < 256);
+ ImGui::GetIO().KeysDown[key] = 1;
+ }
+
+ void ImGuiLayer::OnKeyUp(int key)
+ {
+ E2D_ASSERT(key < 256);
+ ImGui::GetIO().KeysDown[key] = 0;
+ }
+
+ void ImGuiLayer::OnChar(char c)
+ {
+ ImGui::GetIO().AddInputCharacter(c);
+ }
+
+ void ImGuiLayer::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();
+ }
+
+ void ImGuiLayer::OnRender()
+ {
+ ImGuiView::Instance().NewFrame();
+
+ for (const auto& pipeline : pipelines_)
+ {
+ pipeline.second();
+ }
+
+ ImGuiView::Instance().Render();
+ }
+
+ void ImGuiLayer::UpdateMousePos()
+ {
+ ImGuiIO& io = ImGui::GetIO();
+
+ // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
+ if (io.WantSetMousePos)
+ {
+ POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
+ HWND hwnd = target_window_;
+ ::ClientToScreen(hwnd, &pos);
+ ::SetCursorPos(pos.x, pos.y);
+ }
+
+ Point pos = Input::Instance().GetMousePos();
+ io.MousePos = ImVec2(pos.x, pos.y);
+ }
+
+ void ImGuiLayer::UpdateMouseCursor()
+ {
+ static ImGuiMouseCursor last_mouse_cursor = ImGuiMouseCursor_COUNT;
+
+ ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
+
+ if (last_mouse_cursor != imgui_cursor)
+ {
+ last_mouse_cursor = imgui_cursor;
+
+ if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
+ return;
+
+ MouseCursor cursor = MouseCursor::Arrow;
+ switch (imgui_cursor)
+ {
+ case ImGuiMouseCursor_Arrow: cursor = MouseCursor::Arrow; break;
+ case ImGuiMouseCursor_TextInput: cursor = MouseCursor::TextInput; break;
+ case ImGuiMouseCursor_ResizeAll: cursor = MouseCursor::SizeAll; break;
+ case ImGuiMouseCursor_ResizeEW: cursor = MouseCursor::SizeWE; break;
+ case ImGuiMouseCursor_ResizeNS: cursor = MouseCursor::SizeNS; break;
+ case ImGuiMouseCursor_ResizeNESW: cursor = MouseCursor::SizeNESW; break;
+ case ImGuiMouseCursor_ResizeNWSE: cursor = MouseCursor::SizeNWSE; break;
+ case ImGuiMouseCursor_Hand: cursor = MouseCursor::Hand; break;
+ }
+
+ GetScene()->SetMouseCursor(cursor);
+ }
+ }
+
+ void ImGuiLayer::AddItem(ImGuiPipeline const & item, String const & name)
+ {
+ pipelines_.insert(std::make_pair(name, item));
+ }
+
+ void ImGuiLayer::RemoveItem(String const & name)
+ {
+ auto iter = pipelines_.find(name);
+ if (iter != pipelines_.end())
+ {
+ pipelines_.erase(iter);
+ }
+ }
+
+ void ImGuiLayer::RemoveAllItems()
+ {
+ pipelines_.clear();
+ }
+
+}
\ No newline at end of file
diff --git a/project/ImGuiSample/easy2d-imgui/ImGuiLayer.h b/project/ImGuiSample/easy2d-imgui/ImGuiLayer.h
new file mode 100644
index 00000000..7731708d
--- /dev/null
+++ b/project/ImGuiSample/easy2d-imgui/ImGuiLayer.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2019 Nomango
+
+#pragma once
+
+namespace easy2d
+{
+ E2D_DECLARE_SMART_PTR(ImGuiLayer);
+
+ using ImGuiPipeline = std::function;
+
+ class ImGuiLayer
+ : public Layer
+ {
+ public:
+ ImGuiLayer();
+
+ virtual ~ImGuiLayer();
+
+ // 添加 ImGui 元素
+ void AddItem(
+ ImGuiPipeline const& item,
+ String const& name
+ );
+
+ // 移除 ImGui 元素
+ void RemoveItem(
+ String const& name
+ );
+
+ // 移除所有元素
+ void RemoveAllItems();
+
+ public:
+ void OnMouseButtonDown(int btn, Point const& p) override;
+ void OnMouseButtonUp(int btn, Point const& p) override;
+ void OnMouseWheel(float wheel) override;
+
+ void OnKeyDown(int key) override;
+ void OnKeyUp(int key) override;
+ void OnChar(char c) override;
+
+ public:
+ void OnUpdate(Duration dt) override;
+ void OnRender() override;
+
+ void UpdateMousePos();
+ void UpdateMouseCursor();
+
+ protected:
+ HWND target_window_;
+ Map pipelines_;
+ };
+}
diff --git a/project/ImGuiSample/easy2d-imgui/ImGuiView.cpp b/project/ImGuiSample/easy2d-imgui/ImGuiView.cpp
new file mode 100644
index 00000000..0467a44f
--- /dev/null
+++ b/project/ImGuiSample/easy2d-imgui/ImGuiView.cpp
@@ -0,0 +1,83 @@
+// Copyright (C) 2019 Nomango
+
+#include "easy2d-imgui.h"
+#include "imgui_impl_dx11.h"
+
+namespace easy2d
+{
+ void ImGuiView::Setup(Application* app)
+ {
+ // Setup Dear ImGui context
+ 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(app->GetWindow()->GetHandle());
+ }
+
+ void ImGuiView::Destroy()
+ {
+ ImGui_ImplDX11_Shutdown();
+ ImGui::DestroyContext();
+ }
+
+ void ImGuiView::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;
+
+ // 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;
+ io.KeyMap[ImGuiKey_LeftArrow] = KeyCode::Left;
+ io.KeyMap[ImGuiKey_RightArrow] = KeyCode::Right;
+ io.KeyMap[ImGuiKey_UpArrow] = KeyCode::Up;
+ io.KeyMap[ImGuiKey_DownArrow] = KeyCode::Down;
+ io.KeyMap[ImGuiKey_Delete] = KeyCode::Delete;
+ io.KeyMap[ImGuiKey_Backspace] = KeyCode::Back;
+ io.KeyMap[ImGuiKey_Space] = KeyCode::Space;
+ io.KeyMap[ImGuiKey_Enter] = KeyCode::Enter;
+ io.KeyMap[ImGuiKey_Escape] = KeyCode::Esc;
+ io.KeyMap[ImGuiKey_A] = KeyCode::A;
+ io.KeyMap[ImGuiKey_C] = KeyCode::C;
+ io.KeyMap[ImGuiKey_V] = KeyCode::V;
+ io.KeyMap[ImGuiKey_X] = KeyCode::X;
+ io.KeyMap[ImGuiKey_Y] = KeyCode::Y;
+ io.KeyMap[ImGuiKey_Z] = KeyCode::Z;
+
+ ImGui_ImplDX11_Init(
+ Renderer::Instance().GetDeviceResources()->GetD3DDevice(),
+ Renderer::Instance().GetDeviceResources()->GetD3DDeviceContext()
+ );
+ }
+
+ void ImGuiView::NewFrame()
+ {
+ ImGui_ImplDX11_NewFrame();
+
+ ImGuiIO& io = ImGui::GetIO();
+ E2D_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
+
+ // Setup display size (every frame to accommodate for window resizing)
+ Size display_size = Renderer::Instance().GetOutputSize();
+ io.DisplaySize = ImVec2(display_size.x, display_size.y);
+
+ ImGui::NewFrame();
+ }
+
+ void ImGuiView::Render()
+ {
+ ImGui::Render();
+
+ ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
+ }
+
+}
\ No newline at end of file
diff --git a/project/ImGuiSample/easy2d-imgui/ImGuiView.h b/project/ImGuiSample/easy2d-imgui/ImGuiView.h
new file mode 100644
index 00000000..c9cfce9b
--- /dev/null
+++ b/project/ImGuiSample/easy2d-imgui/ImGuiView.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 Nomango
+
+#pragma once
+
+namespace easy2d
+{
+ class ImGuiView
+ : public Singleton
+ , public Component
+ {
+ E2D_DECLARE_SINGLETON(ImGuiView);
+
+ public:
+ void Setup(Application* app) override;
+
+ void Destroy() override;
+
+ public:
+ void Init(HWND hwnd);
+
+ void NewFrame();
+
+ void Render();
+ };
+
+}
diff --git a/project/ImGuiSample/easy2d-imgui/easy2d-imgui.h b/project/ImGuiSample/easy2d-imgui/easy2d-imgui.h
new file mode 100644
index 00000000..f169b80b
--- /dev/null
+++ b/project/ImGuiSample/easy2d-imgui/easy2d-imgui.h
@@ -0,0 +1,9 @@
+// Copyright (C) 2019 Nomango
+
+#pragma once
+#include "easy2d.h"
+#include "ImGuiView.h"
+#include "ImGuiLayer.h"
+
+// ImGui
+#include "imgui.h"
diff --git a/project/ImGuiSample/imgui_impl_dx11.cpp b/project/ImGuiSample/easy2d-imgui/imgui_impl_dx11.cpp
similarity index 100%
rename from project/ImGuiSample/imgui_impl_dx11.cpp
rename to project/ImGuiSample/easy2d-imgui/imgui_impl_dx11.cpp
diff --git a/project/ImGuiSample/imgui_impl_dx11.h b/project/ImGuiSample/easy2d-imgui/imgui_impl_dx11.h
similarity index 100%
rename from project/ImGuiSample/imgui_impl_dx11.h
rename to project/ImGuiSample/easy2d-imgui/imgui_impl_dx11.h
diff --git a/project/ImGuiSample/imgui_impl_win32.cpp b/project/ImGuiSample/imgui_impl_win32.cpp
deleted file mode 100644
index 6d033f66..00000000
--- a/project/ImGuiSample/imgui_impl_win32.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-// dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications)
-// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
-
-#include "imgui.h"
-#include "imgui_impl_win32.h"
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#include
-#include
-
-// Win32 Data
-static HWND g_hWnd = 0;
-static INT64 g_Time = 0;
-static INT64 g_TicksPerSecond = 0;
-static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT;
-
-// Functions
-bool ImGui_ImplWin32_Init(void* hwnd)
-{
- if (!::QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond))
- return false;
- if (!::QueryPerformanceCounter((LARGE_INTEGER *)&g_Time))
- return false;
-
- // Setup back-end capabilities flags
- g_hWnd = (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;
-
- // 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] = VK_TAB;
- io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
- io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
- io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
- io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
- io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
- io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
- io.KeyMap[ImGuiKey_Home] = VK_HOME;
- io.KeyMap[ImGuiKey_End] = VK_END;
- io.KeyMap[ImGuiKey_Insert] = VK_INSERT;
- io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
- io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
- io.KeyMap[ImGuiKey_Space] = VK_SPACE;
- io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
- io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
- io.KeyMap[ImGuiKey_A] = 'A';
- io.KeyMap[ImGuiKey_C] = 'C';
- io.KeyMap[ImGuiKey_V] = 'V';
- io.KeyMap[ImGuiKey_X] = 'X';
- io.KeyMap[ImGuiKey_Y] = 'Y';
- io.KeyMap[ImGuiKey_Z] = 'Z';
-
- return true;
-}
-
-void ImGui_ImplWin32_Shutdown()
-{
- g_hWnd = (HWND)0;
-}
-
-static bool ImGui_ImplWin32_UpdateMouseCursor()
-{
- ImGuiIO& io = ImGui::GetIO();
- if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
- return false;
-
- ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
- if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
- {
- // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
- ::SetCursor(NULL);
- }
- else
- {
- // Show OS mouse cursor
- LPTSTR win32_cursor = IDC_ARROW;
- switch (imgui_cursor)
- {
- case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break;
- case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break;
- case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break;
- case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break;
- case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break;
- case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
- case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
- case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
- }
- ::SetCursor(::LoadCursor(NULL, win32_cursor));
- }
- return true;
-}
-
-static void ImGui_ImplWin32_UpdateMousePos()
-{
- ImGuiIO& io = ImGui::GetIO();
-
- // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
- if (io.WantSetMousePos)
- {
- POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
- ::ClientToScreen(g_hWnd, &pos);
- ::SetCursorPos(pos.x, pos.y);
- }
-
- // Set mouse position
- io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
- POINT pos;
- if (HWND active_window = ::GetForegroundWindow())
- if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd))
- if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos))
- io.MousePos = ImVec2((float)pos.x, (float)pos.y);
-}
-
-void ImGui_ImplWin32_NewFrame()
-{
- ImGuiIO& io = ImGui::GetIO();
- IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
-
- // Setup display size (every frame to accommodate for window resizing)
- RECT rect;
- ::GetClientRect(g_hWnd, &rect);
- io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
-
- // Setup time step
- INT64 current_time;
- ::QueryPerformanceCounter((LARGE_INTEGER *)¤t_time);
- io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond;
- g_Time = current_time;
-
- // Read keyboard modifiers inputs
- io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
- io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
- io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
- io.KeySuper = false;
- // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
-
- // Update OS mouse position
- ImGui_ImplWin32_UpdateMousePos();
-
- // Update OS mouse cursor with the cursor requested by imgui
- ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
- if (g_LastMouseCursor != mouse_cursor)
- {
- g_LastMouseCursor = mouse_cursor;
- ImGui_ImplWin32_UpdateMouseCursor();
- }
-}
-
-// 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
-
-// Process Win32 mouse/keyboard inputs.
-// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
-// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
-// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
-// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
-// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds.
-// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
-IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (ImGui::GetCurrentContext() == NULL)
- return 0;
-
- ImGuiIO& io = ImGui::GetIO();
- switch (msg)
- {
- 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;
- return 0;
- }
- 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();
- return 0;
- }
- case WM_MOUSEWHEEL:
- io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
- return 0;
- case WM_MOUSEHWHEEL:
- io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
- return 0;
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- if (wParam < 256)
- io.KeysDown[wParam] = 1;
- return 0;
- case WM_KEYUP:
- case WM_SYSKEYUP:
- if (wParam < 256)
- io.KeysDown[wParam] = 0;
- return 0;
- case WM_CHAR:
- // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
- if (wParam > 0 && wParam < 0x10000)
- io.AddInputCharacter((unsigned short)wParam);
- return 0;
- case WM_SETCURSOR:
- if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
- return 1;
- return 0;
- }
- return 0;
-}
-
diff --git a/project/ImGuiSample/imgui_impl_win32.h b/project/ImGuiSample/imgui_impl_win32.h
deleted file mode 100644
index debd00d6..00000000
--- a/project/ImGuiSample/imgui_impl_win32.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications)
-// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
-
-#pragma once
-
-IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
-IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
-IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
-
-// Handler for Win32 messages, update mouse/keyboard data.
-// You may or not need this for your implementation, but it can serve as reference for handling inputs.
-// Intentionally commented out to avoid dragging dependencies on types. You can COPY this line into your .cpp code instead.
-/*
-IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
-*/
diff --git a/project/ImGuiSample/main.cpp b/project/ImGuiSample/main.cpp
index ffcdb62d..a3f81827 100644
--- a/project/ImGuiSample/main.cpp
+++ b/project/ImGuiSample/main.cpp
@@ -1,11 +1,8 @@
-// ImGui
-#include "imgui.h"
-#include "imgui_impl_win32.h"
-#include "imgui_impl_dx11.h"
-#include
+// Copyright (C) 2019 Nomango
-// easy2d
#include "easy2d.h"
+#include "easy2d-imgui/easy2d-imgui.h"
+
using namespace easy2d;
const int WINDOW_WIDTH = 1280;
@@ -17,108 +14,36 @@ class ImGuiScene
: public Scene
{
bool show_demo_window = true;
- bool show_another_window = false;
- Color clear_color = Color(0.45f, 0.55f, 0.6f, 1.f);
public:
- void OnEnter() override
+ ImGuiScene()
{
- // Setup Dear ImGui context
- IMGUI_CHECKVERSION();
- ImGui::CreateContext();
- ImGuiIO& io = ImGui::GetIO(); (void)io;
- //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
+ // 创建 ImGui 图层
+ ImGuiLayerPtr layer = new ImGuiLayer;
+ AddChild(layer);
- // Setup Dear ImGui style
- ImGui::StyleColorsDark();
- //ImGui::StyleColorsClassic();
-
- // Setup Platform/Renderer bindings
- ImGui_ImplWin32_Init(Window::Instance().GetHandle());
- ImGui_ImplDX11_Init(
- Renderer::Instance().GetDeviceResources()->GetD3DDevice(),
- Renderer::Instance().GetDeviceResources()->GetD3DDeviceContext()
- );
- }
-
- void OnRender() override
- {
- // Start the Dear ImGui frame
- ImGui_ImplDX11_NewFrame();
- ImGui_ImplWin32_NewFrame();
- ImGui::NewFrame();
-
- // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
- if (show_demo_window)
- ImGui::ShowDemoWindow(&show_demo_window);
-
- // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
- {
- static float f = 0.0f;
- static int counter = 0;
-
- ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
-
- ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
- ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
- ImGui::Checkbox("Another Window", &show_another_window);
-
- ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
- ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
-
- if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
- counter++;
- ImGui::SameLine();
- ImGui::Text("counter = %d", counter);
-
- ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
- ImGui::End();
- }
-
- // 3. Show another simple window.
- if (show_another_window)
- {
- ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
- ImGui::Text("Hello from another window!");
- if (ImGui::Button("Close Me"))
- show_another_window = false;
- ImGui::End();
- }
-
- // Rendering
- ImGui::Render();
-
- ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
-
- Renderer::Instance().SetClearColor(clear_color);
- }
-
- void OnExit() override
- {
- ImGui_ImplDX11_Shutdown();
- ImGui_ImplWin32_Shutdown();
- ImGui::DestroyContext();
+ // 添加 ImGui 提供的 Demo 窗口
+ layer->AddItem([=]() {
+ if (show_demo_window)
+ ImGui::ShowDemoWindow(&show_demo_window);
+ }, L"DemoWindow");
}
};
-
-extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND, UINT, WPARAM, LPARAM);
-
class ImGuiApp
: public Application
{
public:
ImGuiApp()
{
- Options options;
- options.title = L"ImGui Demo";
- options.width = WINDOW_WIDTH;
- options.height = WINDOW_HEIGHT;
+ // 添加 ImGui 组件
+ Use(&ImGuiView::Instance());
+
+ // 初始化
+ Options options(L"ImGui Demo", WINDOW_WIDTH, WINDOW_HEIGHT);
options.clear_color = Color(0.45f, 0.55f, 0.6f, 1.f);
Init(options);
-
- SetPreMessageProc(ImGui_ImplWin32_WndProcHandler);
}
void OnStart() override
diff --git a/project/Samples/main.cpp b/project/Samples/main.cpp
index fa0bb2b8..45c7fa66 100644
--- a/project/Samples/main.cpp
+++ b/project/Samples/main.cpp
@@ -39,7 +39,7 @@ public:
void ChangeDemoScene()
{
- Window::Instance().SetTitle(s_Demos[s_DemoIndex].title);
+ GetWindow()->SetTitle(s_Demos[s_DemoIndex].title);
ScenePtr scene = s_Demos[s_DemoIndex].Create();
EnterScene(scene);
diff --git a/src/audio/Transcoder.cpp b/src/audio/Transcoder.cpp
index d332b019..ce9a66a2 100644
--- a/src/audio/Transcoder.cpp
+++ b/src/audio/Transcoder.cpp
@@ -24,7 +24,7 @@
#include "Transcoder.h"
#include "audio-modules.h"
-#include "../core/ComPtr.hpp"
+#include "../common/ComPtr.hpp"
#include "../core/logs.h"
#include "../core/modules.h"
diff --git a/src/audio/Voice.h b/src/audio/Voice.h
index 583179f9..7993e8f3 100644
--- a/src/audio/Voice.h
+++ b/src/audio/Voice.h
@@ -19,8 +19,8 @@
// THE SOFTWARE.
#pragma once
-#include "../core/macros.h"
-#include "../core/noncopyable.hpp"
+#include "../macros.h"
+#include "../common/noncopyable.hpp"
#include
namespace easy2d
diff --git a/src/audio/audio-modules.h b/src/audio/audio-modules.h
index 36744487..d7b3e184 100644
--- a/src/audio/audio-modules.h
+++ b/src/audio/audio-modules.h
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "../core/macros.h"
+#include "../macros.h"
#include
#include
#include
diff --git a/src/audio/audio.cpp b/src/audio/audio.cpp
index 11354479..4619dc42 100644
--- a/src/audio/audio.cpp
+++ b/src/audio/audio.cpp
@@ -34,7 +34,7 @@ namespace easy2d
{
}
- void Audio::Setup()
+ void Audio::Setup(Application*)
{
E2D_LOG(L"Creating audio resources");
@@ -65,7 +65,11 @@ namespace easy2d
mastering_voice_ = nullptr;
}
- DX::SafeRelease(x_audio2_);
+ if (x_audio2_)
+ {
+ x_audio2_->Release();
+ x_audio2_ = nullptr;
+ }
modules::MediaFoundation::Get().MFShutdown();
}
diff --git a/src/audio/audio.h b/src/audio/audio.h
index b6697c23..22deb128 100644
--- a/src/audio/audio.h
+++ b/src/audio/audio.h
@@ -20,8 +20,8 @@
#pragma once
#include "../core/include-forwards.h"
-#include "../core/Singleton.hpp"
#include "../core/Component.h"
+#include "../common/Singleton.hpp"
#include "Voice.h"
namespace easy2d
@@ -35,7 +35,7 @@ namespace easy2d
using VoiceMap = UnorderedSet;
public:
- void Setup() override;
+ void Setup(Application*) override;
void Destroy() override;
diff --git a/src/core/Array.h b/src/common/Array.h
similarity index 99%
rename from src/core/Array.h
rename to src/common/Array.h
index 284eaf4a..92e38cb9 100644
--- a/src/core/Array.h
+++ b/src/common/Array.h
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "macros.h"
+#include "../macros.h"
namespace easy2d
{
diff --git a/src/core/ComPtr.hpp b/src/common/ComPtr.hpp
similarity index 97%
rename from src/core/ComPtr.hpp
rename to src/common/ComPtr.hpp
index 6f6a6124..4f7b0beb 100644
--- a/src/core/ComPtr.hpp
+++ b/src/common/ComPtr.hpp
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "../core/IntrusivePtr.hpp"
+#include "IntrusivePtr.hpp"
#include
namespace easy2d
diff --git a/src/core/IntrusiveList.hpp b/src/common/IntrusiveList.hpp
similarity index 99%
rename from src/core/IntrusiveList.hpp
rename to src/common/IntrusiveList.hpp
index 729f9193..44004b70 100644
--- a/src/core/IntrusiveList.hpp
+++ b/src/common/IntrusiveList.hpp
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "macros.h"
+#include "../macros.h"
#include
#ifdef E2D_DEBUG
diff --git a/src/core/IntrusivePtr.hpp b/src/common/IntrusivePtr.hpp
similarity index 99%
rename from src/core/IntrusivePtr.hpp
rename to src/common/IntrusivePtr.hpp
index 004c5ec6..edc19c7d 100644
--- a/src/core/IntrusivePtr.hpp
+++ b/src/common/IntrusivePtr.hpp
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "macros.h"
+#include "../macros.h"
#include
namespace easy2d
diff --git a/src/core/Singleton.hpp b/src/common/Singleton.hpp
similarity index 92%
rename from src/core/Singleton.hpp
rename to src/common/Singleton.hpp
index d5d630ff..31f1739c 100644
--- a/src/core/Singleton.hpp
+++ b/src/common/Singleton.hpp
@@ -20,6 +20,14 @@
#pragma once
+// Class that will implement the singleton mode,
+// must use the macro in its delare file
+
+#ifndef E2D_DECLARE_SINGLETON
+#define E2D_DECLARE_SINGLETON( CLASS ) \
+ friend class ::easy2d::Singleton< CLASS >
+#endif
+
namespace easy2d
{
template
@@ -28,7 +36,7 @@ namespace easy2d
public:
static inline _Ty& Instance()
{
- static _Ty instance; // Thread safe
+ static _Ty instance; // Thread-safe
return instance;
}
@@ -41,11 +49,3 @@ namespace easy2d
Singleton& operator=(const Singleton&) = delete;
};
}
-
-// Class that will implement the singleton mode,
-// must use the macro in its delare file
-
-#ifndef E2D_DECLARE_SINGLETON
-#define E2D_DECLARE_SINGLETON( type ) \
- friend class ::easy2d::Singleton< type >
-#endif
diff --git a/src/core/closure.hpp b/src/common/closure.hpp
similarity index 93%
rename from src/core/closure.hpp
rename to src/common/closure.hpp
index 4c877230..793ab423 100644
--- a/src/core/closure.hpp
+++ b/src/common/closure.hpp
@@ -23,6 +23,17 @@
namespace easy2d
{
+ //
+ // Closure is a simple function for binding member functions
+ //
+
+ template
+ std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...));
+
+
+ //
+ // Details of Closure
+ //
namespace __closure__detail
{
// sequence & generater
@@ -62,10 +73,6 @@ namespace easy2d
};
}
- //
- // Closure is a simple function for binding member functions
- //
-
template
inline std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...))
{
diff --git a/src/core/noncopyable.hpp b/src/common/noncopyable.hpp
similarity index 96%
rename from src/core/noncopyable.hpp
rename to src/common/noncopyable.hpp
index 3ec85eeb..2c1dbc80 100644
--- a/src/core/noncopyable.hpp
+++ b/src/common/noncopyable.hpp
@@ -19,11 +19,10 @@
// THE SOFTWARE.
#pragma once
-#include "macros.h"
namespace easy2d
{
- class E2D_API Noncopyable
+ class Noncopyable
{
protected:
Noncopyable() = default;
diff --git a/src/core/config.h b/src/config.h
similarity index 100%
rename from src/core/config.h
rename to src/config.h
diff --git a/src/core/Action.h b/src/core/Action.h
index 98e999f2..97de29bb 100644
--- a/src/core/Action.h
+++ b/src/core/Action.h
@@ -21,7 +21,7 @@
#pragma once
#include "include-forwards.h"
#include "time.h"
-#include "IntrusiveList.hpp"
+#include "../common/IntrusiveList.hpp"
namespace easy2d
{
diff --git a/src/core/Application.cpp b/src/core/Application.cpp
index 9c55849a..820e15c3 100644
--- a/src/core/Application.cpp
+++ b/src/core/Application.cpp
@@ -22,7 +22,6 @@
#include "logs.h"
#include "modules.h"
#include "render.h"
-#include "window.h"
#include "input.h"
#include "Event.hpp"
#include "Scene.h"
@@ -36,22 +35,17 @@
namespace easy2d
{
- namespace
- {
- LRESULT(*pre_proc)(HWND, UINT, WPARAM, LPARAM) = nullptr; // Custom message proc for user
- }
-
Application::Application(String const& app_name)
: end_(true)
, inited_(false)
- , curr_scene_(nullptr)
- , next_scene_(nullptr)
- , transition_(nullptr)
+ , main_window_(nullptr)
, time_scale_(1.f)
, app_name_(app_name)
{
::CoInitialize(nullptr);
+ main_window_ = new Window;
+
Use(&Renderer::Instance());
Use(&Input::Instance());
}
@@ -66,7 +60,7 @@ namespace easy2d
void Application::Init(const Options& options)
{
ThrowIfFailed(
- Window::Instance().Create(
+ main_window_->Create(
options.title,
options.width,
options.height,
@@ -76,16 +70,15 @@ namespace easy2d
)
);
- HWND hwnd = Window::Instance().GetHandle();
+ HWND hwnd = main_window_->GetHandle();
- Renderer::Instance().SetTargetWindow(hwnd);
Renderer::Instance().SetClearColor(options.clear_color);
Renderer::Instance().SetVSyncEnabled(options.vsync);
// Setup all components
for (Component* c : components_)
{
- c->Setup();
+ c->Setup(this);
}
OnStart();
@@ -101,13 +94,15 @@ namespace easy2d
void Application::Run()
{
- HWND hwnd = Window::Instance().GetHandle();
+ HWND hwnd = main_window_->GetHandle();
+
+ if (!hwnd)
+ throw std::exception("Calling Application::Run before Application::Init");
if (hwnd)
{
end_ = false;
-
- Window::Instance().Prepare();
+ main_window_->Prepare();
MSG msg = {};
while (::GetMessageW(&msg, nullptr, 0, 0) && !end_)
@@ -125,24 +120,25 @@ namespace easy2d
void Application::Destroy()
{
+ transition_.Reset();
+ next_scene_.Reset();
+ curr_scene_.Reset();
+ debug_node_.Reset();
+
if (inited_)
{
inited_ = false;
- if (curr_scene_)
- curr_scene_->OnExit();
-
- transition_.Reset();
- next_scene_.Reset();
- curr_scene_.Reset();
- debug_node_.Reset();
-
for (auto iter = components_.rbegin(); iter != components_.rend(); ++iter)
{
(*iter)->Destroy();
}
- Window::Instance().Destroy();
+ if (main_window_)
+ {
+ delete main_window_;
+ main_window_ = nullptr;
+ }
}
}
@@ -166,7 +162,7 @@ namespace easy2d
{
if (component)
{
- for (auto iter = components_.begin(); iter != components_.end(); iter++)
+ for (auto iter = components_.begin(); iter != components_.end(); ++iter)
{
if ((*iter) == component)
{
@@ -213,11 +209,6 @@ namespace easy2d
time_scale_ = scale_factor;
}
- void Application::SetPreMessageProc(LRESULT(*proc)(HWND, UINT, WPARAM, LPARAM))
- {
- pre_proc = proc;
- }
-
void Application::ShowDebugInfo(bool show)
{
if (show)
@@ -290,11 +281,11 @@ namespace easy2d
curr_scene_->Render();
}
+ OnRender();
+
if (debug_node_)
debug_node_->Render();
- OnRender();
-
ThrowIfFailed(
Renderer::Instance().EndDraw()
);
@@ -336,9 +327,6 @@ namespace easy2d
LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
- if (pre_proc && pre_proc(hwnd, msg, wparam, lparam))
- return 1;
-
Application * app = reinterpret_cast(
static_cast(::GetWindowLongPtrW(hwnd, GWLP_USERDATA))
);
@@ -359,13 +347,16 @@ namespace easy2d
break;
case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
case WM_KEYUP:
+ case WM_SYSKEYUP:
{
- Input::Instance().UpdateKey((int)wparam, (msg == WM_KEYDOWN) ? true : false);
+ bool down = msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN;
+ Input::Instance().UpdateKey((int)wparam, down);
if (!app->transition_ && app->curr_scene_)
{
- Event evt((msg == WM_KEYDOWN) ? Event::KeyDown : Event::KeyUp);
+ Event evt(down ? Event::KeyDown : Event::KeyUp);
evt.key.code = static_cast(wparam);
evt.key.count = static_cast(lparam & 0xFF);
@@ -374,6 +365,19 @@ namespace easy2d
}
break;
+ case WM_CHAR:
+ {
+ if (!app->transition_ && app->curr_scene_)
+ {
+ Event evt(Event::Char);
+ evt.key.c = static_cast(wparam);
+ evt.key.count = static_cast(lparam & 0xFF);
+
+ app->curr_scene_->Dispatch(evt);
+ }
+ }
+ break;
+
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
//case WM_LBUTTONDBLCLK:
@@ -426,7 +430,7 @@ namespace easy2d
UINT width = LOWORD(lparam);
UINT height = HIWORD(lparam);
- Renderer::Instance().GetDeviceResources()->SetLogicalSize(Size{ (float)width, (float)height });
+ Renderer::Instance().Resize(width, height);
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
{
@@ -444,7 +448,7 @@ namespace easy2d
app->curr_scene_->Dispatch(evt);
}
- Window::Instance().UpdateWindowRect();
+ app->GetWindow()->UpdateWindowRect();
}
}
break;
@@ -470,7 +474,7 @@ namespace easy2d
E2D_LOG(active ? L"Window activated" : L"Window deactivated");
- Window::Instance().SetActive(active);
+ app->GetWindow()->SetActive(active);
if (app->curr_scene_)
{
@@ -512,11 +516,10 @@ namespace easy2d
{
E2D_LOG(L"Window is closing");
- if (app->OnClosing())
+ if (!app->OnClosing())
{
- Window::Instance().Destroy();
+ return 0;
}
- return 0;
}
break;
diff --git a/src/core/Application.h b/src/core/Application.h
index c764e5eb..28c3cad5 100644
--- a/src/core/Application.h
+++ b/src/core/Application.h
@@ -21,6 +21,7 @@
#pragma once
#include "include-forwards.h"
#include "time.h"
+#include "window.h"
#include "Component.h"
namespace easy2d
@@ -35,20 +36,10 @@ namespace easy2d
bool vsync; // 垂直同步
bool fullscreen; // 全屏模式
- Options()
- : title(L"Easy2D Game")
- , width(640)
- , height(480)
- , icon(nullptr)
- , clear_color(Color::Black)
- , vsync(true)
- , fullscreen(false)
- {}
-
Options(
- String const& title,
- int width,
- int height,
+ String const& title = L"Easy2D Game",
+ int width = 640,
+ int height = 480,
LPCWSTR icon = nullptr,
Color clear_color = Color::Black,
bool vsync = true,
@@ -128,16 +119,14 @@ namespace easy2d
// 获取当前场景
ScenePtr const& GetCurrentScene();
+ // 获取主窗口
+ inline Window* GetWindow() const { return main_window_; }
+
// 设置时间缩放因子
void SetTimeScale(
float scale_factor
);
- // 设置消息预处理函数
- void SetPreMessageProc(
- LRESULT (*proc)(HWND, UINT, WPARAM, LPARAM)
- );
-
// 显示调试信息
void ShowDebugInfo(
bool show = true
@@ -158,11 +147,13 @@ namespace easy2d
bool inited_;
float time_scale_;
String app_name_;
+
ScenePtr curr_scene_;
ScenePtr next_scene_;
NodePtr debug_node_;
TransitionPtr transition_;
- Array components_;
+ Window* main_window_;
+ Array components_;
};
}
diff --git a/src/core/Color.h b/src/core/Color.h
index 8185f1fa..812581a2 100644
--- a/src/core/Color.h
+++ b/src/core/Color.h
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "macros.h"
+#include "../macros.h"
namespace easy2d
{
diff --git a/src/core/Component.h b/src/core/Component.h
index 60e3524c..3a89f380 100644
--- a/src/core/Component.h
+++ b/src/core/Component.h
@@ -22,10 +22,12 @@
namespace easy2d
{
+ class Application;
+
class Component
{
public:
- virtual void Setup() = 0;
+ virtual void Setup(Application*) = 0;
virtual void Destroy() = 0;
};
diff --git a/src/core/DebugNode.cpp b/src/core/DebugNode.cpp
index cff72718..b2e20083 100644
--- a/src/core/DebugNode.cpp
+++ b/src/core/DebugNode.cpp
@@ -19,6 +19,7 @@
// THE SOFTWARE.
#include "DebugNode.h"
+#include "Text.h"
#include "render.h"
#include "../utils/string.h"
#include
diff --git a/src/core/DebugNode.h b/src/core/DebugNode.h
index a8149a23..aee5a022 100644
--- a/src/core/DebugNode.h
+++ b/src/core/DebugNode.h
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "Text.h"
+#include "Node.h"
#include "time.h"
namespace easy2d
diff --git a/src/core/Event.hpp b/src/core/Event.hpp
index 75ed5910..18241b37 100644
--- a/src/core/Event.hpp
+++ b/src/core/Event.hpp
@@ -19,7 +19,6 @@
// THE SOFTWARE.
#pragma once
-#include "macros.h"
#include "keys.hpp"
namespace easy2d
@@ -33,14 +32,17 @@ namespace easy2d
bool left_btn_down; // 左键是否按下
bool right_btn_down; // 右键是否按下
- struct // Events::MouseDown | Events::MouseUp | Events::MouseClick
+ union
{
- int button;
- };
+ struct // Events::MouseDown | Events::MouseUp | Events::MouseClick
+ {
+ int button;
+ };
- struct // Events::MouseWheel
- {
- float wheel;
+ struct // Events::MouseWheel
+ {
+ float wheel;
+ };
};
static bool Check(UINT type);
@@ -49,8 +51,19 @@ namespace easy2d
// 键盘事件
struct KeyboardEvent
{
- int code; // enum KeyCode
int count;
+ union
+ {
+ struct // Events::KeyDown | Events::KeyUp
+ {
+ int code; // enum KeyCode
+ };
+
+ struct // Events::Char
+ {
+ char c;
+ };
+ };
static bool Check(UINT type);
};
@@ -114,6 +127,7 @@ namespace easy2d
KeyFirst,
KeyDown, // 按键按下
KeyUp, // 按键抬起
+ Char, // 输出字符
KeyLast,
// 窗口消息
diff --git a/src/core/EventListener.h b/src/core/EventListener.h
index 62ddb0bb..1630c0de 100644
--- a/src/core/EventListener.h
+++ b/src/core/EventListener.h
@@ -20,7 +20,7 @@
#pragma once
#include "include-forwards.h"
-#include "IntrusiveList.hpp"
+#include "../common/IntrusiveList.hpp"
#include "Event.hpp"
namespace easy2d
diff --git a/src/core/Geometry.h b/src/core/Geometry.h
index aed3637f..7d070250 100644
--- a/src/core/Geometry.h
+++ b/src/core/Geometry.h
@@ -20,6 +20,7 @@
#pragma once
#include "include-forwards.h"
+#include
namespace easy2d
{
diff --git a/src/core/Image.h b/src/core/Image.h
index a335a77a..f544da0b 100644
--- a/src/core/Image.h
+++ b/src/core/Image.h
@@ -21,6 +21,7 @@
#pragma once
#include "include-forwards.h"
#include "Resource.h"
+#include
namespace easy2d
{
diff --git a/src/core/Input.h b/src/core/Input.h
index c3066bcb..2a73cbcf 100644
--- a/src/core/Input.h
+++ b/src/core/Input.h
@@ -21,8 +21,8 @@
#pragma once
#include "include-forwards.h"
#include "keys.hpp"
-#include "Singleton.hpp"
#include "Component.h"
+#include "../common/Singleton.hpp"
namespace easy2d
{
@@ -58,7 +58,7 @@ namespace easy2d
Point GetMousePos();
public:
- void Setup() override {}
+ void Setup(Application*) override {}
void Destroy() override {}
diff --git a/src/core/Layer.cpp b/src/core/Layer.cpp
new file mode 100644
index 00000000..4c552240
--- /dev/null
+++ b/src/core/Layer.cpp
@@ -0,0 +1,88 @@
+// Copyright (c) 2016-2018 Easy2D - 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 "Layer.h"
+#include "render.h"
+
+namespace easy2d
+{
+ Layer::Layer()
+ {
+ SetSize(Renderer::Instance().GetOutputSize());
+
+ AddListener(Event::MouseBtnDown, Closure(this, &Layer::HandleMessages));
+ AddListener(Event::MouseBtnUp, Closure(this, &Layer::HandleMessages));
+ AddListener(Event::MouseMove, Closure(this, &Layer::HandleMessages));
+ AddListener(Event::MouseWheel, Closure(this, &Layer::HandleMessages));
+
+ AddListener(Event::KeyDown, Closure(this, &Layer::HandleMessages));
+ AddListener(Event::KeyUp, Closure(this, &Layer::HandleMessages));
+ AddListener(Event::Char, Closure(this, &Layer::HandleMessages));
+ }
+
+ Layer::~Layer()
+ {
+ }
+
+ void Layer::Dispatch(Event& evt)
+ {
+ if (!IsVisible())
+ return;
+
+ NodePtr prev;
+ for (auto child = children_.Last(); child; child = prev)
+ {
+ prev = child->PrevItem();
+ child->Dispatch(evt);
+ }
+
+ EventDispatcher::Dispatch(evt);
+ }
+
+ void Layer::HandleMessages(Event const & evt)
+ {
+ switch (evt.type)
+ {
+ 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;
+ }
+ }
+
+}
diff --git a/src/math/rand.cpp b/src/core/Layer.h
similarity index 68%
rename from src/math/rand.cpp
rename to src/core/Layer.h
index 5f86ea55..8fdd6bcc 100644
--- a/src/math/rand.cpp
+++ b/src/core/Layer.h
@@ -18,21 +18,32 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include "rand.h"
+#pragma once
+#include "Node.h"
namespace easy2d
{
- namespace math
+ class E2D_API Layer
+ : public Node
{
- namespace
- {
- std::random_device device;
- std::default_random_engine engine(device());
- }
+ public:
+ Layer();
- std::default_random_engine& GetRandomEngine()
- {
- return engine;
- }
- }
+ virtual ~Layer();
+
+ virtual void OnMouseButtonDown(int btn, Point const& p) {}
+ virtual void OnMouseButtonUp(int btn, Point const& p) {}
+ virtual void OnMouseMoved(Point const& p) {}
+ virtual void OnMouseWheel(float wheel) {}
+
+ virtual void OnKeyDown(int key) {}
+ virtual void OnKeyUp(int key) {}
+ virtual void OnChar(char c) {}
+
+ public:
+ void Dispatch(Event& evt) override;
+
+ protected:
+ void HandleMessages(Event const& evt);
+ };
}
diff --git a/src/core/Node.cpp b/src/core/Node.cpp
index 1799e613..09a3bde8 100644
--- a/src/core/Node.cpp
+++ b/src/core/Node.cpp
@@ -48,6 +48,7 @@ namespace easy2d
, dirty_transform_(false)
, dirty_transform_inverse_(false)
, parent_(nullptr)
+ , scene_(nullptr)
, hash_name_(0)
, z_order_(0)
, opacity_(1.f)
@@ -194,16 +195,6 @@ namespace easy2d
return transform_matrix_inverse_;
}
- Node* Node::GetParent() const
- {
- return parent_;
- }
-
- Scene* Node::GetScene() const
- {
- return scene_;
- }
-
void Node::UpdateTransform() const
{
if (!dirty_transform_)
@@ -237,12 +228,15 @@ namespace easy2d
}
}
- void Node::SetScene(Scene * scene)
+ void Node::SetScene(Scene* scene)
{
- scene_ = scene;
- for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
+ if (scene && scene_ != scene)
{
- child->scene_ = scene;
+ scene_ = scene;
+ for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
+ {
+ child->scene_ = scene;
+ }
}
}
diff --git a/src/core/Node.h b/src/core/Node.h
index 6c6f6dce..bbc59fd6 100644
--- a/src/core/Node.h
+++ b/src/core/Node.h
@@ -25,7 +25,6 @@
#include "TaskManager.h"
#include "ActionManager.h"
#include "EventDispatcher.h"
-#include "IntrusiveList.hpp"
namespace easy2d
{
@@ -37,10 +36,9 @@ namespace easy2d
, public TaskManager
, public ActionManager
, public EventDispatcher
- , protected IntrusiveListItem
+ , public IntrusiveListItem
{
friend class Application;
- friend class Scene;
friend class Transition;
friend class IntrusiveList;
@@ -56,9 +54,6 @@ namespace easy2d
// 渲染节点
virtual void OnRender() {}
- // 事件分发
- void Dispatch(Event& evt) override;
-
// 获取显示状态
bool IsVisible() const { return visible_; }
@@ -135,10 +130,10 @@ namespace easy2d
Matrix const& GetTransformInverseMatrix() const;
// 获取父节点
- Node* GetParent() const;
+ inline Node* GetParent() const { return parent_; }
// 获取所在场景
- Scene* GetScene() const;
+ inline Scene* GetScene() const { return scene_; }
// 设置是否显示
void SetVisible(
@@ -364,6 +359,10 @@ namespace easy2d
float anchor_y
);
+ public:
+ // 事件分发
+ void Dispatch(Event& evt) override;
+
protected:
virtual void PrepareRender() {}
@@ -402,6 +401,7 @@ namespace easy2d
};
+ // 可视化节点
class E2D_API VisualNode
: public Node
{
diff --git a/src/core/Object.h b/src/core/Object.h
index 53d6e0c6..4ec57cff 100644
--- a/src/core/Object.h
+++ b/src/core/Object.h
@@ -19,8 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "RefCounter.hpp"
-#include "helper.hpp"
+#include "helper.h"
namespace easy2d
{
diff --git a/src/core/RefCounter.hpp b/src/core/RefCounter.hpp
index df6992de..02482f2a 100644
--- a/src/core/RefCounter.hpp
+++ b/src/core/RefCounter.hpp
@@ -19,8 +19,8 @@
// THE SOFTWARE.
#pragma once
-#include "macros.h"
-#include "noncopyable.hpp"
+#include "../macros.h"
+#include "../common/noncopyable.hpp"
namespace easy2d
{
diff --git a/src/core/Resource.h b/src/core/Resource.h
index ecf39447..61912ded 100644
--- a/src/core/Resource.h
+++ b/src/core/Resource.h
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "helper.hpp"
+#include "helper.h"
namespace easy2d
{
diff --git a/src/core/Scene.cpp b/src/core/Scene.cpp
index 42d95675..e43b53e3 100644
--- a/src/core/Scene.cpp
+++ b/src/core/Scene.cpp
@@ -19,14 +19,18 @@
// THE SOFTWARE.
#include "Scene.h"
-#include "Node.h"
#include "logs.h"
+#include "render.h"
namespace easy2d
{
Scene::Scene()
+ : mouse_cursor_(MouseCursor::Arrow)
+ , last_mouse_cursor(MouseCursor(-1))
{
scene_ = this;
+
+ SetSize(Renderer::Instance().GetOutputSize());
}
Scene::~Scene()
@@ -43,4 +47,33 @@ namespace easy2d
E2D_LOG(L"Scene exited");
}
+ void Scene::Update(Duration dt)
+ {
+ Node::Update(dt);
+
+ if (last_mouse_cursor != mouse_cursor_)
+ {
+ last_mouse_cursor = mouse_cursor_;
+
+ LPTSTR win32_cursor = IDC_ARROW;
+ switch (mouse_cursor_)
+ {
+ case MouseCursor::Arrow: win32_cursor = IDC_ARROW; break;
+ case MouseCursor::TextInput: win32_cursor = IDC_IBEAM; break;
+ case MouseCursor::SizeAll: win32_cursor = IDC_SIZEALL; break;
+ case MouseCursor::SizeWE: win32_cursor = IDC_SIZEWE; break;
+ case MouseCursor::SizeNS: win32_cursor = IDC_SIZENS; break;
+ case MouseCursor::SizeNESW: win32_cursor = IDC_SIZENESW; break;
+ case MouseCursor::SizeNWSE: win32_cursor = IDC_SIZENWSE; break;
+ case MouseCursor::Hand: win32_cursor = IDC_HAND; break;
+ }
+ ::SetCursor(::LoadCursorW(nullptr, win32_cursor));
+ }
+ }
+
+ void Scene::SetMouseCursor(MouseCursor cursor)
+ {
+ mouse_cursor_ = cursor;
+ }
+
}
diff --git a/src/core/Scene.h b/src/core/Scene.h
index 11e24dc1..89b8510d 100644
--- a/src/core/Scene.h
+++ b/src/core/Scene.h
@@ -37,5 +37,16 @@ namespace easy2d
// 退出场景
virtual void OnExit();
+
+ public:
+ void Update(Duration dt);
+
+ void SetMouseCursor(
+ MouseCursor cursor
+ );
+
+ protected:
+ MouseCursor mouse_cursor_;
+ MouseCursor last_mouse_cursor;
};
}
diff --git a/src/core/Task.h b/src/core/Task.h
index 0ca3036f..2c439783 100644
--- a/src/core/Task.h
+++ b/src/core/Task.h
@@ -21,7 +21,7 @@
#pragma once
#include "include-forwards.h"
#include "time.h"
-#include "IntrusiveList.hpp"
+#include "../common/IntrusiveList.hpp"
#include
namespace easy2d
diff --git a/src/core/Text.h b/src/core/Text.h
index 1459d174..abb94a30 100644
--- a/src/core/Text.h
+++ b/src/core/Text.h
@@ -22,6 +22,7 @@
#include "Node.h"
#include "Font.hpp"
#include "TextStyle.hpp"
+#include
namespace easy2d
{
diff --git a/src/core/Transition.cpp b/src/core/Transition.cpp
index e33b7acf..7f8eb3a7 100644
--- a/src/core/Transition.cpp
+++ b/src/core/Transition.cpp
@@ -77,7 +77,7 @@ namespace easy2d
);
}
- window_size_ = Window::Instance().GetSize();
+ window_size_ = Renderer::Instance().GetOutputSize();
out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f };
}
diff --git a/src/core/Transition.h b/src/core/Transition.h
index e21f34a8..12d6a284 100644
--- a/src/core/Transition.h
+++ b/src/core/Transition.h
@@ -21,6 +21,7 @@
#pragma once
#include "include-forwards.h"
#include "time.h"
+#include
namespace easy2d
{
@@ -56,17 +57,17 @@ namespace easy2d
virtual void Reset() { };
protected:
- bool done_;
- float process_;
- Duration duration_;
- Duration delta_;
- Size window_size_;
+ bool done_;
+ float process_;
+ Duration duration_;
+ Duration delta_;
+ Size window_size_;
ScenePtr out_scene_;
ScenePtr in_scene_;
- ComPtr out_layer_;
- ComPtr in_layer_;
- LayerProperties out_layer_prop_;
- LayerProperties in_layer_prop_;
+ ComPtr out_layer_;
+ ComPtr in_layer_;
+ LayerProperties out_layer_prop_;
+ LayerProperties in_layer_prop_;
};
diff --git a/src/core/helper.hpp b/src/core/helper.h
similarity index 93%
rename from src/core/helper.hpp
rename to src/core/helper.h
index fe5b5bb4..99bcbbc2 100644
--- a/src/core/helper.hpp
+++ b/src/core/helper.h
@@ -20,13 +20,8 @@
#pragma once
#include "RefCounter.hpp"
-#include "IntrusivePtr.hpp"
-#include "ComPtr.hpp"
-#include "Array.h"
-#include "closure.hpp"
-#include "../math/vector.hpp"
-#include "../math/Rect.hpp"
-#include "../math/Matrix.hpp"
+#include "../common/Array.h"
+#include "../common/IntrusivePtr.hpp"
#include
#include