├── .gitignore ├── AXStatusItemPopup.podspec ├── AXStatusItemPopup ├── AXStatusItemPopup.h └── AXStatusItemPopup.m ├── Demo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── Demo ├── Code │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── ContentViewController.h │ ├── ContentViewController.m │ ├── ContentViewController.xib │ └── MainMenu.xib ├── Demo-Info.plist ├── Demo-Prefix.pch ├── Resources │ ├── cloud.png │ ├── cloud@2x.png │ ├── cloudgrey.png │ └── cloudgrey@2x.png ├── en.lproj │ ├── Credits.rtf │ ├── InfoPlist.strings │ └── MainMenu.xib └── main.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | -------------------------------------------------------------------------------- /AXStatusItemPopup.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "AXStatusItemPopup" 3 | s.version = "0.0.2" 4 | s.summary = "NSStatusItem that shows a little NSPopover when clicked." 5 | s.homepage = "https://github.com/aschuch/AXStatusItemPopup" 6 | s.license = { :type => "MIT", :text => <<-LICENSE 7 | Copyright (C) 2013 Alexander Schuch 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 9 | software and associated documentation files (the "Software"), to deal in the Software 10 | without restriction, including without limitation the rights to use, copy, modify, merge, 11 | publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 12 | to whom the Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all copies or 15 | substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 18 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 19 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 20 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | DEALINGS IN THE SOFTWARE. 23 | LICENSE 24 | } 25 | s.author = { "Alexander Schuch" => "alexander@schuch.me" } 26 | s.platform = :osx, "10.7" 27 | s.source = { :git => "https://github.com/aschuch/AXStatusItemPopup.git", :tag => s.version.to_s } 28 | s.source_files = "AXStatusItemPopup/*.{h,m}" 29 | end 30 | -------------------------------------------------------------------------------- /AXStatusItemPopup/AXStatusItemPopup.h: -------------------------------------------------------------------------------- 1 | // 2 | // StatusItemPopup.h 3 | // StatusItemPopup 4 | // 5 | // Created by Alexander Schuch on 06/03/13. 6 | // Copyright (c) 2013 Alexander Schuch. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AXStatusItemPopup : NSView 12 | 13 | // properties 14 | @property(assign, nonatomic, getter=isActive) BOOL active; 15 | @property(assign, nonatomic) BOOL animated; 16 | @property(strong, nonatomic) NSImage *image; 17 | @property(strong, nonatomic) NSImage *alternateImage; 18 | @property(strong, nonatomic) NSStatusItem *statusItem; 19 | 20 | /** 21 | Popovers may have one of several predefined appearances. 22 | You may specify the appearance of a popover using the constants defined in NSPopoverAppearance. The default appearance is NSPopoverAppearanceMinimal. 23 | 24 | @param appearance NSPopoverAppearance 25 | */ 26 | @property(nonatomic, strong, readonly) NSPopover *popover; 27 | 28 | // init 29 | - (id)initWithViewController:(NSViewController *)controller; 30 | - (id)initWithViewController:(NSViewController *)controller image:(NSImage *)image; 31 | - (id)initWithViewController:(NSViewController *)controller image:(NSImage *)image alternateImage:(NSImage *)alternateImage; 32 | 33 | 34 | // show / hide popover 35 | - (void)showPopover; 36 | - (void)showPopoverAnimated:(BOOL)animated; 37 | - (void)hidePopover; 38 | 39 | // view size 40 | - (void)setContentSize:(CGSize)size; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /AXStatusItemPopup/AXStatusItemPopup.m: -------------------------------------------------------------------------------- 1 | // 2 | // StatusItemPopup.m 3 | // StatusItemPopup 4 | // 5 | // Created by Alexander Schuch on 06/03/13. 6 | // Copyright (c) 2013 Alexander Schuch. All rights reserved. 7 | // 8 | 9 | #import "AXStatusItemPopup.h" 10 | 11 | #define kMinViewWidth 22 12 | 13 | // 14 | // Private variables 15 | // 16 | @interface AXStatusItemPopup () { 17 | NSViewController *_viewController; 18 | BOOL _active; 19 | NSImageView *_imageView; 20 | NSStatusItem *_statusItem; 21 | NSMenu *_dummyMenu; 22 | id _popoverTransiencyMonitor; 23 | } 24 | 25 | @property(nonatomic, strong, readwrite) NSPopover* popover; 26 | 27 | @end 28 | 29 | /////////////////////////////////// 30 | 31 | // 32 | // Implementation 33 | // 34 | @implementation AXStatusItemPopup 35 | 36 | - (id)initWithViewController:(NSViewController *)controller 37 | { 38 | return [self initWithViewController:controller image:nil]; 39 | } 40 | 41 | - (id)initWithViewController:(NSViewController *)controller image:(NSImage *)image 42 | { 43 | return [self initWithViewController:controller image:image alternateImage:nil]; 44 | } 45 | 46 | - (id)initWithViewController:(NSViewController *)controller image:(NSImage *)image alternateImage:(NSImage *)alternateImage 47 | { 48 | CGFloat height = [NSStatusBar systemStatusBar].thickness; 49 | 50 | self = [super initWithFrame:NSMakeRect(0, 0, kMinViewWidth, height)]; 51 | if (self) { 52 | _viewController = controller; 53 | 54 | self.image = image; 55 | self.alternateImage = alternateImage; 56 | 57 | _imageView = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, kMinViewWidth, height)]; 58 | [self addSubview:_imageView]; 59 | 60 | self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; 61 | self.statusItem.view = self; 62 | _dummyMenu = [[NSMenu alloc] init]; 63 | 64 | _active = NO; 65 | _animated = YES; 66 | } 67 | return self; 68 | } 69 | 70 | 71 | //////////////////////////////////// 72 | #pragma mark - Drawing 73 | //////////////////////////////////// 74 | 75 | - (void)drawRect:(NSRect)dirtyRect 76 | { 77 | // set view background color 78 | if (_active) { 79 | [[NSColor selectedMenuItemColor] setFill]; 80 | } else { 81 | [[NSColor clearColor] setFill]; 82 | } 83 | NSRectFill(dirtyRect); 84 | 85 | // set image 86 | NSImage *image = (_active ? _alternateImage : _image); 87 | _imageView.image = image; 88 | } 89 | 90 | //////////////////////////////////// 91 | #pragma mark - Position / Size 92 | //////////////////////////////////// 93 | 94 | - (void)setContentSize:(CGSize)size 95 | { 96 | _popover.contentSize = size; 97 | } 98 | 99 | //////////////////////////////////// 100 | #pragma mark - Mouse Actions 101 | //////////////////////////////////// 102 | 103 | - (void)mouseDown:(NSEvent *)theEvent 104 | { 105 | if (_popover.isShown) { 106 | [self hidePopover]; 107 | } else { 108 | [self showPopover]; 109 | } 110 | } 111 | 112 | - (void)rightMouseDown:(NSEvent *)theEvent 113 | { 114 | [self mouseDown:nil]; 115 | } 116 | 117 | //////////////////////////////////// 118 | #pragma mark - Setter 119 | //////////////////////////////////// 120 | 121 | - (void)setActive:(BOOL)active 122 | { 123 | _active = active; 124 | [self setNeedsDisplay:YES]; 125 | } 126 | 127 | - (void)setImage:(NSImage *)image 128 | { 129 | _image = image; 130 | [self updateViewFrame]; 131 | } 132 | 133 | - (void)setAlternateImage:(NSImage *)image 134 | { 135 | _alternateImage = image; 136 | if (!image && _image) { 137 | _alternateImage = _image; 138 | } 139 | [self updateViewFrame]; 140 | } 141 | 142 | //////////////////////////////////// 143 | #pragma mark - Helper 144 | //////////////////////////////////// 145 | 146 | - (void)updateViewFrame 147 | { 148 | CGFloat width = MAX(MAX(kMinViewWidth, self.alternateImage.size.width), self.image.size.width); 149 | CGFloat height = [NSStatusBar systemStatusBar].thickness; 150 | 151 | NSRect frame = NSMakeRect(0, 0, width, height); 152 | self.frame = frame; 153 | _imageView.frame = frame; 154 | 155 | [self setNeedsDisplay:YES]; 156 | } 157 | 158 | 159 | //////////////////////////////////// 160 | #pragma mark - Show / Hide Popover 161 | //////////////////////////////////// 162 | 163 | - (void)showPopover 164 | { 165 | [self showPopoverAnimated:_animated]; 166 | } 167 | 168 | - (void)showPopoverAnimated:(BOOL)animated 169 | { 170 | self.active = YES; 171 | 172 | if (!_popover) { 173 | _popover = [[NSPopover alloc] init]; 174 | _popover.contentViewController = _viewController; 175 | } 176 | 177 | if (!_popover.isShown) { 178 | _popover.animates = animated; 179 | [self.statusItem popUpStatusItemMenu:_dummyMenu]; 180 | [_popover showRelativeToRect:self.frame ofView:self preferredEdge:NSMinYEdge]; 181 | _popoverTransiencyMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask handler:^(NSEvent* event) { 182 | [self hidePopover]; 183 | }]; 184 | } 185 | } 186 | 187 | - (void)hidePopover 188 | { 189 | self.active = NO; 190 | 191 | if (_popover && _popover.isShown) { 192 | [_popover close]; 193 | 194 | if (_popoverTransiencyMonitor) { 195 | [NSEvent removeMonitor:_popoverTransiencyMonitor]; 196 | _popoverTransiencyMonitor = nil; 197 | } 198 | } 199 | } 200 | 201 | @end 202 | 203 | -------------------------------------------------------------------------------- /Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4D304D7916E93AF900FAFFA6 /* AXStatusItemPopup.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D304D7816E93AF900FAFFA6 /* AXStatusItemPopup.m */; }; 11 | 4D35953F16E8A7D50047F4BD /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D35953E16E8A7D50047F4BD /* Cocoa.framework */; }; 12 | 4D35954916E8A7D50047F4BD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D35954716E8A7D50047F4BD /* InfoPlist.strings */; }; 13 | 4D35954B16E8A7D50047F4BD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D35954A16E8A7D50047F4BD /* main.m */; }; 14 | 4D35954F16E8A7D50047F4BD /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4D35954D16E8A7D50047F4BD /* Credits.rtf */; }; 15 | 4D35956116E8A86E0047F4BD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D35955D16E8A86E0047F4BD /* AppDelegate.m */; }; 16 | 4D35956216E8A86E0047F4BD /* ContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D35955F16E8A86E0047F4BD /* ContentViewController.m */; }; 17 | 4D35956316E8A86E0047F4BD /* ContentViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4D35956016E8A86E0047F4BD /* ContentViewController.xib */; }; 18 | 4D35956516E8A8850047F4BD /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4D35956416E8A8850047F4BD /* MainMenu.xib */; }; 19 | 4D35956B16E8A89B0047F4BD /* cloud.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D35956716E8A89B0047F4BD /* cloud.png */; }; 20 | 4D35956C16E8A89B0047F4BD /* cloud@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D35956816E8A89B0047F4BD /* cloud@2x.png */; }; 21 | 4D35956D16E8A89B0047F4BD /* cloudgrey.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D35956916E8A89B0047F4BD /* cloudgrey.png */; }; 22 | 4D35956E16E8A89B0047F4BD /* cloudgrey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D35956A16E8A89B0047F4BD /* cloudgrey@2x.png */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 4D304D7716E93AF900FAFFA6 /* AXStatusItemPopup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AXStatusItemPopup.h; sourceTree = ""; }; 27 | 4D304D7816E93AF900FAFFA6 /* AXStatusItemPopup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AXStatusItemPopup.m; sourceTree = ""; }; 28 | 4D35953B16E8A7D40047F4BD /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 4D35953E16E8A7D50047F4BD /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 30 | 4D35954116E8A7D50047F4BD /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 31 | 4D35954216E8A7D50047F4BD /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 32 | 4D35954316E8A7D50047F4BD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 33 | 4D35954616E8A7D50047F4BD /* Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Demo-Info.plist"; sourceTree = ""; }; 34 | 4D35954816E8A7D50047F4BD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 35 | 4D35954A16E8A7D50047F4BD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 36 | 4D35954C16E8A7D50047F4BD /* Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Demo-Prefix.pch"; sourceTree = ""; }; 37 | 4D35954E16E8A7D50047F4BD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 38 | 4D35955C16E8A86E0047F4BD /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 39 | 4D35955D16E8A86E0047F4BD /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 40 | 4D35955E16E8A86E0047F4BD /* ContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentViewController.h; sourceTree = ""; }; 41 | 4D35955F16E8A86E0047F4BD /* ContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContentViewController.m; sourceTree = ""; }; 42 | 4D35956016E8A86E0047F4BD /* ContentViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContentViewController.xib; sourceTree = ""; }; 43 | 4D35956416E8A8850047F4BD /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; }; 44 | 4D35956716E8A89B0047F4BD /* cloud.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud.png; sourceTree = ""; }; 45 | 4D35956816E8A89B0047F4BD /* cloud@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cloud@2x.png"; sourceTree = ""; }; 46 | 4D35956916E8A89B0047F4BD /* cloudgrey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloudgrey.png; sourceTree = ""; }; 47 | 4D35956A16E8A89B0047F4BD /* cloudgrey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cloudgrey@2x.png"; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | 4D35953816E8A7D40047F4BD /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | 4D35953F16E8A7D50047F4BD /* Cocoa.framework in Frameworks */, 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | /* End PBXFrameworksBuildPhase section */ 60 | 61 | /* Begin PBXGroup section */ 62 | 4D304D7616E93AF900FAFFA6 /* AXStatusItemPopup */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 4D304D7716E93AF900FAFFA6 /* AXStatusItemPopup.h */, 66 | 4D304D7816E93AF900FAFFA6 /* AXStatusItemPopup.m */, 67 | ); 68 | path = AXStatusItemPopup; 69 | sourceTree = SOURCE_ROOT; 70 | }; 71 | 4D35953216E8A7D40047F4BD = { 72 | isa = PBXGroup; 73 | children = ( 74 | 4D35954416E8A7D50047F4BD /* Demo */, 75 | 4D35953D16E8A7D40047F4BD /* Frameworks */, 76 | 4D35953C16E8A7D40047F4BD /* Products */, 77 | ); 78 | sourceTree = ""; 79 | }; 80 | 4D35953C16E8A7D40047F4BD /* Products */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 4D35953B16E8A7D40047F4BD /* Demo.app */, 84 | ); 85 | name = Products; 86 | sourceTree = ""; 87 | }; 88 | 4D35953D16E8A7D40047F4BD /* Frameworks */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 4D35953E16E8A7D50047F4BD /* Cocoa.framework */, 92 | 4D35954016E8A7D50047F4BD /* Other Frameworks */, 93 | ); 94 | name = Frameworks; 95 | sourceTree = ""; 96 | }; 97 | 4D35954016E8A7D50047F4BD /* Other Frameworks */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 4D35954116E8A7D50047F4BD /* AppKit.framework */, 101 | 4D35954216E8A7D50047F4BD /* CoreData.framework */, 102 | 4D35954316E8A7D50047F4BD /* Foundation.framework */, 103 | ); 104 | name = "Other Frameworks"; 105 | sourceTree = ""; 106 | }; 107 | 4D35954416E8A7D50047F4BD /* Demo */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 4D35955B16E8A86E0047F4BD /* Code */, 111 | 4D304D7616E93AF900FAFFA6 /* AXStatusItemPopup */, 112 | 4D35956616E8A89B0047F4BD /* Resources */, 113 | 4D35954516E8A7D50047F4BD /* Supporting Files */, 114 | ); 115 | path = Demo; 116 | sourceTree = ""; 117 | }; 118 | 4D35954516E8A7D50047F4BD /* Supporting Files */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 4D35954616E8A7D50047F4BD /* Demo-Info.plist */, 122 | 4D35954716E8A7D50047F4BD /* InfoPlist.strings */, 123 | 4D35954A16E8A7D50047F4BD /* main.m */, 124 | 4D35954C16E8A7D50047F4BD /* Demo-Prefix.pch */, 125 | 4D35954D16E8A7D50047F4BD /* Credits.rtf */, 126 | ); 127 | name = "Supporting Files"; 128 | sourceTree = ""; 129 | }; 130 | 4D35955B16E8A86E0047F4BD /* Code */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 4D35955C16E8A86E0047F4BD /* AppDelegate.h */, 134 | 4D35955D16E8A86E0047F4BD /* AppDelegate.m */, 135 | 4D35956416E8A8850047F4BD /* MainMenu.xib */, 136 | 4D35955E16E8A86E0047F4BD /* ContentViewController.h */, 137 | 4D35955F16E8A86E0047F4BD /* ContentViewController.m */, 138 | 4D35956016E8A86E0047F4BD /* ContentViewController.xib */, 139 | ); 140 | path = Code; 141 | sourceTree = ""; 142 | }; 143 | 4D35956616E8A89B0047F4BD /* Resources */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 4D35956716E8A89B0047F4BD /* cloud.png */, 147 | 4D35956816E8A89B0047F4BD /* cloud@2x.png */, 148 | 4D35956916E8A89B0047F4BD /* cloudgrey.png */, 149 | 4D35956A16E8A89B0047F4BD /* cloudgrey@2x.png */, 150 | ); 151 | path = Resources; 152 | sourceTree = ""; 153 | }; 154 | /* End PBXGroup section */ 155 | 156 | /* Begin PBXNativeTarget section */ 157 | 4D35953A16E8A7D40047F4BD /* Demo */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 4D35955816E8A7D50047F4BD /* Build configuration list for PBXNativeTarget "Demo" */; 160 | buildPhases = ( 161 | 4D35953716E8A7D40047F4BD /* Sources */, 162 | 4D35953816E8A7D40047F4BD /* Frameworks */, 163 | 4D35953916E8A7D40047F4BD /* Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | ); 169 | name = Demo; 170 | productName = Demo; 171 | productReference = 4D35953B16E8A7D40047F4BD /* Demo.app */; 172 | productType = "com.apple.product-type.application"; 173 | }; 174 | /* End PBXNativeTarget section */ 175 | 176 | /* Begin PBXProject section */ 177 | 4D35953316E8A7D40047F4BD /* Project object */ = { 178 | isa = PBXProject; 179 | attributes = { 180 | LastUpgradeCheck = 0510; 181 | ORGANIZATIONNAME = "Alexander Schuch"; 182 | }; 183 | buildConfigurationList = 4D35953616E8A7D40047F4BD /* Build configuration list for PBXProject "Demo" */; 184 | compatibilityVersion = "Xcode 3.2"; 185 | developmentRegion = English; 186 | hasScannedForEncodings = 0; 187 | knownRegions = ( 188 | en, 189 | ); 190 | mainGroup = 4D35953216E8A7D40047F4BD; 191 | productRefGroup = 4D35953C16E8A7D40047F4BD /* Products */; 192 | projectDirPath = ""; 193 | projectRoot = ""; 194 | targets = ( 195 | 4D35953A16E8A7D40047F4BD /* Demo */, 196 | ); 197 | }; 198 | /* End PBXProject section */ 199 | 200 | /* Begin PBXResourcesBuildPhase section */ 201 | 4D35953916E8A7D40047F4BD /* Resources */ = { 202 | isa = PBXResourcesBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | 4D35954916E8A7D50047F4BD /* InfoPlist.strings in Resources */, 206 | 4D35954F16E8A7D50047F4BD /* Credits.rtf in Resources */, 207 | 4D35956316E8A86E0047F4BD /* ContentViewController.xib in Resources */, 208 | 4D35956516E8A8850047F4BD /* MainMenu.xib in Resources */, 209 | 4D35956B16E8A89B0047F4BD /* cloud.png in Resources */, 210 | 4D35956C16E8A89B0047F4BD /* cloud@2x.png in Resources */, 211 | 4D35956D16E8A89B0047F4BD /* cloudgrey.png in Resources */, 212 | 4D35956E16E8A89B0047F4BD /* cloudgrey@2x.png in Resources */, 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | /* End PBXResourcesBuildPhase section */ 217 | 218 | /* Begin PBXSourcesBuildPhase section */ 219 | 4D35953716E8A7D40047F4BD /* Sources */ = { 220 | isa = PBXSourcesBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | 4D35954B16E8A7D50047F4BD /* main.m in Sources */, 224 | 4D35956116E8A86E0047F4BD /* AppDelegate.m in Sources */, 225 | 4D35956216E8A86E0047F4BD /* ContentViewController.m in Sources */, 226 | 4D304D7916E93AF900FAFFA6 /* AXStatusItemPopup.m in Sources */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | /* End PBXSourcesBuildPhase section */ 231 | 232 | /* Begin PBXVariantGroup section */ 233 | 4D35954716E8A7D50047F4BD /* InfoPlist.strings */ = { 234 | isa = PBXVariantGroup; 235 | children = ( 236 | 4D35954816E8A7D50047F4BD /* en */, 237 | ); 238 | name = InfoPlist.strings; 239 | sourceTree = ""; 240 | }; 241 | 4D35954D16E8A7D50047F4BD /* Credits.rtf */ = { 242 | isa = PBXVariantGroup; 243 | children = ( 244 | 4D35954E16E8A7D50047F4BD /* en */, 245 | ); 246 | name = Credits.rtf; 247 | sourceTree = ""; 248 | }; 249 | /* End PBXVariantGroup section */ 250 | 251 | /* Begin XCBuildConfiguration section */ 252 | 4D35955616E8A7D50047F4BD /* Debug */ = { 253 | isa = XCBuildConfiguration; 254 | buildSettings = { 255 | ALWAYS_SEARCH_USER_PATHS = NO; 256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 257 | CLANG_CXX_LIBRARY = "libc++"; 258 | CLANG_ENABLE_OBJC_ARC = YES; 259 | CLANG_WARN_CONSTANT_CONVERSION = YES; 260 | CLANG_WARN_EMPTY_BODY = YES; 261 | CLANG_WARN_ENUM_CONVERSION = YES; 262 | CLANG_WARN_INT_CONVERSION = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | COPY_PHASE_STRIP = NO; 265 | GCC_C_LANGUAGE_STANDARD = gnu99; 266 | GCC_DYNAMIC_NO_PIC = NO; 267 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 268 | GCC_OPTIMIZATION_LEVEL = 0; 269 | GCC_PREPROCESSOR_DEFINITIONS = ( 270 | "DEBUG=1", 271 | "$(inherited)", 272 | ); 273 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 274 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 275 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 276 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 277 | GCC_WARN_UNUSED_VARIABLE = YES; 278 | MACOSX_DEPLOYMENT_TARGET = 10.8; 279 | ONLY_ACTIVE_ARCH = YES; 280 | SDKROOT = macosx; 281 | }; 282 | name = Debug; 283 | }; 284 | 4D35955716E8A7D50047F4BD /* Release */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | ALWAYS_SEARCH_USER_PATHS = NO; 288 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 289 | CLANG_CXX_LIBRARY = "libc++"; 290 | CLANG_ENABLE_OBJC_ARC = YES; 291 | CLANG_WARN_CONSTANT_CONVERSION = YES; 292 | CLANG_WARN_EMPTY_BODY = YES; 293 | CLANG_WARN_ENUM_CONVERSION = YES; 294 | CLANG_WARN_INT_CONVERSION = YES; 295 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 296 | COPY_PHASE_STRIP = YES; 297 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 298 | GCC_C_LANGUAGE_STANDARD = gnu99; 299 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 301 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 302 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 303 | GCC_WARN_UNUSED_VARIABLE = YES; 304 | MACOSX_DEPLOYMENT_TARGET = 10.8; 305 | SDKROOT = macosx; 306 | }; 307 | name = Release; 308 | }; 309 | 4D35955916E8A7D50047F4BD /* Debug */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | COMBINE_HIDPI_IMAGES = YES; 313 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 314 | GCC_PREFIX_HEADER = "Demo/Demo-Prefix.pch"; 315 | INFOPLIST_FILE = "Demo/Demo-Info.plist"; 316 | PRODUCT_NAME = "$(TARGET_NAME)"; 317 | WRAPPER_EXTENSION = app; 318 | }; 319 | name = Debug; 320 | }; 321 | 4D35955A16E8A7D50047F4BD /* Release */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | COMBINE_HIDPI_IMAGES = YES; 325 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 326 | GCC_PREFIX_HEADER = "Demo/Demo-Prefix.pch"; 327 | INFOPLIST_FILE = "Demo/Demo-Info.plist"; 328 | PRODUCT_NAME = "$(TARGET_NAME)"; 329 | WRAPPER_EXTENSION = app; 330 | }; 331 | name = Release; 332 | }; 333 | /* End XCBuildConfiguration section */ 334 | 335 | /* Begin XCConfigurationList section */ 336 | 4D35953616E8A7D40047F4BD /* Build configuration list for PBXProject "Demo" */ = { 337 | isa = XCConfigurationList; 338 | buildConfigurations = ( 339 | 4D35955616E8A7D50047F4BD /* Debug */, 340 | 4D35955716E8A7D50047F4BD /* Release */, 341 | ); 342 | defaultConfigurationIsVisible = 0; 343 | defaultConfigurationName = Release; 344 | }; 345 | 4D35955816E8A7D50047F4BD /* Build configuration list for PBXNativeTarget "Demo" */ = { 346 | isa = XCConfigurationList; 347 | buildConfigurations = ( 348 | 4D35955916E8A7D50047F4BD /* Debug */, 349 | 4D35955A16E8A7D50047F4BD /* Release */, 350 | ); 351 | defaultConfigurationIsVisible = 0; 352 | defaultConfigurationName = Release; 353 | }; 354 | /* End XCConfigurationList section */ 355 | }; 356 | rootObject = 4D35953316E8A7D40047F4BD /* Project object */; 357 | } 358 | -------------------------------------------------------------------------------- /Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Code/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // StatusItemPopup 4 | // 5 | // Created by Alexander Schuch on 06/03/13. 6 | // Copyright (c) 2013 Alexander Schuch. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | @property (assign) IBOutlet NSWindow *window; 14 | 15 | - (IBAction)showPopover:(id)sender; 16 | - (IBAction)showPopoverAnimated:(id)sender; 17 | - (IBAction)hidePopover:(id)sender; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Demo/Code/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // StatusItemPopup 4 | // 5 | // Created by Alexander Schuch on 06/03/13. 6 | // Copyright (c) 2013 Alexander Schuch. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ContentViewController.h" 11 | #import "AXStatusItemPopup.h" 12 | 13 | @interface AppDelegate () { 14 | AXStatusItemPopup *_statusItemPopup; 15 | } 16 | 17 | @end 18 | 19 | @implementation AppDelegate 20 | 21 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 22 | { 23 | // -------------- 24 | // 25 | 26 | // init content view controller 27 | // will be shown inside the popover 28 | ContentViewController *contentViewController = [[ContentViewController alloc] initWithNibName:@"ContentViewController" bundle:nil]; 29 | 30 | // init the status item popup 31 | NSImage *image = [NSImage imageNamed:@"cloud"]; 32 | NSImage *alternateImage = [NSImage imageNamed:@"cloudgrey"]; 33 | 34 | _statusItemPopup = [[AXStatusItemPopup alloc] initWithViewController:contentViewController image:image alternateImage:alternateImage]; 35 | 36 | // globally set animation state (optional, defaults to YES) 37 | //_statusItemPopup.animated = NO; 38 | 39 | // 40 | // -------------- 41 | 42 | // optionally set the popover to the contentview to e.g. hide it from there 43 | contentViewController.statusItemPopup = _statusItemPopup; 44 | } 45 | 46 | //////////////////////////////////// 47 | #pragma mark - Show / Hide Button Actions 48 | //////////////////////////////////// 49 | 50 | - (IBAction)showPopover:(id)sender 51 | { 52 | [_statusItemPopup showPopoverAnimated:NO]; 53 | } 54 | 55 | - (IBAction)showPopoverAnimated:(id)sender 56 | { 57 | [_statusItemPopup showPopoverAnimated:YES]; 58 | } 59 | 60 | - (IBAction)hidePopover:(id)sender 61 | { 62 | [_statusItemPopup hidePopover]; 63 | } 64 | 65 | - (IBAction)appearanceValueChanged:(id)sender { 66 | if ([_statusItemPopup isActive]) { 67 | [_statusItemPopup hidePopover]; 68 | } 69 | 70 | NSButton *checkBox = (NSButton*) sender; 71 | NSPopoverAppearance newAppearance = NSPopoverAppearanceMinimal; 72 | if ([(NSCell*)checkBox.cell state] == 1) { 73 | newAppearance = NSPopoverAppearanceHUD; 74 | } 75 | _statusItemPopup.popover.appearance = newAppearance; 76 | } 77 | @end 78 | -------------------------------------------------------------------------------- /Demo/Code/ContentViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentViewController.h 3 | // StatusItemPopup 4 | // 5 | // Created by Alexander Schuch on 06/03/13. 6 | // Copyright (c) 2013 Alexander Schuch. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AXStatusItemPopup.h" 11 | 12 | @interface ContentViewController : NSViewController 13 | 14 | @property(weak, nonatomic) AXStatusItemPopup *statusItemPopup; 15 | 16 | - (IBAction)closeButtonPressed:(id)sender; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Demo/Code/ContentViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContentViewController.m 3 | // StatusItemPopup 4 | // 5 | // Created by Alexander Schuch on 06/03/13. 6 | // Copyright (c) 2013 Alexander Schuch. All rights reserved. 7 | // 8 | 9 | #import "ContentViewController.h" 10 | 11 | @interface ContentViewController () 12 | 13 | @end 14 | 15 | @implementation ContentViewController 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Initialization code here. 22 | } 23 | 24 | return self; 25 | } 26 | 27 | - (IBAction)closeButtonPressed:(id)sender 28 | { 29 | [_statusItemPopup hidePopover]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Demo/Code/ContentViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1070 5 | 12C2034 6 | 3084 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.CocoaPlugin 11 | 3084 12 | 13 | 14 | IBNSLayoutConstraint 15 | NSButton 16 | NSButtonCell 17 | NSCustomObject 18 | NSCustomView 19 | NSTextField 20 | NSTextFieldCell 21 | 22 | 23 | com.apple.InterfaceBuilder.CocoaPlugin 24 | 25 | 26 | PluginDependencyRecalculationVersion 27 | 28 | 29 | 30 | 31 | ContentViewController 32 | 33 | 34 | FirstResponder 35 | 36 | 37 | NSApplication 38 | 39 | 40 | 41 | 268 42 | 43 | 44 | 45 | 268 46 | {{110, 59}, {46, 19}} 47 | 48 | 49 | _NS:9 50 | YES 51 | 52 | -2080374784 53 | 134217728 54 | Close 55 | 56 | LucidaGrande 57 | 12 58 | 16 59 | 60 | _NS:9 61 | 62 | -2038153216 63 | 164 64 | 65 | 66 | 400 67 | 75 68 | 69 | NO 70 | 71 | 72 | 73 | 268 74 | {{78, 86}, {111, 17}} 75 | 76 | 77 | _NS:1535 78 | YES 79 | 80 | 68157504 81 | 272630784 82 | StatusItemPopup 83 | 84 | LucidaGrande 85 | 13 86 | 1044 87 | 88 | _NS:1535 89 | 90 | 91 | 6 92 | System 93 | controlColor 94 | 95 | 3 96 | MC42NjY2NjY2NjY3AA 97 | 98 | 99 | 100 | 6 101 | System 102 | controlTextColor 103 | 104 | 3 105 | MAA 106 | 107 | 108 | 109 | NO 110 | 111 | 112 | {267, 162} 113 | 114 | 115 | 116 | NSView 117 | 118 | 119 | 120 | 121 | 122 | 123 | view 124 | 125 | 126 | 127 | 2 128 | 129 | 130 | 131 | closeButtonPressed: 132 | 133 | 134 | 135 | 15 136 | 137 | 138 | 139 | 140 | 141 | 0 142 | 143 | 144 | 145 | 146 | 147 | -2 148 | 149 | 150 | File's Owner 151 | 152 | 153 | -1 154 | 155 | 156 | First Responder 157 | 158 | 159 | -3 160 | 161 | 162 | Application 163 | 164 | 165 | 1 166 | 167 | 168 | 169 | 170 | 3 171 | 0 172 | 173 | 4 174 | 1 175 | 176 | 8 177 | 178 | 1000 179 | 180 | 6 181 | 24 182 | 3 183 | 184 | 185 | 186 | 9 187 | 0 188 | 189 | 9 190 | 1 191 | 192 | 0.0 193 | 194 | 1000 195 | 196 | 5 197 | 22 198 | 2 199 | 200 | 201 | 202 | 9 203 | 0 204 | 205 | 9 206 | 1 207 | 208 | 0.0 209 | 210 | 1000 211 | 212 | 6 213 | 24 214 | 2 215 | 216 | 217 | 218 | 3 219 | 0 220 | 221 | 3 222 | 1 223 | 224 | 59 225 | 226 | 1000 227 | 228 | 3 229 | 9 230 | 3 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 3 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 4 247 | 248 | 249 | 250 | 251 | 7 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 8 260 | 261 | 262 | 263 | 264 | 9 265 | 266 | 267 | 268 | 269 | 11 270 | 271 | 272 | 273 | 274 | 13 275 | 276 | 277 | 278 | 279 | 14 280 | 281 | 282 | 283 | 284 | 285 | 286 | com.apple.InterfaceBuilder.CocoaPlugin 287 | com.apple.InterfaceBuilder.CocoaPlugin 288 | com.apple.InterfaceBuilder.CocoaPlugin 289 | 290 | 291 | 292 | 293 | 294 | 295 | com.apple.InterfaceBuilder.CocoaPlugin 296 | com.apple.InterfaceBuilder.CocoaPlugin 297 | com.apple.InterfaceBuilder.CocoaPlugin 298 | com.apple.InterfaceBuilder.CocoaPlugin 299 | 300 | com.apple.InterfaceBuilder.CocoaPlugin 301 | com.apple.InterfaceBuilder.CocoaPlugin 302 | 303 | com.apple.InterfaceBuilder.CocoaPlugin 304 | com.apple.InterfaceBuilder.CocoaPlugin 305 | com.apple.InterfaceBuilder.CocoaPlugin 306 | 307 | 308 | 309 | 310 | 311 | 15 312 | 313 | 314 | 315 | 316 | ContentViewController 317 | NSViewController 318 | 319 | closeButtonPressed: 320 | id 321 | 322 | 323 | closeButtonPressed: 324 | 325 | closeButtonPressed: 326 | id 327 | 328 | 329 | 330 | IBProjectSource 331 | ./Classes/ContentViewController.h 332 | 333 | 334 | 335 | NSLayoutConstraint 336 | NSObject 337 | 338 | IBProjectSource 339 | ./Classes/NSLayoutConstraint.h 340 | 341 | 342 | 343 | 344 | 0 345 | IBCocoaFramework 346 | 347 | com.apple.InterfaceBuilder.CocoaPlugin.macosx 348 | 349 | 350 | YES 351 | 3 352 | YES 353 | 354 | 355 | -------------------------------------------------------------------------------- /Demo/Code/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | Default 523 | 524 | 525 | 526 | 527 | 528 | 529 | Left to Right 530 | 531 | 532 | 533 | 534 | 535 | 536 | Right to Left 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | Default 548 | 549 | 550 | 551 | 552 | 553 | 554 | Left to Right 555 | 556 | 557 | 558 | 559 | 560 | 561 | Right to Left 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 670 | 681 | 692 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | -------------------------------------------------------------------------------- /Demo/Demo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | at.smartcode.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2013 Alexander Schuch. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Demo/Demo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Demo' target in the 'Demo' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Demo/Resources/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aschuch/AXStatusItemPopup/03da6de83f75aed133223caa4f6653846c94cc6a/Demo/Resources/cloud.png -------------------------------------------------------------------------------- /Demo/Resources/cloud@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aschuch/AXStatusItemPopup/03da6de83f75aed133223caa4f6653846c94cc6a/Demo/Resources/cloud@2x.png -------------------------------------------------------------------------------- /Demo/Resources/cloudgrey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aschuch/AXStatusItemPopup/03da6de83f75aed133223caa4f6653846c94cc6a/Demo/Resources/cloudgrey.png -------------------------------------------------------------------------------- /Demo/Resources/cloudgrey@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aschuch/AXStatusItemPopup/03da6de83f75aed133223caa4f6653846c94cc6a/Demo/Resources/cloudgrey@2x.png -------------------------------------------------------------------------------- /Demo/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /Demo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Demo 4 | // 5 | // Created by Alexander Schuch on 07/03/13. 6 | // Copyright (c) 2013 Alexander Schuch. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AXStatusItemPopup 2 | 3 | ```NSStatusItem``` that shows a little ```NSPopover``` when clicked. 4 | 5 | ![equation](http://schuch.me/github/AXStatusItemPopup/demo.png "AXStatusItemPopup") 6 | 7 | ## Installation 8 | 9 | Simply drag and drop the .h and .m file from the ```AXStatusItemPopup``` into your project. 10 | 11 | ## Usage 12 | 13 | ```objective-c 14 | AXStatusItemPopup *statusItemPopup = [[AXStatusItemPopup alloc] initWithViewController:contentViewController image:image alternateImage:alternateImage]; 15 | ``` 16 | 17 | ```contentViewController``` an NSViewController instance. The contents of this view controllers view will be shown inside the popup. ```image``` is an NSImage that should be shown in the status bar. ```alternateImage``` an NSImage that should be shown if the popover is currently active. 18 | 19 | ### Full Example 20 | 21 | ```objective-c 22 | // init content view controller 23 | // its contents will be shown inside the popover 24 | ContentViewController *contentViewController = [[ContentViewController alloc] initWithNibName:@"ContentViewController" bundle:nil]; 25 | 26 | // create icon images shown in statusbar 27 | NSImage *image = [NSImage imageNamed:@"cloud"]; 28 | NSImage *alternateImage = [NSImage imageNamed:@"cloudgrey"]; 29 | 30 | AXStatusItemPopup *statusItemPopup = [[AXStatusItemPopup alloc] initWithViewController:contentViewController image:image alternateImage:alternateImage]; 31 | ``` 32 | 33 | ### Animations 34 | 35 | By default showing and hiding the popover is animated. However, animations on the popover can be globally disabled. 36 | 37 | ```objective-c 38 | statusItemPopup.animated = NO; 39 | ``` 40 | 41 | ### Remotely show and hide popover 42 | 43 | The popover can be shown and hidden manually within code by calling the following methods on the ```AXStatusItemPopup``` instance. 44 | 45 | ```objective-c 46 | // animation defaults to the value set in statusItemPopup.animated 47 | [statusItemPopup showPopover]; 48 | 49 | // overrides any value set to statusItemPopup.animated 50 | [statusItemPopup showPopoverAnimated:YES]; 51 | 52 | // hides popover 53 | [statusItemPopup hidePopover]; 54 | ``` 55 | 56 | 57 | ## Contributing 58 | 59 | * Create something awesome, make the code better, add some functionality, 60 | whatever (this is the hardest part). 61 | * [Fork it](http://help.github.com/forking/) 62 | * Create new branch to make your changes 63 | * Commit all your changes to your branch 64 | * Submit a [pull request](http://help.github.com/pull-requests/) 65 | 66 | ## Contact 67 | 68 | Feel free to get in touch. 69 | 70 | * Website: 71 | * Twitter: [@schuchalexander](http://twitter.com/schuchalexander) 72 | 73 | ## Licence 74 | 75 | Copyright (C) 2013 Alexander Schuch 76 | 77 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 78 | 79 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 80 | 81 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 82 | 83 | ## Attribution 84 | [Cloud icon](http://thenounproject.com/noun/cloud/#icon-No6852) designed by [Pieter J. Smits](http://thenounproject.com/pjsmits) from The Noun Project. --------------------------------------------------------------------------------