From 0f3e84f0ef4c62d20e5cb4d9e5677ec39afb894d Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 17 Nov 2021 19:41:39 +0800 Subject: ... --- include/cru/platform/gui/Keyboard.hpp | 7 ++++ include/cru/ui/controls/TextHostControlService.hpp | 2 ++ src/osx/gui/Window.mm | 41 ++++++++++++++++------ src/ui/controls/TextHostControlService.cpp | 14 ++++++++ 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/include/cru/platform/gui/Keyboard.hpp b/include/cru/platform/gui/Keyboard.hpp index 926b8d91..347b57bc 100644 --- a/include/cru/platform/gui/Keyboard.hpp +++ b/include/cru/platform/gui/Keyboard.hpp @@ -125,8 +125,15 @@ struct KeyModifiers { static constexpr KeyModifier shift{0b1}; static constexpr KeyModifier ctrl{0b10}; static constexpr KeyModifier alt{0b100}; + static constexpr KeyModifier command{0b1000}; }; +#ifdef CRU_PLATFORM_OSX +constexpr KeyModifier kKeyModifierCommand = KeyModifiers::command; +#else +constexpr KeyModifier kKeyModifierCommand = KeyModifiers::ctrl; +#endif + CRU_PLATFORM_GUI_API String ToString(KeyCode key_code); CRU_PLATFORM_GUI_API String ToString(KeyModifier key_modifier, StringView separator = u"+"); diff --git a/include/cru/ui/controls/TextHostControlService.hpp b/include/cru/ui/controls/TextHostControlService.hpp index f63a45c2..1b0908ce 100644 --- a/include/cru/ui/controls/TextHostControlService.hpp +++ b/include/cru/ui/controls/TextHostControlService.hpp @@ -119,6 +119,8 @@ class TextHostControlService : public Object { void SetSelection(gsl::index caret_position); void SetSelection(TextRange selection, bool scroll_to_caret = true); + void SelectAll(); + void ChangeSelectionEnd(gsl::index new_end); void AbortSelection(); diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm index 04ec4bce..a026a455 100644 --- a/src/osx/gui/Window.mm +++ b/src/osx/gui/Window.mm @@ -31,6 +31,10 @@ #include #include +namespace { +constexpr int key_down_debug = 0; +} + using cru::platform::osx::Convert; using cru::platform::graphics::osx::quartz::Convert; @@ -292,6 +296,8 @@ cru::platform::gui::KeyModifier GetKeyModifier(NSEvent* event) { 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; } } @@ -432,14 +438,25 @@ cru::platform::gui::KeyModifier GetKeyModifier(NSEvent* event) { namespace { using cru::platform::gui::KeyCode; -const std::unordered_set bypass_codes{KeyCode::Return, KeyCode::Space, KeyCode::Backspace, - KeyCode::Delete, KeyCode::Left, KeyCode::Right, - KeyCode::Up, KeyCode::Down, KeyCode::Home, - KeyCode::End, KeyCode::PageUp, KeyCode::PageDown}; +const std::unordered_set 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}; } +const std::unordered_set 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 { - // cru::log::TagDebug(u"CruView", u"Recieved key down."); + if constexpr (key_down_debug) { + cru::log::TagDebug(u"CruView", u"Recieved key down."); + } + + auto key_modifier = GetKeyModifier(event); bool handled = false; @@ -450,8 +467,11 @@ const std::unordered_set bypass_codes{KeyCode::Return, KeyCode::Space, auto c = cru::platform::gui::osx::KeyCodeFromOsxToCru(event.keyCode); if (input_context->IsEnabled()) { - if (bypass_codes.count(c)) { - if (!(input_context->GetCompositionText().text.empty())) { + 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) { @@ -462,14 +482,15 @@ const std::unordered_set bypass_codes{KeyCode::Return, KeyCode::Space, handled = true; } } - } else { - handled = [[self inputContext] handleEvent:event]; } } if (!handled) { - auto key_modifier = GetKeyModifier(event); _p->OnKeyDown(c, key_modifier); + } else { + if constexpr (key_down_debug) { + cru::log::TagDebug(u"CruView", u"Key down is handled by input context."); + } } } diff --git a/src/ui/controls/TextHostControlService.cpp b/src/ui/controls/TextHostControlService.cpp index 42153ffd..edfabb94 100644 --- a/src/ui/controls/TextHostControlService.cpp +++ b/src/ui/controls/TextHostControlService.cpp @@ -318,6 +318,10 @@ void TextHostControlService::SetSelection(TextRange selection, } } +void TextHostControlService::SelectAll() { + this->SetSelection(TextRange{0, this->text_.size()}); +} + void TextHostControlService::ChangeSelectionEnd(Index new_end) { auto selection = GetSelection(); selection.ChangeEnd(new_end); @@ -482,6 +486,16 @@ void TextHostControlService::LoseFocusHandler( void TextHostControlService::SetUpShortcuts() { using platform::gui::KeyCode; using platform::gui::KeyModifiers; + using platform::gui::kKeyModifierCommand; + + shortcut_hub_.RegisterShortcut(u"Select All", + {KeyCode::A, kKeyModifierCommand}, [this] { + if (IsEnabled()) { + this->SelectAll(); + return true; + } + return false; + }); shortcut_hub_.RegisterShortcut(u"Backspace", KeyCode::Backspace, [this] { if (!IsEnabled()) return false; -- cgit v1.2.3