0

I have an application that has two types of interfaces - it exists as a menubar application and a windowed application. However it cannot exist simultaneously in both states.

How can I allow the user to click on a button that allows him/her to change states?

For example if my application is currently a window, when the user clicks on the button I want it to change into a menubar application and the window should disappear. However if the user clicks again all menubar info should disappear and the window should reappear.

The application is very system heavy therefore I cannot afford for the menubar version and the windowed version to work simultaneously.

How would I accomplish this?

I am working on OSX Mountain Lion and need a solution in Objective-C/C.

fdh
  • 5,142
  • 11
  • 55
  • 101
  • 1
    I can understand the *application* being 'very system heavy', but that doesn't preclude you from allowing the UI to run in two different modes. (With a shared core.) I think breaking this into two applications is the more complicated approach. Why not hide/show the menubar in one mode, and hide/show the window in the other mode? – Craig Otis Sep 13 '12 at 18:27
  • I agree with craig. You need to implement high & show menu bar as per your need. – ManthanDalal Sep 15 '12 at 10:00
  • @craig Could you post an example show how I would go about doing this? – fdh Sep 15 '12 at 17:30
  • @FarhadYusufali How about giving it a shot yourself, and coming back with any questions/problems you encounter? There are lots of resources available, many of them right here on SO. For example: http://stackoverflow.com/questions/3409985/how-to-create-a-menubar-application-for-mac – Craig Otis Sep 15 '12 at 20:49
  • @craig I checked out the link and was able to create a basic menu bar application. Two questions though: 1) How would I switch between the UIs? ( Disable one and enable the other) – fdh Sep 15 '12 at 21:27
  • 2) I have several objects in my window that I also have in my menubar application. Rather than creating brand new outlets for them, can I switch my outlets to new objects when the UI is changed? For example I have a textbox in my Menubar application and a textbox in my window application that show the same output. Rather than having two outlets(1 per box) can I have 1 outlet that switches what it points at depending on the UI? (if in window mode, point at the window textbox otherwise point at the Menubar textbox). Or is having two separate outlets my only option? – fdh Sep 15 '12 at 21:28
  • Unless they're the exact same text box, you need two separate outlets. You can write a helper method that accepts an `NSString` parameter that you can call from the different UIs to share the common code, but it's never a good idea to reassign an IBOutlet. Keep the UI code separate, and the business logic shared. (as much as possible) – Craig Otis Sep 16 '12 at 16:46
  • @craig I see. How about question one? How do I switch between UIs? In other words how do I disable one and enable another at the click of a button? – fdh Sep 16 '12 at 16:51

2 Answers2

1

Assuming that you know how to display your UI in a NSWindow and separately in a NSStatusItem, then you can "switch" from one UI to the other by:

  1. hiding the NSWindow and showing the NSStatusItem; or

  2. hiding the NSStatusItem and showing the NSWindow.

You can hidea NSWindow by using: -(void)orderOut:, and you can restore its visibility by using: -(void)orderFront:.

As to your NSStatusItem, you can create (see: –statusItemWithLength:)and remove it (see: – removeStatusItem:) when required.

EDIT:

if you need to do anything on the UI elements inside of the NSWindow, you can do that by iterating over them:

for(NSView* view in [[window contentView] subviews])
{
   [view ...];
}

If your NSWindow content is made of NSControls, you can disable them like this:

for(NSView* currentView in [[window contentView] subviews]) {

    if( [currentView respondsToSelector:@selector(setEnabled:)] )
    {
        [(NSControl*)currentView setEnabled:NO];
    }
}

If you have a complex hierarchy of controls, you can create a method and call it recursively.

sergio
  • 68,479
  • 11
  • 101
  • 120
  • Does -(void) orderOut disable any IBOutlets associated with the window or it's contents? If not, how would I disable all outlets when I hide the window and then reenable all outlets when I show the window again? – fdh Sep 16 '12 at 18:47
  • I don't think anything will be disabled, only, the `NSWindow` will not be displayed. If you need to modify any element inside of the NSWindow, you can do as per my edit. – sergio Sep 16 '12 at 18:57
1

However it cannot exist simultaneously in both states.

Why not? I suggest considering a different approach where you separate what the app does of how it's presented to the user. This way the system heavy code run just once in a controller and both the window and the status bar item can visualise the operation progress or result or whatever you want to show.

A usual practice is to use the status bar item to toggle window visibility or show a menu to control the main window. But you can use it to show different app states (kind of notifications) with small color variations (black and white preferred) or different images, or to show a popover with a simplified version of the windowed interface when the main window is hidden, etc.

When the user closes or shows the window it doesn't have to affect the main app operations. It just hide that specific view of the progress/results. Add specific buttons or menu items to pause/stop/start the operations.

djromero
  • 19,431
  • 4
  • 69
  • 67