mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
Addressed request for change in NSMenu.m, and moved function of
-[_organizeMenu] to GSTheme-[organizeMenu:isHorizontal].
This commit is contained in:
parent
096327e87b
commit
225eea02d5
3 changed files with 223 additions and 227 deletions
|
@ -1539,16 +1539,12 @@ withRepeatedImage: (NSImage*)image
|
|||
forMenuItem: (NSMenuItem *)menuItem;
|
||||
|
||||
/**
|
||||
* Used to determine whether or not the theme handles organizing the app's main
|
||||
* menu. The default implementation returns NO.
|
||||
* Used by the theme to organize the main menu. The default implementation
|
||||
* organizes the main menu in the same way that NSMenu's old default behaviour
|
||||
* did, generating an "app name" menu for horizontal display.
|
||||
*/
|
||||
- (BOOL) organizesMainMenu;
|
||||
|
||||
/**
|
||||
* Used by the theme to organize the main menu. The default implementation does
|
||||
* nothing, because it will never be called.
|
||||
*/
|
||||
- (void) organizeMainMenu: (NSMenu *)menu;
|
||||
- (void) organizeMenu: (NSMenu *)menu
|
||||
isHorizontal: (BOOL)horizontal;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#import "AppKit/NSWindow.h"
|
||||
#import "AppKit/NSMenuView.h"
|
||||
#import "AppKit/NSApplication.h"
|
||||
#import "AppKit/NSImage.h"
|
||||
|
||||
#import "GNUstepGUI/GSTheme.h"
|
||||
#import "GNUstepGUI/GSWindowDecorationView.h"
|
||||
|
@ -58,6 +59,14 @@
|
|||
}
|
||||
@end
|
||||
|
||||
@interface NSMenu (GNUstepPrivate)
|
||||
|
||||
- (BOOL) _isMain;
|
||||
|
||||
- (void) _organizeMenu;
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSTheme (Menu)
|
||||
- (void) setMenu: (NSMenu *)menu
|
||||
forWindow: (NSWindow *)window
|
||||
|
@ -199,14 +208,215 @@
|
|||
return title;
|
||||
}
|
||||
|
||||
- (BOOL) organizesMainMenu
|
||||
- (void) organizeMenu: (NSMenu *)menu
|
||||
isHorizontal: (BOOL)horizontal
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
NSString *infoString = _(@"Info");
|
||||
NSString *servicesString = _(@"Services");
|
||||
int i;
|
||||
|
||||
- (void) organizeMainMenu: (NSMenu *)menu
|
||||
{
|
||||
// Do nothing, just return.
|
||||
if ([menu _isMain])
|
||||
{
|
||||
NSString *appTitle;
|
||||
NSMenu *appMenu;
|
||||
id <NSMenuItem> appItem;
|
||||
|
||||
appTitle = [[[NSBundle mainBundle] localizedInfoDictionary]
|
||||
objectForKey: @"ApplicationName"];
|
||||
if (nil == appTitle)
|
||||
{
|
||||
appTitle = [[NSProcessInfo processInfo] processName];
|
||||
}
|
||||
appItem = [menu itemWithTitle: appTitle];
|
||||
appMenu = [appItem submenu];
|
||||
|
||||
if (horizontal == YES)
|
||||
{
|
||||
NSMutableArray *itemsToMove;
|
||||
|
||||
itemsToMove = [NSMutableArray new];
|
||||
|
||||
if (appMenu == nil)
|
||||
{
|
||||
[menu insertItemWithTitle: appTitle
|
||||
action: NULL
|
||||
keyEquivalent: @""
|
||||
atIndex: 0];
|
||||
appItem = [menu itemAtIndex: 0];
|
||||
appMenu = [NSMenu new];
|
||||
[menu setSubmenu: appMenu forItem: appItem];
|
||||
RELEASE(appMenu);
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = [menu indexOfItem: appItem];
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
RETAIN (appItem);
|
||||
[menu removeItemAtIndex: index];
|
||||
[menu insertItem: appItem atIndex: 0];
|
||||
RELEASE (appItem);
|
||||
}
|
||||
}
|
||||
|
||||
if ([[GSTheme theme] menuShouldShowIcon])
|
||||
{
|
||||
NSImage *ti;
|
||||
float bar;
|
||||
ti = [[NSApp applicationIconImage] copy];
|
||||
if (ti == nil)
|
||||
{
|
||||
ti = [[NSImage imageNamed: @"GNUstep"] copy];
|
||||
}
|
||||
[ti setScalesWhenResized: YES];
|
||||
bar = [NSMenuView menuBarHeight] - 4;
|
||||
[ti setSize: NSMakeSize(bar, bar)];
|
||||
[appItem setImage: ti];
|
||||
RELEASE(ti);
|
||||
}
|
||||
|
||||
// Collect all simple items plus "Info" and "Services"
|
||||
for (i = 1; i < [[menu itemArray] count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [[menu itemArray] objectAtIndex: i];
|
||||
NSString *title = [anItem title];
|
||||
NSMenu *submenu = [anItem submenu];
|
||||
|
||||
if (submenu == nil)
|
||||
{
|
||||
[itemsToMove addObject: anItem];
|
||||
}
|
||||
else
|
||||
{
|
||||
// The menu may not be localized, so we have to
|
||||
// check both the English and the local version.
|
||||
if ([title isEqual: @"Info"] ||
|
||||
[title isEqual: @"Services"] ||
|
||||
[title isEqual: infoString] ||
|
||||
[title isEqual: servicesString])
|
||||
{
|
||||
[itemsToMove addObject: anItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < [itemsToMove count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [itemsToMove objectAtIndex: i];
|
||||
|
||||
[menu removeItem: anItem];
|
||||
[appMenu addItem: anItem];
|
||||
}
|
||||
|
||||
RELEASE(itemsToMove);
|
||||
}
|
||||
else
|
||||
{
|
||||
[appItem setImage: nil];
|
||||
if (appMenu != nil)
|
||||
{
|
||||
NSArray *array = [NSArray arrayWithArray: [appMenu itemArray]];
|
||||
/*
|
||||
* Everything above the Serives menu goes into the info submenu,
|
||||
* the rest into the main menu.
|
||||
*/
|
||||
int k = [appMenu indexOfItemWithTitle: servicesString];
|
||||
|
||||
// The menu may not be localized, so we have to
|
||||
// check both the English and the local version.
|
||||
if (k == -1)
|
||||
k = [appMenu indexOfItemWithTitle: @"Services"];
|
||||
|
||||
if ((k > 0) && ([[array objectAtIndex: k - 1] isSeparatorItem]))
|
||||
k--;
|
||||
|
||||
if (k == 1)
|
||||
{
|
||||
// Exactly one info item
|
||||
NSMenuItem *anItem = [array objectAtIndex: 0];
|
||||
|
||||
[appMenu removeItem: anItem];
|
||||
[menu insertItem: anItem atIndex: 0];
|
||||
}
|
||||
else if (k > 1)
|
||||
{
|
||||
id <NSMenuItem> infoItem;
|
||||
NSMenu *infoMenu;
|
||||
|
||||
// Multiple info items, add a submenu for them
|
||||
[menu insertItemWithTitle: infoString
|
||||
action: NULL
|
||||
keyEquivalent: @""
|
||||
atIndex: 0];
|
||||
infoItem = [menu itemAtIndex: 0];
|
||||
infoMenu = [NSMenu new];
|
||||
[menu setSubmenu: infoMenu forItem: infoItem];
|
||||
RELEASE(infoMenu);
|
||||
|
||||
for (i = 0; i < k; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [array objectAtIndex: i];
|
||||
|
||||
[appMenu removeItem: anItem];
|
||||
[infoMenu addItem: anItem];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No service menu, or it is the first item.
|
||||
// We still look for an info item.
|
||||
NSMenuItem *anItem = [array objectAtIndex: 0];
|
||||
NSString *title = [anItem title];
|
||||
|
||||
// The menu may not be localized, so we have to
|
||||
// check both the English and the local version.
|
||||
if ([title isEqual: @"Info"] ||
|
||||
[title isEqual: infoString])
|
||||
{
|
||||
[appMenu removeItem: anItem];
|
||||
[menu insertItem: anItem atIndex: 0];
|
||||
k = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the remaining entries.
|
||||
for (i = k; i < [array count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [array objectAtIndex: i];
|
||||
|
||||
[appMenu removeItem: anItem];
|
||||
[menu addItem: anItem];
|
||||
}
|
||||
|
||||
[menu removeItem: appItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// recurse over all submenus
|
||||
for (i = 0; i < [[menu itemArray] count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [[menu itemArray] objectAtIndex: i];
|
||||
NSMenu *submenu = [anItem submenu];
|
||||
|
||||
if (submenu != nil)
|
||||
{
|
||||
if ([submenu isTransient])
|
||||
{
|
||||
[submenu closeTransient];
|
||||
}
|
||||
[submenu close];
|
||||
[submenu _organizeMenu];
|
||||
}
|
||||
}
|
||||
|
||||
[[menu menuRepresentation] update];
|
||||
[menu sizeToFit];
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
214
Source/NSMenu.m
214
Source/NSMenu.m
|
@ -261,218 +261,8 @@ static BOOL menuBarVisible = YES;
|
|||
|
||||
- (void) _organizeMenu
|
||||
{
|
||||
NSString *infoString = _(@"Info");
|
||||
NSString *servicesString = _(@"Services");
|
||||
int i;
|
||||
|
||||
if ([self _isMain])
|
||||
{
|
||||
NSString *appTitle;
|
||||
NSMenu *appMenu;
|
||||
id <NSMenuItem> appItem;
|
||||
|
||||
appTitle = [[[NSBundle mainBundle] localizedInfoDictionary]
|
||||
objectForKey: @"ApplicationName"];
|
||||
if (nil == appTitle)
|
||||
{
|
||||
appTitle = [[NSProcessInfo processInfo] processName];
|
||||
}
|
||||
appItem = [self itemWithTitle: appTitle];
|
||||
appMenu = [appItem submenu];
|
||||
|
||||
if ([[GSTheme theme] organizesMainMenu])
|
||||
{
|
||||
[[GSTheme theme] organizeMainMenu: self];
|
||||
return;
|
||||
}
|
||||
|
||||
if (_menu.horizontal == YES)
|
||||
{
|
||||
NSMutableArray *itemsToMove;
|
||||
|
||||
itemsToMove = [NSMutableArray new];
|
||||
|
||||
if (appMenu == nil)
|
||||
{
|
||||
[self insertItemWithTitle: appTitle
|
||||
action: NULL
|
||||
keyEquivalent: @""
|
||||
atIndex: 0];
|
||||
appItem = [self itemAtIndex: 0];
|
||||
appMenu = [NSMenu new];
|
||||
[self setSubmenu: appMenu forItem: appItem];
|
||||
RELEASE(appMenu);
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = [self indexOfItem: appItem];
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
RETAIN (appItem);
|
||||
[self removeItemAtIndex: index];
|
||||
[self insertItem: appItem atIndex: 0];
|
||||
RELEASE (appItem);
|
||||
}
|
||||
}
|
||||
|
||||
if ([[GSTheme theme] menuShouldShowIcon])
|
||||
{
|
||||
NSImage *ti;
|
||||
float bar;
|
||||
ti = [[NSApp applicationIconImage] copy];
|
||||
if (ti == nil)
|
||||
{
|
||||
ti = [[NSImage imageNamed: @"GNUstep"] copy];
|
||||
}
|
||||
[ti setScalesWhenResized: YES];
|
||||
bar = [NSMenuView menuBarHeight] - 4;
|
||||
[ti setSize: NSMakeSize(bar, bar)];
|
||||
[appItem setImage: ti];
|
||||
RELEASE(ti);
|
||||
}
|
||||
|
||||
// Collect all simple items plus "Info" and "Services"
|
||||
for (i = 1; i < [_items count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [_items objectAtIndex: i];
|
||||
NSString *title = [anItem title];
|
||||
NSMenu *submenu = [anItem submenu];
|
||||
|
||||
if (submenu == nil)
|
||||
{
|
||||
[itemsToMove addObject: anItem];
|
||||
}
|
||||
else
|
||||
{
|
||||
// The menu may not be localized, so we have to
|
||||
// check both the English and the local version.
|
||||
if ([title isEqual: @"Info"] ||
|
||||
[title isEqual: @"Services"] ||
|
||||
[title isEqual: infoString] ||
|
||||
[title isEqual: servicesString])
|
||||
{
|
||||
[itemsToMove addObject: anItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < [itemsToMove count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [itemsToMove objectAtIndex: i];
|
||||
|
||||
[self removeItem: anItem];
|
||||
[appMenu addItem: anItem];
|
||||
}
|
||||
|
||||
RELEASE(itemsToMove);
|
||||
}
|
||||
else
|
||||
{
|
||||
[appItem setImage: nil];
|
||||
if (appMenu != nil)
|
||||
{
|
||||
NSArray *array = [NSArray arrayWithArray: [appMenu itemArray]];
|
||||
/*
|
||||
* Everything above the Serives menu goes into the info submenu,
|
||||
* the rest into the main menu.
|
||||
*/
|
||||
int k = [appMenu indexOfItemWithTitle: servicesString];
|
||||
|
||||
// The menu may not be localized, so we have to
|
||||
// check both the English and the local version.
|
||||
if (k == -1)
|
||||
k = [appMenu indexOfItemWithTitle: @"Services"];
|
||||
|
||||
if ((k > 0) && ([[array objectAtIndex: k - 1] isSeparatorItem]))
|
||||
k--;
|
||||
|
||||
if (k == 1)
|
||||
{
|
||||
// Exactly one info item
|
||||
NSMenuItem *anItem = [array objectAtIndex: 0];
|
||||
|
||||
[appMenu removeItem: anItem];
|
||||
[self insertItem: anItem atIndex: 0];
|
||||
}
|
||||
else if (k > 1)
|
||||
{
|
||||
id <NSMenuItem> infoItem;
|
||||
NSMenu *infoMenu;
|
||||
|
||||
// Multiple info items, add a submenu for them
|
||||
[self insertItemWithTitle: infoString
|
||||
action: NULL
|
||||
keyEquivalent: @""
|
||||
atIndex: 0];
|
||||
infoItem = [self itemAtIndex: 0];
|
||||
infoMenu = [NSMenu new];
|
||||
[self setSubmenu: infoMenu forItem: infoItem];
|
||||
RELEASE(infoMenu);
|
||||
|
||||
for (i = 0; i < k; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [array objectAtIndex: i];
|
||||
|
||||
[appMenu removeItem: anItem];
|
||||
[infoMenu addItem: anItem];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No service menu, or it is the first item.
|
||||
// We still look for an info item.
|
||||
NSMenuItem *anItem = [array objectAtIndex: 0];
|
||||
NSString *title = [anItem title];
|
||||
|
||||
// The menu may not be localized, so we have to
|
||||
// check both the English and the local version.
|
||||
if ([title isEqual: @"Info"] ||
|
||||
[title isEqual: infoString])
|
||||
{
|
||||
[appMenu removeItem: anItem];
|
||||
[self insertItem: anItem atIndex: 0];
|
||||
k = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the remaining entries.
|
||||
for (i = k; i < [array count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [array objectAtIndex: i];
|
||||
|
||||
[appMenu removeItem: anItem];
|
||||
[self addItem: anItem];
|
||||
}
|
||||
|
||||
[self removeItem: appItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// recurse over all submenus
|
||||
for (i = 0; i < [_items count]; i++)
|
||||
{
|
||||
NSMenuItem *anItem = [_items objectAtIndex: i];
|
||||
NSMenu *submenu = [anItem submenu];
|
||||
|
||||
if (submenu != nil)
|
||||
{
|
||||
if ([submenu isTransient])
|
||||
{
|
||||
[submenu closeTransient];
|
||||
}
|
||||
[submenu close];
|
||||
[submenu _organizeMenu];
|
||||
}
|
||||
}
|
||||
|
||||
[[self menuRepresentation] update];
|
||||
[self sizeToFit];
|
||||
[[GSTheme theme] organizeMenu: self
|
||||
isHorizontal: _menu.horizontal];
|
||||
}
|
||||
|
||||
- (void) _setGeometry
|
||||
|
|
Loading…
Reference in a new issue