If you have an issue with any of our projects. feel free to register.

Commit 581b9e42 authored by Dmitry Nevedomsky's avatar Dmitry Nevedomsky

Use SF Symbols in Preferences on Big Sur.

And refactoring of Preference Window.
parent 0fdabd55
......@@ -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
......@@ -11,49 +11,39 @@
@implementation GeneralPreferencePane
+ (GeneralPreferencePane *)preferencePaneWithView:(NSView *)v title:(NSString *)t iconNamed:(NSString *)n
@synthesize title = _title;
@synthesize icon = _icon;
@synthesize view;
+ (instancetype)preferencePaneWithView:(NSView *)view
title:(NSString *)title
systemIconName:(NSString *)systemIconName
orOldIconNamed:(NSString *)oldIconName
{
GeneralPreferencePane *pane = [[GeneralPreferencePane alloc] init];
if (pane)
{
[pane setView:v];
[pane setTitle:t];
NSImage *i = [[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:n]];
[pane setIcon:i];
}
return pane;
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
......@@ -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;
......
......@@ -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
......@@ -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"]];
}
......
......@@ -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
......@@ -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"]];
}
......
......@@ -8,20 +8,21 @@
#import <Cocoa/Cocoa.h>
#define NSLocalizedPrefString(key) \
[[NSBundle bundleWithIdentifier:@"org.cogx.cog.preferences"] localizedStringForKey:(key) value:@"" table:nil]
@protocol PreferencePanePlugin <NSObject>
@protocol PreferencePane <NSObject>
@required
// An array of PrefPaneController instances that the plugin has available
+ (NSArray *)preferencePanes;
@property(readonly) NSView *view;
@property(readonly, copy) NSString *title;
@property(readonly) NSImage *icon;
@end
@protocol PreferencePane <NSObject>
@protocol PreferencePanePlugin <NSObject>
@required
- (NSView *)view;
- (NSString *)title;
- (NSImage *)icon;
// An array of PrefPaneController instances that the plugin has available
+ (NSArray<id<PreferencePane>> *)preferencePanes;
@end
......@@ -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];
}
......
......@@ -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;
......
......@@ -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];
}