Repo // Deprecating Zonble's Tooltip controller.
This commit is contained in:
parent
21c369defb
commit
3cb0872a1d
|
@ -88,7 +88,7 @@
|
|||
- ctlInputMethod 輸入法主控制器內則採用策略設計模式來處理各種狀態。
|
||||
- 半衰記憶模組的 C++ 原版作者是 Mengjuei Hsieh,且由 Shiki Suen 用 Swift 與 C# 分別重寫、繼續開發。
|
||||
- 僅供研發人員調試方便而使用的 App 版安裝程式 (by Zonble Yang),不對公眾使用。
|
||||
- Voltaire MK2 選字窗、飄雲通知視窗、工具提示 (by Zonble Yang),有大幅度修改。
|
||||
- Voltaire MK2 選字窗、飄雲通知視窗 (by Zonble Yang),有大幅度修改。
|
||||
|
||||
威注音輸入法 macOS 版以 MIT-NTL License 授權釋出 (與 MIT 相容):© 2021-2022 vChewing 專案。
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
- ctlInputMethod 输入法主控制器内则采用策略设计模式来处理各种状态。
|
||||
- 半衰记忆模组的 C++ 原版作者是 Mengjuei Hsieh,且由 Shiki Suen 用 Swift 与 C# 分别重写、继续开发。
|
||||
- 仅供研发人员调试方便而使用的 App 版安装程式 (by Zonble Yang),不对公众使用。
|
||||
- Voltaire MK2 选字窗、飘云通知视窗、工具提示 (by Zonble Yang),有大幅度修改。
|
||||
- Voltaire MK2 选字窗、飘云通知视窗 (by Zonble Yang),有大幅度修改。
|
||||
|
||||
威注音输入法 macOS 版以 MIT-NTL License 授权释出 (与 MIT 相容):© 2021-2022 vChewing 专案。
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ extension StateData {
|
|||
}
|
||||
arrOutput.append(neta)
|
||||
}
|
||||
return arrOutput.joined(separator: " ")
|
||||
return arrOutput.joined(separator: "\u{A0}")
|
||||
}
|
||||
|
||||
/// 更新工具提示內容、以及對應配對是否在庫。
|
||||
|
@ -187,7 +187,7 @@ extension StateData {
|
|||
public static func updateParameters(_ data: inout StateData) {
|
||||
var tooltipGenerated: String {
|
||||
if mgrPrefs.phraseReplacementEnabled {
|
||||
ctlInputMethod.tooltipController.setColor(state: .warning)
|
||||
ctlInputMethod.tooltipInstance.setColor(state: .warning)
|
||||
return NSLocalizedString(
|
||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry.", comment: ""
|
||||
)
|
||||
|
@ -198,18 +198,18 @@ extension StateData {
|
|||
|
||||
let text = data.displayedText.charComponents[data.markedRange].joined()
|
||||
if data.markedRange.count < mgrPrefs.allowedMarkRange.lowerBound {
|
||||
ctlInputMethod.tooltipController.setColor(state: .denialInsufficiency)
|
||||
ctlInputMethod.tooltipInstance.setColor(state: .denialInsufficiency)
|
||||
return String(
|
||||
format: NSLocalizedString(
|
||||
"\"%@\" length must ≥ 2 for a user phrase.", comment: ""
|
||||
) + "\n// " + generateReadingThread(data), text
|
||||
) + "\n◆ " + generateReadingThread(data), text
|
||||
)
|
||||
} else if data.markedRange.count > mgrPrefs.allowedMarkRange.upperBound {
|
||||
ctlInputMethod.tooltipController.setColor(state: .denialOverflow)
|
||||
ctlInputMethod.tooltipInstance.setColor(state: .denialOverflow)
|
||||
return String(
|
||||
format: NSLocalizedString(
|
||||
"\"%@\" length should ≤ %d for a user phrase.", comment: ""
|
||||
) + "\n// " + generateReadingThread(data), text, mgrPrefs.allowedMarkRange.upperBound
|
||||
) + "\n◆ " + generateReadingThread(data), text, mgrPrefs.allowedMarkRange.upperBound
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -219,17 +219,17 @@ extension StateData {
|
|||
)
|
||||
if exist {
|
||||
data.markedTargetExists = exist
|
||||
ctlInputMethod.tooltipController.setColor(state: .prompt)
|
||||
ctlInputMethod.tooltipInstance.setColor(state: .prompt)
|
||||
return String(
|
||||
format: NSLocalizedString(
|
||||
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.",
|
||||
comment: ""
|
||||
) + "\n// " + generateReadingThread(data), text
|
||||
) + "\n◆ " + generateReadingThread(data), text
|
||||
)
|
||||
}
|
||||
ctlInputMethod.tooltipController.resetColor()
|
||||
ctlInputMethod.tooltipInstance.resetColor()
|
||||
return String(
|
||||
format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: "") + "\n// "
|
||||
format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: "") + "\n◆ "
|
||||
+ generateReadingThread(data),
|
||||
text
|
||||
)
|
||||
|
|
|
@ -27,8 +27,8 @@ class ctlInputMethod: IMKInputController {
|
|||
static var ctlCandidateCurrent: ctlCandidateProtocol =
|
||||
mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
|
||||
|
||||
/// 工具提示視窗的副本。
|
||||
static let tooltipController = TooltipController()
|
||||
/// 工具提示視窗的副本,每次都重新初始化。
|
||||
static var tooltipInstance = ctlTooltip()
|
||||
|
||||
// MARK: -
|
||||
|
||||
|
|
|
@ -27,15 +27,21 @@ extension ctlInputMethod {
|
|||
cursor -= 1
|
||||
}
|
||||
var finalOrigin: NSPoint = lineHeightRect.origin
|
||||
let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
|
||||
if isVerticalTyping {
|
||||
finalOrigin = NSPoint(
|
||||
x: lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, y: lineHeightRect.origin.y - 4.0
|
||||
x: lineHeightRect.origin.x + lineHeightRect.size.width + 5, y: lineHeightRect.origin.y
|
||||
)
|
||||
ctlInputMethod.tooltipInstance.show(
|
||||
tooltip: tooltip, at: finalOrigin,
|
||||
bottomOutOfScreenAdjustmentHeight: delta, direction: .vertical
|
||||
)
|
||||
ctlInputMethod.tooltipController.direction = .vertical
|
||||
} else {
|
||||
ctlInputMethod.tooltipController.direction = .horizontal
|
||||
ctlInputMethod.tooltipInstance.show(
|
||||
tooltip: tooltip, at: finalOrigin,
|
||||
bottomOutOfScreenAdjustmentHeight: delta, direction: .horizontal
|
||||
)
|
||||
}
|
||||
ctlInputMethod.tooltipController.show(tooltip: tooltip, at: finalOrigin)
|
||||
}
|
||||
|
||||
func show(candidateWindowWith state: IMEStateProtocol) {
|
||||
|
|
|
@ -25,7 +25,7 @@ extension ctlInputMethod {
|
|||
case .ofDeactivated:
|
||||
ctlInputMethod.ctlCandidateCurrent.delegate = nil
|
||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||
ctlInputMethod.tooltipController.hide()
|
||||
ctlInputMethod.tooltipInstance.hide()
|
||||
if previous.hasComposition {
|
||||
commit(text: previous.displayedText)
|
||||
}
|
||||
|
@ -39,20 +39,20 @@ extension ctlInputMethod {
|
|||
previous = state
|
||||
}
|
||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||
ctlInputMethod.tooltipController.hide()
|
||||
ctlInputMethod.tooltipInstance.hide()
|
||||
// 全專案用以判斷「.Abortion」的地方僅此一處。
|
||||
if previous.hasComposition, state.type != .ofAbortion {
|
||||
commit(text: previous.displayedText)
|
||||
}
|
||||
// 在這裡手動再取消一次選字窗與工具提示的顯示,可謂雙重保險。
|
||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||
ctlInputMethod.tooltipController.hide()
|
||||
ctlInputMethod.tooltipInstance.hide()
|
||||
clearInlineDisplay()
|
||||
// 最後一道保險
|
||||
keyHandler.clear()
|
||||
case .ofCommitting:
|
||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||
ctlInputMethod.tooltipController.hide()
|
||||
ctlInputMethod.tooltipInstance.hide()
|
||||
let textToCommit = state.textToCommit
|
||||
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
||||
clearInlineDisplay()
|
||||
|
@ -60,7 +60,7 @@ extension ctlInputMethod {
|
|||
keyHandler.clear()
|
||||
case .ofInputting:
|
||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||
ctlInputMethod.tooltipController.hide()
|
||||
ctlInputMethod.tooltipInstance.hide()
|
||||
let textToCommit = state.textToCommit
|
||||
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
||||
setInlineDisplayWithCursor()
|
||||
|
@ -74,7 +74,7 @@ extension ctlInputMethod {
|
|||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||
setInlineDisplayWithCursor()
|
||||
if state.tooltip.isEmpty {
|
||||
ctlInputMethod.tooltipController.hide()
|
||||
ctlInputMethod.tooltipInstance.hide()
|
||||
} else {
|
||||
let cursorReference: Int = {
|
||||
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
|
||||
|
@ -86,7 +86,7 @@ extension ctlInputMethod {
|
|||
)
|
||||
}
|
||||
case .ofCandidates, .ofAssociates, .ofSymbolTable:
|
||||
ctlInputMethod.tooltipController.hide()
|
||||
ctlInputMethod.tooltipInstance.hide()
|
||||
setInlineDisplayWithCursor()
|
||||
show(candidateWindowWith: state)
|
||||
default: break
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
// (c) 2021 and onwards Weizhong Yang (MIT License).
|
||||
// All possible vChewing-specific modifications are of:
|
||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
// ====================
|
||||
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||
// ... with NTL restriction stating that:
|
||||
// No trademark license is granted to use the trade names, trademarks, service
|
||||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import Cocoa
|
||||
|
||||
public class TooltipController: NSWindowController {
|
||||
public enum ColorStates {
|
||||
case normal
|
||||
case redAlert
|
||||
case warning
|
||||
case denialOverflow
|
||||
case denialInsufficiency
|
||||
case prompt
|
||||
}
|
||||
|
||||
public enum displayDirection {
|
||||
case horizontal
|
||||
case vertical
|
||||
}
|
||||
|
||||
private var backgroundColor = NSColor.windowBackgroundColor
|
||||
private var textColor = NSColor.windowBackgroundColor
|
||||
private var messageTextField: NSTextField
|
||||
private var tooltip: String = "" {
|
||||
didSet {
|
||||
messageTextField.stringValue = tooltip
|
||||
adjustSize()
|
||||
}
|
||||
}
|
||||
|
||||
public var direction: displayDirection = .horizontal
|
||||
|
||||
public init() {
|
||||
let contentRect = NSRect(x: 128.0, y: 128.0, width: 300.0, height: 20.0)
|
||||
let styleMask: NSWindow.StyleMask = [.borderless, .nonactivatingPanel]
|
||||
let panel = NSPanel(
|
||||
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||
)
|
||||
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
|
||||
panel.hasShadow = true
|
||||
|
||||
messageTextField = NSTextField()
|
||||
messageTextField.isEditable = false
|
||||
messageTextField.isSelectable = false
|
||||
messageTextField.isBezeled = false
|
||||
messageTextField.textColor = textColor
|
||||
messageTextField.drawsBackground = true
|
||||
messageTextField.backgroundColor = backgroundColor
|
||||
messageTextField.font = .systemFont(ofSize: NSFont.systemFontSize(for: .small))
|
||||
panel.contentView?.addSubview(messageTextField)
|
||||
super.init(window: panel)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
public required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func show(tooltip: String, at point: NSPoint) {
|
||||
messageTextField.textColor = textColor
|
||||
messageTextField.backgroundColor = backgroundColor
|
||||
self.tooltip = tooltip
|
||||
window?.orderFront(nil)
|
||||
set(windowLocation: point)
|
||||
}
|
||||
|
||||
public func setColor(state: ColorStates) {
|
||||
switch state {
|
||||
case .normal:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.18, green: 0.18, blue: 0.18, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor.white
|
||||
case .redAlert:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.55, green: 0.00, blue: 0.00, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor.white
|
||||
case .warning:
|
||||
backgroundColor = NSColor.purple
|
||||
textColor = NSColor.white
|
||||
case .denialOverflow:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.13, green: 0.08, blue: 0.00, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor(
|
||||
red: 1.00, green: 0.60, blue: 0.00, alpha: 1.00
|
||||
)
|
||||
case .denialInsufficiency:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.18, green: 0.18, blue: 0.18, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor(
|
||||
red: 0.86, green: 0.86, blue: 0.86, alpha: 1.00
|
||||
)
|
||||
case .prompt:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.00, green: 0.18, blue: 0.13, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor(
|
||||
red: 0.00, green: 1.00, blue: 0.74, alpha: 1.00
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public func resetColor() {
|
||||
setColor(state: .normal)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func hide() {
|
||||
window?.orderOut(nil)
|
||||
}
|
||||
|
||||
private func set(windowLocation windowTopLeftPoint: NSPoint) {
|
||||
var adjustedPoint = windowTopLeftPoint
|
||||
adjustedPoint.y -= 5
|
||||
|
||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
||||
for screen in NSScreen.screens {
|
||||
let frame = screen.visibleFrame
|
||||
if windowTopLeftPoint.x >= frame.minX, windowTopLeftPoint.x <= frame.maxX,
|
||||
windowTopLeftPoint.y >= frame.minY, windowTopLeftPoint.y <= frame.maxY
|
||||
{
|
||||
screenFrame = frame
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let windowSize = window?.frame.size ?? NSSize.zero
|
||||
|
||||
// bottom beneath the screen?
|
||||
if adjustedPoint.y - windowSize.height < screenFrame.minY {
|
||||
adjustedPoint.y = screenFrame.minY + windowSize.height
|
||||
}
|
||||
|
||||
// top over the screen?
|
||||
if adjustedPoint.y >= screenFrame.maxY {
|
||||
adjustedPoint.y = screenFrame.maxY - 1.0
|
||||
}
|
||||
|
||||
// right
|
||||
if adjustedPoint.x + windowSize.width >= screenFrame.maxX {
|
||||
adjustedPoint.x = screenFrame.maxX - windowSize.width
|
||||
}
|
||||
|
||||
// left
|
||||
if adjustedPoint.x < screenFrame.minX {
|
||||
adjustedPoint.x = screenFrame.minX
|
||||
}
|
||||
|
||||
window?.setFrameTopLeftPoint(adjustedPoint)
|
||||
}
|
||||
|
||||
private func adjustSize() {
|
||||
let attrString = messageTextField.attributedStringValue
|
||||
var rect = attrString.boundingRect(
|
||||
with: NSSize(width: 1600.0, height: 1600.0), options: .usesLineFragmentOrigin
|
||||
)
|
||||
|
||||
rect.size.width += 10
|
||||
messageTextField.frame = rect
|
||||
window?.setFrame(rect, display: true)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
// ====================
|
||||
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||
// ... with NTL restriction stating that:
|
||||
// No trademark license is granted to use the trade names, trademarks, service
|
||||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import Cocoa
|
||||
|
||||
public class ctlTooltip: NSWindowController {
|
||||
public enum ColorStates {
|
||||
case normal
|
||||
case redAlert
|
||||
case warning
|
||||
case denialOverflow
|
||||
case denialInsufficiency
|
||||
case prompt
|
||||
}
|
||||
|
||||
private var messageText: NSAttributedTextView
|
||||
private var tooltip: String = "" {
|
||||
didSet {
|
||||
messageText.text = tooltip.isEmpty ? nil : tooltip
|
||||
adjustSize()
|
||||
}
|
||||
}
|
||||
|
||||
public var direction: NSAttributedTextView.writingDirection = .horizontal {
|
||||
didSet {
|
||||
messageText.direction = direction
|
||||
}
|
||||
}
|
||||
|
||||
public init() {
|
||||
let contentRect = NSRect(x: 128.0, y: 128.0, width: 300.0, height: 20.0)
|
||||
let styleMask: NSWindow.StyleMask = [.borderless, .nonactivatingPanel]
|
||||
let panel = NSPanel(
|
||||
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||
)
|
||||
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
|
||||
panel.hasShadow = true
|
||||
panel.backgroundColor = NSColor.controlBackgroundColor
|
||||
messageText = NSAttributedTextView()
|
||||
messageText.backgroundColor = NSColor.controlBackgroundColor
|
||||
messageText.textColor = NSColor.textColor
|
||||
panel.contentView?.addSubview(messageText)
|
||||
super.init(window: panel)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
public required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func show(
|
||||
tooltip: String = "", at point: NSPoint,
|
||||
bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat,
|
||||
direction: NSAttributedTextView.writingDirection = .horizontal
|
||||
) {
|
||||
self.direction = direction
|
||||
messageText.direction = self.direction
|
||||
self.tooltip = tooltip
|
||||
window?.orderFront(nil)
|
||||
set(windowTopLeftPoint: point, bottomOutOfScreenAdjustmentHeight: heightDelta)
|
||||
}
|
||||
|
||||
public func setColor(state: ColorStates) {
|
||||
var backgroundColor = NSColor.controlBackgroundColor
|
||||
var textColor = NSColor.textColor
|
||||
switch state {
|
||||
case .normal:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.18, green: 0.18, blue: 0.18, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor.white
|
||||
case .redAlert:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.55, green: 0.00, blue: 0.00, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor.white
|
||||
case .warning:
|
||||
backgroundColor = NSColor.purple
|
||||
textColor = NSColor.white
|
||||
case .denialOverflow:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.13, green: 0.08, blue: 0.00, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor(
|
||||
red: 1.00, green: 0.60, blue: 0.00, alpha: 1.00
|
||||
)
|
||||
case .denialInsufficiency:
|
||||
backgroundColor = NSColor.windowBackgroundColor
|
||||
textColor = NSColor.labelColor
|
||||
case .prompt:
|
||||
backgroundColor = NSColor(
|
||||
red: 0.09, green: 0.15, blue: 0.15, alpha: 1.00
|
||||
)
|
||||
textColor = NSColor(
|
||||
red: 0.91, green: 0.95, blue: 0.92, alpha: 1.00
|
||||
)
|
||||
}
|
||||
if !IME.isDarkMode {
|
||||
switch state {
|
||||
case .denialInsufficiency: break
|
||||
default:
|
||||
let colorInterchange = backgroundColor
|
||||
backgroundColor = textColor
|
||||
textColor = colorInterchange
|
||||
}
|
||||
}
|
||||
window?.backgroundColor = backgroundColor
|
||||
messageText.backgroundColor = backgroundColor
|
||||
messageText.textColor = textColor
|
||||
}
|
||||
|
||||
public func resetColor() {
|
||||
setColor(state: .normal)
|
||||
}
|
||||
|
||||
public func hide() {
|
||||
window?.orderOut(nil)
|
||||
}
|
||||
|
||||
private func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat) {
|
||||
guard let window = window else { return }
|
||||
let windowSize = window.frame.size
|
||||
|
||||
var adjustedPoint = windowTopLeftPoint
|
||||
var delta = heightDelta
|
||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
||||
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
|
||||
screenFrame = frame
|
||||
break
|
||||
}
|
||||
|
||||
if delta > screenFrame.size.height / 2.0 { delta = 0.0 }
|
||||
|
||||
if adjustedPoint.y < screenFrame.minY + windowSize.height {
|
||||
adjustedPoint.y = windowTopLeftPoint.y + windowSize.height + delta
|
||||
}
|
||||
adjustedPoint.y = min(adjustedPoint.y, screenFrame.maxY - 1.0)
|
||||
adjustedPoint.x = min(max(adjustedPoint.x, screenFrame.minX), screenFrame.maxX - windowSize.width - 1.0)
|
||||
|
||||
window.setFrameTopLeftPoint(adjustedPoint)
|
||||
}
|
||||
|
||||
private func adjustSize() {
|
||||
let attrString = messageText.attributedStringValue
|
||||
var rect = attrString.boundingRect(
|
||||
with: NSSize(width: 1600.0, height: 1600.0),
|
||||
options: [.usesLineFragmentOrigin, .usesFontLeading, .usesDeviceMetrics]
|
||||
)
|
||||
if direction != .horizontal {
|
||||
rect = .init(x: rect.minX, y: rect.minY, width: rect.height, height: rect.width)
|
||||
rect.size.height += NSFont.systemFontSize
|
||||
rect.size.width *= 1.03
|
||||
rect.size.width = max(rect.size.width, NSFont.systemFontSize * 1.05)
|
||||
rect.size.width = ceil(rect.size.width)
|
||||
} else {
|
||||
rect = .init(x: rect.minX, y: rect.minY, width: rect.width, height: rect.height)
|
||||
rect.size.width += NSFont.systemFontSize
|
||||
rect.size.height *= 1.03
|
||||
rect.size.height = max(rect.size.height, NSFont.systemFontSize * 1.05)
|
||||
rect.size.height = ceil(rect.size.height)
|
||||
}
|
||||
var bigRect = rect
|
||||
bigRect.size.width += NSFont.systemFontSize
|
||||
bigRect.size.height += NSFont.systemFontSize
|
||||
rect.origin.x += NSFont.systemFontSize / 2
|
||||
rect.origin.y += NSFont.systemFontSize / 2
|
||||
messageText.frame = rect
|
||||
window?.setFrame(bigRect, display: true)
|
||||
messageText.draw(messageText.frame)
|
||||
}
|
||||
}
|
|
@ -33,11 +33,11 @@
|
|||
5B5948CE289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */; };
|
||||
5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; };
|
||||
5B5F8AEB28C86AAD007C11F1 /* NSAttributedTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5F8AEA28C86AAD007C11F1 /* NSAttributedTextView.swift */; };
|
||||
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */; };
|
||||
5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */; };
|
||||
5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33527AE795800A19448 /* mgrPrefs.swift */; };
|
||||
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; };
|
||||
5B62A34727AE7CD900A19448 /* ctlCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34027AE7CD900A19448 /* ctlCandidate.swift */; };
|
||||
5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34327AE7CD900A19448 /* TooltipController.swift */; };
|
||||
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.swift */; };
|
||||
5B6C141228A9D4B30098ADF8 /* ctlInputMethod_Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */; };
|
||||
5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; };
|
||||
|
@ -248,11 +248,11 @@
|
|||
5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMInstantiator_DateTimeExtension.swift; sourceTree = "<group>"; };
|
||||
5B5E535127EF261400C6AA1E /* IME.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = IME.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B5F8AEA28C86AAD007C11F1 /* NSAttributedTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedTextView.swift; sourceTree = "<group>"; };
|
||||
5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlTooltip.swift; sourceTree = "<group>"; };
|
||||
5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = FSEventStreamHelper.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B62A33527AE795800A19448 /* mgrPrefs.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = mgrPrefs.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B62A34027AE7CD900A19448 /* ctlCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlCandidate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B62A34327AE7CD900A19448 /* TooltipController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = TooltipController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B62A34527AE7CD900A19448 /* NotifierController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = NotifierController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B65B919284D0185007C558B /* README-CHT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "README-CHT.md"; sourceTree = "<group>"; };
|
||||
5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlInputMethod_Common.swift; sourceTree = "<group>"; };
|
||||
|
@ -621,7 +621,7 @@
|
|||
5B62A34227AE7CD900A19448 /* TooltipUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5B62A34327AE7CD900A19448 /* TooltipController.swift */,
|
||||
5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */,
|
||||
);
|
||||
path = TooltipUI;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1214,6 +1214,7 @@
|
|||
D47B92C027972AD100458394 /* main.swift in Sources */,
|
||||
D4A13D5A27A59F0B003BE359 /* ctlInputMethod_Core.swift in Sources */,
|
||||
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */,
|
||||
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */,
|
||||
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
|
||||
5B2170E7289FACAD00BE7304 /* 1_Compositor.swift in Sources */,
|
||||
5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */,
|
||||
|
@ -1263,7 +1264,6 @@
|
|||
5B40730D281672610023DFFF /* lmReplacements.swift in Sources */,
|
||||
5B5E535227EF261400C6AA1E /* IME.swift in Sources */,
|
||||
5B2170E0289FACAD00BE7304 /* 7_LangModel.swift in Sources */,
|
||||
5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */,
|
||||
5BA9FD4027FEF3C8002DE248 /* Localization.swift in Sources */,
|
||||
5BF0B84C28C070B000795FC6 /* NSEventExtension.swift in Sources */,
|
||||
5BAA8FBE282CAF380066C406 /* SyllableComposer.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue