From 6d1bd824517870b7cd4a19d9882f73eb924f5fc3 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Wed, 1 Jun 2022 19:00:59 +0800 Subject: [PATCH] KeyHandler // Add tooltips for rare cursor position cases. --- .../ControllerModules/KeyHandler_States.swift | 44 +++++++++++++++++-- .../Resources/Base.lproj/Localizable.strings | 2 + Source/Resources/en.lproj/Localizable.strings | 2 + Source/Resources/ja.lproj/Localizable.strings | 2 + .../zh-Hans.lproj/Localizable.strings | 2 + .../zh-Hant.lproj/Localizable.strings | 2 + 6 files changed, 51 insertions(+), 3 deletions(-) diff --git a/Source/Modules/ControllerModules/KeyHandler_States.swift b/Source/Modules/ControllerModules/KeyHandler_States.swift index 752faad0..fa8693f4 100644 --- a/Source/Modules/ControllerModules/KeyHandler_States.swift +++ b/Source/Modules/ControllerModules/KeyHandler_States.swift @@ -34,13 +34,13 @@ extension KeyHandler { var buildInputtingState: InputState.Inputting { // "Updating the composing buffer" means to request the client // to "refresh" the text input buffer with our "composing text" + var tooltipParameterRef: [String] = ["", ""] var composingBuffer = "" var composedStringCursorIndex = 0 var readingCursorIndex = 0 // We must do some Unicode codepoint counting to find the actual cursor location for the client // i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars - // locations. These processes are inherited from the ObjC++ version of this class and might be - // unnecessary in Swift, but this deduction requires further experiments. + // locations. Even if we are using Swift, NSString is still necessary here. for walkedNode in _walkedNodes { if let theNode = walkedNode.node { let strNodeValue = theNode.currentKeyValue.value @@ -72,6 +72,22 @@ extension KeyHandler { if readingCursorIndex > builderCursorIndex { readingCursorIndex = builderCursorIndex } + // Now we start preparing the contents of the tooltips used + // in cases of moving cursors across certain emojis which emoji + // char count is inequal to the reading count. + // Example in McBopomofo: Typing 王建民 (3 readings) gets a tree emoji. + // Example in vChewing: Typing 義麵 (two readings) gets a pasta emoji. + switch builderCursorIndex { + case _builder.readings.count...: + tooltipParameterRef[0] = _builder.readings[_builder.readings.count - 1] + case 0: + tooltipParameterRef[1] = _builder.readings[builderCursorIndex] + default: + do { + tooltipParameterRef[0] = _builder.readings[builderCursorIndex - 1] + tooltipParameterRef[1] = _builder.readings[builderCursorIndex] + } + } } } } @@ -87,7 +103,29 @@ extension KeyHandler { let composedText = head + reading + tail let cursorIndex = composedStringCursorIndex + reading.count - return InputState.Inputting(composingBuffer: composedText, cursorIndex: UInt(cursorIndex)) + let stateResult = InputState.Inputting(composingBuffer: composedText, cursorIndex: UInt(cursorIndex)) + + // Now we start weaving the contents of the tooltip. + if tooltipParameterRef[0].isEmpty, tooltipParameterRef[1].isEmpty { + stateResult.tooltip = "" + } else if tooltipParameterRef[0].isEmpty { + stateResult.tooltip = String( + format: NSLocalizedString("Cursor is to the rear of \"%@\".", comment: ""), + tooltipParameterRef[1] + ) + } else if tooltipParameterRef[1].isEmpty { + stateResult.tooltip = String( + format: NSLocalizedString("Cursor is in front of \"%@\".", comment: ""), + tooltipParameterRef[0] + ) + } else { + stateResult.tooltip = String( + format: NSLocalizedString("Cursor is between \"%@\" and \"%@\".", comment: ""), + tooltipParameterRef[0], tooltipParameterRef[1] + ) + } + + return stateResult } // MARK: - 用以生成候選詞陣列及狀態 diff --git a/Source/Resources/Base.lproj/Localizable.strings b/Source/Resources/Base.lproj/Localizable.strings index 7c518d3b..55469beb 100644 --- a/Source/Resources/Base.lproj/Localizable.strings +++ b/Source/Resources/Base.lproj/Localizable.strings @@ -57,6 +57,8 @@ "Edit User Symbol & Emoji Data…" = "Edit User Symbol & Emoji Data…"; "Choose your desired user data folder." = "Choose your desired user data folder."; "Cursor is between \"%@\" and \"%@\"." = "Cursor is between \"%@\" and \"%@\"."; +"Cursor is to the rear of \"%@\"." = "Cursor is to the rear of \"%@\"."; +"Cursor is in front of \"%@\"." = "Cursor is in front of \"%@\"."; "Loading CHS Core Dict..." = "Loading CHS Core Dict..."; "Loading CHT Core Dict..." = "Loading CHT Core Dict..."; "Core Dict loading complete." = "Core Dict loading complete."; diff --git a/Source/Resources/en.lproj/Localizable.strings b/Source/Resources/en.lproj/Localizable.strings index 7c518d3b..55469beb 100644 --- a/Source/Resources/en.lproj/Localizable.strings +++ b/Source/Resources/en.lproj/Localizable.strings @@ -57,6 +57,8 @@ "Edit User Symbol & Emoji Data…" = "Edit User Symbol & Emoji Data…"; "Choose your desired user data folder." = "Choose your desired user data folder."; "Cursor is between \"%@\" and \"%@\"." = "Cursor is between \"%@\" and \"%@\"."; +"Cursor is to the rear of \"%@\"." = "Cursor is to the rear of \"%@\"."; +"Cursor is in front of \"%@\"." = "Cursor is in front of \"%@\"."; "Loading CHS Core Dict..." = "Loading CHS Core Dict..."; "Loading CHT Core Dict..." = "Loading CHT Core Dict..."; "Core Dict loading complete." = "Core Dict loading complete."; diff --git a/Source/Resources/ja.lproj/Localizable.strings b/Source/Resources/ja.lproj/Localizable.strings index 36d79218..1d0f6f16 100644 --- a/Source/Resources/ja.lproj/Localizable.strings +++ b/Source/Resources/ja.lproj/Localizable.strings @@ -57,6 +57,8 @@ "Edit User Symbol & Emoji Data…" = "ユーザー符号&絵文字辞書を編集…"; "Choose your desired user data folder." = "欲しがるユーザー辞書フォルダをお選びください。"; "Cursor is between \"%@\" and \"%@\"." = "カーソルは「%@」と「%@」に間れ。"; +"Cursor is to the rear of \"%@\"." = "カーソルは「%@」の後ろに。"; +"Cursor is in front of \"%@\"." = "カーソルは「%@」の前に。"; "Loading CHS Core Dict..." = "簡体中国語核心辞書読込中…"; "Loading CHT Core Dict..." = "繁体中国語核心辞書読込中…"; "Core Dict loading complete." = "核心辞書読込完了"; diff --git a/Source/Resources/zh-Hans.lproj/Localizable.strings b/Source/Resources/zh-Hans.lproj/Localizable.strings index 20e7847c..89b4c435 100644 --- a/Source/Resources/zh-Hans.lproj/Localizable.strings +++ b/Source/Resources/zh-Hans.lproj/Localizable.strings @@ -57,6 +57,8 @@ "Edit User Symbol & Emoji Data…" = "编辑自订符号&绘文字资料…"; "Choose your desired user data folder." = "请选择您想指定的使用者语汇档案目录。"; "Cursor is between \"%@\" and \"%@\"." = "游标介于「%@」与「%@」之间。"; +"Cursor is to the rear of \"%@\"." = "游标在「%@」的后方。"; +"Cursor is in front of \"%@\"." = "游标在「%@」的前方。."; "Loading CHS Core Dict..." = "载入简体中文核心辞典…"; "Loading CHT Core Dict..." = "载入繁体中文核心辞典…"; "Core Dict loading complete." = "核心辞典载入完毕"; diff --git a/Source/Resources/zh-Hant.lproj/Localizable.strings b/Source/Resources/zh-Hant.lproj/Localizable.strings index dd8a587d..232da7f1 100644 --- a/Source/Resources/zh-Hant.lproj/Localizable.strings +++ b/Source/Resources/zh-Hant.lproj/Localizable.strings @@ -57,6 +57,8 @@ "Edit User Symbol & Emoji Data…" = "編輯自訂符號&繪文字資料…"; "Choose your desired user data folder." = "請選擇您想指定的使用者語彙檔案目錄。"; "Cursor is between \"%@\" and \"%@\"." = "游標介於「%@」與「%@」之間。"; +"Cursor is to the rear of \"%@\"." = "游標在「%@」的後方。"; +"Cursor is in front of \"%@\"." = "游標在「%@」的前方。."; "Loading CHS Core Dict..." = "載入簡體中文核心辭典…"; "Loading CHT Core Dict..." = "載入繁體中文核心辭典…"; "Core Dict loading complete." = "核心辭典載入完畢";