aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-10-16 22:30:29 +0800
committercrupest <crupest@outlook.com>2021-10-16 22:30:29 +0800
commite9f586071a83b2551dbc7c98ccfaa8e6b3189f01 (patch)
tree1191207902f833584517df87d4b1fa7d7ce5783b /src
parented368423531b24e8735db0afe38c7486145caa56 (diff)
downloadcru-e9f586071a83b2551dbc7c98ccfaa8e6b3189f01.tar.gz
cru-e9f586071a83b2551dbc7c98ccfaa8e6b3189f01.tar.bz2
cru-e9f586071a83b2551dbc7c98ccfaa8e6b3189f01.zip
...
Diffstat (limited to 'src')
-rw-r--r--src/osx/graphics/quartz/Painter.cpp13
-rw-r--r--src/osx/gui/Window.mm308
2 files changed, 217 insertions, 104 deletions
diff --git a/src/osx/graphics/quartz/Painter.cpp b/src/osx/graphics/quartz/Painter.cpp
index 6effe9f9..4771ca47 100644
--- a/src/osx/graphics/quartz/Painter.cpp
+++ b/src/osx/graphics/quartz/Painter.cpp
@@ -7,6 +7,13 @@
#include "cru/platform/Exception.hpp"
namespace cru::platform::graphics::osx::quartz {
+QuartzCGContextPainter::~QuartzCGContextPainter() {
+ if (auto_release_) {
+ CGContextRelease(cg_context_);
+ cg_context_ = nullptr;
+ }
+}
+
Matrix QuartzCGContextPainter::GetTransform() {
return Convert(CGContextGetCTM(cg_context_));
}
@@ -101,11 +108,7 @@ void QuartzCGContextPainter::PopLayer() {
// TODO: Implement this.
}
-void QuartzCGContextPainter::EndDraw() {
- CGContextRelease(cg_context_);
- CGContextFlush(cg_context_);
- cg_context_ = nullptr;
-}
+void QuartzCGContextPainter::EndDraw() { CGContextFlush(cg_context_); }
void QuartzCGContextPainter::Validate() {
if (cg_context_ == nullptr)
diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm
index da39d34d..dfe94d43 100644
--- a/src/osx/gui/Window.mm
+++ b/src/osx/gui/Window.mm
@@ -3,6 +3,7 @@
#include "CursorPrivate.h"
#include "cru/common/Range.hpp"
#include "cru/osx/Convert.hpp"
+#include "cru/osx/graphics/quartz/Convert.hpp"
#include "cru/osx/graphics/quartz/Painter.hpp"
#include "cru/osx/gui/Cursor.hpp"
#include "cru/osx/gui/Keyboard.hpp"
@@ -30,21 +31,44 @@ using cru::platform::osx::Convert;
- (id)init:(cru::platform::gui::osx::details::OsxWindowPrivate*)p;
@end
+@interface Window : NSWindow
+- (instancetype)init:(cru::platform::gui::osx::details::OsxWindowPrivate*)p
+ contentRect:(NSRect)contentRect
+ style:(NSWindowStyleMask)style;
+
+- (void)mouseMoved:(NSEvent*)event;
+- (void)mouseEntered:(NSEvent*)event;
+- (void)mouseExited:(NSEvent*)event;
+- (void)mouseDown:(NSEvent*)event;
+- (void)mouseUp:(NSEvent*)event;
+- (void)rightMouseDown:(NSEvent*)event;
+- (void)rightMouseUp:(NSEvent*)event;
+- (void)scrollWheel:(NSEvent*)event;
+- (void)keyDown:(NSEvent*)event;
+- (void)keyUp:(NSEvent*)event;
+@end
+
@interface InputClient : NSObject <NSTextInputClient>
- (id)init:(cru::platform::gui::osx::details::OsxInputMethodContextPrivate*)p;
@end
namespace cru::platform::gui::osx {
-namespace details {
+namespace {
+inline NSWindowStyleMask CalcWindowStyleMask(bool frame) {
+ return frame ? NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
+ NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable
+ : NSWindowStyleMaskBorderless;
+}
+}
+
+namespace details {
class OsxWindowPrivate {
friend OsxWindow;
friend OsxInputMethodContextPrivate;
public:
- explicit OsxWindowPrivate(OsxWindow* osx_window) : osx_window_(osx_window) {
- window_delegate_ = [[WindowDelegate alloc] init:this];
- }
+ explicit OsxWindowPrivate(OsxWindow* osx_window) : osx_window_(osx_window) {}
CRU_DELETE_COPY(OsxWindowPrivate)
CRU_DELETE_MOVE(OsxWindowPrivate)
@@ -52,6 +76,14 @@ class OsxWindowPrivate {
~OsxWindowPrivate() = default;
public:
+ void OnMouseEnterLeave(MouseEnterLeaveType type);
+ void OnMouseMove(Point p);
+ void OnMouseDown(MouseButton button, Point p, KeyModifier key_modifier);
+ void OnMouseUp(MouseButton button, Point p, KeyModifier key_modifier);
+ void OnMouseWheel(float delta, Point p, KeyModifier key_modifier);
+ void OnKeyDown(KeyCode key, KeyModifier key_modifier);
+ void OnKeyUp(KeyCode key, KeyModifier key_modifier);
+
void OnWindowWillClose();
void OnWindowDidExpose();
void OnWindowDidUpdate();
@@ -70,6 +102,7 @@ class OsxWindowPrivate {
NSWindow* window_;
WindowDelegate* window_delegate_;
+ NSGraphicsContext* graphics_context_;
bool mouse_in_ = false;
@@ -78,11 +111,53 @@ class OsxWindowPrivate {
std::unique_ptr<OsxInputMethodContext> input_method_context_;
};
-void OsxWindowPrivate::OnWindowWillClose() { osx_window_->destroy_event_.Raise(nullptr); }
+void OsxWindowPrivate::OnWindowWillClose() {
+ osx_window_->destroy_event_.Raise(nullptr);
+ window_ = nil;
+ graphics_context_ = nil;
+}
+
void OsxWindowPrivate::OnWindowDidExpose() { [window_ update]; }
void OsxWindowPrivate::OnWindowDidUpdate() { osx_window_->paint_event_.Raise(nullptr); }
void OsxWindowPrivate::OnWindowDidResize() {
osx_window_->resize_event_.Raise(osx_window_->GetClientSize());
+
+ NSRect rect = [NSWindow contentRectForFrameRect:[window_ frame]
+ styleMask:CalcWindowStyleMask(frame_)];
+
+ content_rect_ = cru::platform::graphics::osx::quartz::Convert(rect);
+}
+
+void OsxWindowPrivate::OnMouseEnterLeave(MouseEnterLeaveType type) {
+ osx_window_->mouse_enter_leave_event_.Raise(type);
+ if (type == MouseEnterLeaveType::Enter) {
+ mouse_in_ = true;
+ UpdateCursor();
+ } else {
+ mouse_in_ = false;
+ }
+}
+
+void OsxWindowPrivate::OnMouseMove(Point p) { osx_window_->mouse_move_event_.Raise(p); }
+
+void OsxWindowPrivate::OnMouseDown(MouseButton button, Point p, KeyModifier key_modifier) {
+ osx_window_->mouse_down_event_.Raise({button, p, key_modifier});
+}
+
+void OsxWindowPrivate::OnMouseUp(MouseButton button, Point p, KeyModifier key_modifier) {
+ osx_window_->mouse_up_event_.Raise({button, p, key_modifier});
+}
+
+void OsxWindowPrivate::OnMouseWheel(float delta, Point p, KeyModifier key_modifier) {
+ osx_window_->mouse_wheel_event_.Raise({delta, p, key_modifier});
+}
+
+void OsxWindowPrivate::OnKeyDown(KeyCode key, KeyModifier key_modifier) {
+ osx_window_->key_down_event_.Raise({key, key_modifier});
+}
+
+void OsxWindowPrivate::OnKeyUp(KeyCode key, KeyModifier key_modifier) {
+ osx_window_->key_up_event_.Raise({key, key_modifier});
}
void OsxWindowPrivate::UpdateCursor() {
@@ -96,17 +171,10 @@ void OsxWindowPrivate::UpdateCursor() {
}
}
-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_->window_delegate_ = [[WindowDelegate alloc] init:p_.get()];
+
p_->parent_ = parent;
p_->frame_ = frame;
@@ -116,10 +184,7 @@ OsxWindow::OsxWindow(OsxUiApplication* ui_application, INativeWindow* parent, bo
}
OsxWindow::~OsxWindow() {
- if (p_->window_) {
- [p_->window_ close];
- }
-
+ Close();
dynamic_cast<OsxUiApplication*>(GetUiApplication())->UnregisterWindow(this);
}
@@ -146,6 +211,7 @@ void OsxWindow::SetVisible(bool is_visible) {
} else {
if (is_visible) {
CreateWindow();
+ [p_->window_ orderFront:p_->window_];
}
}
}
@@ -185,98 +251,23 @@ void OsxWindow::SetWindowRect(const Rect& rect) {
void OsxWindow::RequestRepaint() { [p_->window_ update]; }
std::unique_ptr<graphics::IPainter> OsxWindow::BeginPaint() {
- NSGraphicsContext* ns_graphics_context =
- [NSGraphicsContext graphicsContextWithWindow:p_->window_];
-
- CGContextRef cg_context = [ns_graphics_context CGContext];
+ CGContextRef cg_context = [p_->graphics_context_ CGContext];
return std::make_unique<cru::platform::graphics::osx::quartz::QuartzCGContextPainter>(
- GetUiApplication()->GetGraphicsFactory(), cg_context, true, GetClientSize());
+ GetUiApplication()->GetGraphicsFactory(), cg_context, false, GetClientSize());
}
void OsxWindow::CreateWindow() {
- NSRect content_rect{p_->content_rect_.left, p_->content_rect_.top, p_->content_rect_.width,
- p_->content_rect_.height};
+ NSRect content_rect = CGRectMake(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];
+ p_->window_ = [[Window alloc] init:p_.get() contentRect:content_rect style:style_mask];
[p_->window_ setDelegate:p_->window_delegate_];
- [p_->window_
- trackEventsMatchingMask:NSEventMaskAny
- timeout:std::numeric_limits<double>::max()
- mode:NSRunLoopCommonModes
- handler:^(NSEvent* _Nullable event, BOOL* _Nonnull stop) {
- KeyModifier key_modifer;
- if (event.modifierFlags & NSEventModifierFlagControl)
- key_modifer |= KeyModifiers::ctrl;
- if (event.modifierFlags & NSEventModifierFlagOption)
- key_modifer |= KeyModifiers::alt;
- if (event.modifierFlags & NSEventModifierFlagShift)
- key_modifer |= KeyModifiers::shift;
-
- switch (event.type) {
- case NSEventTypeMouseEntered:
- this->mouse_enter_leave_event_.Raise(MouseEnterLeaveType::Enter);
- p_->mouse_in_ = true;
- p_->UpdateCursor();
- break;
- case NSEventTypeMouseExited:
- this->mouse_enter_leave_event_.Raise(MouseEnterLeaveType::Leave);
- p_->mouse_in_ = false;
- break;
- case NSEventTypeMouseMoved:
- this->mouse_move_event_.Raise(
- Point(event.locationInWindow.x, event.locationInWindow.y));
- break;
- case NSEventTypeLeftMouseDown:
- this->mouse_down_event_.Raise(NativeMouseButtonEventArgs{
- mouse_buttons::left,
- Point(event.locationInWindow.x, event.locationInWindow.y),
- key_modifer});
- break;
- case NSEventTypeLeftMouseUp:
- this->mouse_up_event_.Raise(NativeMouseButtonEventArgs{
- mouse_buttons::left,
- Point(event.locationInWindow.x, event.locationInWindow.y),
- key_modifer});
- break;
- case NSEventTypeRightMouseDown:
- this->mouse_down_event_.Raise(NativeMouseButtonEventArgs{
- mouse_buttons::right,
- Point(event.locationInWindow.x, event.locationInWindow.y),
- key_modifer});
- break;
- case NSEventTypeRightMouseUp:
- this->mouse_up_event_.Raise(NativeMouseButtonEventArgs{
- mouse_buttons::right,
- Point(event.locationInWindow.x, event.locationInWindow.y),
- key_modifer});
- break;
- case NSEventTypeScrollWheel:
- this->mouse_wheel_event_.Raise(NativeMouseWheelEventArgs{
- static_cast<float>(event.scrollingDeltaY),
- Point(event.locationInWindow.x, event.locationInWindow.y),
- key_modifer});
- break;
- case NSEventTypeKeyDown:
- this->key_down_event_.Raise(NativeKeyEventArgs{
- KeyCodeFromOsxToCru(event.keyCode), key_modifer});
- break;
- case NSEventTypeKeyUp:
- this->key_up_event_.Raise(NativeKeyEventArgs{
- KeyCodeFromOsxToCru(event.keyCode), key_modifer});
- break;
- default:
- break;
- }
- *stop = false;
- }];
+ p_->graphics_context_ = [NSGraphicsContext graphicsContextWithWindow:p_->window_];
}
Point OsxWindow::GetMousePosition() {
@@ -410,6 +401,125 @@ IEvent<std::nullptr_t>* OsxInputMethodContext::CompositionEvent() {
IEvent<StringView>* OsxInputMethodContext::TextEvent() { return &p_->text_event_; }
}
+@implementation Window {
+ cru::platform::gui::osx::details::OsxWindowPrivate* _p;
+}
+
+- (instancetype)init:(cru::platform::gui::osx::details::OsxWindowPrivate*)p
+ contentRect:(NSRect)contentRect
+ style:(NSWindowStyleMask)style {
+ [super initWithContentRect:contentRect
+ styleMask:style
+ backing:NSBackingStoreBuffered
+ defer:false];
+ _p = p;
+ return self;
+}
+
+- (void)mouseMoved:(NSEvent*)event {
+ _p->OnMouseMove(cru::platform::Point(event.locationInWindow.x, event.locationInWindow.y));
+}
+
+- (void)mouseEntered:(NSEvent*)event {
+ _p->OnMouseEnterLeave(cru::platform::gui::MouseEnterLeaveType::Enter);
+}
+
+- (void)mouseExited:(NSEvent*)event {
+ _p->OnMouseEnterLeave(cru::platform::gui::MouseEnterLeaveType::Leave);
+}
+
+- (void)mouseDown:(NSEvent*)event {
+ cru::platform::gui::KeyModifier key_modifier;
+ if (event.modifierFlags & NSEventModifierFlagControl)
+ key_modifier |= cru::platform::gui::KeyModifiers::ctrl;
+ if (event.modifierFlags & NSEventModifierFlagOption)
+ key_modifier |= cru::platform::gui::KeyModifiers::alt;
+ if (event.modifierFlags & NSEventModifierFlagShift)
+ key_modifier |= cru::platform::gui::KeyModifiers::shift;
+ cru::platform::Point p(event.locationInWindow.x, event.locationInWindow.y);
+
+ _p->OnMouseDown(cru::platform::gui::mouse_buttons::left, p, key_modifier);
+}
+
+- (void)mouseUp:(NSEvent*)event {
+ cru::platform::gui::KeyModifier key_modifier;
+ if (event.modifierFlags & NSEventModifierFlagControl)
+ key_modifier |= cru::platform::gui::KeyModifiers::ctrl;
+ if (event.modifierFlags & NSEventModifierFlagOption)
+ key_modifier |= cru::platform::gui::KeyModifiers::alt;
+ if (event.modifierFlags & NSEventModifierFlagShift)
+ key_modifier |= cru::platform::gui::KeyModifiers::shift;
+ cru::platform::Point p(event.locationInWindow.x, event.locationInWindow.y);
+
+ _p->OnMouseUp(cru::platform::gui::mouse_buttons::left, p, key_modifier);
+}
+
+- (void)rightMouseDown:(NSEvent*)event {
+ cru::platform::gui::KeyModifier key_modifier;
+ if (event.modifierFlags & NSEventModifierFlagControl)
+ key_modifier |= cru::platform::gui::KeyModifiers::ctrl;
+ if (event.modifierFlags & NSEventModifierFlagOption)
+ key_modifier |= cru::platform::gui::KeyModifiers::alt;
+ if (event.modifierFlags & NSEventModifierFlagShift)
+ key_modifier |= cru::platform::gui::KeyModifiers::shift;
+ cru::platform::Point p(event.locationInWindow.x, event.locationInWindow.y);
+
+ _p->OnMouseDown(cru::platform::gui::mouse_buttons::right, p, key_modifier);
+}
+
+- (void)rightMouseUp:(NSEvent*)event {
+ cru::platform::gui::KeyModifier key_modifier;
+ if (event.modifierFlags & NSEventModifierFlagControl)
+ key_modifier |= cru::platform::gui::KeyModifiers::ctrl;
+ if (event.modifierFlags & NSEventModifierFlagOption)
+ key_modifier |= cru::platform::gui::KeyModifiers::alt;
+ if (event.modifierFlags & NSEventModifierFlagShift)
+ key_modifier |= cru::platform::gui::KeyModifiers::shift;
+ cru::platform::Point p(event.locationInWindow.x, event.locationInWindow.y);
+
+ _p->OnMouseUp(cru::platform::gui::mouse_buttons::right, p, key_modifier);
+}
+
+- (void)scrollWheel:(NSEvent*)event {
+ cru::platform::gui::KeyModifier key_modifier;
+ if (event.modifierFlags & NSEventModifierFlagControl)
+ key_modifier |= cru::platform::gui::KeyModifiers::ctrl;
+ if (event.modifierFlags & NSEventModifierFlagOption)
+ key_modifier |= cru::platform::gui::KeyModifiers::alt;
+ if (event.modifierFlags & NSEventModifierFlagShift)
+ key_modifier |= cru::platform::gui::KeyModifiers::shift;
+ cru::platform::Point p(event.locationInWindow.x, event.locationInWindow.y);
+
+ _p->OnMouseWheel(static_cast<float>(event.scrollingDeltaY), p, key_modifier);
+}
+
+- (void)keyDown:(NSEvent*)event {
+ cru::platform::gui::KeyModifier key_modifier;
+ if (event.modifierFlags & NSEventModifierFlagControl)
+ key_modifier |= cru::platform::gui::KeyModifiers::ctrl;
+ if (event.modifierFlags & NSEventModifierFlagOption)
+ key_modifier |= cru::platform::gui::KeyModifiers::alt;
+ if (event.modifierFlags & NSEventModifierFlagShift)
+ key_modifier |= cru::platform::gui::KeyModifiers::shift;
+ auto c = cru::platform::gui::osx::KeyCodeFromOsxToCru(event.keyCode);
+
+ _p->OnKeyDown(c, key_modifier);
+}
+
+- (void)keyUp:(NSEvent*)event {
+ cru::platform::gui::KeyModifier key_modifier;
+ if (event.modifierFlags & NSEventModifierFlagControl)
+ key_modifier |= cru::platform::gui::KeyModifiers::ctrl;
+ if (event.modifierFlags & NSEventModifierFlagOption)
+ key_modifier |= cru::platform::gui::KeyModifiers::alt;
+ if (event.modifierFlags & NSEventModifierFlagShift)
+ key_modifier |= cru::platform::gui::KeyModifiers::shift;
+ auto c = cru::platform::gui::osx::KeyCodeFromOsxToCru(event.keyCode);
+
+ _p->OnKeyUp(c, key_modifier);
+}
+@end
+
@implementation WindowDelegate {
cru::platform::gui::osx::details::OsxWindowPrivate* _p;
}