From a61c6434b25fc4b92ea6e75cc55b3a5fbdf63fc4 Mon Sep 17 00:00:00 2001 From: richard Date: Tue, 14 Dec 1999 11:18:11 +0000 Subject: [PATCH] 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 --- ChangeLog | 10 ++ Headers/gnustep/gui/NSMenuItemCell.h | 2 +- Source/NSImage.m | 16 ++- Source/NSMenuItemCell.m | 159 ++++++++++++++++++--------- 4 files changed, 128 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad4579eba..cebb9453f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Tue Dec 14 11:15:00 1999 Richard Frith-Macdonald + + * 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 * Source/NSWindow.m (-_processResizeEvent): Add DPScurrentgstate diff --git a/Headers/gnustep/gui/NSMenuItemCell.h b/Headers/gnustep/gui/NSMenuItemCell.h index 2366ed6e0..d02aa8474 100644 --- a/Headers/gnustep/gui/NSMenuItemCell.h +++ b/Headers/gnustep/gui/NSMenuItemCell.h @@ -55,7 +55,7 @@ typedef void (*DrawingIMP)(id, SEL, NSRect, NSView*); NSSize mcell_imageSize; @private - DrawingIMP _drawMethods[4]; + NSColor *_backgroundColor; } - (void)setHighlighted:(BOOL)flag; diff --git a/Source/NSImage.m b/Source/NSImage.m index 09f065f45..77a306217 100644 --- a/Source/NSImage.m +++ b/Source/NSImage.m @@ -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) diff --git a/Source/NSMenuItemCell.m b/Source/NSMenuItemCell.m index 29fba166e..04fa25a8b 100644 --- a/Source/NSMenuItemCell.m +++ b/Source/NSMenuItemCell.m @@ -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; }