From b53527fbe50a953ad0e3225cc812eb76b8a1f82d Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 27 Jun 2019 17:02:58 +0800 Subject: ... --- include/cru/platform/graph/graph_factory.hpp | 3 + include/cru/platform/graph/util/painter_util.hpp | 4 +- include/cru/platform/matrix.hpp | 4 +- include/cru/platform/native/native_event.hpp | 5 +- include/cru/platform/native/native_window.hpp | 37 ++- include/cru/platform/native/ui_applicaition.hpp | 32 +- include/cru/platform/native_resource.hpp | 5 +- include/cru/ui/base.hpp | 21 ++ include/cru/ui/control.hpp | 1 + include/cru/ui/event/ui_event.hpp | 17 +- include/cru/ui/render/border_render_object.hpp | 22 +- .../cru/ui/render/flex_layout_render_object.hpp | 2 +- include/cru/ui/render/render_object.hpp | 6 +- include/cru/ui/render/text_render_object.hpp | 34 +-- include/cru/ui/render/window_render_object.hpp | 2 +- include/cru/ui/ui_manager.hpp | 17 +- include/cru/ui/window.hpp | 6 +- include/cru/win/graph/direct/exception.hpp | 35 +-- include/cru/win/graph/direct/graph_factory.hpp | 2 +- include/cru/win/graph/direct/platform_id.hpp | 13 +- include/cru/win/native/exception.hpp | 6 + include/cru/win/native/god_window.hpp | 8 +- include/cru/win/native/native_window.hpp | 138 +++++++++ include/cru/win/native/platform_id.hpp | 19 ++ include/cru/win/native/ui_application.hpp | 69 +++++ include/cru/win/native/win_application.hpp | 66 ---- include/cru/win/native/win_native_window.hpp | 135 -------- include/cru/win/native/window_class.hpp | 2 +- .../native/window_native_message_event_args.hpp | 2 +- include/cru/win/native/window_render_target.hpp | 16 +- src/main.cpp | 11 +- src/ui/CMakeLists.txt | 1 + src/ui/render/border_render_object.cpp | 14 +- src/ui/render/flex_layout_render_object.cpp | 2 +- src/ui/render/text_render_object.cpp | 16 +- src/ui/render/window_render_object.cpp | 4 +- src/ui/ui_manager.cpp | 17 +- src/ui/window.cpp | 8 +- src/win/exception.cpp | 2 +- src/win/graph/direct/CMakeLists.txt | 1 - src/win/graph/direct/exception.cpp | 29 -- src/win/native/CMakeLists.txt | 16 +- src/win/native/dpi_util.hpp | 4 +- src/win/native/god_window.cpp | 12 +- src/win/native/god_window_message.hpp | 2 +- src/win/native/native_window.cpp | 340 +++++++++++++++++++++ src/win/native/timer.cpp | 4 +- src/win/native/timer.hpp | 2 +- src/win/native/ui_application.cpp | 121 ++++++++ src/win/native/win_application.cpp | 117 ------- src/win/native/win_native_window.cpp | 340 --------------------- src/win/native/window_class.cpp | 6 +- src/win/native/window_d2d_painter.cpp | 33 ++ src/win/native/window_d2d_painter.hpp | 21 ++ src/win/native/window_manager.cpp | 15 +- src/win/native/window_manager.hpp | 8 +- src/win/native/window_painter.cpp | 31 -- src/win/native/window_painter.hpp | 21 -- src/win/native/window_render_target.cpp | 12 +- 59 files changed, 988 insertions(+), 951 deletions(-) create mode 100644 include/cru/ui/base.hpp create mode 100644 include/cru/win/native/exception.hpp create mode 100644 include/cru/win/native/native_window.hpp create mode 100644 include/cru/win/native/platform_id.hpp create mode 100644 include/cru/win/native/ui_application.hpp delete mode 100644 include/cru/win/native/win_application.hpp delete mode 100644 include/cru/win/native/win_native_window.hpp delete mode 100644 src/win/graph/direct/exception.cpp create mode 100644 src/win/native/native_window.cpp create mode 100644 src/win/native/ui_application.cpp delete mode 100644 src/win/native/win_application.cpp delete mode 100644 src/win/native/win_native_window.cpp create mode 100644 src/win/native/window_d2d_painter.cpp create mode 100644 src/win/native/window_d2d_painter.hpp delete mode 100644 src/win/native/window_painter.cpp delete mode 100644 src/win/native/window_painter.hpp diff --git a/include/cru/platform/graph/graph_factory.hpp b/include/cru/platform/graph/graph_factory.hpp index 69afc7b3..0b1034cc 100644 --- a/include/cru/platform/graph/graph_factory.hpp +++ b/include/cru/platform/graph/graph_factory.hpp @@ -55,5 +55,8 @@ class GraphFactory : public NativeResource { virtual TextLayout* CreateTextLayout(std::shared_ptr font, std::wstring text) = 0; + + virtual bool IsAutoDelete() const = 0; + virtual void SetAutoDelete(bool value) = 0; }; } // namespace cru::platform::graph diff --git a/include/cru/platform/graph/util/painter_util.hpp b/include/cru/platform/graph/util/painter_util.hpp index 71e125c3..7a655a34 100644 --- a/include/cru/platform/graph/util/painter_util.hpp +++ b/include/cru/platform/graph/util/painter_util.hpp @@ -6,9 +6,9 @@ namespace cru::platform::graph::util { template -inline void WithTransform(IPainter* painter, const Matrix& matrix, +inline void WithTransform(Painter* painter, const Matrix& matrix, const Fn& action) { - static_assert(std::is_invocable_v, + static_assert(std::is_invocable_v, "Action must can be be invoked with painter."); const auto old = painter->GetTransform(); painter->SetTransform(old * matrix); diff --git a/include/cru/platform/matrix.hpp b/include/cru/platform/matrix.hpp index b0165a88..cbb55c78 100644 --- a/include/cru/platform/matrix.hpp +++ b/include/cru/platform/matrix.hpp @@ -37,8 +37,8 @@ struct Matrix { return Product(*this, matrix); } - ui::Point TransformPoint(const ui::Point& point) const { - return ui::Point{point.x * m11 + point.y * m21 + m31, + Point TransformPoint(const Point& point) const { + return Point{point.x * m11 + point.y * m21 + m31, point.x * m12 + point.y * m22 + m32}; } diff --git a/include/cru/platform/native/native_event.hpp b/include/cru/platform/native/native_event.hpp index 21db5f90..54bab00c 100644 --- a/include/cru/platform/native/native_event.hpp +++ b/include/cru/platform/native/native_event.hpp @@ -1,12 +1,11 @@ #pragma once -#include "cru/common/base.hpp" +#include "../graphic_base.hpp" #include "basic_types.hpp" -#include "cru/common/ui_base.hpp" namespace cru::platform::native { struct NativeMouseButtonEventArgs { MouseButton button; - ui::Point point; + Point point; }; } // namespace cru::platform::native diff --git a/include/cru/platform/native/native_window.hpp b/include/cru/platform/native/native_window.hpp index bb97ef21..22a2dce0 100644 --- a/include/cru/platform/native/native_window.hpp +++ b/include/cru/platform/native/native_window.hpp @@ -1,13 +1,13 @@ #pragma once -#include "cru/common/base.hpp" +#include "../native_resource.hpp" +#include "../graphic_base.hpp" #include "basic_types.hpp" #include "cru/common/event.hpp" -#include "cru/common/ui_base.hpp" #include "native_event.hpp" namespace cru::platform::graph { -struct IPainter; +class Painter; } namespace cru::platform::native { @@ -19,7 +19,20 @@ namespace cru::platform::native { // Close or closed by the user, which leads to an invalid instance. You can // check the validity by IsValid. When you call perform native operations on the // invalid instance, there is no effect. -struct INativeWindow : public virtual Interface { +class NativeWindow : public NativeResource { + protected: + NativeWindow() = default; + + public: + NativeWindow(const NativeWindow& other) = delete; + NativeWindow& operator=(const NativeWindow& other) = delete; + + NativeWindow(NativeWindow&& other) = delete; + NativeWindow& operator=(NativeWindow&& other) = delete; + + ~NativeWindow() override = default; + + public: // Return if the window is still valid, that is, hasn't been closed or // destroyed. virtual bool IsValid() = 0; @@ -27,30 +40,30 @@ struct INativeWindow : public virtual Interface { virtual void Close() = 0; - virtual INativeWindow* GetParent() = 0; + virtual NativeWindow* GetParent() = 0; virtual bool IsVisible() = 0; virtual void SetVisible(bool is_visible) = 0; - virtual ui::Size GetClientSize() = 0; - virtual void SetClientSize(const ui::Size& size) = 0; + virtual Size GetClientSize() = 0; + virtual void SetClientSize(const Size& size) = 0; // Get the rect of the window containing frame. // The lefttop of the rect is relative to screen lefttop. - virtual ui::Rect GetWindowRect() = 0; + virtual Rect GetWindowRect() = 0; // Set the rect of the window containing frame. // The lefttop of the rect is relative to screen lefttop. - virtual void SetWindowRect(const ui::Rect& rect) = 0; + virtual void SetWindowRect(const Rect& rect) = 0; - virtual graph::IPainter* BeginPaint() = 0; + virtual graph::Painter* BeginPaint() = 0; virtual IEvent* DestroyEvent() = 0; virtual IEvent* PaintEvent() = 0; - virtual IEvent* ResizeEvent() = 0; + virtual IEvent* ResizeEvent() = 0; virtual IEvent* FocusEvent() = 0; virtual IEvent* MouseEnterLeaveEvent() = 0; - virtual IEvent* MouseMoveEvent() = 0; + virtual IEvent* MouseMoveEvent() = 0; virtual IEvent* MouseDownEvent() = 0; virtual IEvent* MouseUpEvent() = 0; virtual IEvent* KeyDownEvent() = 0; diff --git a/include/cru/platform/native/ui_applicaition.hpp b/include/cru/platform/native/ui_applicaition.hpp index 655b8ea0..aa8d98da 100644 --- a/include/cru/platform/native/ui_applicaition.hpp +++ b/include/cru/platform/native/ui_applicaition.hpp @@ -1,29 +1,41 @@ #pragma once -#include "cru/common/base.hpp" - -#include "cru/common/auto_delete.hpp" +#include "../native_resource.hpp" #include #include #include namespace cru::platform::native { -struct INativeWindow; +class NativeWindow; // The entry point of a ui application. // It will call IGraphFactory::CreateInstance during its creation // and set graph factory to be auto deleted. If you want to keep // the graph factory then you should manually set it to false after // creating the ui application. -struct IUiApplication : virtual Interface, virtual IAutoDelete { +class UiApplication : public NativeResource { + public: // Create a platform-specific instance and save it as the global instance. // Do not create the instance twice. Implements should assert for that. // After creating, get the instance by GetInstance. - static IUiApplication* CreateInstance(); + static UiApplication* CreateInstance(); // Get the global instance. If it is not created, then return nullptr. - static IUiApplication* GetInstance(); + static UiApplication* GetInstance(); + + protected: + UiApplication() = default; + + public: + UiApplication(const UiApplication& other) = delete; + UiApplication& operator=(const UiApplication& other) = delete; + + UiApplication(UiApplication&& other) = delete; + UiApplication& operator=(UiApplication&& other) = delete; + + ~UiApplication() override = default; + public: virtual int Run() = 0; virtual void Quit(int quite_code) = 0; @@ -36,7 +48,7 @@ struct IUiApplication : virtual Interface, virtual IAutoDelete { const std::function& action) = 0; virtual void CancelTimer(unsigned long id) = 0; - virtual std::vector GetAllWindow() = 0; - virtual INativeWindow* CreateWindow(INativeWindow* parent) = 0; + virtual std::vector GetAllWindow() = 0; + virtual NativeWindow* CreateWindow(NativeWindow* parent) = 0; }; -} // namespace cru::platform::ui +} // namespace cru::platform::native diff --git a/include/cru/platform/native_resource.hpp b/include/cru/platform/native_resource.hpp index 787c46a5..ec7f01b6 100644 --- a/include/cru/platform/native_resource.hpp +++ b/include/cru/platform/native_resource.hpp @@ -9,8 +9,9 @@ class NativeResource : public Object { NativeResource() = default; public: - NativeResource(NativeResource&& other) = delete; - NativeResource& operator=(NativeResource&& other) = delete; + NativeResource(const NativeResource& other) = delete; + NativeResource& operator=(const NativeResource& other) = delete; + NativeResource(NativeResource&& other) = delete; NativeResource& operator=(NativeResource&& other) = delete; diff --git a/include/cru/ui/base.hpp b/include/cru/ui/base.hpp new file mode 100644 index 00000000..427615b9 --- /dev/null +++ b/include/cru/ui/base.hpp @@ -0,0 +1,21 @@ +#pragma once +#include "cru/platform/graphic_base.hpp" +#include "cru/platform/matrix.hpp" +#include "cru/platform/native/basic_types.hpp" + +namespace cru::ui { +using cru::platform::Color; +using cru::platform::Ellipse; +using cru::platform::Matrix; +using cru::platform::Point; +using cru::platform::Rect; +using cru::platform::RoundedRect; +using cru::platform::Size; +using cru::platform::TextRange; +using cru::platform::Thickness; +using cru::platform::native::MouseButton; + +namespace colors { +using namespace cru::platform::colors; +} +} // namespace cru::ui \ No newline at end of file diff --git a/include/cru/ui/control.hpp b/include/cru/ui/control.hpp index 652efe89..15eeb6fa 100644 --- a/include/cru/ui/control.hpp +++ b/include/cru/ui/control.hpp @@ -1,5 +1,6 @@ #pragma once #include "cru/common/base.hpp" +#include "base.hpp" #include "cru/platform/native/basic_types.hpp" #include "event/ui_event.hpp" diff --git a/include/cru/ui/event/ui_event.hpp b/include/cru/ui/event/ui_event.hpp index 2704cc4f..62045808 100644 --- a/include/cru/ui/event/ui_event.hpp +++ b/include/cru/ui/event/ui_event.hpp @@ -1,14 +1,13 @@ #pragma once #include "cru/common/base.hpp" +#include "../base.hpp" #include "cru/common/event.hpp" -#include "cru/common/ui_base.hpp" -#include "cru/platform/native/basic_types.hpp" #include namespace cru::platform::graph { -struct IPainter; +class Painter; } namespace cru::ui { @@ -79,7 +78,7 @@ class MouseButtonEventArgs : public MouseEventArgs { public: MouseButtonEventArgs(Object* sender, Object* original_sender, const Point& point, - const platform::native::MouseButton button) + const MouseButton button) : MouseEventArgs(sender, original_sender, point), button_(button) {} MouseButtonEventArgs(const MouseButtonEventArgs& other) = default; MouseButtonEventArgs(MouseButtonEventArgs&& other) = default; @@ -87,10 +86,10 @@ class MouseButtonEventArgs : public MouseEventArgs { MouseButtonEventArgs& operator=(MouseButtonEventArgs&& other) = default; ~MouseButtonEventArgs() override = default; - platform::native::MouseButton GetMouseButton() const { return button_; } + MouseButton GetMouseButton() const { return button_; } private: - platform::native::MouseButton button_; + MouseButton button_; }; class MouseWheelEventArgs : public MouseEventArgs { @@ -113,7 +112,7 @@ class MouseWheelEventArgs : public MouseEventArgs { class PaintEventArgs : public UiEventArgs { public: PaintEventArgs(Object* sender, Object* original_sender, - platform::graph::IPainter* painter) + platform::graph::Painter* painter) : UiEventArgs(sender, original_sender), painter_(painter) {} PaintEventArgs(const PaintEventArgs& other) = default; PaintEventArgs(PaintEventArgs&& other) = default; @@ -121,10 +120,10 @@ class PaintEventArgs : public UiEventArgs { PaintEventArgs& operator=(PaintEventArgs&& other) = default; ~PaintEventArgs() = default; - platform::graph::IPainter* GetPainter() const { return painter_; } + platform::graph::Painter* GetPainter() const { return painter_; } private: - platform::graph::IPainter* painter_; + platform::graph::Painter* painter_; }; class FocusChangeEventArgs : public UiEventArgs { diff --git a/include/cru/ui/render/border_render_object.hpp b/include/cru/ui/render/border_render_object.hpp index 407edbb3..ab424e60 100644 --- a/include/cru/ui/render/border_render_object.hpp +++ b/include/cru/ui/render/border_render_object.hpp @@ -4,9 +4,9 @@ #include namespace cru::platform::graph { -struct IBrush; -struct IGeometry; -} // namespace cru::platform +class Brush; +class Geometry; +} // namespace cru::platform::graph namespace cru::ui::render { struct CornerRadius { @@ -32,7 +32,7 @@ struct CornerRadius { class BorderRenderObject : public RenderObject { public: - explicit BorderRenderObject(std::shared_ptr brush); + explicit BorderRenderObject(std::shared_ptr brush); BorderRenderObject(const BorderRenderObject& other) = delete; BorderRenderObject(BorderRenderObject&& other) = delete; BorderRenderObject& operator=(const BorderRenderObject& other) = delete; @@ -42,8 +42,10 @@ class BorderRenderObject : public RenderObject { bool IsEnabled() const { return is_enabled_; } void SetEnabled(bool enabled) { is_enabled_ = enabled; } - std::shared_ptr GetBrush() const { return border_brush_; } - void SetBrush(std::shared_ptr new_brush) { + std::shared_ptr GetBrush() const { + return border_brush_; + } + void SetBrush(std::shared_ptr new_brush) { border_brush_ = std::move(new_brush); } @@ -59,7 +61,7 @@ class BorderRenderObject : public RenderObject { void Refresh() { RecreateGeometry(); } - void Draw(platform::graph::IPainter* painter) override; + void Draw(platform::graph::Painter* painter) override; RenderObject* HitTest(const Point& point) override; @@ -83,11 +85,11 @@ class BorderRenderObject : public RenderObject { private: bool is_enabled_ = false; - std::shared_ptr border_brush_ = nullptr; + std::shared_ptr border_brush_ = nullptr; Thickness border_thickness_{}; CornerRadius corner_radius_{}; - std::shared_ptr geometry_ = nullptr; - std::shared_ptr border_outer_geometry_ = nullptr; + std::shared_ptr geometry_ = nullptr; + std::shared_ptr border_outer_geometry_ = nullptr; }; } // namespace cru::ui::render diff --git a/include/cru/ui/render/flex_layout_render_object.hpp b/include/cru/ui/render/flex_layout_render_object.hpp index 8d881239..1234b920 100644 --- a/include/cru/ui/render/flex_layout_render_object.hpp +++ b/include/cru/ui/render/flex_layout_render_object.hpp @@ -64,7 +64,7 @@ class FlexLayoutRenderObject : public RenderObject { FlexChildLayoutData* GetChildLayoutData(int position); - void Draw(platform::graph::IPainter* painter) override; + void Draw(platform::graph::Painter* painter) override; RenderObject* HitTest(const Point& point) override; diff --git a/include/cru/ui/render/render_object.hpp b/include/cru/ui/render/render_object.hpp index b6614317..dca254cc 100644 --- a/include/cru/ui/render/render_object.hpp +++ b/include/cru/ui/render/render_object.hpp @@ -1,7 +1,7 @@ #pragma once #include "cru/common/base.hpp" -#include "cru/common/ui_base.hpp" +#include "../base.hpp" #include @@ -11,7 +11,7 @@ class Control; } namespace cru::platform::graph { -struct IPainter; +class Painter; } namespace cru::ui::render { @@ -58,7 +58,7 @@ class RenderObject : public Object { void Measure(const Size& available_size); void Layout(const Rect& rect); - virtual void Draw(platform::graph::IPainter* painter) = 0; + virtual void Draw(platform::graph::Painter* painter) = 0; virtual RenderObject* HitTest(const Point& point) = 0; diff --git a/include/cru/ui/render/text_render_object.hpp b/include/cru/ui/render/text_render_object.hpp index ecad6bb8..054d9b47 100644 --- a/include/cru/ui/render/text_render_object.hpp +++ b/include/cru/ui/render/text_render_object.hpp @@ -6,17 +6,17 @@ // forward declarations namespace cru::platform::graph { -struct IBrush; -struct IFontDescriptor; -struct ITextLayout; +class Brush; +class Font; +class TextLayout; } // namespace cru::platform::graph namespace cru::ui::render { class TextRenderObject : public RenderObject { public: - TextRenderObject(std::shared_ptr brush, - std::shared_ptr font, - std::shared_ptr selection_brush); + TextRenderObject(std::shared_ptr brush, + std::shared_ptr font, + std::shared_ptr selection_brush); TextRenderObject(const TextRenderObject& other) = delete; TextRenderObject(TextRenderObject&& other) = delete; TextRenderObject& operator=(const TextRenderObject& other) = delete; @@ -26,13 +26,13 @@ class TextRenderObject : public RenderObject { std::wstring GetText() const; void SetText(std::wstring new_text); - std::shared_ptr GetBrush() const { return brush_; } - void SetBrush(std::shared_ptr new_brush) { + std::shared_ptr GetBrush() const { return brush_; } + void SetBrush(std::shared_ptr new_brush) { new_brush.swap(brush_); } - std::shared_ptr GetFont() const; - void SetFont(std::shared_ptr font); + std::shared_ptr GetFont() const; + void SetFont(std::shared_ptr font); std::optional GetSelectionRange() const { return selection_range_; @@ -41,14 +41,14 @@ class TextRenderObject : public RenderObject { selection_range_ = std::move(new_range); } - std::shared_ptr GetSelectionBrush() const { + std::shared_ptr GetSelectionBrush() const { return selection_brush_; } - void SetSelectionBrush(std::shared_ptr new_brush) { + void SetSelectionBrush(std::shared_ptr new_brush) { new_brush.swap(selection_brush_); } - void Draw(platform::graph::IPainter* painter) override; + void Draw(platform::graph::Painter* painter) override; RenderObject* HitTest(const Point& point) override; @@ -59,11 +59,11 @@ class TextRenderObject : public RenderObject { void OnLayoutContent(const Rect& content_rect) override; private: - std::shared_ptr brush_; - std::shared_ptr font_; - std::shared_ptr text_layout_; + std::shared_ptr brush_; + std::shared_ptr font_; + std::shared_ptr text_layout_; std::optional selection_range_ = std::nullopt; - std::shared_ptr selection_brush_; + std::shared_ptr selection_brush_; }; } // namespace cru::ui::render diff --git a/include/cru/ui/render/window_render_object.hpp b/include/cru/ui/render/window_render_object.hpp index b95acbce..dfeae487 100644 --- a/include/cru/ui/render/window_render_object.hpp +++ b/include/cru/ui/render/window_render_object.hpp @@ -17,7 +17,7 @@ class WindowRenderObject : public RenderObject { void MeasureAndLayout(); - void Draw(platform::graph::IPainter* painter) override; + void Draw(platform::graph::Painter* painter) override; RenderObject* HitTest(const Point& point) override; diff --git a/include/cru/ui/ui_manager.hpp b/include/cru/ui/ui_manager.hpp index f3f78722..d2b8ad53 100644 --- a/include/cru/ui/ui_manager.hpp +++ b/include/cru/ui/ui_manager.hpp @@ -1,15 +1,16 @@ #pragma once +#include "base.hpp" #include "cru/common/base.hpp" #include namespace cru::platform::graph { -struct IBrush; -struct IFontDescriptor; -} // namespace cru::platform +class Brush; +class Font; +} // namespace cru::platform::graph namespace cru::ui { -//TODO: Make this theme resource. +// TODO: Make this theme resource. class PredefineResources : public Object { public: PredefineResources(); @@ -20,12 +21,12 @@ class PredefineResources : public Object { ~PredefineResources() override = default; // region Button - std::shared_ptr button_normal_border_brush; + std::shared_ptr button_normal_border_brush; // region TextBlock - std::shared_ptr text_block_selection_brush; - std::shared_ptr text_block_text_brush; - std::shared_ptr text_block_font; + std::shared_ptr text_block_selection_brush; + std::shared_ptr text_block_text_brush; + std::shared_ptr text_block_font; }; class UiManager : public Object { diff --git a/include/cru/ui/window.hpp b/include/cru/ui/window.hpp index e175b234..311f1487 100644 --- a/include/cru/ui/window.hpp +++ b/include/cru/ui/window.hpp @@ -9,7 +9,7 @@ #include namespace cru::platform::native { -struct INativeWindow; +class NativeWindow; } namespace cru::ui { @@ -41,7 +41,7 @@ class Window final : public ContentControl, public SelfResovable { render::RenderObject* GetRenderObject() const override; - platform::native::INativeWindow* GetNativeWindow() const { + platform::native::NativeWindow* GetNativeWindow() const { return native_window_; } @@ -91,7 +91,7 @@ class Window final : public ContentControl, public SelfResovable { const Point& point); private: - platform::native::INativeWindow* native_window_; + platform::native::NativeWindow* native_window_; std::vector event_revoker_guards_; std::shared_ptr render_object_; diff --git a/include/cru/win/graph/direct/exception.hpp b/include/cru/win/graph/direct/exception.hpp index bfa14aaf..8e955825 100644 --- a/include/cru/win/graph/direct/exception.hpp +++ b/include/cru/win/graph/direct/exception.hpp @@ -1,36 +1,7 @@ #pragma once -#include "../../win_pre_config.hpp" - -#include "cru/platform/exception.hpp" - -#include -#include +#include "../../exception.hpp" namespace cru::platform::graph::win::direct { - -class HResultError : public PlatformException { - public: - explicit HResultError(HRESULT h_result); - explicit HResultError(HRESULT h_result, - const std::string_view& additional_message); - HResultError(const HResultError& other) = default; - HResultError(HResultError&& other) = default; - HResultError& operator=(const HResultError& other) = default; - HResultError& operator=(HResultError&& other) = default; - ~HResultError() override = default; - - HRESULT GetHResult() const { return h_result_; } - - private: - HRESULT h_result_; -}; - -inline void ThrowIfFailed(const HRESULT h_result) { - if (FAILED(h_result)) throw HResultError(h_result); -} - -inline void ThrowIfFailed(const HRESULT h_result, - const std::string_view& message) { - if (FAILED(h_result)) throw HResultError(h_result, message); -} +using platform::win::HResultError; +using platform::win::ThrowIfFailed; } // namespace cru::platform::graph::win::direct \ No newline at end of file diff --git a/include/cru/win/graph/direct/graph_factory.hpp b/include/cru/win/graph/direct/graph_factory.hpp index 841dd104..fb26a7c5 100644 --- a/include/cru/win/graph/direct/graph_factory.hpp +++ b/include/cru/win/graph/direct/graph_factory.hpp @@ -10,7 +10,7 @@ #include "cru/platform/graph/graph_factory.hpp" namespace cru::platform::graph::win::direct { -class DirectGraphFactory : public GraphFactory, IDirectFactory { +class DirectGraphFactory : public GraphFactory, public IDirectFactory { friend GraphFactory* GraphFactory::CreateInstance(); public: diff --git a/include/cru/win/graph/direct/platform_id.hpp b/include/cru/win/graph/direct/platform_id.hpp index ff02eb27..edac38f1 100644 --- a/include/cru/win/graph/direct/platform_id.hpp +++ b/include/cru/win/graph/direct/platform_id.hpp @@ -1,19 +1,18 @@ #pragma once #include -#include #include namespace cru::platform::graph::win::direct { -constexpr std::wstring_view platform_id = L"Windows Direct"; +constexpr std::wstring_view win_direct_platform_id = L"Windows Direct"; -bool IsDirectResource(NativeResource* resource) { - return resource->GetPlatformId() == platform_id; +inline bool IsDirectResource(NativeResource* resource) { + return resource->GetPlatformId() == win_direct_platform_id; } } // namespace cru::platform::graph::win::direct -#define CRU_PLATFORMID_IMPLEMENT_DIRECT \ - std::wstring_view GetPlatformId() const override { \ - return ::cru::platform::graph::win::direct::platform_id; \ +#define CRU_PLATFORMID_IMPLEMENT_DIRECT \ + std::wstring_view GetPlatformId() const override { \ + return ::cru::platform::graph::win::direct::win_direct_platform_id; \ } diff --git a/include/cru/win/native/exception.hpp b/include/cru/win/native/exception.hpp new file mode 100644 index 00000000..637f021d --- /dev/null +++ b/include/cru/win/native/exception.hpp @@ -0,0 +1,6 @@ +#pragma once +#include "../exception.hpp" + +namespace cru::platform::native::win { +using platform::win::Win32Error; +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/god_window.hpp b/include/cru/win/native/god_window.hpp index 9ac49858..9fd20caa 100644 --- a/include/cru/win/native/god_window.hpp +++ b/include/cru/win/native/god_window.hpp @@ -5,13 +5,13 @@ #include -namespace cru::win::native { -class WinApplication; +namespace cru::platform::native::win { +class WinUiApplication; class WindowClass; class GodWindow : public Object { public: - explicit GodWindow(WinApplication* application); + explicit GodWindow(WinUiApplication* application); GodWindow(const GodWindow& other) = delete; GodWindow(GodWindow&& other) = delete; GodWindow& operator=(const GodWindow& other) = delete; @@ -24,7 +24,7 @@ class GodWindow : public Object { LPARAM l_param, LRESULT* result); private: - WinApplication* application_; + WinUiApplication* application_; std::shared_ptr god_window_class_; HWND hwnd_; diff --git a/include/cru/win/native/native_window.hpp b/include/cru/win/native/native_window.hpp new file mode 100644 index 00000000..ed678591 --- /dev/null +++ b/include/cru/win/native/native_window.hpp @@ -0,0 +1,138 @@ +#pragma once +#include "../win_pre_config.hpp" + +#include "cru/platform/native/native_window.hpp" +#include "platform_id.hpp" +#include "window_native_message_event_args.hpp" + +#include + +namespace cru::platform::native::win { +class WinUiApplication; +class WindowClass; +class WindowManager; +class WindowRenderTarget; + +class WinNativeWindow : public NativeWindow { + public: + WinNativeWindow(WinUiApplication* application, + std::shared_ptr 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; + + CRU_PLATFORMID_IMPLEMENT_WIN + + public: + bool IsValid() override; + void SetDeleteThisOnDestroy(bool value) override; + + void Close() override; + + WinNativeWindow* GetParent() override { return parent_window_; } + + bool IsVisible() override; + void SetVisible(bool is_visible) override; + + Size GetClientSize() override; + void SetClientSize(const Size& size) override; + + // Get the rect of the window containing frame. + // The lefttop of the rect is relative to screen lefttop. + Rect GetWindowRect() override; + + // Set the rect of the window containing frame. + // The lefttop of the rect is relative to screen lefttop. + void SetWindowRect(const Rect& rect) override; + + graph::Painter* BeginPaint() override; + + IEvent* DestroyEvent() override { return &destroy_event_; } + IEvent* PaintEvent() override { return &paint_event_; } + IEvent* ResizeEvent() override { return &resize_event_; } + IEvent* FocusEvent() override { return &focus_event_; } + IEvent* MouseEnterLeaveEvent() override { + return &mouse_enter_leave_event_; + } + IEvent* MouseMoveEvent() override { return &mouse_move_event_; } + IEvent* MouseDownEvent() + override { + return &mouse_down_event_; + } + IEvent* MouseUpEvent() + override { + return &mouse_up_event_; + } + IEvent* KeyDownEvent() override { return &key_down_event_; } + IEvent* KeyUpEvent() override { return &key_up_event_; } + + IEvent* 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); + + WindowRenderTarget* GetWindowRenderTarget() const { + return window_render_target_.get(); + } + + 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(platform::native::MouseButton button, POINT point); + void OnMouseUpInternal(platform::native::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: + WinUiApplication* application_; + + bool delete_this_on_destroy_ = true; + + HWND hwnd_; + WinNativeWindow* parent_window_; + + bool has_focus_ = false; + bool is_mouse_in_ = false; + + std::shared_ptr window_render_target_; + + Event destroy_event_; + Event paint_event_; + Event resize_event_; + Event focus_event_; + Event mouse_enter_leave_event_; + Event mouse_move_event_; + Event mouse_down_event_; + Event mouse_up_event_; + Event key_down_event_; + Event key_up_event_; + + Event native_message_event_; +}; +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/platform_id.hpp b/include/cru/win/native/platform_id.hpp new file mode 100644 index 00000000..4b018d51 --- /dev/null +++ b/include/cru/win/native/platform_id.hpp @@ -0,0 +1,19 @@ +#pragma once +#include + +#include +#include + +namespace cru::platform::native::win { +constexpr std::wstring_view win_platform_id = L"Windows"; + +inline bool IsWindowsResource(NativeResource* resource) { + return resource->GetPlatformId() == win_platform_id; +} + +} // namespace cru::platform::native::win + +#define CRU_PLATFORMID_IMPLEMENT_WIN \ + std::wstring_view GetPlatformId() const override { \ + return ::cru::platform::native::win::win_platform_id; \ + } diff --git a/include/cru/win/native/ui_application.hpp b/include/cru/win/native/ui_application.hpp new file mode 100644 index 00000000..08a9c3ed --- /dev/null +++ b/include/cru/win/native/ui_application.hpp @@ -0,0 +1,69 @@ +#pragma once +#include "../win_pre_config.hpp" + +#include "platform_id.hpp" + +#include "cru/platform/native/ui_applicaition.hpp" + +#include + +namespace cru::platform::native::win { +class GodWindow; +class TimerManager; +class WindowManager; + +class WinUiApplication : public UiApplication { + friend UiApplication* UiApplication::CreateInstance(); + + public: + static WinUiApplication* GetInstance(); + + private: + explicit WinUiApplication(HINSTANCE h_instance); + + public: + WinUiApplication(const WinUiApplication&) = delete; + WinUiApplication(WinUiApplication&&) = delete; + WinUiApplication& operator=(const WinUiApplication&) = delete; + WinUiApplication& operator=(WinUiApplication&&) = delete; + ~WinUiApplication() override; + + CRU_PLATFORMID_IMPLEMENT_WIN + + public: + int Run() override; + void Quit(int quit_code) override; + + void AddOnQuitHandler(const std::function& handler) override; + + void InvokeLater(const std::function& action) override; + unsigned long SetTimeout(std::chrono::milliseconds milliseconds, + const std::function& action) override; + unsigned long SetInterval(std::chrono::milliseconds milliseconds, + const std::function& action) override; + void CancelTimer(unsigned long id) override; + + std::vector GetAllWindow() override; + NativeWindow* CreateWindow(NativeWindow* parent) override; + + bool IsAutoDelete() const { return auto_delete_; } + void SetAutoDelete(bool value) { auto_delete_ = value; } + + HINSTANCE GetInstanceHandle() const { return h_instance_; } + + GodWindow* GetGodWindow() const { return god_window_.get(); } + TimerManager* GetTimerManager() const { return timer_manager_.get(); } + WindowManager* GetWindowManager() const { return window_manager_.get(); } + + private: + bool auto_delete_ = false; + + HINSTANCE h_instance_; + + std::shared_ptr god_window_; + std::shared_ptr timer_manager_; + std::shared_ptr window_manager_; + + std::vector> quit_handlers_; +}; +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/win_application.hpp b/include/cru/win/native/win_application.hpp deleted file mode 100644 index d3e705e1..00000000 --- a/include/cru/win/native/win_application.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once -#include "../win_pre_config.hpp" - -#include "cru/platform/native/ui_applicaition.hpp" - -#include - -namespace cru::win::native { -class GodWindow; -class TimerManager; -class WindowManager; - -class WinApplication : public Object, - public virtual platform::native::IUiApplication { - friend IUiApplication* IUiApplication::CreateInstance(); - public: - static WinApplication* GetInstance(); - - private: - explicit WinApplication(HINSTANCE h_instance); - - public: - WinApplication(const WinApplication&) = delete; - WinApplication(WinApplication&&) = delete; - WinApplication& operator=(const WinApplication&) = delete; - WinApplication& operator=(WinApplication&&) = delete; - ~WinApplication() override; - - public: - int Run() override; - void Quit(int quit_code) override; - - void AddOnQuitHandler(const std::function& handler) override; - - void InvokeLater(const std::function& action) override; - unsigned long SetTimeout(std::chrono::milliseconds milliseconds, - const std::function& action) override; - unsigned long SetInterval(std::chrono::milliseconds milliseconds, - const std::function& action) override; - void CancelTimer(unsigned long id) override; - - std::vector GetAllWindow() override; - platform::native::INativeWindow* CreateWindow( - platform::native::INativeWindow* parent) override; - - bool IsAutoDelete() const override { return auto_delete_; } - void SetAutoDelete(bool value) override { auto_delete_ = value; } - - HINSTANCE GetInstanceHandle() const { return h_instance_; } - - GodWindow* GetGodWindow() const { return god_window_.get(); } - TimerManager* GetTimerManager() const { return timer_manager_.get(); } - WindowManager* GetWindowManager() const { return window_manager_.get(); } - - private: - bool auto_delete_ = false; - - HINSTANCE h_instance_; - - std::shared_ptr god_window_; - std::shared_ptr timer_manager_; - std::shared_ptr window_manager_; - - std::vector> quit_handlers_; -}; -} // namespace cru::win::native diff --git a/include/cru/win/native/win_native_window.hpp b/include/cru/win/native/win_native_window.hpp deleted file mode 100644 index 18de4f5d..00000000 --- a/include/cru/win/native/win_native_window.hpp +++ /dev/null @@ -1,135 +0,0 @@ -#pragma once -#include "../win_pre_config.hpp" - -#include "cru/platform/native/native_window.hpp" -#include "window_native_message_event_args.hpp" - -#include - -namespace cru::win::native { -class WinApplication; -class WindowClass; -class WindowManager; -class WindowRenderTarget; - -class WinNativeWindow : public Object, - public virtual platform::native::INativeWindow { - public: - WinNativeWindow(WinApplication* application, - std::shared_ptr 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; - - INativeWindow* 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; - - platform::graph::IPainter* BeginPaint() override; - - IEvent* DestroyEvent() override { return &destroy_event_; } - IEvent* PaintEvent() override { return &paint_event_; } - IEvent* ResizeEvent() override { return &resize_event_; } - IEvent* FocusEvent() override { return &focus_event_; } - IEvent* MouseEnterLeaveEvent() override { - return &mouse_enter_leave_event_; - } - IEvent* MouseMoveEvent() override { return &mouse_move_event_; } - IEvent* MouseDownEvent() - override { - return &mouse_down_event_; - } - IEvent* MouseUpEvent() - override { - return &mouse_up_event_; - } - IEvent* KeyDownEvent() override { return &key_down_event_; } - IEvent* KeyUpEvent() override { return &key_up_event_; } - - IEvent* 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); - - WindowRenderTarget* GetWindowRenderTarget() const { - return window_render_target_.get(); - } - - 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(platform::native::MouseButton button, POINT point); - void OnMouseUpInternal(platform::native::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; - - std::shared_ptr window_render_target_; - - Event destroy_event_; - Event paint_event_; - Event resize_event_; - Event focus_event_; - Event mouse_enter_leave_event_; - Event mouse_move_event_; - Event mouse_down_event_; - Event mouse_up_event_; - Event key_down_event_; - Event key_up_event_; - - Event native_message_event_; -}; -} // namespace cru::win::native diff --git a/include/cru/win/native/window_class.hpp b/include/cru/win/native/window_class.hpp index 17712958..fec3b32e 100644 --- a/include/cru/win/native/window_class.hpp +++ b/include/cru/win/native/window_class.hpp @@ -5,7 +5,7 @@ #include -namespace cru::win::native { +namespace cru::platform::native::win { class WindowClass : public Object { public: WindowClass(const std::wstring& name, WNDPROC window_proc, diff --git a/include/cru/win/native/window_native_message_event_args.hpp b/include/cru/win/native/window_native_message_event_args.hpp index 37149f36..4cf744f2 100644 --- a/include/cru/win/native/window_native_message_event_args.hpp +++ b/include/cru/win/native/window_native_message_event_args.hpp @@ -3,7 +3,7 @@ #include "cru/common/base.hpp" -namespace cru::win::native { +namespace cru::platform::native::win { struct WindowNativeMessage { HWND hwnd; UINT msg; diff --git a/include/cru/win/native/window_render_target.hpp b/include/cru/win/native/window_render_target.hpp index 5ff8ec87..bde47f4f 100644 --- a/include/cru/win/native/window_render_target.hpp +++ b/include/cru/win/native/window_render_target.hpp @@ -3,15 +3,15 @@ #include "cru/common/base.hpp" -namespace cru::win::graph { -struct IWinNativeFactory; +namespace cru::platform::graph::win::direct { +struct IDirectFactory; } -namespace cru::win::native { +namespace cru::platform::native::win { // Represents a window render target. class WindowRenderTarget : public Object { public: - WindowRenderTarget(graph::IWinNativeFactory* factory, HWND hwnd); + WindowRenderTarget(graph::win::direct::IDirectFactory* factory, HWND hwnd); WindowRenderTarget(const WindowRenderTarget& other) = delete; WindowRenderTarget(WindowRenderTarget&& other) = delete; WindowRenderTarget& operator=(const WindowRenderTarget& other) = delete; @@ -19,7 +19,9 @@ class WindowRenderTarget : public Object { ~WindowRenderTarget() override = default; public: - graph::IWinNativeFactory* GetWinNativeFactory() const { return factory_; } + graph::win::direct::IDirectFactory* GetWinNativeFactory() const { + return factory_; + } // Get the target bitmap which can be set as the ID2D1DeviceContext's target. ID2D1Bitmap1* GetTargetBitmap() const { return target_bitmap_.Get(); } @@ -37,8 +39,8 @@ class WindowRenderTarget : public Object { void CreateTargetBitmap(); private: - graph::IWinNativeFactory* factory_; + graph::win::direct::IDirectFactory* factory_; Microsoft::WRL::ComPtr dxgi_swap_chain_; Microsoft::WRL::ComPtr target_bitmap_; }; -} // namespace cru::win::native +} // namespace cru::platform::native::win diff --git a/src/main.cpp b/src/main.cpp index ee381430..f9c0e56b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,7 +5,7 @@ #include "cru/ui/controls/text_block.hpp" #include "cru/ui/window.hpp" -using cru::platform::native::IUiApplication; +using cru::platform::native::UiApplication; using cru::ui::Rect; using cru::ui::Thickness; using cru::ui::Window; @@ -15,13 +15,16 @@ using cru::ui::controls::TextBlock; /* int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { + +*/ + +int main() { + #ifdef CRU_DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif -*/ -int main() { - std::unique_ptr application(IUiApplication::CreateInstance()); + std::unique_ptr application(UiApplication::CreateInstance()); const auto window = Window::CreateOverlapped(); diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index a725c54b..6d6fc02d 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(cru_ui STATIC render/window_render_object.cpp ) target_sources(cru_ui PUBLIC + ${CRU_UI_INCLUDE_DIR}/base.hpp ${CRU_UI_INCLUDE_DIR}/content_control.hpp ${CRU_UI_INCLUDE_DIR}/control.hpp ${CRU_UI_INCLUDE_DIR}/layout_control.hpp diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp index 99c2cb4c..16d2f1ea 100644 --- a/src/ui/render/border_render_object.cpp +++ b/src/ui/render/border_render_object.cpp @@ -10,13 +10,13 @@ namespace cru::ui::render { BorderRenderObject::BorderRenderObject( - std::shared_ptr brush) { + std::shared_ptr brush) { assert(brush); this->border_brush_ = std::move(brush); RecreateGeometry(); } -void BorderRenderObject::Draw(platform::graph::IPainter* painter) { +void BorderRenderObject::Draw(platform::graph::Painter* painter) { painter->FillGeometry(geometry_.get(), border_brush_.get()); if (const auto child = GetChild()) { auto offset = child->GetOffset(); @@ -154,7 +154,7 @@ void BorderRenderObject::RecreateGeometry() { geometry_.reset(); border_outer_geometry_.reset(); - auto f = [](platform::graph::IGeometryBuilder* builder, const Rect& rect, + auto f = [](platform::graph::GeometryBuilder* builder, const Rect& rect, const CornerRadius& corner) { builder->BeginFigure(Point(rect.left + corner.left_top.x, rect.top)); builder->LineTo(Point(rect.GetRight() - corner.right_top.x, rect.top)); @@ -181,18 +181,18 @@ void BorderRenderObject::RecreateGeometry() { const Rect outer_rect{margin.left, margin.top, size.width - margin.GetHorizontalTotal(), size.height - margin.GetVerticalTotal()}; - const auto graph_factory = platform::graph::IGraphFactory::GetInstance(); - std::unique_ptr builder{ + const auto graph_factory = platform::graph::GraphFactory::GetInstance(); + std::unique_ptr builder{ graph_factory->CreateGeometryBuilder()}; f(builder.get(), outer_rect, corner_radius_); - border_outer_geometry_.reset(builder->End()); + border_outer_geometry_.reset(builder->Build()); builder.reset(); const Rect inner_rect = outer_rect.Shrink(border_thickness_); builder.reset(graph_factory->CreateGeometryBuilder()); f(builder.get(), outer_rect, corner_radius_); f(builder.get(), inner_rect, corner_radius_); - geometry_.reset(builder->End()); + geometry_.reset(builder->Build()); builder.reset(); } } // namespace cru::ui::render diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp index a9841813..8ce2db0a 100644 --- a/src/ui/render/flex_layout_render_object.cpp +++ b/src/ui/render/flex_layout_render_object.cpp @@ -15,7 +15,7 @@ FlexChildLayoutData* FlexLayoutRenderObject::GetChildLayoutData(int position) { return &child_layout_data_[position]; } -void FlexLayoutRenderObject::Draw(platform::graph::IPainter* painter) { +void FlexLayoutRenderObject::Draw(platform::graph::Painter* painter) { for (const auto child : GetChildren()) { auto offset = child->GetOffset(); platform::graph::util::WithTransform( diff --git a/src/ui/render/text_render_object.cpp b/src/ui/render/text_render_object.cpp index 849bff11..64a34b6c 100644 --- a/src/ui/render/text_render_object.cpp +++ b/src/ui/render/text_render_object.cpp @@ -9,9 +9,9 @@ namespace cru::ui::render { TextRenderObject::TextRenderObject( - std::shared_ptr brush, - std::shared_ptr font, - std::shared_ptr selection_brush) { + std::shared_ptr brush, + std::shared_ptr font, + std::shared_ptr selection_brush) { assert(brush); assert(font); assert(selection_brush); @@ -20,7 +20,7 @@ TextRenderObject::TextRenderObject( font.swap(font_); selection_brush.swap(selection_brush_); - const auto graph_factory = platform::graph::IGraphFactory::GetInstance(); + const auto graph_factory = platform::graph::GraphFactory::GetInstance(); text_layout_.reset(graph_factory->CreateTextLayout(font_, L"")); } @@ -32,22 +32,22 @@ void TextRenderObject::SetText(std::wstring new_text) { text_layout_->SetText(std::move(new_text)); } -std::shared_ptr TextRenderObject::GetFont() +std::shared_ptr TextRenderObject::GetFont() const { return text_layout_->GetFont(); } void TextRenderObject::SetFont( - std::shared_ptr font) { + std::shared_ptr font) { text_layout_->SetFont(std::move(font)); } -void TextRenderObject::Draw(platform::graph::IPainter* painter) { +void TextRenderObject::Draw(platform::graph::Painter* painter) { platform::graph::util::WithTransform( painter, platform::Matrix::Translation(GetMargin().left + GetPadding().left, GetMargin().top + GetPadding().top), - [this](platform::graph::IPainter* p) { + [this](platform::graph::Painter* p) { if (this->selection_range_.has_value()) { const auto&& rects = text_layout_->TextRangeRect(this->selection_range_.value()); diff --git a/src/ui/render/window_render_object.cpp b/src/ui/render/window_render_object.cpp index f2e29603..89bb0beb 100644 --- a/src/ui/render/window_render_object.cpp +++ b/src/ui/render/window_render_object.cpp @@ -13,13 +13,13 @@ void WindowRenderObject::MeasureAndLayout() { Layout(Rect{Point{}, client_size}); } -void WindowRenderObject::Draw(platform::graph::IPainter* painter) { +void WindowRenderObject::Draw(platform::graph::Painter* painter) { painter->Clear(colors::white); if (const auto child = GetChild()) { auto offset = child->GetOffset(); platform::graph::util::WithTransform( painter, platform::Matrix::Translation(offset.x, offset.y), - [child](platform::graph::IPainter* p) { child->Draw(p); }); + [child](platform::graph::Painter* p) { child->Draw(p); }); } } diff --git a/src/ui/ui_manager.cpp b/src/ui/ui_manager.cpp index cc741ec5..376b1b45 100644 --- a/src/ui/ui_manager.cpp +++ b/src/ui/ui_manager.cpp @@ -6,21 +6,22 @@ #include "cru/platform/native/ui_applicaition.hpp" namespace cru::ui { +using namespace cru::platform::graph; PredefineResources::PredefineResources() { - const auto graph_factory = platform::graph::IGraphFactory::GetInstance(); + const auto graph_factory = GraphFactory::GetInstance(); - button_normal_border_brush.reset(static_cast( - graph_factory->CreateSolidColorBrush(colors::black))); - text_block_selection_brush.reset(static_cast( + button_normal_border_brush.reset( + static_cast(graph_factory->CreateSolidColorBrush(colors::black))); + text_block_selection_brush.reset(static_cast( graph_factory->CreateSolidColorBrush(colors::skyblue))); - text_block_text_brush.reset(static_cast( - graph_factory->CreateSolidColorBrush(colors::black))); - text_block_font.reset(graph_factory->CreateFontDescriptor(L"等线", 24.0f)); + text_block_text_brush.reset( + static_cast(graph_factory->CreateSolidColorBrush(colors::black))); + text_block_font.reset(graph_factory->CreateFont(L"等线", 24.0f)); } UiManager* UiManager::GetInstance() { static UiManager* instance = new UiManager(); - platform::native::IUiApplication::GetInstance()->AddOnQuitHandler([] { + platform::native::UiApplication::GetInstance()->AddOnQuitHandler([] { delete instance; instance = nullptr; }); diff --git a/src/ui/window.cpp b/src/ui/window.cpp index 4a1bc108..9eabc4a6 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -111,7 +111,7 @@ void BindNativeEvent(Window* window, IEvent* event, Window::Window(tag_overlapped_constructor) : mouse_hover_control_(nullptr), focus_control_(this) { native_window_ = - platform::native::IUiApplication::GetInstance()->CreateWindow(nullptr); + platform::native::UiApplication::GetInstance()->CreateWindow(nullptr); render_object_.reset(new render::WindowRenderObject(this)); BindNativeEvent(this, native_window_->DestroyEvent(), @@ -151,7 +151,7 @@ void Window::Relayout() { this->render_object_->MeasureAndLayout(); } void Window::InvalidateLayout() { if (!need_layout_) { - platform::native::IUiApplication::GetInstance()->InvokeLater( + platform::native::UiApplication::GetInstance()->InvokeLater( [resolver = this->CreateResolver()] { if (const auto window = resolver.Resolve()) { window->Relayout(); @@ -192,9 +192,9 @@ void Window::OnNativeDestroy(std::nullptr_t) { delete this; } void Window::OnNativePaint(std::nullptr_t) { const auto painter = - std::unique_ptr(native_window_->BeginPaint()); + std::unique_ptr(native_window_->BeginPaint()); render_object_->Draw(painter.get()); - painter->End(); + painter->EndDraw(); } void Window::OnNativeResize(const Size& size) { diff --git a/src/win/exception.cpp b/src/win/exception.cpp index 62305329..4cac66bb 100644 --- a/src/win/exception.cpp +++ b/src/win/exception.cpp @@ -2,7 +2,7 @@ #include "cru/common/format.hpp" -namespace cru::win { +namespace cru::platform::win { using util::Format; inline std::string HResultMakeMessage(HRESULT h_result, diff --git a/src/win/graph/direct/CMakeLists.txt b/src/win/graph/direct/CMakeLists.txt index 7cbbb080..7228802c 100644 --- a/src/win/graph/direct/CMakeLists.txt +++ b/src/win/graph/direct/CMakeLists.txt @@ -2,7 +2,6 @@ set(CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/win/graph/direct) add_library(cru_win_graph_direct STATIC brush.cpp - exception.cpp font.cpp geometry.cpp graph_factory.cpp diff --git a/src/win/graph/direct/exception.cpp b/src/win/graph/direct/exception.cpp deleted file mode 100644 index 23c267c1..00000000 --- a/src/win/graph/direct/exception.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "cru/win/graph/direct/exception.hpp" - -#include "cru/common/format.hpp" - -namespace cru::platform::graph::win::direct { -using util::Format; - -inline std::string HResultMakeMessage(HRESULT h_result, - const std::string_view* message) { - char buffer[10]; - sprintf_s(buffer, "%#08x", h_result); - - if (message) - return Format( - "An HResultError is thrown. HRESULT: {}.\nAdditional message: {}\n", - buffer, *message); - else - return Format("An HResultError is thrown. HRESULT: {}.\n", buffer); -} - -HResultError::HResultError(HRESULT h_result) - : PlatformException(HResultMakeMessage(h_result, nullptr)), - h_result_(h_result) {} - -HResultError::HResultError(HRESULT h_result, - const std::string_view& additional_message) - : PlatformException(HResultMakeMessage(h_result, &additional_message)), - h_result_(h_result) {} -} // namespace cru::platform::graph::win::direct diff --git a/src/win/native/CMakeLists.txt b/src/win/native/CMakeLists.txt index a9ee84e7..757eae57 100644 --- a/src/win/native/CMakeLists.txt +++ b/src/win/native/CMakeLists.txt @@ -4,24 +4,26 @@ add_library(cru_win_native STATIC dpi_util.hpp god_window_message.hpp timer.hpp + window_d2d_painter.hpp window_manager.hpp - window_painter.hpp god_window.cpp + native_window.cpp timer.cpp - win_application.cpp - win_native_window.cpp + ui_application.cpp window_class.cpp + window_d2d_painter.cpp window_manager.cpp - window_painter.cpp window_render_target.cpp ) target_sources(cru_win_native PUBLIC + ${CRU_WIN_NATIVE_INCLUDE_DIR}/exception.hpp ${CRU_WIN_NATIVE_INCLUDE_DIR}/god_window.hpp - ${CRU_WIN_NATIVE_INCLUDE_DIR}/win_application.hpp - ${CRU_WIN_NATIVE_INCLUDE_DIR}/win_native_window.hpp + ${CRU_WIN_NATIVE_INCLUDE_DIR}/native_window.hpp + ${CRU_WIN_NATIVE_INCLUDE_DIR}/platform_id.hpp + ${CRU_WIN_NATIVE_INCLUDE_DIR}/ui_application.hpp ${CRU_WIN_NATIVE_INCLUDE_DIR}/window_class.hpp ${CRU_WIN_NATIVE_INCLUDE_DIR}/window_native_message_event_args.hpp ${CRU_WIN_NATIVE_INCLUDE_DIR}/window_render_target.hpp ) -target_link_libraries(cru_win_native PUBLIC cru_win_graph) +target_link_libraries(cru_win_native PUBLIC cru_win_graph_direct) diff --git a/src/win/native/dpi_util.hpp b/src/win/native/dpi_util.hpp index d459e8c6..a642fd79 100644 --- a/src/win/native/dpi_util.hpp +++ b/src/win/native/dpi_util.hpp @@ -5,7 +5,7 @@ // The dpi awareness needs to be implemented in the future. Currently we use 96 // as default. -namespace cru::win::native { +namespace cru::platform::native::win { inline platform::native::Dpi GetDpi() { return platform::native::Dpi{96.0f, 96.0f}; } @@ -33,4 +33,4 @@ inline float PixelToDipX(const int pixel_x) { inline float PixelToDipY(const int pixel_y) { return DipToPixelInternal(pixel_y, GetDpi().y); } -} // namespace cru::win::native +} // namespace cru::platform::native::win diff --git a/src/win/native/god_window.cpp b/src/win/native/god_window.cpp index 58fb663c..5f1d7b53 100644 --- a/src/win/native/god_window.cpp +++ b/src/win/native/god_window.cpp @@ -1,17 +1,17 @@ #include "cru/win/native/god_window.hpp" -#include "cru/win/exception.hpp" -#include "cru/win/native/win_application.hpp" +#include "cru/win/native/exception.hpp" +#include "cru/win/native/ui_application.hpp" #include "cru/win/native/window_class.hpp" #include "god_window_message.hpp" #include "timer.hpp" -namespace cru::win::native { +namespace cru::platform::native::win { constexpr auto god_window_class_name = L"GodWindowClass"; LRESULT CALLBACK GodWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - const auto app = WinApplication::GetInstance(); + const auto app = WinUiApplication::GetInstance(); if (app) { LRESULT result; @@ -25,7 +25,7 @@ LRESULT CALLBACK GodWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, return DefWindowProcW(hWnd, uMsg, wParam, lParam); } -GodWindow::GodWindow(WinApplication* application) { +GodWindow::GodWindow(WinUiApplication* application) { application_ = application; const auto h_instance = application->GetInstanceHandle(); @@ -70,4 +70,4 @@ bool GodWindow::HandleGodWindowMessage(HWND hwnd, UINT msg, WPARAM w_param, } return false; } -} // namespace cru::win::native +} // namespace cru::platform::native::win diff --git a/src/win/native/god_window_message.hpp b/src/win/native/god_window_message.hpp index 10268625..591270d9 100644 --- a/src/win/native/god_window_message.hpp +++ b/src/win/native/god_window_message.hpp @@ -1,6 +1,6 @@ #pragma once #include "cru/win/win_pre_config.hpp" -namespace cru::win::native { +namespace cru::platform::native::win { constexpr int invoke_later_message_id = WM_USER + 2000; } diff --git a/src/win/native/native_window.cpp b/src/win/native/native_window.cpp new file mode 100644 index 00000000..fd29f9c5 --- /dev/null +++ b/src/win/native/native_window.cpp @@ -0,0 +1,340 @@ +#include "cru/win/native/native_window.hpp" + +#include "cru/win/graph/direct/graph_factory.hpp" +#include "cru/win/native/exception.hpp" +#include "cru/win/native/ui_application.hpp" +#include "cru/win/native/window_class.hpp" +#include "cru/win/native/window_render_target.hpp" +#include "dpi_util.hpp" +#include "window_d2d_painter.hpp" +#include "window_manager.hpp" + +#include +#include + +namespace cru::platform::native::win { +WinNativeWindow::WinNativeWindow(WinUiApplication* application, + std::shared_ptr window_class, + DWORD window_style, WinNativeWindow* parent) { + assert(application); // application can't be null. + assert(parent == nullptr || + parent->IsValid()); // Parent window is not valid. + + application_ = application; + parent_window_ = parent; + + const auto window_manager = application->GetWindowManager(); + + hwnd_ = CreateWindowExW( + 0, window_manager->GetGeneralWindowClass()->GetName(), L"", window_style, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + parent == nullptr ? nullptr : parent->GetWindowHandle(), nullptr, + application->GetInstanceHandle(), nullptr); + + if (hwnd_ == nullptr) + throw Win32Error(::GetLastError(), "Failed to create window."); + + window_manager->RegisterWindow(hwnd_, this); + + window_render_target_.reset( + new WindowRenderTarget(graph::win::direct::DirectGraphFactory::GetInstance(), hwnd_)); +} + +WinNativeWindow::~WinNativeWindow() { + if (IsValid()) { + SetDeleteThisOnDestroy(false); // avoid double delete. + Close(); + } +} + +bool WinNativeWindow::IsValid() { return hwnd_ != nullptr; } + +void WinNativeWindow::SetDeleteThisOnDestroy(bool value) { + delete_this_on_destroy_ = value; +} + +void WinNativeWindow::Close() { + if (IsValid()) DestroyWindow(hwnd_); +} + +bool WinNativeWindow::IsVisible() { + if (IsValid()) return ::IsWindowVisible(hwnd_); + return false; +} + +void WinNativeWindow::SetVisible(bool is_visible) { + if (!IsValid()) return; + is_visible ? ShowWindow(hwnd_, SW_SHOWNORMAL) : ShowWindow(hwnd_, SW_HIDE); +} +Size WinNativeWindow::GetClientSize() { + if (!IsValid()) return Size{}; + + const auto pixel_rect = GetClientRectPixel(); + return Size(PixelToDipX(pixel_rect.right), + PixelToDipY(pixel_rect.bottom)); +} + +void WinNativeWindow::SetClientSize(const Size& size) { + if (IsValid()) { + const auto window_style = + static_cast(GetWindowLongPtr(hwnd_, GWL_STYLE)); + const auto window_ex_style = + static_cast(GetWindowLongPtr(hwnd_, GWL_EXSTYLE)); + + RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = DipToPixelX(size.width); + rect.bottom = DipToPixelY(size.height); + if (!AdjustWindowRectEx(&rect, window_style, FALSE, window_ex_style)) + throw Win32Error(::GetLastError(), + "Failed to invoke AdjustWindowRectEx."); + + if (!SetWindowPos(hwnd_, nullptr, 0, 0, rect.right - rect.left, + rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE)) + throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos."); + } +} + +Rect WinNativeWindow::GetWindowRect() { + if (!IsValid()) return Rect{}; + + RECT rect; + if (!::GetWindowRect(hwnd_, &rect)) + throw Win32Error(::GetLastError(), "Failed to invoke GetWindowRect."); + + return Rect::FromVertices(PixelToDipX(rect.left), PixelToDipY(rect.top), + PixelToDipX(rect.right), + PixelToDipY(rect.bottom)); +} + +void WinNativeWindow::SetWindowRect(const Rect& rect) { + if (IsValid()) { + if (!SetWindowPos(hwnd_, nullptr, DipToPixelX(rect.left), + DipToPixelY(rect.top), DipToPixelX(rect.GetRight()), + DipToPixelY(rect.GetBottom()), SWP_NOZORDER)) + throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos."); + } +} + +graph::Painter* WinNativeWindow::BeginPaint() { + return new WindowD2DPainter(this); +} + +bool WinNativeWindow::HandleNativeWindowMessage(HWND hwnd, UINT msg, + WPARAM w_param, LPARAM l_param, + LRESULT* result) { + WindowNativeMessageEventArgs args{ + WindowNativeMessage{hwnd, msg, w_param, l_param}}; + native_message_event_.Raise(args); + if (args.IsHandled()) { + *result = args.GetResult(); + return true; + } + + switch (msg) { + case WM_PAINT: + OnPaintInternal(); + *result = 0; + return true; + case WM_ERASEBKGND: + *result = 1; + return true; + case WM_SETFOCUS: + OnSetFocusInternal(); + *result = 0; + return true; + case WM_KILLFOCUS: + OnKillFocusInternal(); + *result = 0; + return true; + case WM_MOUSEMOVE: { + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + OnMouseMoveInternal(point); + *result = 0; + return true; + } + case WM_LBUTTONDOWN: { + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + OnMouseDownInternal(platform::native::MouseButton::Left, point); + *result = 0; + return true; + } + case WM_LBUTTONUP: { + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + OnMouseUpInternal(platform::native::MouseButton::Left, point); + *result = 0; + return true; + } + case WM_RBUTTONDOWN: { + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + OnMouseDownInternal(platform::native::MouseButton::Right, point); + *result = 0; + return true; + } + case WM_RBUTTONUP: { + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + OnMouseUpInternal(platform::native::MouseButton::Right, point); + *result = 0; + return true; + } + case WM_MBUTTONDOWN: { + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + OnMouseDownInternal(platform::native::MouseButton::Middle, point); + *result = 0; + return true; + } + case WM_MBUTTONUP: { + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + OnMouseUpInternal(platform::native::MouseButton::Middle, point); + *result = 0; + return true; + } + case WM_MOUSEWHEEL: + POINT point; + point.x = GET_X_LPARAM(l_param); + point.y = GET_Y_LPARAM(l_param); + ScreenToClient(hwnd, &point); + OnMouseWheelInternal(GET_WHEEL_DELTA_WPARAM(w_param), point); + *result = 0; + return true; + case WM_KEYDOWN: + OnKeyDownInternal(static_cast(w_param)); + *result = 0; + return true; + case WM_KEYUP: + OnKeyUpInternal(static_cast(w_param)); + *result = 0; + return true; + case WM_CHAR: + OnCharInternal(static_cast(w_param)); + *result = 0; + return true; + case WM_SIZE: + OnResizeInternal(LOWORD(l_param), HIWORD(l_param)); + *result = 0; + return true; + case WM_ACTIVATE: + if (w_param == WA_ACTIVE || w_param == WA_CLICKACTIVE) + OnActivatedInternal(); + else if (w_param == WA_INACTIVE) + OnDeactivatedInternal(); + *result = 0; + return true; + case WM_DESTROY: + OnDestroyInternal(); + *result = 0; + return true; + default: + return false; + } +} + +RECT WinNativeWindow::GetClientRectPixel() { + RECT rect; + if (!GetClientRect(hwnd_, &rect)) + throw Win32Error(::GetLastError(), "Failed to invoke GetClientRect."); + return rect; +} + +void WinNativeWindow::OnDestroyInternal() { + application_->GetWindowManager()->UnregisterWindow(hwnd_); + hwnd_ = nullptr; + destroy_event_.Raise(nullptr); + if (delete_this_on_destroy_) + application_->InvokeLater([this] { delete this; }); +} + +void WinNativeWindow::OnPaintInternal() { + paint_event_.Raise(nullptr); + ValidateRect(hwnd_, nullptr); +} + +void WinNativeWindow::OnResizeInternal(const int new_width, + const int new_height) { + if (!(new_width == 0 && new_height == 0)) { + window_render_target_->ResizeBuffer(new_width, new_height); + resize_event_.Raise( + Size{PixelToDipX(new_width), PixelToDipY(new_height)}); + } +} + +void WinNativeWindow::OnSetFocusInternal() { + has_focus_ = true; + focus_event_.Raise(true); +} + +void WinNativeWindow::OnKillFocusInternal() { + has_focus_ = false; + focus_event_.Raise(false); +} + +inline Point PiToDip(const POINT& pi_point) { + return Point(PixelToDipX(pi_point.x), PixelToDipY(pi_point.y)); +} + +void WinNativeWindow::OnMouseMoveInternal(const POINT point) { + // when mouse was previous outside the window + if (!is_mouse_in_) { + // invoke TrackMouseEvent to have WM_MOUSELEAVE sent. + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof tme; + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd_; + + TrackMouseEvent(&tme); + + is_mouse_in_ = true; + mouse_enter_leave_event_.Raise(true); + } + + mouse_move_event_.Raise(PiToDip(point)); +} + +void WinNativeWindow::OnMouseLeaveInternal() { + is_mouse_in_ = false; + mouse_enter_leave_event_.Raise(false); +} + +void WinNativeWindow::OnMouseDownInternal(platform::native::MouseButton button, + POINT point) { + const auto dip_point = PiToDip(point); + mouse_down_event_.Raise({button, dip_point}); +} + +void WinNativeWindow::OnMouseUpInternal(platform::native::MouseButton button, + POINT point) { + const auto dip_point = PiToDip(point); + mouse_up_event_.Raise({button, dip_point}); +} + +void WinNativeWindow::OnMouseWheelInternal(short delta, POINT point) {} + +void WinNativeWindow::OnKeyDownInternal(int virtual_code) { + key_down_event_.Raise(virtual_code); +} + +void WinNativeWindow::OnKeyUpInternal(int virtual_code) { + key_up_event_.Raise(virtual_code); +} + +void WinNativeWindow::OnCharInternal(wchar_t c) {} + +void WinNativeWindow::OnActivatedInternal() {} + +void WinNativeWindow::OnDeactivatedInternal() {} +} // namespace cru::platform::native::win diff --git a/src/win/native/timer.cpp b/src/win/native/timer.cpp index 9e3bbde6..ed2ae069 100644 --- a/src/win/native/timer.cpp +++ b/src/win/native/timer.cpp @@ -1,6 +1,6 @@ #include "timer.hpp" -namespace cru::win::native { +namespace cru::platform::native::win { TimerManager::TimerManager(GodWindow* god_window) { god_window_ = god_window; } UINT_PTR TimerManager::CreateTimer(const UINT milliseconds, const bool loop, @@ -25,4 +25,4 @@ std::optional> TimerManager::GetAction( if (find_result == map_.cend()) return std::nullopt; return find_result->second; } -} // namespace cru::win::native +} // namespace cru::platform::native::win diff --git a/src/win/native/timer.hpp b/src/win/native/timer.hpp index f30d9b91..08749768 100644 --- a/src/win/native/timer.hpp +++ b/src/win/native/timer.hpp @@ -9,7 +9,7 @@ #include #include -namespace cru::win::native { +namespace cru::platform::native::win { using TimerAction = std::function; class TimerManager : public Object { diff --git a/src/win/native/ui_application.cpp b/src/win/native/ui_application.cpp new file mode 100644 index 00000000..360f6e41 --- /dev/null +++ b/src/win/native/ui_application.cpp @@ -0,0 +1,121 @@ +#include "cru/win/native/ui_application.hpp" + +#include "cru/win/graph/direct/graph_factory.hpp" +#include "cru/win/native/exception.hpp" +#include "cru/win/native/god_window.hpp" +#include "cru/win/native/native_window.hpp" +#include "god_window_message.hpp" +#include "timer.hpp" +#include "window_manager.hpp" + +#include +#include + +namespace cru::platform::native::win { +namespace { +WinUiApplication* instance = nullptr; +} +} // namespace cru::platform::native::win + +namespace cru::platform::native { +UiApplication* UiApplication::CreateInstance() { + auto& i = + ::cru::platform::native::win::instance; // avoid long namespace prefix + assert(i == nullptr); + i = new win::WinUiApplication(::GetModuleHandleW(nullptr)); + return i; +} + +UiApplication* UiApplication::GetInstance() { + return ::cru::platform::native::win::instance; +} +} // namespace cru::platform::native + +namespace cru::platform::native::win { +WinUiApplication* WinUiApplication::GetInstance() { return instance; } + +WinUiApplication::WinUiApplication(HINSTANCE h_instance) + : h_instance_(h_instance) { + assert(instance == nullptr); + + if (!::IsWindows8OrGreater()) + throw std::runtime_error("Must run on Windows 8 or later."); + + const auto graph_factory = graph::GraphFactory::CreateInstance(); + graph_factory->SetAutoDelete(true); + + god_window_ = std::make_shared(this); + timer_manager_ = std::make_shared(god_window_.get()); + window_manager_ = std::make_shared(this); +} + +WinUiApplication::~WinUiApplication() { instance = nullptr; } + +int WinUiApplication::Run() { + MSG msg; + while (GetMessageW(&msg, nullptr, 0, 0)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + for (const auto& handler : quit_handlers_) handler(); + + if (auto_delete_) delete this; + + return static_cast(msg.wParam); +} + +void WinUiApplication::Quit(const int quit_code) { + ::PostQuitMessage(quit_code); +} + +void WinUiApplication::AddOnQuitHandler(const std::function& handler) { + quit_handlers_.push_back(handler); +} + +void WinUiApplication::InvokeLater(const std::function& action) { + // copy the action to a safe place + auto p_action_copy = new std::function(action); + + if (PostMessageW(GetGodWindow()->GetHandle(), invoke_later_message_id, + reinterpret_cast(p_action_copy), 0) == 0) + throw Win32Error(::GetLastError(), "InvokeLater failed to post message."); +} + +unsigned long WinUiApplication::SetTimeout( + std::chrono::milliseconds milliseconds, + const std::function& action) { + return static_cast(timer_manager_->CreateTimer( + static_cast(milliseconds.count()), false, action)); +} + +unsigned long WinUiApplication::SetInterval( + std::chrono::milliseconds milliseconds, + const std::function& action) { + return static_cast(timer_manager_->CreateTimer( + static_cast(milliseconds.count()), true, action)); +} + +void WinUiApplication::CancelTimer(unsigned long id) { + timer_manager_->KillTimer(static_cast(id)); +} + +std::vector WinUiApplication::GetAllWindow() { + const auto&& windows = window_manager_->GetAllWindows(); + std::vector result; + for (const auto w : windows) { + result.push_back(static_cast(w)); + } + return result; +} + +NativeWindow* WinUiApplication::CreateWindow(NativeWindow* parent) { + WinNativeWindow* p = nullptr; + if (parent != nullptr) { + p = dynamic_cast(parent); + assert(p); + } + return new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(), + WS_OVERLAPPEDWINDOW, p); +} +} // namespace cru::platform::native::win diff --git a/src/win/native/win_application.cpp b/src/win/native/win_application.cpp deleted file mode 100644 index 586af331..00000000 --- a/src/win/native/win_application.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "cru/win/native/win_application.hpp" - -#include "cru/win/exception.hpp" -#include "cru/win/graph/win_graph_factory.hpp" -#include "cru/win/native/god_window.hpp" -#include "cru/win/native/win_native_window.hpp" -#include "god_window_message.hpp" -#include "timer.hpp" -#include "window_manager.hpp" - -#include -#include - -namespace cru::win::native { -namespace { -WinApplication* instance = nullptr; -} -} // namespace cru::win::native - -namespace cru::platform::native { -IUiApplication* IUiApplication::CreateInstance() { - auto& i = ::cru::win::native::instance; // avoid long namespace prefix - assert(i == nullptr); - i = new win::native::WinApplication(::GetModuleHandleW(nullptr)); - return i; -} - -IUiApplication* IUiApplication::GetInstance() { - return ::cru::win::native::instance; -} -} // namespace cru::platform::native - -namespace cru::win::native { -WinApplication* WinApplication::GetInstance() { return instance; } - -WinApplication::WinApplication(HINSTANCE h_instance) : h_instance_(h_instance) { - assert(instance == nullptr); - - if (!::IsWindows8OrGreater()) - throw std::runtime_error("Must run on Windows 8 or later."); - - const auto graph_factory = platform::graph::IGraphFactory::CreateInstance(); - graph_factory->SetAutoDelete(true); - - god_window_ = std::make_shared(this); - timer_manager_ = std::make_shared(god_window_.get()); - window_manager_ = std::make_shared(this); -} - -WinApplication::~WinApplication() { instance = nullptr; } - -int WinApplication::Run() { - MSG msg; - while (GetMessageW(&msg, nullptr, 0, 0)) { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - - for (const auto& handler : quit_handlers_) handler(); - - if (auto_delete_) delete this; - - return static_cast(msg.wParam); -} - -void WinApplication::Quit(const int quit_code) { ::PostQuitMessage(quit_code); } - -void WinApplication::AddOnQuitHandler(const std::function& handler) { - quit_handlers_.push_back(handler); -} - -void WinApplication::InvokeLater(const std::function& action) { - // copy the action to a safe place - auto p_action_copy = new std::function(action); - - if (PostMessageW(GetGodWindow()->GetHandle(), invoke_later_message_id, - reinterpret_cast(p_action_copy), 0) == 0) - throw Win32Error(::GetLastError(), "InvokeLater failed to post message."); -} - -unsigned long WinApplication::SetTimeout(std::chrono::milliseconds milliseconds, - const std::function& action) { - return static_cast(timer_manager_->CreateTimer( - static_cast(milliseconds.count()), false, action)); -} - -unsigned long WinApplication::SetInterval( - std::chrono::milliseconds milliseconds, - const std::function& action) { - return static_cast(timer_manager_->CreateTimer( - static_cast(milliseconds.count()), true, action)); -} - -void WinApplication::CancelTimer(unsigned long id) { - timer_manager_->KillTimer(static_cast(id)); -} - -std::vector WinApplication::GetAllWindow() { - const auto&& windows = window_manager_->GetAllWindows(); - std::vector result; - for (const auto w : windows) { - result.push_back(static_cast(w)); - } - return result; -} - -platform::native::INativeWindow* WinApplication::CreateWindow( - platform::native::INativeWindow* parent) { - WinNativeWindow* p = nullptr; - if (parent != nullptr) { - p = dynamic_cast(parent); - assert(p); - } - return new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(), - WS_OVERLAPPEDWINDOW, p); -} -} // namespace cru::win::native diff --git a/src/win/native/win_native_window.cpp b/src/win/native/win_native_window.cpp deleted file mode 100644 index 9ca37321..00000000 --- a/src/win/native/win_native_window.cpp +++ /dev/null @@ -1,340 +0,0 @@ -#include "cru/win/native/win_native_window.hpp" - -#include "cru/win/exception.hpp" -#include "cru/win/graph/win_graph_factory.hpp" -#include "cru/win/native/win_application.hpp" -#include "cru/win/native/window_class.hpp" -#include "cru/win/native/window_render_target.hpp" -#include "dpi_util.hpp" -#include "window_manager.hpp" -#include "window_painter.hpp" - -#include -#include - -namespace cru::win::native { -WinNativeWindow::WinNativeWindow(WinApplication* application, - std::shared_ptr window_class, - DWORD window_style, WinNativeWindow* parent) { - assert(application); // application can't be null. - assert(parent == nullptr || - parent->IsValid()); // Parent window is not valid. - - application_ = application; - parent_window_ = parent; - - const auto window_manager = application->GetWindowManager(); - - hwnd_ = CreateWindowExW( - 0, window_manager->GetGeneralWindowClass()->GetName(), L"", window_style, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - parent == nullptr ? nullptr : parent->GetWindowHandle(), nullptr, - application->GetInstanceHandle(), nullptr); - - if (hwnd_ == nullptr) - throw Win32Error(::GetLastError(), "Failed to create window."); - - window_manager->RegisterWindow(hwnd_, this); - - window_render_target_.reset( - new WindowRenderTarget(graph::WinGraphFactory::GetInstance(), hwnd_)); -} - -WinNativeWindow::~WinNativeWindow() { - if (IsValid()) { - SetDeleteThisOnDestroy(false); // avoid double delete. - Close(); - } -} - -bool WinNativeWindow::IsValid() { return hwnd_ != nullptr; } - -void WinNativeWindow::SetDeleteThisOnDestroy(bool value) { - delete_this_on_destroy_ = value; -} - -void WinNativeWindow::Close() { - if (IsValid()) DestroyWindow(hwnd_); -} - -bool WinNativeWindow::IsVisible() { - if (IsValid()) return ::IsWindowVisible(hwnd_); - return false; -} - -void WinNativeWindow::SetVisible(bool is_visible) { - if (!IsValid()) return; - is_visible ? ShowWindow(hwnd_, SW_SHOWNORMAL) : ShowWindow(hwnd_, SW_HIDE); -} -ui::Size WinNativeWindow::GetClientSize() { - if (!IsValid()) return ui::Size{}; - - const auto pixel_rect = GetClientRectPixel(); - return ui::Size(PixelToDipX(pixel_rect.right), - PixelToDipY(pixel_rect.bottom)); -} - -void WinNativeWindow::SetClientSize(const ui::Size& size) { - if (IsValid()) { - const auto window_style = - static_cast(GetWindowLongPtr(hwnd_, GWL_STYLE)); - const auto window_ex_style = - static_cast(GetWindowLongPtr(hwnd_, GWL_EXSTYLE)); - - RECT rect; - rect.left = 0; - rect.top = 0; - rect.right = DipToPixelX(size.width); - rect.bottom = DipToPixelY(size.height); - if (!AdjustWindowRectEx(&rect, window_style, FALSE, window_ex_style)) - throw Win32Error(::GetLastError(), - "Failed to invoke AdjustWindowRectEx."); - - if (!SetWindowPos(hwnd_, nullptr, 0, 0, rect.right - rect.left, - rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE)) - throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos."); - } -} - -ui::Rect WinNativeWindow::GetWindowRect() { - if (!IsValid()) return ui::Rect{}; - - RECT rect; - if (!::GetWindowRect(hwnd_, &rect)) - throw Win32Error(::GetLastError(), "Failed to invoke GetWindowRect."); - - return ui::Rect::FromVertices(PixelToDipX(rect.left), PixelToDipY(rect.top), - PixelToDipX(rect.right), - PixelToDipY(rect.bottom)); -} - -void WinNativeWindow::SetWindowRect(const ui::Rect& rect) { - if (IsValid()) { - if (!SetWindowPos(hwnd_, nullptr, DipToPixelX(rect.left), - DipToPixelY(rect.top), DipToPixelX(rect.GetRight()), - DipToPixelY(rect.GetBottom()), SWP_NOZORDER)) - throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos."); - } -} - -platform::graph::IPainter* WinNativeWindow::BeginPaint() { - return new WindowPainter(this); -} - -bool WinNativeWindow::HandleNativeWindowMessage(HWND hwnd, UINT msg, - WPARAM w_param, LPARAM l_param, - LRESULT* result) { - WindowNativeMessageEventArgs args{ - WindowNativeMessage{hwnd, msg, w_param, l_param}}; - native_message_event_.Raise(args); - if (args.IsHandled()) { - *result = args.GetResult(); - return true; - } - - switch (msg) { - case WM_PAINT: - OnPaintInternal(); - *result = 0; - return true; - case WM_ERASEBKGND: - *result = 1; - return true; - case WM_SETFOCUS: - OnSetFocusInternal(); - *result = 0; - return true; - case WM_KILLFOCUS: - OnKillFocusInternal(); - *result = 0; - return true; - case WM_MOUSEMOVE: { - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - OnMouseMoveInternal(point); - *result = 0; - return true; - } - case WM_LBUTTONDOWN: { - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - OnMouseDownInternal(platform::native::MouseButton::Left, point); - *result = 0; - return true; - } - case WM_LBUTTONUP: { - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - OnMouseUpInternal(platform::native::MouseButton::Left, point); - *result = 0; - return true; - } - case WM_RBUTTONDOWN: { - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - OnMouseDownInternal(platform::native::MouseButton::Right, point); - *result = 0; - return true; - } - case WM_RBUTTONUP: { - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - OnMouseUpInternal(platform::native::MouseButton::Right, point); - *result = 0; - return true; - } - case WM_MBUTTONDOWN: { - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - OnMouseDownInternal(platform::native::MouseButton::Middle, point); - *result = 0; - return true; - } - case WM_MBUTTONUP: { - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - OnMouseUpInternal(platform::native::MouseButton::Middle, point); - *result = 0; - return true; - } - case WM_MOUSEWHEEL: - POINT point; - point.x = GET_X_LPARAM(l_param); - point.y = GET_Y_LPARAM(l_param); - ScreenToClient(hwnd, &point); - OnMouseWheelInternal(GET_WHEEL_DELTA_WPARAM(w_param), point); - *result = 0; - return true; - case WM_KEYDOWN: - OnKeyDownInternal(static_cast(w_param)); - *result = 0; - return true; - case WM_KEYUP: - OnKeyUpInternal(static_cast(w_param)); - *result = 0; - return true; - case WM_CHAR: - OnCharInternal(static_cast(w_param)); - *result = 0; - return true; - case WM_SIZE: - OnResizeInternal(LOWORD(l_param), HIWORD(l_param)); - *result = 0; - return true; - case WM_ACTIVATE: - if (w_param == WA_ACTIVE || w_param == WA_CLICKACTIVE) - OnActivatedInternal(); - else if (w_param == WA_INACTIVE) - OnDeactivatedInternal(); - *result = 0; - return true; - case WM_DESTROY: - OnDestroyInternal(); - *result = 0; - return true; - default: - return false; - } -} - -RECT WinNativeWindow::GetClientRectPixel() { - RECT rect; - if (!GetClientRect(hwnd_, &rect)) - throw Win32Error(::GetLastError(), "Failed to invoke GetClientRect."); - return rect; -} - -void WinNativeWindow::OnDestroyInternal() { - application_->GetWindowManager()->UnregisterWindow(hwnd_); - hwnd_ = nullptr; - destroy_event_.Raise(nullptr); - if (delete_this_on_destroy_) - application_->InvokeLater([this] { delete this; }); -} - -void WinNativeWindow::OnPaintInternal() { - paint_event_.Raise(nullptr); - ValidateRect(hwnd_, nullptr); -} - -void WinNativeWindow::OnResizeInternal(const int new_width, - const int new_height) { - if (!(new_width == 0 && new_height == 0)) { - window_render_target_->ResizeBuffer(new_width, new_height); - resize_event_.Raise( - ui::Size{PixelToDipX(new_width), PixelToDipY(new_height)}); - } -} - -void WinNativeWindow::OnSetFocusInternal() { - has_focus_ = true; - focus_event_.Raise(true); -} - -void WinNativeWindow::OnKillFocusInternal() { - has_focus_ = false; - focus_event_.Raise(false); -} - -inline ui::Point PiToDip(const POINT& pi_point) { - return ui::Point(PixelToDipX(pi_point.x), PixelToDipY(pi_point.y)); -} - -void WinNativeWindow::OnMouseMoveInternal(const POINT point) { - // when mouse was previous outside the window - if (!is_mouse_in_) { - // invoke TrackMouseEvent to have WM_MOUSELEAVE sent. - TRACKMOUSEEVENT tme; - tme.cbSize = sizeof tme; - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwnd_; - - TrackMouseEvent(&tme); - - is_mouse_in_ = true; - mouse_enter_leave_event_.Raise(true); - } - - mouse_move_event_.Raise(PiToDip(point)); -} - -void WinNativeWindow::OnMouseLeaveInternal() { - is_mouse_in_ = false; - mouse_enter_leave_event_.Raise(false); -} - -void WinNativeWindow::OnMouseDownInternal(platform::native::MouseButton button, - POINT point) { - const auto dip_point = PiToDip(point); - mouse_down_event_.Raise({button, dip_point}); -} - -void WinNativeWindow::OnMouseUpInternal(platform::native::MouseButton button, - POINT point) { - const auto dip_point = PiToDip(point); - mouse_up_event_.Raise({button, dip_point}); -} - -void WinNativeWindow::OnMouseWheelInternal(short delta, POINT point) {} - -void WinNativeWindow::OnKeyDownInternal(int virtual_code) { - key_down_event_.Raise(virtual_code); -} - -void WinNativeWindow::OnKeyUpInternal(int virtual_code) { - key_up_event_.Raise(virtual_code); -} - -void WinNativeWindow::OnCharInternal(wchar_t c) {} - -void WinNativeWindow::OnActivatedInternal() {} - -void WinNativeWindow::OnDeactivatedInternal() {} -} // namespace cru::win::native diff --git a/src/win/native/window_class.cpp b/src/win/native/window_class.cpp index 6c7d0d3d..d69160ab 100644 --- a/src/win/native/window_class.cpp +++ b/src/win/native/window_class.cpp @@ -1,8 +1,8 @@ #include "cru/win/native/window_class.hpp" -#include "cru/win/exception.hpp" +#include "cru/win/native/exception.hpp" -namespace cru::win::native { +namespace cru::platform::native::win { WindowClass::WindowClass(const std::wstring& name, WNDPROC window_proc, HINSTANCE h_instance) : name_(name) { @@ -25,4 +25,4 @@ WindowClass::WindowClass(const std::wstring& name, WNDPROC window_proc, if (atom_ == 0) throw Win32Error(::GetLastError(), "Failed to create window class."); } -} // namespace cru::win::native +} // namespace cru::platform::native::win diff --git a/src/win/native/window_d2d_painter.cpp b/src/win/native/window_d2d_painter.cpp new file mode 100644 index 00000000..16d276ef --- /dev/null +++ b/src/win/native/window_d2d_painter.cpp @@ -0,0 +1,33 @@ +#include "window_d2d_painter.hpp" + +#include "cru/win/graph/direct/direct_factory.hpp" +#include "cru/win/graph/direct/exception.hpp" +#include "cru/win/native/window_render_target.hpp" + +#include + +namespace cru::platform::native::win { +using namespace cru::platform::graph::win::direct; + +WindowD2DPainter::WindowD2DPainter(WinNativeWindow* window) + : D2DPainter(window->GetWindowRenderTarget() + ->GetWinNativeFactory() + ->GetD2D1DeviceContext()), + window_(window) { + window->GetWindowRenderTarget()->SetAsTarget(); + window->GetWindowRenderTarget() + ->GetWinNativeFactory() + ->GetD2D1DeviceContext() + ->BeginDraw(); +} + +WindowD2DPainter::~WindowD2DPainter() { EndDraw(); } + +void WindowD2DPainter::DoEndDraw() { + ThrowIfFailed(window_->GetWindowRenderTarget() + ->GetWinNativeFactory() + ->GetD2D1DeviceContext() + ->EndDraw()); + window_->GetWindowRenderTarget()->Present(); +} +} // namespace cru::platform::native::win diff --git a/src/win/native/window_d2d_painter.hpp b/src/win/native/window_d2d_painter.hpp new file mode 100644 index 00000000..1c90e8ab --- /dev/null +++ b/src/win/native/window_d2d_painter.hpp @@ -0,0 +1,21 @@ +#pragma once +#include "cru/win/graph/direct/painter.hpp" +#include "cru/win/native/native_window.hpp" + +namespace cru::platform::native::win { +class WindowD2DPainter : public graph::win::direct::D2DPainter { + public: + explicit WindowD2DPainter(WinNativeWindow* window); + WindowD2DPainter(const WindowD2DPainter& other) = delete; + WindowD2DPainter& operator=(const WindowD2DPainter& other) = delete; + WindowD2DPainter(WindowD2DPainter&& other) = delete; + WindowD2DPainter& operator=(WindowD2DPainter&& other) = delete; + ~WindowD2DPainter() override; + + protected: + void DoEndDraw() override; + + private: + WinNativeWindow* window_; +}; +} // namespace cru::win::native diff --git a/src/win/native/window_manager.cpp b/src/win/native/window_manager.cpp index 5fea5a27..7f70d3cc 100644 --- a/src/win/native/window_manager.cpp +++ b/src/win/native/window_manager.cpp @@ -1,16 +1,16 @@ #include "window_manager.hpp" -#include "cru/win/native/win_application.hpp" -#include "cru/win/native/win_native_window.hpp" +#include "cru/win/native/ui_application.hpp" +#include "cru/win/native/native_window.hpp" #include "cru/win/native/window_class.hpp" #include -namespace cru::win::native { +namespace cru::platform::native::win { LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { auto window = - WinApplication::GetInstance()->GetWindowManager()->FromHandle(hWnd); + WinUiApplication::GetInstance()->GetWindowManager()->FromHandle(hWnd); LRESULT result; if (window != nullptr && @@ -20,15 +20,14 @@ LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam, return DefWindowProc(hWnd, Msg, wParam, lParam); } -WindowManager::WindowManager(WinApplication* application) { +WindowManager::WindowManager(WinUiApplication* application) { application_ = application; general_window_class_ = std::make_shared( L"CruUIWindowClass", GeneralWndProc, application->GetInstanceHandle()); } WindowManager::~WindowManager() { - for (const auto [key, window] : window_map_) - delete window; + for (const auto [key, window] : window_map_) delete window; } void WindowManager::RegisterWindow(HWND hwnd, WinNativeWindow* window) { @@ -56,4 +55,4 @@ std::vector WindowManager::GetAllWindows() const { for (auto [key, value] : window_map_) windows.push_back(value); return windows; } -} // namespace cru::win::native +} // namespace cru::platform::native::win diff --git a/src/win/native/window_manager.hpp b/src/win/native/window_manager.hpp index 8fab9cfc..a0661556 100644 --- a/src/win/native/window_manager.hpp +++ b/src/win/native/window_manager.hpp @@ -7,14 +7,14 @@ #include #include -namespace cru::win::native { -class WinApplication; +namespace cru::platform::native::win { +class WinUiApplication; class WinNativeWindow; class WindowClass; class WindowManager : public Object { public: - WindowManager(WinApplication* application); + WindowManager(WinUiApplication* application); WindowManager(const WindowManager& other) = delete; WindowManager(WindowManager&& other) = delete; WindowManager& operator=(const WindowManager& other) = delete; @@ -43,7 +43,7 @@ class WindowManager : public Object { std::vector GetAllWindows() const; private: - WinApplication* application_; + WinUiApplication* application_; std::shared_ptr general_window_class_; std::map window_map_; diff --git a/src/win/native/window_painter.cpp b/src/win/native/window_painter.cpp deleted file mode 100644 index 463be128..00000000 --- a/src/win/native/window_painter.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "window_painter.hpp" - -#include "cru/win/exception.hpp" -#include "cru/win/graph/win_native_factory.hpp" -#include "cru/win/native/window_render_target.hpp" - -#include - -namespace cru::win::native { -WindowPainter::WindowPainter(WinNativeWindow* window) - : WinPainter(window->GetWindowRenderTarget() - ->GetWinNativeFactory() - ->GetD2D1DeviceContext()), - window_(window) { - window->GetWindowRenderTarget()->SetAsTarget(); - window->GetWindowRenderTarget() - ->GetWinNativeFactory() - ->GetD2D1DeviceContext() - ->BeginDraw(); -} - -WindowPainter::~WindowPainter() { End(); } - -void WindowPainter::DoEndDraw() { - ThrowIfFailed(window_->GetWindowRenderTarget() - ->GetWinNativeFactory() - ->GetD2D1DeviceContext() - ->EndDraw()); - window_->GetWindowRenderTarget()->Present(); -} -} // namespace cru::win::native diff --git a/src/win/native/window_painter.hpp b/src/win/native/window_painter.hpp deleted file mode 100644 index 78731ef3..00000000 --- a/src/win/native/window_painter.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include "cru/win/graph/win_painter.hpp" -#include "cru/win/native/win_native_window.hpp" - -namespace cru::win::native { -class WindowPainter : public graph::WinPainter { - public: - explicit WindowPainter(WinNativeWindow* window); - WindowPainter(const WindowPainter& other) = delete; - WindowPainter& operator=(const WindowPainter& other) = delete; - WindowPainter(WindowPainter&& other) = delete; - WindowPainter& operator=(WindowPainter&& other) = delete; - ~WindowPainter() override; - - protected: - void DoEndDraw() override; - - private: - WinNativeWindow* window_; -}; -} // namespace cru::win::native diff --git a/src/win/native/window_render_target.cpp b/src/win/native/window_render_target.cpp index 606b51f8..426afdf6 100644 --- a/src/win/native/window_render_target.cpp +++ b/src/win/native/window_render_target.cpp @@ -1,14 +1,14 @@ #include "cru/win/native/window_render_target.hpp" -#include "cru/win/exception.hpp" -#include "cru/win/graph/win_native_factory.hpp" +#include "cru/win/graph/direct/direct_factory.hpp" +#include "cru/win/graph/direct/exception.hpp" #include "dpi_util.hpp" #include -namespace cru::win::native { -WindowRenderTarget::WindowRenderTarget(graph::IWinNativeFactory* factory, - HWND hwnd) { +namespace cru::platform::native::win { +using namespace cru::platform::graph::win::direct; +WindowRenderTarget::WindowRenderTarget(IDirectFactory* factory, HWND hwnd) { this->factory_ = factory; const auto d3d11_device = factory->GetD3D11Device(); @@ -86,4 +86,4 @@ void WindowRenderTarget::CreateTargetBitmap() { ThrowIfFailed(factory_->GetD2D1DeviceContext()->CreateBitmapFromDxgiSurface( dxgi_back_buffer.Get(), &bitmap_properties, &target_bitmap_)); } -} // namespace cru::win::native +} // namespace cru::platform::native::win -- cgit v1.2.3