├── .gitignore ├── Classes ├── NSAttributedString+DDConvenience.h ├── NSAttributedString+DDConvenience.m ├── NSString+size.h ├── NSString+size.m ├── OMMiniXcode.h ├── OMMiniXcode.m ├── OMSchemeSelectionView.h └── OMSchemeSelectionView.m ├── Icon.png ├── Info.plist ├── LICENSE.txt ├── OMMiniXcode.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── xcshareddata │ └── OMMiniXcode.xccheckout ├── README.md ├── Resources ├── XCBuildAnalyzerResultIcon.tiff ├── XCBuildErrorIcon.tiff ├── XCBuildSuccessIcon.tiff └── XCBuildWarningIcon.tiff ├── Screenshot.png └── Screenshot2.png /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.xcodeproj/*.pbxuser 3 | *.xcodeproj/*.perspectivev3 4 | *.xcodeproj/xcuserdata 5 | .DS_Store 6 | .swp 7 | ~.nib 8 | .pbxuser 9 | .perspective 10 | *.perspectivev3 11 | *.mode1v3 12 | *.xcworkspacedata 13 | *.xcuserstate 14 | *xcuserdata* 15 | -------------------------------------------------------------------------------- /Classes/NSAttributedString+DDConvenience.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+DDConvenience.h 3 | // OMMiniXcode 4 | // 5 | // Created by Dominik Pich on 9/18/12. 6 | // 7 | // 8 | #import 9 | #if TARGET_OS_IPHONE 10 | #else 11 | #import 12 | #endif 13 | 14 | @interface NSAttributedString (DDConvenience) 15 | 16 | #if TARGET_OS_IPHONE 17 | #else 18 | + (NSAttributedString *)attributedStringWithImage:(NSImage*)image; 19 | #endif 20 | 21 | + (NSAttributedString *)attributedStringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2); 22 | @end 23 | -------------------------------------------------------------------------------- /Classes/NSAttributedString+DDConvenience.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+Image.m 3 | // OMMiniXcode 4 | // 5 | // Created by Dominik Pich on 9/18/12. 6 | // 7 | // 8 | 9 | #import "NSAttributedString+DDConvenience.h" 10 | 11 | @implementation NSAttributedString (DDConvenience) 12 | 13 | #if TARGET_OS_IPHONE 14 | #else 15 | + (NSAttributedString *)attributedStringWithImage:(NSImage*)image { 16 | NSParameterAssert(image); 17 | 18 | NSTextAttachment* attachment = [[NSTextAttachment alloc] init]; 19 | NSTextAttachmentCell *cell = [[NSTextAttachmentCell alloc] initImageCell:image]; 20 | [attachment setAttachmentCell:cell]; 21 | 22 | NSAttributedString *icon = [NSAttributedString attributedStringWithAttachment:attachment]; 23 | return icon; 24 | } 25 | #endif 26 | 27 | + (NSAttributedString *)attributedStringWithFormat:(NSString *)format, ... { 28 | NSParameterAssert(format); 29 | 30 | //get str 31 | va_list argp; 32 | va_start(argp, format); 33 | NSString *str = [[NSString alloc] initWithFormat:format arguments:argp]; 34 | va_end(argp); 35 | 36 | return [[NSAttributedString alloc] initWithString:str]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Classes/NSString+size.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+size.h 3 | // OMMiniXcode 4 | // 5 | // Created by Dominik Pich on 27/10/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (size) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/NSString+size.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+size.m 3 | // OMMiniXcode 4 | // 5 | // Created by Dominik Pich on 27/10/13. 6 | // 7 | // 8 | 9 | #import "NSString+size.h" 10 | 11 | @implementation NSString (size) 12 | 13 | - (CGSize)size { 14 | return CGSizeZero; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Classes/OMMiniXcode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OMMiniXcode.h 3 | // OMMiniXcode 4 | // 5 | // Created by Ole Zorn on 09/07/12. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class OMSchemeSelectionView; 13 | 14 | @interface OMMiniXcode : NSObject { 15 | NSImage *_errorImage; 16 | NSImage *_warningImage; 17 | NSImage *_analyzerResultImage; 18 | NSImage *_successImage; 19 | } 20 | 21 | - (OMSchemeSelectionView *)schemePopUpButtonContainerForWindow:(NSWindow *)window; 22 | - (NSPopUpButton *)schemePopUpButtonForWindow:(NSWindow *)window; 23 | 24 | @end 25 | 26 | -------------------------------------------------------------------------------- /Classes/OMMiniXcode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OMMiniXcode.m 3 | // OMMiniXcode 4 | // 5 | // Created by Ole Zorn on 09/07/12. 6 | // Modified by Dominik Pich 7 | // 8 | // 9 | 10 | #import "OMMiniXcode.h" 11 | #import "OMSchemeSelectionView.h" 12 | #import "NSAttributedString+DDConvenience.h" 13 | 14 | #define SCHEME_POPUP_BUTTON_CONTAINER_TAG 456 15 | #define SCHEME_POPUP_BUTTON_TAG 457 16 | #define BUILD_PROGRESS_SPINNER_TAG 458 17 | 18 | #define kOMMiniXcodeDisableSchemeSelectionInTitleBar @"OMMiniXcodeDisableSchemeSelectionInTitleBar" 19 | 20 | //TODO: Use the actual headers from class-dump 21 | 22 | @interface NSObject (IDEKit) 23 | - (void)setActiveRunContext:(id)arg1 andRunDestination:(id)arg2; 24 | - (id)_bestDestinationForScheme:(id)arg1 previousDestination:(id)arg2; 25 | - (id)activeRunDestination; 26 | + (id)workspaceWindowControllers; 27 | @end 28 | 29 | 30 | @implementation OMMiniXcode { 31 | id _schemeView; 32 | } 33 | 34 | #pragma mark - lifecycle management 35 | 36 | + (void)pluginDidLoad:(NSBundle *)plugin 37 | { 38 | static id sharedPlugin = nil; 39 | static dispatch_once_t onceToken; 40 | dispatch_once(&onceToken, ^{ 41 | sharedPlugin = [[self alloc] init]; 42 | }); 43 | } 44 | 45 | - (id)init 46 | { 47 | if (self = [super init]) { 48 | //observe path 49 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(buildProductsLocationDidChange:) name:@"IDEWorkspaceBuildProductsLocationDidChangeNotification" object:nil]; 50 | 51 | //observer window state 52 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:nil]; 53 | // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(splitViewDidResizeSubviews:) name:NSSplitViewDidResizeSubviewsNotification object:nil]; 54 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidEndLiveResize:) name:NSWindowDidEndLiveResizeNotification object:nil]; 55 | 56 | //observe builds 57 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(buildWillStart:) name:@"IDEBuildOperationWillStartNotification" object:nil]; 58 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(buildDidStop:) name:@"IDEBuildOperationDidStopNotification" object:nil]; 59 | 60 | //preload our icons 61 | NSBundle *bundle = [NSBundle bundleForClass:self.class]; 62 | _errorImage = [bundle imageForResource:@"XCBuildErrorIcon"]; 63 | _warningImage = [bundle imageForResource:@"XCBuildWarningIcon"]; 64 | _analyzerResultImage = [bundle imageForResource:@"XCBuildAnalyzerResultIcon"]; 65 | _successImage = [bundle imageForResource:@"XCBuildSuccessIcon"]; 66 | 67 | //add an entry to toggle 'us' to the view menu 68 | NSMenuItem *viewMenuItem = [[NSApp mainMenu] itemWithTitle:@"View"]; 69 | if (viewMenuItem) { 70 | [[viewMenuItem submenu] addItem:[NSMenuItem separatorItem]]; 71 | NSMenuItem *toggleSchemeInTitleBarItem = [[NSMenuItem alloc] initWithTitle:@"Scheme Selection in Title Bar" action:@selector(toggleSchemeInTitleBar:) keyEquivalent:@""]; 72 | [toggleSchemeInTitleBarItem setTarget:self]; 73 | [[viewMenuItem submenu] addItem:toggleSchemeInTitleBarItem]; 74 | } 75 | 76 | //catch keydowns on our schemeview 77 | [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^NSEvent *(NSEvent *event) { 78 | unsigned short keyCode = [event keyCode]; 79 | if ((keyCode == 26 || keyCode == 28) && [event modifierFlags] & NSControlKeyMask) { 80 | NSWindow *window = [NSApp keyWindow]; 81 | OMSchemeSelectionView *schemeView = [self schemePopUpButtonContainerForWindow:window]; 82 | NSPopUpButton *popUpButton = schemeView.popUpButton; 83 | BOOL toolbarVisible = [[window toolbar] isVisible]; 84 | if (schemeView && !toolbarVisible) { 85 | NSMenuItem *selectedItem = [popUpButton selectedItem]; 86 | if (keyCode == 28) { 87 | for (NSMenuItem *item in [[[popUpButton menu] itemArray] reverseObjectEnumerator]) { 88 | if (item.state == NSOnState) { 89 | selectedItem = item; 90 | break; 91 | } 92 | } 93 | } 94 | [[popUpButton menu] popUpMenuPositioningItem:selectedItem atLocation:NSMakePoint(-14, 2) inView:popUpButton]; 95 | } else if (popUpButton) { 96 | @try { 97 | NSToolbar *toolbar = [window toolbar]; 98 | if (toolbar.items.count >= 3) { 99 | NSToolbarItem *schemeItem = [toolbar.items objectAtIndex:2]; 100 | NSView *schemeView = schemeItem.view; 101 | if (schemeView.subviews.count > 0) { 102 | NSPathControl *pathControl = (NSPathControl *)[schemeView.subviews objectAtIndex:0]; 103 | if ([pathControl isKindOfClass:[NSPathControl class]] && [pathControl isKindOfClass:NSClassFromString(@"IDEPathControl")]) { 104 | NSArray *componentCells = [pathControl pathComponentCells]; 105 | if (componentCells.count > 1) { 106 | NSPathComponentCell *cell = [componentCells objectAtIndex:(keyCode == 26 ? 0 : 1)]; 107 | if ([pathControl respondsToSelector:@selector(popUpMenuForComponentCell:)]) { 108 | [pathControl performSelector:@selector(popUpMenuForComponentCell:) withObject:cell]; 109 | } 110 | } 111 | } 112 | } 113 | } 114 | } 115 | @catch (NSException *exception) { } 116 | } else { 117 | NSBeep(); 118 | } 119 | return nil; 120 | } 121 | return event; 122 | }]; 123 | } 124 | return self; 125 | } 126 | 127 | 128 | - (void)dealloc 129 | { 130 | //remove all observers 131 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 132 | } 133 | 134 | - (void)toggleSchemeInTitleBar:(id)sender 135 | { 136 | BOOL titleBarDisabled = [[NSUserDefaults standardUserDefaults] boolForKey:kOMMiniXcodeDisableSchemeSelectionInTitleBar]; 137 | titleBarDisabled = !titleBarDisabled; 138 | [[NSUserDefaults standardUserDefaults] setBool:titleBarDisabled forKey:kOMMiniXcodeDisableSchemeSelectionInTitleBar]; 139 | 140 | @try { 141 | NSArray *workspaceWindowControllers = [NSClassFromString(@"IDEWorkspaceWindowController") workspaceWindowControllers]; 142 | for (NSWindow *window in [workspaceWindowControllers valueForKey:@"window"]) { 143 | OMSchemeSelectionView *schemeView = [self schemePopUpButtonContainerForWindow:window]; 144 | BOOL toolbarVisible = [[window toolbar] isVisible]; 145 | if (schemeView) { 146 | [schemeView setHidden:titleBarDisabled || toolbarVisible]; 147 | } 148 | } 149 | } 150 | @catch (NSException *exception) { } 151 | } 152 | 153 | - (void)selectDestination:(id)sender 154 | { 155 | NSDictionary *info = [sender representedObject]; 156 | id destination = [info objectForKey:@"destination"]; 157 | id context = [info objectForKey:@"context"]; 158 | @try { 159 | id runContextManager = [[[NSApp keyWindow] windowController] valueForKeyPath:@"_workspace.runContextManager"]; 160 | [runContextManager setActiveRunContext:context andRunDestination:destination]; 161 | } 162 | @catch (NSException *exception) { } 163 | } 164 | 165 | - (void)selectRunContext:(id)sender 166 | { 167 | NSDictionary *info = [sender representedObject]; 168 | id context = [info objectForKey:@"context"]; 169 | @try { 170 | id runContextManager = [[[NSApp keyWindow] windowController] valueForKeyPath:@"_workspace.runContextManager"]; 171 | id bestDestination = [runContextManager _bestDestinationForScheme:context previousDestination:[runContextManager activeRunDestination]]; 172 | [runContextManager setActiveRunContext:context andRunDestination:bestDestination]; 173 | } 174 | @catch (NSException *exception) { } 175 | } 176 | 177 | - (BOOL)validateMenuItem:(NSMenuItem *)menuItem 178 | { 179 | if ([menuItem action] == @selector(toggleSchemeInTitleBar:)) { 180 | BOOL toolbarVisible = [[[NSApp keyWindow] toolbar] isVisible]; 181 | BOOL disabled = [[NSUserDefaults standardUserDefaults] boolForKey:kOMMiniXcodeDisableSchemeSelectionInTitleBar]; 182 | [menuItem setState:disabled ? NSOffState : NSOnState]; 183 | if (toolbarVisible) { 184 | return NO; 185 | } 186 | } 187 | return YES; 188 | } 189 | 190 | - (NSView *)windowTitleViewForWindow:(NSWindow *)window 191 | { 192 | NSView *windowFrameView = [[window contentView] superview]; 193 | for (NSView *view in windowFrameView.subviews) { 194 | if ([view isKindOfClass:NSClassFromString(@"DVTDualProxyWindowTitleView")]) { 195 | return view; 196 | } 197 | } 198 | return nil; 199 | } 200 | 201 | - (NSPopUpButton *)schemePopUpButtonForWindow:(NSWindow *)window 202 | { 203 | OMSchemeSelectionView *container = [self schemePopUpButtonContainerForWindow:window]; 204 | return container.popUpButton; 205 | } 206 | 207 | - (OMSchemeSelectionView *)schemePopUpButtonContainerForWindow:(NSWindow *)window 208 | { 209 | if ([window isKindOfClass:NSClassFromString(@"IDEWorkspaceWindow")]) { 210 | NSView *windowFrameView = [[window contentView] superview]; 211 | OMSchemeSelectionView *popUpContainerView = [windowFrameView viewWithTag:SCHEME_POPUP_BUTTON_CONTAINER_TAG]; 212 | if (!popUpContainerView) { 213 | 214 | CGFloat buttonWidth = 300.0; 215 | // NSView *titleView = [self windowTitleViewForWindow:window]; 216 | // if (titleView) { 217 | // buttonWidth = MIN(buttonWidth, titleView.frame.origin.x - 10 - 80); 218 | // } 219 | 220 | popUpContainerView = [[OMSchemeSelectionView alloc] initWithFrame:NSMakeRect(70, windowFrameView.bounds.size.height - 22, buttonWidth + 174, 20)]; 221 | popUpContainerView.tag = SCHEME_POPUP_BUTTON_CONTAINER_TAG; 222 | popUpContainerView.autoresizingMask = NSViewMinYMargin; 223 | 224 | BOOL toolbarVisible = [[window toolbar] isVisible]; 225 | BOOL titleBarDisabled = [[NSUserDefaults standardUserDefaults] boolForKey:kOMMiniXcodeDisableSchemeSelectionInTitleBar]; 226 | 227 | [popUpContainerView setHidden:toolbarVisible || titleBarDisabled]; 228 | [windowFrameView addSubview:popUpContainerView]; 229 | 230 | } 231 | return popUpContainerView; 232 | } 233 | return nil; 234 | } 235 | 236 | #pragma mark - window state & splitview callbacks 237 | 238 | - (void)windowDidEndLiveResize:(NSNotification *)notification 239 | { 240 | NSWindow *window = [notification object]; 241 | NSView *schemeView = [self schemePopUpButtonContainerForWindow:window]; 242 | if (schemeView) { 243 | double delayInSeconds = 0.0; 244 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 245 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 246 | [self handleResizeOfWindow:window]; 247 | }); 248 | } 249 | } 250 | 251 | - (void)windowDidBecomeKey:(NSNotification *)notification 252 | { 253 | NSWindow *window = [notification object]; 254 | if ([window isKindOfClass:NSClassFromString(@"IDEWorkspaceWindow")]) { 255 | @try { 256 | NSWindowController *windowController = [window windowController]; 257 | if ([windowController isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) { 258 | id workspace = [windowController valueForKey:@"_workspace"]; 259 | NSNotification *dummyNotification = [NSNotification notificationWithName:@"IDEWorkspaceBuildProductsLocationDidChangeNotification" object:workspace]; 260 | [self buildProductsLocationDidChange:dummyNotification]; 261 | } 262 | } 263 | @catch (NSException *exception) { } 264 | } 265 | } 266 | 267 | - (void)handleResizeOfWindow:(NSWindow*)window 268 | { 269 | NSView *schemeView = [self schemePopUpButtonContainerForWindow:window]; 270 | if (schemeView) { 271 | BOOL titleBarDisabled = [[NSUserDefaults standardUserDefaults] boolForKey:kOMMiniXcodeDisableSchemeSelectionInTitleBar]; 272 | BOOL toolbarVisible = [[window toolbar] isVisible]; 273 | [schemeView setHidden:toolbarVisible || titleBarDisabled]; 274 | // NSView *titleView = [self windowTitleViewForWindow:window]; 275 | // if (titleView) { 276 | // leftMostWidth = MIN(leftMostWidth, titleView.frame.origin.x - 174); 277 | // } 278 | // schemeView.frame = NSMakeRect(schemeView.frame.origin.x, schemeView.frame.origin.y, schemeView.frame.size.width, schemeView.frame.size.height); 279 | } 280 | } 281 | 282 | #pragma mark - build callbacks 283 | 284 | - (void)buildWillStart:(NSNotification *)notification 285 | { 286 | @try { 287 | NSArray *workspaceWindowControllers = [NSClassFromString(@"IDEWorkspaceWindowController") workspaceWindowControllers]; 288 | for (NSWindow *window in [workspaceWindowControllers valueForKey:@"window"]) { 289 | OMSchemeSelectionView *schemeView = [self schemePopUpButtonContainerForWindow:window]; 290 | if (schemeView) { 291 | schemeView.spinner.hidden = NO; 292 | [schemeView resizeSubviewsWithOldSize:schemeView.frame.size]; 293 | [schemeView.spinner startAnimation:nil]; 294 | 295 | _schemeView = schemeView; 296 | [notification.object addObserver:self 297 | forKeyPath:@"percentComplete" 298 | options:0 299 | context:(__bridge void *)(schemeView)]; 300 | } 301 | } 302 | } 303 | @catch (NSException *exception) { } 304 | } 305 | 306 | - (void)buildDidStop:(NSNotification *)notification 307 | { 308 | @try { 309 | NSArray *workspaceWindowControllers = [NSClassFromString(@"IDEWorkspaceWindowController") workspaceWindowControllers]; 310 | for (NSWindow *window in [workspaceWindowControllers valueForKey:@"window"]) { 311 | OMSchemeSelectionView *schemeView = [self schemePopUpButtonContainerForWindow:window]; 312 | if (schemeView) { 313 | [schemeView.spinner stopAnimation:nil]; 314 | schemeView.spinner.hidden = YES; 315 | [schemeView resizeSubviewsWithOldSize:schemeView.frame.size]; 316 | 317 | [notification.object removeObserver:self 318 | forKeyPath:@"percentComplete" 319 | context:(__bridge void *)(schemeView)]; 320 | _schemeView = nil; 321 | } 322 | } 323 | } 324 | @catch (NSException *exception) { } 325 | } 326 | 327 | - (void)buildProductsLocationDidChange:(NSNotification *)notification 328 | { 329 | @try { 330 | id workspace = [notification object]; 331 | if ([workspace isKindOfClass:NSClassFromString(@"IDEWorkspace")]) { 332 | NSArray *workspaceWindowControllers = [NSClassFromString(@"IDEWorkspaceWindowController") workspaceWindowControllers]; 333 | for (NSWindowController *workspaceWindowController in workspaceWindowControllers) { 334 | id workspaceForWindowController = [workspaceWindowController valueForKey:@"_workspace"]; 335 | if (workspace == workspaceForWindowController) { 336 | NSPopUpButton *popUpButton = [self schemePopUpButtonForWindow:workspaceWindowController.window]; 337 | NSMenu *menu = [[NSMenu alloc] init]; 338 | [menu setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; 339 | 340 | id runContextManager = [workspace valueForKey:@"runContextManager"]; 341 | id activeDestination = [runContextManager valueForKey:@"_activeRunDestination"]; 342 | id activeScheme = [runContextManager valueForKey:@"_activeRunContext"]; 343 | NSArray *runContexts = [runContextManager performSelector:@selector(runContexts)]; 344 | for (id scheme in runContexts) { 345 | NSMenuItem *schemeItem = [[NSMenuItem alloc] initWithTitle:[scheme valueForKey:@"name"] action:@selector(selectRunContext:) keyEquivalent:@""]; 346 | NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:scheme, @"context", nil]; 347 | [schemeItem setRepresentedObject:info]; 348 | if (scheme == activeScheme) { 349 | [schemeItem setState:NSOnState]; 350 | [schemeItem setTitle:[NSString stringWithFormat:@"%@ | %@", [scheme name], [activeDestination displayName]]]; 351 | } else { 352 | [schemeItem setState:NSOffState]; 353 | } 354 | NSArray *destinations = [scheme valueForKey:@"availableRunDestinations"]; 355 | if (destinations.count > 0) { 356 | NSMenu *submenu = [[NSMenu alloc] initWithTitle:@""]; 357 | [schemeItem setSubmenu:submenu]; 358 | for (id destination in destinations) { 359 | NSMenuItem *destinationItem = [[NSMenuItem alloc] initWithTitle:[destination valueForKey:@"fullDisplayName"] action:@selector(selectDestination:) keyEquivalent:@""]; 360 | NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:destination, @"destination", scheme, @"context", nil]; 361 | [destinationItem setRepresentedObject:info]; 362 | [destinationItem setTarget:self]; 363 | [destinationItem setState:(destination == activeDestination) ? NSOnState : NSOffState]; 364 | [submenu addItem:destinationItem]; 365 | } 366 | } 367 | [schemeItem setTarget:self]; 368 | [menu addItem:schemeItem]; 369 | } 370 | [menu addItem:[NSMenuItem separatorItem]]; 371 | NSArray *activeSchemeDestinations = [activeScheme valueForKey:@"availableRunDestinations"]; 372 | for (id destination in activeSchemeDestinations) { 373 | NSMenuItem *destinationItem = [[NSMenuItem alloc] initWithTitle:[destination valueForKey:@"fullDisplayName"] action:@selector(selectDestination:) keyEquivalent:@""]; 374 | NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:destination, @"destination", activeScheme, @"context", nil]; 375 | [destinationItem setRepresentedObject:info]; 376 | [destinationItem setTarget:self]; 377 | [destinationItem setState:(destination == activeDestination) ? NSOnState : NSOffState]; 378 | [menu addItem:destinationItem]; 379 | } 380 | [popUpButton setMenu:menu]; 381 | } 382 | } 383 | } 384 | } 385 | @catch (NSException *exception) { 386 | 387 | } 388 | } 389 | 390 | - (void)build:(id)build progressedForView:(OMSchemeSelectionView*)view { 391 | id complete = [build valueForKey:@"percentComplete"]; 392 | id log = [build valueForKey:@"buildLog"]; 393 | 394 | // build progess string 395 | NSMutableAttributedString *attributedProgress = [[NSMutableAttributedString alloc] init]; 396 | 397 | //err 398 | id number = [log valueForKey:@"totalNumberOfErrors"]; 399 | if([number intValue]) { 400 | [attributedProgress appendAttributedString:[NSAttributedString attributedStringWithImage:_errorImage]]; 401 | [attributedProgress addAttribute:NSBaselineOffsetAttributeName value:@(-2) range:NSMakeRange(attributedProgress.length-1, 1)]; 402 | [attributedProgress appendAttributedString:[NSAttributedString attributedStringWithFormat:@"%@ ", number]]; 403 | } 404 | 405 | //warn 406 | number = [log valueForKey:@"totalNumberOfWarnings"]; 407 | if([number intValue]) { 408 | [attributedProgress appendAttributedString:[NSAttributedString attributedStringWithImage:_warningImage]]; 409 | [attributedProgress addAttribute:NSBaselineOffsetAttributeName value:@(-2) range:NSMakeRange(attributedProgress.length-1, 1)]; 410 | [attributedProgress appendAttributedString:[NSAttributedString attributedStringWithFormat:@"%@ ", number]]; 411 | } 412 | 413 | //analyzer 414 | number = [log valueForKey:@"totalNumberOfAnalyzerWarnings"]; 415 | id number2 = [log valueForKey:@"totalNumberOfAnalyzerResults"]; 416 | number = @([number intValue]+[number2 intValue]); 417 | if([number intValue]) { 418 | [attributedProgress appendAttributedString:[NSAttributedString attributedStringWithImage:_analyzerResultImage]]; 419 | [attributedProgress addAttribute:NSBaselineOffsetAttributeName value:@(-2) range:NSMakeRange(attributedProgress.length-1, 1)]; 420 | [attributedProgress appendAttributedString:[NSAttributedString attributedStringWithFormat:@"%@ ", number]]; 421 | } 422 | 423 | //add percentage if != 100 424 | if([complete intValue]!=100) { 425 | [attributedProgress appendAttributedString:[NSAttributedString attributedStringWithFormat:@"%d%% ", [complete intValue]]]; 426 | } 427 | 428 | view.label.attributedStringValue = attributedProgress; 429 | } 430 | 431 | #pragma mark build progress monitor via KVO 432 | 433 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 434 | @try { 435 | if([keyPath isEqualToString:@"percentComplete"]) { 436 | [self build:object progressedForView:(__bridge OMSchemeSelectionView *)(context)]; 437 | } 438 | else { 439 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 440 | } 441 | } 442 | @catch (NSException *exception) { 443 | 444 | } 445 | } 446 | 447 | 448 | @end 449 | -------------------------------------------------------------------------------- /Classes/OMSchemeSelectionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // OMSchemeSelectionView.h 3 | // OMMiniXcode 4 | // 5 | // Created by Ole Zorn on 10.09.12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface OMSchemeSelectionView : NSView { 12 | 13 | NSPopUpButton *_popUpButton; 14 | NSProgressIndicator *_spinner; 15 | NSTextField *_label; 16 | NSInteger _tag; 17 | } 18 | 19 | @property (nonatomic, strong) NSPopUpButton *popUpButton; 20 | @property (nonatomic, strong) NSProgressIndicator *spinner; 21 | @property (nonatomic, strong) NSTextField *label; 22 | @property (nonatomic, assign) NSInteger tag; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Classes/OMSchemeSelectionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // OMSchemeSelectionView.m 3 | // OMMiniXcode 4 | // 5 | // Created by Ole Zorn on 10.09.12. 6 | // 7 | // 8 | 9 | #import "OMSchemeSelectionView.h" 10 | 11 | @implementation OMSchemeSelectionView 12 | 13 | @synthesize popUpButton=_popUpButton, tag=_tag, spinner=_spinner, label=_label; 14 | 15 | - (id)initWithFrame:(NSRect)frame 16 | { 17 | self = [super initWithFrame:frame]; 18 | if (self) { 19 | _popUpButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, frame.size.width - 174, 20)]; 20 | _popUpButton.autoresizingMask = NSViewWidthSizable; 21 | 22 | [_popUpButton setBezelStyle:NSTexturedRoundedBezelStyle]; 23 | [[_popUpButton cell] setControlSize:NSSmallControlSize]; 24 | [_popUpButton setFont:[NSFont systemFontOfSize:11.0]]; 25 | [self addSubview:_popUpButton]; 26 | 27 | _spinner = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(NSMaxX(self.bounds) - 170, 2, 16, 16)]; 28 | [_spinner setControlSize:NSSmallControlSize]; 29 | _spinner.autoresizingMask = NSViewMinXMargin; 30 | [_spinner setStyle:NSProgressIndicatorSpinningStyle]; 31 | [_spinner setDisplayedWhenStopped:NO]; 32 | [_spinner setHidden:YES]; 33 | [self addSubview:_spinner]; 34 | 35 | _label = [[NSTextField alloc] initWithFrame:NSMakeRect(NSMaxX(self.bounds) - 170, 2, 170, 16)]; 36 | _label.autoresizingMask = NSViewMinXMargin; 37 | [_label setBezeled:NO]; 38 | [_label setDrawsBackground:NO]; 39 | [_label setEditable:NO]; 40 | [_label setSelectable:NO]; 41 | [_popUpButton setFont:[NSFont systemFontOfSize:11.0]]; 42 | [self addSubview:_label]; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize 48 | { 49 | [super resizeSubviewsWithOldSize:oldBoundsSize]; 50 | 51 | self.popUpButton.frame = NSMakeRect(0, 0, NSMaxX(self.bounds) - 174, NSMaxY(self.bounds)); 52 | self.spinner.frame = NSMakeRect(NSMaxX(self.bounds) - 170, 2, 16, 16); 53 | 54 | CGFloat size = self.spinner.isHidden ? 170 : 150; 55 | self.label.frame = NSMakeRect(NSMaxX(self.bounds) - size, 2, size, 16); 56 | } 57 | 58 | - (BOOL)isOpaque 59 | { 60 | return NO; 61 | } 62 | 63 | - (NSView *)hitTest:(NSPoint)aPoint 64 | { 65 | //Ignore mouse events for the spinner or the label 66 | return [self.popUpButton hitTest:[self convertPoint:aPoint fromView:self.superview]]; 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daij-Djan/MiniXcode/08ac43e6f96f476f1ee88821e88c0ecd0b705070/Icon.png -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.omz-software.${PRODUCT_NAME:identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | ${CURRENT_PROJECT_VERSION} 19 | CFBundleVersion 20 | ${CURRENT_PROJECT_VERSION} 21 | DVTPlugInCompatibilityUUIDs 22 | 23 | 37B30044-3B14-46BA-ABAA-F01000C27B63 24 | A2E4D43F-41F4-4FB9-BB94-7177011C9AED 25 | 26 | NSPrincipalClass 27 | OMMiniXcode 28 | XC4Compatible 29 | 30 | XC5Compatible 31 | 32 | XCGCReady 33 | 34 | XCPluginHasUI 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Dominik Pich 2 | Copyright (c) 2012, Ole Zorn 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /OMMiniXcode.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7F2EB89C145057F200E97A87 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F2EB899145057EA00E97A87 /* AppKit.framework */; }; 11 | 7FFE01F215FE1B3300CB8659 /* OMSchemeSelectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FFE01F115FE1B3300CB8659 /* OMSchemeSelectionView.m */; }; 12 | B481E523181D353300C153EC /* NSString+size.m in Sources */ = {isa = PBXBuildFile; fileRef = B481E522181D353300C153EC /* NSString+size.m */; }; 13 | B482911A1607D7A400D20D8F /* NSAttributedString+DDConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = B48291191607D7A400D20D8F /* NSAttributedString+DDConvenience.m */; }; 14 | B49EF6911607E0D900CE06FF /* XCBuildErrorIcon.tiff in CopyFiles */ = {isa = PBXBuildFile; fileRef = B48291141607D3CC00D20D8F /* XCBuildErrorIcon.tiff */; }; 15 | B49EF6921607E0D900CE06FF /* XCBuildSuccessIcon.tiff in CopyFiles */ = {isa = PBXBuildFile; fileRef = B48291151607D3CC00D20D8F /* XCBuildSuccessIcon.tiff */; }; 16 | B49EF6931607E0D900CE06FF /* XCBuildAnalyzerResultIcon.tiff in CopyFiles */ = {isa = PBXBuildFile; fileRef = B48291171607D53200D20D8F /* XCBuildAnalyzerResultIcon.tiff */; }; 17 | B49EF6941607E0D900CE06FF /* XCBuildWarningIcon.tiff in CopyFiles */ = {isa = PBXBuildFile; fileRef = B48291161607D3CC00D20D8F /* XCBuildWarningIcon.tiff */; }; 18 | DA1B5D020E64686800921439 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 089C1672FE841209C02AAC07 /* Foundation.framework */; }; 19 | DA37E2DC0E6291C8001BDFEF /* OMMiniXcode.m in Sources */ = {isa = PBXBuildFile; fileRef = DA37E2DB0E6291C8001BDFEF /* OMMiniXcode.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXCopyFilesBuildPhase section */ 23 | B49EF68F1607E0A600CE06FF /* CopyFiles */ = { 24 | isa = PBXCopyFilesBuildPhase; 25 | buildActionMask = 2147483647; 26 | dstPath = ""; 27 | dstSubfolderSpec = 7; 28 | files = ( 29 | B49EF6911607E0D900CE06FF /* XCBuildErrorIcon.tiff in CopyFiles */, 30 | B49EF6921607E0D900CE06FF /* XCBuildSuccessIcon.tiff in CopyFiles */, 31 | B49EF6931607E0D900CE06FF /* XCBuildAnalyzerResultIcon.tiff in CopyFiles */, 32 | B49EF6941607E0D900CE06FF /* XCBuildWarningIcon.tiff in CopyFiles */, 33 | ); 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXCopyFilesBuildPhase section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 40 | 7F2B355F15FA59D000DB3249 /* OMMiniXcode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OMMiniXcode.h; sourceTree = ""; }; 41 | 7F2EB899145057EA00E97A87 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 42 | 7FFE01F015FE1B3300CB8659 /* OMSchemeSelectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OMSchemeSelectionView.h; sourceTree = ""; }; 43 | 7FFE01F115FE1B3300CB8659 /* OMSchemeSelectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OMSchemeSelectionView.m; sourceTree = ""; }; 44 | 8D5B49B6048680CD000E48DA /* OMMiniXcode.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OMMiniXcode.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | B481E521181D353300C153EC /* NSString+size.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+size.h"; sourceTree = ""; }; 47 | B481E522181D353300C153EC /* NSString+size.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+size.m"; sourceTree = ""; }; 48 | B48291141607D3CC00D20D8F /* XCBuildErrorIcon.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = XCBuildErrorIcon.tiff; path = Resources/XCBuildErrorIcon.tiff; sourceTree = ""; }; 49 | B48291151607D3CC00D20D8F /* XCBuildSuccessIcon.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = XCBuildSuccessIcon.tiff; path = Resources/XCBuildSuccessIcon.tiff; sourceTree = ""; }; 50 | B48291161607D3CC00D20D8F /* XCBuildWarningIcon.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = XCBuildWarningIcon.tiff; path = Resources/XCBuildWarningIcon.tiff; sourceTree = ""; }; 51 | B48291171607D53200D20D8F /* XCBuildAnalyzerResultIcon.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = XCBuildAnalyzerResultIcon.tiff; path = Resources/XCBuildAnalyzerResultIcon.tiff; sourceTree = ""; }; 52 | B48291181607D7A400D20D8F /* NSAttributedString+DDConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+DDConvenience.h"; sourceTree = ""; }; 53 | B48291191607D7A400D20D8F /* NSAttributedString+DDConvenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+DDConvenience.m"; sourceTree = ""; }; 54 | DA37E2DB0E6291C8001BDFEF /* OMMiniXcode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OMMiniXcode.m; sourceTree = ""; }; 55 | /* End PBXFileReference section */ 56 | 57 | /* Begin PBXFrameworksBuildPhase section */ 58 | 8D5B49B3048680CD000E48DA /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | DA1B5D020E64686800921439 /* Foundation.framework in Frameworks */, 63 | 7F2EB89C145057F200E97A87 /* AppKit.framework in Frameworks */, 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXFrameworksBuildPhase section */ 68 | 69 | /* Begin PBXGroup section */ 70 | 089C166AFE841209C02AAC07 /* QuietXcode */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 7F411B0C15FABAC6002F77B6 /* Classes */, 74 | 089C167CFE841241C02AAC07 /* Resources */, 75 | 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, 76 | 19C28FB8FE9D52D311CA2CBB /* Products */, 77 | ); 78 | name = QuietXcode; 79 | sourceTree = ""; 80 | }; 81 | 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 7F2EB899145057EA00E97A87 /* AppKit.framework */, 85 | 089C1672FE841209C02AAC07 /* Foundation.framework */, 86 | ); 87 | name = "Frameworks and Libraries"; 88 | sourceTree = ""; 89 | }; 90 | 089C167CFE841241C02AAC07 /* Resources */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | B48291141607D3CC00D20D8F /* XCBuildErrorIcon.tiff */, 94 | B48291151607D3CC00D20D8F /* XCBuildSuccessIcon.tiff */, 95 | B48291171607D53200D20D8F /* XCBuildAnalyzerResultIcon.tiff */, 96 | B48291161607D3CC00D20D8F /* XCBuildWarningIcon.tiff */, 97 | 8D5B49B7048680CD000E48DA /* Info.plist */, 98 | ); 99 | name = Resources; 100 | sourceTree = ""; 101 | }; 102 | 19C28FB8FE9D52D311CA2CBB /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 8D5B49B6048680CD000E48DA /* OMMiniXcode.xcplugin */, 106 | ); 107 | name = Products; 108 | sourceTree = ""; 109 | }; 110 | 7F411B0C15FABAC6002F77B6 /* Classes */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 7F2B355F15FA59D000DB3249 /* OMMiniXcode.h */, 114 | DA37E2DB0E6291C8001BDFEF /* OMMiniXcode.m */, 115 | 7FFE01F015FE1B3300CB8659 /* OMSchemeSelectionView.h */, 116 | 7FFE01F115FE1B3300CB8659 /* OMSchemeSelectionView.m */, 117 | B48291181607D7A400D20D8F /* NSAttributedString+DDConvenience.h */, 118 | B48291191607D7A400D20D8F /* NSAttributedString+DDConvenience.m */, 119 | B481E521181D353300C153EC /* NSString+size.h */, 120 | B481E522181D353300C153EC /* NSString+size.m */, 121 | ); 122 | path = Classes; 123 | sourceTree = ""; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXNativeTarget section */ 128 | 8D5B49AC048680CD000E48DA /* OMMiniXcode */ = { 129 | isa = PBXNativeTarget; 130 | buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "OMMiniXcode" */; 131 | buildPhases = ( 132 | 8D5B49B1048680CD000E48DA /* Sources */, 133 | 8D5B49B3048680CD000E48DA /* Frameworks */, 134 | B49EF68F1607E0A600CE06FF /* CopyFiles */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = OMMiniXcode; 141 | productInstallPath = "$(HOME)/Library/Bundles"; 142 | productName = QuietXcode; 143 | productReference = 8D5B49B6048680CD000E48DA /* OMMiniXcode.xcplugin */; 144 | productType = "com.apple.product-type.bundle"; 145 | }; 146 | /* End PBXNativeTarget section */ 147 | 148 | /* Begin PBXProject section */ 149 | 089C1669FE841209C02AAC07 /* Project object */ = { 150 | isa = PBXProject; 151 | attributes = { 152 | LastUpgradeCheck = 0440; 153 | }; 154 | buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "OMMiniXcode" */; 155 | compatibilityVersion = "Xcode 3.2"; 156 | developmentRegion = English; 157 | hasScannedForEncodings = 1; 158 | knownRegions = ( 159 | English, 160 | Japanese, 161 | French, 162 | German, 163 | ); 164 | mainGroup = 089C166AFE841209C02AAC07 /* QuietXcode */; 165 | projectDirPath = ""; 166 | projectRoot = ""; 167 | targets = ( 168 | 8D5B49AC048680CD000E48DA /* OMMiniXcode */, 169 | ); 170 | }; 171 | /* End PBXProject section */ 172 | 173 | /* Begin PBXSourcesBuildPhase section */ 174 | 8D5B49B1048680CD000E48DA /* Sources */ = { 175 | isa = PBXSourcesBuildPhase; 176 | buildActionMask = 2147483647; 177 | files = ( 178 | B481E523181D353300C153EC /* NSString+size.m in Sources */, 179 | DA37E2DC0E6291C8001BDFEF /* OMMiniXcode.m in Sources */, 180 | 7FFE01F215FE1B3300CB8659 /* OMSchemeSelectionView.m in Sources */, 181 | B482911A1607D7A400D20D8F /* NSAttributedString+DDConvenience.m in Sources */, 182 | ); 183 | runOnlyForDeploymentPostprocessing = 0; 184 | }; 185 | /* End PBXSourcesBuildPhase section */ 186 | 187 | /* Begin XCBuildConfiguration section */ 188 | 1DEB913B08733D840010E9CD /* Debug */ = { 189 | isa = XCBuildConfiguration; 190 | buildSettings = { 191 | ALWAYS_SEARCH_USER_PATHS = NO; 192 | CLANG_ENABLE_OBJC_ARC = YES; 193 | COMBINE_HIDPI_IMAGES = YES; 194 | COPY_PHASE_STRIP = NO; 195 | DEPLOYMENT_LOCATION = YES; 196 | DEPLOYMENT_POSTPROCESSING = YES; 197 | DSTROOT = "$(HOME)"; 198 | GCC_DYNAMIC_NO_PIC = NO; 199 | GCC_OPTIMIZATION_LEVEL = 0; 200 | INFOPLIST_FILE = Info.plist; 201 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 202 | LD_RUNPATH_SEARCH_PATHS = /Developer; 203 | PRODUCT_NAME = OMMiniXcode; 204 | STRIP_INSTALLED_PRODUCT = NO; 205 | WRAPPER_EXTENSION = xcplugin; 206 | }; 207 | name = Debug; 208 | }; 209 | 1DEB913F08733D840010E9CD /* Debug */ = { 210 | isa = XCBuildConfiguration; 211 | buildSettings = { 212 | ARCHS = "$(ARCHS_STANDARD)"; 213 | CLANG_ENABLE_OBJC_ARC = NO; 214 | CURRENT_PROJECT_VERSION = 1.0.1; 215 | GCC_C_LANGUAGE_STANDARD = c99; 216 | GCC_OPTIMIZATION_LEVEL = 0; 217 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 218 | GCC_WARN_UNUSED_VARIABLE = YES; 219 | INSTALL_PATH = "$(HOME)/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 220 | SDKROOT = macosx; 221 | }; 222 | name = Debug; 223 | }; 224 | /* End XCBuildConfiguration section */ 225 | 226 | /* Begin XCConfigurationList section */ 227 | 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "OMMiniXcode" */ = { 228 | isa = XCConfigurationList; 229 | buildConfigurations = ( 230 | 1DEB913B08733D840010E9CD /* Debug */, 231 | ); 232 | defaultConfigurationIsVisible = 0; 233 | defaultConfigurationName = Debug; 234 | }; 235 | 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "OMMiniXcode" */ = { 236 | isa = XCConfigurationList; 237 | buildConfigurations = ( 238 | 1DEB913F08733D840010E9CD /* Debug */, 239 | ); 240 | defaultConfigurationIsVisible = 0; 241 | defaultConfigurationName = Debug; 242 | }; 243 | /* End XCConfigurationList section */ 244 | }; 245 | rootObject = 089C1669FE841209C02AAC07 /* Project object */; 246 | } 247 | -------------------------------------------------------------------------------- /OMMiniXcode.xcodeproj/project.xcworkspace/xcshareddata/OMMiniXcode.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | D6451E7F-199A-42AC-A23A-B377C6A0D3DD 9 | IDESourceControlProjectName 10 | OMMiniXcode 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | F2FAE469-328F-4A9A-B9B4-7F13DDE80DB4 14 | ssh://github.com/Daij-Djan/MiniXcode.git 15 | 16 | IDESourceControlProjectPath 17 | OMMiniXcode.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | F2FAE469-328F-4A9A-B9B4-7F13DDE80DB4 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://github.com/Daij-Djan/MiniXcode.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | F2FAE469-328F-4A9A-B9B4-7F13DDE80DB4 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | F2FAE469-328F-4A9A-B9B4-7F13DDE80DB4 36 | IDESourceControlWCCName 37 | MiniXcode 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mini Xcode Plugin 2 | 3 | ## Overview 4 | 5 | This is a plugin that makes it easier to run Xcode without the main toolbar. It adds keyboard shortcuts for selecting the active scheme and device (`Ctrl`+`7` / `Ctrl` + `8`), and a compact popup menu in the window title bar that shows the currently selected run configuration. 6 | 7 | While building a target, a circular spinner, the current progress (%) and all eventual errors, warnings and analyzer results are shown. 8 | 9 | You can disable the popup from the _View_ menu if you find it distracting, the keyboard shortcuts will also work without it. The popup is automatically hidden when the main toolbar is visible. 10 | 11 | ![Screenshot](https://raw.githubusercontent.com/Daij-Djan/MiniXcode/master/Screenshot.png) 12 | ![Screenshot](https://raw.githubusercontent.com/Daij-Djan/MiniXcode/master/Screenshot2.png) 13 | 14 | ## Installation 15 | 16 | Simply build the Xcode project and restart Xcode. The plugin will automatically be installed in `~/Library/Application Support/Developer/Shared/Xcode/Plug-ins`. To uninstall, just remove the plugin from there (and restart Xcode). 17 | 18 | This is tested on OS X 10.8 with Xcode 4.4.1 and 4.5.0 19 | 20 | ## License 21 | 22 | Copyright (c) 2012, Ole Zorn 23 | All rights reserved. 24 | 25 | Redistribution and use in source and binary forms, with or without 26 | modification, are permitted provided that the following conditions are met: 27 | 28 | * Redistributions of source code must retain the above copyright notice, this 29 | list of conditions and the following disclaimer. 30 | 31 | * Redistributions in binary form must reproduce the above copyright notice, 32 | this list of conditions and the following disclaimer in the documentation 33 | and/or other materials provided with the distribution. 34 | 35 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 36 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 37 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 39 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 40 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 41 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 42 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 43 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 44 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 | -------------------------------------------------------------------------------- /Resources/XCBuildAnalyzerResultIcon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daij-Djan/MiniXcode/08ac43e6f96f476f1ee88821e88c0ecd0b705070/Resources/XCBuildAnalyzerResultIcon.tiff -------------------------------------------------------------------------------- /Resources/XCBuildErrorIcon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daij-Djan/MiniXcode/08ac43e6f96f476f1ee88821e88c0ecd0b705070/Resources/XCBuildErrorIcon.tiff -------------------------------------------------------------------------------- /Resources/XCBuildSuccessIcon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daij-Djan/MiniXcode/08ac43e6f96f476f1ee88821e88c0ecd0b705070/Resources/XCBuildSuccessIcon.tiff -------------------------------------------------------------------------------- /Resources/XCBuildWarningIcon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daij-Djan/MiniXcode/08ac43e6f96f476f1ee88821e88c0ecd0b705070/Resources/XCBuildWarningIcon.tiff -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daij-Djan/MiniXcode/08ac43e6f96f476f1ee88821e88c0ecd0b705070/Screenshot.png -------------------------------------------------------------------------------- /Screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daij-Djan/MiniXcode/08ac43e6f96f476f1ee88821e88c0ecd0b705070/Screenshot2.png --------------------------------------------------------------------------------