From b056b9035d34a3915bc718eec7678d11a2d45be6 Mon Sep 17 00:00:00 2001 From: Jonathan Bailey Date: Thu, 29 Jan 2015 06:14:02 +0000 Subject: [PATCH 1/3] Add brightness slider (and fix label not showing if not set) --- LIFX Menu.xcodeproj/project.pbxproj | 27 ++++++++++++------- LIFX Menu/AppDelegate.m | 26 ++++++++++++++++--- LIFX Menu/LXMSliderMenuItem.h | 14 ++++++++++ LIFX Menu/LXMSliderMenuItem.m | 40 +++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 LIFX Menu/LXMSliderMenuItem.h create mode 100644 LIFX Menu/LXMSliderMenuItem.m diff --git a/LIFX Menu.xcodeproj/project.pbxproj b/LIFX Menu.xcodeproj/project.pbxproj index 7a5aa67..a8e2bf6 100644 --- a/LIFX Menu.xcodeproj/project.pbxproj +++ b/LIFX Menu.xcodeproj/project.pbxproj @@ -7,8 +7,9 @@ objects = { /* Begin PBXBuildFile section */ - C721034519E6BA380085E99B /* LIFXKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C721974619E622B200FCA5CB /* LIFXKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C721034619E6BBC30085E99B /* LIFXKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C721974619E622B200FCA5CB /* LIFXKit.framework */; }; + AB0FC2B81A79F1A700D90728 /* LIFXKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C721974619E622B200FCA5CB /* LIFXKit.framework */; }; + AB0FC2BA1A79F1BF00D90728 /* LIFXKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C721974619E622B200FCA5CB /* LIFXKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + AB0FC2BE1A79FDC000D90728 /* LXMSliderMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AB0FC2BD1A79FDC000D90728 /* LXMSliderMenuItem.m */; }; C721970919E5F79600FCA5CB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C721970819E5F79600FCA5CB /* main.m */; }; C721970C19E5F79600FCA5CB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C721970B19E5F79600FCA5CB /* AppDelegate.m */; }; C721970E19E5F79600FCA5CB /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C721970D19E5F79600FCA5CB /* Images.xcassets */; }; @@ -32,19 +33,22 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - C721974919E622E700FCA5CB /* CopyFiles */ = { + AB0FC2BB1A79F1BF00D90728 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - C721034519E6BA380085E99B /* LIFXKit.framework in CopyFiles */, + AB0FC2BA1A79F1BF00D90728 /* LIFXKit.framework in Embed Frameworks */, ); + name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + AB0FC2BC1A79FDC000D90728 /* LXMSliderMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXMSliderMenuItem.h; sourceTree = ""; }; + AB0FC2BD1A79FDC000D90728 /* LXMSliderMenuItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXMSliderMenuItem.m; sourceTree = ""; }; C721970319E5F79600FCA5CB /* LIFX Menu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "LIFX Menu.app"; sourceTree = BUILT_PRODUCTS_DIR; }; C721970719E5F79600FCA5CB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C721970819E5F79600FCA5CB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -72,7 +76,7 @@ files = ( C721975419E631FD00FCA5CB /* SystemConfiguration.framework in Frameworks */, C721973719E5FA1200FCA5CB /* libz.dylib in Frameworks */, - C721034619E6BBC30085E99B /* LIFXKit.framework in Frameworks */, + AB0FC2B81A79F1A700D90728 /* LIFXKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -109,6 +113,8 @@ children = ( C721970A19E5F79600FCA5CB /* AppDelegate.h */, C721970B19E5F79600FCA5CB /* AppDelegate.m */, + AB0FC2BC1A79FDC000D90728 /* LXMSliderMenuItem.h */, + AB0FC2BD1A79FDC000D90728 /* LXMSliderMenuItem.m */, C721974E19E6292A00FCA5CB /* Launch at login */, C721970D19E5F79600FCA5CB /* Images.xcassets */, C721970F19E5F79700FCA5CB /* MainMenu.xib */, @@ -176,7 +182,7 @@ C72196FF19E5F79600FCA5CB /* Sources */, C721970019E5F79600FCA5CB /* Frameworks */, C721970119E5F79600FCA5CB /* Resources */, - C721974919E622E700FCA5CB /* CopyFiles */, + AB0FC2BB1A79F1BF00D90728 /* Embed Frameworks */, ); buildRules = ( ); @@ -216,7 +222,7 @@ TargetAttributes = { C721970219E5F79600FCA5CB = { CreatedOnToolsVersion = 6.0; - DevelopmentTeam = NFTL2336WY; + DevelopmentTeam = T7QSHJ836T; }; C721971519E5F79700FCA5CB = { CreatedOnToolsVersion = 6.0; @@ -271,6 +277,7 @@ files = ( C721975319E631D400FCA5CB /* LaunchAtLoginController.m in Sources */, C721970C19E5F79600FCA5CB /* AppDelegate.m in Sources */, + AB0FC2BE1A79FDC000D90728 /* LXMSliderMenuItem.m in Sources */, C721970919E5F79600FCA5CB /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -385,13 +392,14 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", "$(PROJECT_DIR)/LIFX", Menu, + "$(PROJECT_DIR)/LIFX", + Menu, ); INFOPLIST_FILE = "LIFX Menu/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; @@ -404,13 +412,14 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", "$(PROJECT_DIR)/LIFX", Menu, + "$(PROJECT_DIR)/LIFX", + Menu, ); INFOPLIST_FILE = "LIFX Menu/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; diff --git a/LIFX Menu/AppDelegate.m b/LIFX Menu/AppDelegate.m index 4e86963..63aaba6 100644 --- a/LIFX Menu/AppDelegate.m +++ b/LIFX Menu/AppDelegate.m @@ -6,7 +6,7 @@ // Copyright (c) 2014 Kyle Howells. All rights reserved. // -#import +#import "LIFXKit.framework/Headers/LIFXKit.h" #import "AppDelegate.h" #import "LaunchAtLoginController.h" @@ -102,7 +102,10 @@ -(void)toggleLight:(NSMenuItem*)item{ [light setPowerState:((light.powerState == LFXPowerStateOn) ? LFXPowerStateOff : LFXPowerStateOn)]; } - +-(void)changeBrightness:(LXMSliderMenuItem *)item{ + LFXLight *light = [item representedObject]; + [light setColor:[[light color] colorWithBrightness:[[item slider] floatValue]]]; +} @@ -119,6 +122,13 @@ -(void)addLight:(LFXLight*)light{ NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[self titleForLight:light] action:@selector(toggleLight:) keyEquivalent:@""]; [item setRepresentedObject:light]; + + LXMSliderMenuItem *sliderItem = [[LXMSliderMenuItem alloc] initWithTitle:@"Brightness" target:self action:@selector(changeBrightness:)]; + [sliderItem setRepresentedObject:light]; + + [item setSubmenu:[[NSMenu alloc] init]]; + [[item submenu] addItem:sliderItem]; + [self updateLightMenuItem:item]; [self.menu insertItem:item atIndex:(self.menu.numberOfItems - 2)]; @@ -158,8 +168,13 @@ -(void)updateLight:(LFXLight*)light{ -(void)updateLightMenuItem:(NSMenuItem*)item{ LFXLight *light = [item representedObject]; - [item setTitle:(light.label ?: light.deviceID)]; + [item setTitle:[self titleForLight:light]]; [item setState:((light.powerState == LFXPowerStateOn) ? NSOnState : NSOffState)]; + + LXMSliderMenuItem *sliderMenuItem = (LXMSliderMenuItem *)[[item submenu] itemWithTitle:@"Brightness"]; + [[sliderMenuItem slider] setMinValue:LFXHSBKColorMinBrightness]; + [[sliderMenuItem slider] setMaxValue:LFXHSBKColorMaxBrightness]; + [[sliderMenuItem slider] setFloatValue:light.color.brightness]; } @@ -189,6 +204,9 @@ -(void)light:(LFXLight *)light didChangeLabel:(NSString *)label{ -(void)light:(LFXLight *)light didChangePowerState:(LFXPowerState)powerState{ [self updateLight:light]; } +-(void)light:(LFXLight *)light didChangeColor:(LFXHSBKColor *)color { + [self updateLight:light]; +} @@ -212,7 +230,7 @@ -(NSMenuItem*)menuItemForLight:(LFXLight*)light{ return item; } -(NSString*)titleForLight:(LFXLight*)light{ - return (light.label ?: light.deviceID); + return ([light.label length] > 0 ? light.label : light.deviceID); } diff --git a/LIFX Menu/LXMSliderMenuItem.h b/LIFX Menu/LXMSliderMenuItem.h new file mode 100644 index 0000000..5c5a387 --- /dev/null +++ b/LIFX Menu/LXMSliderMenuItem.h @@ -0,0 +1,14 @@ +// +// LXMSliderMenuItem.h +// LIFX Menu +// +// Created by Jonathan on 29/01/2015. +// Copyright (c) 2015 Kyle Howells. All rights reserved. +// + +#import + +@interface LXMSliderMenuItem : NSMenuItem +-(instancetype)initWithTitle:(NSString *)title target:(id)target action:(SEL)aSelector; +@property (nonatomic, readonly) NSSlider *slider; +@end diff --git a/LIFX Menu/LXMSliderMenuItem.m b/LIFX Menu/LXMSliderMenuItem.m new file mode 100644 index 0000000..b1b71b5 --- /dev/null +++ b/LIFX Menu/LXMSliderMenuItem.m @@ -0,0 +1,40 @@ +// +// LXMSliderMenuItem.m +// LIFX Menu +// +// Created by Jonathan on 29/01/2015. +// Copyright (c) 2015 Kyle Howells. All rights reserved. +// + +#import "LXMSliderMenuItem.h" +@interface LXMSliderMenuItem () +@property (nonatomic, strong, readwrite) NSSlider *slider; +@end + +@implementation LXMSliderMenuItem +-(instancetype)initWithTitle:(NSString *)title target:(id)target action:(SEL)aSelector { + if (self = [super initWithTitle:title action:aSelector keyEquivalent:@""]) { + [self setTarget:target]; + + NSView *customView = [[NSView alloc] initWithFrame:NSMakeRect(10, 0, 150, 25)]; + NSSlider *slider = [[NSSlider alloc] init]; + [customView addSubview:slider]; + [customView setAutoresizingMask:NSViewWidthSizable]; + [slider setTranslatesAutoresizingMaskIntoConstraints:NO]; + [customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[slider]-10-|" options:0 metrics:nil views:@{@"slider" : slider}]]; + [customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[slider]|" options:0 metrics:nil views:@{@"slider" : slider}]]; + [slider setTarget:self]; + [slider setAction:@selector(sliderChanged:)]; + [self setSlider:slider]; + [self setView:customView]; + } + return self; +} + +-(void)sliderChanged:(NSSlider *)sender { + if ([self action] && [[self target] respondsToSelector:[self action]]) { + [[self target] performSelector:[self action] withObject:self]; + } +} + +@end From 4ac060388416d82b18a4a94d30acf53d2f600ab5 Mon Sep 17 00:00:00 2001 From: Jonathan Bailey Date: Thu, 29 Jan 2015 06:16:17 +0000 Subject: [PATCH 2/3] Header import was missed --- LIFX Menu/AppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LIFX Menu/AppDelegate.m b/LIFX Menu/AppDelegate.m index 63aaba6..394bf65 100644 --- a/LIFX Menu/AppDelegate.m +++ b/LIFX Menu/AppDelegate.m @@ -9,7 +9,7 @@ #import "LIFXKit.framework/Headers/LIFXKit.h" #import "AppDelegate.h" #import "LaunchAtLoginController.h" - +#import "LXMSliderMenuItem.h" @interface AppDelegate () @property (nonatomic, strong) NSStatusItem *statusItem; From 13c232ee309d7175df9e9d5722428d479feaec9a Mon Sep 17 00:00:00 2001 From: Jonathan Bailey Date: Thu, 29 Jan 2015 06:26:37 +0000 Subject: [PATCH 3/3] Add option to change label --- LIFX Menu/AppDelegate.m | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/LIFX Menu/AppDelegate.m b/LIFX Menu/AppDelegate.m index 394bf65..29f67d5 100644 --- a/LIFX Menu/AppDelegate.m +++ b/LIFX Menu/AppDelegate.m @@ -107,6 +107,22 @@ -(void)changeBrightness:(LXMSliderMenuItem *)item{ [light setColor:[[light color] colorWithBrightness:[[item slider] floatValue]]]; } +-(void)changeLabel:(NSMenuItem *)item{ + LFXLight *light = [item representedObject]; + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:@"Enter new name:"]; + [alert addButtonWithTitle:@"Ok"]; + [alert addButtonWithTitle:@"Cancel"]; + + NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)]; + [input setStringValue:[light label]]; + + [alert setAccessoryView:input]; + NSInteger button = [alert runModal]; + if (button == NSAlertFirstButtonReturn) { + [light setLabel:[input stringValue]]; + } +} @@ -126,8 +142,12 @@ -(void)addLight:(LFXLight*)light{ LXMSliderMenuItem *sliderItem = [[LXMSliderMenuItem alloc] initWithTitle:@"Brightness" target:self action:@selector(changeBrightness:)]; [sliderItem setRepresentedObject:light]; + NSMenuItem *labelItem = [[NSMenuItem alloc] initWithTitle:@"Set label..." action:@selector(changeLabel:) keyEquivalent:@""]; + [labelItem setRepresentedObject:light]; + [item setSubmenu:[[NSMenu alloc] init]]; [[item submenu] addItem:sliderItem]; + [[item submenu] addItem:labelItem]; [self updateLightMenuItem:item]; @@ -136,6 +156,7 @@ -(void)addLight:(LFXLight*)light{ [light addLightObserver:self]; } + /** * Removes the light from the menu and array. Also removes self as an observer for that light. */