vChewing-macOS/Source/Modules/WindowControllers/CtlRevLookupWindow.swift

192 lines
8.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// (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
import LangModelAssembly
class CtlRevLookupWindow: NSWindowController, NSWindowDelegate {
static var shared: CtlRevLookupWindow?
static func show() {
if shared == nil { Self.shared = .init(window: FrmRevLookupWindow()) }
guard let shared = Self.shared, let window = shared.window as? FrmRevLookupWindow else { return }
shared.window = window
window.delegate = shared
window.setPosition(vertical: .bottom, horizontal: .right, padding: 20)
window.orderFrontRegardless() //
window.level = .statusBar
window.titlebarAppearsTransparent = true
shared.showWindow(shared)
NSApp.activate(ignoringOtherApps: true)
}
}
class FrmRevLookupWindow: NSWindow {
typealias LMRevLookup = vChewingLM.LMRevLookup
static var lmRevLookupCore = LMRevLookup(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup"))
// Dictionary
static var lmRevLookupCNS1 = LMRevLookup(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS1"))
static var lmRevLookupCNS2 = LMRevLookup(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS2"))
static var lmRevLookupCNS3 = LMRevLookup(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS3"))
static var lmRevLookupCNS4 = LMRevLookup(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS4"))
static var lmRevLookupCNS5 = LMRevLookup(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS5"))
static var lmRevLookupCNS6 = LMRevLookup(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS6"))
public lazy var inputField = NSTextField()
public lazy var resultView = NSTextView()
private lazy var clipView = NSClipView()
private lazy var scrollView = NSScrollView()
private lazy var button = NSButton()
private lazy var view = NSView()
static func reloadData() {
DispatchQueue.main.async { lmRevLookupCore = .init(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup")) }
DispatchQueue.main.async { lmRevLookupCNS1 = .init(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS1")) }
DispatchQueue.main.async { lmRevLookupCNS2 = .init(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS2")) }
DispatchQueue.main.async { lmRevLookupCNS3 = .init(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS3")) }
DispatchQueue.main.async { lmRevLookupCNS4 = .init(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS4")) }
DispatchQueue.main.async { lmRevLookupCNS5 = .init(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS5")) }
DispatchQueue.main.async { lmRevLookupCNS6 = .init(data: LMMgr.getDictionaryData("data-bpmf-reverse-lookup-CNS6")) }
}
init() {
super.init(
contentRect: CGRect(x: 196, y: 240, width: 480, height: 340),
styleMask: [.titled, .closable],
backing: .buffered, defer: true
)
setupUI()
}
private func setupUI() {
contentView = view
allowsToolTipsWhenApplicationIsInactive = false
autorecalculatesKeyViewLoop = false
isReleasedWhenClosed = false
title = "Reverse Lookup (Phonabets)".localized
view.addSubview(inputField)
view.addSubview(scrollView)
view.addSubview(button)
view.wantsLayer = true
button.autoresizingMask = [.maxXMargin, .minYMargin]
button.frame = CGRect(x: 446, y: 319, width: 31, height: 21)
button.setContentHuggingPriority(.defaultHigh, for: .vertical)
button.alignment = .center
button.bezelStyle = .recessed
button.font = NSFont.systemFont(ofSize: 12)
button.imageScaling = .scaleProportionallyDown
button.title = "👓"
button.cell.map { $0 as? NSButtonCell }??.isBordered = true
button.target = self
button.action = #selector(keyboardConfirmed(_:))
button.keyEquivalent = String(utf16CodeUnits: [unichar(NSEvent.SpecialKey.enter.rawValue)], count: 1) as String
scrollView.autoresizingMask = [.maxXMargin, .minYMargin]
scrollView.borderType = .noBorder
scrollView.frame = CGRect(x: 0, y: 0, width: 480, height: 320)
scrollView.hasHorizontalScroller = false
scrollView.horizontalLineScroll = 10
scrollView.horizontalPageScroll = 10
scrollView.verticalLineScroll = 10
scrollView.verticalPageScroll = 10
clipView.documentView = resultView
clipView.autoresizingMask = [.width, .height]
clipView.drawsBackground = false
clipView.frame = CGRect(x: 0, y: 0, width: 480, height: 320)
resultView.autoresizingMask = [.width, .height]
resultView.backgroundColor = NSColor.textBackgroundColor
resultView.frame = CGRect(x: 0, y: 0, width: 480, height: 320)
resultView.importsGraphics = false
resultView.insertionPointColor = NSColor.textColor
resultView.isEditable = false
resultView.isRichText = false
resultView.isVerticallyResizable = true
resultView.maxSize = CGSize(width: 774, height: 10_000_000)
resultView.minSize = CGSize(width: 480, height: 320)
resultView.smartInsertDeleteEnabled = true
resultView.textColor = NSColor.textColor
resultView.wantsLayer = true
resultView.font = NSFont.systemFont(ofSize: 13)
resultView.string = "Maximum 15 results returnable.".localized
scrollView.contentView = clipView
inputField.autoresizingMask = [.maxXMargin, .minYMargin]
inputField.frame = CGRect(x: 0, y: 320, width: 441, height: 20)
inputField.setContentHuggingPriority(.defaultHigh, for: .vertical)
inputField.backgroundColor = NSColor.textBackgroundColor
inputField.drawsBackground = true
inputField.font = NSFont.systemFont(ofSize: 13)
inputField.isBezeled = true
inputField.isEditable = true
inputField.isSelectable = true
inputField.lineBreakMode = .byClipping
inputField.textColor = NSColor.controlTextColor
inputField.cell.map { $0 as? NSTextFieldCell }??.isScrollable = true
inputField.cell.map { $0 as? NSTextFieldCell }??.sendsActionOnEndEditing = true
inputField.cell.map { $0 as? NSTextFieldCell }??.usesSingleLineMode = true
inputField.action = #selector(keyboardConfirmed(_:))
inputField.toolTip =
"Maximum 15 results returnable.".localized
}
@objc func keyboardConfirmed(_: Any?) {
if inputField.stringValue.isEmpty { return }
resultView.string = "\n" + "Loading…".localized
DispatchQueue.main.async { [self] in
self.updateResult(with: self.inputField.stringValue)
}
}
private func updateResult(with input: String) {
guard !input.isEmpty else { return }
button.isEnabled = false
inputField.isEnabled = false
let strBuilder = NSMutableString()
strBuilder.append("\n")
strBuilder.append("Char\tReading(s)\n".localized)
strBuilder.append("==\t====\n")
var i = 0
theLoop: for char in input.map(\.description) {
if i == 15 {
strBuilder.append("Maximum 15 results returnable.".localized + "\n")
break theLoop
}
var arrResult = Self.lmRevLookupCore.query(with: char) ?? []
//
arrResult +=
Self.lmRevLookupCNS1.query(with: char)
?? Self.lmRevLookupCNS2.query(with: char)
?? Self.lmRevLookupCNS3.query(with: char)
?? Self.lmRevLookupCNS4.query(with: char)
?? Self.lmRevLookupCNS5.query(with: char)
?? Self.lmRevLookupCNS6.query(with: char)
?? []
arrResult = arrResult.deduplicated
if !arrResult.isEmpty {
strBuilder.append(char + "\t")
strBuilder.append(arrResult.joined(separator: ", "))
strBuilder.append("\n")
i += 1
}
}
resultView.string = strBuilder.description
button.isEnabled = true
inputField.isEnabled = true
}
}