aboutsummaryrefslogtreecommitdiff
path: root/include/cru/platform
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru/platform')
-rw-r--r--include/cru/platform/basic_types.hpp11
-rw-r--r--include/cru/platform/dpi_util.hpp32
-rw-r--r--include/cru/platform/native_window.hpp19
-rw-r--r--include/cru/platform/ui_applicaition.hpp10
-rw-r--r--include/cru/platform/win/god_window.hpp5
-rw-r--r--include/cru/platform/win/win_application.hpp10
-rw-r--r--include/cru/platform/win/win_native_window.hpp123
-rw-r--r--include/cru/platform/win/window_native_message_event_args.hpp45
8 files changed, 246 insertions, 9 deletions
diff --git a/include/cru/platform/basic_types.hpp b/include/cru/platform/basic_types.hpp
new file mode 100644
index 00000000..67637b83
--- /dev/null
+++ b/include/cru/platform/basic_types.hpp
@@ -0,0 +1,11 @@
+#include "cru/common/pre_config.hpp"
+
+namespace cru::platform {
+struct Dpi {
+ float x;
+ float y;
+};
+
+enum class MouseButton { Left, Right, Middle };
+
+} // namespace cru::platform
diff --git a/include/cru/platform/dpi_util.hpp b/include/cru/platform/dpi_util.hpp
new file mode 100644
index 00000000..3c0ae6ca
--- /dev/null
+++ b/include/cru/platform/dpi_util.hpp
@@ -0,0 +1,32 @@
+#pragma once
+#include "ui_applicaition.hpp"
+
+namespace cru::platform {
+inline Dpi GetDpi() {
+ return UiApplication::GetInstance()->GetDpi();
+}
+
+inline int DipToPixelInternal(const float dip, const float dpi) {
+ return static_cast<int>(dip * dpi / 96.0f);
+}
+
+inline int DipToPixelX(const float dip_x) {
+ return DipToPixelInternal(dip_x, GetDpi().x);
+}
+
+inline int DipToPixelY(const float dip_y) {
+ return DipToPixelInternal(dip_y, GetDpi().y);
+}
+
+inline float DipToPixelInternal(const int pixel, const float dpi) {
+ return static_cast<float>(pixel) * 96.0f / dpi;
+}
+
+inline float PixelToDipX(const int pixel_x) {
+ return DipToPixelInternal(pixel_x, GetDpi().x);
+}
+
+inline float PixelToDipY(const int pixel_y) {
+ return DipToPixelInternal(pixel_y, GetDpi().y);
+}
+} // namespace cru::platform
diff --git a/include/cru/platform/native_window.hpp b/include/cru/platform/native_window.hpp
index 1ed9a25e..5e8897ab 100644
--- a/include/cru/platform/native_window.hpp
+++ b/include/cru/platform/native_window.hpp
@@ -1,18 +1,24 @@
#pragma once
#include "cru/common/base.hpp"
+
+#include "basic_types.hpp"
+#include "cru/common/event.hpp"
#include "cru/common/ui_base.hpp"
namespace cru::platform {
struct Painter;
struct NativeWindow : public virtual Interface {
+ // Return if the window is still valid, that is, hasn't been closed or
+ // destroyed.
virtual bool IsValid() = 0;
+ virtual void SetDeleteThisOnDestroy(bool value) = 0;
virtual void Close() = 0;
virtual NativeWindow* GetParent() = 0;
- virtual bool IsVisible() const = 0;
+ virtual bool IsVisible() = 0;
virtual void SetVisible(bool is_visible) = 0;
virtual ui::Size GetClientSize() = 0;
@@ -27,5 +33,16 @@ struct NativeWindow : public virtual Interface {
virtual void SetWindowRect(const ui::Rect& rect) = 0;
virtual Painter* GetPainter() = 0;
+
+ virtual Event<>* DestroyEvent() = 0;
+ virtual Event<ui::Size>* ResizeEvent() = 0;
+ virtual Event<>* PaintEvent() = 0;
+ virtual Event<bool>* FocusEvent() = 0;
+ virtual Event<bool>* MouseEnterLeaveEvent() = 0;
+ virtual Event<ui::Point>* MouseMoveEvent() = 0;
+ virtual Event<MouseButton, ui::Point>* MouseDownEvent() = 0;
+ virtual Event<MouseButton, ui::Point>* MouseUpEvent() = 0;
+ virtual Event<int>* KeyDownEvent() = 0;
+ virtual Event<int>* KeyUpEvent() = 0;
};
} // namespace cru::platform
diff --git a/include/cru/platform/ui_applicaition.hpp b/include/cru/platform/ui_applicaition.hpp
index 1345d38c..e149166b 100644
--- a/include/cru/platform/ui_applicaition.hpp
+++ b/include/cru/platform/ui_applicaition.hpp
@@ -1,8 +1,11 @@
#pragma once
#include "cru/common/base.hpp"
+#include "basic_types.hpp"
+
#include <chrono>
#include <functional>
+#include <vector>
namespace cru::platform {
struct NativeWindow;
@@ -16,13 +19,16 @@ struct UiApplication : public virtual Interface {
virtual void InvokeLater(const std::function<void()>& action) = 0;
virtual unsigned long SetTimeout(std::chrono::milliseconds milliseconds,
- const std::function<void()>& action) = 0;
+ const std::function<void()>& action) = 0;
virtual unsigned long SetInterval(std::chrono::milliseconds milliseconds,
- const std::function<void()>& action) = 0;
+ const std::function<void()>& action) = 0;
virtual void CancelTimer(unsigned long id) = 0;
+ virtual std::vector<NativeWindow*> GetAllWindow() = 0;
virtual NativeWindow* CreateWindow() = 0;
+ virtual Dpi GetDpi() = 0;
+
virtual GraphFactory* GetGraphFactory() = 0;
};
} // namespace cru::platform
diff --git a/include/cru/platform/win/god_window.hpp b/include/cru/platform/win/god_window.hpp
index 534dfedb..95a253e9 100644
--- a/include/cru/platform/win/god_window.hpp
+++ b/include/cru/platform/win/god_window.hpp
@@ -2,7 +2,6 @@
#include "win_pre_config.hpp"
#include <memory>
-#include <optional>
#include "cru/common/base.hpp"
@@ -21,8 +20,8 @@ class GodWindow : public Object {
HWND GetHandle() const { return hwnd_; }
- std::optional<LRESULT> HandleGodWindowMessage(HWND hwnd, int msg,
- WPARAM w_param, LPARAM l_param);
+ bool HandleGodWindowMessage(HWND hwnd, UINT msg, WPARAM w_param,
+ LPARAM l_param, LRESULT* result);
private:
WinApplication* application_;
diff --git a/include/cru/platform/win/win_application.hpp b/include/cru/platform/win/win_application.hpp
index 363ae170..fcc0a7c9 100644
--- a/include/cru/platform/win/win_application.hpp
+++ b/include/cru/platform/win/win_application.hpp
@@ -9,6 +9,7 @@
namespace cru::platform::win {
class GodWindow;
class TimerManager;
+class WindowManager;
class WinApplication : public Object, public virtual UiApplication {
public:
@@ -33,21 +34,24 @@ class WinApplication : public Object, public virtual UiApplication {
void InvokeLater(const std::function<void()>& action) override;
unsigned long SetTimeout(std::chrono::milliseconds milliseconds,
- const std::function<void()>& action) override;
+ const std::function<void()>& action) override;
unsigned long SetInterval(std::chrono::milliseconds milliseconds,
- const std::function<void()>& action) override;
+ const std::function<void()>& action) override;
void CancelTimer(unsigned long id) override;
HINSTANCE GetInstanceHandle() const { return h_instance_; }
GodWindow* GetGodWindow() const { return god_window_.get(); }
- TimerManager* GetTimerManager() const;
+ TimerManager* GetTimerManager() const { return timer_manager_.get(); }
+
+ WindowManager* GetWindowManager() const { return window_manager_.get(); }
private:
HINSTANCE h_instance_;
std::shared_ptr<GodWindow> god_window_;
std::shared_ptr<TimerManager> timer_manager_;
+ std::shared_ptr<WindowManager> window_manager_;
};
} // namespace cru::platform::win
diff --git a/include/cru/platform/win/win_native_window.hpp b/include/cru/platform/win/win_native_window.hpp
new file mode 100644
index 00000000..9deac767
--- /dev/null
+++ b/include/cru/platform/win/win_native_window.hpp
@@ -0,0 +1,123 @@
+#pragma once
+#include "win_pre_config.hpp"
+
+#include "../native_window.hpp"
+#include "window_native_message_event_args.hpp"
+
+#include <memory>
+
+namespace cru::platform::win {
+class WinApplication;
+class WindowClass;
+class WindowManager;
+
+class WinNativeWindow : public Object, public virtual NativeWindow {
+ public:
+ WinNativeWindow(WinApplication* application,
+ std::shared_ptr<WindowClass> window_class, DWORD window_style,
+ WinNativeWindow* parent);
+ WinNativeWindow(const WinNativeWindow& other) = delete;
+ WinNativeWindow(WinNativeWindow&& other) = delete;
+ WinNativeWindow& operator=(const WinNativeWindow& other) = delete;
+ WinNativeWindow& operator=(WinNativeWindow&& other) = delete;
+ ~WinNativeWindow() override;
+
+ bool IsValid() override;
+ void SetDeleteThisOnDestroy(bool value) override;
+
+ void Close() override;
+
+ NativeWindow* GetParent() override { return parent_window_; }
+
+ bool IsVisible() override;
+ void SetVisible(bool is_visible) override;
+
+ ui::Size GetClientSize() override;
+ void SetClientSize(const ui::Size& size) override;
+
+ // Get the rect of the window containing frame.
+ // The lefttop of the rect is relative to screen lefttop.
+ ui::Rect GetWindowRect() override;
+
+ // Set the rect of the window containing frame.
+ // The lefttop of the rect is relative to screen lefttop.
+ void SetWindowRect(const ui::Rect& rect) override;
+
+ Event<>* DestroyEvent() override { return &destroy_event_; }
+ Event<ui::Size>* ResizeEvent() override { return &resize_event_; }
+ Event<>* PaintEvent() override { return &paint_event_; }
+ Event<bool>* FocusEvent() override { return &focus_event_; }
+ Event<bool>* MouseEnterLeaveEvent() override {
+ return &mouse_enter_leave_event_;
+ }
+ Event<ui::Point>* MouseMoveEvent() override { return &mouse_move_event_; }
+ Event<MouseButton, ui::Point>* MouseDownEvent() override {
+ return &mouse_down_event_;
+ }
+ Event<MouseButton, ui::Point>* MouseUpEvent() override {
+ return &mouse_up_event_;
+ }
+ Event<int>* KeyDownEvent() override { return &key_down_event_; }
+ Event<int>* KeyUpEvent() override { return &key_up_event_; }
+
+ Event<WindowNativeMessageEventArgs&>* NativeMessageEvent() {
+ return &native_message_event_;
+ }
+
+ // Get the handle of the window. Return null if window is invalid.
+ HWND GetWindowHandle() const { return hwnd_; }
+
+ bool HandleNativeWindowMessage(HWND hwnd, UINT msg, WPARAM w_param,
+ LPARAM l_param, LRESULT* result);
+
+ private:
+ // Get the client rect in pixel.
+ RECT GetClientRectPixel();
+
+ //*************** region: native messages ***************
+
+ void OnDestroyInternal();
+ void OnPaintInternal();
+ void OnResizeInternal(int new_width, int new_height);
+
+ void OnSetFocusInternal();
+ void OnKillFocusInternal();
+
+ void OnMouseMoveInternal(POINT point);
+ void OnMouseLeaveInternal();
+ void OnMouseDownInternal(MouseButton button, POINT point);
+ void OnMouseUpInternal(MouseButton button, POINT point);
+
+ void OnMouseWheelInternal(short delta, POINT point);
+ void OnKeyDownInternal(int virtual_code);
+ void OnKeyUpInternal(int virtual_code);
+ void OnCharInternal(wchar_t c);
+
+ void OnActivatedInternal();
+ void OnDeactivatedInternal();
+
+ private:
+ WinApplication* application_;
+
+ bool delete_this_on_destroy_ = true;
+
+ HWND hwnd_;
+ WinNativeWindow* parent_window_;
+
+ bool has_focus_ = false;
+ bool is_mouse_in_ = false;
+
+ Event<> destroy_event_;
+ Event<ui::Size> resize_event_;
+ Event<> paint_event_;
+ Event<bool> focus_event_;
+ Event<bool> mouse_enter_leave_event_;
+ Event<ui::Point> mouse_move_event_;
+ Event<MouseButton, ui::Point> mouse_down_event_;
+ Event<MouseButton, ui::Point> mouse_up_event_;
+ Event<int> key_down_event_;
+ Event<int> key_up_event_;
+
+ Event<WindowNativeMessageEventArgs&> native_message_event_;
+};
+} // namespace cru::platform::win
diff --git a/include/cru/platform/win/window_native_message_event_args.hpp b/include/cru/platform/win/window_native_message_event_args.hpp
new file mode 100644
index 00000000..b3419c24
--- /dev/null
+++ b/include/cru/platform/win/window_native_message_event_args.hpp
@@ -0,0 +1,45 @@
+#pragma once
+#include "win_pre_config.hpp"
+
+#include "cru/common/base.hpp"
+
+namespace cru::platform::win {
+struct WindowNativeMessage {
+ HWND hwnd;
+ UINT msg;
+ WPARAM w_param;
+ LPARAM l_param;
+};
+
+class WindowNativeMessageEventArgs : public Object {
+ public:
+ WindowNativeMessageEventArgs(const WindowNativeMessage& message)
+ : message_(message) {}
+ WindowNativeMessageEventArgs(const WindowNativeMessageEventArgs& other) =
+ default;
+ WindowNativeMessageEventArgs(WindowNativeMessageEventArgs&& other) = default;
+ WindowNativeMessageEventArgs& operator=(
+ const WindowNativeMessageEventArgs& other) = default;
+ WindowNativeMessageEventArgs& operator=(
+ WindowNativeMessageEventArgs&& other) = default;
+ ~WindowNativeMessageEventArgs() override = default;
+
+ WindowNativeMessage GetWindowMessage() const { return message_; }
+
+ LRESULT GetResult() const { return result_; }
+ void SetResult(LRESULT result) { result_ = result; }
+
+ bool IsHandled() const { return handled_; }
+ void SetHandled(bool handled) { handled_ = handled; }
+
+ void HandledAndSetResult(LRESULT result) {
+ handled_ = true;
+ result_ = result;
+ }
+
+ private:
+ WindowNativeMessage message_;
+ LRESULT result_;
+ bool handled_ = false;
+};
+} // namespace cru::platform::win