aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/osx/gui/Window.hpp7
-rw-r--r--include/cru/platform/GraphicsBase.hpp5
-rw-r--r--src/osx/gui/Window.mm105
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];
+}
}