Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Updated look & feel #19

Merged
merged 5 commits into from

2 participants

@c-alpha

Visible changes:

  • Look & feel is now exactly as was Apple's old battery gauge

  • Using hi-res artwork to draw the capacity bar

Under the hood:

  • Images are loaded only once at startup and cached
c-alpha added some commits
@c-alpha c-alpha Changed look to match old Apple battery gauge exactly.
Images are loaded only once at startup and cached.
5e259b1
@c-alpha c-alpha Changed look to match old Apple battery gauge exactly.
Images are loaded only once at startup and cached.
0fe0ba1
@c-alpha c-alpha Merge branch 'master' of https://github.com/c-alpha/Battery-Time-Rema…
…ining

Conflicts:
	Battery Time Remaining/AppDelegate.m
8d4a401
@c-alpha

Sorry for the confusion about the commits after the pull request. I had forgotten to change the limit value for drawing a red capacity bar back to 15% from my debugging value.

@codler
Owner

There is some points I would like to say.

aside from that it was good improvements you made

@c-alpha

First of all, thanks a lot for the quick review and kind comments!

I think paranthesis around the time are not needed

That was the way Apple's pre-ML battery gauge did it. I also felt that the parentheses helped me
to visually discern the battery time from the clock, as it has the same composition of digits
and the colon (":"). Which might be why Apple put them there in the first place? Your mileage
may vary, of course. Maybe a candidate for a configurable option? I'll look into making it into one.

and also "Not charging"-text. When it is fully charged it will change battery icon (v1.5 have
a bug which dont change the icon, but this is already fixed for next release). This will also
save space in menubar which most people want.

Good point. In Apple's pre-ML gauge it would display the "not charging" for the couple of seconds
it takes to switch the power source and put the battery to charging mode, when you connect the
charger. Re-reading the code I realise that it will show "not charging" also when fully charged. To
get the pre-ML behaviour, the FSM would need to be extended; like which I don't feel at the
moment. So I rest my case re. the "not charging".

I saw you removed [image setTemplate:YES];. This should not be removed as it fixes white
drop shadow. #5

Hm. With the setTemplate: call, the red capacity bar would be rendered dithered in grey. The
documentation of setTemplate: hints to this:

(...) Images you mark as template images should consist of only black and clear colors. You can
use the alpha channel in the image to adjust the opacity of black content, however. (...)

But maybe it's a consequence of how I compose the image. I'll look for a way of having a red
capacity bar with setTemplate: in place.

The icon is more blocky in retina display. If you dont have retina display you can still test on
your computer. [...]

Thanks for the pointer! I'll check this out.

@codler
Owner

I agree that parenthesis in pre-ML might be to distinguish battery time and clock time, but I don't think it is needed in our case, because you can distinguish by:

  • As third party app this battery time can only be on the left side of the menubar and the clock always on the right side.
  • The font is smaller.

I want to try keep the app as simple as possible for users.


What is FSM?


oh, I didn't notice setTemplate would make the red color grey. Thanks for pointing it out! this is a bug in 1.5.1 then.

@c-alpha c-alpha Fixed blurry battery icon on hi-re displays.
Added setting for switching parentheses around time remaining on and off.
Moved all settings (incl. "advanced") to a submenu.
Added German and French localizations for new menu items.
TODO: Swedish and Dutch localizations missing.
c129b54
@c-alpha

Ok, I believe to have implemented all of your comments (for which thanks), except the setTemplate: issue.
But see more below.

I agree that parenthesis in pre-ML might be to distinguish battery time and clock time, but I
don't think it is needed in our case, because you can distinguish by:
As third party app this battery time can only be on the left side of the menubar and the clock
always on the right side. The font is smaller. I want to try keep the app as simple as possible
for users.

Agreed. I made it a configurable option, and the default is "off".

What is FSM?

Finite state machine. See here. This is used to model the behaviour of the system. E.g. when you connect the charger, it goes from "charging" to "not charging" (the electronics takes a few seconds to switch power and start charging the battery), and then to "charging".

oh, I didn't notice setTemplate would make the red color grey. Thanks for pointing it out!
this is a bug in 1.5.1 then.

Hm, not sure whether it's a bug for your repo. I changed the way the capacity bar is drawn, which may well affect the colour rendering. I will need to dig more to understand why this happens with setTemplate:.

@codler
Owner

It looks good now :)

Just one thing. I get this in my log when I compile

2012-08-25 16:12:39.185 Battery Time Remaining[3830:303] It does not make sense to draw an image when [NSGraphicsContext currentContext] is nil. This is a programming error. Break on void _NSWarnForDrawingImageWithNoCurrentContext() to debug. This will be logged only once. This may break in the future.

@c-alpha

It looks good now :)

Glad you like it. ;-))

Just one thing. I get this in my log when I compile
[...]

I get the same message when I run it. But not always. I have googled for the error message both on the Interwebs, and the Apple developer forums. There are some others who have seen the same message in various contexts. It seems that on most occasions, the issue is linked to legacy code using lockFocus and unlockFocus being deployed on ML. Although this is officially supported (when using drawInRect:fromRect:operation:fraction:), it seems that there are situations where this doesn't play with the new, multi-threaded drawing architecture in ML. Plus we are in a special situation being an NSStatusItem where we don't have an NSView to get around said issues.

It seems that when I start/stop our app very often in a short time, the message is more likely to occur. After the message has shown up, if you inspect the graphics, you will find that there are rendering errors (e.g. a red segment used at the end of the capacity bar instead of a black one). Also if I wait a few minutes, the hit "Run" again, without touching anything else, it just works without the message.

So I suspect that it is rather an issue with the environment where our status bar item is hosted. And that we can do very little about it. I guess for NSStatusItems the resources are more limited than for general apps. So I wouldn't be surprised if it were for example not possible to have a video playing in a status bar image. ;-)

As for setTemplate it seems that it is was conceived for toolbar buttons (see here), which reduces my hopes that a template image would be capable of displaying colour. This seems to imply that to get the white shadow, and colour, we would have to roll our own drawEtchedInRect: method, juggling with masks etc.

@codler
Owner

I c, ye I also only get that msg sometimes which makes it harder to debug.

I notice that the native battery icon don't have drop shadow when it shows the red color.


What do this line do? Is it necessary?

[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]

I tested to remove that line and everything seem to still work.

@codler codler merged commit d42f37d into codler:master
@codler
Owner

I found out why we got "_NSWarnForDrawingImageWithNoCurrentContext" in the log. It has to do with this code

NSDrawThreePartImage(NSMakeRect(capBarLeftOffset, capBarTopOffset, capBarLength, capBarHeight),
                        batteryLevelLeft, batteryLevelMiddle, batteryLevelRight,

When capBarLength is shorter than batteryLevelLeft+batteryLevelRight together it will leave no room to render batteryLevelMiddle, thats why we got the output in log. So it wasn't random when the output came, It only came when we had low battery percent left :P Ill fix this tomorrow.

@codler
Owner

I refactor your code :P 9102c77

@c-alpha

1) Thanks a lot for pulling in my code! Glad you liked it.

2) Also thanks for the clean-up. I like it.

3) for discovering the NSDrawThreePartImage() issue. I like your subtle fix, too. ;-))

4) I can confirm your observation of Apple's battery indicator not having the white shadow when in red state. I can also confirm, that even Apple are using setTemplate: themselves to get the white shadow. With a low battery level (say 5%), when you plug/unplug the charger, Apples battery icon is not updated during the "calculating..." phase. After you unplug the charger, they also immediately switch to the capacity bar, but it's grey (i.e. they apply setTemplate on the red capacity bar). Only after the "calculating..." state is left, Apple updates their icon (white shadow is removed and capacity bar becomes red). I have added a fe small updates to adopt this scheme, and even improve on it (capacity bar is rendered as red - when applicable - even during calculating state). See commit commit ff6259daf3 in my fork.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 24, 2012
  1. @c-alpha

    Changed look to match old Apple battery gauge exactly.

    c-alpha authored
    Images are loaded only once at startup and cached.
  2. @c-alpha

    Changed look to match old Apple battery gauge exactly.

    c-alpha authored
    Images are loaded only once at startup and cached.
  3. @c-alpha

    Merge branch 'master' of https://github.com/c-alpha/Battery-Time-Rema…

    c-alpha authored
    …ining
    
    Conflicts:
    	Battery Time Remaining/AppDelegate.m
Commits on Aug 25, 2012
  1. @c-alpha

    Fixed blurry battery icon on hi-re displays.

    c-alpha authored
    Added setting for switching parentheses around time remaining on and off.
    Moved all settings (incl. "advanced") to a submenu.
    Added German and French localizations for new menu items.
    TODO: Swedish and Dutch localizations missing.
  2. @c-alpha
This page is out of date. Refresh to see the latest.
View
2  Battery Time Remaining/AppDelegate.h
@@ -20,6 +20,8 @@
#define kBTRMenuEnergySaverSetting 7
#define kBTRMenuUpdater 8
#define kBTRMenuQuitKey 9
+#define kBTRMenuSettings 10
+#define kBTRMenuParentheses 11
#endif
View
234 Battery Time Remaining/AppDelegate.m
@@ -15,6 +15,11 @@
#import <IOKit/pwr_mgt/IOPMLib.h>
#import <QuartzCore/QuartzCore.h>
+// In Apple's battery gauge, the battery icon is rendered further down from the
+// top than NSStatusItem does it. Hence we add an extra top offset to get the
+// exact same look.
+#define EXTRA_TOP_OFFSET 2.0f
+
// IOPS notification callback on power source change
static void PowerSourceChanged(void * context)
{
@@ -23,6 +28,14 @@ static void PowerSourceChanged(void * context)
[self updateStatusItem];
}
+@interface AppDelegate () {
+ NSDictionary *m_images;
+ BOOL m_showParens;
+}
+- (void)cacheNamedImages;
+- (NSImage *)loadBatteryIconNamed:(NSString *)iconName;
+@end
+
@implementation AppDelegate
@synthesize statusItem, notifications, previousPercent;
@@ -30,7 +43,8 @@ @implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
self.advancedSupported = ([self getAdvancedBatteryInfo] != nil);
-
+ [self cacheNamedImages];
+
// Init notification
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
[self loadNotificationSetting];
@@ -84,14 +98,29 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
[notificationMenu setTag:kBTRMenuNotification];
[notificationMenu setSubmenu:notificationSubmenu];
[notificationMenu setHidden:self.advancedSupported && ![[NSUserDefaults standardUserDefaults] boolForKey:@"advanced"]];
-
+
+ // Build the settings submenu
+ NSMenu *settingsSubmenu = [[NSMenu alloc] initWithTitle:@"Settings Menu"];
// Advanced mode menu item
- NSMenuItem *advancedMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Advanced mode", @"Advanced mode setting") action:@selector(toggleAdvanced:) keyEquivalent:@""];
- [advancedMenu setTag:kBTRMenuAdvanced];
- advancedMenu.target = self;
- advancedMenu.state = ([[NSUserDefaults standardUserDefaults] boolForKey:@"advanced"]) ? NSOnState : NSOffState;
- [advancedMenu setHidden:!self.advancedSupported];
-
+ NSMenuItem *advancedSubmenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Advanced mode", @"Advanced mode setting") action:@selector(toggleAdvanced:) keyEquivalent:@""];
+ [advancedSubmenuItem setTag:kBTRMenuAdvanced];
+ advancedSubmenuItem.target = self;
+ advancedSubmenuItem.state = ([[NSUserDefaults standardUserDefaults] boolForKey:@"advanced"]) ? NSOnState : NSOffState;
+ [advancedSubmenuItem setHidden:!self.advancedSupported];
+ [settingsSubmenu addItem:advancedSubmenuItem];
+ // time display control menu item
+ NSMenuItem *timeFormatSubmenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Time display with braces", @"Time display with braces setting") action:@selector(toggleParentheses:) keyEquivalent:@""];
+ [timeFormatSubmenuItem setTag:kBTRMenuParentheses];
+ timeFormatSubmenuItem.target = self;
+ m_showParens = [[NSUserDefaults standardUserDefaults] boolForKey:@"parentheses"];
+ timeFormatSubmenuItem.state = (m_showParens) ? NSOnState : NSOffState;
+ [settingsSubmenu addItem:timeFormatSubmenuItem];
+
+ // Settings menu item
+ NSMenuItem *settingsMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Settings", @"Settings menuitem") action:nil keyEquivalent:@""];
+ [settingsMenu setTag:kBTRMenuSettings];
+ [settingsMenu setSubmenu:settingsSubmenu];
+
// Updater menu
NSMenuItem *updaterMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Checking for updates…", @"Update menuitem") action:nil keyEquivalent:@""];
[updaterMenu setTag:kBTRMenuUpdater];
@@ -108,7 +137,7 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
[statusBarMenu addItem:startAtLoginMenu];
[statusBarMenu addItem:notificationMenu];
- [statusBarMenu addItem:advancedMenu];
+ [statusBarMenu addItem:settingsMenu];
[statusBarMenu addItem:[NSMenuItem separatorItem]]; // Separator
[statusBarMenu addItemWithTitle:NSLocalizedString(@"Energy Saver Preferences…", @"Open Energy Saver Preferences menuitem") action:@selector(openEnergySaverPreference:) keyEquivalent:@""];
@@ -124,7 +153,7 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
statusItem.highlightMode = YES;
statusItem.menu = statusBarMenu;
[self updateStatusItem];
-
+
// Capture Power Source updates and make sure our callback is called
CFRunLoopSourceRef loop = IOPSNotificationCreateRunLoopSource(PowerSourceChanged, (__bridge void *)self);
CFRunLoopAddSource(CFRunLoopGetCurrent(), loop, kCFRunLoopDefaultMode);
@@ -177,7 +206,10 @@ - (void)updateStatusItem
NSInteger minute = timeTilCharged % 60;
// Return the time remaining string
- [self setStatusBarImage:[self getBatteryIconNamed:@"BatteryCharging"] title:[NSString stringWithFormat:@" %ld:%02ld", hour, minute]];
+ [self setStatusBarImage:[self getBatteryIconNamed:@"BatteryCharging"] title:[NSString stringWithFormat:@" %@%ld:%02ld%@",
+ (m_showParens)?@"(":@"",
+ hour, minute,
+ (m_showParens)?@")":@""]];
}
else
{
@@ -217,8 +249,11 @@ - (void)updateStatusItem
NSInteger minute = (int)timeRemaining % 3600 / 60;
// Return the time remaining string
- [self setStatusBarImage:[self getBatteryIconPercent:self.currentPercent] title:[NSString stringWithFormat:@" %ld:%02ld", hour, minute]];
-
+ [self setStatusBarImage:[self getBatteryIconPercent:self.currentPercent] title:[NSString stringWithFormat:@" %@%ld:%02ld%@",
+ (m_showParens)?@"(":@"",
+ hour, minute,
+ (m_showParens)?@")":@""]];
+
for (NSString *key in self.notifications)
{
if ([[self.notifications valueForKey:key] boolValue] && [key intValue] == self.currentPercent)
@@ -240,17 +275,16 @@ - (void)updateStatusItem
- (void)setStatusBarImage:(NSImage *)image title:(NSString *)title
{
// Image
- [image setTemplate:YES];
[self.statusItem setImage:image];
[self.statusItem setAlternateImage:[self imageInvertColor:image]];
-
+
// Title
NSDictionary *attributedStyle = [NSDictionary dictionaryWithObjectsAndKeys:
- // Font
- [NSFont menuFontOfSize:12.5f],
- NSFontAttributeName,
- nil];
-
+ // Font
+ [NSFont menuFontOfSize:12.0f],
+ NSFontAttributeName,
+ nil];
+
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title attributes:attributedStyle];
self.statusItem.attributedTitle = attributedTitle;
}
@@ -282,44 +316,113 @@ - (NSDictionary *)getMoreAdvancedBatteryInfo
- (NSImage *)getBatteryIconPercent:(NSInteger)percent
{
- // Make dynamic battery icon
- NSImage *batteryDynamic = [self getBatteryIconNamed:@"BatteryEmpty"];
-
- [batteryDynamic lockFocus];
-
- NSRect sourceRect;
- sourceRect.origin = NSZeroPoint;
- sourceRect.origin.x += [batteryDynamic size].width / 100 * 15;
- sourceRect.origin.y += [batteryDynamic size].height / 50 * 15;
- sourceRect.size = [batteryDynamic size];
- sourceRect.size.width -= [batteryDynamic size].width / 100 * 43;
- sourceRect.size.height -= [batteryDynamic size].height / 50 * 30;
-
- sourceRect.size.width -= [batteryDynamic size].width / 100 * (60.f - (60.f / 100.f * percent));
-
- // Set different color at 15 percent
- if (percent > 15)
- {
- [[NSColor blackColor] set];
- }
- else
- {
- [[NSColor redColor] set];
- }
-
- NSRectFill(sourceRect);
-
- [batteryDynamic unlockFocus];
-
- return batteryDynamic;
+ //
+ // Mimic Apple's original battery icon using hires artwork
+ //
+ NSImage *batteryOutline = [self getBatteryIconNamed:@"BatteryEmpty"];
+ NSImage *batteryLevelLeft = nil;
+ NSImage *batteryLevelMiddle = nil;
+ NSImage *batteryLevelRight = nil;
+
+ if (percent > 15) {
+ // draw black capacity bar
+ batteryLevelLeft = [self getBatteryIconNamed:@"BatteryLevelCapB-L"];
+ batteryLevelMiddle = [self getBatteryIconNamed:@"BatteryLevelCapB-M"];
+ batteryLevelRight = [self getBatteryIconNamed:@"BatteryLevelCapB-R"];
+ }
+ else {
+ // draw red capacity bar
+ batteryLevelLeft = [self getBatteryIconNamed:@"BatteryLevelCapR-L"];
+ batteryLevelMiddle = [self getBatteryIconNamed:@"BatteryLevelCapR-M"];
+ batteryLevelRight = [self getBatteryIconNamed:@"BatteryLevelCapR-R"];
+ }
+
+ const CGFloat drawingUnit = [batteryLevelLeft size].width;
+ const CGFloat capBarLeftOffset = 3.0f * drawingUnit;
+ CGFloat capBarHeight = [batteryLevelLeft size].height;
+ CGFloat capBarTopOffset = (([batteryOutline size].height - (EXTRA_TOP_OFFSET * drawingUnit)) - capBarHeight) / 2.0;
+ CGFloat capBarLength = ceil(percent / 8.0f) * drawingUnit; // max width is 13 units
+ if (capBarLength < (2 * drawingUnit)) { capBarLength = 2 * drawingUnit; }
+
+ [batteryOutline lockFocus];
+ [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
+ NSDrawThreePartImage(NSMakeRect(capBarLeftOffset, capBarTopOffset, capBarLength, capBarHeight),
+ batteryLevelLeft, batteryLevelMiddle, batteryLevelRight,
+ NO,
+ NSCompositeCopy,
+ 0.94f,
+ NO);
+ [batteryOutline unlockFocus];
+
+ return batteryOutline;
+}
+
+- (NSImage *)getBatteryIconNamed:(NSString *)iconName {
+ return [m_images objectForKey:iconName];
}
-- (NSImage *)getBatteryIconNamed:(NSString *)iconName
+- (NSImage *)loadBatteryIconNamed:(NSString *)iconName
{
NSString *fileName = [NSString stringWithFormat:@"/System/Library/CoreServices/Menu Extras/Battery.menu/Contents/Resources/%@.pdf", iconName];
return [[NSImage alloc] initWithContentsOfFile:fileName];
}
+- (void)cacheNamedImages {
+ // special treatment for the BatteryCharging, BatteryCharged, and BatteryEmpty images
+ // they need to be shifted down by 1px to be in the same position as Apple's
+ NSSize newSize;
+ NSImage *origImg = nil;
+
+ origImg = [self loadBatteryIconNamed:@"BatteryCharging"];
+ newSize.width = origImg.size.width;
+ newSize.height = origImg.size.height + EXTRA_TOP_OFFSET;
+ NSImage *imgCharging = [[NSImage alloc] initWithSize:newSize];
+ [imgCharging lockFocus];
+ [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
+ [origImg drawInRect:NSMakeRect(0, 0, origImg.size.width, origImg.size.height)
+ fromRect:NSMakeRect(0, 0, origImg.size.width, origImg.size.height)
+ operation:NSCompositeSourceOver
+ fraction:1.0];
+ [imgCharging unlockFocus];
+
+ origImg = [self loadBatteryIconNamed:@"BatteryCharged"];
+ newSize.width = origImg.size.width;
+ newSize.height = origImg.size.height + EXTRA_TOP_OFFSET;
+ NSImage *imgCharged = [[NSImage alloc] initWithSize:newSize];
+ [imgCharged lockFocus];
+ [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
+ [origImg drawInRect:NSMakeRect(0, 0, origImg.size.width, origImg.size.height)
+ fromRect:NSMakeRect(0, 0, origImg.size.width, origImg.size.height)
+ operation:NSCompositeSourceOver
+ fraction:1.0];
+ [imgCharged unlockFocus];
+
+ origImg = [self loadBatteryIconNamed:@"BatteryEmpty"];
+ newSize.width = origImg.size.width;
+ newSize.height = origImg.size.height + EXTRA_TOP_OFFSET;
+ NSImage *imgEmpty = [[NSImage alloc] initWithSize:newSize];
+ [imgEmpty lockFocus];
+ [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
+ [origImg drawInRect:NSMakeRect(0, 0, origImg.size.width, origImg.size.height)
+ fromRect:NSMakeRect(0, 0, origImg.size.width, origImg.size.height)
+ operation:NSCompositeSourceOver
+ fraction:1.0];
+ [imgEmpty unlockFocus];
+
+ // finally construct the dictionary from which we will retrieve the images at runtime
+ m_images = [NSDictionary dictionaryWithObjectsAndKeys:
+ imgCharging, @"BatteryCharging",
+ imgCharged, @"BatteryCharged",
+ imgEmpty, @"BatteryEmpty",
+ [self loadBatteryIconNamed:@"BatteryLevelCapB-L"], @"BatteryLevelCapB-L",
+ [self loadBatteryIconNamed:@"BatteryLevelCapB-M"], @"BatteryLevelCapB-M",
+ [self loadBatteryIconNamed:@"BatteryLevelCapB-R"], @"BatteryLevelCapB-R",
+ [self loadBatteryIconNamed:@"BatteryLevelCapR-L"], @"BatteryLevelCapR-L",
+ [self loadBatteryIconNamed:@"BatteryLevelCapR-M"], @"BatteryLevelCapR-M",
+ [self loadBatteryIconNamed:@"BatteryLevelCapR-R"], @"BatteryLevelCapR-R",
+ nil];
+}
+
- (NSImage *)imageInvertColor:(NSImage *)_image
{
NSImage *image = [_image copy];
@@ -363,18 +466,19 @@ - (void)toggleStartAtLogin:(id)sender
- (void)toggleAdvanced:(id)sender
{
+ NSMenuItem *item = sender;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:@"advanced"])
{
- [self.statusItem.menu itemWithTag:kBTRMenuAdvanced].state = NSOffState;
+ item.state = NSOffState;
[[self.statusItem.menu itemWithTag:kBTRMenuPowerSourceAdvanced] setHidden:YES];
[[self.statusItem.menu itemWithTag:kBTRMenuNotification] setHidden:YES];
[defaults setBool:NO forKey:@"advanced"];
}
else
{
- [self.statusItem.menu itemWithTag:kBTRMenuAdvanced].state = NSOnState;
+ item.state = NSOnState;
[[self.statusItem.menu itemWithTag:kBTRMenuPowerSourceAdvanced] setHidden:NO];
[[self.statusItem.menu itemWithTag:kBTRMenuNotification] setHidden:NO];
[defaults setBool:YES forKey:@"advanced"];
@@ -384,6 +488,28 @@ - (void)toggleAdvanced:(id)sender
[self updateStatusItem];
}
+- (void)toggleParentheses:(id)sender
+{
+ NSMenuItem *item = sender;
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+
+ if ([defaults boolForKey:@"parentheses"])
+ {
+ item.state = NSOffState;
+ m_showParens = NO;
+ [defaults setBool:NO forKey:@"parentheses"];
+ }
+ else
+ {
+ item.state = NSOnState;
+ m_showParens = YES;
+ [defaults setBool:YES forKey:@"parentheses"];
+ }
+ [defaults synchronize];
+
+ [self updateStatusItem];
+}
+
- (void)notify:(NSString *)message
{
NSUserNotification *notification = [[NSUserNotification alloc] init];
@@ -452,7 +578,7 @@ - (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNot
- (void)menuWillOpen:(NSMenu *)menu
{
// Show power source data in menu
- if (self.advancedSupported && [self.statusItem.menu itemWithTag:kBTRMenuAdvanced].state == NSOnState)
+ if (self.advancedSupported && [[self.statusItem.menu itemWithTag:kBTRMenuSettings].submenu itemWithTag:kBTRMenuAdvanced].state == NSOnState)
{
NSDictionary *advancedBatteryInfo = [self getAdvancedBatteryInfo];
NSDictionary *moreAdvancedBatteryInfo = [self getMoreAdvancedBatteryInfo];
View
BIN  Battery Time Remaining/de.lproj/Localizable.strings
Binary file not shown
View
BIN  Battery Time Remaining/en.lproj/Localizable.strings
Binary file not shown
View
BIN  Battery Time Remaining/fr.lproj/Localizable.strings
Binary file not shown
View
BIN  Battery Time Remaining/nl.lproj/Localizable.strings
Binary file not shown
View
BIN  Battery Time Remaining/sv.lproj/Localizable.strings
Binary file not shown
Something went wrong with that request. Please try again.