#include #include #include "GraphicToolbox.h" #include "GSDrawFunctions.h" @interface NSButtonCell (theme) // declare some methods used by gnustep.. - (void) drawGradientWithFrame: (NSRect) frame inView: (NSView*) view; @end @implementation NSButtonCell (theme) - (BOOL) isOpaque { return NO; } - (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView { // Save last view drawn to if (_control_view != controlView) _control_view = controlView; // transparent buttons never draw if (_buttoncell_is_transparent) return; // do nothing if cell's frame rect is zero if (NSIsEmptyRect(cellFrame)) return; if ((_cell.is_bordered) && (!_shows_border_only_while_mouse_inside || _mouse_inside)) { // [THEME drawButton: cellFrame : NSZeroRect]; [THEME drawButton: cellFrame inView: controlView style: _bezel_style highlighted: _cell.is_highlighted]; } else if (_cell.is_highlighted) { NSColor *backgroundColor = nil; backgroundColor = [NSColor selectedControlColor]; if (backgroundColor != nil) { [backgroundColor set]; NSRectFill (cellFrame); } } [self drawInteriorWithFrame: cellFrame inView: controlView]; /* if (_cell.shows_first_responder && [[controlView window] firstResponder] == controlView) { [THEME drawFocusFrame: cellFrame]; } */ } - (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView { unsigned mask; NSImage *imageToDisplay; NSRect imageRect; NSAttributedString *titleToDisplay; NSRect titleRect; NSSize imageSize = {0, 0}; NSSize titleSize = {0, 0}; NSColor *backgroundColor = nil; BOOL flippedView = [controlView isFlipped]; NSCellImagePosition ipos = _cell.image_position; // transparent buttons never draw if (_buttoncell_is_transparent) return; _control_view = controlView; // 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 (ipos != NSImageAbove) // cellFrame = NSOffsetRect(cellFrame, 1., flippedView ? 1. : -1.); if (_cell.is_bordered && (mask & NSPushInCellMask)) { cellFrame = NSOffsetRect(cellFrame, 1., flippedView ? 1. : -1.); } /* Draw the cell's background color. We draw when there is a border or when highlightsByMask is NSChangeBackgroundCellMask or NSChangeGrayCellMask, as required by our nextstep-like look and feel. */ /* if (_cell.is_bordered || (_highlightsByMask & NSChangeBackgroundCellMask) || (_highlightsByMask & NSChangeGrayCellMask)) { // Determine the background color. if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask)) { backgroundColor = [NSColor selectedControlColor]; } else if (_cell.is_bordered) { backgroundColor = [NSColor controlBackgroundColor]; } if (backgroundColor != nil) { [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). */ if (mask & NSContentsCellMask) { imageToDisplay = _altImage; if (!imageToDisplay) { imageToDisplay = _cell_image; } titleToDisplay = [self attributedAlternateTitle]; if (titleToDisplay == nil || [titleToDisplay length] == 0) { titleToDisplay = [self attributedTitle]; } } else { imageToDisplay = _cell_image; titleToDisplay = [self attributedTitle]; } if (imageToDisplay && ipos != NSNoImage) { imageSize = [imageToDisplay size]; } if (titleToDisplay && ipos != NSImageOnly) { titleSize = [titleToDisplay size]; } if (flippedView == YES) { if (ipos == NSImageAbove) { ipos = NSImageBelow; } else if (ipos == NSImageBelow) { ipos = NSImageAbove; } } /* The size calculations here should be changed very carefully, and _must_ be kept in sync with -cellSize. Changing the calculations to require more space isn't OK; this breaks interfaces designed using the old sizes by clipping away parts of the title. The current size calculations ensure that for bordered or bezeled cells, there's always at least a three point margin between the size returned by -cellSize and the minimum size required not to clip text. (In other words, the text can become three points wider (due to eg. font mismatches) before you lose the last character.) */ switch (ipos) { case NSNoImage: imageToDisplay = nil; titleRect = cellFrame; if (titleSize.width + 6 <= titleRect.size.width) { titleRect.origin.x += 3; titleRect.size.width -= 6; } break; case NSImageOnly: titleToDisplay = nil; imageRect = cellFrame; break; case NSImageLeft: imageRect.origin = cellFrame.origin; imageRect.size.width = imageSize.width; imageRect.size.height = cellFrame.size.height; if (_cell.is_bordered || _cell.is_bezeled) { imageRect.origin.x += 3; } titleRect = imageRect; titleRect.origin.x += imageSize.width + GSCellTextImageXDist; titleRect.size.width = NSMaxX(cellFrame) - titleRect.origin.x; if (titleSize.width + 3 <= titleRect.size.width) { titleRect.size.width -= 3; } break; case NSImageRight: imageRect.origin.x = NSMaxX(cellFrame) - imageSize.width; imageRect.origin.y = cellFrame.origin.y; imageRect.size.width = imageSize.width; imageRect.size.height = cellFrame.size.height; if (_cell.is_bordered || _cell.is_bezeled) { imageRect.origin.x -= 3; } titleRect.origin = cellFrame.origin; titleRect.size.width = imageRect.origin.x - titleRect.origin.x - GSCellTextImageXDist; titleRect.size.height = cellFrame.size.height; if (titleSize.width + 3 <= titleRect.size.width) { titleRect.origin.x += 3; titleRect.size.width -= 3; } break; case NSImageAbove: /* * In this case, imageRect is all the space we can allocate * above the text. * The drawing code below will then center the image in imageRect. */ titleRect.origin.x = cellFrame.origin.x; titleRect.origin.y = cellFrame.origin.y + GSCellTextImageYDist; titleRect.size.width = cellFrame.size.width; titleRect.size.height = titleSize.height; imageRect.origin.x = cellFrame.origin.x; imageRect.origin.y = NSMaxY(titleRect); imageRect.size.width = cellFrame.size.width; imageRect.size.height = NSMaxY(cellFrame) - imageRect.origin.y; if (_cell.is_bordered || _cell.is_bezeled) { imageRect.origin.y -= 1; } if (titleSize.width + 6 <= titleRect.size.width) { titleRect.origin.x += 3; titleRect.size.width -= 6; } break; case NSImageBelow: /* * In this case, imageRect is all the space we can allocate * below the text. * The drawing code below will then center the image in imageRect. */ titleRect.origin.x = cellFrame.origin.x; titleRect.origin.y = NSMaxY(cellFrame) - titleSize.height; titleRect.size.width = cellFrame.size.width; titleRect.size.height = titleSize.height; imageRect.origin.x = cellFrame.origin.x; imageRect.origin.y = cellFrame.origin.y; imageRect.size.width = cellFrame.size.width; imageRect.size.height = titleRect.origin.y - GSCellTextImageYDist - imageRect.origin.y; if (_cell.is_bordered || _cell.is_bezeled) { imageRect.origin.y += 1; } if (titleSize.width + 6 <= titleRect.size.width) { titleRect.origin.x += 3; titleRect.size.width -= 6; } break; case NSImageOverlaps: imageRect = cellFrame; titleRect = cellFrame; if (titleSize.width + 6 <= titleRect.size.width) { titleRect.origin.x += 3; titleRect.size.width -= 6; } break; } // Draw gradient if (!_cell.is_highlighted && _gradient_type != NSGradientNone) { //NRO: this thing SHOULD NOT BE THERE --> a call to GSDrawFunctions would be better. //FIXME: Fix this in GNUstep cvs [self drawGradientWithFrame: cellFrame inView: controlView]; } // Draw image if (imageToDisplay != nil) { NSSize size; NSPoint position; size = [imageToDisplay size]; position.x = MAX(NSMidX(imageRect) - (size.width / 2.), 0.); position.y = MAX(NSMidY(imageRect) - (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 (flippedView) { position.y += size.height; } if (_cell.is_disabled && _image_dims_when_disabled) { [imageToDisplay dissolveToPoint: position fraction: 0.5]; } else { [imageToDisplay compositeToPoint: position operation: NSCompositeSourceOver]; } } // Draw title if (titleToDisplay != nil) { [self _drawAttributedText: titleToDisplay inFrame: titleRect]; } // Draw first responder /* if (_cell.shows_first_responder && [[controlView window] firstResponder] == controlView) { NSDottedFrameRect(cellFrame); } */ } @end