merge in themes branch to keep in sync

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@23705 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-10-02 05:09:48 +00:00
parent 300ada29b4
commit d8f8954b02
13 changed files with 1446 additions and 372 deletions

View file

@ -1,3 +1,42 @@
2006-10-01 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTheme.m: Add rudimentary inspector.
Make themes in panel be in alphabetical order except for the
default theme (always first in the list).
Allow setting of default theme for application.
* Source/NSHelpManager.m:
* Source/NSHelpPanel.m: Implement simple fallback help panel display
for systems where no rtf/rtfd viewing application is installed.
2006-09-30 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSColor.m: Remove debug log message.
* Source/GSInfoPanel.m: Open theme handling panel.
* Source/GSTheme.m: Rudimentary theme handling panel.
* Headers/Additions/GNUstepGUI/GSTheme.h: A few more methods.
Start adding a panel to allow selection of themes in a running app.
2006-09-29 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSWindow.m: If ordering out a deferred window which was
never ordered in, there is nothing to do.
* Source/NSMenu.m: (_organize) when switching from horizontal to
vertical menu, attempt to restore contents fo the app menu to the
main menu in a reasonable manner.
* Source/NSHelpManager.m: Use the help file specified in Info.plist
* Headers/Additions/GNUstepGUI/GSTheme.h:
* Source/GSTheme.m: Add -authors and -icon methods. Support loading
from an absolute path.
2006-09-28 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTheme.m: Update main menu on theme activation.
* Source/NSMenu.m: ([setMain:]) handle change of interface style.
* Source/NSInterfaceStyle.m: Observe/handle theme activation.
* Headers/AppKit/NSMenu.h: remove internal method from public header
* Headers/Additions/GNUstepGUI/GSTheme.h: add -infoDictionary method
and documentation.
2006-09-26 Richard Frith-Macdonald <rfm@gnu.org> 2006-09-26 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSWorkspace.m: Use png in preference to tiff. * Source/NSWorkspace.m: Use png in preference to tiff.
@ -25,7 +64,7 @@
2006-09-23 Richard Frith-Macdonald <rfm@gnu.org> 2006-09-23 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSWindowDecorationView.m: coimment out dubious change. * Source/GSWindowDecorationView.m: comment out dubious change.
* Source/GSDisplayServer.m: Add method for expose events * Source/GSDisplayServer.m: Add method for expose events
* Source/NSWindow.m: Handle expose events. * Source/NSWindow.m: Handle expose events.
* Headers/AppKit/NSEvent.h: Add expose event type. * Headers/AppKit/NSEvent.h: Add expose event type.

View file

@ -139,8 +139,11 @@
#include "AppKit/NSButtonCell.h" #include "AppKit/NSButtonCell.h"
#if OS_API_VERSION(GS_API_NONE,GS_API_NONE) #if OS_API_VERSION(GS_API_NONE,GS_API_NONE)
@class NSArray;
@class NSBundle; @class NSBundle;
@class NSColor; @class NSColor;
@class NSDictionary;
@class NSImage;
@class GSDrawTiles; @class GSDrawTiles;
/** /**
@ -207,8 +210,15 @@ APPKIT_EXPORT NSString *GSThemeDidDeactivateNotification;
NSBundle *_bundle; NSBundle *_bundle;
NSMutableArray *_images; NSMutableArray *_images;
NSMutableDictionary *_tiles; NSMutableDictionary *_tiles;
NSImage *_icon;
} }
/**
* Creates and displays a panel allowing selection of different themes
* and display of the current theme inspector.
*/
+ (void) orderFrontSharedThemePanel: (id)sender;
/** /**
* Set the currently active theme to be the instance specified.<br /> * Set the currently active theme to be the instance specified.<br />
* You do not normally need to call this method as it is called * You do not normally need to call this method as it is called
@ -228,17 +238,27 @@ APPKIT_EXPORT NSString *GSThemeDidDeactivateNotification;
* <p>This method is called automatically when the receiver is made into * <p>This method is called automatically when the receiver is made into
* the currently active theme by the +setTheme: method. Subclasses may * the currently active theme by the +setTheme: method. Subclasses may
* override it to perform startup operations, but should call the super * override it to perform startup operations, but should call the super
* class implementation before doing their own thing. * class implementation after doing their own thing.
* </p> * </p>
* <p>The base implementation handles setup and caching of certain image * <p>The base implementation handles setup and caching of the system
* information and then sends a GSThemeDidActivateNotification to allow * color list, standard image information, tiling information,
* other parts of the GUI library to update themselves from the new theme.<br /> * and user defaults.<br />
* It then sends a GSThemeDidActivateNotification to allow other
* parts of the GUI library to update themselves from the new theme.<br />
* If the theme sets an alternative system color list, the notification * If the theme sets an alternative system color list, the notification
* userInfo dictionary will contain that list keyed on <em>Colors</em>. * userInfo dictionary will contain that list keyed on <em>Colors</em>.
* </p> * </p>
* <p>Finally, this method marks all windows in the application as needing
* update ... so they will draw themselves with the new theme information.
* </p>
*/ */
- (void) activate; - (void) activate;
/**
* Returns the names of the theme's authors.
*/
- (NSArray*) authors;
/** /**
* Return the bundle containing the resources used by the current theme. * Return the bundle containing the resources used by the current theme.
*/ */
@ -258,6 +278,11 @@ APPKIT_EXPORT NSString *GSThemeDidDeactivateNotification;
*/ */
- (void) deactivate; - (void) deactivate;
/**
* Returns the theme's icon.
*/
- (NSImage*) icon;
/** <init /> /** <init />
* Initialise an instance of a theme with the specified resource bundle.<br /> * Initialise an instance of a theme with the specified resource bundle.<br />
* You don't need to call this method directly, but if you are subclassing * You don't need to call this method directly, but if you are subclassing
@ -265,6 +290,59 @@ APPKIT_EXPORT NSString *GSThemeDidDeactivateNotification;
*/ */
- (id) initWithBundle: (NSBundle*)bundle; - (id) initWithBundle: (NSBundle*)bundle;
/**
* <p>Returns the info dictionary for this theme. In the base class
* implementation this is simply the info dictionary of the theme
* bundle, but subclasses may override this method to return extra
* or different information.
* </p>
* <p>Keys found in this dictionary include:
* </p>
* <deflist>
* <term>GSThemeDomain</term>
* <desc>A dictionary whose key/value pairs are used to set up new values
* in the GSThemeDomain domain of the user defaults system, and hence
* define values for these unless overridden by values set explicitly by
* the user.
* </desc>
* <term>GSThemeTiles</term>
* <desc>A dictionary keyed on tile names and containing the following:
* <deflist>
* <term>FileName</term>
* <desc>Name of the file (within the GSThemeTiles directory in the
* bundle) in which the image for this tile is tored.
* </desc>
* <term>HorizontalDivision</term>
* <desc>The offet along the X-axis used to divide the image into
* columns of tiles.
* </desc>
* <term>VerticalDivision</term>
* <desc>The offet along the Y-axis used to divide the image into
* rows of tiles.
* </desc>
* </deflist>
* </desc>
* </deflist>
*/
- (NSDictionary*) infoDictionary;
/**
* Return the theme's name.
*/
- (NSString*) name;
/**
* <p>Provides a standard inspector window used to display information about
* the receiver. The default implementation displays the icon, the name,
* and the authors of the theme.
* </p>
* <p>The code managing this object (if any) must be prepared to have the
* content view of the window reparented into another window for display
* on screen.
* </p>
*/
- (NSWindow*) themeInspector;
/** /**
* Returns the tile image information for a particular image name, * Returns the tile image information for a particular image name,
* or nil if there is no such information.<br /> * or nil if there is no such information.<br />

View file

@ -48,43 +48,43 @@
// //
// Accessing the Help Panel // Accessing the Help Panel
// //
+ (NSHelpPanel *)sharedHelpPanel; + (NSHelpPanel *) sharedHelpPanel;
+ (NSHelpPanel *)sharedHelpPanelWithDirectory:(NSString *)helpDirectory; + (NSHelpPanel *) sharedHelpPanelWithDirectory: (NSString *)helpDirectory;
// //
// Managing the Contents // Managing the Contents
// //
+ (void)setHelpDirectory:(NSString *)helpDirectory; + (void) setHelpDirectory: (NSString *)helpDirectory;
- (void)addSupplement:(NSString *)helpDirectory - (void) addSupplement: (NSString *)helpDirectory
inPath:(NSString *)supplementPath; inPath: (NSString *)supplementPath;
- (NSString *)helpDirectory; - (NSString *) helpDirectory;
- (NSString *)helpFile; - (NSString *) helpFile;
// //
// Attaching Help to Objects // Attaching Help to Objects
// //
+ (void)attachHelpFile:(NSString *)filename + (void) attachHelpFile: (NSString *)filename
markerName:(NSString *)markerName markerName: (NSString *)markerName
to:(id)anObject; to: (id)anObject;
+ (void)detachHelpFrom:(id)anObject; + (void) detachHelpFrom: (id)anObject;
// //
// Showing Help // Showing Help
// //
- (void)showFile:(NSString *)filename - (void) showFile: (NSString *)filename
atMarker:(NSString *)markerName; atMarker: (NSString *)markerName;
- (BOOL)showHelpAttachedTo:(id)anObject; - (BOOL) showHelpAttachedTo: (id)anObject;
// //
// Printing // Printing
// //
- (void)print:(id)sender; - (void) print: (id)sender;
// //
// NSCoding protocol // NSCoding protocol
// //
- (void)encodeWithCoder: (NSCoder *)aCoder; - (void) encodeWithCoder: (NSCoder *)aCoder;
- initWithCoder: (NSCoder *)aDecoder; - (id) initWithCoder: (NSCoder *)aDecoder;
@end @end

View file

@ -592,9 +592,14 @@ The displayed menus on the screen have the following structure:
- (NSWindow*) window; - (NSWindow*) window;
/** /**
Flag this menu to be the main menu of the application, <p>Flag this menu to be the main menu of the application,
when isMain is YES. Flag it as no longer being the main when isMain is YES. Flag it as no longer being the main
menu when NO is handed in. menu when NO is handed in.
</p>
<p>This method also checks the user defaults to determine how
the menu is to be displayed (eg vertical or horizontal) and can
therefore be used to change window geometry.
</p>
*/ */
- (void) setMain: (BOOL)isMain; - (void) setMain: (BOOL)isMain;
@ -609,13 +614,6 @@ The displayed menus on the screen have the following structure:
*/ */
- (void) displayTransient; - (void) displayTransient;
/**
Positions the menu according to the standard user defaults.
If the position is not found in the defaults revert to positioning
the window in the upper left corner.
*/
- (void) setGeometry;
/** /**
When the flag is YES When the flag is YES
this method will detach the receiver from its parent and this method will detach the receiver from its parent and

View file

@ -30,11 +30,13 @@
#include "AppKit/NSFont.h" #include "AppKit/NSFont.h"
#include "AppKit/NSImage.h" #include "AppKit/NSImage.h"
#include "AppKit/NSTextField.h" #include "AppKit/NSTextField.h"
#include "GNUstepGUI/GSInfoPanel.h"
#include <Foundation/NSBundle.h> #include <Foundation/NSBundle.h>
#include <Foundation/NSDictionary.h> #include <Foundation/NSDictionary.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <Foundation/NSProcessInfo.h> #include <Foundation/NSProcessInfo.h>
#include "GNUstepGUI/GSInfoPanel.h"
#include "GNUstepGUI/GSTheme.h"
static id static id
value_from_info_plist_for_key (NSString *key) value_from_info_plist_for_key (NSString *key)
@ -156,7 +158,7 @@ new_label (NSString *value)
} }
} }
-(id) initWithDictionary: (NSDictionary *)dictionary; - (id) initWithDictionary: (NSDictionary *)dictionary;
{ {
/* Info to show */ /* Info to show */
NSString *name = nil; NSString *name = nil;
@ -593,4 +595,15 @@ new_label (NSString *value)
[self center]; [self center];
return self; return self;
} }
- (void) mouseDown: (NSEvent*)theEvent
{
/*
* Mouse down on window background ... we could do different things in
* different regions of the window, but for now we just use this to
* activate the theme panel.
*/
[GSTheme orderFrontSharedThemePanel: self];
}
@end @end

File diff suppressed because it is too large Load diff

View file

@ -1680,7 +1680,6 @@ systemColorWithName(NSString *name)
list = [NSColorList colorListNamed: @"System"]; list = [NSColorList colorListNamed: @"System"];
ASSIGN(systemColors, list); ASSIGN(systemColors, list);
[systemDict removeAllObjects]; [systemDict removeAllObjects];
NSLog(@"Theme activation with control background %@", [self controlBackgroundColor]);
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
postNotificationName: NSSystemColorsDidChangeNotification object: nil]; postNotificationName: NSSystemColorsDidChangeNotification object: nil];
} }

View file

@ -27,6 +27,7 @@
*/ */
#include <Foundation/NSUserDefaults.h> #include <Foundation/NSUserDefaults.h>
#include <Foundation/NSData.h>
#include <Foundation/NSNotification.h> #include <Foundation/NSNotification.h>
#include <Foundation/NSFileManager.h> #include <Foundation/NSFileManager.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
@ -36,13 +37,14 @@
#include "AppKit/NSApplication.h" #include "AppKit/NSApplication.h"
#include "AppKit/NSWorkspace.h" #include "AppKit/NSWorkspace.h"
#include "AppKit/NSHelpManager.h" #include "AppKit/NSHelpManager.h"
#include "AppKit/NSHelpPanel.h"
#include "AppKit/NSGraphics.h" #include "AppKit/NSGraphics.h"
#include "GNUstepGUI/GSHelpManagerPanel.h" #include "GNUstepGUI/GSHelpManagerPanel.h"
@implementation NSBundle (NSHelpManager) @implementation NSBundle (NSHelpManager)
- (NSString *)pathForHelpResource:(NSString *)fileName - (NSString *) pathForHelpResource: (NSString *)fileName
{ {
NSFileManager *fm = [NSFileManager defaultManager]; NSFileManager *fm = [NSFileManager defaultManager];
NSMutableArray *array = [NSMutableArray array]; NSMutableArray *array = [NSMutableArray array];
@ -59,6 +61,7 @@
while ((language = [enumerator nextObject])) while ((language = [enumerator nextObject]))
{ {
NSString *langDir = [NSString stringWithFormat: @"%@.lproj", language]; NSString *langDir = [NSString stringWithFormat: @"%@.lproj", language];
[array addObject: [primary stringByAppendingPathComponent: langDir]]; [array addObject: [primary stringByAppendingPathComponent: langDir]];
} }
@ -71,6 +74,7 @@
while ((language = [enumerator nextObject])) while ((language = [enumerator nextObject]))
{ {
NSString *langDir = [NSString stringWithFormat: @"%@.lproj", language]; NSString *langDir = [NSString stringWithFormat: @"%@.lproj", language];
[array addObject: [primary stringByAppendingPathComponent: langDir]]; [array addObject: [primary stringByAppendingPathComponent: langDir]];
} }
@ -107,7 +111,7 @@
return nil; return nil;
} }
- (NSAttributedString *)contextHelpForKey:(NSString *)key - (NSAttributedString *) contextHelpForKey: (NSString *)key
{ {
NSFileManager *fm = [NSFileManager defaultManager]; NSFileManager *fm = [NSFileManager defaultManager];
NSString *dictPath = [self pathForResource: @"Help" ofType: @"plist"]; NSString *dictPath = [self pathForResource: @"Help" ofType: @"plist"];
@ -127,8 +131,8 @@
if (helpFile) if (helpFile)
{ {
NSData *data = [helpFile objectForKey: @"NSHelpRTFContents"]; NSData *data = [helpFile objectForKey: @"NSHelpRTFContents"];
return ((data != nil) ? [NSUnarchiver unarchiveObjectWithData: data] : return ((data != nil) ? [NSUnarchiver unarchiveObjectWithData: data]
nil) ; : nil);
} }
else else
@ -137,8 +141,10 @@
if (helpFile) if (helpFile)
{ {
NSString *helpstr = [[NSAttributedString alloc] initWithPath: helpFile NSString *helpstr;
documentAttributes: NULL];
helpstr = [[NSAttributedString alloc] initWithPath: helpFile
documentAttributes: NULL];
return TEST_AUTORELEASE (helpstr); return TEST_AUTORELEASE (helpstr);
} }
} }
@ -165,7 +171,7 @@
// "appname.rtfd" or "appname.rtf" // "appname.rtfd" or "appname.rtf"
} }
if (help) if (help != nil)
{ {
NSString *file = nil; NSString *file = nil;
@ -180,13 +186,64 @@
[help stringByAppendingPathExtension: @"rtf"]]; [help stringByAppendingPathExtension: @"rtf"]];
} }
} }
else
{
file = [mb pathForHelpResource: help];
}
if (file) if (file != nil)
{ {
[[NSWorkspace sharedWorkspace] openFile: file]; if ([[NSWorkspace sharedWorkspace] openFile: file] == YES)
return; {
} return;
} }
else
{
NSHelpPanel *panel = [NSHelpPanel sharedHelpPanel];
NSString *ext = [file pathExtension];
NSTextView *tv;
id object;
tv = [(NSScrollView*)[panel contentView] documentView];
if (ext == nil
|| [ext isEqualToString: @""]
|| [ext isEqualToString: @"txt"]
|| [ext isEqualToString: @"text"])
{
object = [NSString stringWithContentsOfFile: file];
}
else if ([ext isEqualToString: @"rtf"])
{
NSData *data = [NSData dataWithContentsOfFile: file];
object = [[NSAttributedString alloc] initWithRTF: data
documentAttributes: 0];
AUTORELEASE (object);
}
else if ([ext isEqualToString: @"rtfd"])
{
NSFileWrapper *wrapper;
wrapper = [[NSFileWrapper alloc] initWithPath: file];
AUTORELEASE (wrapper);
object = [[NSAttributedString alloc]
initWithRTFDFileWrapper: wrapper
documentAttributes: 0];
AUTORELEASE (object);
}
if (object != nil)
{
[[tv textStorage] setAttributedString: object];
[tv sizeToFit];
}
[tv setNeedsDisplay: YES];
[panel makeKeyAndOrderFront: self];
return;
}
}
}
NSBeep(); NSBeep();
} }
@ -207,7 +264,7 @@ static BOOL _gnu_contextHelpActive = NO;
// //
// Class methods // Class methods
// //
+ (NSHelpManager*)sharedHelpManager + (NSHelpManager*) sharedHelpManager
{ {
if (!_gnu_sharedHelpManager) if (!_gnu_sharedHelpManager)
{ {
@ -217,12 +274,12 @@ static BOOL _gnu_contextHelpActive = NO;
return _gnu_sharedHelpManager; return _gnu_sharedHelpManager;
} }
+ (BOOL)isContextHelpModeActive + (BOOL) isContextHelpModeActive
{ {
return _gnu_contextHelpActive; return _gnu_contextHelpActive;
} }
+ (void)setContextHelpModeActive: (BOOL) flag + (void) setContextHelpModeActive: (BOOL) flag
{ {
_gnu_contextHelpActive = flag; _gnu_contextHelpActive = flag;
if (flag) if (flag)
@ -287,7 +344,7 @@ static BOOL _gnu_contextHelpActive = NO;
NSMapRemove(contextHelpTopics, object); NSMapRemove(contextHelpTopics, object);
} }
- (void)setContextHelp:(NSAttributedString *)help forObject:(id)object - (void) setContextHelp: (NSAttributedString *)help forObject: (id)object
{ {
NSMapInsert(contextHelpTopics, object, help); NSMapInsert(contextHelpTopics, object, help);
} }

View file

@ -26,6 +26,9 @@
#include "config.h" #include "config.h"
#include "AppKit/NSHelpPanel.h" #include "AppKit/NSHelpPanel.h"
#include "AppKit/NSHelpManager.h" #include "AppKit/NSHelpManager.h"
#include "AppKit/NSScrollView.h"
#include "AppKit/NSTextView.h"
#include "AppKit/NSTextContainer.h"
@implementation NSApplication (NSHelpPanel) @implementation NSApplication (NSHelpPanel)
@ -40,49 +43,68 @@
@implementation NSHelpPanel @implementation NSHelpPanel
static NSString *_helpDirectory = nil;
static NSString *_helpFile = nil;
static NSHelpPanel *_sharedPanel = nil;
// //
// Class methods // Class methods
// //
+ (void)initialize + (void) initialize
{ {
if (self == [NSHelpPanel class]) if (self == [NSHelpPanel class])
{ {
// Initial version // Initial version
[self setVersion:1]; [self setVersion: 1];
} }
} }
// //
// Accessing the Help Panel // Accessing the Help Panel
// //
+ (NSHelpPanel *)sharedHelpPanel + (NSHelpPanel*) sharedHelpPanel
{ {
NSRunAlertPanel (NULL, @"Help Panel not implemented yet", if (_sharedPanel == nil)
@"OK", NULL, NULL); {
return nil; return [self new];
}
return _sharedPanel;
} }
+ (NSHelpPanel *)sharedHelpPanelWithDirectory:(NSString *)helpDirectory + (NSHelpPanel *) sharedHelpPanelWithDirectory: (NSString *)helpDirectory
{ {
return nil; [self setHelpDirectory: helpDirectory];
return [self sharedHelpPanel];
} }
// //
// Managing the Contents // Managing the Contents
// //
+ (void)setHelpDirectory:(NSString *)helpDirectory + (void) setHelpDirectory: (NSString *)helpDirectory
{} {
ASSIGN(_helpDirectory, helpDirectory);
}
// //
// Attaching Help to Objects // Attaching Help to Objects
// //
+ (void)attachHelpFile:(NSString *)filename + (void) attachHelpFile: (NSString *)filename
markerName:(NSString *)markerName markerName: (NSString *)markerName
to:(id)anObject to: (id)anObject
{} {
if ([filename isAbsolutePath] == NO)
{
filename = [[[NSHelpPanel sharedHelpPanel] helpDirectory]
stringByAppendingPathComponent: filename];
}
[[NSHelpManager sharedHelpManager] setContextHelp: (id)filename
forObject: anObject];
}
+ (void)detachHelpFrom:(id)anObject + (void) detachHelpFrom: (id)anObject
{} {
[[NSHelpManager sharedHelpManager] removeContextHelpForObject: anObject];
}
// //
// Instance methods // Instance methods
@ -90,37 +112,100 @@ to:(id)anObject
// //
// Managing the Contents // Managing the Contents
// //
- (void)addSupplement:(NSString *)helpDirectory - (void) addSupplement: (NSString *)helpDirectory
inPath:(NSString *)supplementPath inPath: (NSString *)supplementPath
{}
- (NSString *)helpDirectory
{ {
return nil;
} }
- (NSString *)helpFile - (NSString *) helpDirectory
{ {
return nil; return _helpDirectory;
}
- (NSString *) helpFile
{
return _helpFile;
}
- (id) initWithContentRect: (NSRect)contentRect
styleMask: (unsigned int)aStyle
backing: (NSBackingStoreType)bufferingType
defer: (BOOL)flag
screen: (NSScreen*)aScreen
{
if (_sharedPanel == nil)
{
NSScrollView *s;
NSTextView *v;
NSRect r;
self = [super initWithContentRect: NSMakeRect(100,100,400,500)
styleMask: NSTitledWindowMask|NSClosableWindowMask|NSResizableWindowMask
backing: NSBackingStoreBuffered
defer: NO
screen: nil];
[self setReleasedWhenClosed: NO];
[self setTitle: @"Help"];
s = [[NSScrollView alloc] initWithFrame: contentRect];
[s setHasHorizontalScroller: YES];
[s setHasVerticalScroller: YES];
[s setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)];
[self setContentView: s];
RELEASE(s);
r = [[s documentView] frame];
v = [[NSTextView alloc] initWithFrame: r];
[v setHorizontallyResizable: YES];
[v setVerticallyResizable: YES];
[v setEditable: NO];
[v setRichText: YES];
[v setMinSize: NSMakeSize (0, 0)];
[v setMaxSize: NSMakeSize (1E7, 1E7)];
[v setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
[[v textContainer] setContainerSize:
NSMakeSize (r.size.width, 1e7)];
[[v textContainer] setWidthTracksTextView: YES];
[s setDocumentView: v];
RELEASE(v);
_sharedPanel = self;
}
else
{
RELEASE(self);
}
return _sharedPanel;
} }
// //
// Showing Help // Showing Help
// //
- (void)showFile:(NSString *)filename - (void) showFile: (NSString *)filename
atMarker:(NSString *)markerName atMarker: (NSString *)markerName
{}
- (BOOL)showHelpAttachedTo:(id)anObject
{ {
return NO; if ([filename isAbsolutePath] == NO)
{
filename = [[[NSHelpPanel sharedHelpPanel] helpDirectory]
stringByAppendingPathComponent: filename];
}
[[NSHelpManager sharedHelpManager] setContextHelp: (id)filename
forObject: self];
[self showHelpAttachedTo: self];
}
- (BOOL) showHelpAttachedTo: (id)anObject
{
return [[NSHelpManager sharedHelpManager]
showContextHelpForObject: anObject locationHint: NSZeroPoint];
} }
// //
// Printing // Printing
// //
- (void)print:(id)sender - (void) print: (id)sender
{} {
}
// //
// NSCoding protocol // NSCoding protocol

View file

@ -33,6 +33,7 @@
#include "AppKit/NSResponder.h" #include "AppKit/NSResponder.h"
#include "AppKit/NSInterfaceStyle.h" #include "AppKit/NSInterfaceStyle.h"
#include "GNUstepGUI/GSTheme.h"
NSString *NSInterfaceStyleDefault = @"NSInterfaceStyleDefault"; NSString *NSInterfaceStyleDefault = @"NSInterfaceStyleDefault";
@ -173,6 +174,11 @@ NSInterfaceStyleForKey(NSString *key, NSResponder *responder)
selector: @selector(defaultsDidChange:) selector: @selector(defaultsDidChange:)
name: NSUserDefaultsDidChangeNotification name: NSUserDefaultsDidChangeNotification
object: nil]; object: nil];
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(defaultsDidChange:)
name: GSThemeDidActivateNotification
object: nil];
} }
} }
@ -183,6 +189,12 @@ NSInterfaceStyleForKey(NSString *key, NSResponder *responder)
NSString *key; NSString *key;
void *val; void *val;
/*
* We ignore the actual notification, which may be nil (when called at
* initialization), or may contain a user defaults object (if a persistent
* domain changed), or may contain a theme object (if a theme activated).
* What we need to do is examine the current state of the standard defaults.
*/
defs = [NSUserDefaults standardUserDefaults]; defs = [NSUserDefaults standardUserDefaults];
/* /*

View file

@ -120,10 +120,11 @@ static NSNotificationCenter *nc;
@interface NSMenu (GNUstepPrivate) @interface NSMenu (GNUstepPrivate)
- (NSString *) _locationKey;
- (NSMenuPanel *) _createWindow; - (NSMenuPanel *) _createWindow;
- (void) _updateUserDefaults: (id) notification; - (NSString *) _locationKey;
- (void) _rightMouseDisplay: (NSEvent*)theEvent; - (void) _rightMouseDisplay: (NSEvent*)theEvent;
- (void) _setGeometry;
- (void) _updateUserDefaults: (id) notification;
@end @end
@ -204,38 +205,78 @@ static NSNotificationCenter *nc;
- (void) _organizeMenu - (void) _organizeMenu
{ {
if (_horizontal == YES) int i;
if ([self isEqual: [NSApp mainMenu]] == YES)
{ {
NSString *title = [[NSProcessInfo processInfo] processName]; NSString *appTitle;
NSMenu *appMenu = [[self itemWithTitle: title] submenu]; NSMenu *appMenu;
NSMenuItem *appItem;
if (![self isEqual: [NSApp mainMenu]]) appTitle = [[NSProcessInfo processInfo] processName];
return; appItem = (NSMenuItem *)[self itemWithTitle: appTitle];
appMenu = [appItem submenu];
if (appMenu == nil) if (_horizontal == YES)
{ {
int i; NSMutableArray *itemsToMove;
NSMutableArray *itemsToMove = [NSMutableArray new]; NSImage *ti;
NSMenuItem *appItem; float bar;
NSImage *ti = [[NSApp applicationIconImage] copy];
float bar = [NSMenuView menuBarHeight] - 4;
appMenu = [NSMenu new]; ti = [[NSApp applicationIconImage] copy];
if (ti == nil)
for (i = 0; i < [_items count]; i++)
{ {
NSMenuItem *anItem = [_items objectAtIndex: i]; ti = [[NSImage imageNamed: @"GNUstep"] copy];
NSString *title = [anItem title]; }
[ti setScalesWhenResized: YES];
bar = [NSMenuView menuBarHeight] - 4;
[ti setSize: NSMakeSize(bar, bar)];
if (![anItem submenu]) 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);
}
}
[appItem setImage: ti];
RELEASE(ti);
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]; [itemsToMove addObject: anItem];
} }
else
if ([title isEqual: NSLocalizedString (@"Info",
@"Info")])
{ {
[itemsToMove addObject: anItem]; if ([title isEqual: NSLocalizedString (@"Info", @"Info")])
{
[itemsToMove addObject: anItem];
}
[[submenu menuRepresentation] update];
} }
} }
@ -244,76 +285,99 @@ static NSNotificationCenter *nc;
[self removeItem: [itemsToMove objectAtIndex: i]]; [self removeItem: [itemsToMove objectAtIndex: i]];
[appMenu addItem: [itemsToMove objectAtIndex: i]]; [appMenu addItem: [itemsToMove objectAtIndex: i]];
} }
[[appMenu menuRepresentation] update];
[self insertItemWithTitle: [[NSProcessInfo processInfo] processName] RELEASE(itemsToMove);
action: NULL
keyEquivalent: @""
atIndex: 0];
appItem = (NSMenuItem *)[self itemWithTitle: title];
if (!ti)
ti = [[NSImage imageNamed: @"GNUstep"] copy];
[ti setScalesWhenResized: YES];
[ti setSize: NSMakeSize(bar, bar)];
[appItem setImage: ti];
RELEASE (ti);
[self setSubmenu: appMenu forItem: appItem];
[itemsToMove release];
} }
else else
{ {
int i; [appItem setImage: nil];
NSMutableArray *itemsToMove = [NSMutableArray new]; if (appMenu != nil)
NSMenuItem *appItem = [self itemWithTitle: [[NSProcessInfo processInfo] processName]];
int index = [self indexOfItem: appItem];
NSImage *ti = [[NSApp applicationIconImage] copy];
float bar = [NSMenuView menuBarHeight] - 4;
if (!ti)
ti = [[NSImage imageNamed: @"GNUstep"] copy];
[ti setScalesWhenResized: YES];
[ti setSize: NSMakeSize(bar, bar)];
[appItem setImage: ti];
RELEASE (ti);
if (index != 0)
{ {
RETAIN (appItem); NSArray *array = [NSArray arrayWithArray: [appMenu itemArray]];
[self removeItemAtIndex: index];
[self insertItem: appItem atIndex: 0];
RELEASE (appItem);
}
for (i = 0; i < [_items count]; i++) for (i = 0; i < [array count]; i++)
{ {
NSMenuItem *anItem = [_items objectAtIndex: i]; NSMenuItem *anItem = [array objectAtIndex: i];
NSString *title = [anItem title]; NSMenu *submenu = [anItem submenu];
if (![anItem submenu]) [appMenu removeItem: anItem];
{ if (submenu == nil)
[itemsToMove addObject: anItem]; {
} [self addItem: anItem];
}
if ([title isEqual: NSLocalizedString (@"Info", else
@"Info")]) {
{ [self insertItem: anItem atIndex: 0]; // Info menu
[itemsToMove addObject: anItem]; }
} }
[self removeItem: appItem];
} }
for (i = 0; i < [itemsToMove count]; i++)
{
[self removeItem: [itemsToMove objectAtIndex: i]];
[appMenu addItem: [itemsToMove objectAtIndex: i]];
}
[itemsToMove release];
} }
} }
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];
}
- (void) _setGeometry
{
NSPoint origin;
if (_horizontal == YES)
{
origin = NSMakePoint (0, [[NSScreen mainScreen] frame].size.height
- [_aWindow frame].size.height);
[_aWindow setFrameOrigin: origin];
[_bWindow setFrameOrigin: origin];
}
else
{
NSString *key;
if (nil != (key = [self _locationKey]))
{
NSUserDefaults *defaults;
NSDictionary *menuLocations;
NSString *location;
defaults = [NSUserDefaults standardUserDefaults];
menuLocations = [defaults objectForKey: NSMenuLocationsKey];
if ([menuLocations isKindOfClass: [NSDictionary class]])
location = [menuLocations objectForKey: key];
else
location = nil;
if (location && [location isKindOfClass: [NSString class]])
{
[_aWindow setFrameFromString: location];
[_bWindow setFrameFromString: location];
return;
}
}
origin = NSMakePoint(0, [[_aWindow screen] visibleFrame].size.height
- [_aWindow frame].size.height);
[_aWindow setFrameOrigin: origin];
[_bWindow setFrameOrigin: origin];
}
} }
/** /**
@ -543,7 +607,7 @@ static NSNotificationCenter *nc;
else else
[_notifications addObject: inserted]; [_notifications addObject: inserted];
// Set this after the insert notification has been send. // Set this after the insert notification has been sent.
[newItem setMenu: self]; [newItem setMenu: self];
} }
@ -1407,9 +1471,9 @@ static NSNotificationCenter *nc;
_superMenu->_attachedMenu = self; _superMenu->_attachedMenu = self;
} }
else if ([_aWindow frame].origin.y <= 0 else if ([_aWindow frame].origin.y <= 0
&& _popUpButtonCell == nil) // get geometry only if not set && _popUpButtonCell == nil) // get geometry only if not set
{ {
[self setGeometry]; [self _setGeometry];
} }
NSDebugLLog (@"NSMenu", NSDebugLLog (@"NSMenu",
@ -1472,51 +1536,6 @@ static NSNotificationCenter *nc;
[_bWindow orderFront: self]; [_bWindow orderFront: self];
} }
- (void) setGeometry
{
NSPoint origin;
if (_horizontal == YES)
{
origin = NSMakePoint (0, [[NSScreen mainScreen] frame].size.height
- [_aWindow frame].size.height);
[_aWindow setFrameOrigin: origin];
[_bWindow setFrameOrigin: origin];
}
else
{
NSString *key;
if (nil != (key = [self _locationKey]))
{
NSUserDefaults *defaults;
NSDictionary *menuLocations;
NSString *location;
defaults = [NSUserDefaults standardUserDefaults];
menuLocations = [defaults objectForKey: NSMenuLocationsKey];
if ([menuLocations isKindOfClass: [NSDictionary class]])
location = [menuLocations objectForKey: key];
else
location = nil;
if (location && [location isKindOfClass: [NSString class]])
{
[_aWindow setFrameFromString: location];
[_bWindow setFrameFromString: location];
return;
}
}
origin = NSMakePoint(0, [[_aWindow screen] visibleFrame].size.height
- [_aWindow frame].size.height);
[_aWindow setFrameOrigin: origin];
[_bWindow setFrameOrigin: origin];
}
}
- (void) close - (void) close
{ {
NSMenu *sub = [self attachedMenu]; NSMenu *sub = [self attachedMenu];
@ -1591,22 +1610,40 @@ static NSNotificationCenter *nc;
{ {
if (isMain) if (isMain)
{ {
/* NSMenuView *oldRep;
* If necessary,. rebuild menu for macintosh (horizontal) style NSInterfaceStyle oldStyle;
*/ NSInterfaceStyle newStyle;
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil)
== NSMacintoshInterfaceStyle)
{
NSMenuView *rep = [[NSMenuView alloc] initWithFrame: NSZeroRect];
[rep setHorizontal: YES]; oldRep = [self menuRepresentation];
[self setMenuRepresentation: rep]; oldStyle = [oldRep interfaceStyle];
newStyle = NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil);
/*
* If necessary, rebuild menu for (different) style
*/
if (oldStyle != newStyle)
{
NSMenuView *newRep;
newRep = [[NSMenuView alloc] initWithFrame: NSZeroRect];
if (newStyle == NSMacintoshInterfaceStyle)
{
[newRep setHorizontal: YES];
}
else
{
[newRep setHorizontal: NO];
}
[newRep setInterfaceStyle: newStyle];
[self setMenuRepresentation: newRep];
[self _organizeMenu]; [self _organizeMenu];
RELEASE(rep); RELEASE(newRep);
} }
[[self window] setTitle: [[NSProcessInfo processInfo] processName]]; [[self window] setTitle: [[NSProcessInfo processInfo] processName]];
[[self window] setLevel: NSMainMenuWindowLevel]; [[self window] setLevel: NSMainMenuWindowLevel];
[self setGeometry]; [self _setGeometry];
[self sizeToFit];
if ([NSApp isActive]) if ([NSApp isActive])
{ {

View file

@ -74,11 +74,11 @@ static NSMapTable *viewInfo = 0;
@class NSButton; @class NSButton;
@interface NSMenuView (Private) @interface NSMenuView (Private)
- (BOOL) _rootIsHorizontal; - (BOOL) _rootIsHorizontal: (BOOL*)isAppMenu;
@end @end
@implementation NSMenuView (Private) @implementation NSMenuView (Private)
- (BOOL) _rootIsHorizontal - (BOOL) _rootIsHorizontal: (BOOL*)isAppMenu
{ {
NSMenu *m = _attachedMenu; NSMenu *m = _attachedMenu;
@ -87,6 +87,17 @@ static NSMapTable *viewInfo = 0;
{ {
m = [m supermenu]; m = [m supermenu];
} }
if (isAppMenu != 0)
{
if (m == [NSApp mainMenu])
{
*isAppMenu = YES;
}
else
{
*isAppMenu = NO;
}
}
return [[m menuRepresentation] isHorizontal]; return [[m menuRepresentation] isHorizontal];
} }
@end @end
@ -220,6 +231,8 @@ _addLeftBorderOffsetToRect(NSRect aRect)
- (void) setMenu: (NSMenu*)menu - (void) setMenu: (NSMenu*)menu
{ {
NSNotificationCenter *theCenter = [NSNotificationCenter defaultCenter]; NSNotificationCenter *theCenter = [NSNotificationCenter defaultCenter];
unsigned count;
unsigned i;
if (_attachedMenu != nil) if (_attachedMenu != nil)
{ {
@ -248,30 +261,25 @@ _addLeftBorderOffsetToRect(NSRect aRect)
selector: @selector(itemRemoved:) selector: @selector(itemRemoved:)
name: NSMenuDidRemoveItemNotification name: NSMenuDidRemoveItemNotification
object: _attachedMenu]; object: _attachedMenu];
// Force menu view's layout to be recalculated.
[self setNeedsSizing: YES];
[self update];
} }
if (_horizontal)
count = [[[self menu] itemArray] count];
for (i = 0; i < count; i++)
{ {
unsigned count = [[[self menu] itemArray] count]; NSNumber *n = [NSNumber numberWithInt: i];
unsigned i; NSDictionary *d;
for (i = 0; i < count; i++) d = [NSDictionary dictionaryWithObject: n forKey: @"NSMenuItemIndex"];
{
NSNumber *n = [NSNumber numberWithInt: i];
NSDictionary *d;
d = [NSDictionary dictionaryWithObject: n forKey: @"NSMenuItemIndex"]; [self itemAdded: [NSNotification
notificationWithName: NSMenuDidAddItemNotification
[self itemAdded: [NSNotification object: self
notificationWithName: NSMenuDidAddItemNotification userInfo: d]];
object: self
userInfo: d]];
}
} }
// Force menu view's layout to be recalculated.
[self setNeedsSizing: YES];
[self update];
} }
- (NSMenu*) menu - (NSMenu*) menu
@ -559,43 +567,55 @@ _addLeftBorderOffsetToRect(NSRect aRect)
*/ */
- (void) update - (void) update
{ {
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", self) BOOL needTitleView;
== NSMacintoshInterfaceStyle) BOOL rootIsAppMenu;
NSDebugLLog (@"NSMenu", @"update called on menu view");
/*
* Ensure that a title view exists only if needed.
*/
if (_attachedMenu == nil)
{ {
[self sizeToFit]; needTitleView = NO;
}
else if ([self _rootIsHorizontal: &rootIsAppMenu] == YES)
{
needTitleView = NO;
}
else if (rootIsAppMenu == YES)
{
needTitleView = YES;
} }
else else
{ {
NSDebugLLog (@"NSMenu", @"update called on menu view"); needTitleView = ([_attachedMenu _ownedByPopUp] == YES) ? NO : YES;
}
/* if (needTitleView == YES && _titleView == nil)
* Ensure that a title view exists only if needed. {
*/ _titleView = [[GSTitleView alloc] initWithOwner: _attachedMenu];
if (![_attachedMenu _ownedByPopUp] && !_titleView) [self addSubview: _titleView];
RELEASE(_titleView);
}
if (needTitleView == NO && _titleView != nil)
{
[_titleView removeFromSuperview];
_titleView = nil;
}
[self sizeToFit];
if ([_attachedMenu _ownedByPopUp] == NO)
{
if ([_attachedMenu isTornOff] && ![_attachedMenu isTransient])
{ {
_titleView = [[GSTitleView alloc] initWithOwner:_attachedMenu]; [_titleView
[self addSubview: _titleView]; addCloseButtonWithAction: @selector(_performMenuClose:)];
RELEASE(_titleView);
} }
else if ([_attachedMenu _ownedByPopUp] && _titleView) else
{ {
[_titleView removeFromSuperview]; [_titleView removeCloseButton];
_titleView = nil;
}
[self sizeToFit];
if ([_attachedMenu _ownedByPopUp] == NO)
{
if ([_attachedMenu isTornOff] && ![_attachedMenu isTransient])
{
[_titleView
addCloseButtonWithAction: @selector(_performMenuClose:)];
}
else
{
[_titleView removeCloseButton];
}
} }
} }
} }
@ -809,9 +829,8 @@ _addLeftBorderOffsetToRect(NSRect aRect)
+ menuBarHeight)]; + menuBarHeight)];
[_titleView setFrame: NSMakeRect (0, howMany * _cellSize.height, [_titleView setFrame: NSMakeRect (0, howMany * _cellSize.height,
NSWidth (_bounds), menuBarHeight)]; NSWidth (_bounds), menuBarHeight)];
_needsSizing = NO;
} }
_needsSizing = NO;
} }
- (float) stateImageOffset - (float) stateImageOffset
@ -969,15 +988,15 @@ _addLeftBorderOffsetToRect(NSRect aRect)
subOrigin.y - NSHeight(submenuFrame) - 3 + subOrigin.y - NSHeight(submenuFrame) - 3 +
2*[NSMenuView menuBarHeight]); 2*[NSMenuView menuBarHeight]);
} }
else if ([self _rootIsHorizontal] == YES) else if ([self _rootIsHorizontal: 0] == YES)
{ {
NSRect aRect = [self rectOfItemAtIndex: NSRect aRect = [self rectOfItemAtIndex:
[_attachedMenu indexOfItemWithSubmenu: aSubmenu]]; [_attachedMenu indexOfItemWithSubmenu: aSubmenu]];
NSPoint subOrigin = [_window convertBaseToScreen: NSPoint subOrigin = [_window convertBaseToScreen:
NSMakePoint(aRect.origin.x, aRect.origin.y)]; NSMakePoint(aRect.origin.x, aRect.origin.y)];
// FIXME ... why is the offset +1 needed below?
return NSMakePoint (NSMaxX(frame), return NSMakePoint (NSMaxX(frame),
subOrigin.y - NSHeight(submenuFrame) + aRect.size.height); subOrigin.y - NSHeight(submenuFrame) + aRect.size.height + 1);
} }
else else
{ {
@ -1042,7 +1061,8 @@ _addLeftBorderOffsetToRect(NSRect aRect)
// Compute position for popups, if needed // Compute position for popups, if needed
if (selectedItemIndex != -1) if (selectedItemIndex != -1)
{ {
screenFrame.origin.y += screenRect.size.height * selectedItemIndex; screenFrame.origin.y
+= screenRect.size.height * selectedItemIndex;
} }
} }
else else

View file

@ -1534,6 +1534,10 @@ many times.
if (place == NSWindowOut) if (place == NSWindowOut)
{ {
if (_windowNum == 0)
{
return; /* This deferred window was never ordered in. */
}
_f.visible = NO; _f.visible = NO;
/* /*
* Don't keep trying to update the window while it is ordered out * Don't keep trying to update the window while it is ordered out