Reputation: 20394
I'm using wxWidgets 2.9.4 on OSX 10.8.3 and built the library for Cocoa.
I want to add a menu bar with some menus to a wxFrame
:
wxMenuBar* menuBar = new wxMenuBar();
wxMenu* fileMenu = new wxMenu();
wxMenu* helpMenu = new wxMenu();
helpMenu->Append(wxID_ABOUT, wxT("About"));
fileMenu->Append(wxID_EXIT, wxT("Exit"));
menuBar->Append(fileMenu, wxT("File"));
menuBar->Append(helpMenu, wxT("About"));
SetMenuBar(menuBar);
Since i'm using standard IDs for adding menu items(as described here), it automatically moves About and Exit to application menu(I think it's called apple
menu
), but also makes File and Help menus empty:
Are there any ways to hide those empty menus?
Actually I tried to remove them:
#if defined(__WXMAC__) || defined(__WXOSX__) || defined(__WXOSX_COCOA__)
menuBar->Remove(0);
menuBar->Remove(0);
#endif
but that caused the about and exit menu items HelpText, not to be displayed on my frame StatusBar (might have other side effects as well.)
Upvotes: 2
Views: 1212
Reputation: 711
I am new to wxWidgets and I came across the exact same problem. (Or so it seemed :) Its amazing how similar our specs are. I think the only difference is I'm on Mac OSX 10.8.4
I didn't want to write an Objective-C work around as it seemed a little counter-intuitive to me, (No Offense, I admire your perseverance) so I found a bug report that answered the question. Thought I'd post it here for future visitors.
Our problem was reported and answered in a bug report at trac.wxwidgets.org
On Mac, the Quit and About menu items are designed to belong in the program menu. (The one in bold, on the far left) And if you try add a menu item with the wxID_EXIT id to the file menu it won't show up.
If you MUST put the Quit and/or About menu items in another menu besides the program menu, you can do it by assigning it different ID besides wxID_EXIT. Like 10 for instance.
file->Append(wxID_EXIT, wxT("&Quit"));
to:
file->Append(10, wxT("&Quit"));
I thought I was doomed. Seriously. To never be able to have menus in my programs was unthinkable. Buts it's just those few standard menus like "Quit" and "About" that are reserved for the program menu on Mac.
I hope this helped you guys. Happy widgeting!
Upvotes: 1
Reputation: 20394
It seems there's no standard way for hiding menus in wxWidgets.
I ended up writing a few lines of Objective-C code to find and hide empty menus:
// MacMenuWorkaround.h
#import <Cocoa/Cocoa.h>
@interface MacMenuWorkaround : NSObject
+(void) hideEmptyMenus;
@end
// MacMenuWorkaround.m
#import "MacMenuWorkaround.h"
@implementation MacMenuWorkaround
+(void) hideEmptyMenus {
NSMenu* mainMenu = [[NSApplication sharedApplication] mainMenu];
for (NSMenuItem* item in [mainMenu itemArray]) {
NSMenu* menu = [item submenu];
if ([[menu itemArray] count] < 2) {
[item setHidden:YES];
}
}
}
@end
// MacMenuWorkaroundBridge.h
#ifndef __wxstarter__MacMenuWorkaroundBridge__
#define __wxstarter__MacMenuWorkaroundBridge__
namespace CocoaBridge {
void hideEmptyMenus();
}
#endif /* defined(__wxstarter__MacMenuWorkaroundBridge__) */
// MacMenuWorkaroundBridge.cpp
// Set file type to Objective-C++ Source
#import "MacMenuWorkaround.h"
#include "MacMenuWorkaroundBridge.h"
namespace CocoaBridge {
void hideEmptyMenus() {
[MacMenuWorkaround hideEmptyMenus];
}
}
Then in my code:
#include "MacMenuWorkaroundBridge.h"
//...
#if defined(__WXMAC__) || defined(__WXOSX__) || defined(__WXOSX_COCOA__)
CocoaBridge::hideEmptyMenus();
#endif
Upvotes: 1
Reputation: 22688
This is something that could (and hopefully will, before 3.0) be improved in wxOSX itself but for now you need to work around this special case when a top level menu only contains a menu item with a standard identifier which is moved to the application menu under OS X.
For the "File" menu this is usually not a problem at all, you will almost always have other items in it in a real application, but this does happen for the "Help" menu quite often. The best you can do right now is indeed put a #ifndef __WXOSX__
(this is enough, BTW, no need to test for the other two, see preprocessor symbols documentation) around your "Help" menu creation code and, on the contrary, add wxID_ABOUT
to some other menu (doesn't matter which one as it's going to be moved anyhow, so could be "File" in your example) in #ifdef __WXOSX__
case.
Upvotes: 0