Динамические NSTooltips: модификатор (и) ключа события, влияющий на подсказки - PullRequest
0 голосов
/ 04 июля 2019

Существует ли механизм уведомлений для всплывающих подсказок, поэтому можно использовать ключевые модификаторы, чтобы сделать их динамичными? Я не знаю ни одного, поэтому пошел по этому пути, чтобы захватить создаваемое представление всплывающей подсказки и пытаться вызвать перерисовку, когда происходит ключевое событие.

Я отслеживаю ключевые модификаторы (в моем делегате приложения); сосредоточив внимание на SHIFT здесь, но любой ключевой модификатор подойдет:

var localKeyDownMonitor : Any? = nil
var globalKeyDownMonitor : Any? = nil
var shiftKeyDown : Bool = false {
    didSet {
        let notif = Notification(name: Notification.Name(rawValue: "shiftKeyDown"),
                                 object: NSNumber(booleanLiteral: shiftKeyDown));
        NotificationCenter.default.post(notif)
    }
}

, который установит процесс запуска приложения ...

// Local/Global Monitor
_ /*accessEnabled*/ = AXIsProcessTrustedWithOptions([kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String: true] as CFDictionary)
globalKeyDownMonitor = NSEvent.addGlobalMonitorForEvents(matching: NSEventMask.flagsChanged) { (event) -> Void in
    _ = self.keyDownMonitor(event: event)
}
localKeyDownMonitor = NSEvent.addLocalMonitorForEvents(matching: NSEventMask.flagsChanged) { (event) -> NSEvent? in
    return self.keyDownMonitor(event: event) ? nil : event
}

, а затем перехватить отправку уведомлений через делегат приложения didSet выше (поэтому при изменении значения отправляется уведомление!):

func keyDownMonitor(event: NSEvent) -> Bool {
    switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
    case [.shift]:
        self.shiftKeyDown = true
        return true

    default:
        //  Only clear when true
        if shiftKeyDown { self.shiftKeyDown = false }
        return false
    }
}

Для одноэлементных привязок всплывающей подсказки это может быть динамическим, если в уведомлении сообщается (KVO о некотором ключе), я бы хотел, чтобы процедура делегата представления действовала на этом:

func tableView(_ tableView: NSTableView, toolTipFor cell: NSCell, rect: NSRectPointer, tableColumn: NSTableColumn?, row: Int, mouseLocation: NSPoint) -> String {
    if tableView == playlistTableView
    {
        let play = (playlistArrayController.arrangedObjects as! [PlayList])[row]

        if shiftKeyDown {
            return String(format: "%ld play(s)", play.plays)
        }
        else
        {
            return String(format: "%ld item(s)", play.list.count)
        }
    }
    ...

Так что я бы хотел, чтобы мой обработчик уведомлений делал что-то вроде

internal func shiftKeyDown(_ note: Notification) {
    let keyPaths = ["cornerImage","cornerTooltip","<table-view>.<column-view>"]
    for keyPath in (keyPaths)
    {
        self.willChangeValue(forKey: keyPath)
    }
    if subview.className == "NSCustomToolTipDrawView" {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "CustomToolTipView"), object: subview)
    }
    for keyPath in (keyPaths)
    {
        self.didChangeValue(forKey: keyPath)
    }
}

где я хотел бы заставить всплывающую подсказку перерисовываться, но ничего не происходит.

То, что я сделал, чтобы получить представление всплывающей подсказки, - это просмотр любого уведомления (используйте для этого имя nil), которое выглядело многообещающим и нашло одно - путем мониторинга всех уведомлений, поэтому я публикую в нем заинтересованные контроллер представления, который является делегатом tableView. Контроллер представления наблюдает за «CustomToolTipView» и запоминает объект send - tooltipView; это новый вид всплывающей подсказки.

Но ничего не происходит - shiftKeyDown (), чтобы перерисовать представление.

Я подозреваю, что он не будет обновляться в текущем цикле событий, но я вижу выходные данные отладки.

1 Ответ

0 голосов
/ 08 июля 2019

С предложением * Виллека я перенес табличное представление на ячейку, добавил свойство get для всплывающей подсказки и получил соответствующие уведомления реестра соответствующих процедур init () для изменений клавиши Shift. Это привело к меньшему количеству кода. Беспроигрышный вариант: -)

...