From 39fbad9a4214b25c005bb1c5dc3481e1993f1dde Mon Sep 17 00:00:00 2001 From: rfm Date: Sat, 14 Jan 2012 16:10:48 +0000 Subject: [PATCH] Cleanup/simplify code for handling theme names in defaults system git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@34527 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 5 +++ Headers/Additions/GNUstepGUI/GSTheme.h | 56 +++++++++++++------------- Source/GSTheme.m | 51 ++++++++++++----------- 3 files changed, 60 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45e9b5905..aedeab71a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-14 Richard Frith-Macdonald + + * Source/GSTheme.m: Clean up and simplify theme switching based on + defaults system values. + 2012-01-12 Fred Kiefer * Source/GSStandardWindowDecorationView.m (-mouseDown:): Pass the diff --git a/Headers/Additions/GNUstepGUI/GSTheme.h b/Headers/Additions/GNUstepGUI/GSTheme.h index a73eac7e6..02234ba73 100644 --- a/Headers/Additions/GNUstepGUI/GSTheme.h +++ b/Headers/Additions/GNUstepGUI/GSTheme.h @@ -133,7 +133,7 @@

While many themes can be created without subclassing GSTheme, there are some cases where writing code is necessary (most - notably when interfacing to a native themeing engine for some + notably when interfacing to a native theming engine for some platform in order to make a GNUstep app have a native look).
In these cases the subclass should follow certain rules in order to operate cleanly and efficiently: @@ -160,17 +160,17 @@ with versions stored in the theme bundle.
If a subclass wishes to dynamically provide these resources rather than supplying them as static information in the bundle, it may - update the in-memory information after the normal opertation has + update the in-memory information after the normal operation has taken place. This should be done by the theme registering itsself as an observer of GSThemeWillActivateNotification and adding the - resources just before the theme bocomes active.
+ resources just before the theme becomes active.
Cleanup may be done in response to a GSThemeWillDeactivateNotification (called before the default cleanup) or a GSThemeDidDeactivateNotification (called after the default cleanup). Versioning - With a theme which contains opnly static resources, versioning is + With a theme which contains only static resources, versioning is not much of an issue, but with a code-based theme (ie where you subclass GSTheme) versioning does become very important. This is because, while you can load code from a bundle, you can't unload @@ -460,7 +460,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

This method is called automatically when the receiver is made into * the currently active theme by the +setTheme: method. Subclasses may * override it to perform startup operations, however, the method is not - * really intended to be overridden, and subcasses should generally + * really intended to be overridden, and subclasses should generally * handle activation work in response to the GSThemeWillActivatenotification * posted by this method. *

@@ -475,7 +475,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

Finally, this method marks all windows in the application as needing * update ... so they will draw themselves with the new theme information. *

- *

NB. If a GSTheme subclass is integrating to an external native themeing + *

NB. If a GSTheme subclass is integrating to an external native theming * mechanism in order to make GNUstep apps look like native apps, then the * external theme may change dynamically and the GSTheme subclass may need * to change the GNUstep application to reflect this change. When this @@ -547,7 +547,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; * sends a GSThemeDidDeactivateNotification to allow other parts of the * GUI library to update themselves. *

- *

NB. If a GSTheme subclass is integrating to an external native themeing + *

NB. If a GSTheme subclass is integrating to an external native theming * mechanism in order to make GNUstep apps look like native apps, then the * external theme may change dynamically and the GSTheme subclass may need * to change the GNUstep application to reflect this change. When this @@ -602,14 +602,14 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; * * FileName * Name of the file (within the GSThemeTiles directory in the - * bundle) in which the image for this tile is tored. + * bundle) in which the image for this tile is stored. * * HorizontalDivision - * The offet along the X-axis used to divide the image into + * The offset along the X-axis used to divide the image into * columns of tiles. * * VerticalDivision - * The offet along the Y-axis used to divide the image into + * The offer along the Y-axis used to divide the image into * rows of tiles. * * @@ -623,7 +623,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; */ - (NSString*) name; -/** Returns the name used to locate theming resources for a particular gui +/** Returns the name used to locate theming resources for a particular GUI * element. If no name has been set for the particular object this method * returns nil. */ @@ -649,7 +649,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; - (void) setName: (NSString*)aString; /** Set the name that is used to identify theming resources for a particular - * control or other gui element. This is used so that where an element is + * control or other GUI element. This is used so that where an element is * part of a control it can be displayed differently from the same class of * element used outside that control.
* Supplying a nil value for aString simply removes any name setting for @@ -673,13 +673,13 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; * and the authors of the theme. *

*

The code managing this object (if any) must be prepared to have the - * content view of the window reparented into another window for display + * content view of the window re-parented into another window for display * on screen. *

*/ - (NSWindow*) themeInspector; -/** Removes the name tile images from cahce, forcing re-creation next +/** Removes the name tile images from cache, forcing re-creation next * time the named tiles are required.
* Passing nil for aName removes all named tiles.
* Passing a negative value for elementState applies to all caches. @@ -699,7 +699,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; * The elementState argument specifies the state for which tiles are * requested. * See the -colorNamed:state: method for determining colors to be - * used for drawing specific gui elements. + * used for drawing specific GUI elements. */ - (GSDrawTiles*) tilesNamed: (NSString*)aName state: (GSThemeControlState)elementState; @@ -715,7 +715,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; * Theme drawing methods.
* Methods which return information/resources are generally expected * (ie unless explicitly documented otherwise) to be returning something - * which persists until the mewthod is called again or until the current + * which persists until the method is called again or until the current * theme is deactivated (whichever comes first).
* This means that drawing code should not need to * retain/release any returned object (the theme is responsible for @@ -822,7 +822,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; - (float) defaultScrollerWidth; /** - * Method fors toolbar theming. + * Method for toolbar theming. */ - (NSColor *) toolbarBackgroundColor; - (NSColor *) toolbarBorderColor; @@ -886,7 +886,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

The returned color is used by * -drawBackgroundForMenuView:withFrame:dirtyRect:horizontal:

* - *

Can be overriden in subclasses to return a custom color.

+ *

Can be overridden in subclasses to return a custom color.

*/ - (NSColor *) menuBackgroundColor; /** @@ -903,7 +903,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; * -drawBorderAndBackgroundForMenuItemCell:withFrame:inView:state:isHorizontal: * and [NSMenuItemCell-backgroundColor].

* - *

Can be overriden in subclasses to return a custom color.

+ *

Can be overridden in subclasses to return a custom color.

*/ - (NSColor *) menuItemBackgroundColor; - (NSColor *) menuBarBackgroundColor; @@ -917,7 +917,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

The returned color is used by * -drawBackgroundForMenuView:withFrame:dirtyRect:horizontal:

* - *

Can be overriden in subclasses to return a custom color.

+ *

Can be overridden in subclasses to return a custom color.

*/ - (NSColor *) menuBorderColor; /** @@ -929,7 +929,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

The returned edge color is used by * -drawBackgroundForMenuView:withFrame:dirtyRect:horizontal:

* - *

Can be overriden in subclasses to return a custom color per edge.

+ *

Can be overridden in subclasses to return a custom color per edge.

*/ - (NSColor *) menuBorderColorForEdge: (NSRectEdge)edge isHorizontal: (BOOL)horizontal; @@ -946,7 +946,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

The returned value used by * -drawBorderAndBackgroundForMenuItemCell:withFrame:inView:state:isHorizontal:

* - *

Can be overriden in subclasses.

+ *

Can be overridden in subclasses.

*/ - (BOOL) drawsBorderForMenuItemCell: (NSMenuItemCell *)cell state: (GSThemeControlState)state @@ -960,7 +960,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; /** *

Draws the menu item title.

* - *

Can be overriden to customize the text font, size and position.
+ *

Can be overridden to customize the text font, size and position.
* You can use [[cell menuItem] title] to get the title.

* *

The title color is mapped to the theme state as described below:

@@ -984,7 +984,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

The returned color is used by * -drawSeparatorItemForMenuItemCell:withFrame:inView:isHorizontal:

* - *

Can be overriden in subclasses to return a custom color.

+ *

Can be overridden in subclasses to return a custom color.

*/ - (NSColor *) menuSeparatorColor; /** @@ -995,7 +995,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; *

The returned color is used by * -drawSeparatorItemForMenuItemCell:withFrame:inView:isHorizontal:

* - *

Can be overriden in subclasses to return a custom value.

+ *

Can be overridden in subclasses to return a custom value.

*/ - (CGFloat) menuSeparatorInset; /** @@ -1006,7 +1006,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; * *

You can provide an image tile named GSMenuSeparatorItem to * draw the separator.
- * Can be overriden in subclasses to customize the drawing.

+ * Can be overridden in subclasses to customize the drawing.

* *

See also -menuSeparatorColor and -menuSeparatorInset

*/ @@ -1140,7 +1140,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; inRect: (NSRect)border withClip: (NSRect)clip; -/** Draw a grey bezel border */ +/** Draw a gray bezel border */ - (NSRect) drawGrayBezel: (NSRect)border withClip: (NSRect)clip; /** Draw a groove border */ @@ -1155,7 +1155,7 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification; @end /** - * Low level drawiong methods ... themes may use these for drawing, + * Low level drawing methods ... themes may use these for drawing, * but should not normally override them. */ @interface GSTheme (LowLevelDrawing) diff --git a/Source/GSTheme.m b/Source/GSTheme.m index 5189d2158..a709f0180 100644 --- a/Source/GSTheme.m +++ b/Source/GSTheme.m @@ -231,7 +231,6 @@ GSStringFromBorderType(NSBorderType borderType) @implementation GSTheme static GSTheme *defaultTheme = nil; -static NSString *currentThemeName = nil; static GSTheme *theTheme = nil; static NSMutableDictionary *themes = nil; static NSNull *null = nil; @@ -273,10 +272,17 @@ typedef struct { defs = [NSUserDefaults standardUserDefaults]; name = [defs stringForKey: @"GSTheme"]; - if (name != currentThemeName && [name isEqual: currentThemeName] == NO) + if (0 == [name length]) + { + name = @"GNUstep"; + } + else if ([[name pathExtension] isEqual: @"theme"]) + { + name = [name stringByDeletingPathExtension]; + } + if (NO == [[name lastPathComponent] isEqual: [theTheme name]]) { [self setTheme: [self loadThemeNamed: name]]; - ASSIGN(currentThemeName, name); // Don't try to load again. } } @@ -288,13 +294,12 @@ typedef struct { null = RETAIN([NSNull null]); defaultTheme = [[self alloc] initWithBundle: nil]; ASSIGN(theTheme, defaultTheme); - ASSIGN(currentThemeName, [defaultTheme name]); names = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSIntMapValueCallBacks, 0); + /* Establish the theme specified by the user defaults (if any); + */ + [self defaultsDidChange: nil]; } - /* Establish the theme specified by the user defaults (if any); - */ - [self defaultsDidChange: nil]; } + (GSTheme*) loadThemeNamed: (NSString*)aName @@ -304,7 +309,11 @@ typedef struct { GSTheme *instance; NSString *theme; - if ([aName length] == 0) + if ([[aName pathExtension] isEqual: @"theme"]) + { + aName = [aName stringByDeletingPathExtension]; + } + if ([aName length] == 0 || [[aName lastPathComponent] isEqual: @"GNUstep"]) { return defaultTheme; } @@ -316,21 +325,17 @@ typedef struct { else { aName = [aName lastPathComponent]; + } - /* Ensure that the theme name has the 'theme' extension. - */ - if ([[aName pathExtension] isEqualToString: @"theme"] == YES) - { - theme = aName; - } - else - { - theme = [aName stringByAppendingPathExtension: @"theme"]; - } - if ([theme isEqualToString: @"GNUstep.theme"] == YES) - { - return defaultTheme; - } + /* Ensure that the theme name has the 'theme' extension. + */ + if ([[aName pathExtension] isEqualToString: @"theme"] == YES) + { + theme = aName; + } + else + { + theme = [aName stringByAppendingPathExtension: @"theme"]; } bundle = [themes objectForKey: theme]; @@ -415,10 +420,8 @@ typedef struct { removeObserver: self]; [theTheme deactivate]; - DESTROY(currentThemeName); ASSIGN (theTheme, theme); [theTheme activate]; - ASSIGN(currentThemeName, [theTheme name]); /* * Listen to notifications...