diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..46ed1ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +RDM.app +SetResX +.DS_Store diff --git a/ResMenuItem.h b/ResMenuItem.h index 12db822..0576871 100644 --- a/ResMenuItem.h +++ b/ResMenuItem.h @@ -10,16 +10,18 @@ static inline CFDictionaryRef CGDisplayModeGetDictionary(CGDisplayModeRef mode) @interface ResMenuItem : NSMenuItem { CGDirectDisplayID _display; - + int modeNum; - + //CGDisplayModeRef _mode; - + float refreshRate; float scale; int colorDepth; int width; int height; + int _w; + int _h; } @@ -40,7 +42,10 @@ static inline CFDictionaryRef CGDisplayModeGetDictionary(CGDisplayModeRef mode) - (int) height; - (float) refreshRate; - (float) scale; +- (int) _w; +- (int) _h; +- (float) aspect; - (NSComparisonResult) compareResMenuItem: (ResMenuItem*) otherItem; -@end \ No newline at end of file +@end diff --git a/ResMenuItem.mm b/ResMenuItem.mm index 38932dc..0ee85ab 100644 --- a/ResMenuItem.mm +++ b/ResMenuItem.mm @@ -18,21 +18,35 @@ - (id) initWithDisplay: (CGDirectDisplayID) display andMode: (modes_D4*) mode modeNum = mode->derived.mode; scale = mode->derived.density; - + width = mode->derived.width; height = mode->derived.height; - + refreshRate = mode->derived.freq; - + colorDepth = (mode->derived.depth == 4) ? 32 : 16; - - + + int a = width; + int b = height; + int t; + while (b != 0) { + t = b; + b = a % b; + a = t; + } + _w = width / a; + _h = height / a; + if (_h == 5) { + _w *= 2; + _h *= 2; + } + NSString* title; if(scale == 2.0f) { if(refreshRate) { - title = [NSString stringWithFormat: @"%d × %d ⚡️, %.0f Hz", width, height, refreshRate]; + title = [NSString stringWithFormat: @"%d × %d, %.0f Hz ⚡️", width, height, refreshRate]; } else { @@ -51,7 +65,7 @@ - (id) initWithDisplay: (CGDirectDisplayID) display andMode: (modes_D4*) mode } } [self setTitle: title]; - + return self; } else @@ -74,16 +88,16 @@ - (void) setTextFormat: (int) textFormat title = [NSString stringWithFormat: @"%d × %d", width, height]; } } - + if(textFormat == 2) { title = [NSString stringWithFormat: @"%.0f Hz", refreshRate]; } if(title) [self setTitle: title]; - - - + + + } - (CGDirectDisplayID) display @@ -111,6 +125,16 @@ - (int) height return height; } +- (int) _w +{ + return _w; +} + +- (int) _h +{ + return _h; +} + - (float) refreshRate { return refreshRate; @@ -121,8 +145,30 @@ - (float) scale return scale; } +- (float) aspect +{ + return float(_w) / _h; +} + - (NSComparisonResult) compareResMenuItem: (ResMenuItem*) otherItem { + { + float aspect = [self aspect]; + float o_aspect = [otherItem aspect]; + if (aspect < o_aspect) + return NSOrderedAscending; + else if (aspect > o_aspect) + return NSOrderedDescending; +// return NSOrderedSame; + } + { + int o_height = [otherItem height]; + if(height < o_height) + return NSOrderedDescending; + else if(height > o_height) + return NSOrderedAscending; +// return NSOrderedSame; + } { int o_width = [otherItem width]; if(width < o_width) @@ -137,14 +183,6 @@ - (NSComparisonResult) compareResMenuItem: (ResMenuItem*) otherItem return NSOrderedDescending; else if(scale > o_scale) return NSOrderedAscending; -// return NSOrderedSame; - } - { - int o_height = [otherItem height]; - if(height < o_height) - return NSOrderedDescending; - else if(height > o_height) - return NSOrderedAscending; // return NSOrderedSame; } { @@ -159,4 +197,4 @@ - (NSComparisonResult) compareResMenuItem: (ResMenuItem*) otherItem } -@end \ No newline at end of file +@end diff --git a/SRApplicationDelegate.mm b/SRApplicationDelegate.mm index 7226fb4..29a5635 100644 --- a/SRApplicationDelegate.mm +++ b/SRApplicationDelegate.mm @@ -33,13 +33,13 @@ - (void) refreshStatusMenu { if(statusMenu) [statusMenu release]; - + statusMenu = [[NSMenu alloc] initWithTitle: @""]; - + uint32_t nDisplays; CGDirectDisplayID displays[0x10]; CGGetOnlineDisplayList(0x10, displays, &nDisplays); - + for(int i=0; i lastRefreshRate))) - { - if(lastAddedItem) - { - [submenu removeItem: lastAddedItem]; - lastAddedItem = nil; - } - [submenu addItem: item]; - lastAddedItem = item; - } + NSMenuItem* aspect; + NSString* title = [NSString stringWithFormat: @"%d:%d", [item _w], [item _h]]; + aspect = [[NSMenuItem alloc] initWithTitle: title action: nil keyEquivalent: @""]; + [aspect setEnabled: NO]; + [submenu addItem: aspect]; } - else - { + + if (!lastAddedItem || [lastAddedItem width] != [item width] || [lastAddedItem height] != [item height]) { [submenu addItem: item]; - lastAddedItem = item; } + lastAddedItem = item; } } - + NSString* title; { if([mainItem scale] == 2.0f) { - title = [NSString stringWithFormat: @"%d × %d ⚡️️", [mainItem width], [mainItem height]]; + title = [NSString stringWithFormat: @"⚡️ %d:%d — %d × %d", [mainItem _w], [mainItem _h], [mainItem width], [mainItem height]]; } else { - title = [NSString stringWithFormat: @"%d × %d", [mainItem width], [mainItem height]]; + title = [NSString stringWithFormat: @"%d:%d — %d × %d", [mainItem _w], [mainItem _h], [mainItem width], [mainItem height]]; } } - - + + NSMenuItem* resolution = [[NSMenuItem alloc] initWithTitle: title action: nil keyEquivalent: @""]; [resolution setSubmenu: submenu]; [submenu release]; [statusMenu addItem: resolution]; [resolution release]; - + [displayMenuItems release]; } - + { NSMutableArray* displayMenuItems = [NSMutableArray new]; ResMenuItem* mainItem = nil; @@ -158,7 +146,7 @@ - (void) refreshStatusMenu if(mainModeNum == j) { mainItem = item; - [item setState: NSOnState]; + [item setState: NSOnState]; } [displayMenuItems addObject: item]; [item release]; @@ -171,8 +159,8 @@ - (void) refreshStatusMenu idealRefreshRate = [mainItem refreshRate]; } [displayMenuItems sortUsingSelector: @selector(compareResMenuItem:)]; - - + + NSMenu* submenu = [[NSMenu alloc] initWithTitle: @""]; for(int j=0; j< [displayMenuItems count]; j++) { @@ -188,7 +176,7 @@ - (void) refreshStatusMenu if(idealRefreshRate) { NSMenuItem* freq = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"%.0f Hz", [mainItem refreshRate]] action: nil keyEquivalent: @""]; - + if([submenu numberOfItems] > 1) { [freq setSubmenu: submenu]; @@ -201,21 +189,21 @@ - (void) refreshStatusMenu [freq release]; } [submenu release]; - + [displayMenuItems release]; - + } - - + + free(modes); - - + + [statusMenu addItem: [NSMenuItem separatorItem]]; } - + [statusMenu addItemWithTitle: @"About RDM" action: @selector(showAbout) keyEquivalent: @""]; - - + + [statusMenu addItemWithTitle: @"Quit" action: @selector(quit) keyEquivalent: @""]; [statusMenu setDelegate: self]; [statusItem setMenu: statusMenu]; @@ -226,10 +214,10 @@ - (void) setMode: (ResMenuItem*) item { CGDirectDisplayID display = [item display]; int modeNum = [item modeNum]; - + SetDisplayModeNum(display, modeNum); /* - + CGDisplayConfigRef config; if (CGBeginDisplayConfiguration(&config) == kCGErrorSuccess) { CGConfigureDisplayWithDisplayMode(config, display, mode, NULL); @@ -242,7 +230,7 @@ - (void) applicationDidFinishLaunching: (NSNotification*) notification { // NSLog(@"Finished launching"); statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength: NSSquareStatusItemLength] retain]; - + NSImage* statusImage = [NSImage imageNamed: @"StatusIcon"]; [statusItem setImage: statusImage]; [statusItem setHighlightMode: YES]; @@ -253,7 +241,7 @@ - (void) applicationDidFinishLaunching: (NSNotification*) notification } [self refreshStatusMenu]; - + } @end