Repo // Deprecating Zonble's Tooltip controller.

This commit is contained in:
ShikiSuen 2022-09-07 19:40:21 +08:00
parent 21c369defb
commit 3cb0872a1d
9 changed files with 211 additions and 201 deletions

View File

@ -88,7 +88,7 @@
- ctlInputMethod 輸入法主控制器內則採用策略設計模式來處理各種狀態。 - ctlInputMethod 輸入法主控制器內則採用策略設計模式來處理各種狀態。
- 半衰記憶模組的 C++ 原版作者是 Mengjuei Hsieh且由 Shiki Suen 用 Swift 與 C# 分別重寫、繼續開發。 - 半衰記憶模組的 C++ 原版作者是 Mengjuei Hsieh且由 Shiki Suen 用 Swift 與 C# 分別重寫、繼續開發。
- 僅供研發人員調試方便而使用的 App 版安裝程式 (by Zonble Yang),不對公眾使用。 - 僅供研發人員調試方便而使用的 App 版安裝程式 (by Zonble Yang),不對公眾使用。
- Voltaire MK2 選字窗、飄雲通知視窗、工具提示 (by Zonble Yang),有大幅度修改。 - Voltaire MK2 選字窗、飄雲通知視窗 (by Zonble Yang),有大幅度修改。
威注音輸入法 macOS 版以 MIT-NTL License 授權釋出 (與 MIT 相容):© 2021-2022 vChewing 專案。 威注音輸入法 macOS 版以 MIT-NTL License 授權釋出 (與 MIT 相容):© 2021-2022 vChewing 專案。

View File

@ -88,7 +88,7 @@
- ctlInputMethod 输入法主控制器内则采用策略设计模式来处理各种状态。 - ctlInputMethod 输入法主控制器内则采用策略设计模式来处理各种状态。
- 半衰记忆模组的 C++ 原版作者是 Mengjuei Hsieh且由 Shiki Suen 用 Swift 与 C# 分别重写、继续开发。 - 半衰记忆模组的 C++ 原版作者是 Mengjuei Hsieh且由 Shiki Suen 用 Swift 与 C# 分别重写、继续开发。
- 仅供研发人员调试方便而使用的 App 版安装程式 (by Zonble Yang),不对公众使用。 - 仅供研发人员调试方便而使用的 App 版安装程式 (by Zonble Yang),不对公众使用。
- Voltaire MK2 选字窗、飘云通知视窗、工具提示 (by Zonble Yang),有大幅度修改。 - Voltaire MK2 选字窗、飘云通知视窗 (by Zonble Yang),有大幅度修改。
威注音输入法 macOS 版以 MIT-NTL License 授权释出 (与 MIT 相容):© 2021-2022 vChewing 专案。 威注音输入法 macOS 版以 MIT-NTL License 授权释出 (与 MIT 相容):© 2021-2022 vChewing 专案。

View File

@ -179,7 +179,7 @@ extension StateData {
} }
arrOutput.append(neta) 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) { public static func updateParameters(_ data: inout StateData) {
var tooltipGenerated: String { var tooltipGenerated: String {
if mgrPrefs.phraseReplacementEnabled { if mgrPrefs.phraseReplacementEnabled {
ctlInputMethod.tooltipController.setColor(state: .warning) ctlInputMethod.tooltipInstance.setColor(state: .warning)
return NSLocalizedString( return NSLocalizedString(
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry.", comment: "" "⚠︎ Phrase replacement mode enabled, interfering user phrase entry.", comment: ""
) )
@ -198,18 +198,18 @@ extension StateData {
let text = data.displayedText.charComponents[data.markedRange].joined() let text = data.displayedText.charComponents[data.markedRange].joined()
if data.markedRange.count < mgrPrefs.allowedMarkRange.lowerBound { if data.markedRange.count < mgrPrefs.allowedMarkRange.lowerBound {
ctlInputMethod.tooltipController.setColor(state: .denialInsufficiency) ctlInputMethod.tooltipInstance.setColor(state: .denialInsufficiency)
return String( return String(
format: NSLocalizedString( format: NSLocalizedString(
"\"%@\" length must ≥ 2 for a user phrase.", comment: "" "\"%@\" length must ≥ 2 for a user phrase.", comment: ""
) + "\n// " + generateReadingThread(data), text ) + "\n " + generateReadingThread(data), text
) )
} else if data.markedRange.count > mgrPrefs.allowedMarkRange.upperBound { } else if data.markedRange.count > mgrPrefs.allowedMarkRange.upperBound {
ctlInputMethod.tooltipController.setColor(state: .denialOverflow) ctlInputMethod.tooltipInstance.setColor(state: .denialOverflow)
return String( return String(
format: NSLocalizedString( format: NSLocalizedString(
"\"%@\" length should ≤ %d for a user phrase.", comment: "" "\"%@\" 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 { if exist {
data.markedTargetExists = exist data.markedTargetExists = exist
ctlInputMethod.tooltipController.setColor(state: .prompt) ctlInputMethod.tooltipInstance.setColor(state: .prompt)
return String( return String(
format: NSLocalizedString( format: NSLocalizedString(
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.", "\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.",
comment: "" comment: ""
) + "\n// " + generateReadingThread(data), text ) + "\n " + generateReadingThread(data), text
) )
} }
ctlInputMethod.tooltipController.resetColor() ctlInputMethod.tooltipInstance.resetColor()
return String( return String(
format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: "") + "\n// " format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: "") + "\n "
+ generateReadingThread(data), + generateReadingThread(data),
text text
) )

View File

@ -27,8 +27,8 @@ class ctlInputMethod: IMKInputController {
static var ctlCandidateCurrent: ctlCandidateProtocol = static var ctlCandidateCurrent: ctlCandidateProtocol =
mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal) mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
/// ///
static let tooltipController = TooltipController() static var tooltipInstance = ctlTooltip()
// MARK: - // MARK: -

View File

@ -27,15 +27,21 @@ extension ctlInputMethod {
cursor -= 1 cursor -= 1
} }
var finalOrigin: NSPoint = lineHeightRect.origin var finalOrigin: NSPoint = lineHeightRect.origin
let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
if isVerticalTyping { if isVerticalTyping {
finalOrigin = NSPoint( 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 { } 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) { func show(candidateWindowWith state: IMEStateProtocol) {

View File

@ -25,7 +25,7 @@ extension ctlInputMethod {
case .ofDeactivated: case .ofDeactivated:
ctlInputMethod.ctlCandidateCurrent.delegate = nil ctlInputMethod.ctlCandidateCurrent.delegate = nil
ctlInputMethod.ctlCandidateCurrent.visible = false ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipController.hide() ctlInputMethod.tooltipInstance.hide()
if previous.hasComposition { if previous.hasComposition {
commit(text: previous.displayedText) commit(text: previous.displayedText)
} }
@ -39,20 +39,20 @@ extension ctlInputMethod {
previous = state previous = state
} }
ctlInputMethod.ctlCandidateCurrent.visible = false ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipController.hide() ctlInputMethod.tooltipInstance.hide()
// .Abortion // .Abortion
if previous.hasComposition, state.type != .ofAbortion { if previous.hasComposition, state.type != .ofAbortion {
commit(text: previous.displayedText) commit(text: previous.displayedText)
} }
// //
ctlInputMethod.ctlCandidateCurrent.visible = false ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipController.hide() ctlInputMethod.tooltipInstance.hide()
clearInlineDisplay() clearInlineDisplay()
// //
keyHandler.clear() keyHandler.clear()
case .ofCommitting: case .ofCommitting:
ctlInputMethod.ctlCandidateCurrent.visible = false ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipController.hide() ctlInputMethod.tooltipInstance.hide()
let textToCommit = state.textToCommit let textToCommit = state.textToCommit
if !textToCommit.isEmpty { commit(text: textToCommit) } if !textToCommit.isEmpty { commit(text: textToCommit) }
clearInlineDisplay() clearInlineDisplay()
@ -60,7 +60,7 @@ extension ctlInputMethod {
keyHandler.clear() keyHandler.clear()
case .ofInputting: case .ofInputting:
ctlInputMethod.ctlCandidateCurrent.visible = false ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipController.hide() ctlInputMethod.tooltipInstance.hide()
let textToCommit = state.textToCommit let textToCommit = state.textToCommit
if !textToCommit.isEmpty { commit(text: textToCommit) } if !textToCommit.isEmpty { commit(text: textToCommit) }
setInlineDisplayWithCursor() setInlineDisplayWithCursor()
@ -74,7 +74,7 @@ extension ctlInputMethod {
ctlInputMethod.ctlCandidateCurrent.visible = false ctlInputMethod.ctlCandidateCurrent.visible = false
setInlineDisplayWithCursor() setInlineDisplayWithCursor()
if state.tooltip.isEmpty { if state.tooltip.isEmpty {
ctlInputMethod.tooltipController.hide() ctlInputMethod.tooltipInstance.hide()
} else { } else {
let cursorReference: Int = { let cursorReference: Int = {
if state.data.marker >= state.data.cursor { return state.data.u16Cursor } if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
@ -86,7 +86,7 @@ extension ctlInputMethod {
) )
} }
case .ofCandidates, .ofAssociates, .ofSymbolTable: case .ofCandidates, .ofAssociates, .ofSymbolTable:
ctlInputMethod.tooltipController.hide() ctlInputMethod.tooltipInstance.hide()
setInlineDisplayWithCursor() setInlineDisplayWithCursor()
show(candidateWindowWith: state) show(candidateWindowWith: state)
default: break default: break

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -33,11 +33,11 @@
5B5948CE289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */; }; 5B5948CE289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */; };
5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; }; 5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; };
5B5F8AEB28C86AAD007C11F1 /* NSAttributedTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5F8AEA28C86AAD007C11F1 /* NSAttributedTextView.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 */; }; 5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */; };
5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33527AE795800A19448 /* mgrPrefs.swift */; }; 5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33527AE795800A19448 /* mgrPrefs.swift */; };
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; }; 5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; };
5B62A34727AE7CD900A19448 /* ctlCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34027AE7CD900A19448 /* ctlCandidate.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 */; }; 5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.swift */; };
5B6C141228A9D4B30098ADF8 /* ctlInputMethod_Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.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 */; }; 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>"; }; 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; }; 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>"; }; 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; }; 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; }; 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; }; 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; }; 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; }; 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>"; }; 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>"; }; 5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlInputMethod_Common.swift; sourceTree = "<group>"; };
@ -621,7 +621,7 @@
5B62A34227AE7CD900A19448 /* TooltipUI */ = { 5B62A34227AE7CD900A19448 /* TooltipUI */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
5B62A34327AE7CD900A19448 /* TooltipController.swift */, 5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */,
); );
path = TooltipUI; path = TooltipUI;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1214,6 +1214,7 @@
D47B92C027972AD100458394 /* main.swift in Sources */, D47B92C027972AD100458394 /* main.swift in Sources */,
D4A13D5A27A59F0B003BE359 /* ctlInputMethod_Core.swift in Sources */, D4A13D5A27A59F0B003BE359 /* ctlInputMethod_Core.swift in Sources */,
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */, 5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */,
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */,
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */, 5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
5B2170E7289FACAD00BE7304 /* 1_Compositor.swift in Sources */, 5B2170E7289FACAD00BE7304 /* 1_Compositor.swift in Sources */,
5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */, 5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */,
@ -1263,7 +1264,6 @@
5B40730D281672610023DFFF /* lmReplacements.swift in Sources */, 5B40730D281672610023DFFF /* lmReplacements.swift in Sources */,
5B5E535227EF261400C6AA1E /* IME.swift in Sources */, 5B5E535227EF261400C6AA1E /* IME.swift in Sources */,
5B2170E0289FACAD00BE7304 /* 7_LangModel.swift in Sources */, 5B2170E0289FACAD00BE7304 /* 7_LangModel.swift in Sources */,
5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */,
5BA9FD4027FEF3C8002DE248 /* Localization.swift in Sources */, 5BA9FD4027FEF3C8002DE248 /* Localization.swift in Sources */,
5BF0B84C28C070B000795FC6 /* NSEventExtension.swift in Sources */, 5BF0B84C28C070B000795FC6 /* NSEventExtension.swift in Sources */,
5BAA8FBE282CAF380066C406 /* SyllableComposer.swift in Sources */, 5BAA8FBE282CAF380066C406 /* SyllableComposer.swift in Sources */,