From d52678c9592b71d976e49b17b35beb3d6ae58abc Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Sat, 10 Sep 2022 19:13:45 +0800 Subject: [PATCH] ctlIME // Add "lineHeightRect" and simplify display process. --- .../ctlInputMethod_HandleDisplay.swift | 55 +++++++++---------- .../ctlInputMethod_HandleStates.swift | 15 +---- 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift b/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift index a969cc21..7e7d25b2 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift @@ -13,19 +13,31 @@ import Cocoa // MARK: - Tooltip Display and Candidate Display Methods extension ctlInputMethod { - func show(tooltip: String, displayedText: String, u16Cursor: Int) { - guard let client = client() else { return } - var lineHeightRect = NSRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0) - var cursor = u16Cursor - if cursor == displayedText.utf16.count, cursor != 0 { - cursor -= 1 + func lineHeightRect(zeroCursor: Bool = false) -> NSRect { + var lineHeightRect = NSRect.seniorTheBeast + guard let client = client() else { + return lineHeightRect } - while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, cursor >= 0 { + var u16Cursor: Int = { + // iMessage 在 cursor == 0 時的計算會有一些偏差,所以例外處理。 + if clientBundleIdentifier == "com.apple.MobileSMS" { return state.data.u16Cursor } + if state.data.marker >= state.data.cursor { return state.data.u16Cursor } + return state.data.u16Marker // 這樣可以讓工具提示視窗始終盡量往書寫方向的後方顯示。 + }() + u16Cursor = max(min(state.data.displayedTextConverted.utf16.count, u16Cursor), 0) + if zeroCursor { u16Cursor = 0 } + while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, u16Cursor >= 0 { client.attributes( - forCharacterIndex: cursor, lineHeightRectangle: &lineHeightRect + forCharacterIndex: u16Cursor, lineHeightRectangle: &lineHeightRect ) - cursor -= 1 + u16Cursor -= 1 } + return lineHeightRect + } + + func show(tooltip: String) { + guard client() != nil else { return } + let lineHeightRect = lineHeightRect() var finalOrigin: NSPoint = lineHeightRect.origin let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight if isVerticalTyping { @@ -120,34 +132,17 @@ extension ctlInputMethod { ctlInputMethod.ctlCandidateCurrent.visible = true - var lineHeightRect = NSRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0) - var cursor = 0 - - if [.ofCandidates, .ofSymbolTable].contains(state.type) { - cursor = state.data.u16Cursor - if cursor == state.displayedText.utf16.count, cursor != 0 { - cursor -= 1 - } - } - - while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, cursor >= 0 { - client.attributes( - forCharacterIndex: cursor, lineHeightRectangle: &lineHeightRect - ) - cursor -= 1 - } - if isVerticalTyping { ctlInputMethod.ctlCandidateCurrent.set( windowTopLeftPoint: NSPoint( - x: lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, y: lineHeightRect.origin.y - 4.0 + x: lineHeightRect().origin.x + lineHeightRect().size.width + 4.0, y: lineHeightRect().origin.y - 4.0 ), - bottomOutOfScreenAdjustmentHeight: lineHeightRect.size.height + 4.0 + bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0 ) } else { ctlInputMethod.ctlCandidateCurrent.set( - windowTopLeftPoint: NSPoint(x: lineHeightRect.origin.x, y: lineHeightRect.origin.y - 4.0), - bottomOutOfScreenAdjustmentHeight: lineHeightRect.size.height + 4.0 + windowTopLeftPoint: NSPoint(x: lineHeightRect().origin.x, y: lineHeightRect().origin.y - 4.0), + bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0 ) } } diff --git a/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift b/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift index 6bb1b30b..0c23eb42 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift @@ -65,10 +65,8 @@ extension ctlInputMethod { if !textToCommit.isEmpty { commit(text: textToCommit) } setInlineDisplayWithCursor() if !state.tooltip.isEmpty { - show( - tooltip: state.tooltip, displayedText: state.displayedText, - u16Cursor: state.data.u16Cursor - ) + show(tooltip: state.tooltip) + } } case .ofMarking: ctlInputMethod.ctlCandidateCurrent.visible = false @@ -76,14 +74,7 @@ extension ctlInputMethod { if state.tooltip.isEmpty { ctlInputMethod.tooltipInstance.hide() } else { - let cursorReference: Int = { - if state.data.marker >= state.data.cursor { return state.data.u16Cursor } - return state.data.u16Marker // 這樣可以讓工具提示視窗始終盡量往書寫方向的後方顯示。 - }() - show( - tooltip: state.tooltip, displayedText: state.displayedText, - u16Cursor: cursorReference - ) + show(tooltip: state.tooltip) } case .ofCandidates, .ofAssociates, .ofSymbolTable: ctlInputMethod.tooltipInstance.hide()