Repo // Utilizing NSAttributedString.boundingDimension.

This commit is contained in:
ShikiSuen 2023-02-17 20:46:53 +08:00
parent 7d4e7ae551
commit d3454ccd56
11 changed files with 40 additions and 45 deletions

View File

@ -12,11 +12,15 @@ let package = Package(
targets: ["NSAttributedTextView"] targets: ["NSAttributedTextView"]
), ),
], ],
dependencies: [], dependencies: [
.package(path: "../vChewing_CocoaExtension"),
],
targets: [ targets: [
.target( .target(
name: "NSAttributedTextView", name: "NSAttributedTextView",
dependencies: [] dependencies: [
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"),
]
), ),
] ]
) )

View File

@ -6,6 +6,7 @@
// Modified by The vChewing Project in order to use it with AppKit. // Modified by The vChewing Project in order to use it with AppKit.
import Cocoa import Cocoa
import CocoaExtension
import SwiftUI import SwiftUI
@available(macOS 10.15, *) @available(macOS 10.15, *)
@ -107,20 +108,14 @@ public class NSAttributedTextView: NSView {
default: return attributedStringValue(areaCalculation: true) default: return attributedStringValue(areaCalculation: true)
} }
}() }()
var rect = attrString.boundingRect( var textWH = attrString.boundingDimension
with: NSSize(width: 1600.0, height: 1600.0),
options: [.usesLineFragmentOrigin, .usesFontLeading, .usesDeviceMetrics]
)
rect.size.height *= 1.03
rect.size.height = max(rect.size.height, NSFont.systemFontSize * 1.1)
rect.size.height = ceil(rect.size.height)
rect.size.width *= 1.03
rect.size.width = max(rect.size.width, NSFont.systemFontSize * 1.05)
rect.size.width = ceil(rect.size.width)
if direction != .horizontal { if direction != .horizontal {
rect = .init(x: rect.minX, y: rect.minY, width: rect.height, height: rect.width) textWH.height *= 1.03
textWH.height = max(textWH.height, NSFont.systemFontSize * 1.1)
textWH.height = ceil(textWH.height)
textWH = .init(width: textWH.height, height: textWH.width)
} }
return rect return .init(origin: .zero, size: textWH)
} }
override public func draw(_ rect: CGRect) { override public func draw(_ rect: CGRect) {

View File

@ -58,11 +58,7 @@ public class CandidateCellData: Hashable {
public var cellLength: Int { public var cellLength: Int {
if displayedText.count <= 2 { return Int(ceil(size * 3)) } if displayedText.count <= 2 { return Int(ceil(size * 3)) }
let rect = attributedStringForLengthCalculation.boundingRect( return Int(ceil(attributedStringForLengthCalculation.boundingDimension.width))
with: NSSize(width: 1600.0, height: 1600.0), options: [.usesLineFragmentOrigin]
)
let rawResult = ceil(rect.width)
return Int(rawResult)
} }
public var attributedStringHeader: NSAttributedString { public var attributedStringHeader: NSAttributedString {

View File

@ -12,11 +12,15 @@ let package = Package(
targets: ["NotifierUI"] targets: ["NotifierUI"]
), ),
], ],
dependencies: [], dependencies: [
.package(path: "../vChewing_CocoaExtension"),
],
targets: [ targets: [
.target( .target(
name: "NotifierUI", name: "NotifierUI",
dependencies: [] dependencies: [
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"),
]
), ),
] ]
) )

View File

@ -7,6 +7,7 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import Cocoa import Cocoa
import CocoaExtension
public class Notifier: NSWindowController { public class Notifier: NSWindowController {
public static func notify(message: String) { public static func notify(message: String) {
@ -78,10 +79,8 @@ public class Notifier: NSWindowController {
let attrStringAlt = NSMutableAttributedString(string: additionalString, attributes: attrAlt) let attrStringAlt = NSMutableAttributedString(string: additionalString, attributes: attrAlt)
attrString.insert(attrStringAlt, at: attrString.length) attrString.insert(attrStringAlt, at: attrString.length)
let textRect: NSRect = attrString.boundingRect( let textWH = attrString.boundingDimension
with: NSSize(width: 1600.0, height: 1600.0), options: [.usesLineFragmentOrigin] let windowWidth = Double(4) * kLargeFontSize + textWH.width
)
let windowWidth = Double(4) * kLargeFontSize + textRect.width
let contentRect = NSRect(x: 0, y: 0, width: windowWidth, height: 60.0) let contentRect = NSRect(x: 0, y: 0, width: windowWidth, height: 60.0)
var windowRect = contentRect var windowRect = contentRect
windowRect.origin.x = screenRect.maxX - windowRect.width - 10 windowRect.origin.x = screenRect.maxX - windowRect.width - 10
@ -123,8 +122,8 @@ public class Notifier: NSWindowController {
theWindow.contentView?.addSubview(lblMessage) theWindow.contentView?.addSubview(lblMessage)
let x = lblMessage.frame.origin.x let x = lblMessage.frame.origin.x
let y = ((theWindow.frame.height) - textRect.height) / 1.9 let y = ((theWindow.frame.height) - textWH.height) / 1.9
let newFrame = NSRect(x: x, y: y, width: theWindow.frame.width, height: textRect.height) let newFrame = NSRect(x: x, y: y, width: theWindow.frame.width, height: textWH.height)
lblMessage.frame = newFrame lblMessage.frame = newFrame
super.init(window: theWindow) super.init(window: theWindow)

View File

@ -164,13 +164,10 @@ public class PopupCompositionBuffer: NSWindowController {
private func adjustSize() { private func adjustSize() {
let attrString = messageTextField.attributedStringValue let attrString = messageTextField.attributedStringValue
var rect = attrString.boundingRect( var rect = NSRect(origin: .zero, size: attrString.boundingDimension)
with: NSSize(width: 1600.0, height: 1600.0),
options: [.usesLineFragmentOrigin, .usesFontLeading]
)
rect.size.width = max(rect.size.width, 20 * Double(attrString.string.count)) + 2
rect.size.height *= 1.2 rect.size.height *= 1.2
rect.size.height = max(22, rect.size.height) rect.size.height = max(22, rect.size.height)
rect.size.width = max(rect.size.width, 20 * Double(attrString.string.count)) + 2
if isTypingDirectionVertical { if isTypingDirectionVertical {
rect = .init(x: rect.minX, y: rect.minY, width: rect.height, height: rect.width) rect = .init(x: rect.minX, y: rect.minY, width: rect.height, height: rect.width)
} }

View File

@ -119,7 +119,7 @@ public class InputHandler: InputHandlerProtocol {
var isHaninKeyboardSymbolMode = false var isHaninKeyboardSymbolMode = false
static let tooltipHaninKeyboardSymbolMode: String = "\("Hanin Keyboard Symbol Input.".localized)  " static let tooltipHaninKeyboardSymbolMode: String = "\("Hanin Keyboard Symbol Input.".localized)"
// MARK: - Codepoint Input Buffer. // MARK: - Codepoint Input Buffer.
@ -134,12 +134,13 @@ public class InputHandler: InputHandlerProtocol {
var tooltipCodePointInputMode: String { var tooltipCodePointInputMode: String {
let commonTerm = NSMutableString() let commonTerm = NSMutableString()
commonTerm.insert("Code Point Input.".localized, at: 0) commonTerm.insert("Code Point Input.".localized, at: 0)
switch IMEApp.currentInputMode { if !(delegate?.isVerticalTyping ?? false) {
case .imeModeCHS: commonTerm.insert("[GB] ", at: 0) switch IMEApp.currentInputMode {
case .imeModeCHT: commonTerm.insert("[Big5] ", at: 0) case .imeModeCHS: commonTerm.insert("[GB] ", at: 0)
default: break case .imeModeCHT: commonTerm.insert("[Big5] ", at: 0)
default: break
}
} }
commonTerm.append("  ")
return commonTerm.description return commonTerm.description
} }

View File

@ -204,7 +204,7 @@ extension InputHandler {
if calligrapher.isEmpty, isWildcardKeyInput { if calligrapher.isEmpty, isWildcardKeyInput {
delegate.callError("3606B9C0") delegate.callError("3606B9C0")
var newEmptyState = compositor.isEmpty ? IMEState.ofEmpty() : generateStateOfInputting() var newEmptyState = compositor.isEmpty ? IMEState.ofEmpty() : generateStateOfInputting()
newEmptyState.tooltip = NSLocalizedString("Wildcard key cannot be the initial key.", comment: "") + "  " newEmptyState.tooltip = NSLocalizedString("Wildcard key cannot be the initial key.", comment: "")
newEmptyState.data.tooltipColorState = .redAlert newEmptyState.data.tooltipColorState = .redAlert
newEmptyState.tooltipDuration = 1.0 newEmptyState.tooltipDuration = 1.0
delegate.switchState(newEmptyState) delegate.switchState(newEmptyState)
@ -345,7 +345,7 @@ extension InputHandler {
delegate.callError("D220B880輸入的字碼沒有對應的字元。") delegate.callError("D220B880輸入的字碼沒有對應的字元。")
var updatedState = IMEState.ofAbortion() var updatedState = IMEState.ofAbortion()
updatedState.tooltipDuration = 0 updatedState.tooltipDuration = 0
updatedState.tooltip = "Invalid Code Point.".localized + "  " updatedState.tooltip = "Invalid Code Point.".localized
delegate.switchState(updatedState) delegate.switchState(updatedState)
isCodePointInputMode = true isCodePointInputMode = true
return true return true

View File

@ -166,7 +166,7 @@ extension InputHandler {
return true return true
} }
var newState = generateStateOfInputting() var newState = generateStateOfInputting()
newState.tooltip = NSLocalizedString(tooltipMessage, comment: "") + "  " newState.tooltip = NSLocalizedString(tooltipMessage, comment: "")
newState.data.tooltipColorState = tooltipColorState newState.data.tooltipColorState = tooltipColorState
newState.tooltipDuration = 1.85 newState.tooltipDuration = 1.85
delegate.switchState(newState) delegate.switchState(newState)
@ -185,7 +185,7 @@ extension InputHandler {
return true return true
} }
var newState = generateStateOfInputting() var newState = generateStateOfInputting()
newState.tooltip = NSLocalizedString(tooltipMessage, comment: "") + "  " newState.tooltip = NSLocalizedString(tooltipMessage, comment: "")
newState.data.tooltipColorState = .warning newState.data.tooltipColorState = .warning
newState.tooltipDuration = 1.85 newState.tooltipDuration = 1.85
delegate.switchState(newState) delegate.switchState(newState)
@ -808,7 +808,6 @@ extension InputHandler {
} else { } else {
newTooltip.insert((newIndex + 1).description + " / " + candidates.count.description, at: 0) newTooltip.insert((newIndex + 1).description + " / " + candidates.count.description, at: 0)
} }
newTooltip.append("  ")
newState.tooltip = newTooltip.description newState.tooltip = newTooltip.description
vCLog(newState.tooltip) vCLog(newState.tooltip)
newState.tooltipDuration = 0 newState.tooltipDuration = 0

View File

@ -233,7 +233,7 @@ extension SessionCtl: CtlCandidateDelegate {
tooltipMessage = succeeded ? "! Succeeded in filtering a candidate." : "⚠︎ Failed from filtering a candidate." tooltipMessage = succeeded ? "! Succeeded in filtering a candidate." : "⚠︎ Failed from filtering a candidate."
} }
if !succeeded { newState.data.tooltipColorState = .redAlert } if !succeeded { newState.data.tooltipColorState = .redAlert }
newState.tooltip = NSLocalizedString(tooltipMessage, comment: "") + "  " newState.tooltip = NSLocalizedString(tooltipMessage, comment: "")
switchState(newState) switchState(newState)
} }
} }

View File

@ -99,7 +99,7 @@ public extension SessionCtl {
if !LMMgr.currentLM.isCoreLMLoaded { if !LMMgr.currentLM.isCoreLMLoaded {
if (event as InputSignalProtocol).isReservedKey { return false } if (event as InputSignalProtocol).isReservedKey { return false }
var newState: IMEStateProtocol = IMEState.ofEmpty() var newState: IMEStateProtocol = IMEState.ofEmpty()
newState.tooltip = NSLocalizedString("Factory dictionary not loaded yet.", comment: "") + "  " newState.tooltip = NSLocalizedString("Factory dictionary not loaded yet.", comment: "")
newState.tooltipDuration = 1.85 newState.tooltipDuration = 1.85
newState.data.tooltipColorState = .redAlert newState.data.tooltipColorState = .redAlert
switchState(newState) switchState(newState)