Skip to content

Commit

Permalink
Dark mode support
Browse files Browse the repository at this point in the history
  • Loading branch information
tonsky committed Mar 3, 2015
1 parent a4fec23 commit 3fc1eb3
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 97 deletions.
96 changes: 56 additions & 40 deletions AnyBar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,29 @@
objects = {

/* Begin PBXBuildFile section */
7648BAB81AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAAD1AA5A3C0003DA28F /* [email protected] */; };
7648BAB91AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAAE1AA5A3C0003DA28F /* [email protected] */; };
7648BABA1AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAAF1AA5A3C0003DA28F /* [email protected] */; };
7648BABB1AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAB01AA5A3C0003DA28F /* [email protected] */; };
7648BABC1AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAB11AA5A3C0003DA28F /* [email protected] */; };
7648BABD1AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAB21AA5A3C0003DA28F /* [email protected] */; };
7648BABE1AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAB31AA5A3C0003DA28F /* [email protected] */; };
7648BABF1AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAB41AA5A3C0003DA28F /* [email protected] */; };
7648BAC11AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAB61AA5A3C0003DA28F /* [email protected] */; };
7648BAC21AA5A3C0003DA28F /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 7648BAB71AA5A3C0003DA28F /* [email protected] */; };
7648BAC31AA5A50B003DA28F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = C5AB32C41A8F9091002258B6 /* MainMenu.xib */; };
C5AB32BF1A8F9091002258B6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C5AB32BE1A8F9091002258B6 /* AppDelegate.m */; };
C5AB32C11A8F9091002258B6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C5AB32C01A8F9091002258B6 /* main.m */; };
C5AB32C31A8F9091002258B6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C5AB32C21A8F9091002258B6 /* Images.xcassets */; };
C5AB32E71A8F9B4E002258B6 /* GCDAsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = C5AB32E41A8F9B4E002258B6 /* GCDAsyncSocket.m */; };
C5AB32E81A8F9B4E002258B6 /* GCDAsyncUdpSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = C5AB32E61A8F9B4E002258B6 /* GCDAsyncUdpSocket.m */; };
C5E0271D1AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027101AA6435E0032F2E9 /* [email protected] */; };
C5E0271E1AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027111AA6435E0032F2E9 /* [email protected] */; };
C5E0271F1AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027121AA6435E0032F2E9 /* [email protected] */; };
C5E027201AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027131AA6435E0032F2E9 /* [email protected] */; };
C5E027211AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027141AA6435E0032F2E9 /* [email protected] */; };
C5E027221AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027151AA6435E0032F2E9 /* [email protected] */; };
C5E027231AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027161AA6435E0032F2E9 /* [email protected] */; };
C5E027241AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E027171AA6435E0032F2E9 /* [email protected] */; };
C5E027271AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E0271A1AA6435E0032F2E9 /* [email protected] */; };
C5E027281AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E0271B1AA6435E0032F2E9 /* [email protected] */; };
C5E027291AA6435E0032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E0271C1AA6435E0032F2E9 /* [email protected] */; };
C5E0272F1AA64BD90032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E0272C1AA64BD90032F2E9 /* [email protected] */; };
C5E027301AA64BD90032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E0272D1AA64BD90032F2E9 /* [email protected] */; };
C5E027311AA64BD90032F2E9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5E0272E1AA64BD90032F2E9 /* [email protected] */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
7648BAAD1AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAAE1AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAAF1AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAB01AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAB11AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAB21AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAB31AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAB41AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAB61AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
7648BAB71AA5A3C0003DA28F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C511DFFB1AA4E9CF00DEE15F /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
C5AB32B81A8F9091002258B6 /* AnyBar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnyBar.app; sourceTree = BUILT_PRODUCTS_DIR; };
C5AB32BC1A8F9091002258B6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand All @@ -48,6 +42,20 @@
C5AB32E41A8F9B4E002258B6 /* GCDAsyncSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDAsyncSocket.m; sourceTree = "<group>"; };
C5AB32E51A8F9B4E002258B6 /* GCDAsyncUdpSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDAsyncUdpSocket.h; sourceTree = "<group>"; };
C5AB32E61A8F9B4E002258B6 /* GCDAsyncUdpSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDAsyncUdpSocket.m; sourceTree = "<group>"; };
C5E027101AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E027111AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E027121AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E027131AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E027141AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E027151AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E027161AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E027171AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E0271A1AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E0271B1AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E0271C1AA6435E0032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E0272C1AA64BD90032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E0272D1AA64BD90032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
C5E0272E1AA64BD90032F2E9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -64,16 +72,20 @@
7648BAAC1AA5A3C0003DA28F /* Resources */ = {
isa = PBXGroup;
children = (
7648BAAD1AA5A3C0003DA28F /* [email protected] */,
7648BAAE1AA5A3C0003DA28F /* [email protected] */,
7648BAAF1AA5A3C0003DA28F /* [email protected] */,
7648BAB01AA5A3C0003DA28F /* [email protected] */,
7648BAB11AA5A3C0003DA28F /* [email protected] */,
7648BAB21AA5A3C0003DA28F /* [email protected] */,
7648BAB31AA5A3C0003DA28F /* [email protected] */,
7648BAB41AA5A3C0003DA28F /* [email protected] */,
7648BAB61AA5A3C0003DA28F /* [email protected] */,
7648BAB71AA5A3C0003DA28F /* [email protected] */,
C5E0272C1AA64BD90032F2E9 /* [email protected] */,
C5E0272D1AA64BD90032F2E9 /* [email protected] */,
C5E0272E1AA64BD90032F2E9 /* [email protected] */,
C5E027101AA6435E0032F2E9 /* [email protected] */,
C5E027111AA6435E0032F2E9 /* [email protected] */,
C5E027121AA6435E0032F2E9 /* [email protected] */,
C5E027131AA6435E0032F2E9 /* [email protected] */,
C5E027141AA6435E0032F2E9 /* [email protected] */,
C5E027151AA6435E0032F2E9 /* [email protected] */,
C5E027161AA6435E0032F2E9 /* [email protected] */,
C5E027171AA6435E0032F2E9 /* [email protected] */,
C5E0271A1AA6435E0032F2E9 /* [email protected] */,
C5E0271B1AA6435E0032F2E9 /* [email protected] */,
C5E0271C1AA6435E0032F2E9 /* [email protected] */,
);
path = Resources;
sourceTree = "<group>";
Expand Down Expand Up @@ -178,18 +190,22 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7648BABF1AA5A3C0003DA28F /* [email protected] in Resources */,
7648BAC21AA5A3C0003DA28F /* [email protected] in Resources */,
7648BABE1AA5A3C0003DA28F /* [email protected] in Resources */,
7648BAC11AA5A3C0003DA28F /* [email protected] in Resources */,
C5E027241AA6435E0032F2E9 /* [email protected] in Resources */,
C5E027231AA6435E0032F2E9 /* [email protected] in Resources */,
C5AB32C31A8F9091002258B6 /* Images.xcassets in Resources */,
7648BAB81AA5A3C0003DA28F /* [email protected] in Resources */,
7648BABC1AA5A3C0003DA28F /* [email protected] in Resources */,
7648BAB91AA5A3C0003DA28F /* [email protected] in Resources */,
7648BABB1AA5A3C0003DA28F /* [email protected] in Resources */,
7648BABA1AA5A3C0003DA28F /* [email protected] in Resources */,
7648BABD1AA5A3C0003DA28F /* [email protected] in Resources */,
C5E027291AA6435E0032F2E9 /* [email protected] in Resources */,
C5E027311AA64BD90032F2E9 /* [email protected] in Resources */,
C5E027301AA64BD90032F2E9 /* [email protected] in Resources */,
C5E027271AA6435E0032F2E9 /* [email protected] in Resources */,
C5E027281AA6435E0032F2E9 /* [email protected] in Resources */,
7648BAC31AA5A50B003DA28F /* MainMenu.xib in Resources */,
C5E027211AA6435E0032F2E9 /* [email protected] in Resources */,
C5E0272F1AA64BD90032F2E9 /* [email protected] in Resources */,
C5E0271E1AA6435E0032F2E9 /* [email protected] in Resources */,
C5E027201AA6435E0032F2E9 /* [email protected] in Resources */,
C5E0271F1AA6435E0032F2E9 /* [email protected] in Resources */,
C5E027221AA6435E0032F2E9 /* [email protected] in Resources */,
C5E0271D1AA6435E0032F2E9 /* [email protected] in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Binary file not shown.
122 changes: 70 additions & 52 deletions AnyBar/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,31 @@

#import "AppDelegate.h"

static NSString* const AppConfigDirectoryName = @".AnyBar";
static NSString* const PortEnvironmentName = @"ANYBAR_PORT";
static NSString* const DefaultPort = @"1738";
static NSString* const DefaultImageName = @"[email protected]";
static NSString* const AlternateImageName = @"[email protected]";
static const int UdpPortMin = 0;
static const int UdpPortMax = 65535;

@interface AppDelegate()

@property (weak, nonatomic) IBOutlet NSWindow *window;
@property (strong, nonatomic) NSStatusItem *statusItem;
@property (strong, nonatomic) GCDAsyncUdpSocket *udpSocket;
@property (assign, nonatomic) BOOL dark;
@property (strong, nonatomic) NSString *imageName;

@end

@implementation AppDelegate

-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSImage *defaultImage = [NSImage imageNamed:DefaultImageName];
NSImage *warnImage = [NSImage imageNamed:NSImageNameStatusUnavailable];
int port = -1;

_imageName = @"white";
self.statusItem = [self initializeStatusBarItem];
[self updateStatusImage: defaultImage];
[self refreshDarkMode];

@try {
port = [self getUdpPort];

_udpSocket = [self initializeUdpSocket: port];
}
@catch(NSException *ex) {
NSLog(@"Error: %@: %@", ex.name, ex.reason);

[self updateStatusImage:warnImage];
_statusItem.image = [NSImage imageNamed:@"[email protected]"];
}
@finally {
NSString *portTitle = [NSString stringWithFormat:@"UDP port: %@",
Expand All @@ -53,6 +43,13 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
quitTitle: [NSValue valueWithPointer:@selector(terminate:)]
}];
}

NSDistributedNotificationCenter *center = [NSDistributedNotificationCenter defaultCenter];
[center addObserver: self
selector: @selector(refreshDarkMode)
name: @"AppleInterfaceThemeChangedNotification"
object: nil];

}

-(void)applicationWillTerminate:(NSNotification *)aNotification {
Expand All @@ -64,9 +61,9 @@ -(void)applicationWillTerminate:(NSNotification *)aNotification {
}

-(int) getUdpPort {
int port = [self readIntFromEnvironmentVariable:PortEnvironmentName usingDefault:DefaultPort];
int port = [self readIntFromEnvironmentVariable:@"ANYBAR_PORT" usingDefault:@"1738"];

if (port < UdpPortMin || port > UdpPortMax) {
if (port < 0 || port > 65535) {
@throw([NSException exceptionWithName:@"Argument Exception"
reason:[NSString stringWithFormat:@"UDP Port range is invalid: %d", port]
userInfo:@{@"argument": [NSNumber numberWithInt:port]}]);
Expand All @@ -76,6 +73,15 @@ -(int) getUdpPort {
return port;
}

- (void)refreshDarkMode {
NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
if ([osxMode isEqualToString:@"Dark"])
self.dark = YES;
else
self.dark = NO;
[self setImage:_imageName];
}

-(GCDAsyncUdpSocket*)initializeUdpSocket:(int)port {
NSError *error = nil;
GCDAsyncUdpSocket *udpSocket = [[GCDAsyncUdpSocket alloc]
Expand Down Expand Up @@ -110,46 +116,62 @@ -(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
[self processUdpSocketMsg:sock withData:data fromAddress:address];
}

-(NSImage*)tryImage:(NSString *)path {
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path])
return [[NSImage alloc] initWithContentsOfFile:path];
else
return nil;
}

-(NSString*)bundledImagePath:(NSString *)name {
return [[NSBundle mainBundle] pathForResource:name ofType:@"png"];
}

-(NSString*)homedirImagePath:(NSString *)name {
return [NSString stringWithFormat:@"%@/%@/%@.png", NSHomeDirectory(), @".AnyBar", name];
}

-(void)setImage:(NSString*) name {

NSImage *image = nil;
if (_dark)
image = [self tryImage:[self bundledImagePath:[name stringByAppendingString:@"_alt@2x"]]];
if (!image)
image = [self tryImage:[self bundledImagePath:[name stringByAppendingString:@"@2x"]]];
if (_dark && !image)
image = [self tryImage:[self homedirImagePath:[name stringByAppendingString:@"_alt"]]];
if (_dark && !image)
image = [self tryImage:[self homedirImagePath:[name stringByAppendingString:@"_alt@2x"]]];
if (!image)
image = [self tryImage:[self homedirImagePath:[name stringByAppendingString:@"@2x"]]];
if (!image)
image = [self tryImage:[self homedirImagePath:name]];
if (!image) {
if (_dark)
image = [self tryImage:[self bundledImagePath:@"question_alt@2x"]];
else
image = [self tryImage:[self bundledImagePath:@"question@2x"]];
NSLog(@"Cannot find image '%@'", name);
}

_statusItem.image = image;
_imageName = name;
}

-(void)processUdpSocketMsg:(GCDAsyncUdpSocket *)sock withData:(NSData *)data
fromAddress:(NSData *)address {
NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

if ([msg isEqualToString:@"quit"]) {
if ([msg isEqualToString:@"quit"])
[[NSApplication sharedApplication] terminate:nil];
}
else {
NSImage *image = nil;
NSString *fileName = [msg stringByAppendingString:@"@2x"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *bundledFile = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:fileName, msg]
ofType:@"png"];

BOOL fileExists = [fileManager fileExistsAtPath:bundledFile];
if (fileExists) {
image = [[NSImage alloc] initWithContentsOfFile:bundledFile];
}
else {
// Let's lookup for the file in ~/.AnyBar
NSString *fallbackFile = [NSString stringWithFormat:@"%@/%@/%@.png",
NSHomeDirectory(), AppConfigDirectoryName, fileName];
fileExists = [fileManager fileExistsAtPath:fallbackFile];
if (fileExists) {
image = [[NSImage alloc] initWithContentsOfFile:fallbackFile];
}
}

if (fileExists && image != nil) {
[self updateStatusImage: image];
}
else {
NSLog(@"No image for the command %@ found", msg);
}
}
else
[self setImage:msg];
}

-(NSStatusItem*) initializeStatusBarItem {
NSStatusItem *statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
statusItem.alternateImage = [NSImage imageNamed:AlternateImageName];
statusItem.alternateImage = [NSImage imageNamed:@"[email protected]"];
statusItem.highlightMode = YES;
return statusItem;
}
Expand All @@ -166,10 +188,6 @@ -(NSMenu*) initializeStatusBarMenu:(NSDictionary*)menuDictionary {
return menu;
}

-(void) updateStatusImage:(NSImage*) image {
_statusItem.image = image;
}

-(int) readIntFromEnvironmentVariable:(NSString*) envVariable usingDefault:(NSString*) defStr {
int intVal = -1;

Expand Down
Loading

0 comments on commit 3fc1eb3

Please sign in to comment.