aboutsummaryrefslogtreecommitdiff
path: root/src/osx/gui/Window.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/osx/gui/Window.mm')
-rw-r--r--src/osx/gui/Window.mm800
1 files changed, 0 insertions, 800 deletions
diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm
deleted file mode 100644
index 8d15ef37..00000000
--- a/src/osx/gui/Window.mm
+++ /dev/null
@@ -1,800 +0,0 @@
-#include "cru/osx/gui/Window.h"
-#include "WindowPrivate.h"
-
-#include "CursorPrivate.h"
-#include "InputMethodPrivate.h"
-#include "cru/common/Range.h"
-#include "cru/common/log/Logger.h"
-#include "cru/osx/Convert.h"
-#include "cru/osx/graphics/quartz/Convert.h"
-#include "cru/osx/graphics/quartz/Painter.h"
-#include "cru/osx/gui/Cursor.h"
-#include "cru/osx/gui/InputMethod.h"
-#include "cru/osx/gui/Keyboard.h"
-#include "cru/osx/gui/Resource.h"
-#include "cru/osx/gui/UiApplication.h"
-#include "cru/platform/Check.h"
-#include "cru/platform/graphics/NullPainter.h"
-#include "cru/platform/gui/TimerHelper.h"
-
-#include <AppKit/AppKit.h>
-#include <Foundation/Foundation.h>
-
-#include <limits>
-#include <memory>
-#include <unordered_set>
-
-namespace {
-constexpr int key_down_debug = 0;
-}
-
-using cru::platform::osx::Convert;
-using cru::platform::graphics::osx::quartz::Convert;
-
-namespace cru::platform::gui::osx {
-namespace {
-inline NSWindowStyleMask CalcWindowStyleMask(WindowStyleFlag flag) {
- return flag & WindowStyleFlags::NoCaptionAndBorder
- ? NSWindowStyleMaskBorderless
- : NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
- NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable;
-}
-}
-
-namespace details {
-OsxWindowPrivate::OsxWindowPrivate(OsxWindow* osx_window) : osx_window_(osx_window) {
- window_delegate_ = [[CruWindowDelegate alloc] init:this];
-
- content_rect_ = {100, 100, 400, 200};
-
- input_method_context_ = std::make_unique<OsxInputMethodContext>(osx_window);
-}
-
-OsxWindowPrivate::~OsxWindowPrivate() {}
-
-void OsxWindowPrivate::OnWindowWillClose() {
- if (window_) destroy_event_.Raise(nullptr);
- window_ = nil;
- CGLayerRelease(draw_layer_);
- draw_layer_ = nullptr;
-
- if (osx_window_->GetUiApplication()->IsQuitOnAllWindowClosed()) {
- const auto& all_window = osx_window_->GetUiApplication()->GetAllWindow();
-
- bool quit = true;
-
- for (auto window : all_window) {
- auto w = CheckPlatform<OsxWindow>(window, osx_window_->GetPlatformId());
- if (w->p_->window_) {
- quit = false;
- break;
- }
- }
-
- if (quit) {
- osx_window_->GetUiApplication()->RequestQuit(0);
- }
- }
-}
-
-void OsxWindowPrivate::OnWindowDidExpose() { osx_window_->RequestRepaint(); }
-void OsxWindowPrivate::OnWindowDidUpdate() {}
-void OsxWindowPrivate::OnWindowDidMove() { content_rect_ = RetrieveContentRect(); }
-
-void OsxWindowPrivate::OnWindowDidResize() {
- content_rect_ = RetrieveContentRect();
-
- auto view = [window_ contentView];
- [view removeTrackingArea:[view trackingAreas][0]];
- auto tracking_area = [[NSTrackingArea alloc]
- initWithRect:CGRectMake(0, 0, content_rect_.width, content_rect_.height)
- options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways)
- owner:view
- userInfo:nil];
- [view addTrackingArea:tracking_area];
-
- CGLayerRelease(draw_layer_);
- draw_layer_ = CreateLayer(Convert(content_rect_.GetSize()));
-
- resize_event_.Raise(osx_window_->GetClientSize());
-
- osx_window_->RequestRepaint();
-}
-
-void OsxWindowPrivate::OnBecomeKeyWindow() { focus_event_.Raise(FocusChangeType::Gain); }
-
-void OsxWindowPrivate::OnResignKeyWindow() { focus_event_.Raise(FocusChangeType::Lose); }
-
-void OsxWindowPrivate::OnMouseEnterLeave(MouseEnterLeaveType type) {
- mouse_enter_leave_event_.Raise(type);
- if (type == MouseEnterLeaveType::Enter) {
- mouse_in_ = true;
- UpdateCursor();
- } else {
- mouse_in_ = false;
- }
-}
-
-void OsxWindowPrivate::OnMouseMove(Point p) { mouse_move_event_.Raise(TransformMousePoint(p)); }
-
-void OsxWindowPrivate::OnMouseDown(MouseButton button, Point p, KeyModifier key_modifier) {
- mouse_down_event_.Raise({button, TransformMousePoint(p), key_modifier});
-}
-
-void OsxWindowPrivate::OnMouseUp(MouseButton button, Point p, KeyModifier key_modifier) {
- mouse_up_event_.Raise({button, TransformMousePoint(p), key_modifier});
-}
-
-void OsxWindowPrivate::OnMouseWheel(float delta, Point p, KeyModifier key_modifier,
- bool horizontal) {
- mouse_wheel_event_.Raise({delta, TransformMousePoint(p), key_modifier, horizontal});
-}
-
-void OsxWindowPrivate::OnKeyDown(KeyCode key, KeyModifier key_modifier) {
- key_down_event_.Raise({key, key_modifier});
-}
-
-void OsxWindowPrivate::OnKeyUp(KeyCode key, KeyModifier key_modifier) {
- key_up_event_.Raise({key, key_modifier});
-}
-
-CGLayerRef OsxWindowPrivate::CreateLayer(const CGSize& size) {
- auto s = size;
- if (s.width == 0) s.width = 1;
- if (s.height == 0) s.height = 1;
-
- auto draw_layer = CGLayerCreateWithContext(nullptr, s, nullptr);
- Ensures(draw_layer);
-
- return draw_layer;
-}
-
-void OsxWindowPrivate::UpdateCursor() {
- auto cursor = cursor_ == nullptr
- ? std::dynamic_pointer_cast<OsxCursor>(
- osx_window_->GetUiApplication()->GetCursorManager()->GetSystemCursor(
- SystemCursorType::Arrow))
- : cursor_;
-
- [cursor->p_->ns_cursor_ set];
-}
-
-Point OsxWindowPrivate::TransformMousePoint(const Point& point) {
- Point r = point;
- r.y = content_rect_.height - r.y;
- return r;
-}
-
-void OsxWindowPrivate::CreateWindow() {
- Expects(!window_);
-
- NSWindowStyleMask style_mask = CalcWindowStyleMask(style_flag_);
- window_ = [[CruWindow alloc] init:this
- contentRect:{0, 0, content_rect_.width, content_rect_.height}
- style:style_mask];
- Ensures(window_);
-
- osx_window_->SetClientRect(content_rect_);
-
- [window_ setDelegate:window_delegate_];
-
- if (parent_) {
- auto parent = CheckPlatform<OsxWindow>(parent_, this->osx_window_->GetPlatformId());
- [window_ setParentWindow:parent->p_->window_];
- }
-
- NSView* content_view = [[CruView alloc] init:this
- input_context_p:input_method_context_->p_.get()
- frame:Rect(Point{}, content_rect_.GetSize())];
-
- [window_ setContentView:content_view];
-
- auto title_str = Convert(title_);
- [window_ setTitle:(NSString*)title_str];
- CFRelease(title_str);
-
- draw_layer_ = CreateLayer(Convert(content_rect_.GetSize()));
-
- create_event_.Raise(nullptr);
-
- osx_window_->RequestRepaint();
-}
-
-Size OsxWindowPrivate::GetScreenSize() {
- auto screen = window_ ? [window_ screen] : [NSScreen mainScreen];
- auto size = [screen frame].size;
- return Convert(size);
-}
-
-Rect OsxWindowPrivate::RetrieveContentRect() {
- NSRect rect = [NSWindow contentRectForFrameRect:[window_ frame]
- styleMask:CalcWindowStyleMask(style_flag_)];
- rect.origin.y = GetScreenSize().height - rect.origin.y - rect.size.height;
- return cru::platform::graphics::osx::quartz::Convert(rect);
-}
-
-}
-
-OsxWindow::OsxWindow(OsxUiApplication* ui_application)
- : OsxGuiResource(ui_application), p_(new details::OsxWindowPrivate(this)) {}
-
-OsxWindow::~OsxWindow() {
- if (p_->window_) {
- [p_->window_ close];
- }
- dynamic_cast<OsxUiApplication*>(GetUiApplication())->UnregisterWindow(this);
-}
-
-void OsxWindow::Close() {
- if (p_->window_) {
- [p_->window_ close];
- }
-}
-
-INativeWindow* OsxWindow::GetParent() { return p_->parent_; }
-
-void OsxWindow::SetParent(INativeWindow* parent) {
- auto p = CheckPlatform<OsxWindow>(parent, GetPlatformId());
-
- p_->parent_ = parent;
-
- if (p_->window_) {
- [p_->window_ setParentWindow:p->p_->window_];
- }
-}
-
-WindowStyleFlag OsxWindow::GetStyleFlag() { return p_->style_flag_; }
-
-void OsxWindow::SetStyleFlag(WindowStyleFlag flag) {
- p_->style_flag_ = flag;
-
- if (p_->window_) {
- [p_->window_ close];
- }
-}
-
-String OsxWindow::GetTitle() { return p_->title_; }
-
-void OsxWindow::SetTitle(String title) {
- p_->title_ = title;
-
- if (p_->window_) {
- auto str = Convert(title);
- [p_->window_ setTitle:(NSString*)str];
- CFRelease(str);
- }
-}
-
-WindowVisibilityType OsxWindow::GetVisibility() {
- if (!p_->window_) return WindowVisibilityType::Hide;
- if ([p_->window_ isMiniaturized]) return WindowVisibilityType::Minimize;
- return [p_->window_ isVisible] ? WindowVisibilityType::Show : WindowVisibilityType::Hide;
-}
-
-void OsxWindow::SetVisibility(WindowVisibilityType visibility) {
- if (p_->window_) {
- if (visibility == WindowVisibilityType::Show) {
- [p_->window_ orderFront:nil];
- p_->visibility_change_event_.Raise(WindowVisibilityType::Show);
- } else if (visibility == WindowVisibilityType::Hide) {
- [p_->window_ orderOut:nil];
- p_->visibility_change_event_.Raise(WindowVisibilityType::Hide);
- } else if (visibility == WindowVisibilityType::Minimize) {
- [p_->window_ miniaturize:nil];
- }
- } else {
- if (visibility == WindowVisibilityType::Show) {
- p_->CreateWindow();
- [p_->window_ orderFront:nil];
- p_->visibility_change_event_.Raise(WindowVisibilityType::Show);
- }
- }
-}
-
-Size OsxWindow::GetClientSize() { return p_->content_rect_.GetSize(); }
-
-void OsxWindow::SetClientSize(const Size& size) {
- if (p_->window_) {
- auto rect = GetClientRect();
- rect.SetSize(size);
- SetClientRect(rect);
- } else {
- p_->content_rect_.SetSize(size);
- }
-}
-
-Rect OsxWindow::GetClientRect() { return p_->content_rect_; }
-
-void OsxWindow::SetClientRect(const Rect& rect) {
- if (p_->window_) {
- auto r = Convert(rect);
- r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height;
- r = [NSWindow frameRectForContentRect:r styleMask:CalcWindowStyleMask(p_->style_flag_)];
- [p_->window_ setFrame:r display:false];
- } else {
- p_->content_rect_ = rect;
- }
-}
-
-Rect OsxWindow::GetWindowRect() {
- auto r = Convert(p_->content_rect_);
- r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height;
- r = [NSWindow frameRectForContentRect:r styleMask:CalcWindowStyleMask(p_->style_flag_)];
- r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height;
- return Convert(r);
-}
-
-void OsxWindow::SetWindowRect(const Rect& rect) {
- auto r = Convert(rect);
- r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height;
- r = [NSWindow frameRectForContentRect:r styleMask:CalcWindowStyleMask(p_->style_flag_)];
- r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height;
- SetClientRect(Convert(r));
-}
-
-void OsxWindow::RequestRepaint() {
- if (!p_->draw_timer_) {
- p_->draw_timer_ = GetUiApplication()->SetImmediate([this] {
- p_->paint_event_.Raise(nullptr);
- p_->draw_timer_.Release();
- });
- }
-}
-
-std::unique_ptr<graphics::IPainter> OsxWindow::BeginPaint() {
- if (!p_->window_) {
- return std::make_unique<graphics::NullPainter>();
- }
-
- CGContextRef cg_context = CGLayerGetContext(p_->draw_layer_);
-
- return std::make_unique<cru::platform::graphics::osx::quartz::QuartzCGContextPainter>(
- GetUiApplication()->GetGraphicsFactory(), cg_context, false, GetClientSize(),
- [this](graphics::osx::quartz::QuartzCGContextPainter*) {
- [[p_->window_ contentView] setNeedsDisplay:YES];
- });
-}
-
-bool OsxWindow::RequestFocus() {
- if (!p_->window_) return false;
- [p_->window_ makeKeyWindow];
- return true;
-}
-
-Point OsxWindow::GetMousePosition() {
- auto p = [p_->window_ mouseLocationOutsideOfEventStream];
- return Point(p.x, p.y);
-}
-
-bool OsxWindow::CaptureMouse() { return true; }
-
-bool OsxWindow::ReleaseMouse() { return true; }
-
-void OsxWindow::SetCursor(std::shared_ptr<ICursor> cursor) {
- p_->cursor_ = CheckPlatform<OsxCursor>(cursor, GetPlatformId());
- p_->UpdateCursor();
-}
-
-void OsxWindow::SetToForeground() {
- if (!p_->window_) return;
- [p_->window_ makeMainWindow];
- [p_->window_ orderFrontRegardless];
-}
-
-IEvent<std::nullptr_t>* OsxWindow::CreateEvent() { return &p_->create_event_; }
-IEvent<std::nullptr_t>* OsxWindow::DestroyEvent() { return &p_->destroy_event_; }
-IEvent<std::nullptr_t>* OsxWindow::PaintEvent() { return &p_->paint_event_; }
-IEvent<WindowVisibilityType>* OsxWindow::VisibilityChangeEvent() {
- return &p_->visibility_change_event_;
-}
-IEvent<Size>* OsxWindow::ResizeEvent() { return &p_->resize_event_; }
-IEvent<FocusChangeType>* OsxWindow::FocusEvent() { return &p_->focus_event_; }
-IEvent<MouseEnterLeaveType>* OsxWindow::MouseEnterLeaveEvent() {
- return &p_->mouse_enter_leave_event_;
-}
-IEvent<Point>* OsxWindow::MouseMoveEvent() { return &p_->mouse_move_event_; }
-IEvent<NativeMouseButtonEventArgs>* OsxWindow::MouseDownEvent() { return &p_->mouse_down_event_; }
-IEvent<NativeMouseButtonEventArgs>* OsxWindow::MouseUpEvent() { return &p_->mouse_up_event_; }
-IEvent<NativeMouseWheelEventArgs>* OsxWindow::MouseWheelEvent() { return &p_->mouse_wheel_event_; }
-IEvent<NativeKeyEventArgs>* OsxWindow::KeyDownEvent() { return &p_->key_down_event_; }
-IEvent<NativeKeyEventArgs>* OsxWindow::KeyUpEvent() { return &p_->key_up_event_; }
-
-IInputMethodContext* OsxWindow::GetInputMethodContext() { return p_->input_method_context_.get(); }
-}
-
-namespace {
-cru::platform::gui::KeyModifier GetKeyModifier(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;
- if (event.modifierFlags & NSEventModifierFlagCommand)
- key_modifier |= cru::platform::gui::KeyModifiers::command;
- return key_modifier;
-}
-}
-
-@implementation CruWindow {
- 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;
-
- [self setAcceptsMouseMovedEvents:YES];
-
- return self;
-}
-
-- (BOOL)canBecomeMainWindow {
- return YES;
-}
-
-- (BOOL)canBecomeKeyWindow {
- return YES;
-}
-@end
-
-@implementation CruView {
- cru::platform::gui::osx::details::OsxWindowPrivate* _p;
- cru::platform::gui::osx::details::OsxInputMethodContextPrivate* _input_context_p;
- NSMutableAttributedString* _input_context_text;
-}
-
-- (instancetype)init:(cru::platform::gui::osx::details::OsxWindowPrivate*)p
- input_context_p:
- (cru::platform::gui::osx::details::OsxInputMethodContextPrivate*)input_context_p
- frame:(cru::platform::Rect)frame {
- [super initWithFrame:cru::platform::graphics::osx::quartz::Convert(frame)];
- _p = p;
- _input_context_p = input_context_p;
-
- auto tracking_area = [[NSTrackingArea alloc]
- initWithRect:Convert(frame)
- options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways)
- owner:self
- userInfo:nil];
- [self addTrackingArea:tracking_area];
-
- return self;
-}
-
-- (void)drawRect:(NSRect)dirtyRect {
- auto cg_context = [[NSGraphicsContext currentContext] CGContext];
- auto layer = _p->GetDrawLayer();
- Ensures(layer);
- CGContextDrawLayerAtPoint(cg_context, CGPointMake(0, 0), layer);
-}
-
-- (BOOL)acceptsFirstResponder {
- return YES;
-}
-
-- (BOOL)canBecomeKeyView {
- return YES;
-}
-
-- (void)mouseMoved:(NSEvent*)event {
- _p->OnMouseMove(cru::platform::Point(event.locationInWindow.x, event.locationInWindow.y));
-}
-
-- (void)mouseDragged:(NSEvent*)event {
- _p->OnMouseMove(cru::platform::Point(event.locationInWindow.x, event.locationInWindow.y));
-}
-
-- (void)rightMouseDragged:(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 {
- [[self window] makeKeyWindow];
-
- auto key_modifier = GetKeyModifier(event);
- 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 {
- auto key_modifier = GetKeyModifier(event);
- 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 {
- auto key_modifier = GetKeyModifier(event);
- 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 {
- auto key_modifier = GetKeyModifier(event);
- 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 {
- auto key_modifier = GetKeyModifier(event);
- cru::platform::Point p(event.locationInWindow.x, event.locationInWindow.y);
-
- if (event.scrollingDeltaY) {
- _p->OnMouseWheel(static_cast<float>(event.scrollingDeltaY), p, key_modifier, false);
- }
-
- if (event.scrollingDeltaX) {
- _p->OnMouseWheel(static_cast<float>(event.scrollingDeltaX), p, key_modifier, true);
- }
-}
-
-namespace {
-using cru::platform::gui::KeyCode;
-const std::unordered_set<KeyCode> input_context_handle_codes{
- KeyCode::A,
- KeyCode::B,
- KeyCode::C,
- KeyCode::D,
- KeyCode::E,
- KeyCode::F,
- KeyCode::G,
- KeyCode::H,
- KeyCode::I,
- KeyCode::J,
- KeyCode::K,
- KeyCode::L,
- KeyCode::M,
- KeyCode::N,
- KeyCode::O,
- KeyCode::P,
- KeyCode::Q,
- KeyCode::R,
- KeyCode::S,
- KeyCode::T,
- KeyCode::U,
- KeyCode::V,
- KeyCode::W,
- KeyCode::X,
- KeyCode::Y,
- KeyCode::Z,
- KeyCode::N0,
- KeyCode::N1,
- KeyCode::N2,
- KeyCode::N3,
- KeyCode::N4,
- KeyCode::N5,
- KeyCode::N6,
- KeyCode::N7,
- KeyCode::N8,
- KeyCode::N9,
- KeyCode::Comma,
- KeyCode::Period,
- KeyCode::Slash,
- KeyCode::Semicolon,
- KeyCode::Quote,
- KeyCode::LeftSquareBracket,
- KeyCode::RightSquareBracket,
- KeyCode::BackSlash,
- KeyCode::Minus,
- KeyCode::Equal,
- KeyCode::GraveAccent,
-};
-}
-
-const std::unordered_set<KeyCode> input_context_handle_codes_when_has_text{
- KeyCode::Backspace, KeyCode::Space, KeyCode::Return, KeyCode::Left,
- KeyCode::Right, KeyCode::Up, KeyCode::Down};
-
-- (void)keyDown:(NSEvent*)event {
- auto key_modifier = GetKeyModifier(event);
-
- bool handled = false;
-
- auto input_context = dynamic_cast<cru::platform::gui::osx::OsxInputMethodContext*>(
- _p->GetWindow()->GetInputMethodContext());
- Ensures(input_context);
-
- auto c = cru::platform::gui::osx::KeyCodeFromOsxToCru(event.keyCode);
-
- if (input_context->IsEnabled()) {
- if (input_context_handle_codes.count(c) &&
- !(key_modifier & ~cru::platform::gui::KeyModifiers::shift)) {
- handled = [[self inputContext] handleEvent:event];
- } else if (input_context_handle_codes_when_has_text.count(c) && !key_modifier) {
- if (!input_context->GetCompositionText().text.empty()) {
- handled = [[self inputContext] handleEvent:event];
- } else {
- if (c == KeyCode::Return) {
- _input_context_p->RaiseTextEvent(u"\n");
- handled = true;
- } else if (c == KeyCode::Space) {
- _input_context_p->RaiseTextEvent(u" ");
- handled = true;
- }
- }
- }
- }
-
- if (!handled) {
- _p->OnKeyDown(c, key_modifier);
- }
-}
-
-- (void)keyUp:(NSEvent*)event {
- // cru::CRU_LOG_DEBUG(u"CruView", u"Recieved key up.");
-
- auto key_modifier = GetKeyModifier(event);
- auto c = cru::platform::gui::osx::KeyCodeFromOsxToCru(event.keyCode);
-
- _p->OnKeyUp(c, key_modifier);
-}
-
-- (BOOL)hasMarkedText {
- return _input_context_text != nil;
-}
-
-- (NSRange)markedRange {
- return _input_context_text == nil ? NSRange{NSNotFound, 0}
- : NSRange{0, [_input_context_text length]};
-}
-
-- (NSRange)selectedRange {
- return NSMakeRange(_input_context_p->GetSelectionRange().position,
- _input_context_p->GetSelectionRange().count);
-}
-
-- (void)setMarkedText:(id)string
- selectedRange:(NSRange)selectedRange
- replacementRange:(NSRange)replacementRange {
- CFStringRef s;
- if ([string isKindOfClass:[NSString class]]) {
- s = (CFStringRef)string;
- } else {
- auto as = (CFAttributedStringRef)string;
- s = CFAttributedStringGetString(as);
- }
-
- auto ss = Convert(s);
-
- // cru::CRU_LOG_DEBUG(u"CruView",
- // u"Received setMarkedText string: {}, selected range: ({}, {}), "
- // u"replacement range: ({}, {}).",
- // ss, selectedRange.location, selectedRange.length, replacementRange.location,
- // replacementRange.length);
-
- if (_input_context_text == nil) {
- _input_context_text = [[NSMutableAttributedString alloc] init];
- _input_context_p->RaiseCompositionStartEvent();
- }
-
- if (replacementRange.location == NSNotFound) replacementRange.location = 0;
-
- [_input_context_text
- replaceCharactersInRange:NSMakeRange(0, [_input_context_text length])
- withAttributedString:[[NSAttributedString alloc] initWithString:(NSString*)s]];
-
- cru::platform::gui::CompositionText composition_text;
- composition_text.text = Convert((CFStringRef)[_input_context_text string]);
- composition_text.selection.position = ss.IndexFromCodePointToCodeUnit(selectedRange.location);
- composition_text.selection.count =
- ss.IndexFromCodePointToCodeUnit(selectedRange.location + selectedRange.length) -
- composition_text.selection.position;
- _input_context_p->SetCompositionText(composition_text);
- _input_context_p->RaiseCompositionEvent();
-}
-
-- (void)unmarkText {
- _input_context_text = nil;
- _input_context_p->RaiseCompositionEndEvent();
-}
-
-- (NSArray<NSAttributedStringKey>*)validAttributesForMarkedText {
- return @[
- (NSString*)kCTUnderlineColorAttributeName, (NSString*)kCTUnderlineStyleAttributeName,
- (NSString*)kCTForegroundColorAttributeName, (NSString*)kCTBackgroundColorAttributeName
- ];
-}
-
-- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range
- actualRange:(NSRangePointer)actualRange {
- cru::Range r(range.location, range.length);
-
- r = r.CoerceInto(0, [_input_context_text length]);
-
- return [_input_context_text attributedSubstringFromRange:NSMakeRange(r.position, r.count)];
-}
-
-- (void)insertText:(id)string replacementRange:(NSRange)replacementRange {
- CFStringRef s;
- if ([string isKindOfClass:[NSString class]]) {
- s = (CFStringRef)string;
- } else {
- auto as = (CFAttributedStringRef)string;
- s = CFAttributedStringGetString(as);
- }
-
- _input_context_text = nil;
- _input_context_p->SetCompositionText(cru::platform::gui::CompositionText());
- cru::String ss = Convert(s);
-
- // cru::CRU_LOG_DEBUG(u"CruView", u"Finish composition: {}, replacement range: ({}, {})", ss,
- // replacementRange.location, replacementRange.length);
-
- _input_context_p->RaiseCompositionEvent();
- _input_context_p->RaiseCompositionEndEvent();
- _input_context_p->RaiseTextEvent(ss);
-}
-
-- (NSUInteger)characterIndexForPoint:(NSPoint)point {
- return NSNotFound;
-}
-
-- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange {
- NSRect result;
- result.origin.x = _input_context_p->GetCandidateWindowPosition().x;
- result.origin.y = _input_context_p->GetCandidateWindowPosition().y;
- result.size.height = 16;
- result.size.width = 0;
- return result;
-}
-
-- (void)doCommandBySelector:(SEL)selector {
- _input_context_p->PerformSel(selector);
-}
-@end
-
-@implementation CruWindowDelegate {
- cru::platform::gui::osx::details::OsxWindowPrivate* _p;
-}
-
-- (id)init:(cru::platform::gui::osx::details::OsxWindowPrivate*)p {
- _p = p;
- return self;
-}
-
-- (void)windowWillClose:(NSNotification*)notification {
- _p->OnWindowWillClose();
-}
-
-- (void)windowDidExpose:(NSNotification*)notification {
- _p->OnWindowDidExpose();
-}
-
-- (void)windowDidUpdate:(NSNotification*)notification {
- _p->OnWindowDidUpdate();
-}
-
-- (void)windowDidMove:(NSNotification*)notification {
- _p->OnWindowDidMove();
-}
-
-- (void)windowDidResize:(NSNotification*)notification {
- _p->OnWindowDidResize();
-}
-
-- (void)windowDidBecomeKey:(NSNotification*)notification {
- _p->OnBecomeKeyWindow();
-}
-
-- (void)windowDidResignKey:(NSNotification*)notification {
- _p->OnResignKeyWindow();
-}
-@end