From 169d03ab9be4f61403db737dfa8ec905a57ec30f Mon Sep 17 00:00:00 2001 From: zonble Date: Mon, 31 Jan 2022 14:16:16 +0800 Subject: [PATCH] Minor changes on the associated phrases. 1. Removes the tooltip on the candidate window to make the exprience looks like OpenVanilla. 2. Adds a Shift key symbol on the key label. --- .../CandidateUI/CandidateController.swift | 16 ++++++++- .../HorizontalCandidateController.swift | 4 +-- .../VerticalCandidateController.swift | 3 +- Source/AppDelegate.swift | 2 +- Source/InputMethodController.swift | 33 +++++++++---------- Source/KeyHandler.mm | 27 +++++++++------ Source/PreferencesWindowController.swift | 4 ++- 7 files changed, 55 insertions(+), 34 deletions(-) diff --git a/Packages/CandidateUI/Sources/CandidateUI/CandidateController.swift b/Packages/CandidateUI/Sources/CandidateUI/CandidateController.swift index 36eb27b9..df5b0ec0 100644 --- a/Packages/CandidateUI/Sources/CandidateUI/CandidateController.swift +++ b/Packages/CandidateUI/Sources/CandidateUI/CandidateController.swift @@ -23,6 +23,18 @@ import Cocoa +@objc(VTCandidateKeyLabel) +public class CandidateKeyLabel: NSObject { + @objc public private(set) var key: String + @objc public private(set) var displayedText: String + + public init(key: String, displayedText: String) { + self.key = key + self.displayedText = displayedText + super.init() + } +} + @objc(VTCandidateControllerDelegate) public protocol CandidateControllerDelegate: AnyObject { func candidateCountForController(_ controller: CandidateController) -> UInt @@ -62,7 +74,9 @@ public class CandidateController: NSWindowController { } } - @objc public var keyLabels: [String] = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] + @objc public var keyLabels: [CandidateKeyLabel] = ["1", "2", "3", "4", "5", "6", "7", "8", "9"].map { + CandidateKeyLabel(key: $0, displayedText: $0) + } @objc public var keyLabelFont: NSFont = NSFont.systemFont(ofSize: 14) @objc public var candidateFont: NSFont = NSFont.systemFont(ofSize: 18) @objc public var tooltip: String = "" diff --git a/Packages/CandidateUI/Sources/CandidateUI/HorizontalCandidateController.swift b/Packages/CandidateUI/Sources/CandidateUI/HorizontalCandidateController.swift index 37ad07ea..4945db6f 100644 --- a/Packages/CandidateUI/Sources/CandidateUI/HorizontalCandidateController.swift +++ b/Packages/CandidateUI/Sources/CandidateUI/HorizontalCandidateController.swift @@ -73,7 +73,6 @@ fileprivate class HorizontalCandidateView: NSView { return result } - @objc(setKeyLabels:displayedCandidates:) func set(keyLabels labels: [String], displayedCandidates candidates: [String]) { let count = min(labels.count, candidates.count) keyLabels = Array(labels[0..= candidateFontSize) ? 0.0 : floor((candidateFontSize - keyLabelFontSize) / 2.0) let rowHeight = ceil(fontSize * 1.25) diff --git a/Source/AppDelegate.swift b/Source/AppDelegate.swift index 6cf344b6..067814ec 100644 --- a/Source/AppDelegate.swift +++ b/Source/AppDelegate.swift @@ -248,7 +248,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NonModalAlertWindowControlle } } -extension AppDelegate : FSEventStreamHelperDelegate { +extension AppDelegate: FSEventStreamHelperDelegate { func helper(_ helper: FSEventStreamHelper, didReceive events: [FSEventStreamHelper.Event]) { DispatchQueue.main.async { LanguageModelManager.loadUserPhrases() diff --git a/Source/InputMethodController.swift b/Source/InputMethodController.swift index f8b149a0..3b0982f6 100644 --- a/Source/InputMethodController.swift +++ b/Source/InputMethodController.swift @@ -437,11 +437,10 @@ extension McBopomofoInputMethodController { extension McBopomofoInputMethodController { private func show(candidateWindowWith state: InputState, client: Any!) { - let useVerticalMode:Bool = { + let useVerticalMode: Bool = { if let state = state as? InputState.ChoosingCandidate { return state.useVerticalMode - } - else if let state = state as? InputState.AssociatedPhrases { + } else if let state = state as? InputState.AssociatedPhrases { return state.useVerticalMode } return false @@ -455,12 +454,6 @@ extension McBopomofoInputMethodController { gCurrentCandidateController = McBopomofoInputMethodController.verticalCandidateController } - if state is InputState.AssociatedPhrases { - gCurrentCandidateController?.tooltip = NSLocalizedString("Associated Phrases", comment: "") - } else { - gCurrentCandidateController?.tooltip = "" - } - // set the attributes for the candidate panel (which uses NSAttributedString) let textSize = Preferences.candidateListTextSize let keyLabelSize = max(textSize / 2, kMinKeyLabelSize) @@ -477,10 +470,11 @@ extension McBopomofoInputMethodController { let candidateKeys = Preferences.candidateKeys let keyLabels = candidateKeys.count > 4 ? Array(candidateKeys) : Array(Preferences.defaultCandidateKeys) + let keyLabelPrefix = state is InputState.AssociatedPhrases ? "⇧ " : "" + gCurrentCandidateController?.keyLabels = keyLabels.map { + CandidateKeyLabel(key: String($0), displayedText: keyLabelPrefix + String($0)) + } - gCurrentCandidateController?.keyLabels = Array(keyLabels.map { - String($0) - }) gCurrentCandidateController?.delegate = self gCurrentCandidateController?.reloadData() currentCandidateClient = client @@ -488,7 +482,7 @@ extension McBopomofoInputMethodController { gCurrentCandidateController?.visible = true var lineHeightRect = NSMakeRect(0.0, 0.0, 16.0, 16.0) - var cursor:UInt = 0 + var cursor: UInt = 0 if let state = state as? InputState.ChoosingCandidate { cursor = state.cursorIndex @@ -579,10 +573,10 @@ extension McBopomofoInputMethodController: CandidateControllerDelegate { if keyHandler.inputMode == .plainBopomofo { keyHandler.clear() - let text = inputting.composingBuffer - handle(state: .Committing(poppedText: text), client: currentCandidateClient) + let composingBuffer = inputting.composingBuffer + handle(state: .Committing(poppedText: composingBuffer), client: currentCandidateClient) if Preferences.associatedPhrasesEnabled, - let associatePhrases = keyHandler.buildAssociatePhraseState(withKey: text, useVerticalMode: state.useVerticalMode) as? InputState.AssociatedPhrases { + let associatePhrases = keyHandler.buildAssociatePhraseState(withKey: composingBuffer, useVerticalMode: state.useVerticalMode) as? InputState.AssociatedPhrases { self.handle(state: associatePhrases, client: self.currentCandidateClient) } else { handle(state: .Empty(), client: currentDeferredClient) @@ -593,7 +587,12 @@ extension McBopomofoInputMethodController: CandidateControllerDelegate { } else if let state = state as? InputState.AssociatedPhrases { let selectedValue = state.candidates[Int(index)] handle(state: .Committing(poppedText: selectedValue), client: currentCandidateClient) - handle(state: .Empty(), client: currentDeferredClient) + if Preferences.associatedPhrasesEnabled, + let associatePhrases = keyHandler.buildAssociatePhraseState(withKey: selectedValue, useVerticalMode: state.useVerticalMode) as? InputState.AssociatedPhrases { + self.handle(state: associatePhrases, client: self.currentCandidateClient) + } else { + handle(state: .Empty(), client: currentDeferredClient) + } } } } diff --git a/Source/KeyHandler.mm b/Source/KeyHandler.mm index d777d197..44d53e05 100644 --- a/Source/KeyHandler.mm +++ b/Source/KeyHandler.mm @@ -890,8 +890,11 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot } if (charCode == 13 || [input isEnter]) { - if ([state isKindOfClass: [InputStateAssociatedPhrases class]] && ![input isShiftHold]) { - return NO; + if ([state isKindOfClass: [InputStateAssociatedPhrases class]]) { + [self clear]; + InputStateEmptyIgnoringPreviousState *empty = [[InputStateEmptyIgnoringPreviousState alloc] init]; + stateCallback(empty); + return YES; } [self.delegate keyHandler:self didSelectCandidateAtIndex:gCurrentCandidateController.selectedCandidateIndex candidateController:gCurrentCandidateController]; return YES; @@ -1012,10 +1015,12 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot if ([state isKindOfClass: [InputStateChoosingCandidate class]]) { candidates = [(InputStateChoosingCandidate *)state candidates]; + } else if ([state isKindOfClass: [InputStateAssociatedPhrases class]]) { + candidates = [(InputStateAssociatedPhrases *)state candidates]; } - if ([state isKindOfClass: [InputStateAssociatedPhrases class]]) { - candidates = [(InputStateAssociatedPhrases *)state candidates]; + if (!candidates) { + return NO; } if (([input isEnd] || input.emacsKey == McBopomofoEmacsKeyEnd) && candidates.count > 0) { @@ -1029,21 +1034,23 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot return YES; } - if ([state isKindOfClass: [InputStateAssociatedPhrases class]]) { + if ([state isKindOfClass:[InputStateAssociatedPhrases class]]) { if (![input isShiftHold]) { return NO; } } NSInteger index = NSNotFound; - NSString *match = inputText; - - if ([state isKindOfClass: [InputStateAssociatedPhrases class]]) { + NSString *match; + if ([state isKindOfClass:[InputStateAssociatedPhrases class]]) { match = input.inputTextIgnoringModifiers; + } else { + match = inputText; } for (NSUInteger j = 0, c = [gCurrentCandidateController.keyLabels count]; j < c; j++) { - if ([match compare:[gCurrentCandidateController.keyLabels objectAtIndex:j] options:NSCaseInsensitiveSearch] == NSOrderedSame) { + VTCandidateKeyLabel *label = gCurrentCandidateController.keyLabels[j]; + if ([match compare:label.key options:NSCaseInsensitiveSearch] == NSOrderedSame) { index = j; break; } @@ -1057,7 +1064,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot } } - if ([state isKindOfClass: [InputStateAssociatedPhrases class]]) { + if ([state isKindOfClass:[InputStateAssociatedPhrases class]]) { return NO; } diff --git a/Source/PreferencesWindowController.swift b/Source/PreferencesWindowController.swift index acbf1e0c..8e1baddd 100644 --- a/Source/PreferencesWindowController.swift +++ b/Source/PreferencesWindowController.swift @@ -133,7 +133,9 @@ import Carbon } @IBAction func changeSelectionKeyAction(_ sender: Any) { - guard let keys = (sender as AnyObject).stringValue?.trimmingCharacters(in: .whitespacesAndNewlines) else { + guard let keys = (sender as AnyObject).stringValue? + .trimmingCharacters(in: .whitespacesAndNewlines) + .lowercased() else { return } do {