Repo // Implementing set() for NSWindowController.
This commit is contained in:
parent
c7347f0efb
commit
5832136e05
|
@ -52,7 +52,7 @@ open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
|
|||
}
|
||||
set {
|
||||
DispatchQueue.main.async {
|
||||
self.set(windowTopLeftPoint: newValue, bottomOutOfScreenAdjustmentHeight: 0)
|
||||
self.set(windowTopLeftPoint: newValue, bottomOutOfScreenAdjustmentHeight: 0, useGCD: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,37 +72,6 @@ open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
|
|||
visible = false
|
||||
}
|
||||
|
||||
/// 設定選字窗的顯示位置。
|
||||
///
|
||||
/// 需注意:該函數會藉由設定選字窗左上角頂點的方式、使選字窗始終位於某個螢幕之內。
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - windowTopLeftPoint: 給定的視窗顯示位置。
|
||||
/// - heightDelta: 為了「防止選字窗抻出螢幕下方」而給定的預留高度。
|
||||
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double) {
|
||||
DispatchQueue.main.async { [self] in
|
||||
guard let window = window, var screenFrame = NSScreen.main?.visibleFrame else { return }
|
||||
let windowSize = window.frame.size
|
||||
|
||||
var adjustedPoint = windowTopLeftPoint
|
||||
var delta = heightDelta
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 不需要在這裡仔細實作的內容。
|
||||
|
||||
@available(*, unavailable)
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// (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 InputMethodKit
|
||||
|
||||
extension NSWindowController {
|
||||
/// 設定選字窗的顯示位置。
|
||||
///
|
||||
/// 需注意:該函式會藉由設定選字窗左上角頂點的方式、使選字窗始終位於某個螢幕之內。
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - windowTopLeftPoint: 給定的視窗顯示位置。
|
||||
/// - heightDelta: 為了「防止選字窗抻出螢幕下方」而給定的預留高度。
|
||||
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double, useGCD: Bool) {
|
||||
func doSet() {
|
||||
guard let window = window, var screenFrame = NSScreen.main?.visibleFrame else { return }
|
||||
let windowSize = window.frame.size
|
||||
|
||||
var adjustedPoint = windowTopLeftPoint
|
||||
var delta = heightDelta
|
||||
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)
|
||||
}
|
||||
|
||||
if !useGCD { doSet() } else { DispatchQueue.main.async { doSet() } }
|
||||
}
|
||||
}
|
||||
|
||||
extension IMKCandidates {
|
||||
/// 設定選字窗的顯示位置。
|
||||
///
|
||||
/// 需注意:該函式會藉由設定選字窗左上角頂點的方式、使選字窗始終位於某個螢幕之內。
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - windowTopLeftPoint: 給定的視窗顯示位置。
|
||||
/// - heightDelta: 為了「防止選字窗抻出螢幕下方」而給定的預留高度。
|
||||
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double, useGCD: Bool) {
|
||||
func doSet() {
|
||||
DispatchQueue.main.async { [self] in
|
||||
guard var screenFrame = NSScreen.main?.visibleFrame else { return }
|
||||
var adjustedPoint = windowTopLeftPoint
|
||||
let windowSize = candidateFrame().size
|
||||
var delta = heightDelta
|
||||
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)
|
||||
|
||||
setCandidateFrameTopLeft(adjustedPoint)
|
||||
}
|
||||
}
|
||||
|
||||
if useGCD { doSet() } else { DispatchQueue.main.async { doSet() } }
|
||||
}
|
||||
}
|
|
@ -36,5 +36,5 @@ public protocol CtlCandidateProtocol {
|
|||
func highlightNextCandidate() -> Bool
|
||||
func highlightPreviousCandidate() -> Bool
|
||||
func candidateIndexAtKeyLabelIndex(_: Int) -> Int
|
||||
func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: Double)
|
||||
func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: Double, useGCD: Bool)
|
||||
}
|
||||
|
|
|
@ -57,8 +57,10 @@ public class TooltipUI: NSWindowController {
|
|||
) {
|
||||
self.direction = direction
|
||||
self.tooltip = tooltip
|
||||
window?.setIsVisible(false)
|
||||
window?.orderFront(nil)
|
||||
set(windowTopLeftPoint: point, bottomOutOfScreenAdjustmentHeight: heightDelta)
|
||||
set(windowTopLeftPoint: point, bottomOutOfScreenAdjustmentHeight: heightDelta, useGCD: false)
|
||||
window?.setIsVisible(true)
|
||||
}
|
||||
|
||||
public func setColor(state: TooltipColorState) {
|
||||
|
@ -118,29 +120,6 @@ public class TooltipUI: NSWindowController {
|
|||
window?.orderOut(nil)
|
||||
}
|
||||
|
||||
private func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double) {
|
||||
guard let window = window else { return }
|
||||
let windowSize = window.frame.size
|
||||
|
||||
var adjustedPoint = windowTopLeftPoint
|
||||
var delta = heightDelta
|
||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||
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() {
|
||||
var rect = messageText.shrinkFrame()
|
||||
var bigRect = rect
|
||||
|
|
|
@ -133,12 +133,14 @@ extension SessionCtl {
|
|||
windowTopLeftPoint: NSPoint(
|
||||
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,
|
||||
useGCD: true
|
||||
)
|
||||
} else {
|
||||
ctlCandidateCurrent.set(
|
||||
windowTopLeftPoint: NSPoint(x: lineHeightRect().origin.x, y: lineHeightRect().origin.y - 4.0),
|
||||
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0
|
||||
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0,
|
||||
useGCD: true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
|
|||
}
|
||||
set {
|
||||
DispatchQueue.main.async {
|
||||
self.set(windowTopLeftPoint: newValue, bottomOutOfScreenAdjustmentHeight: 0)
|
||||
self.set(windowTopLeftPoint: newValue, bottomOutOfScreenAdjustmentHeight: 0, useGCD: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,33 +146,6 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
|
|||
get { selectedCandidate() }
|
||||
set { selectCandidate(withIdentifier: newValue) }
|
||||
}
|
||||
|
||||
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: Double) {
|
||||
DispatchQueue.main.async {
|
||||
self.doSet(windowTopLeftPoint: windowTopLeftPoint, bottomOutOfScreenAdjustmentHeight: height)
|
||||
}
|
||||
}
|
||||
|
||||
func doSet(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double) {
|
||||
guard var screenFrame = NSScreen.main?.visibleFrame else { return }
|
||||
var adjustedPoint = windowTopLeftPoint
|
||||
let windowSize = candidateFrame().size
|
||||
var delta = heightDelta
|
||||
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)
|
||||
|
||||
setCandidateFrameTopLeft(adjustedPoint)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Generate TISInputSource Object
|
||||
|
|
Loading…
Reference in New Issue