diff options
-rw-r--r-- | include/cru/osx/gui/Window.hpp | 7 | ||||
-rw-r--r-- | include/cru/platform/GraphicsBase.hpp | 5 | ||||
-rw-r--r-- | src/osx/gui/Window.mm | 105 |
3 files changed, 113 insertions, 4 deletions
diff --git a/include/cru/osx/gui/Window.hpp b/include/cru/osx/gui/Window.hpp index 1e790a65..6bb6b747 100644 --- a/include/cru/osx/gui/Window.hpp +++ b/include/cru/osx/gui/Window.hpp @@ -1,5 +1,6 @@ #pragma once #include "Resource.hpp" +#include "cru/platform/gui/Base.hpp" #include "cru/platform/gui/Window.hpp" #include <memory> @@ -15,7 +16,8 @@ class OsxWindow : public OsxGuiResource, public INativeWindow { friend details::OsxWindowPrivate; public: - explicit OsxWindow(OsxUiApplication* ui_application); + OsxWindow(OsxUiApplication* ui_application, INativeWindow* parent, + bool frame); CRU_DELETE_COPY(OsxWindow) CRU_DELETE_MOVE(OsxWindow) @@ -62,6 +64,9 @@ class OsxWindow : public OsxGuiResource, public INativeWindow { IInputMethodContext* GetInputMethodContext() override; private: + void CreateWindow(); + + private: std::unique_ptr<details::OsxWindowPrivate> p_; }; } // namespace cru::platform::gui::osx diff --git a/include/cru/platform/GraphicsBase.hpp b/include/cru/platform/GraphicsBase.hpp index e7201ec0..aee718a1 100644 --- a/include/cru/platform/GraphicsBase.hpp +++ b/include/cru/platform/GraphicsBase.hpp @@ -182,6 +182,11 @@ struct Rect final { return Point(left + width / 2.0f, top + height / 2.0f); } + constexpr void SetSize(const Size& size) { + width = size.width; + height = size.height; + } + constexpr Size GetSize() const { return Size(width, height); } constexpr Rect Expand(const Thickness& thickness) const { diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm index 1ee0299a..52cc3934 100644 --- a/src/osx/gui/Window.mm +++ b/src/osx/gui/Window.mm @@ -1,6 +1,9 @@ #include "cru/osx/gui/Window.hpp" #include "cru/osx/gui/UiApplication.hpp" +#include "cru/platform/gui/Base.hpp" + +#include <AppKit/NSWindow.h> namespace cru::platform::gui::osx { namespace details { @@ -17,11 +20,107 @@ class OsxWindowPrivate { private: OsxWindow* osx_window_; + + INativeWindow* parent_; + + bool frame_; + Rect content_rect_; + + NSWindow* window_; }; } -OsxWindow::OsxWindow(OsxUiApplication* ui_application) - : OsxGuiResource(ui_application), p_(new details::OsxWindowPrivate(this)) {} +namespace { +inline NSWindowStyleMask CalcWindowStyleMask(bool frame) { + return frame ? NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | + NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable + : NSWindowStyleMaskBorderless; +} + +} + +OsxWindow::OsxWindow(OsxUiApplication* ui_application, INativeWindow* parent, bool frame) + : OsxGuiResource(ui_application), p_(new details::OsxWindowPrivate(this)) { + p_->parent_ = parent; + + p_->frame_ = frame; + p_->content_rect_ = {100, 100, 400, 200}; +} + +OsxWindow::~OsxWindow() { + if (p_->window_) { + [p_->window_ close]; + } +} + +void OsxWindow::Close() { + if (p_->window_) { + [p_->window_ close]; + } +} + +INativeWindow* OsxWindow::GetParent() { return p_->parent_; } -OsxWindow::~OsxWindow() {} +bool OsxWindow::IsVisible() { + if (!p_->window_) return false; + return [p_->window_ isVisible]; +} + +void OsxWindow::SetVisible(bool is_visible) { + if (p_->window_) { + if (is_visible) { + [p_->window_ orderFront:p_->window_]; + } else { + [p_->window_ orderOut:p_->window_]; + } + } else { + if (is_visible) { + CreateWindow(); + } + } +} + +Size OsxWindow::GetClientSize() { return p_->content_rect_.GetSize(); } + +void OsxWindow::SetClientSize(const Size& size) { + if (p_->window_) { + [p_->window_ setContentSize:NSSize{size.width, size.height}]; + } else { + p_->content_rect_.SetSize(size); + } +} + +Rect OsxWindow::GetWindowRect() { + if (p_->window_) { + auto r = [p_->window_ frame]; + return Rect(r.origin.x, r.origin.y, r.size.width, r.size.height); + } else { + NSRect rr{p_->content_rect_.left, p_->content_rect_.top, p_->content_rect_.width, + p_->content_rect_.height}; + auto r = [NSWindow frameRectForContentRect:rr styleMask:CalcWindowStyleMask(p_->frame_)]; + return Rect(r.origin.x, r.origin.y, r.size.width, r.size.height); + } +} + +void OsxWindow::SetWindowRect(const Rect& rect) { + auto rr = NSRect{rect.left, rect.top, rect.width, rect.height}; + if (p_->window_) { + [p_->window_ setFrame:rr display:false]; + } else { + auto r = [NSWindow contentRectForFrameRect:rr styleMask:CalcWindowStyleMask(p_->frame_)]; + p_->content_rect_ = Rect(r.origin.x, r.origin.y, r.size.width, r.size.height); + } +} + +void OsxWindow::CreateWindow() { + NSRect content_rect{p_->content_rect_.left, p_->content_rect_.top, p_->content_rect_.width, + p_->content_rect_.height}; + + NSWindowStyleMask style_mask = CalcWindowStyleMask(p_->frame_); + + p_->window_ = [[NSWindow alloc] initWithContentRect:content_rect + styleMask:style_mask + backing:NSBackingStoreBuffered + defer:false]; +} } |