#include #include #include "GSDrawFunctions.h" static NSImage *arrowImageUnselected = nil; static NSImage *arrowImageSelected = nil; static NSImage *arrowImageCurrent = nil; @implementation NSMenuItemCell (theme) - (void) drawBorderAndBackgroundWithFrame: (NSRect)cellFrame inView: (NSView *)controlView { // if (!_cell.is_bordered) // return; if (_cell.is_highlighted && (_highlightsByMask & NSPushInCellMask)) { //[THEME drawGrayBezel: cellFrame : NSZeroRect]; [THEME drawButton: cellFrame inView: nil style: NSRegularSquareBezelStyle highlighted: YES]; } else { [THEME drawButton: cellFrame inView: nil style: NSRegularSquareBezelStyle highlighted: NO]; } } - (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView { unsigned mask; // Transparent buttons never draw if (_buttoncell_is_transparent) return; cellFrame = [self drawingRectForBounds: cellFrame]; if (_cell.is_highlighted) { mask = _highlightsByMask; if (_cell.state) mask &= ~_showAltStateMask; } else if (_cell.state) mask = _showAltStateMask; else mask = NSNoCellMask; // pushed in buttons contents are displaced to the bottom right 1px if (_cell.is_bordered && (mask & NSPushInCellMask)) { cellFrame = NSOffsetRect(cellFrame, 1., [controlView isFlipped] ? 1. : -1.); } /* * 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 (arrowImageSelected == nil) arrowImageSelected = [[NSImage imageNamed: @"Arrows/hierarchical-arrows-selected.tiff"] retain]; if (arrowImageUnselected == nil) arrowImageUnselected = [[NSImage imageNamed: @"Arrows/hierarchical-arrows-unselected.tiff"] retain]; if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask)) { _backgroundColor = [NSColor selectedMenuItemColor]; arrowImageCurrent = arrowImageSelected; [_backgroundColor set]; NSRectFill(cellFrame); } else { // not selected.. arrowImageCurrent = arrowImageUnselected; } if (_backgroundColor == nil) _backgroundColor = [NSColor controlBackgroundColor]; // Set cell's background color // [_backgroundColor set]; // NSRectFill(cellFrame); /* * Determine the image and the title that will be * displayed. If the NSContentsCellMask is set the * image and title are swapped only if state is 1 or * if highlighting is set (when a button is pushed it's * content is changed to the face of reversed state). * The results are saved in two ivars for use in other * drawing methods. */ if (mask & NSContentsCellMask) { _imageToDisplay = _altImage; if (!_imageToDisplay) _imageToDisplay = [_menuItem image]; _titleToDisplay = _altContents; if (_titleToDisplay == nil || [_titleToDisplay isEqual: @""]) _titleToDisplay = [_menuItem title]; } else { _imageToDisplay = [_menuItem image]; _titleToDisplay = [_menuItem title]; } if (_imageToDisplay) { _imageWidth = [_imageToDisplay size].width; } // Draw the state image if (_stateImageWidth > 0) [self drawStateImageWithFrame: cellFrame inView: controlView]; // Draw the image if (_imageWidth > 0) [self drawImageWithFrame: cellFrame inView: controlView]; // Draw the title if (_titleWidth > 0) [self drawTitleWithFrame: cellFrame inView: controlView]; // Draw the key equivalent if (_keyEquivalentWidth > 0) [self drawKeyEquivalentWithFrame: cellFrame inView: controlView]; _backgroundColor = nil; } /* - (void) idrawWithFrame: (NSRect) cellFrame inView: (NSView*) controlView { [super drawWithFrame: cellFrame inView: controlView]; } - (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView { unsigned mask; // Transparent buttons never draw if (_buttoncell_is_transparent) return; cellFrame = [self drawingRectForBounds: cellFrame]; if (_cell.is_highlighted) { mask = _highlightsByMask; if (_cell.state) mask &= ~_showAltStateMask; } else if (_cell.state) mask = _showAltStateMask; else mask = NSNoCellMask; // pushed in buttons contents are displaced to the bottom right 1px if (_cell.is_bordered && (mask & NSPushInCellMask)) { cellFrame = NSOffsetRect(cellFrame, 1., [controlView isFlipped] ? 1. : -1.); } if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask)) { [[NSColor selectedMenuItemColor] set]; NSRectFill(cellFrame); } else { /* NSColor* startColor = [NSColor colorWithCalibratedRed: 0.65 green: 0.65 blue: 0.65 alpha: 1.0]; NSColor* endColor = [NSColor colorWithCalibratedRed: 0.9 green: 0.9 blue: 0.9 alpha: 1.0]; if ([[self controlView] isKindOfClass: [NSPopUpButton class]]) { //NSColor* startColor = [NSColor colorWithCalibratedRed: 0.75 green: 0.75 blue: 0.75 alpha: 1.0]; /* NSColor* startColor = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0]; NSColor* endColor = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0]; [GraphicToolbox drawVerticalGradientOnRect: cellFrame withStartColor: startColor andEndColor: endColor]; */ /* NSColor* startColor = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0]; NSColor* endColor = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0]; NSBezierPath* cadre1 = [NSBezierPath bezierPath]; [cadre1 moveToPoint: NSMakePoint (cellFrame.origin.x + 3, cellFrame.origin.y)]; [cadre1 lineToPoint: NSMakePoint (cellFrame.origin.x + cellFrame.size.width, cellFrame.origin.y)]; [cadre1 lineToPoint: NSMakePoint (cellFrame.origin.x + cellFrame.size.width, cellFrame.origin.y + cellFrame.size.height - 3)]; [[NSColor colorWithCalibratedRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.10] set]; [cadre1 setLineWidth: 0]; [cadre1 stroke]; NSBezierPath* cadre2 = [NSBezierPath bezierPath]; [cadre2 moveToPoint: NSMakePoint (cellFrame.origin.x + 2, cellFrame.origin.y + 1)]; [cadre2 lineToPoint: NSMakePoint (cellFrame.origin.x + cellFrame.size.width - 1, cellFrame.origin.y + 1)]; [cadre2 lineToPoint: NSMakePoint (cellFrame.origin.x + cellFrame.size.width - 1, cellFrame.origin.y + cellFrame.size.height - 2)]; [[NSColor colorWithCalibratedRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.30] set]; [cadre2 setLineWidth: 0]; [cadre2 stroke]; NSBezierPath* cadre = [NSBezierPath bezierPathWithRect: NSMakeRect (cellFrame.origin.x, cellFrame.origin.y + 2, cellFrame.size.width - 2, cellFrame.size.height - 2)]; [[NSColor colorWithCalibratedRed: 0.4 green: 0.4 blue: 0.4 alpha: 1.00] set]; [cadre setLineWidth: 0]; [cadre stroke]; NSRect rect = NSMakeRect (cellFrame.origin.x + 1, cellFrame.origin.y + 2, cellFrame.size.width - 4, cellFrame.size.height - 4); [GraphicToolbox drawVerticalGradientOnRect: rect withStartColor: startColor andEndColor: endColor]; [GraphicToolbox drawVerticalGradientOnRect: NSMakeRect (rect.origin.x, rect.origin.y, 2, rect.size.height) withStartColor: endColor andEndColor: startColor]; [GraphicToolbox drawVerticalGradientOnRect: NSMakeRect (rect.origin.x + rect.size.width - 2, rect.origin.y, 2, rect.size.height) withStartColor: endColor andEndColor: startColor]; } else { [GraphicToolbox drawHorizontalGradientOnRect: cellFrame withStartColor: endColor andEndColor: startColor]; } // } // * Determine the image and the title that will be * displayed. If the NSContentsCellMask is set the * image and title are swapped only if state is 1 or * if highlighting is set (when a button is pushed it's * content is changed to the face of reversed state). * The results are saved in two ivars for use in other * drawing methods. // if (mask & NSContentsCellMask) { _imageToDisplay = _altImage; if (!_imageToDisplay) _imageToDisplay = [_menuItem image]; _titleToDisplay = _altContents; if (_titleToDisplay == nil || [_titleToDisplay isEqual: @""]) _titleToDisplay = [_menuItem title]; } else { _imageToDisplay = [_menuItem image]; _titleToDisplay = [_menuItem title]; } if (_imageToDisplay) { _imageWidth = [_imageToDisplay size].width; } // Draw the state image if (_stateImageWidth > 0) [self drawStateImageWithFrame: cellFrame inView: controlView]; // Draw the image if (_imageWidth > 0) [self drawImageWithFrame: cellFrame inView: controlView]; // Draw the title if (_titleWidth > 0) [self drawTitleWithFrame: cellFrame inView: controlView]; // Draw the key equivalent if (_keyEquivalentWidth > 0) [self drawKeyEquivalentWithFrame: cellFrame inView: controlView]; _backgroundColor = nil; } */ - (void) drawKeyEquivalentWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { cellFrame = [self keyEquivalentRectForBounds: cellFrame]; if ([_menuItem hasSubmenu]) { if (arrowImageCurrent == nil) { NSWarnMLog(@"Missing arrow image to draw menu item with submenu"); } else { NSSize size; NSPoint position; size = [arrowImageCurrent size]; position.x = cellFrame.origin.x + cellFrame.size.width - size.width; position.y = MAX(NSMidY(cellFrame) - (size.height/2.), 0.); /* * * Images are always drawn with their bottom-left corner at the origin * * so we must adjust the position to take account of a flipped view. * */ if ([controlView isFlipped]) position.y += size.height; [arrowImageCurrent compositeToPoint: position operation: NSCompositeSourceOver]; } } /* FIXME/TODO here - decide a consistent policy for images. * * * * The reason of the following code is that we draw the key * * equivalent, but not if we are a popup button and are displaying * * an image (the image is displayed in the title or selected entry * * in the popup, it's the small square on the right). In that case, * * the image will be drawn in the same position where the key * * equivalent would be, so we do not display the key equivalent, * * else they would be displayed one over the other one. * */ else if (![[_menuView menu] _ownedByPopUp]) { [self _drawText: [_menuItem keyEquivalent] inFrame: cellFrame]; } else if (_imageToDisplay == nil) { [self _drawText: [_menuItem keyEquivalent] inFrame: cellFrame]; } } @end