fixes to sizeToFit, NSMenuTitleView's drawRect, added titleSize

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@16198 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
stoyan 2003-03-18 16:24:31 +00:00
parent ed81b1248e
commit efa8df36c4

View file

@ -55,10 +55,12 @@
@interface NSMenuWindowTitleView : NSView @interface NSMenuWindowTitleView : NSView
{ {
NSMenu *menu; NSMenu *menu;
NSButton *button; NSButton *button;
NSDictionary *attr;
} }
- (NSSize) titleSize;
- (void) addCloseButton; - (void) addCloseButton;
- (void) removeCloseButton; - (void) removeCloseButton;
- (void) createButton; - (void) createButton;
@ -110,6 +112,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal)
{ {
return YES; return YES;
} }
// We do not want to popup menus in this menu. // We do not want to popup menus in this menu.
- (id) menuForEvent: (NSEvent*) theEvent - (id) menuForEvent: (NSEvent*) theEvent
{ {
@ -117,7 +120,6 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal)
return nil; return nil;
} }
/* /*
* Init methods. * Init methods.
*/ */
@ -497,121 +499,145 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal)
- (void) sizeToFit - (void) sizeToFit
{ {
unsigned i; unsigned i;
unsigned howMany = [_itemCells count]; unsigned howMany = [_itemCells count];
float neededImageAndTitleWidth = [_font widthOfString: [_menu title]]; unsigned wideTitleView = 1;
float neededKeyEquivalentWidth = 0.0; float neededImageAndTitleWidth = [_titleView titleSize].width;
float neededStateImageWidth = 0.0; float neededKeyEquivalentWidth = 0.0;
float accumulatedOffset = 0.0; float neededStateImageWidth = 0.0;
float accumulatedOffset = 0.0;
/* Set the necessary offset for the menuView. That is, how many pixels /* Set the necessary offset for the menuView. That is, how many pixels
* do we need for our left side border line. For regular menus this * do we need for our left side border line. For regular menus this
* equals 1, for popups it is 0. * equals 1, for popups it is 0.
* *
* Why here? I could not think of a better place. I figure that everyone * Why here? I could not think of a better place. I figure that everyone
* should sizeToFit their popup/menu before using it so we should get * should sizeToFit their popup/menu before using it so we should get
* this set properly fairly early. * this set properly fairly early.
*/ */
if ([_menu _ownedByPopUp]) if ([_menu _ownedByPopUp])
_leftBorderOffset = 0; _leftBorderOffset = 0;
if ([_menu supermenu] != nil) // TODO: Optimize this loop.
neededImageAndTitleWidth = [_font widthOfString: [_menu title]] + 15; for (i = 0; i < howMany; i++)
else {
neededImageAndTitleWidth = [_font widthOfString: [_menu title]]; float aStateImageWidth = 0.0;
float aTitleWidth = 0.0;
float anImageWidth = 0.0;
float anImageAndTitleWidth = 0.0;
float aKeyEquivalentWidth = 0.0;
NSMenuItemCell *aCell = [_itemCells objectAtIndex: i];
// TODO: Optimize this loop. // State image area.
for (i = 0; i < howMany; i++) aStateImageWidth = [aCell stateImageWidth];
{
float anImageAndTitleWidth = 0.0;
float anImageWidth = 0.0;
float aKeyEquivalentWidth = 0.0;
float aStateImageWidth = 0.0;
float aTitleWidth = 0.0;
NSMenuItemCell *aCell = [_itemCells objectAtIndex: i];
// State image area. // Title and Image area.
aStateImageWidth = [aCell stateImageWidth]; aTitleWidth = [aCell titleWidth];
anImageWidth = [aCell imageWidth];
// Title and Image area. // Key equivalent area.
aTitleWidth = [aCell titleWidth]; aKeyEquivalentWidth = [aCell keyEquivalentWidth];
anImageWidth = [aCell imageWidth];
// Key equivalent area. switch ([aCell imagePosition])
aKeyEquivalentWidth = [aCell keyEquivalentWidth];
switch ([aCell imagePosition])
{ {
case NSNoImage: case NSNoImage:
anImageAndTitleWidth = aTitleWidth; anImageAndTitleWidth = aTitleWidth;
break; break;
case NSImageOnly: case NSImageOnly:
anImageAndTitleWidth = anImageWidth; anImageAndTitleWidth = anImageWidth;
break; break;
case NSImageLeft: case NSImageLeft:
case NSImageRight: case NSImageRight:
anImageAndTitleWidth = anImageWidth + aTitleWidth + xDist; anImageAndTitleWidth = anImageWidth + aTitleWidth + xDist;
break; break;
case NSImageBelow: case NSImageBelow:
case NSImageAbove: case NSImageAbove:
case NSImageOverlaps: case NSImageOverlaps:
default: default:
if (aTitleWidth > anImageWidth) if (aTitleWidth > anImageWidth)
anImageAndTitleWidth = aTitleWidth; anImageAndTitleWidth = aTitleWidth;
else else
anImageAndTitleWidth = anImageWidth; anImageAndTitleWidth = anImageWidth;
break; break;
} }
anImageAndTitleWidth += aStateImageWidth; anImageAndTitleWidth += aStateImageWidth;
if (aStateImageWidth > neededStateImageWidth) if (aStateImageWidth > neededStateImageWidth)
neededStateImageWidth = aStateImageWidth; neededStateImageWidth = aStateImageWidth;
if (anImageAndTitleWidth > neededImageAndTitleWidth) if (anImageAndTitleWidth > neededImageAndTitleWidth)
neededImageAndTitleWidth = anImageAndTitleWidth; {
neededImageAndTitleWidth = anImageAndTitleWidth;
wideTitleView = 0;
}
if (aKeyEquivalentWidth > neededKeyEquivalentWidth) if (aKeyEquivalentWidth > neededKeyEquivalentWidth)
neededKeyEquivalentWidth = aKeyEquivalentWidth; neededKeyEquivalentWidth = aKeyEquivalentWidth;
} }
// Cache the needed widths. // Cache the needed widths.
_stateImageWidth = neededStateImageWidth; _stateImageWidth = neededStateImageWidth;
_imageAndTitleWidth = neededImageAndTitleWidth; _imageAndTitleWidth = neededImageAndTitleWidth;
_keyEqWidth = neededKeyEquivalentWidth; _keyEqWidth = neededKeyEquivalentWidth;
// Calculate the offsets and cache them. if (howMany)
_stateImageOffset = _imageAndTitleOffset = accumulatedOffset {
= _horizontalEdgePad; // Calculate the offsets and cache them.
accumulatedOffset += neededImageAndTitleWidth; if (neededStateImageWidth)
{
_stateImageOffset = accumulatedOffset += _horizontalEdgePad;
accumulatedOffset += neededStateImageWidth;
}
_keyEqOffset = accumulatedOffset += 2 * _horizontalEdgePad; _imageAndTitleOffset = accumulatedOffset += _horizontalEdgePad;
accumulatedOffset += neededKeyEquivalentWidth + _horizontalEdgePad; accumulatedOffset += neededImageAndTitleWidth;
// Calculate frame size. if (neededKeyEquivalentWidth)
if (![_menu _ownedByPopUp]) {
{ _keyEqOffset = accumulatedOffset += (2 * _horizontalEdgePad);
_cellSize.width = accumulatedOffset + 3; // Add the border width accumulatedOffset += neededKeyEquivalentWidth + _horizontalEdgePad;
} }
else
{
if (wideTitleView && [_menu supermenu] != nil)
accumulatedOffset += 15 + 3 + 2;
else
accumulatedOffset += 3 * _horizontalEdgePad;
}
}
else
{
accumulatedOffset += 5 + neededImageAndTitleWidth + 3 + 2;
if (wideTitleView && [_menu supermenu] != nil)
accumulatedOffset += 15;
}
if (_horizontal == NO) // Calculate frame size.
{ if (![_menu _ownedByPopUp])
float menuBarHeight = [[self class] menuBarHeight]; {
// Add the border width: 1 for left, 2 for right sides
[self setFrameSize: NSMakeSize(_cellSize.width + _leftBorderOffset, _cellSize.width = accumulatedOffset + 3;
(howMany * _cellSize.height) + menuBarHeight)]; }
[_titleView setFrame: NSMakeRect (0, howMany * _cellSize.height,
NSWidth (_bounds), menuBarHeight)];
}
else
{
[self setFrameSize: NSMakeSize((howMany * _cellSize.width),
_cellSize.height + _leftBorderOffset)];
}
_needsSizing = NO; if (_horizontal == NO)
{
float menuBarHeight = [[self class] menuBarHeight];
[self setFrameSize: NSMakeSize(_cellSize.width + _leftBorderOffset,
(howMany * _cellSize.height) + menuBarHeight)];
[_titleView setFrame: NSMakeRect (0, howMany * _cellSize.height,
NSWidth (_bounds), menuBarHeight)];
}
else
{
[self setFrameSize: NSMakeSize((howMany * _cellSize.width),
_cellSize.height + _leftBorderOffset)];
}
_needsSizing = NO;
} }
- (float) stateImageOffset - (float) stateImageOffset
@ -1414,6 +1440,15 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal)
@implementation NSMenuWindowTitleView @implementation NSMenuWindowTitleView
- (id) init
{
[super init];
attr = nil;
return self;
}
- (BOOL) acceptsFirstMouse: (NSEvent *)theEvent - (BOOL) acceptsFirstMouse: (NSEvent *)theEvent
{ {
return YES; return YES;
@ -1429,104 +1464,107 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal)
return menu; return menu;
} }
- (NSSize) titleSize
{
if (attr == nil)
{
attr = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSFont boldSystemFontOfSize: 0], NSFontAttributeName,
[NSColor windowFrameTextColor], NSForegroundColorAttributeName,
nil];
}
return [[menu title] sizeWithAttributes: attr];
}
- (void) drawRect: (NSRect)rect - (void) drawRect: (NSRect)rect
{ {
NSRect workRect = [self bounds]; NSRect workRect = [self bounds];
NSSize titleSize; NSSize titleSize;
NSRectEdge sides[] = {NSMinXEdge, NSMaxYEdge}; NSRectEdge sides[] = {NSMinXEdge, NSMaxYEdge};
float grays[] = {NSDarkGray, NSDarkGray}; float grays[] = {NSDarkGray, NSDarkGray};
/* Cache the title attributes */
static NSDictionary *attr = nil;
// Draw the dark gray upper left lines. // Draw the dark gray upper left lines.
workRect = NSDrawTiledRects(workRect, workRect, sides, grays, 2); workRect = NSDrawTiledRects(workRect, workRect, sides, grays, 2);
// Draw the title box's button.
NSDrawButton(workRect, workRect);
// Paint it Black!
workRect.origin.x += 1;
workRect.origin.y += 2;
workRect.size.height -= 3;
workRect.size.width -= 3;
[[NSColor windowFrameColor] set];
NSRectFill(workRect);
// Draw the title // Draw the title box's button.
if (attr == nil) NSDrawButton(workRect, workRect);
{
attr = [[NSDictionary alloc]
initWithObjectsAndKeys:
[NSFont boldSystemFontOfSize: 0], NSFontAttributeName,
[NSColor windowFrameTextColor], NSForegroundColorAttributeName,
nil];
}
titleSize = [[menu title] sizeWithAttributes: attr]; // Paint it Black!
workRect.origin.x += 5; workRect.origin.x += 1;
workRect.origin.y = NSMidY (workRect) - titleSize.height / 2; workRect.origin.y += 2;
workRect.size.height = titleSize.height; workRect.size.height -= 3;
[[menu title] drawInRect: workRect withAttributes: attr]; workRect.size.width -= 3;
[[NSColor windowFrameColor] set];
NSRectFill(workRect);
// Draw the title
titleSize = [self titleSize];
workRect.origin.x += 4;
workRect.origin.y = NSMidY (workRect) - titleSize.height / 2;
workRect.size.height = titleSize.height;
[[menu title] drawInRect: workRect withAttributes: attr];
} }
- (void) mouseDown: (NSEvent*)theEvent - (void) mouseDown: (NSEvent*)theEvent
{ {
NSPoint lastLocation; NSPoint lastLocation;
NSPoint location; NSPoint location;
unsigned eventMask = NSLeftMouseUpMask | NSLeftMouseDraggedMask; unsigned eventMask = NSLeftMouseUpMask | NSLeftMouseDraggedMask;
BOOL done = NO; BOOL done = NO;
NSDate *theDistantFuture = [NSDate distantFuture]; NSDate *theDistantFuture = [NSDate distantFuture];
NSDebugLLog (@"NSMenu", @"Mouse down in title!"); NSDebugLLog (@"NSMenu", @"Mouse down in title!");
lastLocation = [theEvent locationInWindow];
if (![menu isTornOff] && [menu supermenu])
{
[menu setTornOff: YES];
}
while (!done) lastLocation = [theEvent locationInWindow];
{
theEvent = [NSApp nextEventMatchingMask: eventMask
untilDate: theDistantFuture
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
switch ([theEvent type])
{
case NSRightMouseUp:
case NSLeftMouseUp:
done = YES;
break;
case NSRightMouseDragged:
case NSLeftMouseDragged:
location = [_window mouseLocationOutsideOfEventStream];
if (NSEqualPoints(location, lastLocation) == NO)
{
NSPoint origin = [_window frame].origin;
origin.x += (location.x - lastLocation.x); if (![menu isTornOff] && [menu supermenu])
origin.y += (location.y - lastLocation.y); {
[menu nestedSetFrameOrigin: origin]; [menu setTornOff: YES];
} }
break;
while (!done)
default: {
break; theEvent = [NSApp nextEventMatchingMask: eventMask
} untilDate: theDistantFuture
} inMode: NSEventTrackingRunLoopMode
dequeue: YES];
switch ([theEvent type])
{
case NSRightMouseUp:
case NSLeftMouseUp:
done = YES;
break;
case NSRightMouseDragged:
case NSLeftMouseDragged:
location = [_window mouseLocationOutsideOfEventStream];
if (NSEqualPoints(location, lastLocation) == NO)
{
NSPoint origin = [_window frame].origin;
origin.x += (location.x - lastLocation.x);
origin.y += (location.y - lastLocation.y);
[menu nestedSetFrameOrigin: origin];
}
break;
default:
break;
}
}
} }
- (void) createButton - (void) createButton
{ {
// create the menu's close button // create the menu's close button
NSImage* closeImage = [NSImage imageNamed: @"common_Close"]; NSImage *closeImage = [NSImage imageNamed: @"common_Close"];
NSImage* closeHImage = [NSImage imageNamed: @"common_CloseH"]; NSImage *closeHImage = [NSImage imageNamed: @"common_CloseH"];
NSSize imageSize = [closeImage size]; NSSize imageSize = [closeImage size];
NSRect rect = { { _frame.size.width - imageSize.width - 4, NSRect rect = {
(_frame.size.height - imageSize.height) / 2}, { _frame.size.width - imageSize.width - 4,
{ imageSize.height, imageSize.width } }; (_frame.size.height - imageSize.height) / 2 },
{ imageSize.width, imageSize.height } };
button = [[NSButton alloc] initWithFrame: rect]; button = [[NSButton alloc] initWithFrame: rect];
[button setRefusesFirstResponder: YES]; [button setRefusesFirstResponder: YES];
@ -1556,7 +1594,6 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal)
[self setNeedsDisplay: YES]; [self setNeedsDisplay: YES];
} }
- (void) rightMouseDown: (NSEvent*)theEvent - (void) rightMouseDown: (NSEvent*)theEvent
{ {
} }