aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/native/cursor.hpp37
-rw-r--r--include/cru/platform/native/ui_applicaition.hpp4
-rw-r--r--include/cru/win/native/cursor.hpp51
-rw-r--r--include/cru/win/native/ui_application.hpp9
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/win/native/CMakeLists.txt2
-rw-r--r--src/win/native/cursor.cpp51
-rw-r--r--src/win/native/ui_application.cpp6
8 files changed, 159 insertions, 2 deletions
diff --git a/include/cru/platform/native/cursor.hpp b/include/cru/platform/native/cursor.hpp
new file mode 100644
index 00000000..b0ff4494
--- /dev/null
+++ b/include/cru/platform/native/cursor.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "../native_resource.hpp"
+
+#include <memory>
+
+namespace cru::platform::native {
+class Cursor : public NativeResource {
+ public:
+ Cursor() = default;
+
+ CRU_DELETE_COPY(Cursor)
+ CRU_DELETE_MOVE(Cursor)
+
+ ~Cursor() override = default;
+};
+
+enum class SystemCursor {
+ Arrow,
+ Hand,
+};
+
+class CursorManager : public NativeResource {
+ public:
+ CursorManager() = default;
+
+ CRU_DELETE_COPY(CursorManager)
+ CRU_DELETE_MOVE(CursorManager)
+
+ ~CursorManager() override = default;
+
+ public:
+ virtual std::shared_ptr<Cursor> GetSystemCursor(SystemCursor type) = 0;
+
+ //TODO: Add method to create cursor.
+};
+} // namespace cru::platform::native
diff --git a/include/cru/platform/native/ui_applicaition.hpp b/include/cru/platform/native/ui_applicaition.hpp
index aa8d98da..923fbaf7 100644
--- a/include/cru/platform/native/ui_applicaition.hpp
+++ b/include/cru/platform/native/ui_applicaition.hpp
@@ -1,6 +1,8 @@
#pragma once
#include "../native_resource.hpp"
+#include "cursor.hpp"
+
#include <chrono>
#include <functional>
#include <vector>
@@ -50,5 +52,7 @@ class UiApplication : public NativeResource {
virtual std::vector<NativeWindow*> GetAllWindow() = 0;
virtual NativeWindow* CreateWindow(NativeWindow* parent) = 0;
+
+ virtual CursorManager* GetCursorManager() = 0;
};
} // namespace cru::platform::native
diff --git a/include/cru/win/native/cursor.hpp b/include/cru/win/native/cursor.hpp
new file mode 100644
index 00000000..3ef480ea
--- /dev/null
+++ b/include/cru/win/native/cursor.hpp
@@ -0,0 +1,51 @@
+#pragma once
+#include <memory>
+#include "../win_pre_config.hpp"
+
+#include "cru/common/base.hpp"
+#include "cru/platform/native/cursor.hpp"
+#include "cru/win/native/platform_id.hpp"
+
+namespace cru::platform::native::win {
+class WinCursor : public Cursor {
+ public:
+ WinCursor(HCURSOR handle, bool auto_delete);
+
+ CRU_DELETE_COPY(WinCursor)
+ CRU_DELETE_MOVE(WinCursor)
+
+ ~WinCursor() override;
+
+ CRU_PLATFORMID_IMPLEMENT_WIN
+
+ public:
+ HCURSOR GetHandle() const { return handle_; }
+
+ private:
+ HCURSOR handle_;
+ bool auto_delete_;
+};
+
+class WinCursorManager : public CursorManager {
+ public:
+ WinCursorManager();
+
+ CRU_DELETE_COPY(WinCursorManager)
+ CRU_DELETE_MOVE(WinCursorManager)
+
+ ~WinCursorManager() override = default;
+
+ CRU_PLATFORMID_IMPLEMENT_WIN
+
+ public:
+ std::shared_ptr<WinCursor> GetSystemWinCursor(SystemCursor type);
+
+ std::shared_ptr<Cursor> GetSystemCursor(SystemCursor type) override {
+ return std::static_pointer_cast<Cursor>(GetSystemWinCursor(type));
+ }
+
+ private:
+ std::shared_ptr<WinCursor> sys_arrow_;
+ std::shared_ptr<WinCursor> sys_hand_;
+};
+} // namespace cru::platform::native::win
diff --git a/include/cru/win/native/ui_application.hpp b/include/cru/win/native/ui_application.hpp
index 08a9c3ed..d7da4409 100644
--- a/include/cru/win/native/ui_application.hpp
+++ b/include/cru/win/native/ui_application.hpp
@@ -1,10 +1,11 @@
#pragma once
#include "../win_pre_config.hpp"
-#include "platform_id.hpp"
-
#include "cru/platform/native/ui_applicaition.hpp"
+#include "platform_id.hpp"
+#include "cursor.hpp"
+
#include <memory>
namespace cru::platform::native::win {
@@ -46,6 +47,8 @@ class WinUiApplication : public UiApplication {
std::vector<NativeWindow*> GetAllWindow() override;
NativeWindow* CreateWindow(NativeWindow* parent) override;
+ WinCursorManager* GetCursorManager() override;
+
bool IsAutoDelete() const { return auto_delete_; }
void SetAutoDelete(bool value) { auto_delete_ = value; }
@@ -64,6 +67,8 @@ class WinUiApplication : public UiApplication {
std::shared_ptr<TimerManager> timer_manager_;
std::shared_ptr<WindowManager> window_manager_;
+ std::unique_ptr<WinCursorManager> cursor_manager_;
+
std::vector<std::function<void()>> quit_handlers_;
};
} // namespace cru::platform::native::win
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0507ee2b..ece4ca7e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -39,6 +39,7 @@ set(CRU_PLATFORM_NATIVE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/native)
add_library(cru_platform_native INTERFACE)
target_sources(cru_platform_native INTERFACE
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/basic_types.hpp
+ ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/cursor.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_event.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_window.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/ui_application.hpp
diff --git a/src/win/native/CMakeLists.txt b/src/win/native/CMakeLists.txt
index 757eae57..02f3afce 100644
--- a/src/win/native/CMakeLists.txt
+++ b/src/win/native/CMakeLists.txt
@@ -7,6 +7,7 @@ add_library(cru_win_native STATIC
window_d2d_painter.hpp
window_manager.hpp
+ cursor.cpp
god_window.cpp
native_window.cpp
timer.cpp
@@ -17,6 +18,7 @@ add_library(cru_win_native STATIC
window_render_target.cpp
)
target_sources(cru_win_native PUBLIC
+ ${CRU_WIN_NATIVE_INCLUDE_DIR}/cursor.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/exception.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/god_window.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/native_window.hpp
diff --git a/src/win/native/cursor.cpp b/src/win/native/cursor.cpp
new file mode 100644
index 00000000..987d2d54
--- /dev/null
+++ b/src/win/native/cursor.cpp
@@ -0,0 +1,51 @@
+#include "cru/win/native/cursor.hpp"
+
+#include "cru/common/format.hpp"
+#include "cru/platform/debug.hpp"
+#include "cru/win/native/exception.hpp"
+
+#include <stdexcept>
+
+namespace cru::platform::native::win {
+WinCursor::WinCursor(HCURSOR handle, bool auto_delete) {
+ handle_ = handle;
+ auto_delete_ = auto_delete;
+}
+
+WinCursor::~WinCursor() {
+ if (auto_delete_) {
+ if (!::DestroyCursor(handle_)) {
+ DebugMessage(
+ util::Format(L"Failed to destroy a cursor. Last error code: {}",
+ ::GetLastError())); // This is not a fetal error but
+ // might still need notice.
+ }
+ }
+}
+
+namespace {
+WinCursor* LoadWinCursor(const wchar_t* name) {
+ const auto handle = ::LoadCursorW(NULL, name);
+ if (handle == NULL) {
+ throw Win32Error(::GetLastError(), "Failed to get system cursor.");
+ }
+ return new WinCursor(handle, false);
+}
+} // namespace
+
+WinCursorManager::WinCursorManager()
+ : sys_arrow_(LoadWinCursor(IDC_ARROW)),
+ sys_hand_(LoadWinCursor(IDC_HAND)) {}
+
+std::shared_ptr<WinCursor> WinCursorManager::GetSystemWinCursor(
+ SystemCursor type) {
+ switch (type) {
+ case SystemCursor::Arrow:
+ return sys_arrow_;
+ case SystemCursor::Hand:
+ return sys_hand_;
+ default:
+ throw std::runtime_error("Unknown system cursor value.");
+ }
+}
+} // namespace cru::platform::native::win
diff --git a/src/win/native/ui_application.cpp b/src/win/native/ui_application.cpp
index 360f6e41..fdc0aace 100644
--- a/src/win/native/ui_application.cpp
+++ b/src/win/native/ui_application.cpp
@@ -47,6 +47,8 @@ WinUiApplication::WinUiApplication(HINSTANCE h_instance)
god_window_ = std::make_shared<GodWindow>(this);
timer_manager_ = std::make_shared<TimerManager>(god_window_.get());
window_manager_ = std::make_shared<WindowManager>(this);
+
+ cursor_manager_.reset(new WinCursorManager());
}
WinUiApplication::~WinUiApplication() { instance = nullptr; }
@@ -118,4 +120,8 @@ NativeWindow* WinUiApplication::CreateWindow(NativeWindow* parent) {
return new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(),
WS_OVERLAPPEDWINDOW, p);
}
+
+WinCursorManager* WinUiApplication::GetCursorManager() {
+ return cursor_manager_.get();
+}
} // namespace cru::platform::native::win