SFML community forums

Help => General => Topic started by: zenroth on May 15, 2012, 03:35:54 am

Title: Mac Menubar
Post by: zenroth on May 15, 2012, 03:35:54 am
Anyways to make this actually functional or add entries to it?

Title: Re: Mac Menubar
Post by: Hiura on May 15, 2012, 05:42:22 pm
This is planned for 2.x. See https://github.com/SFML/SFML/issues/11
Title: Re: Mac Menubar
Post by: zenroth on May 15, 2012, 08:58:02 pm
Hmm, not what I was hoping to hear. I guess I might need to hack in my own simple menu bar somewhere, as I have a feeling Apple will likely reject this non-functional one.
Title: Re: Mac Menubar
Post by: Ceylo on May 16, 2012, 08:27:49 pm
I don't really know what you want to do, but in any case you can still develop a Cocoa application where you set the menu bar as you want, and then create SFML windows within the Cocoa application.
Title: Re: Mac Menubar
Post by: zenroth on January 24, 2013, 07:45:08 pm
I don't really know what you want to do, but in any case you can still develop a Cocoa application where you set the menu bar as you want, and then create SFML windows within the Cocoa application.

Well 8 months down the road and this issue has come up to bite me. Our one game on the Mac App Store, has now been denied an update due to lacking a menu bar, and specifically the ability to click on the App name in the menu bar and select quit.

Has there been any progress on this general issue? If not I guess I'll be trying to embed my game into an existing cocoa window.
Title: Re: Mac Menubar
Post by: Hiura on January 24, 2013, 08:16:57 pm
unfortunately I haven't had the time to work on this issue yet. So no progress so far.
Title: Re: Mac Menubar
Post by: zenroth on January 24, 2013, 09:12:26 pm
unfortunately I haven't had the time to work on this issue yet. So no progress so far.

Oh well no worries, just wanted to check, before diving off into the deep.

Do you know if I should expect any major issues if I try an use SFML from within a existing cocoa setup? I pretty much just use SMFL for doing the OpenGL context creation and input gathering.

I suppose the biggest headache might just be the event stuff.
Title: Re: Mac Menubar
Post by: Hiura on January 25, 2013, 09:02:34 am
Events should work the same way (theoretically). If something doesn't just tell me.

The main difficulty I had when writing the cocoa example was to mix C++ and Objective-C. From what I recall there are a few tricks like C++ constructor not being called on C++ attribute in a Objective-C class (use new/delete to workaround that).
Title: Re: Mac Menubar
Post by: Acrobat on January 25, 2013, 02:41:37 pm
You can do it without going deep in sfml, application. Just do it as always.
Title: Re: Mac Menubar
Post by: Hiura on January 25, 2013, 02:43:13 pm
what do you mean by «as always» ?
Title: Re: Mac Menubar
Post by: Acrobat on January 25, 2013, 02:59:13 pm
You can use [NSApplication sharedApplication] in application, as i remember you can add menu there. Am i wrong ?
Title: Re: Mac Menubar
Post by: Hiura on January 25, 2013, 03:07:55 pm
yes, probably, but wouldn't be easier to use the interface build to do it ? I mean, in any case you need some obj-c object to catch the action so it simpler to design everything in Xcode with some nice drag'n'drops than doing everything in code.
Title: Re: Mac Menubar
Post by: zenroth on January 25, 2013, 06:54:52 pm
Thanks guys, I hadn't even realized there was a cocoa example.  I'll also take a look at the whole  [NSApplication sharedApplication] i've actually never used interface builder, despite doing Obj C and so forth. (Admittedly I try to limit Obj C to the bare minimum.)
Title: Re: Mac Menubar
Post by: zenroth on January 25, 2013, 08:51:53 pm
Alright this was actually trivial to accomplish it seems.

I just created a little objective c interface to handle my callbacks, set NSApp's delegate to my own callback which SFML doesn't appear to touch, then created a menu and added it via [NSApp setMainMenu:];

I then populated the menu with the standard menu item entries like about, show all, hide, and quit.

I was able to do all of this inside of my own initialization routines and didn't need to mess with nib files or cocoa runloops or anything, in about 40 lines total i'd guess.

Finally wrap the code in a #ifdef for mac platform.
Title: Re: Mac Menubar
Post by: Hiura on January 25, 2013, 10:32:30 pm
ho nice ! I thought it was more complicated than that. Could you upload the piece of code ?  :)
Title: Re: Mac Menubar
Post by: zenroth on January 25, 2013, 10:46:36 pm
#ifdef PLATFORM_MAC
NSDictionary *  aboutOptions = [NSDictionary
                        dictionaryWithObjectsAndKeys:@"Credits", @"Credits.rtf",
                        nil];

@interface MenuNotification : NSObject <NSApplicationDelegate>
- (void) terminateRequest: (id)sender;
- (void) performAbout: (id)sender;
@end

@implementation MenuNotification

- (void) performAbout: (id)sender
{
    [ NSApp orderFrontStandardAboutPanelWithOptions: aboutOptions ];
}

- (void) terminateRequest: (id)sender
{
    //set our main loop to end
    DirectReality->running = false;
}
@end

MenuNotification * menuNotify;
#endif
 

#ifdef PLATFORM_MAC
    menuNotify = [[MenuNotification alloc]init];
    [NSApp setDelegate: menuNotify];
   
    id menubar = [[NSMenu new] autorelease];
    id appMenuItem = [[NSMenuItem new] autorelease];
    [menubar addItem:appMenuItem];
    [NSApp setMainMenu:menubar];
   
    id appMenu = [[NSMenu new] autorelease];
    id appName = [[NSProcessInfo processInfo] processName];
   
    NSString *title;
   
    title = [@"About " stringByAppendingString:appName];
    [appMenu addItemWithTitle:title action:@selector(performAbout:) keyEquivalent:@""];
   
    [appMenu addItem:[NSMenuItem separatorItem]];
   
    id quitTitle = [@"Quit " stringByAppendingString:appName];
    id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
                                                  action:@selector(terminateRequest:) keyEquivalent:@"q"] autorelease];
    [appMenu addItem:quitMenuItem];
    [appMenuItem setSubmenu:appMenu];
#endif
 

Anyways no promises on how great that code is. I really don't touch Obj C unless its just to write something once and then wrap it away so I don't have to see it again, but it seems to work just fine.

Title: Re: Mac Menubar
Post by: Hiura on January 26, 2013, 02:37:35 pm
thank you
Title: Re: Mac Menubar
Post by: Ceylo on January 26, 2013, 02:40:41 pm
Hmm... I think
Code: [Select]
menuNotify = [MenuNotification alloc];should be
Code: [Select]
menuNotify = [[MenuNotification alloc] init];
Title: Re: Mac Menubar
Post by: zenroth on January 26, 2013, 04:55:00 pm
Hmm... I think
Code: [Select]
menuNotify = [MenuNotification alloc];should be
Code: [Select]
menuNotify = [[MenuNotification alloc] init];

Reading Apple's documentation I think your right. Though I have no idea what difference it *should* make, given there really shouldn't be much in the way of instance variables I would think, and I'd certainly hope since its a custom class derived just from NSObject that init isn't going to swap me out with something else.

Admittedly though looking at the created object in the debugger does show a whole lot of extra junk there, which I wouldn't personally expect.  However, the same junk seems to get the same values from what I can see regardless of "init" or not.

Ah some more apple documentation "The init method defined in the NSObject class does no initialization; it simply returns self." Since I have no init methods defined myself, it seems like it matters squat in the end. Though programming practice certainly says to do it.
Title: Re: Mac Menubar
Post by: Ceylo on January 26, 2013, 05:39:52 pm
Making assumption that none of the parent classes has anything to initialize is not reliable. Even if the documentation says NSObject doesn't initialize anything, you're not guaranteed it'll remain so. Moreover, your work should be reusable and adaptable, which includes the possibility of changing the parent class without rewriting your class (or at least not dealing with that kind of issue).
Title: Re: Mac Menubar
Post by: zenroth on January 26, 2013, 06:23:48 pm
Making assumption that none of the parent classes has anything to initialize is not reliable. Even if the documentation says NSObject doesn't initialize anything, you're not guaranteed it'll remain so. Moreover, your work should be reusable and adaptable, which includes the possibility of changing the parent class without rewriting your class (or at least not dealing with that kind of issue).

Yeah I agree completely. My ramble was mostly based on trying to discover why the current code seems to work fine, regardless of init or not. I'll edit the pasted code above to include the init.

My disclaimer on the code being complete rubbish still stands though. I write just enough Obj C to accomplish something, and then bury it in a dark place where I hopefully never have to see it again. :) As a consequence my familiarity with Obj C is very minimal. I probably write like 100-200 lines of it a year, and I try to avoid that.
Title: Re: Mac Menubar
Post by: Ceylo on January 26, 2013, 07:19:09 pm
Oh ok, I admit I was a bit afraid that you keep your code without the -init call. There are often people that do things the way they want to and then complain it's working randomly. Sorry for the "rude" tone.
Title: Re: Mac Menubar
Post by: zenroth on January 26, 2013, 08:49:05 pm
Nah no worries. There is rarely ever a good reason to leave something in a sort of undefined behavior state, especially when its a simple correction and doesn't hurt anything. Better safe than sorry down the road when Apple tweaks something, as they have a habit of doing.
Title: Re: Mac Menubar
Post by: Acrobat on January 28, 2013, 10:48:26 am
By the way, have you tested Quit, does it close application properly ? I mean finishing the application loop ?
Title: Re: Mac Menubar
Post by: zenroth on January 28, 2013, 07:30:22 pm
By the way, have you tested Quit, does it close application properly ? I mean finishing the application loop ?
Well in my game, the main loop is just a while loop until a running flag gets set to false, either via a SFML close event, or some other cause. I simply have the Quit menu set my running flag to false, so on the next update the main game loop ends, and it goes off into a normal shutdown flow.

Previously I had tried having the quit option just call Terminate, but this sadly doesn't seem to inject a CLOSE event via SFML.