Author: manolo
Date: 2012-01-11 09:54:51 -0800 (Wed, 11 Jan 2012)
New Revision: 9219
Log:
Fixed the use of fltk3::SUBMENU_POINTER in fltk3::SysMenuBar objects (Mac
OS-specific).
Modified the menubar demo program to exercise the fltk3::SysMenuBar class.
Modified:
branches/branch-3.0/src/fltk3/SysMenuBar.cxx
branches/branch-3.0/src/fltk3/cocoa.mm
branches/branch-3.0/test/menubar.cxx
Modified: branches/branch-3.0/src/fltk3/SysMenuBar.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/SysMenuBar.cxx 2012-01-11 16:16:31 UTC
(rev 9218)
+++ branches/branch-3.0/src/fltk3/SysMenuBar.cxx 2012-01-11 17:54:51 UTC
(rev 9219)
@@ -109,46 +109,46 @@
/*
* create a sub menu for a specific menu handle
*/
-static void createSubMenu( void * mh, pFl_Menu_Item &mm )
+static void createSubMenu( void * mh, pFl_Menu_Item &mm, const
fltk3::MenuItem *mitem )
{
void *submenu;
int miCnt, flags;
void *menuItem;
- submenu =
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::initWithTitle,
mm->text);
+ submenu =
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::initWithTitle,
mitem->text);
int cnt;
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::numberOfItems,
mh, &cnt);
cnt--;
menuItem =
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::itemAtIndex, mh,
cnt);
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setSubmenu,
menuItem, submenu);
- if ( mm->flags & fltk3::MENU_INACTIVE ) {
- fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setEnabled,
menuItem, 0);
- }
- mm++;
while ( mm->text )
{
- int flRank = mm - fltk3::sys_menu_bar->fltk3::Menu_::menu();
- fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem,
submenu, flRank, &miCnt);
+ char visible = mm->visible() ? 1 : 0;
+ fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem,
submenu, mm, &miCnt);
setMenuFlags( submenu, miCnt, mm );
setMenuShortcut( submenu, miCnt, mm );
- if ( mm->flags & fltk3::MENU_INACTIVE ) {
+ if ( mm->flags & fltk3::MENU_INACTIVE || mitem->flags &
fltk3::MENU_INACTIVE) {
void *item =
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::itemAtIndex,
submenu, miCnt);
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setEnabled,
item, 0);
}
flags = mm->flags;
if ( mm->flags & fltk3::SUBMENU )
{
- createSubMenu( submenu, mm );
+ mm++;
+ createSubMenu( submenu, mm, mm - 1 );
}
else if ( mm->flags & fltk3::SUBMENU_POINTER )
{
const fltk3::MenuItem *smm = (fltk3::MenuItem*)mm->user_data_;
- createSubMenu( submenu, smm );
+ createSubMenu( submenu, smm, mm );
}
if ( flags & fltk3::MENU_DIVIDER ) {
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addSeparatorItem,
submenu);
}
+ if ( !visible ) {
+ fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::removeItem,
submenu, miCnt);
+ }
mm++;
}
}
@@ -156,10 +156,11 @@
/*
* convert a complete fltk3::MenuItem array into a series of menus in the top
menu bar
- * ALL PREVIOUS SYSTEM MENUS, EXCEPT APPLICATION MENU, ARE REPLACED BY THE NEW
DATA
+ * ALL PREVIOUS SYSTEM MENUS, EXCEPT THE APPLICATION MENU, ARE REPLACED BY THE
NEW DATA
*/
static void convertToMenuBar(const fltk3::MenuItem *mm)
{
+ int rank;
int count;//first, delete all existing system menus
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::numberOfItems,
fl_system_menu, &count);
for(int i = count - 1; i > 0; i--) {
@@ -171,17 +172,18 @@
if ( !mm || !mm->text )
break;
char visible = mm->visible() ? 1 : 0;
- int flRank = mm - fltk3::sys_menu_bar->fltk3::Menu_::menu();
- fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem,
fl_system_menu, flRank, NULL);
-
- if ( mm->flags & fltk3::SUBMENU )
- createSubMenu( fl_system_menu, mm );
+ fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem,
fl_system_menu, mm, &rank);
+
+ if ( mm->flags & fltk3::SUBMENU ) {
+ mm++;
+ createSubMenu( fl_system_menu, mm, mm - 1);
+ }
else if ( mm->flags & fltk3::SUBMENU_POINTER ) {
const fltk3::MenuItem *smm = (fltk3::MenuItem*)mm->user_data_;
- createSubMenu( fl_system_menu, smm );
+ createSubMenu( fl_system_menu, smm, mm);
}
- if ( visible ) {
- // InsertMenu( mh, 0 );
+ if ( !visible ) {
+ fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::removeItem,
fl_system_menu, rank);
}
mm++;
}
Modified: branches/branch-3.0/src/fltk3/cocoa.mm
===================================================================
--- branches/branch-3.0/src/fltk3/cocoa.mm 2012-01-11 16:16:31 UTC (rev
9218)
+++ branches/branch-3.0/src/fltk3/cocoa.mm 2012-01-11 17:54:51 UTC (rev
9219)
@@ -2946,29 +2946,40 @@
@interface FLMenuItem : NSMenuItem
- (void) doCallback:(id)unused;
- (void) directCallback:(id)unused;
+- (const fltk3::MenuItem*) getFlItem;
@end
@implementation FLMenuItem
+- (const fltk3::MenuItem*) getFlItem
+{
+ return *(const fltk3::MenuItem **)[(NSData*)[self representedObject] bytes];
+}
- (void) doCallback:(id)unused
{
fl_lock_function();
- int flRank = [self tag];
- const fltk3::MenuItem *items = fltk3::sys_menu_bar->fltk3::Menu_::menu();
- const fltk3::MenuItem *item = items + flRank;
+ const fltk3::MenuItem *item = [self getFlItem];
+ NSMenu* menu = [self menu];
+ NSInteger flRank = [menu indexOfItem:self];
+ NSInteger last = [menu numberOfItems];
if (item) {
fltk3::sys_menu_bar->picked(item);
if ( item->flags & fltk3::MENU_TOGGLE ) { // update the menu toggle symbol
[self setState:(item->value() ? NSOnState : NSOffState)];
}
else if ( item->flags & fltk3::MENU_RADIO ) { // update the menu
radio symbols
+ const fltk3::MenuItem *item2;
int from = flRank;
- while( from > 0 && items[from - 1].label() && (items[from - 1].flags &
fltk3::MENU_RADIO) &&
- !(items[from - 1].flags & fltk3::MENU_DIVIDER) ) {
- from--;
+ while(from > 0) {
+ if ([[menu itemAtIndex:from-1] isSeparatorItem]) break;
+ item2 = [(FLMenuItem*)[menu itemAtIndex:from-1] getFlItem];
+ if ( !(item2->flags & fltk3::MENU_RADIO) ) break;
+ from--;
}
int to = flRank;
- while( !(items[to].flags & fltk3::MENU_DIVIDER) && items[to + 1].label()
&&
- (items[to + 1].flags & fltk3::MENU_RADIO) ) {
- to++;
+ while (to+1 < last) {
+ if ([[menu itemAtIndex:to+1] isSeparatorItem]) break;
+ item2 = [(FLMenuItem*)[menu itemAtIndex:to+1] getFlItem];
+ if (!(item2->flags & fltk3::MENU_RADIO)) break;
+ to++;
}
NSMenu *nsmenu = [self menu];
int nsrank = (int)[nsmenu indexOfItem:self];
@@ -3122,20 +3133,21 @@
value = va_arg(ap, int);
[menu removeItem:[menu itemAtIndex:value]];
}
- else if (operation == fltk3::SysMenuBar::addNewItem) { //
arguments: NSMenu *menu, int flrank, int *prank
+ else if (operation == fltk3::SysMenuBar::addNewItem) { //
arguments: NSMenu *menu, flk3::MenuItem flrank, int *prank
// creates a new menu item at the end of 'menu'
- // attaches the item of rank flrank (counted in fltk3::Menu_) of
fltk3::sys_menu_bar to it
+ // attaches the item of fltk3::sys_menu_bar to it
// upon return, puts the rank (counted in NSMenu) of the new item in
*prank unless prank is NULL
menu = va_arg(ap, NSMenu*);
- int flRank = va_arg(ap, int);
- char *name = remove_ampersand( (fltk3::sys_menu_bar->fltk3::Menu_::menu()
+ flRank)->label());
+ fltk3::MenuItem *mitem = va_arg(ap, fltk3::MenuItem *);
int *prank = va_arg(ap, int*);
+ char *name = remove_ampersand(mitem->label());
CFStringRef cfname = CFStringCreateWithCString(NULL, name,
kCFStringEncodingUTF8);
free(name);
FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:(NSString*)cfname
action:@selector(doCallback:)
keyEquivalent:@""];
- [item setTag:flRank];
+ NSData *pointer = [NSData dataWithBytes:&mitem
length:sizeof(fltk3::MenuItem*)];
+ [item setRepresentedObject:pointer];
[menu addItem:item];
CFRelease(cfname);
[item setTarget:item];
Modified: branches/branch-3.0/test/menubar.cxx
===================================================================
--- branches/branch-3.0/test/menubar.cxx 2012-01-11 16:16:31 UTC (rev
9218)
+++ branches/branch-3.0/test/menubar.cxx 2012-01-11 17:54:51 UTC (rev
9219)
@@ -28,7 +28,7 @@
#include <fltk3/run.h>
#include <fltk3/Box.h>
#include <fltk3/DoubleWindow.h>
-#include <fltk3/MenuBar.h>
+#include <fltk3/SysMenuBar.h>
#include <fltk3/ToggleButton.h>
#include <fltk3/MenuButton.h>
#include <fltk3/Choice.h>
@@ -179,6 +179,33 @@
{0}
};
+#ifdef __APPLE__
+fltk3::MenuItem menu_location[] = {
+ {"Window menu bar", 0, 0, 0, fltk3::MENU_VALUE},
+ {"System menu bar", },
+ {0}
+};
+
+fltk3::SysMenuBar* smenubar;
+
+void menu_location_cb(fltk3::Widget* w, void* data)
+{
+ fltk3::MenuBar *menubar = (fltk3::MenuBar*)data;
+ if (((fltk3::Choice*)w)->value() == 1) { // switch to system menu bar
+ menubar->hide();
+ const fltk3::MenuItem *menu = menubar->menu();
+ smenubar = new fltk3::SysMenuBar(0,0,0,30);
+ smenubar->menu(menu);
+ smenubar->callback(test_cb);
+ }
+ else { // switch to window menu bar
+ smenubar->clear();
+ delete smenubar;
+ menubar->show();
+ }
+}
+#endif // __APPLE__
+
#define WIDTH 700
fltk3::Menu_* menus[4];
@@ -213,6 +240,11 @@
fltk3::Box b(200,200,200,100,"Press right button\nfor a pop-up menu");
window.resizable(&mb);
window.size_range(300,400,0,400);
+#ifdef __APPLE__
+ fltk3::Choice ch2(500,100,150,25,"Use:");
+ ch2.menu(menu_location);
+ ch2.callback(menu_location_cb, &menubar);
+#endif
window.end();
window.show(argc, argv);
return fltk3::run();
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit