mirror of
https://github.com/MonitorControl/MonitorControl.git
synced 2026-05-15 14:15:55 -06:00
Addition of a "friendly" display name for Monitors (#89)
- Add customizable display name for monitors
This commit is contained in:
parent
e955d84123
commit
4c09ef1c5e
8 changed files with 121 additions and 14 deletions
7
MonitorControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
MonitorControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
@ -153,7 +153,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
self.displays.append(display)
|
||||
|
||||
let monitorMenuItem = NSMenuItem()
|
||||
monitorMenuItem.title = "\(name)"
|
||||
monitorMenuItem.title = "\(display.getFriendlyName())"
|
||||
if asSubMenu {
|
||||
monitorMenuItem.submenu = monitorSubMenu
|
||||
}
|
||||
|
|
@ -177,6 +177,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
// subscribe KeyTap event listener
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleListenForChanged), name: NSNotification.Name(Utils.PrefKeys.listenFor.rawValue), object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleShowContrastChanged), name: NSNotification.Name(Utils.PrefKeys.showContrast.rawValue), object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleFriendlyNameChanged), name: NSNotification.Name(Utils.PrefKeys.friendlyName.rawValue), object: nil)
|
||||
|
||||
// subscribe Audio output detector (AMCoreAudio)
|
||||
AMCoreAudio.NotificationCenter.defaultCenter.subscribe(self, eventType: AudioHardwareEvent.self, dispatchQueue: DispatchQueue.main)
|
||||
|
|
@ -226,6 +227,10 @@ extension AppDelegate: MediaKeyTapDelegate {
|
|||
self.updateDisplays()
|
||||
}
|
||||
|
||||
@objc func handleFriendlyNameChanged() {
|
||||
self.updateDisplays()
|
||||
}
|
||||
|
||||
private func startOrRestartMediaKeyTap() {
|
||||
var keys: [MediaKey]
|
||||
|
||||
|
|
|
|||
|
|
@ -137,6 +137,14 @@ class Display {
|
|||
return max == 0 ? 100 : max
|
||||
}
|
||||
|
||||
func setFriendlyName(_ value: String) {
|
||||
self.prefs.set(value, forKey: "friendlyName-\(self.identifier)")
|
||||
}
|
||||
|
||||
func getFriendlyName() -> String {
|
||||
return self.prefs.string(forKey: "friendlyName-\(self.identifier)") ?? self.name
|
||||
}
|
||||
|
||||
private func showOsd(command: DDC.Command, value: Int) {
|
||||
guard let manager = OSDManager.sharedManager() as? OSDManager else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -151,6 +151,9 @@ class Utils: NSObject {
|
|||
|
||||
/// Change Brightness/Volume for all screens
|
||||
case allScreens
|
||||
|
||||
/// Friendly name changed
|
||||
case friendlyName
|
||||
}
|
||||
|
||||
/// Keys for the value of listenFor option
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
<objects>
|
||||
<viewController storyboardIdentifier="DisplayPrefsVC" id="NAx-6T-ZPc" customClass="DisplayPrefsViewController" customModule="MonitorControl" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" id="EBf-qN-KaN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="486" height="223"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="677" height="223"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uXD-ZY-N3H">
|
||||
|
|
@ -91,13 +91,13 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B5k-we-kuP">
|
||||
<rect key="frame" x="20" y="20" width="446" height="100"/>
|
||||
<rect key="frame" x="20" y="20" width="637" height="100"/>
|
||||
<clipView key="contentView" drawsBackground="NO" id="4ot-Jo-X5O">
|
||||
<rect key="frame" x="1" y="0.0" width="444" height="99"/>
|
||||
<rect key="frame" x="1" y="0.0" width="635" height="99"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowSizeStyle="automatic" headerView="ckY-Px-mJn" viewBased="YES" id="dyo-uY-pMe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="444" height="76"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="635" height="76"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
|
|
@ -167,6 +167,42 @@
|
|||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn width="140" minWidth="40" maxWidth="1000" id="uoI-1J-RdD">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Friendly Name">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" title="Text Cell" id="afl-95-ZJl">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="aGt-d9-Qcx" customClass="FriendlyNameCellView" customModule="MonitorControl" customModuleProvider="target">
|
||||
<rect key="frame" x="196" y="1" width="140" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CB1-x8-d9G">
|
||||
<rect key="frame" x="0.0" y="0.0" width="140" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" title="Table View Cell" id="DGv-iu-Jg1">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<action selector="valueChanged:" target="aGt-d9-Qcx" id="Rkl-de-KE5"/>
|
||||
</connections>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="CB1-x8-d9G" id="iTj-Jy-ijH"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn width="80" minWidth="10" maxWidth="3.4028234663852886e+38" id="dgp-q7-cBK">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="ID">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
|
|
@ -181,7 +217,7 @@
|
|||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="vw4-Us-VHk">
|
||||
<rect key="frame" x="196" y="1" width="80" height="17"/>
|
||||
<rect key="frame" x="339" y="1" width="80" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="z5b-Gr-EmC">
|
||||
|
|
@ -214,7 +250,7 @@
|
|||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="eVa-Md-Avh">
|
||||
<rect key="frame" x="279" y="1" width="80" height="17"/>
|
||||
<rect key="frame" x="422" y="1" width="80" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NK1-rO-I0Z">
|
||||
|
|
@ -233,7 +269,7 @@
|
|||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn width="80" minWidth="10" maxWidth="3.4028234663852886e+38" id="Nvp-hI-w4x">
|
||||
<tableColumn width="128" minWidth="10" maxWidth="3.4028234663852886e+38" id="Nvp-hI-w4x">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Model">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
|
@ -247,11 +283,11 @@
|
|||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="C4F-JT-GfP">
|
||||
<rect key="frame" x="362" y="1" width="80" height="17"/>
|
||||
<rect key="frame" x="505" y="1" width="128" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4Vl-7d-eft">
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="17"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="128" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="4or-hS-WeW">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
|
@ -284,7 +320,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<tableHeaderView key="headerView" id="ckY-Px-mJn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="444" height="23"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="635" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableHeaderView>
|
||||
</scrollView>
|
||||
|
|
@ -319,7 +355,7 @@
|
|||
</viewController>
|
||||
<customObject id="34q-0u-YTQ" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1159" y="223.5"/>
|
||||
<point key="canvasLocation" x="1254.5" y="223.5"/>
|
||||
</scene>
|
||||
<!--Main Prefs View Controller-->
|
||||
<scene sceneID="zAg-r8-WQ5">
|
||||
|
|
|
|||
33
MonitorControl/UI/FriendlyNameCellView.swift
Normal file
33
MonitorControl/UI/FriendlyNameCellView.swift
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import Cocoa
|
||||
import os.log
|
||||
|
||||
class FriendlyNameCellView: NSTableCellView {
|
||||
var display: Display?
|
||||
let prefs = UserDefaults.standard
|
||||
|
||||
override func draw(_ dirtyRect: NSRect) {
|
||||
super.draw(dirtyRect)
|
||||
}
|
||||
|
||||
@IBAction func valueChanged(_ sender: NSTextFieldCell) {
|
||||
if let display = display {
|
||||
let newValue = sender.stringValue
|
||||
let originalValue = display.getFriendlyName()
|
||||
|
||||
if newValue.isEmpty {
|
||||
self.textField?.stringValue = originalValue
|
||||
return
|
||||
}
|
||||
|
||||
if newValue != originalValue,
|
||||
!newValue.isEmpty {
|
||||
display.setFriendlyName(newValue)
|
||||
NotificationCenter.default.post(name: Notification.Name(Utils.PrefKeys.friendlyName.rawValue), object: nil)
|
||||
|
||||
#if DEBUG
|
||||
os_log("Value changed for friendly name: %{public}@", type: .info, "from `\(originalValue)` to `\(newValue)`")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,9 @@
|
|||
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "CHc-s5-4MN"; */
|
||||
"CHc-s5-4MN.headerCell.title" = "Display Name";
|
||||
|
||||
/* Class = "NSTableColumn"; headerCell.title = "Friendly Name"; ObjectID = "uoI-1J-RdD"; */
|
||||
"uoI-1J-RdD.headerCell.title" = "Friendly Name";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
|
||||
"Dcz-GG-1li.title" = "Keys";
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class DisplayPrefsViewController: NSViewController, MASPreferencesViewController
|
|||
enum DisplayCell: String {
|
||||
case checkbox
|
||||
case name
|
||||
case friendlyName
|
||||
case identifier
|
||||
case vendor
|
||||
case model
|
||||
|
|
@ -96,14 +97,18 @@ class DisplayPrefsViewController: NSViewController, MASPreferencesViewController
|
|||
text = display.name
|
||||
cellType = DisplayCell.name
|
||||
} else if tableColumn == tableView.tableColumns[2] {
|
||||
// Friendly Name
|
||||
text = display.getFriendlyName()
|
||||
cellType = DisplayCell.friendlyName
|
||||
} else if tableColumn == tableView.tableColumns[3] {
|
||||
// Identifier
|
||||
text = "\(display.identifier)"
|
||||
cellType = DisplayCell.identifier
|
||||
} else if tableColumn == tableView.tableColumns[3] {
|
||||
} else if tableColumn == tableView.tableColumns[4] {
|
||||
// Vendor
|
||||
text = display.identifier.vendorNumber.map { String(format: "0x%02X", $0) } ?? NSLocalizedString("unknown", comment: "unknown vendor")
|
||||
cellType = DisplayCell.vendor
|
||||
} else if tableColumn == tableView.tableColumns[4] {
|
||||
} else if tableColumn == tableView.tableColumns[5] {
|
||||
// Model
|
||||
text = display.identifier.modelNumber.map { String(format: "0x%02X", $0) } ?? NSLocalizedString("unknown", comment: "unknown model")
|
||||
cellType = DisplayCell.model
|
||||
|
|
@ -117,6 +122,13 @@ class DisplayPrefsViewController: NSViewController, MASPreferencesViewController
|
|||
}
|
||||
return cell
|
||||
}
|
||||
} else if cellType == DisplayCell.friendlyName {
|
||||
if let cell = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: nil) as? FriendlyNameCellView {
|
||||
cell.display = display
|
||||
cell.textField?.stringValue = text
|
||||
cell.textField?.isEditable = true
|
||||
return cell
|
||||
}
|
||||
} else {
|
||||
if let cell = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: nil) as? NSTableCellView {
|
||||
cell.textField?.stringValue = text
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue