diff options
author | crupest <crupest@outlook.com> | 2019-03-31 19:48:20 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2019-03-31 19:48:20 +0800 |
commit | 8ca0873597eb05a2f120d3ea107660abcff4533c (patch) | |
tree | f2089ad1a420ae0f21ba0d84b5031de3b5e489ca /include | |
parent | 9cc0f5d9192288116443254d790aa9ab36572b8d (diff) | |
download | cru-8ca0873597eb05a2f120d3ea107660abcff4533c.tar.gz cru-8ca0873597eb05a2f120d3ea107660abcff4533c.tar.bz2 cru-8ca0873597eb05a2f120d3ea107660abcff4533c.zip |
...
Diffstat (limited to 'include')
-rw-r--r-- | include/cru/common/event.hpp | 46 | ||||
-rw-r--r-- | include/cru/platform/basic_types.hpp | 11 | ||||
-rw-r--r-- | include/cru/platform/dpi_util.hpp | 32 | ||||
-rw-r--r-- | include/cru/platform/native_window.hpp | 19 | ||||
-rw-r--r-- | include/cru/platform/ui_applicaition.hpp | 10 | ||||
-rw-r--r-- | include/cru/platform/win/god_window.hpp | 5 | ||||
-rw-r--r-- | include/cru/platform/win/win_application.hpp | 10 | ||||
-rw-r--r-- | include/cru/platform/win/win_native_window.hpp | 123 | ||||
-rw-r--r-- | include/cru/platform/win/window_native_message_event_args.hpp | 45 |
9 files changed, 292 insertions, 9 deletions
diff --git a/include/cru/common/event.hpp b/include/cru/common/event.hpp new file mode 100644 index 00000000..ce014fb8 --- /dev/null +++ b/include/cru/common/event.hpp @@ -0,0 +1,46 @@ +#pragma once +#include "base.hpp" + +#include <functional> +#include <map> +#include <utility> + +namespace cru { +// A non-copyable non-movable Event class. +// It stores a list of event handlers. +template <typename... TArgs> +class Event { + public: + using EventHandler = std::function<void(TArgs...)>; + using EventHandlerToken = long; + + Event() = default; + Event(const Event&) = delete; + Event& operator=(const Event&) = delete; + Event(Event&&) = delete; + Event& operator=(Event&&) = delete; + ~Event() = default; + + EventHandlerToken AddHandler(const EventHandler& handler) { + const auto token = current_token_++; + handlers_.emplace(token, handler); + return token; + } + + void RemoveHandler(const EventHandlerToken token) { + auto find_result = handlers_.find(token); + if (find_result != handlers_.cend()) handlers_.erase(find_result); + } + + template <typename... Args> + void Raise(Args&&... args) { + for (const auto& handler : handlers_) + (handler.second)(std::forward<Args>(args)...); + } + + private: + std::map<EventHandlerToken, EventHandler> handlers_; + + EventHandlerToken current_token_ = 0; +}; +} // namespace cru 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 |