Use SF Symbols in Preferences on Big Sur.

And refactoring of Preference Window.
CQTexperiment
Dzmitry Neviadomski 2021-01-08 08:25:30 +03:00
parent 0fdabd55dd
commit 581b9e42b3
12 changed files with 341 additions and 324 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15400" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15400"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -13,6 +13,7 @@
<outlet property="hotKeyPane" destination="6" id="14"/>
<outlet property="iTunesStyleCheck" destination="AIz-WH-Wqk" id="2n1-pY-cZR"/>
<outlet property="midiPane" destination="i5B-ga-Atm" id="rbe-uK-5n2"/>
<outlet property="notificationsView" destination="U4w-jw-ca5" id="wVJ-GH-A21"/>
<outlet property="outputPane" destination="57" id="75"/>
<outlet property="playlistView" destination="231" id="244"/>
<outlet property="scrobblerView" destination="0nK-XQ-5MY" id="dFj-Pk-FCG"/>
@ -21,6 +22,95 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="231" userLabel="PlaylistView">
<rect key="frame" x="0.0" y="0.0" width="530" height="139"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="310">
<rect key="frame" x="18" y="35" width="395" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Read CUE sheets when adding folders to playlist" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="311">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="52" name="value" keyPath="values.readCueSheetsInFolders" id="328"/>
</connections>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="261">
<rect key="frame" x="17" y="59" width="138" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="When opening file with ⇧ or ⌃⌘ held:" id="262">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="259">
<rect key="frame" x="17" y="102" width="129" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="When opening files:" id="260">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="253">
<rect key="frame" x="157" y="63" width="257" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" inset="2" id="254">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="255">
<items>
<menuItem title="Item 1" id="256"/>
<menuItem title="Item 2" id="257"/>
<menuItem title="Item 3" id="258"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<binding destination="246" name="content" keyPath="arrangedObjects" id="264"/>
<binding destination="246" name="contentValues" keyPath="arrangedObjects.name" previousBinding="307" id="308"/>
<binding destination="246" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="264" id="307"/>
<binding destination="52" name="selectedObject" keyPath="values.openingFilesAlteredBehavior" previousBinding="308" id="309"/>
</connections>
</popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="247">
<rect key="frame" x="157" y="95" width="257" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" selectedItem="250" id="248">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="249">
<items>
<menuItem title="Item 1" state="on" id="250"/>
<menuItem title="Item 2" id="251"/>
<menuItem title="Item 3" id="252"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<binding destination="246" name="content" keyPath="arrangedObjects" id="263"/>
<binding destination="246" name="contentValues" keyPath="arrangedObjects.name" previousBinding="304" id="305"/>
<binding destination="246" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="263" id="304"/>
<binding destination="52" name="selectedObject" keyPath="values.openingFilesBehavior" previousBinding="305" id="306"/>
</connections>
</popUpButton>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6QS-GF-Vnc">
<rect key="frame" x="18" y="15" width="388" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Resume playback on startup" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="fUg-Cg-gXa">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="52" name="value" keyPath="values.resumePlaybackOnStartup" id="8OB-tj-Hd0"/>
</connections>
</button>
</subviews>
<point key="canvasLocation" x="-151" y="-239"/>
</customView>
<customObject id="6" userLabel="HotKeyPane" customClass="HotKeyPane">
<connections>
<outlet property="nextHotKeyControl" destination="28" id="36"/>
@ -31,7 +121,7 @@
</connections>
</customObject>
<customView id="11" userLabel="HotKeyView">
<rect key="frame" x="0.0" y="0.0" width="500" height="131"/>
<rect key="frame" x="0.0" y="0.0" width="530" height="131"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="28" customClass="HotKeyControl">
@ -119,10 +209,10 @@
</textFieldCell>
</textField>
</subviews>
<point key="canvasLocation" x="123" y="139"/>
<point key="canvasLocation" x="-151" y="-33"/>
</customView>
<customView id="50" userLabel="UpdatesView">
<rect key="frame" x="0.0" y="0.0" width="500" height="82"/>
<rect key="frame" x="0.0" y="0.0" width="530" height="82"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="111">
@ -139,7 +229,7 @@
<autoresizingMask key="autoresizingMask"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" id="208">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="107">
<items>
<menuItem title="Stable" id="108"/>
@ -167,6 +257,7 @@
</connections>
</button>
</subviews>
<point key="canvasLocation" x="-151" y="153"/>
</customView>
<userDefaultsController representsSharedInstance="YES" id="52" userLabel="Shared Defaults"/>
<customObject id="57" userLabel="OutputPane" customClass="OutputPane">
@ -176,7 +267,7 @@
</connections>
</customObject>
<customView id="58" userLabel="OutputView">
<rect key="frame" x="0.0" y="0.0" width="500" height="103"/>
<rect key="frame" x="0.0" y="0.0" width="530" height="103"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="65">
@ -193,7 +284,7 @@
<autoresizingMask key="autoresizingMask"/>
<popUpButtonCell key="cell" type="push" title="Item1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="62" id="210">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="61">
<items>
<menuItem title="Item1" state="on" id="62"/>
@ -223,7 +314,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="vmS-eb-zen">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="V8o-Xy-HUW">
<items>
<menuItem title="Item 1" id="oWh-lD-mFH"/>
@ -240,6 +331,7 @@
</connections>
</popUpButton>
</subviews>
<point key="canvasLocation" x="-151" y="322"/>
</customView>
<customObject id="i5B-ga-Atm" userLabel="MIDIPane" customClass="MIDIPane">
<connections>
@ -273,7 +365,7 @@
</declaredKeys>
</arrayController>
<customView id="0nK-XQ-5MY" userLabel="ScrobblerView">
<rect key="frame" x="0.0" y="0.0" width="500" height="94"/>
<rect key="frame" x="0.0" y="0.0" width="530" height="94"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3gi-0d-78Z">
@ -310,98 +402,10 @@
</connections>
</button>
</subviews>
<point key="canvasLocation" x="450" y="-262"/>
</customView>
<customView id="231" userLabel="PlaylistView">
<rect key="frame" x="0.0" y="0.0" width="500" height="139"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="310">
<rect key="frame" x="18" y="35" width="395" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Read CUE sheets when adding folders to playlist" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="311">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="52" name="value" keyPath="values.readCueSheetsInFolders" id="328"/>
</connections>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="261">
<rect key="frame" x="17" y="59" width="138" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="When opening file with ⇧ or ⌃⌘ held:" id="262">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="259">
<rect key="frame" x="17" y="102" width="129" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="When opening files:" id="260">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="253">
<rect key="frame" x="157" y="63" width="257" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" inset="2" id="254">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<menu key="menu" title="OtherViews" id="255">
<items>
<menuItem title="Item 1" id="256"/>
<menuItem title="Item 2" id="257"/>
<menuItem title="Item 3" id="258"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<binding destination="246" name="content" keyPath="arrangedObjects" id="264"/>
<binding destination="246" name="contentValues" keyPath="arrangedObjects.name" previousBinding="307" id="308"/>
<binding destination="246" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="264" id="307"/>
<binding destination="52" name="selectedObject" keyPath="values.openingFilesAlteredBehavior" previousBinding="308" id="309"/>
</connections>
</popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="247">
<rect key="frame" x="157" y="95" width="257" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" selectedItem="250" id="248">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<menu key="menu" title="OtherViews" id="249">
<items>
<menuItem title="Item 1" state="on" id="250"/>
<menuItem title="Item 2" id="251"/>
<menuItem title="Item 3" id="252"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<binding destination="246" name="content" keyPath="arrangedObjects" id="263"/>
<binding destination="246" name="contentValues" keyPath="arrangedObjects.name" previousBinding="304" id="305"/>
<binding destination="246" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="263" id="304"/>
<binding destination="52" name="selectedObject" keyPath="values.openingFilesBehavior" previousBinding="305" id="306"/>
</connections>
</popUpButton>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6QS-GF-Vnc">
<rect key="frame" x="18" y="15" width="388" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Resume playback on startup" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="fUg-Cg-gXa">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="52" name="value" keyPath="values.resumePlaybackOnStartup" id="8OB-tj-Hd0"/>
</connections>
</button>
</subviews>
<point key="canvasLocation" x="-78" y="-31.5"/>
</customView>
<customView id="U4w-jw-ca5" userLabel="GrowlView">
<rect key="frame" x="0.0" y="0.0" width="500" height="94"/>
<customView id="U4w-jw-ca5" userLabel="NotificationsView">
<rect key="frame" x="0.0" y="0.0" width="530" height="94"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="njn-Xl-9k9">
@ -438,10 +442,10 @@
</connections>
</button>
</subviews>
<point key="canvasLocation" x="348" y="132"/>
<point key="canvasLocation" x="450" y="-52"/>
</customView>
<customView id="CgN-sy-RmM" userLabel="AppearanceView">
<rect key="frame" x="0.0" y="0.0" width="500" height="54"/>
<rect key="frame" x="0.0" y="0.0" width="530" height="54"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="haX-dq-OIe">
@ -456,9 +460,10 @@
</connections>
</button>
</subviews>
<point key="canvasLocation" x="450" y="139"/>
</customView>
<customView wantsLayer="YES" id="JXu-ar-J3Y" userLabel="MIDIView">
<rect key="frame" x="0.0" y="0.0" width="500" height="137"/>
<rect key="frame" x="0.0" y="0.0" width="530" height="137"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SBO-WF-DVS" userLabel="Push Button - Select a SoundFont">
@ -521,7 +526,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="vaQ-pZ-jXy" id="xcv-1b-kTI">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="pRc-b6-sMR">
<items>
<menuItem title="Item 1" state="on" id="vaQ-pZ-jXy"/>
@ -551,7 +556,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" enabled="NO" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" altersStateOfSelectedItem="NO" selectedItem="XzK-h2-vIT" id="qzt-Ox-taI">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" autoenablesItems="NO" id="q1g-E5-NwQ">
<items>
<menuItem title="Item 1" id="XzK-h2-vIT"/>
@ -577,7 +582,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="3Gx-cs-3B0" id="5q7-83-7V6">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="HKM-FW-dhH">
<items>
<menuItem title="Item 1" state="on" id="3Gx-cs-3B0"/>
@ -594,7 +599,7 @@
</connections>
</popUpButton>
</subviews>
<point key="canvasLocation" x="340" y="567.5"/>
<point key="canvasLocation" x="450" y="339"/>
</customView>
<arrayController objectClassName="NSDictionary" editable="NO" id="JB6-r9-XpG" userLabel="ResamplerBehavior" customClass="ResamplerBehaviorArrayController">
<declaredKeys>

View File

@ -10,16 +10,17 @@
#import "PreferencePanePlugin.h"
@interface GeneralPreferencePane : NSObject <PreferencePane> {
IBOutlet NSView *view;
NSString *title;
NSImage *icon;
IBOutlet NSView *view;
}
+ (GeneralPreferencePane *)preferencePaneWithView:(NSView *)v title:(NSString *)t iconNamed:(NSString *)i;
+ (instancetype)preferencePaneWithView:(NSView *)view
title:(NSString *)title
systemIconName:(NSString *)systemIconName
orOldIconNamed:(NSString *)oldIconName;
- (void)setView:(NSView *)v;
- (void)setTitle:(NSString *)t;
- (void)setIcon:(NSImage *)i;
- (instancetype) init NS_UNAVAILABLE;
- (instancetype) initWithView:(NSView *)contentView
title:(NSString *)title
icon:(NSImage *)image NS_DESIGNATED_INITIALIZER;
@end

View File

@ -11,49 +11,39 @@
@implementation GeneralPreferencePane
+ (GeneralPreferencePane *)preferencePaneWithView:(NSView *)v title:(NSString *)t iconNamed:(NSString *)n
{
GeneralPreferencePane *pane = [[GeneralPreferencePane alloc] init];
if (pane)
{
[pane setView:v];
[pane setTitle:t];
@synthesize title = _title;
@synthesize icon = _icon;
@synthesize view;
NSImage *i = [[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:n]];
[pane setIcon:i];
}
return pane;
+ (instancetype)preferencePaneWithView:(NSView *)view
title:(NSString *)title
systemIconName:(NSString *)systemIconName
orOldIconNamed:(NSString *)oldIconName
{
NSImage *icon;
if (@available(macOS 11.0, *))
{
if (systemIconName)
icon = [NSImage imageWithSystemSymbolName:systemIconName accessibilityDescription:nil];
}
if (icon == nil)
{
NSString *file = [[NSBundle bundleForClass:[self class]] pathForImageResource:oldIconName];
icon = [[NSImage alloc] initWithContentsOfFile:file];
}
return [[GeneralPreferencePane alloc] initWithView:view title:title icon:icon];
}
- (NSView *)view
{
return view;
}
- (NSString *)title
{
return title;
}
- (NSImage *)icon
{
return icon;
}
- (void)setView:(NSView *)v
{
view = v;
}
- (void)setTitle:(NSString *)t
{
title = t;
}
- (void)setIcon:(NSImage *)i
{
icon = i;
- (instancetype)initWithView:(NSView *)contentView title:(NSString *)title icon:(NSImage *)image {
self = [[[self class] alloc] init];
if (self)
{
view = contentView;
_title = title;
_icon = image;
}
return self;
}
@end

View File

@ -15,17 +15,16 @@
#import "MIDIPane.h"
@interface GeneralPreferencesPlugin : NSObject <PreferencePanePlugin> {
IBOutlet HotKeyPane *hotKeyPane;
IBOutlet OutputPane *outputPane;
IBOutlet HotKeyPane *hotKeyPane;
IBOutlet OutputPane *outputPane;
IBOutlet MIDIPane *midiPane;
IBOutlet NSView *playlistView;
IBOutlet NSView *scrobblerView;
IBOutlet NSView *updatesView;
IBOutlet NSView *growlView;
IBOutlet NSView *appearanceView;
IBOutlet NSView *midiView;
IBOutlet NSView *playlistView;
IBOutlet NSView *scrobblerView;
IBOutlet NSView *updatesView;
IBOutlet NSView *notificationsView;
IBOutlet NSView *appearanceView;
__weak IBOutlet NSButton *iTunesStyleCheck;
}
@ -36,7 +35,7 @@
- (GeneralPreferencePane *)updatesPane;
- (GeneralPreferencePane *)scrobblerPane;
- (GeneralPreferencePane *)playlistPane;
- (GeneralPreferencePane *)growlPane;
- (GeneralPreferencePane *)notificationsPane;
- (GeneralPreferencePane *)appearancePane;

View File

@ -25,28 +25,28 @@
+ (NSArray *)preferencePanes
{
GeneralPreferencesPlugin *plugin = [[GeneralPreferencesPlugin alloc] init];
[NSBundle loadNibNamed:@"Preferences" owner:plugin];
return [NSArray arrayWithObjects:
[plugin playlistPane],
[plugin hotKeyPane],
[plugin updatesPane],
[plugin outputPane],
[plugin scrobblerPane],
[plugin growlPane],
[plugin appearancePane],
[plugin midiPane],
nil];
}
[[NSBundle bundleWithIdentifier:@"org.cogx.cog.preferences"] loadNibNamed:@"Preferences"
owner:plugin
topLevelObjects:nil];
return @[[plugin playlistPane],
[plugin hotKeyPane],
[plugin updatesPane],
[plugin outputPane],
[plugin scrobblerPane],
[plugin notificationsPane],
[plugin appearancePane],
[plugin midiPane]];
}
- (HotKeyPane *)hotKeyPane
{
return hotKeyPane;
return hotKeyPane;
}
- (OutputPane *)outputPane
{
return outputPane;
return outputPane;
}
- (MIDIPane *)midiPane
@ -56,36 +56,51 @@
- (GeneralPreferencePane *)updatesPane
{
return [GeneralPreferencePane preferencePaneWithView:updatesView title:NSLocalizedStringFromTableInBundle(@"Updates", nil, [NSBundle bundleForClass:[self class]], @"") iconNamed:@"updates"];
return [GeneralPreferencePane preferencePaneWithView:updatesView
title:NSLocalizedPrefString(@"Updates")
systemIconName:@"arrow.triangle.2.circlepath.circle.fill"
orOldIconNamed:@"updates"];
}
- (GeneralPreferencePane *)scrobblerPane
{
return [GeneralPreferencePane preferencePaneWithView:scrobblerView title:NSLocalizedStringFromTableInBundle(@"Last.fm", nil, [NSBundle bundleForClass:[self class]], @"") iconNamed:@"lastfm"];
return [GeneralPreferencePane preferencePaneWithView:scrobblerView
title:NSLocalizedPrefString(@"Scrobble")
systemIconName:@"dot.radiowaves.left.and.right"
orOldIconNamed:@"lastfm"];
}
- (GeneralPreferencePane *)playlistPane
{
return [GeneralPreferencePane preferencePaneWithView:playlistView title:NSLocalizedStringFromTableInBundle(@"Playlist", nil, [NSBundle bundleForClass:[self class]], @"") iconNamed:@"playlist"];
return [GeneralPreferencePane preferencePaneWithView:playlistView
title:NSLocalizedPrefString(@"Playlist")
systemIconName:@"music.note.list"
orOldIconNamed:@"playlist"];
}
- (GeneralPreferencePane *)growlPane
- (GeneralPreferencePane *)notificationsPane
{
if (@available(macOS 10.14, *)) {
if (iTunesStyleCheck) {
iTunesStyleCheck.hidden = YES;
NSSize size = growlView.frame.size;
NSSize size = notificationsView.frame.size;
size.height -= 18;
[growlView setFrameSize:size];
[notificationsView setFrameSize:size];
}
}
return [GeneralPreferencePane preferencePaneWithView:growlView title:NSLocalizedStringFromTableInBundle(@"Growl", nil, [NSBundle bundleForClass:[self class]], @"") iconNamed:@"growl"];
return [GeneralPreferencePane preferencePaneWithView:notificationsView
title:NSLocalizedPrefString(@"Notifications")
systemIconName:@"bell.fill"
orOldIconNamed:@"growl"];
}
- (GeneralPreferencePane *)appearancePane
{
return [GeneralPreferencePane preferencePaneWithView:appearanceView title:NSLocalizedStringFromTableInBundle(@"Appearance", nil, [NSBundle bundleForClass:[self class]], @"") iconNamed:@"appearance"];
return [GeneralPreferencePane preferencePaneWithView:appearanceView
title:NSLocalizedPrefString(@"Appearance")
systemIconName:@"paintpalette.fill"
orOldIconNamed:@"appearance"];
}
@end

View File

@ -31,11 +31,13 @@ static void setControlText(HotKeyControl* control, NSString* kcprop, NSString* m
- (NSString *)title
{
return NSLocalizedStringFromTableInBundle(@"Hot Keys", nil, [NSBundle bundleForClass:[self class]], @"");
return NSLocalizedPrefString(@"Hot Keys");
}
- (NSImage *)icon
{
if (@available(macOS 11.0, *))
return [NSImage imageWithSystemSymbolName:@"keyboard" accessibilityDescription:nil];
return [[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:@"hot_keys"]];
}

View File

@ -12,17 +12,19 @@
- (NSString *)title
{
return NSLocalizedStringFromTableInBundle(@"Synthesis", nil, [NSBundle bundleForClass:[self class]], @"");
return NSLocalizedPrefString(@"Synthesis");
}
- (NSImage *)icon
{
if (@available(macOS 11.0, *))
return [NSImage imageWithSystemSymbolName:@"pianokeys" accessibilityDescription:nil];
return [[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:@"midi"]];
}
- (IBAction)setSoundFont:(id)sender
{
NSArray *fileTypes = [NSArray arrayWithObjects:@"sf2",@"sf2pack",@"sflist",@"json",nil];
NSArray *fileTypes = @[@"sf2", @"sf2pack", @"sflist", @"json"];
NSOpenPanel * panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:NO];
[panel setCanChooseDirectories:NO];
@ -42,10 +44,8 @@
- (IBAction)setMidiPlugin:(id)sender
{
NSString * plugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"];
if ([plugin isEqualToString:@"Sc55rolD"] || [plugin isEqualToString:@"Sc55RoCl"])
[midiFlavorControl setEnabled:YES];
else
[midiFlavorControl setEnabled:NO];
BOOL enabled = [plugin isEqualToString:@"Sc55rolD"] || [plugin isEqualToString:@"Sc55RoCl"];
[midiFlavorControl setEnabled:enabled];
}
@end

View File

@ -13,11 +13,13 @@
- (NSString *)title
{
return NSLocalizedStringFromTableInBundle(@"Output", nil, [NSBundle bundleForClass:[self class]], @"");
return NSLocalizedPrefString(@"Output");
}
- (NSImage *)icon
{
if (@available(macOS 11.0, *))
return [NSImage imageWithSystemSymbolName:@"hifispeaker.2.fill" accessibilityDescription:nil];
return [[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:@"output"]];
}

View File

@ -8,20 +8,21 @@
#import <Cocoa/Cocoa.h>
#define NSLocalizedPrefString(key) \
[[NSBundle bundleWithIdentifier:@"org.cogx.cog.preferences"] localizedStringForKey:(key) value:@"" table:nil]
@protocol PreferencePane <NSObject>
@required
@property(readonly) NSView *view;
@property(readonly, copy) NSString *title;
@property(readonly) NSImage *icon;
@end
@protocol PreferencePanePlugin <NSObject>
@required
// An array of PrefPaneController instances that the plugin has available
+ (NSArray *)preferencePanes;
@end
@protocol PreferencePane <NSObject>
@required
- (NSView *)view;
- (NSString *)title;
- (NSImage *)icon;
+ (NSArray<id<PreferencePane>> *)preferencePanes;
@end

View File

@ -17,17 +17,13 @@
if (nil == window) {
// Determine path to the sample preference panes
NSString *pluginPath = [[NSBundle mainBundle] pathForResource:@"General" ofType:@"preferencePane"];
NSBundle *bundle = [NSBundle bundleWithPath:pluginPath];
NSBundle *bundle = [NSBundle bundleWithPath:pluginPath];
PreferencePluginController *pluginController = [[PreferencePluginController alloc] initWithPlugins:[NSArray arrayWithObject:bundle]];
window = [[PreferencesWindow alloc] initWithPreferencePanes:[pluginController preferencePanes]];
// Set which panes are included, and their order.
//[prefs setPanesOrder:[NSArray arrayWithObjects:@"General", @"Updating", @"A Non-Existent Preference Pane", nil]];
PreferencePluginController *pluginController = [[PreferencePluginController alloc] initWithPlugins:@[bundle]];
window = [[PreferencesWindow alloc] initWithPreferencePanes:[pluginController preferencePanes]];
}
// Show the preferences window.
[window show];
}

View File

@ -8,14 +8,18 @@
#import <Cocoa/Cocoa.h>
/**
* TODO: Use NSTabViewController.
* This will allow to manage Toolbar automatically, lazy load
* preference panes and and crossfade between them.
*/
@interface PreferencesWindow : NSWindow<NSToolbarDelegate>
@interface PreferencesWindow : NSWindow<NSToolbarDelegate> {
NSMutableArray *preferencePaneOrder;
NSMutableDictionary *preferencePanes;
NSMutableDictionary *toolbarItems;
}
- (id)initWithPreferencePanes:(NSArray *)preferencePanes;
- (instancetype)initWithPreferencePanes:(NSArray *)preferencePanes NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithContentRect:(NSRect)contentRect
styleMask:(NSWindowStyleMask)style
backing:(NSBackingStoreType)backingStoreType
defer:(BOOL)flag NS_UNAVAILABLE;
- (void)show;

View File

@ -20,144 +20,148 @@
@end
@implementation PreferencesWindow
@implementation PreferencesWindow {
NSMutableArray<NSToolbarItemIdentifier> *preferencePaneOrder;
NSMutableDictionary<NSToolbarItemIdentifier, id<PreferencePane>> *preferencePanes;
NSMutableDictionary<NSToolbarItemIdentifier, NSToolbarItem *> *toolbarItems;
}
- (id)initWithPreferencePanes:(NSArray *)panes
- (instancetype)initWithPreferencePanes:(NSArray<id<PreferencePane>> *)panes
{
self = [super initWithContentRect:NSMakeRect(0, 0, 350, 200)
styleMask:(NSClosableWindowMask | NSResizableWindowMask | NSTitledWindowMask)
backing:NSBackingStoreBuffered
defer:NO];
if (self)
{
preferencePaneOrder = [[NSMutableArray alloc] init];
preferencePanes = [[NSMutableDictionary alloc] init];
for (id<PreferencePane> pane in panes) {
[preferencePaneOrder addObject:[pane title]];
[preferencePanes setObject:pane forKey:[pane title]];
}
[self setReleasedWhenClosed:NO];
[self setTitle:@"Preferences"]; // initial default title
[self setShowsToolbarButton: NO];
[self setShowsResizeIndicator:NO];
[self center];
[[self standardWindowButton:NSWindowZoomButton] setEnabled:FALSE];
NSWindowStyleMask windowStyleMask =
(NSWindowStyleMaskClosable | NSWindowStyleMaskTitled);
self = [super initWithContentRect:NSMakeRect(0, 0, 530, 300)
styleMask:windowStyleMask
backing:NSBackingStoreBuffered
defer:NO];
if (self)
{
preferencePaneOrder = [[NSMutableArray alloc] init];
preferencePanes = [[NSMutableDictionary alloc] init];
for (id<PreferencePane> pane in panes) {
[preferencePaneOrder addObject:[pane title]];
[preferencePanes setObject:pane forKey:[pane title]];
}
[self setReleasedWhenClosed:NO];
[self setTitle:@"Preferences"];
[self center];
if (@available(macOS 11, *)) {
[self setToolbarStyle:NSWindowToolbarStylePreference];
}
[self createToolbar];
}
[self createToolbar];
}
return self;
}
- (NSString *)lastPaneDefaultsKey
{
return @"LastPreferencePane";
}
-(NSRect)newFrameForNewContentView:(NSView *)view {
NSRect newFrame = [self frame];
newFrame.size.height = [view frame].size.height + ([self frame].size.height - [[self contentView] frame].size.height);
newFrame.size.width = [view frame].size.width;
newFrame.origin.y += ([[self contentView] frame].size.height - [view frame].size.height);
return newFrame;
return @"LastPreferencePane";
}
- (void)setContentView:(NSView *)view animate:(BOOL)animate
{
NSSize newSize = view.bounds.size;
NSSize oldSize = [self contentView].bounds.size;
CGFloat diff = newSize.height - oldSize.height;
NSRect newFrame = [self frame];
newFrame.size.height += diff;
newFrame.origin.y -= diff;
if (animate) {
NSView *tempView = [[NSView alloc] initWithFrame:[[self contentView] frame]];
[self setContentView:tempView];
[self setContentView:nil];
}
NSRect newFrame = [self newFrameForNewContentView:view];
[self setFrame:newFrame display:animate animate:animate];
[self setContentView:view];
[self setFrame:newFrame display:animate animate:animate];
[self setContentView:view];
[self setContentSize:newSize];
}
- (BOOL)loadPaneNamed:(NSString *)name display:(BOOL)display
{
id<PreferencePane> paneController = [preferencePanes objectForKey:name];
id<PreferencePane> paneController = preferencePanes[name];
if (!paneController) {
return NO;
}
NSView *paneView = [paneController view];
if (!paneView) {
if (!paneView || [self contentView] == paneView) {
return NO;
}
[self setContentView:paneView animate:display];
[self setTitle:name];
[self setContentView:paneView animate:display];
// Update defaults
[[NSUserDefaults standardUserDefaults] setObject:name forKey:[self lastPaneDefaultsKey]];
[[self toolbar] setSelectedItemIdentifier:name];
return YES;
}
- (void)createToolbar
{
toolbarItems = [[NSMutableDictionary alloc] init];
for (NSString *name in preferencePaneOrder) {
id<PreferencePane> pane = [preferencePanes objectForKey:name];
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:name];
[item setPaletteLabel:name]; // item's label in the "Customize Toolbar" sheet (not relevant here, but we set it anyway)
[item setLabel:name]; // item's label in the toolbar
[item setToolTip:name];
[item setImage:[pane icon]];
[item setTarget:self];
[item setAction:@selector(toolbarItemClicked:)]; // action called when item is clicked
[toolbarItems setObject:item forKey:name];
}
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:[bundleIdentifier stringByAppendingString:@" Preferences Toolbar"]];
[toolbar setDelegate:self];
[toolbar setAllowsUserCustomization:NO];
[toolbar setAutosavesConfiguration:NO];
[toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
[toolbar setSizeMode:NSToolbarSizeModeDefault];
[self setToolbar:toolbar];
toolbarItems = [[NSMutableDictionary alloc] init];
for (NSString *name in preferencePaneOrder) {
id<PreferencePane> pane = preferencePanes[name];
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:name];
[item setPaletteLabel:name]; // item's label in the "Customize Toolbar" sheet (not relevant here, but we set it anyway)
[item setLabel:name]; // item's label in the toolbar
[item setToolTip:name];
[item setImage:[pane icon]];
[item setTarget:self];
[item setAction:@selector(toolbarItemClicked:)]; // action called when item is clicked
toolbarItems[name] = item;
}
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:[bundleIdentifier stringByAppendingString:@" Preferences Toolbar"]];
[toolbar setDelegate:self];
[toolbar setAllowsUserCustomization:NO];
[toolbar setAutosavesConfiguration:NO];
[toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
[toolbar setSizeMode:NSToolbarSizeModeDefault];
[self setToolbar:toolbar];
}
- (void)show
{
NSString *lastPane = [[NSUserDefaults standardUserDefaults] objectForKey:[self lastPaneDefaultsKey]];
if (nil == lastPane) {
if (0 >= [preferencePaneOrder count]) {
ALog(@"Error: Preference panes not found!");
}
lastPane = [preferencePaneOrder objectAtIndex:0];
}
[self loadPaneNamed:lastPane display:NO];
[self makeKeyAndOrderFront:self];
NSString *lastPane = [[NSUserDefaults standardUserDefaults] objectForKey:[self lastPaneDefaultsKey]];
// Previous pane names migrations.
if ([lastPane isEqualToString:NSLocalizedPrefString(@"Growl")]) {
lastPane = NSLocalizedPrefString(@"Notifications");
}
if ([lastPane isEqualToString:NSLocalizedPrefString(@"Last.fm")]) {
lastPane = NSLocalizedPrefString(@"Scrobble");
}
if (nil == lastPane) {
if (0 >= [preferencePaneOrder count]) {
ALog(@"Error: Preference panes not found!");
}
lastPane = preferencePaneOrder[0];
}
[self loadPaneNamed:lastPane display:NO];
[self makeKeyAndOrderFront:self];
}
// Close on Esc pressed.
- (void)cancelOperation:(id)sender {
[self close];
}
#pragma mark Delegate methods
@ -180,14 +184,12 @@
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
{
return [toolbarItems objectForKey:itemIdentifier];
return toolbarItems[itemIdentifier];
}
- (void)toolbarItemClicked:(NSToolbarItem *)item
{
if (![[item itemIdentifier] isEqualToString:[self title]]) {
[self loadPaneNamed:[item itemIdentifier] display:YES];
}
[self loadPaneNamed:[item itemIdentifier] display:YES];
}
@end