diff options
-rw-r--r-- | include/cru/platform/native_window.hpp | 2 | ||||
-rw-r--r-- | include/cru/platform/painter.hpp | 4 | ||||
-rw-r--r-- | include/cru/platform/win/win_brush.hpp | 10 | ||||
-rw-r--r-- | include/cru/platform/win/win_native_window.hpp | 2 | ||||
-rw-r--r-- | include/cru/platform/win/win_painter.hpp | 34 | ||||
-rw-r--r-- | src/platform_win/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/platform_win/win_native_window.cpp | 3 | ||||
-rw-r--r-- | src/platform_win/win_painter.cpp | 56 |
8 files changed, 109 insertions, 3 deletions
diff --git a/include/cru/platform/native_window.hpp b/include/cru/platform/native_window.hpp index 3a8e27ad..2daf4870 100644 --- a/include/cru/platform/native_window.hpp +++ b/include/cru/platform/native_window.hpp @@ -32,7 +32,7 @@ struct NativeWindow : public virtual Interface { // The lefttop of the rect is relative to screen lefttop. virtual void SetWindowRect(const ui::Rect& rect) = 0; - virtual Painter* BeginDraw() = 0; + virtual Painter* BeginPaint() = 0; virtual Event<>* DestroyEvent() = 0; virtual Event<ui::Size>* ResizeEvent() = 0; diff --git a/include/cru/platform/painter.hpp b/include/cru/platform/painter.hpp index 4ad09247..77ca5098 100644 --- a/include/cru/platform/painter.hpp +++ b/include/cru/platform/painter.hpp @@ -8,8 +8,10 @@ struct Brush; struct Geometry; struct Painter : virtual Interface { - virtual void StrokeGeometry(Geometry* geometry, Brush* brush, float width) = 0; + virtual void StrokeGeometry(Geometry* geometry, Brush* brush, + float width) = 0; virtual void FillGeometry(Geometry* geometry, Brush* brush) = 0; virtual void EndDraw() = 0; + virtual bool IsDisposed() = 0; }; } // namespace cru::platform diff --git a/include/cru/platform/win/win_brush.hpp b/include/cru/platform/win/win_brush.hpp index 2668215d..d32f6bbc 100644 --- a/include/cru/platform/win/win_brush.hpp +++ b/include/cru/platform/win/win_brush.hpp @@ -4,7 +4,13 @@ #include "../brush.hpp" namespace cru::platform::win { -class WinSolidColorBrush : public Object, public virtual SolidColorBrush { +struct WinBrush : virtual Brush { + virtual ID2D1Brush* GetD2DBrush() = 0; +}; + +class WinSolidColorBrush : public Object, + public virtual SolidColorBrush, + public virtual WinBrush { public: explicit WinSolidColorBrush( Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> brush); @@ -17,6 +23,8 @@ class WinSolidColorBrush : public Object, public virtual SolidColorBrush { ui::Color GetColor() override; void SetColor(const ui::Color& color) override; + ID2D1Brush* GetD2DBrush() override { return brush_.Get(); } + private: Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> brush_; }; diff --git a/include/cru/platform/win/win_native_window.hpp b/include/cru/platform/win/win_native_window.hpp index 8b787485..ae19c9f3 100644 --- a/include/cru/platform/win/win_native_window.hpp +++ b/include/cru/platform/win/win_native_window.hpp @@ -44,6 +44,8 @@ class WinNativeWindow : public Object, public virtual NativeWindow { // The lefttop of the rect is relative to screen lefttop. void SetWindowRect(const ui::Rect& rect) override; + Painter* BeginPaint() override; + Event<>* DestroyEvent() override { return &destroy_event_; } Event<ui::Size>* ResizeEvent() override { return &resize_event_; } Event<>* PaintEvent() override { return &paint_event_; } diff --git a/include/cru/platform/win/win_painter.hpp b/include/cru/platform/win/win_painter.hpp new file mode 100644 index 00000000..7b71ccbd --- /dev/null +++ b/include/cru/platform/win/win_painter.hpp @@ -0,0 +1,34 @@ +#pragma once +#include "win_pre_config.hpp" + +#include "../painter.hpp" + +namespace cru::platform::win { +class WinNativeWindow; + +class WinPainter : public Object, public virtual Painter { + public: + explicit WinPainter(WinNativeWindow* window); + WinPainter(const WinPainter& other) = delete; + WinPainter(WinPainter&& other) = delete; + WinPainter& operator=(const WinPainter& other) = delete; + WinPainter& operator=(WinPainter&& other) = delete; + ~WinPainter() override; + + void StrokeGeometry(Geometry* geometry, Brush* brush, float width) override; + void FillGeometry(Geometry* geometry, Brush* brush) override; + void EndDraw() override; + bool IsDisposed() override { return is_disposed; } + + void EndDrawAndDeleteThis() { + EndDraw(); + delete this; + } + + private: + WinNativeWindow* window_; + ID2D1RenderTarget* render_target_; + + bool is_disposed = false; +}; +} // namespace cru::platform::win diff --git a/src/platform_win/CMakeLists.txt b/src/platform_win/CMakeLists.txt index 40c9d85a..c8a5840e 100644 --- a/src/platform_win/CMakeLists.txt +++ b/src/platform_win/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(cru_platform_win STATIC win_geometry.cpp win_graph_factory.cpp win_native_window.cpp + win_painter.cpp window_class.cpp window_manager.cpp window_render_target.cpp) diff --git a/src/platform_win/win_native_window.cpp b/src/platform_win/win_native_window.cpp index 5c159290..ae740205 100644 --- a/src/platform_win/win_native_window.cpp +++ b/src/platform_win/win_native_window.cpp @@ -2,6 +2,7 @@ #include "cru/platform/win/exception.hpp" #include "cru/platform/win/win_application.hpp" +#include "cru/platform/win/win_painter.hpp" #include "cru/platform/win/window_class.hpp" #include "dpi_util.hpp" #include "window_manager.hpp" @@ -111,6 +112,8 @@ void WinNativeWindow::SetWindowRect(const ui::Rect& rect) { } } +Painter* WinNativeWindow::BeginPaint() { return new WinPainter(this); } + bool WinNativeWindow::HandleNativeWindowMessage(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, LRESULT* result) { diff --git a/src/platform_win/win_painter.cpp b/src/platform_win/win_painter.cpp new file mode 100644 index 00000000..29777669 --- /dev/null +++ b/src/platform_win/win_painter.cpp @@ -0,0 +1,56 @@ +#include "cru/platform/win/win_painter.hpp" + +#include "cru/platform/win/exception.hpp" +#include "cru/platform/win/graph_manager.hpp" +#include "cru/platform/win/win_brush.hpp" +#include "cru/platform/win/win_geometry.hpp" +#include "cru/platform/win/win_native_window.hpp" +#include "cru/platform/win/window_render_target.hpp" + +#include <cassert> + +namespace cru::platform::win { +WinPainter::WinPainter(WinNativeWindow* window) { + assert(window); + window_ = window; + const auto window_render_target = window_->GetWindowRenderTarget(); + render_target_ = + window_render_target->GetGraphManager()->GetD2D1DeviceContext(); + window_render_target->SetAsTarget(); + render_target_->BeginDraw(); +} + +WinPainter::~WinPainter() { + if (!IsDisposed()) { + ThrowIfFailed(render_target_->EndDraw()); + } +} + +void WinPainter::StrokeGeometry(Geometry* geometry, Brush* brush, float width) { + assert(!IsDisposed()); + const auto g = dynamic_cast<WinGeometry*>(geometry); + assert(g); + const auto b = dynamic_cast<WinBrush*>(brush); + assert(b); + + render_target_->DrawGeometry(g->GetNative(), b->GetD2DBrush(), width); +} + +void WinPainter::FillGeometry(Geometry* geometry, Brush* brush) { + assert(!IsDisposed()); + const auto g = dynamic_cast<WinGeometry*>(geometry); + assert(g); + const auto b = dynamic_cast<WinBrush*>(brush); + assert(b); + + render_target_->FillGeometry(g->GetNative(), b->GetD2DBrush()); +} + +void WinPainter::EndDraw() { + if (!IsDisposed()) { + ThrowIfFailed(render_target_->EndDraw()); + render_target_ = nullptr; + is_disposed = true; + } +} +} // namespace cru::platform::win |