Add support for custom Dock icons while running
The emoji labeled buttons will convert and save their respective state icon to the settings folder, and refresh the current icon as necessary. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
78fa70a770
commit
ab798fd86a
18 changed files with 305 additions and 27 deletions
|
@ -13,6 +13,13 @@
|
|||
@interface DockIconController : NSObject {
|
||||
NSImage *dockImage;
|
||||
|
||||
NSInteger lastDockCustom;
|
||||
NSInteger lastDockCustomPlaque;
|
||||
NSInteger dockCustomLoaded;
|
||||
NSImage *dockCustomStop;
|
||||
NSImage *dockCustomPlay;
|
||||
NSImage *dockCustomPause;
|
||||
|
||||
IBOutlet PlaybackController *playbackController;
|
||||
|
||||
NSInteger lastPlaybackStatus;
|
||||
|
|
|
@ -14,16 +14,24 @@
|
|||
|
||||
static NSString *DockIconPlaybackStatusObservationContext = @"DockIconPlaybackStatusObservationContext";
|
||||
|
||||
static NSString *CogCustomDockIconsReloadNotification = @"CogCustomDockIconsReloadNotification";
|
||||
|
||||
- (void)startObserving {
|
||||
[playbackController addObserver:self forKeyPath:@"playbackStatus" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[playbackController addObserver:self forKeyPath:@"progressOverall" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionOld) context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.colorfulDockIcons" options:0 context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.customDockIcons" options:0 context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.customDockIconsPlaque" options:0 context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshDockIcons:) name:CogCustomDockIconsReloadNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)stopObserving {
|
||||
[playbackController removeObserver:self forKeyPath:@"playbackStatus" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[playbackController removeObserver:self forKeyPath:@"progressOverall" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.colorfulDockIcons" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.customDockIcons" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.customDockIconsPlaque" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:CogCustomDockIconsReloadNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)startObservingProgress:(NSProgress *)progress {
|
||||
|
@ -42,6 +50,34 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons) {
|
|||
}
|
||||
}
|
||||
|
||||
static NSString *getCustomIconName(NSString *baseName) {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
NSString *basePath = [[paths firstObject] stringByAppendingPathComponent:@"Cog"];
|
||||
basePath = [basePath stringByAppendingPathComponent:@"Icons"];
|
||||
basePath = [basePath stringByAppendingPathComponent:baseName];
|
||||
return [basePath stringByAppendingPathExtension:@"png"];
|
||||
}
|
||||
|
||||
- (BOOL)loadCustomDockIcons {
|
||||
NSError *error = nil;
|
||||
NSData *dataStopIcon = [NSData dataWithContentsOfFile:getCustomIconName(@"Stop") options:(NSDataReadingMappedIfSafe) error:&error];
|
||||
if(!dataStopIcon || error) {
|
||||
return NO;
|
||||
}
|
||||
NSData *dataPlayIcon = [NSData dataWithContentsOfFile:getCustomIconName(@"Play") options:(NSDataReadingMappedIfSafe) error:&error];
|
||||
if(!dataPlayIcon || error) {
|
||||
return NO;
|
||||
}
|
||||
NSData *dataPauseIcon = [NSData dataWithContentsOfFile:getCustomIconName(@"Pause") options:(NSDataReadingMappedIfSafe) error:&error];
|
||||
if(!dataPauseIcon || error) {
|
||||
return NO;
|
||||
}
|
||||
dockCustomStop = [[NSImage alloc] initWithData:dataStopIcon];
|
||||
dockCustomPlay = [[NSImage alloc] initWithData:dataPlayIcon];
|
||||
dockCustomPause = [[NSImage alloc] initWithData:dataPauseIcon];
|
||||
return (dockCustomStop && dockCustomPlay && dockCustomPause);
|
||||
}
|
||||
|
||||
- (void)refreshDockIcon:(NSInteger)playbackStatus withProgress:(double)progressStatus {
|
||||
// Really weird crash user experienced because the plaque image didn't load?
|
||||
if(!dockImage || dockImage.size.width == 0 || dockImage.size.height == 0) return;
|
||||
|
@ -50,6 +86,30 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons) {
|
|||
BOOL drawIcon = NO;
|
||||
BOOL removeProgress = NO;
|
||||
|
||||
BOOL useCustomDockIcons = [[NSUserDefaults standardUserDefaults] boolForKey:@"customDockIcons"];
|
||||
BOOL useCustomDockIconsPlaque = [[NSUserDefaults standardUserDefaults] boolForKey:@"customDockIconsPlaque"];
|
||||
|
||||
if(useCustomDockIcons && !dockCustomLoaded) {
|
||||
dockCustomLoaded = [self loadCustomDockIcons];
|
||||
if(!dockCustomLoaded) {
|
||||
useCustomDockIcons = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if(useCustomDockIcons != lastDockCustom ||
|
||||
useCustomDockIconsPlaque != lastDockCustomPlaque) {
|
||||
lastDockCustom = useCustomDockIcons;
|
||||
lastDockCustomPlaque = useCustomDockIconsPlaque;
|
||||
drawIcon = YES;
|
||||
|
||||
if(!useCustomDockIcons) {
|
||||
dockCustomLoaded = NO;
|
||||
dockCustomStop = nil;
|
||||
dockCustomPlay = nil;
|
||||
dockCustomPause = nil;
|
||||
}
|
||||
}
|
||||
|
||||
if(playbackStatus < 0)
|
||||
playbackStatus = lastPlaybackStatus;
|
||||
else {
|
||||
|
@ -82,20 +142,20 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons) {
|
|||
if(drawIcon) {
|
||||
switch(playbackStatus) {
|
||||
case CogStatusPlaying:
|
||||
badgeImage = [NSImage imageNamed:getBadgeName(@"Play", colorfulIcons)];
|
||||
badgeImage = useCustomDockIcons ? dockCustomPlay : [NSImage imageNamed:getBadgeName(@"Play", colorfulIcons)];
|
||||
break;
|
||||
case CogStatusPaused:
|
||||
badgeImage = [NSImage imageNamed:getBadgeName(@"Pause", colorfulIcons)];
|
||||
badgeImage = useCustomDockIcons ? dockCustomPause : [NSImage imageNamed:getBadgeName(@"Pause", colorfulIcons)];
|
||||
break;
|
||||
|
||||
default:
|
||||
badgeImage = [NSImage imageNamed:getBadgeName(@"Stop", colorfulIcons)];
|
||||
badgeImage = useCustomDockIcons ? dockCustomStop : [NSImage imageNamed:getBadgeName(@"Stop", colorfulIcons)];
|
||||
break;
|
||||
}
|
||||
|
||||
NSSize badgeSize = [badgeImage size];
|
||||
|
||||
NSImage *newDockImage = [dockImage copy];
|
||||
NSImage *newDockImage = (useCustomDockIcons && !useCustomDockIconsPlaque) ? [[NSImage alloc] initWithSize:NSMakeSize(1024, 1024)] : [dockImage copy];
|
||||
[newDockImage lockFocus];
|
||||
|
||||
[badgeImage drawInRect:NSMakeRect(0, 0, 1024, 1024)
|
||||
|
@ -186,7 +246,9 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons) {
|
|||
}
|
||||
|
||||
[self refreshDockIcon:-1 withProgress:progressStatus];
|
||||
} else if([keyPath isEqualToString:@"values.colorfulDockIcons"]) {
|
||||
} else if([keyPath isEqualToString:@"values.colorfulDockIcons"] ||
|
||||
[keyPath isEqualToString:@"values.customDockIcons"] ||
|
||||
[keyPath isEqualToString:@"values.customDockIconsPlaque"]) {
|
||||
[self refreshDockIcon:-1 withProgress:-10];
|
||||
} else if([keyPath isEqualToString:@"fractionCompleted"]) {
|
||||
double progressStatus = [(NSProgress *)object fractionCompleted];
|
||||
|
@ -197,6 +259,12 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons) {
|
|||
}
|
||||
}
|
||||
|
||||
- (void)refreshDockIcons:(NSNotification *)notification {
|
||||
lastDockCustom = NO;
|
||||
dockCustomLoaded = NO;
|
||||
[self refreshDockIcon:-1 withProgress:-10];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
dockImage = [[NSImage imageNamed:@"Plaque"] copy];
|
||||
lastColorfulStatus = -1;
|
||||
|
|
19
Preferences/Preferences/AppearancePane.h
Normal file
19
Preferences/Preferences/AppearancePane.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// AppearancePane.h
|
||||
// General
|
||||
//
|
||||
// Created by Christopher Snowhill on 11/24/24.
|
||||
//
|
||||
//
|
||||
|
||||
#import "GeneralPreferencePane.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface AppearancePane : GeneralPreferencePane {
|
||||
}
|
||||
|
||||
- (IBAction)setDockIconStop:(id)sender;
|
||||
- (IBAction)setDockIconPlay:(id)sender;
|
||||
- (IBAction)setDockIconPause:(id)sender;
|
||||
|
||||
@end
|
90
Preferences/Preferences/AppearancePane.m
Normal file
90
Preferences/Preferences/AppearancePane.m
Normal file
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// AppearancePane.m
|
||||
// General
|
||||
//
|
||||
// Created by Christopher Snowhill on 11/24/24.
|
||||
//
|
||||
//
|
||||
|
||||
#import "AppearancePane.h"
|
||||
|
||||
static NSString *CogCustomDockIconsReloadNotification = @"CogCustomDockIconsReloadNotification";
|
||||
|
||||
@implementation AppearancePane
|
||||
|
||||
- (NSString *)title {
|
||||
return NSLocalizedPrefString(@"Appearance");
|
||||
}
|
||||
|
||||
- (NSImage *)icon {
|
||||
if(@available(macOS 11.0, *))
|
||||
return [NSImage imageWithSystemSymbolName:@"paintpalette.fill" accessibilityDescription:nil];
|
||||
return [[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:@"appearance"]];
|
||||
}
|
||||
|
||||
- (void)setDockIcon:(NSString *)baseName {
|
||||
NSArray *fileTypes = @[@"jpg", @"jpeg", @"png", @"gif", @"webp", @"avif", @"heic"];
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setCanChooseDirectories:NO];
|
||||
[panel setCanChooseFiles:YES];
|
||||
[panel setFloatingPanel:YES];
|
||||
[panel setAllowedFileTypes:fileTypes];
|
||||
NSInteger result = [panel runModal];
|
||||
if(result == NSModalResponseOK) {
|
||||
NSError *error = nil;
|
||||
NSData *iconData = [NSData dataWithContentsOfURL:[panel URL] options:NSDataReadingMappedIfSafe error:&error];
|
||||
if(iconData && !error) {
|
||||
NSImage *icon = [[NSImage alloc] initWithData:iconData];
|
||||
if(icon) {
|
||||
CGImageRef cgRef = [icon CGImageForProposedRect:NULL
|
||||
context:nil
|
||||
hints:nil];
|
||||
|
||||
if(cgRef) {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
NSString *basePath = [[paths firstObject] stringByAppendingPathComponent:@"Cog"];
|
||||
basePath = [basePath stringByAppendingPathComponent:@"Icons"];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
BOOL isDirectory = NO;
|
||||
if(![fileManager fileExistsAtPath:basePath isDirectory:&isDirectory] || !isDirectory) {
|
||||
if(!isDirectory) {
|
||||
[fileManager removeItemAtPath:basePath error:&error];
|
||||
}
|
||||
[fileManager createDirectoryAtURL:[NSURL fileURLWithPath:basePath] withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
}
|
||||
|
||||
NSString *filePath = [basePath stringByAppendingPathComponent:baseName];
|
||||
filePath = [filePath stringByAppendingPathExtension:@"png"];
|
||||
|
||||
NSBitmapImageRep *newRep =
|
||||
[[NSBitmapImageRep alloc] initWithCGImage:cgRef];
|
||||
NSData *pngData = [newRep
|
||||
representationUsingType:NSBitmapImageFileTypePNG
|
||||
properties:@{}];
|
||||
[pngData writeToURL:[NSURL fileURLWithPath:filePath] atomically:YES];
|
||||
|
||||
// Now to refresh the icons by a little trickery, if enabled
|
||||
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"customDockIcons"];
|
||||
if(enabled) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:CogCustomDockIconsReloadNotification object:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)setDockIconStop:(id)sender {
|
||||
[self setDockIcon:@"Stop"];
|
||||
}
|
||||
|
||||
- (IBAction)setDockIconPlay:(id)sender {
|
||||
[self setDockIcon:@"Play"];
|
||||
}
|
||||
|
||||
- (IBAction)setDockIconPause:(id)sender {
|
||||
[self setDockIcon:@"Pause"];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,14 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="GeneralPreferencesPlugin">
|
||||
<connections>
|
||||
<outlet property="appearanceView" destination="CgN-sy-RmM" id="wvB-aW-Gfx"/>
|
||||
<outlet property="appearancePane" destination="gKy-O9-bcf" id="Kdj-LI-JmX"/>
|
||||
<outlet property="generalPane" destination="tm7-TU-wbV" id="jTO-w4-xwD"/>
|
||||
<outlet property="hotKeyPane" destination="6" id="14"/>
|
||||
<outlet property="iTunesStyleCheck" destination="AIz-WH-Wqk" id="2n1-pY-cZR"/>
|
||||
|
@ -59,7 +59,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" inset="2" selectedItem="250" id="248">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" title="OtherViews" id="249">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="250"/>
|
||||
|
@ -102,7 +102,7 @@
|
|||
<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"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" title="OtherViews" id="255">
|
||||
<items>
|
||||
<menuItem title="Item 1" id="256"/>
|
||||
|
@ -132,6 +132,11 @@
|
|||
</subviews>
|
||||
<point key="canvasLocation" x="-151" y="-283.5"/>
|
||||
</customView>
|
||||
<customObject id="gKy-O9-bcf" userLabel="AppearancePane" customClass="AppearancePane">
|
||||
<connections>
|
||||
<outlet property="view" destination="CgN-sy-RmM" id="eEi-cI-GKg"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="6" userLabel="HotKeyPane" customClass="HotKeyPane">
|
||||
<connections>
|
||||
<outlet property="fadeShortcutView" destination="vEd-Af-7tR" id="DMK-Z9-Sm5"/>
|
||||
|
@ -312,7 +317,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="menu"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" title="OtherViews" id="61">
|
||||
<items>
|
||||
<menuItem title="Item1" state="on" id="62"/>
|
||||
|
@ -342,7 +347,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="menu"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" title="OtherViews" id="V8o-Xy-HUW">
|
||||
<items>
|
||||
<menuItem title="Item 1" id="oWh-lD-mFH"/>
|
||||
|
@ -587,11 +592,11 @@
|
|||
<point key="canvasLocation" x="450" y="-52.5"/>
|
||||
</customView>
|
||||
<customView id="CgN-sy-RmM" userLabel="AppearanceView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="640" height="193"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="640" height="245"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="haX-dq-OIe">
|
||||
<rect key="frame" x="18" y="156" width="602" height="18"/>
|
||||
<rect key="frame" x="18" y="208" width="602" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Colorful dock icons" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="GdX-5e-NeU">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -601,6 +606,28 @@
|
|||
<binding destination="52" name="value" keyPath="values.colorfulDockIcons" id="NZt-v6-8iW"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zv5-2j-Aoj" userLabel="Use custom dock icon set:">
|
||||
<rect key="frame" x="18" y="182" width="477" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Use custom dock icon set:" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="RwB-Tk-ufd">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="52" name="value" keyPath="values.customDockIcons" id="Eps-hb-AfK"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AjL-Ho-0mM">
|
||||
<rect key="frame" x="40" y="158" width="580" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Render over background plaque" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="KZd-iR-dXL">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="52" name="value" keyPath="values.customDockIconsPlaque" id="PQe-kt-nXW"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AA7-fr-NOk">
|
||||
<rect key="frame" x="18" y="130" width="602" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
|
@ -677,6 +704,39 @@
|
|||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5fh-1K-0GQ" userLabel="Stopped">
|
||||
<rect key="frame" x="496" y="174" width="45" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="⏹️" alternateTitle="Stopped" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QYJ-kq-zao">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="setDockIconStop:" target="gKy-O9-bcf" id="C7I-ab-aYn"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="paU-SV-utl" userLabel="Playing">
|
||||
<rect key="frame" x="539" y="174" width="45" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="▶️" alternateTitle="Playing" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Z7K-Px-LDn">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="setDockIconPlay:" target="gKy-O9-bcf" id="EgK-ze-Ymi"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NpP-Uh-srl" userLabel="Paused">
|
||||
<rect key="frame" x="582" y="174" width="45" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="⏸️" alternateTitle="Paused" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="yJA-mn-Xjt">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="setDockIconPause:" target="gKy-O9-bcf" id="Pol-yc-d36"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="450" y="198.5"/>
|
||||
</customView>
|
||||
|
@ -735,7 +795,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="menu"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" id="pRc-b6-sMR">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="vaQ-pZ-jXy"/>
|
||||
|
@ -765,7 +825,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="menu"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" title="OtherViews" id="HKM-FW-dhH">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="3Gx-cs-3B0"/>
|
||||
|
@ -795,7 +855,7 @@
|
|||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" 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="menu"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" autoenablesItems="NO" id="q1g-E5-NwQ">
|
||||
<items>
|
||||
<menuItem title="Item 1" id="XzK-h2-vIT"/>
|
||||
|
|
|
@ -14,17 +14,18 @@
|
|||
#import "HotKeyPane.h"
|
||||
#import "MIDIPane.h"
|
||||
#import "OutputPane.h"
|
||||
#import "AppearancePane.h"
|
||||
|
||||
@interface GeneralPreferencesPlugin : NSObject <PreferencePanePlugin> {
|
||||
IBOutlet HotKeyPane *hotKeyPane;
|
||||
IBOutlet OutputPane *outputPane;
|
||||
IBOutlet MIDIPane *midiPane;
|
||||
IBOutlet GeneralPane *generalPane;
|
||||
IBOutlet AppearancePane *appearancePane;
|
||||
|
||||
IBOutlet NSView *playlistView;
|
||||
IBOutlet NSView *updatesView;
|
||||
IBOutlet NSView *notificationsView;
|
||||
IBOutlet NSView *appearanceView;
|
||||
|
||||
__weak IBOutlet NSButton *iTunesStyleCheck;
|
||||
}
|
||||
|
|
|
@ -90,10 +90,7 @@
|
|||
}
|
||||
|
||||
- (GeneralPreferencePane *)appearancePane {
|
||||
return [GeneralPreferencePane preferencePaneWithView:appearanceView
|
||||
title:NSLocalizedPrefString(@"Appearance")
|
||||
systemIconName:@"paintpalette.fill"
|
||||
orOldIconNamed:@"appearance"];
|
||||
return appearancePane;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
833A899F286FF3850022E036 /* TimeIntervalToStringTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 833A899E286FF3850022E036 /* TimeIntervalToStringTransformer.m */; };
|
||||
83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */; };
|
||||
8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */; };
|
||||
83726F022CF41B3200F15FBF /* AppearancePane.m in Sources */ = {isa = PBXBuildFile; fileRef = 83726F012CF41B3200F15FBF /* AppearancePane.m */; };
|
||||
837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */; };
|
||||
8384917718084D9F00E7332D /* appearance.png in Resources */ = {isa = PBXBuildFile; fileRef = 8384917518084D9F00E7332D /* appearance.png */; };
|
||||
8391EA06286F9D3200A37593 /* PathSuggester.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83DAD9F0286EDBCD000FAA9A /* PathSuggester.xib */; };
|
||||
|
@ -119,6 +120,8 @@
|
|||
83651DA427322C8700A2C097 /* MIDIFlavorBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIFlavorBehaviorArrayController.h; sourceTree = "<group>"; };
|
||||
8372053518E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResamplerBehaviorArrayController.h; sourceTree = "<group>"; };
|
||||
8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResamplerBehaviorArrayController.m; sourceTree = "<group>"; };
|
||||
83726F002CF41B3200F15FBF /* AppearancePane.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppearancePane.h; sourceTree = "<group>"; };
|
||||
83726F012CF41B3200F15FBF /* AppearancePane.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppearancePane.m; sourceTree = "<group>"; };
|
||||
837C0D3E1C50954000CAE18F /* MIDIPluginBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIPluginBehaviorArrayController.h; sourceTree = "<group>"; };
|
||||
837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIPluginBehaviorArrayController.m; sourceTree = "<group>"; };
|
||||
8384913618081ECB00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
||||
|
@ -258,6 +261,8 @@
|
|||
17D5033F0ABDB1570022D1E8 /* Panes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83726F002CF41B3200F15FBF /* AppearancePane.h */,
|
||||
83726F012CF41B3200F15FBF /* AppearancePane.m */,
|
||||
8E07AA820AAC8EA200A4B32F /* GeneralPreferencePane.h */,
|
||||
8E07AA830AAC8EA200A4B32F /* GeneralPreferencePane.m */,
|
||||
8E07AA800AAC8EA200A4B32F /* HotKeyPane.h */,
|
||||
|
@ -494,6 +499,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
83AC573A2861A54D009D6F50 /* PathSuggester.m in Sources */,
|
||||
83726F022CF41B3200F15FBF /* AppearancePane.m in Sources */,
|
||||
83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */,
|
||||
83B06729180D85B8008E3612 /* MIDIPane.m in Sources */,
|
||||
8E07AA880AAC8EA200A4B32F /* HotKeyPane.m in Sources */,
|
||||
|
|
|
@ -244,3 +244,9 @@
|
|||
|
||||
/* Class = "NSButtonCell"; title = "Reduce DSD volume level by 6 dB"; ObjectID = "Phw-hj-6tI"; */
|
||||
"Phw-hj-6tI.title" = "Reduce DSD volume level by 6 dB";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Use custom dock icon set:"; ObjectID = "RwB-Tk-ufd"; */
|
||||
"RwB-Tk-ufd.title" = "Use custom dock icon set:";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Render over background plaque"; ObjectID = "KZd-iR-dXL"; */
|
||||
"KZd-iR-dXL.title" = "Render over background plaque";
|
||||
|
|
|
@ -243,3 +243,9 @@
|
|||
|
||||
/* Class = "NSButtonCell"; title = "Reduce DSD volume level by 6 dB"; ObjectID = "Phw-hj-6tI"; */
|
||||
"Phw-hj-6tI.title" = "Reducir volumen de DSD en 6 dB";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Use custom dock icon set:"; ObjectID = "RwB-Tk-ufd"; */
|
||||
"RwB-Tk-ufd.title" = "Usar conjunto de iconos del dock personalizados:";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Render over background plaque"; ObjectID = "KZd-iR-dXL"; */
|
||||
"KZd-iR-dXL.title" = "Mostrar fondo del icono";
|
||||
|
|
|
@ -109,3 +109,9 @@
|
|||
|
||||
/* Class = "NSButtonCell"; title = "Reduce DSD volume level by 6 dB"; ObjectID = "Phw-hj-6tI"; */
|
||||
"Phw-hj-6tI.title" = "Reduce DSD volume level by 6 dB";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Use custom dock icon set:"; ObjectID = "RwB-Tk-ufd"; */
|
||||
"RwB-Tk-ufd.title" = "własny zestaw ikon:";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Render over background plaque"; ObjectID = "KZd-iR-dXL"; */
|
||||
"KZd-iR-dXL.title" = "tarcza za ikoną";
|
||||
|
|
|
@ -205,3 +205,9 @@
|
|||
|
||||
/* Class = "NSButtonCell"; title = "Reduce DSD volume level by 6 dB"; ObjectID = "Phw-hj-6tI"; */
|
||||
"Phw-hj-6tI.title" = "Reduce DSD volume level by 6 dB";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Use custom dock icon set:"; ObjectID = "RwB-Tk-ufd"; */
|
||||
"RwB-Tk-ufd.title" = "Используйте свой собственный набор икон:";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Render over background plaque"; ObjectID = "KZd-iR-dXL"; */
|
||||
"KZd-iR-dXL.title" = "Отображать икону над щитом";
|
||||
|
|
|
@ -244,3 +244,9 @@
|
|||
|
||||
/* Class = "NSButtonCell"; title = "Reduce DSD volume level by 6 dB"; ObjectID = "Phw-hj-6tI"; */
|
||||
"Phw-hj-6tI.title" = "Reduce DSD volume level by 6 dB";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Use custom dock icon set:"; ObjectID = "RwB-Tk-ufd"; */
|
||||
"RwB-Tk-ufd.title" = "Sahip olduğunuz kendi ikon setini kullanın:";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Render over background plaque"; ObjectID = "KZd-iR-dXL"; */
|
||||
"KZd-iR-dXL.title" = "İkonun şaltırın üzerinde gösterilmesi";
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div>
|
||||
Now with 92% more future!<br><br> Thanks to my patrons:
|
||||
<br> Alexander Pecheny, Electric Keet, Antti Aro, Fjölnir Ásgeirsson, Giampaolo Bellavite, Louis Martinez V, deef.xyz
|
||||
<br><br> Additional code contributions by <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a> and <a href="https://kddlb.com">Kevin López Brante</a>.
|
||||
<br><br> Additional code contributions by <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a>, <a href="https://kddlb.com">Kevin López Brante</a> and mpan.
|
||||
<br><br>
|
||||
<em>This program has been made possible through contributions from users like you.</em>
|
||||
<br><br> All Cog code is copyrighted by me, and is licensed under the <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GPL</a>. Cog contains bits of other code from third parties that are under their own licenses.
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div>
|
||||
¡Ahora con 92% más de futuro!<br><br> Gracias a mis patrocinadores:
|
||||
<br> Alexander Pecheny, Electric Keet, Antti Aro, Fjölnir Ásgeirsson, Giampaolo Bellavite, Louis Martinez V, deef.xyz
|
||||
<br><br> Desarrollo adicional por <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a> and <a href="https://kddlb.com">Kevin López Brante</a>.
|
||||
<br><br> Desarrollo adicional por <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a>, <a href="https://kddlb.com">Kevin López Brante</a> y mpan.
|
||||
<br>Traducido al español por Kevin López Brante.
|
||||
<br><br>
|
||||
<em>Este programa ha sido posible gracias a las contribuciones de usuarios y usuarias como tú.</em>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div>
|
||||
Now with 92% more future!<br><br> Thanks to my patrons:
|
||||
<br> Alexander Pecheny, Electric Keet, Antti Aro, Fjölnir Ásgeirsson, Giampaolo Bellavite, Louis Martinez V, deef.xyz
|
||||
<br><br> Additional code contributions by <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a> and <a href="https://kddlb.com">Kevin López Brante</a>.
|
||||
<br><br> Additional code contributions by <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a>, <a href="https://kddlb.com">Kevin López Brante</a> and mpan.
|
||||
<br><br>
|
||||
<em>This program has been made possible through contributions from users like you.</em>
|
||||
<br><br> All Cog code is copyrighted by me, and is licensed under the <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GPL</a>. Cog contains bits of other code from third parties that are under their own licenses.
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div>
|
||||
Теперь на 92% больше функий!<br><br> Спасибо моим патронам:
|
||||
<br> Alexander Pecheny, Electric Keet, Antti Aro, Fjölnir Ásgeirsson, Giampaolo Bellavite, Louis Martinez V, deef.xyz
|
||||
<br><br> Дополнительный вклад в разработку от <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a> и <a href="https://kddlb.com">Kevin López Brante</a>.
|
||||
<br><br> Дополнительный вклад в разработку от <a href="https://twitter.com/nevack_d">Dzmitry Neviadomski</a>, <a href="https://kddlb.com">Kevin López Brante</a> и mpan.
|
||||
<br><br>
|
||||
<em>Создние этой программы стало возможным благодаря вкладу таких пользователей, как вы.</em>
|
||||
<br><br> Весь код Cog защищен моим авторским правом и распространяется под лицензией <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GPL</a>. Cog содержит фрагменты другого кода от третьих сторон, который находятся под их собственными лицензиями.
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div>
|
||||
Now with 92% more future!<br><br> Thanks to my patrons:
|
||||
<br> Alexander Pecheny, Electric Keet, Antti Aro, Fjölnir Ásgeirsson, Giampaolo Bellavite, Louis Martinez V, deef.xyz
|
||||
<br><br> Additional code contributions by <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a> and <a href="https://kddlb.com">Kevin López Brante</a>.
|
||||
<br><br> Additional code contributions by <a href="https://twitter.com/nevack_d"> Dzmitry Neviadomski</a>, <a href="https://kddlb.com">Kevin López Brante</a> and mpan.
|
||||
<br><br>
|
||||
<em>This program has been made possible through contributions from users like you.</em>
|
||||
<br><br> All Cog code is copyrighted by me, and is licensed under the <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GPL</a>. Cog contains bits of other code from third parties that are under their own licenses.
|
||||
|
|
Loading…
Reference in a new issue