add ImGui Component

minor

minor

refactoring
This commit is contained in:
Nomango 2019-03-12 00:27:54 +08:00 committed by Nomango
parent b1b1f0c22c
commit 8eb3f9887c
82 changed files with 1163 additions and 935 deletions

View File

@ -132,10 +132,7 @@ class MainScene
public: public:
MainScene() MainScene()
{ {
// 修改场景大小, 并设置可响应状态, 使场景可以 // 设置可响应状态, 使场景可以接收到鼠标 Click 消息
// 接收到鼠标 Click 消息
auto size = Window::Instance().GetSize();
SetSize(size);
SetResponsible(true); SetResponsible(true);
// 添加消息监听 // 添加消息监听
@ -144,7 +141,7 @@ public:
// 创建物理世界 // 创建物理世界
world_ = new b2World(b2Vec2(0, 10)); 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); AddChild(board);
CirclePtr circle = new Circle(world_, Point(320, 240)); CirclePtr circle = new Circle(world_, Point(320, 240));
@ -208,7 +205,9 @@ int main()
try try
{ {
Application app; Application app;
app.Init();
Options options(L"Box2D Demo");
app.Init(options);
ScenePtr scene = new MainScene; ScenePtr scene = new MainScene;
app.EnterScene(scene); app.EnterScene(scene);

View File

@ -7,19 +7,23 @@
<ClInclude Include="..\..\src\audio\Player.h" /> <ClInclude Include="..\..\src\audio\Player.h" />
<ClInclude Include="..\..\src\audio\Transcoder.h" /> <ClInclude Include="..\..\src\audio\Transcoder.h" />
<ClInclude Include="..\..\src\audio\Voice.h" /> <ClInclude Include="..\..\src\audio\Voice.h" />
<ClInclude Include="..\..\src\common\Array.h" />
<ClInclude Include="..\..\src\common\closure.hpp" />
<ClInclude Include="..\..\src\common\ComPtr.hpp" />
<ClInclude Include="..\..\src\common\IntrusiveList.hpp" />
<ClInclude Include="..\..\src\common\IntrusivePtr.hpp" />
<ClInclude Include="..\..\src\common\noncopyable.hpp" />
<ClInclude Include="..\..\src\common\Singleton.hpp" />
<ClInclude Include="..\..\src\config.h" />
<ClInclude Include="..\..\src\core\Action.h" /> <ClInclude Include="..\..\src\core\Action.h" />
<ClInclude Include="..\..\src\core\ActionGroup.h" /> <ClInclude Include="..\..\src\core\ActionGroup.h" />
<ClInclude Include="..\..\src\core\ActionHelper.h" /> <ClInclude Include="..\..\src\core\ActionHelper.h" />
<ClInclude Include="..\..\src\core\ActionTween.h" /> <ClInclude Include="..\..\src\core\ActionTween.h" />
<ClInclude Include="..\..\src\core\ActionManager.h" /> <ClInclude Include="..\..\src\core\ActionManager.h" />
<ClInclude Include="..\..\src\core\Animation.h" /> <ClInclude Include="..\..\src\core\Animation.h" />
<ClInclude Include="..\..\src\core\Array.h" />
<ClInclude Include="..\..\src\core\Canvas.h" /> <ClInclude Include="..\..\src\core\Canvas.h" />
<ClInclude Include="..\..\src\core\closure.hpp" />
<ClInclude Include="..\..\src\core\Color.h" /> <ClInclude Include="..\..\src\core\Color.h" />
<ClInclude Include="..\..\src\core\Component.h" /> <ClInclude Include="..\..\src\core\Component.h" />
<ClInclude Include="..\..\src\core\ComPtr.hpp" />
<ClInclude Include="..\..\src\core\config.h" />
<ClInclude Include="..\..\src\core\DebugNode.h" /> <ClInclude Include="..\..\src\core\DebugNode.h" />
<ClInclude Include="..\..\src\core\Event.hpp" /> <ClInclude Include="..\..\src\core\Event.hpp" />
<ClInclude Include="..\..\src\core\EventDispatcher.h" /> <ClInclude Include="..\..\src\core\EventDispatcher.h" />
@ -29,24 +33,20 @@
<ClInclude Include="..\..\src\core\Application.h" /> <ClInclude Include="..\..\src\core\Application.h" />
<ClInclude Include="..\..\src\core\Geometry.h" /> <ClInclude Include="..\..\src\core\Geometry.h" />
<ClInclude Include="..\..\src\core\GeometryNode.h" /> <ClInclude Include="..\..\src\core\GeometryNode.h" />
<ClInclude Include="..\..\src\core\helper.hpp" /> <ClInclude Include="..\..\src\core\helper.h" />
<ClInclude Include="..\..\src\core\Image.h" /> <ClInclude Include="..\..\src\core\Image.h" />
<ClInclude Include="..\..\src\core\include-forwards.h" /> <ClInclude Include="..\..\src\core\include-forwards.h" />
<ClInclude Include="..\..\src\core\Input.h" /> <ClInclude Include="..\..\src\core\Input.h" />
<ClInclude Include="..\..\src\core\IntrusiveList.hpp" />
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp" />
<ClInclude Include="..\..\src\core\keys.hpp" /> <ClInclude Include="..\..\src\core\keys.hpp" />
<ClInclude Include="..\..\src\core\Layer.h" />
<ClInclude Include="..\..\src\core\logs.h" /> <ClInclude Include="..\..\src\core\logs.h" />
<ClInclude Include="..\..\src\core\macros.h" />
<ClInclude Include="..\..\src\core\modules.h" /> <ClInclude Include="..\..\src\core\modules.h" />
<ClInclude Include="..\..\src\core\Node.h" /> <ClInclude Include="..\..\src\core\Node.h" />
<ClInclude Include="..\..\src\core\noncopyable.hpp" />
<ClInclude Include="..\..\src\core\Object.h" /> <ClInclude Include="..\..\src\core\Object.h" />
<ClInclude Include="..\..\src\core\RefCounter.hpp" /> <ClInclude Include="..\..\src\core\RefCounter.hpp" />
<ClInclude Include="..\..\src\core\render.h" /> <ClInclude Include="..\..\src\core\render.h" />
<ClInclude Include="..\..\src\core\Resource.h" /> <ClInclude Include="..\..\src\core\Resource.h" />
<ClInclude Include="..\..\src\core\Scene.h" /> <ClInclude Include="..\..\src\core\Scene.h" />
<ClInclude Include="..\..\src\core\Singleton.hpp" />
<ClInclude Include="..\..\src\core\Sprite.h" /> <ClInclude Include="..\..\src\core\Sprite.h" />
<ClInclude Include="..\..\src\core\Task.h" /> <ClInclude Include="..\..\src\core\Task.h" />
<ClInclude Include="..\..\src\core\TaskManager.h" /> <ClInclude Include="..\..\src\core\TaskManager.h" />
@ -63,6 +63,7 @@
<ClInclude Include="..\..\src\dx\helper.hpp" /> <ClInclude Include="..\..\src\dx\helper.hpp" />
<ClInclude Include="..\..\src\dx\TextRenderer.h" /> <ClInclude Include="..\..\src\dx\TextRenderer.h" />
<ClInclude Include="..\..\src\easy2d.h" /> <ClInclude Include="..\..\src\easy2d.h" />
<ClInclude Include="..\..\src\macros.h" />
<ClInclude Include="..\..\src\math\constants.hpp" /> <ClInclude Include="..\..\src\math\constants.hpp" />
<ClInclude Include="..\..\src\math\ease.hpp" /> <ClInclude Include="..\..\src\math\ease.hpp" />
<ClInclude Include="..\..\src\math\Matrix.hpp" /> <ClInclude Include="..\..\src\math\Matrix.hpp" />
@ -101,6 +102,7 @@
<ClCompile Include="..\..\src\core\GeometryNode.cpp" /> <ClCompile Include="..\..\src\core\GeometryNode.cpp" />
<ClCompile Include="..\..\src\core\Image.cpp" /> <ClCompile Include="..\..\src\core\Image.cpp" />
<ClCompile Include="..\..\src\core\Input.cpp" /> <ClCompile Include="..\..\src\core\Input.cpp" />
<ClCompile Include="..\..\src\core\Layer.cpp" />
<ClCompile Include="..\..\src\core\logs.cpp" /> <ClCompile Include="..\..\src\core\logs.cpp" />
<ClCompile Include="..\..\src\core\modules.cpp" /> <ClCompile Include="..\..\src\core\modules.cpp" />
<ClCompile Include="..\..\src\core\Node.cpp" /> <ClCompile Include="..\..\src\core\Node.cpp" />
@ -119,7 +121,6 @@
<ClCompile Include="..\..\src\dx\D3D10DeviceResources.cpp" /> <ClCompile Include="..\..\src\dx\D3D10DeviceResources.cpp" />
<ClCompile Include="..\..\src\dx\D3D11DeviceResources.cpp" /> <ClCompile Include="..\..\src\dx\D3D11DeviceResources.cpp" />
<ClCompile Include="..\..\src\dx\TextRenderer.cpp" /> <ClCompile Include="..\..\src\dx\TextRenderer.cpp" />
<ClCompile Include="..\..\src\math\rand.cpp" />
<ClCompile Include="..\..\src\ui\Button.cpp" /> <ClCompile Include="..\..\src\ui\Button.cpp" />
<ClCompile Include="..\..\src\ui\Menu.cpp" /> <ClCompile Include="..\..\src\ui\Menu.cpp" />
<ClCompile Include="..\..\src\utils\Data.cpp" /> <ClCompile Include="..\..\src\utils\Data.cpp" />

View File

@ -19,6 +19,9 @@
<Filter Include="audio"> <Filter Include="audio">
<UniqueIdentifier>{836608a6-7443-48f9-8acd-18d3ba664348}</UniqueIdentifier> <UniqueIdentifier>{836608a6-7443-48f9-8acd-18d3ba664348}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="common">
<UniqueIdentifier>{86e2d0f2-a9d0-4456-b6a5-d480228bbf82}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\easy2d.h" /> <ClInclude Include="..\..\src\easy2d.h" />
@ -40,9 +43,6 @@
<ClInclude Include="..\..\src\core\logs.h"> <ClInclude Include="..\..\src\core\logs.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\macros.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\modules.h"> <ClInclude Include="..\..\src\core\modules.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
@ -100,9 +100,6 @@
<ClInclude Include="..\..\src\ui\Menu.h"> <ClInclude Include="..\..\src\ui\Menu.h">
<Filter>ui</Filter> <Filter>ui</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\Singleton.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\RefCounter.hpp"> <ClInclude Include="..\..\src\core\RefCounter.hpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
@ -121,9 +118,6 @@
<ClInclude Include="..\..\src\core\Transform.hpp"> <ClInclude Include="..\..\src\core\Transform.hpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\noncopyable.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\utils\string.h"> <ClInclude Include="..\..\src\utils\string.h">
<Filter>utils</Filter> <Filter>utils</Filter>
</ClInclude> </ClInclude>
@ -154,9 +148,6 @@
<ClInclude Include="..\..\src\core\Object.h"> <ClInclude Include="..\..\src\core\Object.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\helper.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\keys.hpp"> <ClInclude Include="..\..\src\core\keys.hpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
@ -178,27 +169,12 @@
<ClInclude Include="..\..\src\core\Event.hpp"> <ClInclude Include="..\..\src\core\Event.hpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\IntrusiveList.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\closure.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\ActionGroup.h"> <ClInclude Include="..\..\src\core\ActionGroup.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\ActionHelper.h"> <ClInclude Include="..\..\src\core\ActionHelper.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\Array.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\config.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Action.h"> <ClInclude Include="..\..\src\core\Action.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
@ -244,7 +220,33 @@
<ClInclude Include="..\..\src\audio\audio-modules.h"> <ClInclude Include="..\..\src\audio\audio-modules.h">
<Filter>audio</Filter> <Filter>audio</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\core\ComPtr.hpp"> <ClInclude Include="..\..\src\core\Layer.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\config.h" />
<ClInclude Include="..\..\src\macros.h" />
<ClInclude Include="..\..\src\common\Array.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\common\closure.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\common\ComPtr.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\common\IntrusiveList.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\common\IntrusivePtr.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\common\noncopyable.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\common\Singleton.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\helper.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
@ -297,9 +299,6 @@
<ClCompile Include="..\..\src\core\window.cpp"> <ClCompile Include="..\..\src\core\window.cpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\math\rand.cpp">
<Filter>math</Filter>
</ClCompile>
<ClCompile Include="..\..\src\utils\Data.cpp"> <ClCompile Include="..\..\src\utils\Data.cpp">
<Filter>utils</Filter> <Filter>utils</Filter>
</ClCompile> </ClCompile>
@ -393,5 +392,8 @@
<ClCompile Include="..\..\src\audio\audio-modules.cpp"> <ClCompile Include="..\..\src\audio\audio-modules.cpp">
<Filter>audio</Filter> <Filter>audio</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\core\Layer.cpp">
<Filter>core</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -136,8 +136,9 @@
<ClCompile Include="..\..\3rd-party\ImGui\imgui_demo.cpp" /> <ClCompile Include="..\..\3rd-party\ImGui\imgui_demo.cpp" />
<ClCompile Include="..\..\3rd-party\ImGui\imgui_draw.cpp" /> <ClCompile Include="..\..\3rd-party\ImGui\imgui_draw.cpp" />
<ClCompile Include="..\..\3rd-party\ImGui\imgui_widgets.cpp" /> <ClCompile Include="..\..\3rd-party\ImGui\imgui_widgets.cpp" />
<ClCompile Include="imgui_impl_dx11.cpp" /> <ClCompile Include="easy2d-imgui\ImGuiLayer.cpp" />
<ClCompile Include="imgui_impl_win32.cpp" /> <ClCompile Include="easy2d-imgui\ImGuiView.cpp" />
<ClCompile Include="easy2d-imgui\imgui_impl_dx11.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -147,8 +148,10 @@
<ClInclude Include="..\..\3rd-party\ImGui\imstb_rectpack.h" /> <ClInclude Include="..\..\3rd-party\ImGui\imstb_rectpack.h" />
<ClInclude Include="..\..\3rd-party\ImGui\imstb_textedit.h" /> <ClInclude Include="..\..\3rd-party\ImGui\imstb_textedit.h" />
<ClInclude Include="..\..\3rd-party\ImGui\imstb_truetype.h" /> <ClInclude Include="..\..\3rd-party\ImGui\imstb_truetype.h" />
<ClInclude Include="imgui_impl_dx11.h" /> <ClInclude Include="easy2d-imgui\easy2d-imgui.h" />
<ClInclude Include="imgui_impl_win32.h" /> <ClInclude Include="easy2d-imgui\ImGuiLayer.h" />
<ClInclude Include="easy2d-imgui\ImGuiView.h" />
<ClInclude Include="easy2d-imgui\imgui_impl_dx11.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Easy2D\Easy2D.vcxproj"> <ProjectReference Include="..\Easy2D\Easy2D.vcxproj">

View File

@ -2,8 +2,6 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="imgui_impl_win32.cpp" />
<ClCompile Include="imgui_impl_dx11.cpp" />
<ClCompile Include="..\..\3rd-party\ImGui\imgui.cpp"> <ClCompile Include="..\..\3rd-party\ImGui\imgui.cpp">
<Filter>imgui</Filter> <Filter>imgui</Filter>
</ClCompile> </ClCompile>
@ -16,10 +14,17 @@
<ClCompile Include="..\..\3rd-party\ImGui\imgui_widgets.cpp"> <ClCompile Include="..\..\3rd-party\ImGui\imgui_widgets.cpp">
<Filter>imgui</Filter> <Filter>imgui</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="easy2d-imgui\imgui_impl_dx11.cpp">
<Filter>easy2d-imgui</Filter>
</ClCompile>
<ClCompile Include="easy2d-imgui\ImGuiLayer.cpp">
<Filter>easy2d-imgui</Filter>
</ClCompile>
<ClCompile Include="easy2d-imgui\ImGuiView.cpp">
<Filter>easy2d-imgui</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="imgui_impl_win32.h" />
<ClInclude Include="imgui_impl_dx11.h" />
<ClInclude Include="..\..\3rd-party\ImGui\imconfig.h"> <ClInclude Include="..\..\3rd-party\ImGui\imconfig.h">
<Filter>imgui</Filter> <Filter>imgui</Filter>
</ClInclude> </ClInclude>
@ -38,10 +43,25 @@
<ClInclude Include="..\..\3rd-party\ImGui\imstb_truetype.h"> <ClInclude Include="..\..\3rd-party\ImGui\imstb_truetype.h">
<Filter>imgui</Filter> <Filter>imgui</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="easy2d-imgui\imgui_impl_dx11.h">
<Filter>easy2d-imgui</Filter>
</ClInclude>
<ClInclude Include="easy2d-imgui\ImGuiLayer.h">
<Filter>easy2d-imgui</Filter>
</ClInclude>
<ClInclude Include="easy2d-imgui\ImGuiView.h">
<Filter>easy2d-imgui</Filter>
</ClInclude>
<ClInclude Include="easy2d-imgui\easy2d-imgui.h">
<Filter>easy2d-imgui</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="imgui"> <Filter Include="imgui">
<UniqueIdentifier>{24ae99cd-ee12-481f-bb03-d8be40d99342}</UniqueIdentifier> <UniqueIdentifier>{24ae99cd-ee12-481f-bb03-d8be40d99342}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="easy2d-imgui">
<UniqueIdentifier>{37f1585a-e992-454a-8cac-e9a6142b08b6}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,165 @@
// Copyright (C) 2019 Nomango
#include "easy2d-imgui.h"
namespace easy2d
{
namespace
{
Map<int, int> 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();
}
}

View File

@ -0,0 +1,53 @@
// Copyright (C) 2019 Nomango
#pragma once
namespace easy2d
{
E2D_DECLARE_SMART_PTR(ImGuiLayer);
using ImGuiPipeline = std::function<void()>;
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<String, ImGuiPipeline> pipelines_;
};
}

View File

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

View File

@ -0,0 +1,26 @@
// Copyright (C) 2019 Nomango
#pragma once
namespace easy2d
{
class ImGuiView
: public Singleton<ImGuiView>
, public Component
{
E2D_DECLARE_SINGLETON(ImGuiView);
public:
void Setup(Application* app) override;
void Destroy() override;
public:
void Init(HWND hwnd);
void NewFrame();
void Render();
};
}

View File

@ -0,0 +1,9 @@
// Copyright (C) 2019 Nomango
#pragma once
#include "easy2d.h"
#include "ImGuiView.h"
#include "ImGuiLayer.h"
// ImGui
#include "imgui.h"

View File

@ -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 <windows.h>
#include <tchar.h>
// 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 *)&current_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;
}

View File

@ -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 <windows.h> 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);
*/

View File

@ -1,11 +1,8 @@
// ImGui // Copyright (C) 2019 Nomango
#include "imgui.h"
#include "imgui_impl_win32.h"
#include "imgui_impl_dx11.h"
#include <tchar.h>
// easy2d
#include "easy2d.h" #include "easy2d.h"
#include "easy2d-imgui/easy2d-imgui.h"
using namespace easy2d; using namespace easy2d;
const int WINDOW_WIDTH = 1280; const int WINDOW_WIDTH = 1280;
@ -17,108 +14,36 @@ class ImGuiScene
: public Scene : public Scene
{ {
bool show_demo_window = true; bool show_demo_window = true;
bool show_another_window = false;
Color clear_color = Color(0.45f, 0.55f, 0.6f, 1.f);
public: public:
void OnEnter() override ImGuiScene()
{ {
// Setup Dear ImGui context // 创建 ImGui 图层
IMGUI_CHECKVERSION(); ImGuiLayerPtr layer = new ImGuiLayer;
ImGui::CreateContext(); AddChild(layer);
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style // 添加 ImGui 提供的 Demo 窗口
ImGui::StyleColorsDark(); layer->AddItem([=]() {
//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) if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window); ImGui::ShowDemoWindow(&show_demo_window);
}, L"DemoWindow");
// 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();
} }
}; };
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND, UINT, WPARAM, LPARAM);
class ImGuiApp class ImGuiApp
: public Application : public Application
{ {
public: public:
ImGuiApp() ImGuiApp()
{ {
Options options; // 添加 ImGui 组件
options.title = L"ImGui Demo"; Use(&ImGuiView::Instance());
options.width = WINDOW_WIDTH;
options.height = WINDOW_HEIGHT; // 初始化
Options options(L"ImGui Demo", WINDOW_WIDTH, WINDOW_HEIGHT);
options.clear_color = Color(0.45f, 0.55f, 0.6f, 1.f); options.clear_color = Color(0.45f, 0.55f, 0.6f, 1.f);
Init(options); Init(options);
SetPreMessageProc(ImGui_ImplWin32_WndProcHandler);
} }
void OnStart() override void OnStart() override

View File

@ -39,7 +39,7 @@ public:
void ChangeDemoScene() void ChangeDemoScene()
{ {
Window::Instance().SetTitle(s_Demos[s_DemoIndex].title); GetWindow()->SetTitle(s_Demos[s_DemoIndex].title);
ScenePtr scene = s_Demos[s_DemoIndex].Create(); ScenePtr scene = s_Demos[s_DemoIndex].Create();
EnterScene(scene); EnterScene(scene);

View File

@ -24,7 +24,7 @@
#include "Transcoder.h" #include "Transcoder.h"
#include "audio-modules.h" #include "audio-modules.h"
#include "../core/ComPtr.hpp" #include "../common/ComPtr.hpp"
#include "../core/logs.h" #include "../core/logs.h"
#include "../core/modules.h" #include "../core/modules.h"

View File

@ -19,8 +19,8 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/macros.h" #include "../macros.h"
#include "../core/noncopyable.hpp" #include "../common/noncopyable.hpp"
#include <xaudio2.h> #include <xaudio2.h>
namespace easy2d namespace easy2d

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/macros.h" #include "../macros.h"
#include <xaudio2.h> #include <xaudio2.h>
#include <mfapi.h> #include <mfapi.h>
#include <mfidl.h> #include <mfidl.h>

View File

@ -34,7 +34,7 @@ namespace easy2d
{ {
} }
void Audio::Setup() void Audio::Setup(Application*)
{ {
E2D_LOG(L"Creating audio resources"); E2D_LOG(L"Creating audio resources");
@ -65,7 +65,11 @@ namespace easy2d
mastering_voice_ = nullptr; mastering_voice_ = nullptr;
} }
DX::SafeRelease(x_audio2_); if (x_audio2_)
{
x_audio2_->Release();
x_audio2_ = nullptr;
}
modules::MediaFoundation::Get().MFShutdown(); modules::MediaFoundation::Get().MFShutdown();
} }

View File

@ -20,8 +20,8 @@
#pragma once #pragma once
#include "../core/include-forwards.h" #include "../core/include-forwards.h"
#include "../core/Singleton.hpp"
#include "../core/Component.h" #include "../core/Component.h"
#include "../common/Singleton.hpp"
#include "Voice.h" #include "Voice.h"
namespace easy2d namespace easy2d
@ -35,7 +35,7 @@ namespace easy2d
using VoiceMap = UnorderedSet<Voice*>; using VoiceMap = UnorderedSet<Voice*>;
public: public:
void Setup() override; void Setup(Application*) override;
void Destroy() override; void Destroy() override;

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
namespace easy2d namespace easy2d
{ {

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/IntrusivePtr.hpp" #include "IntrusivePtr.hpp"
#include <Unknwnbase.h> #include <Unknwnbase.h>
namespace easy2d namespace easy2d

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
#include <functional> #include <functional>
#ifdef E2D_DEBUG #ifdef E2D_DEBUG

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
#include <utility> #include <utility>
namespace easy2d namespace easy2d

View File

@ -20,6 +20,14 @@
#pragma once #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 namespace easy2d
{ {
template <typename _Ty> template <typename _Ty>
@ -28,7 +36,7 @@ namespace easy2d
public: public:
static inline _Ty& Instance() static inline _Ty& Instance()
{ {
static _Ty instance; // Thread safe static _Ty instance; // Thread-safe
return instance; return instance;
} }
@ -41,11 +49,3 @@ namespace easy2d
Singleton& operator=(const Singleton&) = delete; 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

View File

@ -23,6 +23,17 @@
namespace easy2d namespace easy2d
{ {
//
// Closure is a simple function for binding member functions
//
template<typename _Ty, typename _Ret, typename... _Args>
std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...));
//
// Details of Closure
//
namespace __closure__detail namespace __closure__detail
{ {
// sequence & generater // sequence & generater
@ -62,10 +73,6 @@ namespace easy2d
}; };
} }
//
// Closure is a simple function for binding member functions
//
template<typename _Ty, typename _Ret, typename... _Args> template<typename _Ty, typename _Ret, typename... _Args>
inline std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...)) inline std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...))
{ {

View File

@ -19,11 +19,10 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h"
namespace easy2d namespace easy2d
{ {
class E2D_API Noncopyable class Noncopyable
{ {
protected: protected:
Noncopyable() = default; Noncopyable() = default;

View File

@ -21,7 +21,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "time.h" #include "time.h"
#include "IntrusiveList.hpp" #include "../common/IntrusiveList.hpp"
namespace easy2d namespace easy2d
{ {

View File

@ -22,7 +22,6 @@
#include "logs.h" #include "logs.h"
#include "modules.h" #include "modules.h"
#include "render.h" #include "render.h"
#include "window.h"
#include "input.h" #include "input.h"
#include "Event.hpp" #include "Event.hpp"
#include "Scene.h" #include "Scene.h"
@ -36,22 +35,17 @@
namespace easy2d namespace easy2d
{ {
namespace
{
LRESULT(*pre_proc)(HWND, UINT, WPARAM, LPARAM) = nullptr; // Custom message proc for user
}
Application::Application(String const& app_name) Application::Application(String const& app_name)
: end_(true) : end_(true)
, inited_(false) , inited_(false)
, curr_scene_(nullptr) , main_window_(nullptr)
, next_scene_(nullptr)
, transition_(nullptr)
, time_scale_(1.f) , time_scale_(1.f)
, app_name_(app_name) , app_name_(app_name)
{ {
::CoInitialize(nullptr); ::CoInitialize(nullptr);
main_window_ = new Window;
Use(&Renderer::Instance()); Use(&Renderer::Instance());
Use(&Input::Instance()); Use(&Input::Instance());
} }
@ -66,7 +60,7 @@ namespace easy2d
void Application::Init(const Options& options) void Application::Init(const Options& options)
{ {
ThrowIfFailed( ThrowIfFailed(
Window::Instance().Create( main_window_->Create(
options.title, options.title,
options.width, options.width,
options.height, 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().SetClearColor(options.clear_color);
Renderer::Instance().SetVSyncEnabled(options.vsync); Renderer::Instance().SetVSyncEnabled(options.vsync);
// Setup all components // Setup all components
for (Component* c : components_) for (Component* c : components_)
{ {
c->Setup(); c->Setup(this);
} }
OnStart(); OnStart();
@ -101,13 +94,15 @@ namespace easy2d
void Application::Run() 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) if (hwnd)
{ {
end_ = false; end_ = false;
main_window_->Prepare();
Window::Instance().Prepare();
MSG msg = {}; MSG msg = {};
while (::GetMessageW(&msg, nullptr, 0, 0) && !end_) while (::GetMessageW(&msg, nullptr, 0, 0) && !end_)
@ -125,24 +120,25 @@ namespace easy2d
void Application::Destroy() void Application::Destroy()
{ {
if (inited_)
{
inited_ = false;
if (curr_scene_)
curr_scene_->OnExit();
transition_.Reset(); transition_.Reset();
next_scene_.Reset(); next_scene_.Reset();
curr_scene_.Reset(); curr_scene_.Reset();
debug_node_.Reset(); debug_node_.Reset();
if (inited_)
{
inited_ = false;
for (auto iter = components_.rbegin(); iter != components_.rend(); ++iter) for (auto iter = components_.rbegin(); iter != components_.rend(); ++iter)
{ {
(*iter)->Destroy(); (*iter)->Destroy();
} }
Window::Instance().Destroy(); if (main_window_)
{
delete main_window_;
main_window_ = nullptr;
}
} }
} }
@ -166,7 +162,7 @@ namespace easy2d
{ {
if (component) if (component)
{ {
for (auto iter = components_.begin(); iter != components_.end(); iter++) for (auto iter = components_.begin(); iter != components_.end(); ++iter)
{ {
if ((*iter) == component) if ((*iter) == component)
{ {
@ -213,11 +209,6 @@ namespace easy2d
time_scale_ = scale_factor; time_scale_ = scale_factor;
} }
void Application::SetPreMessageProc(LRESULT(*proc)(HWND, UINT, WPARAM, LPARAM))
{
pre_proc = proc;
}
void Application::ShowDebugInfo(bool show) void Application::ShowDebugInfo(bool show)
{ {
if (show) if (show)
@ -290,11 +281,11 @@ namespace easy2d
curr_scene_->Render(); curr_scene_->Render();
} }
OnRender();
if (debug_node_) if (debug_node_)
debug_node_->Render(); debug_node_->Render();
OnRender();
ThrowIfFailed( ThrowIfFailed(
Renderer::Instance().EndDraw() Renderer::Instance().EndDraw()
); );
@ -336,9 +327,6 @@ namespace easy2d
LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 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<Application*>( Application * app = reinterpret_cast<Application*>(
static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA)) static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA))
); );
@ -359,13 +347,16 @@ namespace easy2d
break; break;
case WM_KEYDOWN: case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP: 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_) 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<int>(wparam); evt.key.code = static_cast<int>(wparam);
evt.key.count = static_cast<int>(lparam & 0xFF); evt.key.count = static_cast<int>(lparam & 0xFF);
@ -374,6 +365,19 @@ namespace easy2d
} }
break; break;
case WM_CHAR:
{
if (!app->transition_ && app->curr_scene_)
{
Event evt(Event::Char);
evt.key.c = static_cast<char>(wparam);
evt.key.count = static_cast<int>(lparam & 0xFF);
app->curr_scene_->Dispatch(evt);
}
}
break;
case WM_LBUTTONUP: case WM_LBUTTONUP:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
//case WM_LBUTTONDBLCLK: //case WM_LBUTTONDBLCLK:
@ -426,7 +430,7 @@ namespace easy2d
UINT width = LOWORD(lparam); UINT width = LOWORD(lparam);
UINT height = HIWORD(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) if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
{ {
@ -444,7 +448,7 @@ namespace easy2d
app->curr_scene_->Dispatch(evt); app->curr_scene_->Dispatch(evt);
} }
Window::Instance().UpdateWindowRect(); app->GetWindow()->UpdateWindowRect();
} }
} }
break; break;
@ -470,7 +474,7 @@ namespace easy2d
E2D_LOG(active ? L"Window activated" : L"Window deactivated"); E2D_LOG(active ? L"Window activated" : L"Window deactivated");
Window::Instance().SetActive(active); app->GetWindow()->SetActive(active);
if (app->curr_scene_) if (app->curr_scene_)
{ {
@ -512,12 +516,11 @@ namespace easy2d
{ {
E2D_LOG(L"Window is closing"); E2D_LOG(L"Window is closing");
if (app->OnClosing()) if (!app->OnClosing())
{ {
Window::Instance().Destroy();
}
return 0; return 0;
} }
}
break; break;
case WM_DESTROY: case WM_DESTROY:

View File

@ -21,6 +21,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "time.h" #include "time.h"
#include "window.h"
#include "Component.h" #include "Component.h"
namespace easy2d namespace easy2d
@ -35,20 +36,10 @@ namespace easy2d
bool vsync; // 垂直同步 bool vsync; // 垂直同步
bool fullscreen; // 全屏模式 bool fullscreen; // 全屏模式
Options()
: title(L"Easy2D Game")
, width(640)
, height(480)
, icon(nullptr)
, clear_color(Color::Black)
, vsync(true)
, fullscreen(false)
{}
Options( Options(
String const& title, String const& title = L"Easy2D Game",
int width, int width = 640,
int height, int height = 480,
LPCWSTR icon = nullptr, LPCWSTR icon = nullptr,
Color clear_color = Color::Black, Color clear_color = Color::Black,
bool vsync = true, bool vsync = true,
@ -128,16 +119,14 @@ namespace easy2d
// 获取当前场景 // 获取当前场景
ScenePtr const& GetCurrentScene(); ScenePtr const& GetCurrentScene();
// »ñÈ¡Ö÷´°¿Ú
inline Window* GetWindow() const { return main_window_; }
// 设置时间缩放因子 // 设置时间缩放因子
void SetTimeScale( void SetTimeScale(
float scale_factor float scale_factor
); );
// 设置消息预处理函数
void SetPreMessageProc(
LRESULT (*proc)(HWND, UINT, WPARAM, LPARAM)
);
// 显示调试信息 // 显示调试信息
void ShowDebugInfo( void ShowDebugInfo(
bool show = true bool show = true
@ -158,11 +147,13 @@ namespace easy2d
bool inited_; bool inited_;
float time_scale_; float time_scale_;
String app_name_; String app_name_;
ScenePtr curr_scene_; ScenePtr curr_scene_;
ScenePtr next_scene_; ScenePtr next_scene_;
NodePtr debug_node_; NodePtr debug_node_;
TransitionPtr transition_; TransitionPtr transition_;
Window* main_window_;
Array<Component*> components_; Array<Component*> components_;
}; };
} }

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
namespace easy2d namespace easy2d
{ {

View File

@ -22,10 +22,12 @@
namespace easy2d namespace easy2d
{ {
class Application;
class Component class Component
{ {
public: public:
virtual void Setup() = 0; virtual void Setup(Application*) = 0;
virtual void Destroy() = 0; virtual void Destroy() = 0;
}; };

View File

@ -19,6 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "DebugNode.h" #include "DebugNode.h"
#include "Text.h"
#include "render.h" #include "render.h"
#include "../utils/string.h" #include "../utils/string.h"
#include <sstream> #include <sstream>

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "Text.h" #include "Node.h"
#include "time.h" #include "time.h"
namespace easy2d namespace easy2d

View File

@ -19,7 +19,6 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h"
#include "keys.hpp" #include "keys.hpp"
namespace easy2d namespace easy2d
@ -33,6 +32,8 @@ namespace easy2d
bool left_btn_down; // 左键是否按下 bool left_btn_down; // 左键是否按下
bool right_btn_down; // 右键是否按下 bool right_btn_down; // 右键是否按下
union
{
struct // Events::MouseDown | Events::MouseUp | Events::MouseClick struct // Events::MouseDown | Events::MouseUp | Events::MouseClick
{ {
int button; int button;
@ -42,6 +43,7 @@ namespace easy2d
{ {
float wheel; float wheel;
}; };
};
static bool Check(UINT type); static bool Check(UINT type);
}; };
@ -49,8 +51,19 @@ namespace easy2d
// 键盘事件 // 键盘事件
struct KeyboardEvent struct KeyboardEvent
{ {
int code; // enum KeyCode
int count; int count;
union
{
struct // Events::KeyDown | Events::KeyUp
{
int code; // enum KeyCode
};
struct // Events::Char
{
char c;
};
};
static bool Check(UINT type); static bool Check(UINT type);
}; };
@ -114,6 +127,7 @@ namespace easy2d
KeyFirst, KeyFirst,
KeyDown, // 按键按下 KeyDown, // 按键按下
KeyUp, // 按键抬起 KeyUp, // 按键抬起
Char, // 输出字符
KeyLast, KeyLast,
// 窗口消息 // 窗口消息

View File

@ -20,7 +20,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "IntrusiveList.hpp" #include "../common/IntrusiveList.hpp"
#include "Event.hpp" #include "Event.hpp"
namespace easy2d namespace easy2d

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include <d2d1.h>
namespace easy2d namespace easy2d
{ {

View File

@ -21,6 +21,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "Resource.h" #include "Resource.h"
#include <d2d1.h>
namespace easy2d namespace easy2d
{ {

View File

@ -21,8 +21,8 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "keys.hpp" #include "keys.hpp"
#include "Singleton.hpp"
#include "Component.h" #include "Component.h"
#include "../common/Singleton.hpp"
namespace easy2d namespace easy2d
{ {
@ -58,7 +58,7 @@ namespace easy2d
Point GetMousePos(); Point GetMousePos();
public: public:
void Setup() override {} void Setup(Application*) override {}
void Destroy() override {} void Destroy() override {}

88
src/core/Layer.cpp Normal file
View File

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

View File

@ -18,21 +18,32 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include "rand.h" #pragma once
#include "Node.h"
namespace easy2d namespace easy2d
{ {
namespace math class E2D_API Layer
: public Node
{ {
namespace public:
{ Layer();
std::random_device device;
std::default_random_engine engine(device());
}
std::default_random_engine& GetRandomEngine() virtual ~Layer();
{
return engine; 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);
};
} }

View File

@ -48,6 +48,7 @@ namespace easy2d
, dirty_transform_(false) , dirty_transform_(false)
, dirty_transform_inverse_(false) , dirty_transform_inverse_(false)
, parent_(nullptr) , parent_(nullptr)
, scene_(nullptr)
, hash_name_(0) , hash_name_(0)
, z_order_(0) , z_order_(0)
, opacity_(1.f) , opacity_(1.f)
@ -194,16 +195,6 @@ namespace easy2d
return transform_matrix_inverse_; return transform_matrix_inverse_;
} }
Node* Node::GetParent() const
{
return parent_;
}
Scene* Node::GetScene() const
{
return scene_;
}
void Node::UpdateTransform() const void Node::UpdateTransform() const
{ {
if (!dirty_transform_) if (!dirty_transform_)
@ -238,6 +229,8 @@ namespace easy2d
} }
void Node::SetScene(Scene* scene) void Node::SetScene(Scene* scene)
{
if (scene && scene_ != scene)
{ {
scene_ = scene; scene_ = scene;
for (Node* child = children_.First().Get(); child; child = child->NextItem().Get()) for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
@ -245,6 +238,7 @@ namespace easy2d
child->scene_ = scene; child->scene_ = scene;
} }
} }
}
void Node::SetZOrder(int zorder) void Node::SetZOrder(int zorder)
{ {

View File

@ -25,7 +25,6 @@
#include "TaskManager.h" #include "TaskManager.h"
#include "ActionManager.h" #include "ActionManager.h"
#include "EventDispatcher.h" #include "EventDispatcher.h"
#include "IntrusiveList.hpp"
namespace easy2d namespace easy2d
{ {
@ -37,10 +36,9 @@ namespace easy2d
, public TaskManager , public TaskManager
, public ActionManager , public ActionManager
, public EventDispatcher , public EventDispatcher
, protected IntrusiveListItem<NodePtr> , public IntrusiveListItem<NodePtr>
{ {
friend class Application; friend class Application;
friend class Scene;
friend class Transition; friend class Transition;
friend class IntrusiveList<NodePtr>; friend class IntrusiveList<NodePtr>;
@ -56,9 +54,6 @@ namespace easy2d
// 渲染节点 // 渲染节点
virtual void OnRender() {} virtual void OnRender() {}
// 事件分发
void Dispatch(Event& evt) override;
// 获取显示状态 // 获取显示状态
bool IsVisible() const { return visible_; } bool IsVisible() const { return visible_; }
@ -135,10 +130,10 @@ namespace easy2d
Matrix const& GetTransformInverseMatrix() const; Matrix const& GetTransformInverseMatrix() const;
// 获取父节点 // 获取父节点
Node* GetParent() const; inline Node* GetParent() const { return parent_; }
// 获取所在场景 // 获取所在场景
Scene* GetScene() const; inline Scene* GetScene() const { return scene_; }
// 设置是否显示 // 设置是否显示
void SetVisible( void SetVisible(
@ -364,6 +359,10 @@ namespace easy2d
float anchor_y float anchor_y
); );
public:
// 事件分发
void Dispatch(Event& evt) override;
protected: protected:
virtual void PrepareRender() {} virtual void PrepareRender() {}
@ -402,6 +401,7 @@ namespace easy2d
}; };
// 可视化节点
class E2D_API VisualNode class E2D_API VisualNode
: public Node : public Node
{ {

View File

@ -19,8 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "RefCounter.hpp" #include "helper.h"
#include "helper.hpp"
namespace easy2d namespace easy2d
{ {

View File

@ -19,8 +19,8 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
#include "noncopyable.hpp" #include "../common/noncopyable.hpp"
namespace easy2d namespace easy2d
{ {

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "helper.hpp" #include "helper.h"
namespace easy2d namespace easy2d
{ {

View File

@ -19,14 +19,18 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "Scene.h" #include "Scene.h"
#include "Node.h"
#include "logs.h" #include "logs.h"
#include "render.h"
namespace easy2d namespace easy2d
{ {
Scene::Scene() Scene::Scene()
: mouse_cursor_(MouseCursor::Arrow)
, last_mouse_cursor(MouseCursor(-1))
{ {
scene_ = this; scene_ = this;
SetSize(Renderer::Instance().GetOutputSize());
} }
Scene::~Scene() Scene::~Scene()
@ -43,4 +47,33 @@ namespace easy2d
E2D_LOG(L"Scene exited"); 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;
}
} }

View File

@ -37,5 +37,16 @@ namespace easy2d
// 退出场景 // 退出场景
virtual void OnExit(); virtual void OnExit();
public:
void Update(Duration dt);
void SetMouseCursor(
MouseCursor cursor
);
protected:
MouseCursor mouse_cursor_;
MouseCursor last_mouse_cursor;
}; };
} }

View File

@ -21,7 +21,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "time.h" #include "time.h"
#include "IntrusiveList.hpp" #include "../common/IntrusiveList.hpp"
#include <functional> #include <functional>
namespace easy2d namespace easy2d

View File

@ -22,6 +22,7 @@
#include "Node.h" #include "Node.h"
#include "Font.hpp" #include "Font.hpp"
#include "TextStyle.hpp" #include "TextStyle.hpp"
#include <dwrite.h>
namespace easy2d namespace easy2d
{ {

View File

@ -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 }; out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f };
} }

View File

@ -21,6 +21,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "time.h" #include "time.h"
#include <d2d1.h>
namespace easy2d namespace easy2d
{ {

View File

@ -20,13 +20,8 @@
#pragma once #pragma once
#include "RefCounter.hpp" #include "RefCounter.hpp"
#include "IntrusivePtr.hpp" #include "../common/Array.h"
#include "ComPtr.hpp" #include "../common/IntrusivePtr.hpp"
#include "Array.h"
#include "closure.hpp"
#include "../math/vector.hpp"
#include "../math/Rect.hpp"
#include "../math/Matrix.hpp"
#include <set> #include <set>
#include <map> #include <map>
#include <list> #include <list>
@ -89,6 +84,7 @@ namespace easy2d
E2D_DECLARE_SMART_PTR(Node); E2D_DECLARE_SMART_PTR(Node);
E2D_DECLARE_SMART_PTR(Scene); E2D_DECLARE_SMART_PTR(Scene);
E2D_DECLARE_SMART_PTR(Layer);
E2D_DECLARE_SMART_PTR(Sprite); E2D_DECLARE_SMART_PTR(Sprite);
E2D_DECLARE_SMART_PTR(Text); E2D_DECLARE_SMART_PTR(Text);
E2D_DECLARE_SMART_PTR(Canvas); E2D_DECLARE_SMART_PTR(Canvas);
@ -120,11 +116,8 @@ namespace easy2d
E2D_DECLARE_SMART_PTR(MoveTransition); E2D_DECLARE_SMART_PTR(MoveTransition);
E2D_DECLARE_SMART_PTR(RotationTransition); E2D_DECLARE_SMART_PTR(RotationTransition);
E2D_DECLARE_NS_SMART_PTR(ui, Button); E2D_DECLARE_SMART_PTR(Button);
E2D_DECLARE_NS_SMART_PTR(ui, Menu); E2D_DECLARE_SMART_PTR(Menu);
using namespace math;
using namespace ui;
} }
namespace easy2d namespace easy2d

View File

@ -19,14 +19,19 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "helper.h"
#include "Color.h" #include "Color.h"
#include "Object.h" #include "Object.h"
#include "helper.hpp" #include "../common/ComPtr.hpp"
#include "../DX/helper.hpp" #include "../common/Closure.hpp"
#include "../math/vector.hpp"
#include "../math/Rect.hpp"
#include "../math/Matrix.hpp"
namespace easy2d namespace easy2d
{ {
using namespace math;
// 画笔样式 // 画笔样式
enum class StrokeStyle : int enum class StrokeStyle : int
{ {
@ -44,6 +49,19 @@ namespace easy2d
Right /* 右 */ Right /* 右 */
}; };
// 鼠标指针
enum class MouseCursor : int
{
Arrow, /* 指针 */
TextInput, /* 输入文本 */
Hand, /* 手指 */
SizeAll,
SizeNESW,
SizeNS,
SizeNWSE,
SizeWE,
};
// 文字抗锯齿属性 // 文字抗锯齿属性
enum class TextAntialias enum class TextAntialias
{ {

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
namespace easy2d namespace easy2d
{ {
@ -54,6 +54,10 @@ namespace easy2d
Esc = VK_ESCAPE, Esc = VK_ESCAPE,
Ctrl = VK_CONTROL, Ctrl = VK_CONTROL,
Shift = VK_SHIFT, Shift = VK_SHIFT,
Alt = VK_MENU,
Tab = VK_TAB,
Delete = VK_DELETE,
Back = VK_BACK,
A = 0x41, A = 0x41,
B, B,

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
#ifdef E2D_DISABLE_LOG_FUNCTIONS #ifdef E2D_DISABLE_LOG_FUNCTIONS

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
#include <xaudio2.h> #include <xaudio2.h>
#include <mfapi.h> #include <mfapi.h>
#include <mfidl.h> #include <mfidl.h>

View File

@ -21,6 +21,7 @@
#include "render.h" #include "render.h"
#include "logs.h" #include "logs.h"
#include "Image.h" #include "Image.h"
#include "Application.h"
namespace easy2d namespace easy2d
{ {
@ -29,7 +30,7 @@ namespace easy2d
, antialias_(true) , antialias_(true)
, vsync_(true) , vsync_(true)
, text_antialias_(TextAntialias::ClearType) , text_antialias_(TextAntialias::ClearType)
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) , clear_color_(Color::Black)
, opacity_(1.f) , opacity_(1.f)
, collecting_data_(false) , collecting_data_(false)
{ {
@ -40,11 +41,14 @@ namespace easy2d
{ {
} }
void Renderer::Setup() void Renderer::Setup(Application* app)
{ {
E2D_LOG(L"Creating device resources"); E2D_LOG(L"Creating device resources");
HRESULT hr = hwnd_ ? S_OK : E_FAIL; HRESULT hr;
hwnd_ = app->GetWindow()->GetHandle();
hr = hwnd_ ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -74,6 +78,11 @@ namespace easy2d
hr = CreateDeviceResources(); hr = CreateDeviceResources();
} }
if (SUCCEEDED(hr))
{
output_size_ = app->GetWindow()->GetSize();
}
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
@ -89,11 +98,6 @@ namespace easy2d
device_resources_.Reset(); device_resources_.Reset();
} }
void Renderer::SetTargetWindow(HWND hwnd)
{
hwnd_ = hwnd;
}
HRESULT Renderer::CreateDeviceResources() HRESULT Renderer::CreateDeviceResources()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -344,6 +348,17 @@ namespace easy2d
return S_OK; return S_OK;
} }
HRESULT Renderer::Resize(UINT width, UINT height)
{
output_size_.x = static_cast<float>(width);
output_size_.y = static_cast<float>(height);
if (device_resources_)
{
return device_resources_->SetLogicalSize(output_size_);
}
return S_OK;
}
void Renderer::StartCollectData() void Renderer::StartCollectData()
{ {
collecting_data_ = true; collecting_data_ = true;
@ -356,7 +371,7 @@ namespace easy2d
void Renderer::SetClearColor(const Color & color) void Renderer::SetClearColor(const Color & color)
{ {
clear_color_ = DX::ConvertToColorF(color); clear_color_ = color;
} }
HRESULT Renderer::SetTransform(const Matrix & matrix) HRESULT Renderer::SetTransform(const Matrix & matrix)

View File

@ -24,7 +24,7 @@
#include "Resource.h" #include "Resource.h"
#include "TextStyle.hpp" #include "TextStyle.hpp"
#include "Component.h" #include "Component.h"
#include "Singleton.hpp" #include "../common/Singleton.hpp"
#include "../DX/helper.hpp" #include "../DX/helper.hpp"
#include "../DX/DeviceResources.h" #include "../DX/DeviceResources.h"
#include "../DX/TextRenderer.h" #include "../DX/TextRenderer.h"
@ -130,13 +130,16 @@ namespace easy2d
HRESULT PopLayer(); HRESULT PopLayer();
HRESULT Resize(
UINT width,
UINT height
);
public: public:
void Setup() override; void Setup(Application*) override;
void Destroy() override; void Destroy() override;
void SetTargetWindow(HWND);
void StartCollectData(); void StartCollectData();
void StopCollectData(); void StopCollectData();
@ -145,6 +148,8 @@ namespace easy2d
inline RenderStatus const& GetStatus() const { return status_; } inline RenderStatus const& GetStatus() const { return status_; }
inline Size const& GetOutputSize() const { return output_size_; }
inline DeviceResources* GetDeviceResources() const { return device_resources_.Get(); } inline DeviceResources* GetDeviceResources() const { return device_resources_.Get(); }
inline ITextRenderer* GetTextRenderer() const { return text_renderer_.Get(); } inline ITextRenderer* GetTextRenderer() const { return text_renderer_.Get(); }
@ -169,8 +174,9 @@ namespace easy2d
bool vsync_; bool vsync_;
bool collecting_data_; bool collecting_data_;
Size output_size_;
Color clear_color_;
TextAntialias text_antialias_; TextAntialias text_antialias_;
D2D1_COLOR_F clear_color_;
RenderStatus status_; RenderStatus status_;
ComPtr<DeviceResources> device_resources_; ComPtr<DeviceResources> device_resources_;

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "macros.h" #include "../macros.h"
namespace easy2d namespace easy2d
{ {

View File

@ -49,6 +49,20 @@ namespace easy2d
Window::~Window() Window::~Window()
{ {
if (is_fullscreen_)
RestoreResolution(device_name_);
if (device_name_)
{
delete[] device_name_;
device_name_ = nullptr;
}
if (handle_)
{
::DestroyWindow(handle_);
handle_ = nullptr;
}
} }
HRESULT Window::Create(String title, int width, int height, LPCWSTR icon, bool fullscreen, WNDPROC proc) HRESULT Window::Create(String title, int width, int height, LPCWSTR icon, bool fullscreen, WNDPROC proc)
@ -65,7 +79,7 @@ namespace easy2d
wcex.hInstance = hinst; wcex.hInstance = hinst;
wcex.hbrBackground = nullptr; wcex.hbrBackground = nullptr;
wcex.lpszMenuName = nullptr; wcex.lpszMenuName = nullptr;
wcex.hCursor = ::LoadCursorW(nullptr, IDC_ARROW); wcex.hCursor = nullptr;
if (icon) if (icon)
{ {
@ -152,24 +166,6 @@ namespace easy2d
return S_OK; return S_OK;
} }
void Window::Destroy()
{
if (is_fullscreen_)
RestoreResolution(device_name_);
if (device_name_)
{
delete[] device_name_;
device_name_ = nullptr;
}
if (handle_)
{
::DestroyWindow(handle_);
handle_ = nullptr;
}
}
void Window::Prepare() void Window::Prepare()
{ {
::ShowWindow(handle_, SW_SHOWNORMAL); ::ShowWindow(handle_, SW_SHOWNORMAL);

View File

@ -20,15 +20,11 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "Singleton.hpp"
namespace easy2d namespace easy2d
{ {
class E2D_API Window class E2D_API Window
: public Singleton<Window>
{ {
E2D_DECLARE_SINGLETON(Window);
public: public:
// »ñÈ¡±êÌâ // »ñÈ¡±êÌâ
String GetTitle() const; String GetTitle() const;
@ -64,8 +60,6 @@ namespace easy2d
WNDPROC proc WNDPROC proc
); );
void Destroy();
void Prepare(); void Prepare();
HWND GetHandle() const; HWND GetHandle() const;
@ -76,7 +70,7 @@ namespace easy2d
void SetActive(bool actived); void SetActive(bool actived);
protected: public:
Window(); Window();
~Window(); ~Window();

View File

@ -401,19 +401,18 @@ namespace easy2d
return hr; return hr;
} }
void D3D11DeviceResources::SetLogicalSize(Size logical_size) HRESULT D3D11DeviceResources::SetLogicalSize(Size logical_size)
{ {
if (logical_size_ != logical_size) if (logical_size_ != logical_size)
{ {
logical_size_ = logical_size; logical_size_ = logical_size;
ThrowIfFailed( return CreateWindowSizeDependentResources();
CreateWindowSizeDependentResources()
);
} }
return S_OK;
} }
void D3D11DeviceResources::SetDpi(float dpi) HRESULT D3D11DeviceResources::SetDpi(float dpi)
{ {
if (dpi != dpi_) if (dpi != dpi_)
{ {
@ -427,10 +426,9 @@ namespace easy2d
GetD2DDeviceContext()->SetDpi(dpi_, dpi_); GetD2DDeviceContext()->SetDpi(dpi_, dpi_);
ThrowIfFailed( return CreateWindowSizeDependentResources();
CreateWindowSizeDependentResources()
);
} }
return S_OK;
} }
} }

View File

@ -39,11 +39,11 @@ namespace easy2d
HRESULT HandleDeviceLost(); HRESULT HandleDeviceLost();
void SetLogicalSize( HRESULT SetLogicalSize(
Size logical_size Size logical_size
); );
void SetDpi( HRESULT SetDpi(
float dpi float dpi
); );

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/macros.h" #include "../macros.h"
#if defined(E2D_USE_DIRECTX10) #if defined(E2D_USE_DIRECTX10)
# include "D3D10DeviceResources.h" # include "D3D10DeviceResources.h"

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/ComPtr.hpp" #include "../common/ComPtr.hpp"
#include "../core/Color.h" #include "../core/Color.h"
#include "../math/vector.hpp" #include "../math/vector.hpp"
#include "../math/Rect.hpp" #include "../math/Rect.hpp"

View File

@ -25,12 +25,13 @@
#pragma once #pragma once
#include "macros.h"
// //
// core // core
// //
#include "core/macros.h"
#include "core/modules.h" #include "core/modules.h"
#include "core/render.h" #include "core/render.h"
#include "core/window.h" #include "core/window.h"
@ -64,6 +65,7 @@
#include "core/Node.h" #include "core/Node.h"
#include "core/Scene.h" #include "core/Scene.h"
#include "core/Layer.h"
#include "core/Sprite.h" #include "core/Sprite.h"
#include "core/Text.h" #include "core/Text.h"
#include "core/Canvas.h" #include "core/Canvas.h"

View File

@ -20,25 +20,19 @@
#pragma once #pragma once
#if _MSC_VER >= 1900
# define E2D_CONSTEXPR constexpr
#else
# define E2D_CONSTEXPR const
#endif
namespace easy2d namespace easy2d
{ {
namespace math namespace math
{ {
namespace constants namespace constants
{ {
E2D_CONSTEXPR auto PI_F = 3.141592653589793f; const auto PI_F = 3.141592653589793f;
E2D_CONSTEXPR auto PI_F_2 = 1.570796326794896f; const auto PI_F_2 = 1.570796326794896f;
E2D_CONSTEXPR auto PI_F_X_2 = 6.283185307179586f; const auto PI_F_X_2 = 6.283185307179586f;
E2D_CONSTEXPR auto PI_D = 3.14159265358979323846; const auto PI_D = 3.14159265358979323846;
E2D_CONSTEXPR auto PI_D_2 = 1.57079632679489661923; const auto PI_D_2 = 1.57079632679489661923;
E2D_CONSTEXPR auto PI_D_X_2 = 6.28318530717958647692; const auto PI_D_X_2 = 6.28318530717958647692;
} }
} }
} }

View File

@ -19,7 +19,6 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/macros.h"
#include <random> #include <random>
namespace easy2d namespace easy2d
@ -35,64 +34,93 @@ namespace easy2d
// double d = math::Rand(1.2, 1.5); // double d = math::Rand(1.2, 1.5);
// //
E2D_API std::default_random_engine& GetRandomEngine(); int Rand(int min, int max);
unsigned int Rand(unsigned int min, unsigned int max);
long Rand(long min, long max);
unsigned long Rand(unsigned long min, unsigned long max);
char Rand(char min, char max);
unsigned char Rand(unsigned char min, unsigned char max);
float Rand(float min, float max);
double Rand(double min, double max);
//
// Details of math::Rand
//
namespace __rand_detail
{
inline std::default_random_engine& GetRandomEngine()
{
static std::random_device device;
static std::default_random_engine engine(device());
return engine;
}
template<typename T> template<typename T>
static T RandomInt(T min, T max) inline T RandomInt(T min, T max)
{ {
std::uniform_int_distribution<T> dist(min, max); std::uniform_int_distribution<T> dist(min, max);
return dist(GetRandomEngine()); return dist(GetRandomEngine());
} }
template<typename T> template<typename T>
static T RandomReal(T min, T max) inline T RandomReal(T min, T max)
{ {
std::uniform_real_distribution<T> dist(min, max); std::uniform_real_distribution<T> dist(min, max);
return dist(GetRandomEngine()); return dist(GetRandomEngine());
} }
}
inline int Rand(int min, int max) inline int Rand(int min, int max)
{ {
return RandomInt(min, max); return __rand_detail::RandomInt(min, max);
} }
inline unsigned int Rand(unsigned int min, unsigned int max) inline unsigned int Rand(unsigned int min, unsigned int max)
{ {
return RandomInt(min, max); return __rand_detail::RandomInt(min, max);
} }
inline long Rand(long min, long max) inline long Rand(long min, long max)
{ {
return RandomInt(min, max); return __rand_detail::RandomInt(min, max);
} }
inline unsigned long Rand(unsigned long min, unsigned long max) inline unsigned long Rand(unsigned long min, unsigned long max)
{ {
return RandomInt(min, max); return __rand_detail::RandomInt(min, max);
} }
inline char Rand(char min, char max) inline char Rand(char min, char max)
{ {
return static_cast<char>( return static_cast<char>(
RandomInt(static_cast<int>(min), static_cast<int>(max)) __rand_detail::RandomInt(static_cast<int>(min), static_cast<int>(max))
); );
} }
inline unsigned char Rand(unsigned char min, unsigned char max) inline unsigned char Rand(unsigned char min, unsigned char max)
{ {
return static_cast<unsigned char>( return static_cast<unsigned char>(
RandomInt(static_cast<unsigned int>(min), static_cast<unsigned int>(max)) __rand_detail::RandomInt(static_cast<unsigned int>(min), static_cast<unsigned int>(max))
); );
} }
inline float Rand(float min, float max) inline float Rand(float min, float max)
{ {
return RandomReal(min, max); return __rand_detail::RandomReal(min, max);
} }
inline double Rand(double min, double max) inline double Rand(double min, double max)
{ {
return RandomReal(min, max); return __rand_detail::RandomReal(min, max);
} }
} }
} }

View File

@ -19,10 +19,9 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "Button.h" #include "Button.h"
#include "../core/Scene.h"
namespace easy2d namespace easy2d
{
namespace ui
{ {
Button::Button() Button::Button()
: enabled_(true) : enabled_(true)
@ -107,6 +106,7 @@ namespace easy2d
if (evt.type == Event::MouseHover) if (evt.type == Event::MouseHover)
{ {
SetStatus(Status::Hover); SetStatus(Status::Hover);
GetScene()->SetMouseCursor(MouseCursor::Hand);
if (mouse_over_callback_) if (mouse_over_callback_)
mouse_over_callback_(); mouse_over_callback_();
@ -114,6 +114,7 @@ namespace easy2d
else if (evt.type == Event::MouseOut) else if (evt.type == Event::MouseOut)
{ {
SetStatus(Status::Normal); SetStatus(Status::Normal);
GetScene()->SetMouseCursor(MouseCursor::Arrow);
if (mouse_out_callback_) if (mouse_out_callback_)
mouse_out_callback_(); mouse_out_callback_();
@ -136,4 +137,3 @@ namespace easy2d
} }
} }
}

View File

@ -23,8 +23,6 @@
#include <functional> #include <functional>
namespace easy2d namespace easy2d
{
namespace ui
{ {
class E2D_API Button class E2D_API Button
: public Sprite : public Sprite
@ -94,4 +92,3 @@ namespace easy2d
Callback mouse_out_callback_; Callback mouse_out_callback_;
}; };
} }
}

View File

@ -21,8 +21,6 @@
#include "Menu.h" #include "Menu.h"
namespace easy2d namespace easy2d
{
namespace ui
{ {
Menu::Menu() Menu::Menu()
: enabled_(true) : enabled_(true)
@ -98,5 +96,5 @@ namespace easy2d
{ {
return buttons_; return buttons_;
} }
}
} }

View File

@ -22,8 +22,6 @@
#include "Button.h" #include "Button.h"
namespace easy2d namespace easy2d
{
namespace ui
{ {
// 꽉데 // 꽉데
class E2D_API Menu class E2D_API Menu
@ -64,5 +62,5 @@ namespace easy2d
bool enabled_; bool enabled_;
Array<ButtonPtr> buttons_; Array<ButtonPtr> buttons_;
}; };
}
} }

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/helper.hpp" #include "../core/helper.h"
namespace easy2d namespace easy2d
{ {

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/helper.hpp" #include "../core/helper.h"
#include "../core/Resource.h" #include "../core/Resource.h"
namespace easy2d namespace easy2d

View File

@ -62,15 +62,10 @@ namespace easy2d
{ {
// 设置数据的保存路径 // 设置数据的保存路径
String local_app_data_path = Path::GetLocalAppDataPath(); String local_app_data_path = Path::GetLocalAppDataPath();
String title = Window::Instance().GetTitle();
String folder_name = std::to_wstring(std::hash<String>{}(title));
if (!local_app_data_path.empty()) if (!local_app_data_path.empty())
{ {
data_path.append(local_app_data_path) data_path.append(local_app_data_path).append(L"\\Easy2DGameData\\");
.append(L"\\Easy2DGameData\\")
.append(folder_name)
.append(L"\\");
File file(data_path); File file(data_path);
if (!file.Exists() && !CreateFolder(data_path)) if (!file.Exists() && !CreateFolder(data_path))
@ -90,15 +85,10 @@ namespace easy2d
{ {
// 设置临时文件保存路径 // 设置临时文件保存路径
wchar_t path[_MAX_PATH]; wchar_t path[_MAX_PATH];
String title = Window::Instance().GetTitle();
String folder_name = std::to_wstring(std::hash<String>{}(title));
if (0 != ::GetTempPath(_MAX_PATH, path)) if (0 != ::GetTempPath(_MAX_PATH, path))
{ {
temp_path.append(path) temp_path.append(path).append(L"\\Easy2DGameTemp\\");
.append(L"\\Easy2DGameTemp\\")
.append(folder_name)
.append(L"\\");
File file(temp_path); File file(temp_path);
if (!file.Exists() && !CreateFolder(temp_path)) if (!file.Exists() && !CreateFolder(temp_path))

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/helper.hpp" #include "../core/helper.h"
namespace easy2d namespace easy2d
{ {

View File

@ -19,7 +19,6 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "string.h" #include "string.h"
#include "../core/macros.h"
#include "../core/logs.h" #include "../core/logs.h"
namespace easy2d namespace easy2d

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../core/macros.h" #include "../macros.h"
#include <string> #include <string>
namespace easy2d namespace easy2d