diff options
Diffstat (limited to 'src/win')
| -rw-r--r-- | src/win/graph/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/win/graph/d2d_painter.cpp (renamed from src/win/graph/win_painter.cpp) | 32 | ||||
| -rw-r--r-- | src/win/graph/graph_manager.cpp | 6 | ||||
| -rw-r--r-- | src/win/graph/win_font.cpp | 2 | ||||
| -rw-r--r-- | src/win/native/win_application.cpp | 33 | ||||
| -rw-r--r-- | src/win/native/win_native_window.cpp | 1 | ||||
| -rw-r--r-- | src/win/native/window_manager.cpp | 5 | ||||
| -rw-r--r-- | src/win/native/window_manager.hpp | 2 | ||||
| -rw-r--r-- | src/win/native/window_painter.cpp | 13 | ||||
| -rw-r--r-- | src/win/native/window_painter.hpp | 6 | 
10 files changed, 63 insertions, 39 deletions
| diff --git a/src/win/graph/CMakeLists.txt b/src/win/graph/CMakeLists.txt index 7781e09a..61749a6a 100644 --- a/src/win/graph/CMakeLists.txt +++ b/src/win/graph/CMakeLists.txt @@ -1,9 +1,9 @@  add_library(cru_win_graph STATIC +	d2d_painter.cpp  	graph_manager.cpp  	win_brush.cpp  	win_font.cpp  	win_geometry.cpp  	win_graph_factory.cpp -	win_painter.cpp  	win_text_layout.cpp)  target_link_libraries(cru_win_graph PUBLIC D3D11 D2d1 DWrite cru_win_base) diff --git a/src/win/graph/win_painter.cpp b/src/win/graph/d2d_painter.cpp index 69ce1141..26f6bef0 100644 --- a/src/win/graph/win_painter.cpp +++ b/src/win/graph/d2d_painter.cpp @@ -1,4 +1,4 @@ -#include "cru/win/graph/win_painter.hpp" +#include "cru/win/graph/d2d_painter.hpp"  #include "cru/win/exception.hpp"  #include "cru/win/graph/d2d_util.hpp" @@ -10,31 +10,29 @@  #include <cassert>  namespace cru::win::graph { -WinPainter::WinPainter(ID2D1RenderTarget* render_target) { +D2DPainter::D2DPainter(ID2D1RenderTarget* render_target) {    assert(render_target);    render_target_ = render_target;  } -WinPainter::~WinPainter() { EndDraw(); } - -platform::Matrix WinPainter::GetTransform() { +platform::Matrix D2DPainter::GetTransform() {    assert(!IsDisposed());    D2D1_MATRIX_3X2_F m;    render_target_->GetTransform(&m);    return util::Convert(m);  } -void WinPainter::SetTransform(const platform::Matrix& matrix) { +void D2DPainter::SetTransform(const platform::Matrix& matrix) {    assert(!IsDisposed());    render_target_->SetTransform(util::Convert(matrix));  } -void WinPainter::Clear(const ui::Color& color) { +void D2DPainter::Clear(const ui::Color& color) {    assert(!IsDisposed());    render_target_->Clear(util::Convert(color));  } -void WinPainter::StrokeRectangle(const ui::Rect& rectangle, +void D2DPainter::StrokeRectangle(const ui::Rect& rectangle,                                   platform::graph::Brush* brush, float width) {    assert(!IsDisposed());    const auto b = dynamic_cast<WinBrush*>(brush); @@ -43,7 +41,7 @@ void WinPainter::StrokeRectangle(const ui::Rect& rectangle,                                  width);  } -void WinPainter::FillRectangle(const ui::Rect& rectangle, +void D2DPainter::FillRectangle(const ui::Rect& rectangle,                                 platform::graph::Brush* brush) {    assert(!IsDisposed());    const auto b = dynamic_cast<WinBrush*>(brush); @@ -51,7 +49,7 @@ void WinPainter::FillRectangle(const ui::Rect& rectangle,    render_target_->FillRectangle(util::Convert(rectangle), b->GetD2DBrush());  } -void WinPainter::StrokeGeometry(platform::graph::Geometry* geometry, +void D2DPainter::StrokeGeometry(platform::graph::Geometry* geometry,                                  platform::graph::Brush* brush, float width) {    assert(!IsDisposed());    const auto g = dynamic_cast<WinGeometry*>(geometry); @@ -62,7 +60,7 @@ void WinPainter::StrokeGeometry(platform::graph::Geometry* geometry,    render_target_->DrawGeometry(g->GetNative(), b->GetD2DBrush(), width);  } -void WinPainter::FillGeometry(platform::graph::Geometry* geometry, +void D2DPainter::FillGeometry(platform::graph::Geometry* geometry,                                platform::graph::Brush* brush) {    assert(!IsDisposed());    const auto g = dynamic_cast<WinGeometry*>(geometry); @@ -73,7 +71,7 @@ void WinPainter::FillGeometry(platform::graph::Geometry* geometry,    render_target_->FillGeometry(g->GetNative(), b->GetD2DBrush());  } -void WinPainter::DrawText(const ui::Point& offset, +void D2DPainter::DrawText(const ui::Point& offset,                            platform::graph::TextLayout* text_layout,                            platform::graph::Brush* brush) {    assert(!IsDisposed()); @@ -86,14 +84,10 @@ void WinPainter::DrawText(const ui::Point& offset,                                   t->GetDWriteTextLayout(), b->GetD2DBrush());  } -void WinPainter::EndDraw() { -  if (!IsDisposed()) { +void D2DPainter::EndDraw() { +  if (!is_disposed_) { +    is_disposed_ = true;      DoEndDraw();    }  } - -void WinPainter::DoEndDraw() { -  ThrowIfFailed(render_target_->EndDraw()); -  is_disposed_ = true; -}  }  // namespace cru::win::graph diff --git a/src/win/graph/graph_manager.cpp b/src/win/graph/graph_manager.cpp index a4306b1b..30e1a14e 100644 --- a/src/win/graph/graph_manager.cpp +++ b/src/win/graph/graph_manager.cpp @@ -2,10 +2,12 @@  #include "cru/win/exception.hpp" +#include <cassert> +  namespace cru::win::graph {  GraphManager* GraphManager::GetInstance() { -  static GraphManager instance; -  return &instance; +  static GraphManager* instance = new GraphManager(); +  return instance;  }  GraphManager::GraphManager() { diff --git a/src/win/graph/win_font.cpp b/src/win/graph/win_font.cpp index 0eb5e6b2..96983d3e 100644 --- a/src/win/graph/win_font.cpp +++ b/src/win/graph/win_font.cpp @@ -13,7 +13,7 @@ WinFontDescriptor::WinFontDescriptor(GraphManager* graph_manager,                                       float font_size) {    assert(graph_manager);    std::array<wchar_t, LOCALE_NAME_MAX_LENGTH> buffer; -  if (!::GetUserDefaultLocaleName(buffer.data(), buffer.size())) +  if (!::GetUserDefaultLocaleName(buffer.data(), static_cast<int>(buffer.size())))      throw Win32Error(::GetLastError(), "Failed to get locale.");    ThrowIfFailed(graph_manager->GetDWriteFactory()->CreateTextFormat( diff --git a/src/win/native/win_application.cpp b/src/win/native/win_application.cpp index 72e12fa0..6c39453f 100644 --- a/src/win/native/win_application.cpp +++ b/src/win/native/win_application.cpp @@ -1,6 +1,7 @@  #include "cru/win/native/win_application.hpp"  #include "cru/win/exception.hpp" +#include "cru/win/graph/graph_manager.hpp"  #include "cru/win/native/god_window.hpp"  #include "cru/win/native/win_native_window.hpp"  #include "god_window_message.hpp" @@ -17,19 +18,22 @@ UiApplication* UiApplication::GetInstance() {  }  // namespace cru::platform::native  namespace cru::win::native { -WinApplication* WinApplication::instance_ = nullptr; +WinApplication* WinApplication::instance = nullptr; + +namespace { +bool application_constructing = false; +}  WinApplication* WinApplication::GetInstance() { -  if (instance_ == nullptr) -    instance_ = new WinApplication(::GetModuleHandleW(nullptr)); -  return instance_; +  if (instance == nullptr && !application_constructing) { +    application_constructing = true; +    instance = new WinApplication(::GetModuleHandleW(nullptr)); +  } +  return instance;  }  WinApplication::WinApplication(HINSTANCE h_instance) : h_instance_(h_instance) { -  if (instance_) -    throw std::runtime_error("A application instance already exists."); - -  instance_ = this; +  assert(instance == nullptr);    if (!::IsWindows8OrGreater())      throw std::runtime_error("Must run on Windows 8 or later."); @@ -39,7 +43,8 @@ WinApplication::WinApplication(HINSTANCE h_instance) : h_instance_(h_instance) {    window_manager_ = std::make_shared<WindowManager>(this);  } -WinApplication::~WinApplication() { instance_ = nullptr; } +WinApplication::~WinApplication() { +  instance = nullptr; }  int WinApplication::Run() {    MSG msg; @@ -47,11 +52,21 @@ int WinApplication::Run() {      TranslateMessage(&msg);      DispatchMessageW(&msg);    } + +  for (const auto& handler : quit_handlers_) handler(); + +  delete graph::GraphManager::GetInstance(); +  delete this; +    return static_cast<int>(msg.wParam);  }  void WinApplication::Quit(const int quit_code) { ::PostQuitMessage(quit_code); } +void WinApplication::AddOnQuitHandler(const std::function<void()>& handler) { +  quit_handlers_.push_back(handler); +} +  void WinApplication::InvokeLater(const std::function<void()>& action) {    // copy the action to a safe place    auto p_action_copy = new std::function<void()>(action); diff --git a/src/win/native/win_native_window.cpp b/src/win/native/win_native_window.cpp index 0afad4e6..1d3b15ba 100644 --- a/src/win/native/win_native_window.cpp +++ b/src/win/native/win_native_window.cpp @@ -254,6 +254,7 @@ RECT WinNativeWindow::GetClientRectPixel() {  void WinNativeWindow::OnDestroyInternal() {    application_->GetWindowManager()->UnregisterWindow(hwnd_);    hwnd_ = nullptr; +  destroy_event_.Raise();    if (delete_this_on_destroy_)      application_->InvokeLater([this] { delete this; });  } diff --git a/src/win/native/window_manager.cpp b/src/win/native/window_manager.cpp index a2fcdb54..5fea5a27 100644 --- a/src/win/native/window_manager.cpp +++ b/src/win/native/window_manager.cpp @@ -26,6 +26,11 @@ WindowManager::WindowManager(WinApplication* application) {        L"CruUIWindowClass", GeneralWndProc, application->GetInstanceHandle());  } +WindowManager::~WindowManager() { +  for (const auto [key, window] : window_map_) +    delete window; +} +  void WindowManager::RegisterWindow(HWND hwnd, WinNativeWindow* window) {    assert(window_map_.count(hwnd) == 0);  // The hwnd is already in the map.    window_map_.emplace(hwnd, window); diff --git a/src/win/native/window_manager.hpp b/src/win/native/window_manager.hpp index fa5bbe9d..8fab9cfc 100644 --- a/src/win/native/window_manager.hpp +++ b/src/win/native/window_manager.hpp @@ -19,7 +19,7 @@ class WindowManager : public Object {    WindowManager(WindowManager&& other) = delete;    WindowManager& operator=(const WindowManager& other) = delete;    WindowManager& operator=(WindowManager&& other) = delete; -  ~WindowManager() override = default; +  ~WindowManager() override;    // Get the general window class for creating ordinary window.    std::shared_ptr<WindowClass> GetGeneralWindowClass() const { diff --git a/src/win/native/window_painter.cpp b/src/win/native/window_painter.cpp index 46364cdd..4e98a7fd 100644 --- a/src/win/native/window_painter.cpp +++ b/src/win/native/window_painter.cpp @@ -1,5 +1,6 @@  #include "window_painter.hpp" +#include "cru/win/exception.hpp"  #include "cru/win/graph/graph_manager.hpp"  #include "cru/win/native/window_render_target.hpp" @@ -7,7 +8,7 @@  namespace cru::win::native {  WindowPainter::WindowPainter(WinNativeWindow* window) -    : WinPainter(window->GetWindowRenderTarget() +    : D2DPainter(window->GetWindowRenderTarget()                       ->GetGraphManager()                       ->GetD2D1DeviceContext()),        window_(window) { @@ -18,7 +19,13 @@ WindowPainter::WindowPainter(WinNativeWindow* window)        ->BeginDraw();  } +WindowPainter::~WindowPainter() { EndDraw(); } +  void WindowPainter::DoEndDraw() { -  WinPainter::DoEndDraw(); -  window_->GetWindowRenderTarget()->Present(); } +  ThrowIfFailed(window_->GetWindowRenderTarget() +                    ->GetGraphManager() +                    ->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 index 0e6ab2cb..78c0717c 100644 --- a/src/win/native/window_painter.hpp +++ b/src/win/native/window_painter.hpp @@ -1,16 +1,16 @@  #pragma once -#include "cru/win/graph/win_painter.hpp" +#include "cru/win/graph/d2d_painter.hpp"  #include "cru/win/native/win_native_window.hpp"  namespace cru::win::native { -class WindowPainter : public graph::WinPainter { +class WindowPainter : public graph::D2DPainter {   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 = default; +  ~WindowPainter() override;   protected:    void DoEndDraw() override; | 
