Improved menu display and image caching

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@5505 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-12-14 11:18:11 +00:00
parent 647e29924b
commit 5ed8c1ec93
4 changed files with 128 additions and 59 deletions

View file

@ -1,3 +1,13 @@
Tue Dec 14 11:15:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Headers/AppKit/NSMenuitemCell.h: Removed implementation cache ivars
and added an ivar for temporary storage of background color.
* Source/NSMenuItemCell.m: Removed draw implementation caching to
decrease memory footprint, but added color and image class caching
which will more than compensate in performance. Also added use of
highlight version of menu arrow.
* Source/NSImage.m: minor image caching fixes and more debug statements.
1999-12-13 <fedor@gnu.org>
* Source/NSWindow.m (-_processResizeEvent): Add DPScurrentgstate

View file

@ -55,7 +55,7 @@ typedef void (*DrawingIMP)(id, SEL, NSRect, NSView*);
NSSize mcell_imageSize;
@private
DrawingIMP _drawMethods[4];
NSColor *_backgroundColor;
}
- (void)setHighlighted:(BOOL)flag;

View file

@ -628,7 +628,8 @@ static Class cacheClass = 0;
{
[rep setOpaque: [repd->original isOpaque]];
}
NSDebugLLog(@"NSImage", @"Rendered rep %d", (int)rep);
NSDebugLLog(@"NSImage", @"Rendered rep %d on background %@",
(int)rep, repd->bg);
}
}
@ -887,6 +888,7 @@ static Class cacheClass = 0;
GSRepData *partialCache = nil;
GSRepData *validCache = nil;
GSRepData *reps[count];
unsigned partialCount = 0;
unsigned i;
BOOL opaque = [rep isOpaque];
@ -896,7 +898,7 @@ static Class cacheClass = 0;
* Search the cached image reps for any whose original is our
* 'best' image rep. See if we can notice any invalidated
* cache as we go - if we don't find a valid cache, we want to
* re-use an invalidated one rather than createing a new one.
* re-use an invalidated one rather than creating a new one.
* NB. If the image rep is opaque, then any cached rep is valid
* irrespective of the background color it was drawn with.
*/
@ -904,7 +906,7 @@ static Class cacheClass = 0;
{
GSRepData *repd = reps[i];
if (repd->original == rep)
if (repd->original == rep && repd->rep != rep)
{
if (repd->bg == nil)
{
@ -921,6 +923,7 @@ NSDebugLLog(@"NSImage", @"Exact %@ ... %@ %d", repd->bg, _color, repd->rep);
{
NSDebugLLog(@"NSImage", @"Partial %@ ... %@ %d", repd->bg, _color, repd->rep);
partialCache = repd;
partialCount++;
}
}
}
@ -943,8 +946,13 @@ NSDebugLLog(@"NSImage", @"Partial %@ ... %@ %d", repd->bg, _color, repd->rep);
}
cacheRep = validCache->rep;
}
else if (partialCache != nil)
else if (partialCache != nil && partialCount > 2)
{
/*
* Only re-use partially correct caches if there are already
* a few partial matches - otherwise we fall default to
* creating a new cache.
*/
if (NSImageForceCaching == NO && [rep isOpaque] == NO)
{
if (invalidCache != nil)

View file

@ -46,12 +46,19 @@
@implementation NSMenuItemCell
static Class colorClass = 0; /* Cache color class. */
static NSImage *arrowImage = nil; /* Cache arrow image. */
static NSImage *arrowImageH = nil;
+ (void) initialize
{
if (self == [NSMenuItemCell class])
{
// Initial version
[self setVersion:2];
[self setVersion: 1];
colorClass = [NSColor class];
arrowImage = [[NSImage imageNamed: @"common_3DArrowRight"] copy];
arrowImageH = [[NSImage imageNamed: @"common_3DArrowRightH"] copy];
}
}
@ -65,15 +72,6 @@
_cell.image_position = NSNoImage;
_cell.text_align = NSLeftTextAlignment;
_drawMethods[0] = (DrawingIMP)
[self methodForSelector:@selector(drawStateImageWithFrame:inView:)];
_drawMethods[1] = (DrawingIMP)
[self methodForSelector:@selector(drawImageWithFrame:inView:)];
_drawMethods[2] = (DrawingIMP)
[self methodForSelector:@selector(drawTitleWithFrame:inView:)];
_drawMethods[3] = (DrawingIMP)
[self methodForSelector:@selector(drawKeyEquivalentWithFrame:inView:)];
return self;
}
@ -361,11 +359,12 @@
}
}
- (void) drawImageWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
- (void) drawImageWithFrame: (NSRect)cellFrame
inView: (NSView *)controlView
{
NSSize size;
NSPoint position;
NSSize size;
NSPoint position;
NSColor *backgroundColor = _backgroundColor;
cellFrame = [self imageRectForBounds: cellFrame];
size = [mcell_imageToDisplay size];
@ -377,6 +376,26 @@
*/
if ([controlView isFlipped])
position.y += size.height;
if (backgroundColor == nil)
{
if (_cell.state)
{
if (_showAltStateMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
backgroundColor = [colorClass selectedMenuItemColor];
}
if (mcell_highlighted)
{
if (_highlightsByMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
backgroundColor = [colorClass selectedMenuItemColor];
}
if (backgroundColor == nil)
backgroundColor = [colorClass controlBackgroundColor];
}
[mcell_imageToDisplay setBackgroundColor: backgroundColor];
[mcell_imageToDisplay compositeToPoint: position operation: NSCompositeCopy];
}
@ -387,11 +406,16 @@
if ([mcell_item hasSubmenu])
{
NSSize size;
NSPoint position;
NSImage *arrowImage = [NSImage imageNamed:@"common_3DArrowRight"];
NSSize size;
NSPoint position;
NSColor *backgroundColor = _backgroundColor;
NSImage *imageToDraw;
size = [arrowImage size];
if (mcell_highlighted)
imageToDraw = arrowImageH;
else
imageToDraw = arrowImage;
size = [imageToDraw size];
position.x = cellFrame.origin.x + cellFrame.size.width - size.width;
position.y = MAX(NSMidY(cellFrame) - (size.height/2.), 0.);
/*
@ -400,7 +424,26 @@
*/
if ([controlView isFlipped])
position.y += size.height;
[arrowImage compositeToPoint: position operation: NSCompositeCopy];
if (backgroundColor == nil)
{
if (_cell.state)
{
if (_showAltStateMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
backgroundColor = [colorClass selectedMenuItemColor];
}
if (mcell_highlighted)
{
if (_highlightsByMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
backgroundColor = [colorClass selectedMenuItemColor];
}
if (backgroundColor == nil)
backgroundColor = [colorClass controlBackgroundColor];
}
[imageToDraw setBackgroundColor: backgroundColor];
[imageToDraw compositeToPoint: position operation: NSCompositeCopy];
}
else
[self _drawText: [mcell_item keyEquivalent] inFrame: cellFrame];
@ -413,12 +456,13 @@
// Maybe somebody wants to support this (Lazaro).
}
- (void) drawStateImageWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
- (void) drawStateImageWithFrame: (NSRect)cellFrame
inView: (NSView*)controlView
{
NSSize size;
NSPoint position;
NSImage *imageToDisplay;
NSSize size;
NSPoint position;
NSImage *imageToDisplay;
NSColor *backgroundColor = _backgroundColor;
cellFrame = [self stateImageRectForBounds: cellFrame];
@ -447,6 +491,25 @@
*/
if ([controlView isFlipped])
position.y += size.height;
if (backgroundColor == nil)
{
if (_cell.state)
{
if (_showAltStateMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
backgroundColor = [colorClass selectedMenuItemColor];
}
if (mcell_highlighted)
{
if (_highlightsByMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
backgroundColor = [colorClass selectedMenuItemColor];
}
if (backgroundColor == nil)
backgroundColor = [colorClass controlBackgroundColor];
}
[imageToDisplay setBackgroundColor: _backgroundColor];
[imageToDisplay compositeToPoint: position operation: NSCompositeCopy];
}
@ -491,7 +554,6 @@
{
BOOL showAlternate = NO;
unsigned mask;
NSColor *backgroundColor = nil;
// Transparent buttons never draw
if (_buttoncell_is_transparent)
@ -504,26 +566,29 @@
&& (_highlightsByMask & NSPushInCellMask))
PStranslate(1., [controlView isFlipped] ? 1. : -1.);
// Determine the background color
/*
* Determine the background color and cache it in an ivar so that the
* low-level drawing methods don't need to do it again.
*/
if (_cell.state)
{
if (_showAltStateMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask) )
backgroundColor = [NSColor selectedMenuItemColor];
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
_backgroundColor = [colorClass selectedMenuItemColor];
}
if (mcell_highlighted)
{
if (_highlightsByMask
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask) )
backgroundColor = [NSColor selectedMenuItemColor];
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
_backgroundColor = [colorClass selectedMenuItemColor];
}
if (backgroundColor == nil)
backgroundColor = [NSColor controlBackgroundColor];
if (_backgroundColor == nil)
_backgroundColor = [colorClass controlBackgroundColor];
// Set cell's background color
[backgroundColor set];
[_backgroundColor set];
NSRectFill(cellFrame);
/*
@ -560,28 +625,25 @@
if (mcell_imageToDisplay)
{
mcell_imageWidth = [mcell_imageToDisplay size].width;
[mcell_imageToDisplay setBackgroundColor: backgroundColor];
}
// Draw the state image
if (mcell_stateImageWidth > 0)
_drawMethods[0](self, @selector(drawStateImageWithFrame:inView:),
cellFrame, controlView);
[self drawStateImageWithFrame: cellFrame inView: controlView];
// Draw the image
if (mcell_imageWidth > 0)
_drawMethods[1](self, @selector(drawImageWithFrame:inView:),
cellFrame, controlView);
[self drawImageWithFrame: cellFrame inView: controlView];
// Draw the title
if (mcell_titleWidth > 0)
_drawMethods[2](self, @selector(drawTitleWithFrame:inView:),
cellFrame, controlView);
[self drawTitleWithFrame: cellFrame inView: controlView];
// Draw the key equivalent
if (mcell_keyEquivalentWidth > 0)
_drawMethods[3](self, @selector(drawKeyEquivalentWithFrame:inView:),
cellFrame, controlView);
[self drawKeyEquivalentWithFrame: cellFrame inView: controlView];
_backgroundColor = nil;
}
//
@ -598,8 +660,6 @@
c->mcell_menuView = mcell_menuView;
c->mcell_needs_sizing = mcell_needs_sizing;
memcpy(c->_drawMethods, _drawMethods, sizeof(DrawingIMP) * 4);
return c;
}
@ -627,15 +687,6 @@
mcell_needs_sizing = YES;
_drawMethods[0] = (DrawingIMP)
[self methodForSelector:@selector(drawStateImageWithFrame:inView:)];
_drawMethods[1] = (DrawingIMP)
[self methodForSelector:@selector(drawImageWithFrame:inView:)];
_drawMethods[2] = (DrawingIMP)
[self methodForSelector:@selector(drawTitleWithFrame:inView:)];
_drawMethods[3] = (DrawingIMP)
[self methodForSelector:@selector(drawKeyEquivalentWithFrame:inView:)];
return self;
}