Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save preference to show or hide NSStatusItem

I've got an application which runs as a normal app but also has a NSStausItem. I wanted to implement the ability to set in the preferences a checkbox and when this checkbox is turned on the status item should be shown, but when the checkbox is off the status item should be removed or be invisible.

I found someone facing a similar problem in a forum here: How do you toggle the status item in the menubar on and off using a checkbox?

But the problem I have with this solution is that it does not work as expected. So I make this checkbox and all works fine, but when I open the application a second time the app does not recognize the choice I took at the first run. This is because the checkbox isn't bound to a BOOL or something, the checkbox only has an IBAction, which removes or adds the status item at runtime.

So my question is: how can I make a checkbox in the preferences which allows me to choose whether the status item should show up or not.


Ok actually i tried the following i copied the from the post i gave you the link

In AppDelegate.h :

 NSStatusItem *item;
NSMenu *menu;
IBOutlet NSButton myStatusItemCheckbox;

and then in the Delegate.m :

- (BOOL)createStatusItem
{
NSStatusBar *bar = [NSStatusBar systemStatusBar];

//Replace NSVariableStatusItemLength with NSSquareStatusItemLength if you
//want the item to be square
item = [bar statusItemWithLength:NSVariableStatusItemLength];

if(!item)
  return NO;

//As noted in the docs, the item must be retained as the receiver does not 
//retain the item, so otherwise will be deallocated
[item retain];

//Set the properties of the item
[item setTitle:@"MenuItem"];
[item setHighlightMode:YES];

//If you want a menu to be shown when the user clicks on the item
[item setMenu:menu]; //Assuming 'menu' is a pointer to an NSMenu instance

return YES;
}


- (void)removeStatusItem
{
NSStatusBar *bar = [NSStatusBar systemStatusBar];
[bar removeStatusItem:item];
[item release];
}


- (IBAction)toggleStatusItem:(id)sender
{
BOOL checked = [sender state];

if(checked) {
  BOOL createItem = [self createStatusItem];
  if(!createItem) {
    //Throw an error
    [sender setState:NO];
  }
}
else
  [self removeStatusItem];
}

then in the IBaction i added this one :

[[NSUserDefaults standardUserDefaults] setInteger:[sender state]
                                               forKey:@"MyApp_ShouldShowStatusItem"];

and in my awakefromnib i added this one : `

NSInteger statusItemState = [[NSUserDefaults standardUserDefaults] integerForKey:@"MyApp_ShouldShowStatusItem"];
 [myStatusItemCheckbox setState:statusItemState];

Then in the interface builder i created a new checkbox connected it with "myStatusItemCheckbox" and added an IBaction also i clicked on the bindings inspector and set in the value the following bind to : NSUserDefaultController and as ModelKeyPath i set: MyApp_ShouldShowStatusItem. Unfortunately this doesnt work at all what am i doing wrong ?

like image 573
dehlen Avatar asked Feb 24 '23 10:02

dehlen


1 Answers

What you need to do is to use the User Defaults system. It makes it very easy to save and load preferences.

In the button's action, you will save its state:

- (IBAction)toggleStatusItem:(id)sender {

    // Your existing code...

    // A button's state is actually an NSInteger, not a BOOL, but
    // you can save it that way if you prefer
    [[NSUserDefaults standardUserDefaults] setInteger:[sender state]
                                               forKey:@"MyApp_ShouldShowStatusItem"];
}

and in your app delegate's (or another appropriate object) awakeFromNib, you will read that value back out of the user defaults:

 NSInteger statusItemState = [[NSUserDefaults standardUserDefaults] integerForKey:@"MyApp_ShouldShowStatusItem"];
 [myStatusItemCheckbox setState:statusItemState];

and then make sure to call removeStatusItem if neccessary.

This procedure will apply to almost any preference you might want to save.

like image 127
jscs Avatar answered Mar 06 '23 21:03

jscs