diff options
Diffstat (limited to 'src/osx')
-rw-r--r-- | src/osx/gui/InputMethod.mm | 88 | ||||
-rw-r--r-- | src/osx/gui/InputMethodPrivate.h | 22 | ||||
-rw-r--r-- | src/osx/gui/Window.mm | 131 | ||||
-rw-r--r-- | src/osx/gui/WindowPrivate.h | 4 |
4 files changed, 121 insertions, 124 deletions
diff --git a/src/osx/gui/InputMethod.mm b/src/osx/gui/InputMethod.mm index 2c4ac643..ec8d194c 100644 --- a/src/osx/gui/InputMethod.mm +++ b/src/osx/gui/InputMethod.mm @@ -7,8 +7,6 @@ #include "cru/osx/Convert.hpp" #include "cru/osx/gui/Window.hpp" -using cru::platform::osx::Convert; - namespace cru::platform::gui::osx { namespace details { OsxInputMethodContextPrivate::OsxInputMethodContextPrivate( @@ -34,14 +32,12 @@ void OsxInputMethodContextPrivate::PerformSel(SEL sel) { } void OsxInputMethodContextPrivate::Activate() { - if (!window_->p_->GetNSWindow()) return; auto input_context = [[window_->p_->GetNSWindow() contentView] inputContext]; Ensures(input_context); [input_context activate]; } void OsxInputMethodContextPrivate::Deactivate() { - if (!window_->p_->GetNSWindow()) return; auto input_context = [[window_->p_->GetNSWindow() contentView] inputContext]; Ensures(input_context); [input_context deactivate]; @@ -95,87 +91,3 @@ IEvent<std::nullptr_t>* OsxInputMethodContext::CompositionEvent() { IEvent<StringView>* OsxInputMethodContext::TextEvent() { return &p_->text_event_; } } - -@implementation CruInputClient { - cru::platform::gui::osx::details::OsxInputMethodContextPrivate* _p; - NSMutableAttributedString* _text; -} - -- (id)init:(cru::platform::gui::osx::details::OsxInputMethodContextPrivate*)p { - _p = p; - return self; -} - -- (BOOL)hasMarkedText { - return _text != nil; -} - -- (NSRange)markedRange { - return _text == nil ? NSRange{NSNotFound, 0} : NSRange{0, [_text length]}; -} - -- (NSRange)selectedRange { - return NSMakeRange(_p->GetSelectionRange().position, _p->GetSelectionRange().count); -} - -- (void)setMarkedText:(id)string - selectedRange:(NSRange)selectedRange - replacementRange:(NSRange)replacementRange { - if (_text == nil) { - _text = [[NSMutableAttributedString alloc] init]; - _p->RaiseCompositionStartEvent(); - } - - [_text deleteCharactersInRange:replacementRange]; - [_text insertAttributedString:[[NSAttributedString alloc] initWithString:(NSString*)string] - atIndex:replacementRange.location]; - - cru::platform::gui::CompositionText composition_text; - composition_text.text = Convert((CFStringRef)[_text string]); - composition_text.selection.position = replacementRange.location + selectedRange.location; - composition_text.selection.count = selectedRange.length; - _p->SetCompositionText(composition_text); - _p->RaiseCompositionEvent(); -} - -- (void)unmarkText { - _text = nil; - _p->RaiseCompositionEndEvent(); -} - -- (NSArray<NSAttributedStringKey>*)validAttributesForMarkedText { - return @[ - (NSString*)kCTUnderlineColorAttributeName, (NSString*)kCTUnderlineStyleAttributeName, - (NSString*)kCTForegroundColorAttributeName, (NSString*)kCTBackgroundColorAttributeName - ]; -} - -- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range - actualRange:(NSRangePointer)actualRange { - return [_text attributedSubstringFromRange:range]; -} - -- (void)insertText:(id)string replacementRange:(NSRange)replacementRange { - _text = nil; - cru::String s = Convert((CFStringRef)string); - _p->RaiseCompositionEndEvent(); - _p->RaiseTextEvent(s); -} - -- (NSUInteger)characterIndexForPoint:(NSPoint)point { - return NSNotFound; -} - -- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange { - NSRect result; - result.origin.x = _p->GetCandidateWindowPosition().x; - result.origin.y = _p->GetCandidateWindowPosition().y; - result.size.height = 16; - result.size.width = 0; - return result; -} - -- (void)doCommandBySelector:(SEL)selector { - _p->PerformSel(selector); -} -@end diff --git a/src/osx/gui/InputMethodPrivate.h b/src/osx/gui/InputMethodPrivate.h index 4b5478e1..d2fccb43 100644 --- a/src/osx/gui/InputMethodPrivate.h +++ b/src/osx/gui/InputMethodPrivate.h @@ -1,11 +1,7 @@ #pragma once #include "cru/osx/gui/InputMethod.hpp" -#import <AppKit/AppKit.h> - -@interface CruInputClient : NSObject <NSTextInputClient> -- (id)init:(cru::platform::gui::osx::details::OsxInputMethodContextPrivate*)p; -@end +#include <AppKit/AppKit.h> namespace cru::platform::gui::osx { namespace details { @@ -13,7 +9,8 @@ class OsxInputMethodContextPrivate { friend OsxInputMethodContext; public: - OsxInputMethodContextPrivate(OsxInputMethodContext* input_method_context, OsxWindow* window); + OsxInputMethodContextPrivate(OsxInputMethodContext* input_method_context, + OsxWindow* window); CRU_DELETE_COPY(OsxInputMethodContextPrivate) CRU_DELETE_MOVE(OsxInputMethodContextPrivate) @@ -30,10 +27,14 @@ class OsxInputMethodContextPrivate { void RaiseTextEvent(StringView text); Point GetCandidateWindowPosition() const { return candidate_window_point_; } - void SetCandidateWindowPosition(const Point& p) { candidate_window_point_ = p; } + void SetCandidateWindowPosition(const Point& p) { + candidate_window_point_ = p; + } Range GetSelectionRange() const { return selection_range_; } - void SetSelectionRange(Range selection_range) { selection_range_ = selection_range; } + void SetSelectionRange(Range selection_range) { + selection_range_ = selection_range; + } void PerformSel(SEL sel); @@ -57,6 +58,5 @@ class OsxInputMethodContextPrivate { Event<std::nullptr_t> composition_end_event_; Event<StringView> text_event_; }; - -} -} +} // namespace details +} // namespace cru::platform::gui::osx diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm index 8e21518e..136c3064 100644 --- a/src/osx/gui/Window.mm +++ b/src/osx/gui/Window.mm @@ -2,6 +2,7 @@ #include "WindowPrivate.h" #include "CursorPrivate.h" +#include "InputMethodPrivate.h" #include "cru/common/Logger.hpp" #include "cru/common/Range.hpp" #include "cru/osx/Convert.hpp" @@ -30,6 +31,7 @@ #include <limits> #include <memory> +using cru::platform::osx::Convert; using cru::platform::graphics::osx::quartz::Convert; namespace cru::platform::gui::osx { @@ -225,6 +227,7 @@ void OsxWindow::CreateWindow() { [p_->window_ setDelegate:p_->window_delegate_]; NSView* content_view = [[CruView alloc] init:p_.get() + input_context_p:p_->input_method_context_->p_.get() frame:Rect(Point{}, p_->content_rect_.GetSize())]; [p_->window_ setContentView:content_view]; @@ -290,16 +293,54 @@ IInputMethodContext* OsxWindow::GetInputMethodContext() { return p_->input_metho - (BOOL)canBecomeKeyWindow { return YES; } + +- (void)keyDown:(NSEvent*)event { + cru::log::TagDebug(u"CruWindow", u"Recieved key down."); + + 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); + + [super keyDown:event]; +} + +- (void)keyUp:(NSEvent*)event { + cru::log::TagDebug(u"CruWindow", u"Recieved key up."); + + 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); + [super keyUp:event]; +} @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) @@ -418,38 +459,80 @@ IInputMethodContext* OsxWindow::GetInputMethodContext() { return p_->input_metho _p->OnMouseWheel(static_cast<float>(event.scrollingDeltaY), p, key_modifier); } -- (void)keyDown:(NSEvent*)event { - cru::log::TagDebug(u"CruView", u"Recieved key down."); +- (BOOL)hasMarkedText { + return _input_context_text != nil; +} - 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); +- (NSRange)markedRange { + return _input_context_text == nil ? NSRange{NSNotFound, 0} + : NSRange{0, [_input_context_text length]}; +} - _p->OnKeyDown(c, key_modifier); +- (NSRange)selectedRange { + return NSMakeRange(_input_context_p->GetSelectionRange().position, + _input_context_p->GetSelectionRange().count); +} - [super keyDown:event]; +- (void)setMarkedText:(id)string + selectedRange:(NSRange)selectedRange + replacementRange:(NSRange)replacementRange { + if (_input_context_text == nil) { + _input_context_text = [[NSMutableAttributedString alloc] init]; + _input_context_p->RaiseCompositionStartEvent(); + } + + [_input_context_text deleteCharactersInRange:replacementRange]; + [_input_context_text + insertAttributedString:[[NSAttributedString alloc] initWithString:(NSString*)string] + atIndex:replacementRange.location]; + + cru::platform::gui::CompositionText composition_text; + composition_text.text = Convert((CFStringRef)[_input_context_text string]); + composition_text.selection.position = replacementRange.location + selectedRange.location; + composition_text.selection.count = selectedRange.length; + _input_context_p->SetCompositionText(composition_text); + _input_context_p->RaiseCompositionEvent(); } -- (void)keyUp:(NSEvent*)event { - cru::log::TagDebug(u"CruView", u"Recieved key up."); +- (void)unmarkText { + _input_context_text = nil; + _input_context_p->RaiseCompositionEndEvent(); +} - 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); +- (NSArray<NSAttributedStringKey>*)validAttributesForMarkedText { + return @[ + (NSString*)kCTUnderlineColorAttributeName, (NSString*)kCTUnderlineStyleAttributeName, + (NSString*)kCTForegroundColorAttributeName, (NSString*)kCTBackgroundColorAttributeName + ]; +} - _p->OnKeyUp(c, key_modifier); +- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range + actualRange:(NSRangePointer)actualRange { + return [_input_context_text attributedSubstringFromRange:range]; +} - [super keyUp:event]; +- (void)insertText:(id)string replacementRange:(NSRange)replacementRange { + _input_context_text = nil; + cru::String s = Convert((CFStringRef)string); + _input_context_p->RaiseCompositionEndEvent(); + _input_context_p->RaiseTextEvent(s); +} + +- (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 diff --git a/src/osx/gui/WindowPrivate.h b/src/osx/gui/WindowPrivate.h index e3b93f8a..076b59d9 100644 --- a/src/osx/gui/WindowPrivate.h +++ b/src/osx/gui/WindowPrivate.h @@ -17,8 +17,10 @@ style:(NSWindowStyleMask)style; @end -@interface CruView : NSView +@interface CruView : NSView <NSTextInputClient> - (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; @end |