mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 07:00:46 +00:00
Some moves towards making scrollers more themable
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@27518 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
99adecef26
commit
62492a9158
6 changed files with 179 additions and 60 deletions
|
@ -2,9 +2,15 @@
|
|||
|
||||
* Headers/Additions/GNUstepGUI/GSTheme.h:
|
||||
* Source/GSTheme.m:
|
||||
* Source/NSButtonCell.m:
|
||||
* Source/NSScroller.m:
|
||||
* Source/GSThemeDrawing.m:
|
||||
Add methods to name specific elements in the gui so that we can
|
||||
locate resources for them and so that override methods can handle
|
||||
them specially.
|
||||
Change tile image lookup for improved consistency/simplicity and
|
||||
to use new naming.
|
||||
Add naming of component parts of a scroller.
|
||||
|
||||
2009-01-04 18:32-EST Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
|
|
|
@ -155,6 +155,18 @@
|
|||
@class NSMenuView;
|
||||
@class GSDrawTiles;
|
||||
|
||||
/* Names for the component parts of a scroller,
|
||||
* allowing tiles and/or colors to be set for them.
|
||||
*/
|
||||
APPKIT_EXPORT NSString *GSScrollerDownArrow;
|
||||
APPKIT_EXPORT NSString *GSScrollerHorizontalKnob;
|
||||
APPKIT_EXPORT NSString *GSScrollerHorizontalSlot;
|
||||
APPKIT_EXPORT NSString *GSScrollerLeftArrow;
|
||||
APPKIT_EXPORT NSString *GSScrollerRightArrow;
|
||||
APPKIT_EXPORT NSString *GSScrollerUpArrow;
|
||||
APPKIT_EXPORT NSString *GSScrollerVerticalKnob;
|
||||
APPKIT_EXPORT NSString *GSScrollerVerticalSlot;
|
||||
|
||||
/**
|
||||
* This defines how the values in a tile array should be used when
|
||||
* drawing a rectangle. Mostly this just effects the center, middle
|
||||
|
@ -379,8 +391,8 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification;
|
|||
- (NSString*) name;
|
||||
|
||||
/** Returns the name used to locate theming resources for a particular gui
|
||||
* element. If no name has been set for the particular object, the name
|
||||
* for the class of object is returned.
|
||||
* element. If no name has been set for the particular object this method
|
||||
* returns nil.
|
||||
*/
|
||||
- (NSString*) nameForElement: (id)anObject;
|
||||
|
||||
|
@ -389,12 +401,16 @@ 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. The name set for a specific element will
|
||||
* override the default (the name of the class of the element), and 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.<br />
|
||||
* 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.<br />
|
||||
* Supplying a nil value for aString simply removes any name setting for
|
||||
* anObject.
|
||||
* anObject.<br />
|
||||
* Supplying nil for anObject is illegal (raises an exception) unless
|
||||
* the value of aString is also nil (and the method does nothing).<br />
|
||||
* Any control which uses this method to set names for subsidiary elements
|
||||
* must also make sure to remove the name mapping before that element is
|
||||
* deallocated.
|
||||
*/
|
||||
- (void) setName: (NSString*)aString forElement: (id)anObject;
|
||||
|
||||
|
@ -417,10 +433,14 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification;
|
|||
* information to draw user interface elements. The tile information
|
||||
* returned by this method can be passed to the
|
||||
* -fillRect:withTiles:background:fillStyle: method.<br />
|
||||
* The elementState argument specifies the state for which tiles are
|
||||
* requested.<br />
|
||||
* The useCache argument controls whether the information is retrieved
|
||||
* from cache or regenerated from information in the theme bundle.
|
||||
*/
|
||||
- (GSDrawTiles*) tilesNamed: (NSString*)aName cache: (BOOL)useCache;
|
||||
- (GSDrawTiles*) tilesNamed: (NSString*)aName
|
||||
state: (GSThemeControlState)elementState
|
||||
cache: (BOOL)useCache;
|
||||
@end
|
||||
|
||||
/**
|
||||
|
@ -441,8 +461,9 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification;
|
|||
/**
|
||||
* Amount by which the button is inset by the border.
|
||||
*/
|
||||
- (NSSize) buttonBorderForStyle: (int)style
|
||||
state: (GSThemeControlState)state;
|
||||
- (NSSize) buttonBorderForCell: (NSCell*)cell
|
||||
style: (int)style
|
||||
state: (GSThemeControlState)state;
|
||||
|
||||
/**
|
||||
* Draws the indicator (normally a dotted rectangle) to show that
|
||||
|
|
107
Source/GSTheme.m
107
Source/GSTheme.m
|
@ -57,6 +57,15 @@
|
|||
#import "AppKit/PSOperators.h"
|
||||
#import "GSThemePrivate.h"
|
||||
|
||||
// Scroller part names
|
||||
NSString *GSScrollerDownArrow = @"GSScrollerDownArrow";
|
||||
NSString *GSScrollerHorizontalKnob = @"GSScrollerHorizontalKnob";
|
||||
NSString *GSScrollerHorizontalSlot = @"GSScrollerHorizontalSlot";
|
||||
NSString *GSScrollerLeftArrow = @"GSScrollerLeftArrow";
|
||||
NSString *GSScrollerRightArrow = @"GSScrollerRightArrow";
|
||||
NSString *GSScrollerUpArrow = @"GSScrollerUpArrow";
|
||||
NSString *GSScrollerVerticalKnob = @"GSScrollerVerticalKnob";
|
||||
NSString *GSScrollerVerticalSlot = @"GSScrollerVerticalSlot";
|
||||
|
||||
NSString *GSThemeDidActivateNotification
|
||||
= @"GSThemeDidActivateNotification";
|
||||
|
@ -80,18 +89,22 @@ typedef struct {
|
|||
NSBundle *bundle;
|
||||
NSColorList *colors;
|
||||
NSMutableDictionary *images;
|
||||
NSMutableDictionary *tiles;
|
||||
NSMutableDictionary *normalTiles;
|
||||
NSMutableDictionary *highlightedTiles;
|
||||
NSMutableDictionary *selectedTiles;
|
||||
NSImage *icon;
|
||||
NSString *name;
|
||||
} internal;
|
||||
|
||||
#define _internal ((internal*)_reserved)
|
||||
#define _bundle _internal->bundle
|
||||
#define _colors _internal->colors
|
||||
#define _images _internal->images
|
||||
#define _tiles _internal->tiles
|
||||
#define _icon _internal->icon
|
||||
#define _name _internal->name
|
||||
#define _internal ((internal*)_reserved)
|
||||
#define _bundle _internal->bundle
|
||||
#define _colors _internal->colors
|
||||
#define _images _internal->images
|
||||
#define _normalTiles _internal->normalTiles
|
||||
#define _highlightedTiles _internal->highlightedTiles
|
||||
#define _selectedTiles _internal->selectedTiles
|
||||
#define _icon _internal->icon
|
||||
#define _name _internal->name
|
||||
|
||||
+ (void) defaultsDidChange: (NSNotification*)n
|
||||
{
|
||||
|
@ -322,7 +335,7 @@ typedef struct {
|
|||
|
||||
/*
|
||||
* We could cache tile info here, but it's probably better for the
|
||||
* tilesNamed:cache: method to do it lazily.
|
||||
* tilesNamed:state:cache: method to do it lazily.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -475,7 +488,9 @@ typedef struct {
|
|||
RELEASE(_bundle);
|
||||
RELEASE(_colors);
|
||||
RELEASE(_images);
|
||||
RELEASE(_tiles);
|
||||
RELEASE(_normalTiles);
|
||||
RELEASE(_highlightedTiles);
|
||||
RELEASE(_selectedTiles);
|
||||
RELEASE(_icon);
|
||||
NSZoneFree ([self zone], _reserved);
|
||||
}
|
||||
|
@ -514,7 +529,9 @@ typedef struct {
|
|||
|
||||
ASSIGN(_bundle, bundle);
|
||||
_images = [NSMutableDictionary new];
|
||||
_tiles = [NSMutableDictionary new];
|
||||
_normalTiles = [NSMutableDictionary new];
|
||||
_highlightedTiles = [NSMutableDictionary new];
|
||||
_selectedTiles = [NSMutableDictionary new];
|
||||
ASSIGN(_name,
|
||||
[[[_bundle bundlePath] lastPathComponent] stringByDeletingPathExtension]);
|
||||
|
||||
|
@ -539,10 +556,6 @@ typedef struct {
|
|||
{
|
||||
NSString *name = (NSString*)NSMapGet(names, (void*)anObject);
|
||||
|
||||
if (name == nil)
|
||||
{
|
||||
name = NSStringFromClass([anObject class]);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -556,18 +569,26 @@ typedef struct {
|
|||
|
||||
- (void) setName: (NSString*)aString forElement: (id)anObject
|
||||
{
|
||||
if (anObject == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@-%@] nil object supplied",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
}
|
||||
if (aString == nil)
|
||||
{
|
||||
if (anObject == nil)
|
||||
{
|
||||
/* Ignore this ... it's most likely a partially initialised
|
||||
* control being deallocated and removing the name for a
|
||||
* subsidiary item which was never allocated in the first place.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
NSMapRemove(names, (void*)anObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (anObject == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@-%@] nil object supplied",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
}
|
||||
NSMapInsert(names, (void*)anObject, (void*)aString);
|
||||
}
|
||||
}
|
||||
|
@ -577,15 +598,45 @@ typedef struct {
|
|||
return [GSThemeInspector sharedThemeInspector];
|
||||
}
|
||||
|
||||
- (GSDrawTiles*) tilesNamed: (NSString*)aName cache: (BOOL)useCache
|
||||
- (GSDrawTiles*) tilesNamed: (NSString*)aName
|
||||
state: (GSThemeControlState)elementState
|
||||
cache: (BOOL)useCache
|
||||
{
|
||||
GSDrawTiles *tiles;
|
||||
GSDrawTiles *tiles;
|
||||
NSMutableDictionary *cache;
|
||||
|
||||
tiles = (useCache == YES) ? [_tiles objectForKey: aName] : nil;
|
||||
switch (elementState)
|
||||
{
|
||||
case GSThemeNormalState:
|
||||
cache = _normalTiles;
|
||||
break;
|
||||
case GSThemeHighlightedState:
|
||||
cache = _highlightedTiles;
|
||||
break;
|
||||
case GSThemeSelectedState:
|
||||
cache = _selectedTiles;
|
||||
break;
|
||||
}
|
||||
|
||||
tiles = (useCache == YES) ? [cache objectForKey: aName] : nil;
|
||||
if (tiles == nil)
|
||||
{
|
||||
NSDictionary *info;
|
||||
NSImage *image;
|
||||
NSString *fullName;
|
||||
|
||||
switch (elementState)
|
||||
{
|
||||
case GSThemeNormalState:
|
||||
fullName = aName;
|
||||
break;
|
||||
case GSThemeHighlightedState:
|
||||
fullName = [aName stringByAppendingString: @"Highlighted"];
|
||||
break;
|
||||
case GSThemeSelectedState:
|
||||
fullName = [aName stringByAppendingString: @"Selected"];
|
||||
break;
|
||||
}
|
||||
|
||||
/* The GSThemeTiles entry in the info dictionary should be a
|
||||
* dictionary containing information about each set of tiles.
|
||||
|
@ -595,7 +646,7 @@ typedef struct {
|
|||
* VerticalDivision Where to divide the image into rows.
|
||||
*/
|
||||
info = [self infoDictionary];
|
||||
info = [[info objectForKey: @"GSThemeTiles"] objectForKey: aName];
|
||||
info = [[info objectForKey: @"GSThemeTiles"] objectForKey: fullName];
|
||||
if ([info isKindOfClass: [NSDictionary class]] == YES)
|
||||
{
|
||||
float x;
|
||||
|
@ -639,7 +690,7 @@ typedef struct {
|
|||
{
|
||||
NSString *ext = [imageTypes objectAtIndex: count];
|
||||
|
||||
imagePath = [_bundle pathForResource: aName
|
||||
imagePath = [_bundle pathForResource: fullName
|
||||
ofType: ext
|
||||
inDirectory: @"ThemeTiles"];
|
||||
if (imagePath != nil)
|
||||
|
@ -657,11 +708,11 @@ typedef struct {
|
|||
|
||||
if (tiles == nil)
|
||||
{
|
||||
[_tiles setObject: null forKey: aName];
|
||||
[cache setObject: null forKey: aName];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_tiles setObject: tiles forKey: aName];
|
||||
[cache setObject: tiles forKey: aName];
|
||||
RELEASE(tiles);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,23 +41,27 @@
|
|||
{
|
||||
GSDrawTiles *tiles = nil;
|
||||
NSColor *color = nil;
|
||||
NSString *name = [self nameForElement: cell];
|
||||
|
||||
if (name == nil)
|
||||
{
|
||||
name = @"NSButton";
|
||||
}
|
||||
|
||||
if (state == GSThemeNormalState)
|
||||
{
|
||||
tiles = [self tilesNamed: @"NSButtonNormal" cache: YES];
|
||||
color = [NSColor controlBackgroundColor];
|
||||
}
|
||||
else if (state == GSThemeHighlightedState)
|
||||
{
|
||||
tiles = [self tilesNamed: @"NSButtonHighlighted" cache: YES];
|
||||
color = [NSColor selectedControlColor];
|
||||
}
|
||||
else if (state == GSThemeSelectedState)
|
||||
{
|
||||
tiles = [self tilesNamed: @"NSButtonPushed" cache: YES];
|
||||
color = [NSColor selectedControlColor];
|
||||
}
|
||||
|
||||
tiles = [self tilesNamed: name state: state cache: YES];
|
||||
if (tiles == nil)
|
||||
{
|
||||
switch (style)
|
||||
|
@ -124,24 +128,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (NSSize) buttonBorderForStyle: (int)style
|
||||
state: (GSThemeControlState)state
|
||||
- (NSSize) buttonBorderForCell: (NSCell*)cell
|
||||
style: (int)style
|
||||
state: (GSThemeControlState)state
|
||||
{
|
||||
GSDrawTiles *tiles = nil;
|
||||
NSString *name = [self nameForElement: cell];
|
||||
|
||||
if (state == GSThemeNormalState)
|
||||
if (name == nil)
|
||||
{
|
||||
tiles = [self tilesNamed: @"NSButtonNormal" cache: YES];
|
||||
}
|
||||
else if (state == GSThemeHighlightedState)
|
||||
{
|
||||
tiles = [self tilesNamed: @"NSButtonHighlighted" cache: YES];
|
||||
}
|
||||
else if (state == GSThemeSelectedState)
|
||||
{
|
||||
tiles = [self tilesNamed: @"NSButtonPushed" cache: YES];
|
||||
name = @"NSButton";
|
||||
}
|
||||
|
||||
tiles = [self tilesNamed: name state: state cache: YES];
|
||||
if (tiles == nil)
|
||||
{
|
||||
switch (style)
|
||||
|
|
|
@ -1311,8 +1311,9 @@ typedef struct _GSButtonCellFlags
|
|||
buttonState = GSThemeSelectedState;
|
||||
}
|
||||
|
||||
borderSize = [[GSTheme theme] buttonBorderForStyle: _bezel_style
|
||||
state: buttonState];
|
||||
borderSize = [[GSTheme theme] buttonBorderForCell: self
|
||||
style: _bezel_style
|
||||
state: buttonState];
|
||||
}
|
||||
else
|
||||
borderSize = NSZeroSize;
|
||||
|
@ -1374,15 +1375,16 @@ typedef struct _GSButtonCellFlags
|
|||
buttonState = GSThemeSelectedState;
|
||||
}
|
||||
|
||||
borderSize = [[GSTheme theme] buttonBorderForStyle: _bezel_style
|
||||
state: buttonState];
|
||||
borderSize = [[GSTheme theme] buttonBorderForCell: self
|
||||
style: _bezel_style
|
||||
state: buttonState];
|
||||
interiorFrame = NSInsetRect(theRect, borderSize.width, borderSize.height);
|
||||
|
||||
/* Pushed in buttons contents are displaced to the bottom right 1px. */
|
||||
if (mask & NSPushInCellMask)
|
||||
{
|
||||
interiorFrame
|
||||
= NSOffsetRect(interiorFrame, 1.0, [_control_view isFlipped] ? 1.0 : -1.0);
|
||||
interiorFrame = NSOffsetRect(interiorFrame, 1.0,
|
||||
[_control_view isFlipped] ? 1.0 : -1.0);
|
||||
}
|
||||
return interiorFrame;
|
||||
}
|
||||
|
|
|
@ -336,6 +336,21 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
|
|||
return [self initWithFrame: NSZeroRect];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
GSTheme *theme = [GSTheme theme];
|
||||
|
||||
[theme setName: nil forElement: upCell];
|
||||
[theme setName: nil forElement: downCell];
|
||||
[theme setName: nil forElement: leftCell];
|
||||
[theme setName: nil forElement: rightCell];
|
||||
[theme setName: nil forElement: verticalKnobCell];
|
||||
[theme setName: nil forElement: horizontalKnobCell];
|
||||
[theme setName: nil forElement: verticalKnobSlotCell];
|
||||
[theme setName: nil forElement: horizontalKnobSlotCell];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache images for scroll arrows and knob. If you override +scrollerWidth
|
||||
* you may need to override this as well (to provide images for the new
|
||||
|
@ -344,23 +359,48 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
|
|||
*/
|
||||
- (void) drawParts
|
||||
{
|
||||
GSTheme *theme = [GSTheme theme] ;
|
||||
GSTheme *theme;
|
||||
|
||||
if (upCell)
|
||||
return;
|
||||
|
||||
theme = [GSTheme theme];
|
||||
|
||||
[theme setName: nil forElement: upCell];
|
||||
ASSIGN(upCell ,[theme cellForScrollerArrow:
|
||||
NSScrollerDecrementArrow horizontal:NO]);
|
||||
[theme setName: GSScrollerUpArrow forElement: upCell];
|
||||
|
||||
[theme setName: nil forElement: downCell];
|
||||
ASSIGN(downCell, [theme cellForScrollerArrow:
|
||||
NSScrollerIncrementArrow horizontal:NO]);
|
||||
[theme setName: GSScrollerDownArrow forElement: downCell];
|
||||
|
||||
[theme setName: nil forElement: leftCell];
|
||||
ASSIGN(leftCell, [theme cellForScrollerArrow:
|
||||
NSScrollerDecrementArrow horizontal:YES]);
|
||||
[theme setName: GSScrollerLeftArrow forElement: leftCell];
|
||||
|
||||
[theme setName: nil forElement: rightCell];
|
||||
ASSIGN(rightCell, [theme cellForScrollerArrow:
|
||||
NSScrollerIncrementArrow horizontal:YES]);
|
||||
[theme setName: GSScrollerRightArrow forElement: rightCell];
|
||||
|
||||
[theme setName: nil forElement: verticalKnobCell];
|
||||
ASSIGN(verticalKnobCell, [theme cellForScrollerKnob: NO]);
|
||||
[theme setName: GSScrollerVerticalKnob forElement: verticalKnobCell];
|
||||
|
||||
[theme setName: nil forElement: horizontalKnobCell];
|
||||
ASSIGN(horizontalKnobCell, [theme cellForScrollerKnob: YES]);
|
||||
[theme setName: GSScrollerHorizontalKnob forElement: horizontalKnobCell];
|
||||
|
||||
[theme setName: nil forElement: verticalKnobSlotCell];
|
||||
ASSIGN(verticalKnobSlotCell, [theme cellForScrollerKnobSlot: NO]);
|
||||
[theme setName: GSScrollerVerticalSlot forElement: verticalKnobSlotCell];
|
||||
|
||||
[theme setName: nil forElement: horizontalKnobSlotCell];
|
||||
ASSIGN(horizontalKnobSlotCell, [theme cellForScrollerKnobSlot: YES]);
|
||||
[theme setName: GSScrollerHorizontalSlot forElement: horizontalKnobSlotCell];
|
||||
|
||||
[downCell setContinuous: YES];
|
||||
[downCell sendActionOn: (NSLeftMouseDownMask | NSPeriodicMask)];
|
||||
|
|
Loading…
Reference in a new issue