diff --git a/ChangeLog b/ChangeLog index f177f2f49..710521450 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2004-08-30 Quentin Mathe + + * Headers/AppKit/NSCell.h: + * Source/NSCell.m: + Make the code a bit more modular with a distinct private method to + implement the image drawing (the text drawing is already located in a + separate method), see -_drawImage:inFrame:isFlipped:, + previously implemented in -drawInteriorWithFrame:inView: + * Source/NSButtonCell.m: Moved code specific to NSButtonCell + -drawInteriorWithFrame:inView: in a new method + -_drawImage:inFrame:isFlipped to match the method added to NSCell. Also + reverted the 2004-08-11 21:35 Alexander Malmberg commit to have identical + margin between the border and the text with every image positions. + Source/NSToolbarItem.m: + Added -_drawImage:inFrame:isFlipped and _drawAttributedText:inFrame: + to override the superclasses behavior, it permits to have the + GSToolbarButtonCell layout not dependent on the NSButtonCell code. + 2004-08-29 02:48 Matt Rice * Source/NSTableView.m (-draggingUpdated:): Return @@ -27,17 +45,24 @@ 2004-08-13 Quentin Mathe - * Source/NSComboBoxCell.m: - * Source/NSComboBox.m: - Fixed broken combo box behavior introduced June 17 with version 1.27, - which produced wrong tracking in the button cell and extra mouse down - call in the NSComboBox superclass. Now the rewritten version is also - documented. - Also now -[GSComboWindow deselectItemAtIndex:] still produces a - -[GSComboWindow tableViewSelectionDidChange:] call but the chain is - stopped in -[GSComboWindow validateSelection] by the _locationSelection - variable, then -[NSComboBoxCell selectItemAtIndex:] is not anymore - wrongly called. + * Source/NSComboBoxCell.m -(runModalPopUpWithComboBoxCell:): Remove the + observer only for the variable onWindow, then it is not needed anymore + to reset the table view delegate. + (-deselectItemAtIndex:): Added a _localSelection flag, the result is now + the method still triggers -[GSComboWindow tableViewSelectionDidChange:] + call but the _localSelection variable in -validateSelection + avoids to have -selectItemAtIndex: wrongly called. + (-trackMouse:inRect:ofView:untilMouseUp:): Fixed broken combo box + behavior introduced June 17 with version 1.27, which produced wrong + tracking in the button cell and extra mouse down call in the NSComboBox + superclass. Now the rewritten version is also documented. + * Source/NSComboBox.m (-mouseDown:): Reverted the use of the variable + clicked (that contributes to fix the bug explained above) and renamed it + buttonClicked. + * Headers/AppKit/NSComboBoxCell.h: Added the method + -trackMouse:inRect:ofView:untilMouseUp to have the documentation + generated for this overriden method , it shouldn't be needed( it is a + temporary hack until we have the root problem corrected). 2004-08-12 01:42 Alexander Malmberg diff --git a/Headers/AppKit/NSCell.h b/Headers/AppKit/NSCell.h index d8cb95769..26d6463b4 100644 --- a/Headers/AppKit/NSCell.h +++ b/Headers/AppKit/NSCell.h @@ -454,7 +454,8 @@ typedef enum _NSControlSize { - (void) _drawText: (NSString*)aString inFrame: (NSRect)cellFrame; - (void) _drawAttributedText: (NSAttributedString*)aString inFrame: (NSRect)aRect; - +- (void) _drawImage: (NSImage *)anImage inFrame: (NSRect)aRect + isFlipped: (BOOL)flipped; @end // diff --git a/Source/NSButtonCell.m b/Source/NSButtonCell.m index 1e1637307..8b47dde7b 100644 --- a/Source/NSButtonCell.m +++ b/Source/NSButtonCell.m @@ -55,6 +55,12 @@ #include +@interface NSButtonCell (Private) +// Overriden private internal method +- (void) _drawImage: (NSImage *)anImage inFrame: (NSRect)aRect + isFlipped: (BOOL)flipped; +@end + @implementation NSButtonCell /* @@ -942,12 +948,12 @@ * The drawing code below will then center the image in imageRect. */ titleRect.origin.x = cellFrame.origin.x; - titleRect.origin.y = cellFrame.origin.y; + 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) + GSCellTextImageYDist; + imageRect.origin.y = NSMaxY(titleRect); imageRect.size.width = cellFrame.size.width; imageRect.size.height = NSMaxY(cellFrame) - imageRect.origin.y; @@ -1009,30 +1015,7 @@ // 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]; - } + [self _drawImage: imageToDisplay inFrame: imageRect isFlipped: flippedView]; } // Draw title @@ -1327,3 +1310,40 @@ } @end + +@implementation NSButtonCell (Private) + +// Overriden private internal method +- (void) _drawImage: (NSImage *)anImage inFrame: (NSRect)aRect + isFlipped: (BOOL)flipped +{ + // To keep partially in sync with the NSCell overriden method + + NSSize size; + NSPoint position; + + size = [anImage size]; + position.x = MAX(NSMidX(aRect) - (size.width / 2.), 0.); + position.y = MAX(NSMidY(aRect) - (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 (flipped) + { + position.y += size.height; + } + + if (_cell.is_disabled && _image_dims_when_disabled) + { + [anImage dissolveToPoint: position fraction: 0.5]; + } + else + { + [anImage compositeToPoint: position + operation: NSCompositeSourceOver]; + } +} + +@end diff --git a/Source/NSCell.m b/Source/NSCell.m index 23a2d3083..0b8acfeb4 100644 --- a/Source/NSCell.m +++ b/Source/NSCell.m @@ -1664,34 +1664,21 @@ static NSColor *shadowCol; switch (_cell.type) { case NSTextCellType: - { - [self _drawAttributedText: [self attributedStringValue] - inFrame: cellFrame]; - } + [self _drawAttributedText: [self attributedStringValue] + inFrame: cellFrame]; break; case NSImageCellType: if (_cell_image) { - NSSize size; - NSPoint position; - - size = [_cell_image size]; - position.x = MAX(NSMidX(cellFrame) - (size.width/2.),0.); - 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; - [_cell_image compositeToPoint: position operation: NSCompositeSourceOver]; - } - break; + [self _drawImage: _cell_image + inFrame: cellFrame + isFlipped: [controlView isFlipped]]; + } + break; case NSNullCellType: - break; + break; } if (_cell.shows_first_responder) @@ -2206,6 +2193,27 @@ static NSColor *shadowCol; RELEASE (attributes); } +- (void) _drawImage: (NSImage *)anImage inFrame: (NSRect)aRect + isFlipped: (BOOL)flipped +{ + NSSize size; + NSPoint position; + + size = [anImage size]; + position.x = MAX(NSMidX(aRect) - (size.width/2.),0.); + position.y = MAX(NSMidY(aRect) - (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 (flipped) + position.y += size.height; + + [anImage compositeToPoint: position operation: NSCompositeSourceOver]; +} + @end /* diff --git a/Source/NSToolbarItem.m b/Source/NSToolbarItem.m index fca92c210..313562704 100644 --- a/Source/NSToolbarItem.m +++ b/Source/NSToolbarItem.m @@ -38,8 +38,10 @@ #include "AppKit/NSMenuItem.h" #include "AppKit/NSImage.h" #include "AppKit/NSButton.h" +#include "AppKit/NSButtonCell.h" #include "AppKit/NSFont.h" #include "AppKit/NSEvent.h" +#include "AppKit/NSParagraphStyle.h" #include "GNUstepGUI/GSToolbar.h" #include "GNUstepGUI/GSToolbarView.h" @@ -122,16 +124,35 @@ static NSFont *SmallFont = nil; - (void) setToolbarItemAction: (SEL)action; @end +@interface GSToolbarButtonCell : NSButtonCell +{ + NSRect titleRect; + NSRect imageRect; +} + +@end + +// --- + @implementation GSToolbarButton ++ (void) initialize +{ + if (self == [GSToolbarButton class]) + [GSToolbarButton setCellClass: [GSToolbarButtonCell class]]; +} + - (id) initWithToolbarItem: (NSToolbarItem *)toolbarItem { - self = [super initWithFrame: NSMakeRect(ItemBackViewX, ItemBackViewY, ItemBackViewDefaultWidth, ItemBackViewDefaultHeight)]; + self = [super initWithFrame: NSMakeRect(ItemBackViewX, ItemBackViewY, + ItemBackViewDefaultWidth, ItemBackViewDefaultHeight)]; // Frame will be reset by the layout method if (self != nil) { // Don't do an ASSIGN here, the toolbar item itself retains us. _toolbarItem = toolbarItem; + + //[self setCell: [[GSToolbarButtonCell alloc] init]]; } return self; } @@ -280,6 +301,84 @@ static NSFont *SmallFont = nil; @end +@implementation GSToolbarButtonCell + +// Overriden NSButtonCell method +- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView +{ + NSSize titleSize = [[self attributedTitle] size]; + // We ignore alternateAttributedTitle, it is not needed + + // We store the values we need to customize the drawing into titleRect and imageRect + + titleRect.origin.x = cellFrame.origin.x; + titleRect.origin.y = cellFrame.origin.y + InsetItemTextY; + titleRect.size.width = cellFrame.size.width; + titleRect.size.height = titleSize.height; + + imageRect.origin.x = cellFrame.origin.x; + imageRect.origin.y = cellFrame.origin.y; + if ([self imagePosition] != NSImageOnly) + imageRect.origin.y += titleRect.size.height; + imageRect.size.width = cellFrame.size.width; + imageRect.size.height = cellFrame.size.height; + if ([self imagePosition] != NSImageOnly) + imageRect.size.height -= titleRect.size.height; + + [super drawInteriorWithFrame: cellFrame inView: controlView]; +} + +// Overriden NSCell method +- (void) _drawAttributedText: (NSAttributedString*)aString + inFrame: (NSRect)aRect +{ + if (aString == nil) + return; + + /** Important: text should always be vertically centered without + * considering descender [as if descender did not exist]. + * This is particularly important for single line texts. + * Please make sure the output remains always correct. + */ + // We ignore aRect value + + [aString drawInRect: titleRect]; +} + +// Overriden NSButtonCell method +- (void) _drawImage: (NSImage *)anImage inFrame: (NSRect)aRect isFlipped: (BOOL)flipped +{ + NSSize size; + NSPoint position; + + // We ignore aRect value + + size = [anImage 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 (flipped) + { + position.y += size.height; + } + + if (_cell.is_disabled && _image_dims_when_disabled) + { + [anImage dissolveToPoint: position fraction: 0.5]; + } + else + { + [anImage compositeToPoint: position + operation: NSCompositeSourceOver]; + } +} + +@end + /* * Back view used to enclose toolbar item's custom view */ @@ -322,37 +421,48 @@ static NSFont *SmallFont = nil; [super dealloc]; } -- (void)drawRect: (NSRect)rect -{ - NSAttributedString *attrString; - NSDictionary *attr; - NSColor *color; - float textX; - +- (void) drawRect: (NSRect)rect +{ [super drawRect: rect]; // We draw _view which is a subview - - if (_enabled) - { - color = [NSColor blackColor]; - } - else - { - color = [NSColor disabledControlTextColor]; - } - + if (_showLabel) { + NSAttributedString *attrString; + NSDictionary *attr; + NSColor *color; + NSMutableParagraphStyle *pStyle = [NSMutableParagraphStyle defaultParagraphStyle]; + NSRect titleRect; + NSRect viewBounds = [self bounds]; + + if (_enabled) + { + color = [NSColor blackColor]; + } + else + { + color = [NSColor disabledControlTextColor]; + } + + [pStyle setAlignment: NSCenterTextAlignment]; + // We draw the label attr = [NSDictionary dictionaryWithObjectsAndKeys: _font, NSFontAttributeName, color, NSForegroundColorAttributeName, + pStyle, + NSParagraphStyleAttributeName, nil]; attrString = [[NSAttributedString alloc] initWithString: [_toolbarItem label] attributes: attr]; - textX = (([self frame].size.width - InsetItemTextX) - [attrString size].width) / 2; - [attrString drawAtPoint: NSMakePoint(textX, InsetItemTextY)]; + + titleRect.origin.x = viewBounds.origin.x; + titleRect.origin.y = viewBounds.origin.y + InsetItemTextY; + titleRect.size.width = viewBounds.size.width; + titleRect.size.height = [attrString size].height; + [attrString drawInRect: titleRect]; + DESTROY(attrString); - } + } } - (void) layout