diff --git a/ChangeLog b/ChangeLog index 300879989..32b2853cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2003-03-23 Serg Stoyan + * Source/NSMenuView.m: Removed horizontal menu related code. + (setHorizontal:): Removed. + (isHorizontal:): Removed. + (_addLeftBorderOffsetToRect): Removed isHorizontal parameter. + (setMenu:): Place [self setNeedsSizing: YES] before [self update]. + (update): Removed title view removal, because it's not always known + owner of menu at this point. Remove title view creating. + (sizeToFit:): Reformatting. + (innerRect:): Idem. + (setWindowFrameForAttachingToRect:onScreen:preferredEdge:popUpSelectedItem:): + Title view removal code placed here, because this is only place where + non-titled menu can appear. + (initWithFrame:): Removed comment about _leftBorderOffset for popups, + because we use _leftBorderOffset for regular and popups now. Title view + creating added. + (rectOfItemAtIndex:): Removed comment about _leftBorderOffset for popups. + (indexOfItemAtPoint:): Idem. Add left border offset for popups too. Correct + calling of _addLeftBorderOffsetToRect. + (setNeedsDisplayForItemAtIndex:): Idem. + (rightMouseDown:): Ddded comment. + + * Headers/NSMenuView.h + (setHorizontal:): Removed. + (isHorizontal:): Removed. + 2003-03-22 Willem Rein Oudshoorn * Source/NSMenu.m ([NSMenu -display]): Added optimization of Michael Hanni diff --git a/Headers/gnustep/gui/NSMenuView.h b/Headers/gnustep/gui/NSMenuView.h index d5de238fb..7ae906244 100644 --- a/Headers/gnustep/gui/NSMenuView.h +++ b/Headers/gnustep/gui/NSMenuView.h @@ -99,8 +99,8 @@ - (id)initAsTearOff; - (void)setMenu:(NSMenu *)menu; - (NSMenu *)menu; -- (void)setHorizontal:(BOOL)flag; -- (BOOL)isHorizontal; +/*- (void)setHorizontal:(BOOL)flag; +- (BOOL)isHorizontal;*/ - (void)setFont:(NSFont *)font; - (NSFont *)font; - (void)setHighlightedItemIndex:(int)index; diff --git a/Source/NSMenuView.m b/Source/NSMenuView.m index 02bb38d06..cc867d352 100644 --- a/Source/NSMenuView.m +++ b/Source/NSMenuView.m @@ -72,18 +72,11 @@ @implementation NSMenuView static NSRect -_addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) +_addLeftBorderOffsetToRect(NSRect aRect) { - if (isHorizontal == NO) - { - aRect.origin.x--; - aRect.size.width++; - } - else - { - aRect.origin.y--; - aRect.size.height++; - } + aRect.origin.x--; + aRect.size.width++; + return aRect; } @@ -139,14 +132,18 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) _horizontalEdgePad = 4.; /* 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 - * equals 1, for popups it is 0. + * do we need for our left side border line. */ _leftBorderOffset = 1; // Create an array to store our menu item cells. _itemCells = [NSMutableArray new]; + // Add title view. If this menu owned by popup + _titleView = [[NSMenuWindowTitleView alloc] init]; + [self addSubview: _titleView]; + [_titleView release]; + return self; } @@ -210,9 +207,10 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) name: NSMenuDidRemoveItemNotification object: _menu]; - [self update]; // Force menu view's layout to be recalculated. [self setNeedsSizing: YES]; + + [self update]; } - (NSMenu*) menu @@ -220,16 +218,6 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) return _menu; } -- (void) setHorizontal: (BOOL)flag -{ - _horizontal = flag; -} - -- (BOOL) isHorizontal -{ - return _horizontal; -} - - (void) setFont: (NSFont*)font { ASSIGN(_font, font); @@ -469,18 +457,6 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) { NSDebugLLog (@"NSMenu", @"update called on menu view"); - if ([_menu _ownedByPopUp] && _titleView) - { - [_titleView removeFromSuperview]; - _titleView = nil; - } - if (![_menu _ownedByPopUp] && !_titleView) - { - _titleView = [[NSMenuWindowTitleView alloc] init]; - [_titleView setMenu: _menu]; - [self addSubview: _titleView]; - [_titleView release]; - } [_titleView setMenu: _menu]; if (_needsSizing) @@ -517,7 +493,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) float accumulatedOffset = 0.0; float popupImageWidth = 0.0; float menuBarHeight = 0.0; - + // Popup menu doesn't need title bar if (![_menu _ownedByPopUp] && _titleView) { @@ -641,18 +617,11 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) _keyEqOffset = _cellSize.width - _keyEqWidth - popupImageWidth; } - if (_horizontal == NO) - { - [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)]; - } + [self setFrameSize: NSMakeSize (_cellSize.width + _leftBorderOffset, + (howMany * _cellSize.height) + + menuBarHeight)]; + [_titleView setFrame: NSMakeRect (0, howMany * _cellSize.height, + NSWidth (_bounds), menuBarHeight)]; _needsSizing = NO; } @@ -707,16 +676,10 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) - (NSRect) innerRect { - if (_horizontal == NO) - { - return NSMakeRect(_bounds.origin.x + _leftBorderOffset, _bounds.origin.y, - _bounds.size.width - _leftBorderOffset, _bounds.size.height); - } - else - { - return NSMakeRect(_bounds.origin.x, _bounds.origin.y + _leftBorderOffset, - _bounds.size.width, _bounds.size.height - _leftBorderOffset); - } + return NSMakeRect(_bounds.origin.x + _leftBorderOffset, + _bounds.origin.y, + _bounds.size.width - _leftBorderOffset, + _bounds.size.height); } - (NSRect) rectOfItemAtIndex: (int)index @@ -730,20 +693,10 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) /* When we are a normal menu we fiddle with the origin so that the item * rect is shifted 1 pixel over so we do not draw on the heavy line at - * origin.x = 0. However, for popups we don't want this modification of - * our rect so our _leftBorderOffset = 0 (set in sizeToFit). + * origin.x = 0. */ - if (_horizontal == NO) - { - theRect.origin.y = _cellSize.height * ([_itemCells count] - index - 1); - theRect.origin.x = _leftBorderOffset; - } - else - { - theRect.origin.x = _cellSize.width * index; - theRect.origin.y = _leftBorderOffset; - } - + theRect.origin.y = _cellSize.height * ([_itemCells count] - index - 1); + theRect.origin.x = _leftBorderOffset; theRect.size = _cellSize; /* NOTE: This returns the correct NSRect for drawing cells, but nothing @@ -767,16 +720,10 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) { NSRect aRect = [self rectOfItemAtIndex: i]; - /* We need to modify the rect to take into account the modifications - * to origin made by [-rectOfItemAtIndex:] in order to return an - * item clicked at the left hand margin. However, for a popup this - * calculation is unnecessary since we have no extra margin. - */ - if (![_menu _ownedByPopUp]) - aRect = _addLeftBorderOffsetToRect(aRect, _horizontal); + aRect = _addLeftBorderOffsetToRect(aRect); if (NSMouseInRect(point, aRect, NO)) - return (int)i; + return (int)i; } return -1; @@ -788,13 +735,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) aRect = [self rectOfItemAtIndex: index]; - /* We need to modify the rect to take into account the modifications - * to origin made by [-rectOfItemAtIndex:] in order to return an - * item clicked at the left hand margin. However, for a popup this - * calculation is unnecessary since we have no extra margin. - */ - if (![_menu _ownedByPopUp]) - aRect = _addLeftBorderOffsetToRect(aRect, _horizontal); + aRect = _addLeftBorderOffsetToRect(aRect); [self setNeedsDisplayInRect: aRect]; } @@ -816,36 +757,22 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) else submenuFrame = NSZeroRect; - if (_horizontal == NO) - { - if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil) - == GSWindowMakerInterfaceStyle) - { - NSRect aRect = [self rectOfItemAtIndex: - [_menu indexOfItemWithSubmenu: aSubmenu]]; - NSPoint subOrigin = [_window convertBaseToScreen: - NSMakePoint(aRect.origin.x, - aRect.origin.y)]; - - return NSMakePoint (NSMaxX(frame), - subOrigin.y - NSHeight(submenuFrame) - 3 + - 2*[NSMenuView menuBarHeight]); - } - else - { - return NSMakePoint(NSMaxX(frame), - NSMaxY(frame) - NSHeight(submenuFrame)); - } - } - else + if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil) + == GSWindowMakerInterfaceStyle) { NSRect aRect = [self rectOfItemAtIndex: - [_menu indexOfItemWithSubmenu: aSubmenu]]; + [_menu indexOfItemWithSubmenu: aSubmenu]]; NSPoint subOrigin = [_window convertBaseToScreen: - NSMakePoint(NSMinX(aRect), - NSMaxY(aRect))]; - return NSMakePoint(subOrigin.x, - subOrigin.y - NSHeight(submenuFrame)); + NSMakePoint(aRect.origin.x, aRect.origin.y)]; + + return NSMakePoint (NSMaxX(frame), + subOrigin.y - NSHeight(submenuFrame) - 3 + + 2*[NSMenuView menuBarHeight]); + } + else + { + return NSMakePoint(NSMaxX(frame), + NSMaxY(frame) - NSHeight(submenuFrame)); } } @@ -868,7 +795,14 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) cellFrame.size = screenRect.size; cellFrame.origin = [_window convertScreenToBase: screenRect.origin]; cellFrame = [self convertRect: cellFrame fromView: nil]; - + + // Remove title view if we owned by popup button + if ([_menu _ownedByPopUp] && _titleView) + { + [_titleView removeFromSuperview]; + _titleView = nil; + } + _cellSize = cellFrame.size; [self sizeToFit]; @@ -879,20 +813,12 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) if (items > 1) { float f; - - if (_horizontal == NO) - { - f = screenRect.size.height * (items - 1); - screenFrame.size.height += f + _leftBorderOffset; - screenFrame.origin.y -= f; - screenFrame.size.width += _leftBorderOffset; - screenFrame.origin.x -= _leftBorderOffset; - } - else - { - f = screenRect.size.width * (items - 1); - screenFrame.size.width += f; - } + + f = screenRect.size.height * (items - 1); + screenFrame.size.height += f + _leftBorderOffset; + screenFrame.origin.y -= f; + screenFrame.size.width += _leftBorderOffset; + screenFrame.origin.x -= _leftBorderOffset; } // Move the menu window to screen? @@ -901,14 +827,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) // Compute position for popups, if needed if (selectedItemIndex != -1) { - if (_horizontal == NO) - { - screenFrame.origin.y += screenRect.size.height * selectedItemIndex; - } - else - { - screenFrame.origin.x -= screenRect.size.width * selectedItemIndex; - } + screenFrame.origin.y += screenRect.size.height * selectedItemIndex; } // Get the frameRect @@ -931,7 +850,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) int howMany = [_itemCells count]; NSRectEdge sides[] = {NSMinXEdge, NSMaxYEdge}; float grays[] = {NSDarkGray, NSDarkGray}; - + // Draw the dark gray upper left lines. NSDrawTiledRects(rect, rect, sides, grays, 2); @@ -959,24 +878,24 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) NSMenuView *targetMenuView; int indexToHighlight = index; int oldHighlightedIndex; - + for (;;) { NSMenu *superMenu = [candidateMenu supermenu]; if (superMenu == nil - || [candidateMenu isAttached] - || [candidateMenu isTornOff]) - { - targetMenuView = [candidateMenu menuRepresentation]; + || [candidateMenu isAttached] + || [candidateMenu isTornOff]) + { + targetMenuView = [candidateMenu menuRepresentation]; - break; - } + break; + } else - { - indexToHighlight = [superMenu indexOfItemWithSubmenu: candidateMenu]; - candidateMenu = superMenu; - } + { + indexToHighlight = [superMenu indexOfItemWithSubmenu: candidateMenu]; + candidateMenu = superMenu; + } } oldHighlightedIndex = [targetMenuView highlightedItemIndex]; @@ -1062,7 +981,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) NSEvent *original; NSEventType type; NSEventType end; - + /* * The original event is unused except to determine whether the method * was invoked in response to a right or left mouse down. @@ -1094,42 +1013,42 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) end = NSLeftMouseUp; eventMask |= NSLeftMouseUpMask | NSLeftMouseDraggedMask; } - + do { if (type == NSPeriodic || event == original) - { + { NSPoint location; int index; - + location = [_window mouseLocationOutsideOfEventStream]; index = [self indexOfItemAtPoint: location]; - /* + /* * 1 - if menus is only partly visible and the mouse is at the * edge of the screen we move the menu so it will be visible. */ - if ([_menu isPartlyOffScreen]) - { - NSPoint pointerLoc = [_window convertBaseToScreen: location]; + if ([_menu isPartlyOffScreen]) + { + NSPoint pointerLoc = [_window convertBaseToScreen: location]; /* - * The +/-1 in the y - direction is because the flipping - * between X-coordinates and GNUstep coordinates let the - * GNUstep screen coordinates start with 1. - */ - if (pointerLoc.x == 0 || pointerLoc.y == 1 + * The +/-1 in the y - direction is because the flipping + * between X-coordinates and GNUstep coordinates let the + * GNUstep screen coordinates start with 1. + */ + if (pointerLoc.x == 0 || pointerLoc.y == 1 || pointerLoc.x == [[_window screen] frame].size.width - 1 || pointerLoc.y == [[_window screen] frame].size.height) - [_menu shiftOnScreen]; - } + [_menu shiftOnScreen]; + } /* - * 2 - Check if we have to reset the justAttachedNewSubmenu - * flag to NO. - */ + * 2 - Check if we have to reset the justAttachedNewSubmenu + * flag to NO. + */ if (justAttachedNewSubmenu && index != -1 - && index != _highlightedItemIndex) + && index != _highlightedItemIndex) { if (location.x - lastLocation.x > MOVE_THRESHOLD_DELTA) { @@ -1152,53 +1071,56 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) NSPoint locationInScreenCoordinates; NSWindow *windowUnderMouse; NSMenu *candidateMenu; - - subMenusNeedRemoving = NO; - - locationInScreenCoordinates - = [_window convertBaseToScreen: location]; - /* + subMenusNeedRemoving = NO; + + locationInScreenCoordinates + = [_window convertBaseToScreen: location]; + + /* * 3a - Check if moved into one of the ancester menus. * This is tricky, there are a few possibilities: * We are a transient attached menu of a - * non-transient menu + * non-transient menu * We are a non-transient attached menu * We are a root: isTornOff of AppMenu - */ + */ candidateMenu = [_menu supermenu]; while (candidateMenu - && !NSMouseInRect (locationInScreenCoordinates, [[candidateMenu window] frame], NO) // not found yet - && (! ([candidateMenu isTornOff] && ![candidateMenu isTransient])) // no root of display tree - && [candidateMenu isAttached]) // has displayed parent + && !NSMouseInRect (locationInScreenCoordinates, + [[candidateMenu window] frame], + NO) // not found yet + && (! ([candidateMenu isTornOff] + && ![candidateMenu isTransient])) // no root of display tree + && [candidateMenu isAttached]) // has displayed parent { candidateMenu = [candidateMenu supermenu]; } - + if (candidateMenu != nil - && NSMouseInRect (locationInScreenCoordinates, - [[candidateMenu window] frame], NO)) + && NSMouseInRect (locationInScreenCoordinates, + [[candidateMenu window] frame], NO)) { // The call to fetch attachedMenu is not needed. But putting // it here avoids flicker when we go back to an ancester meu // and the attached menu is alreay correct. [[[candidateMenu attachedMenu] menuRepresentation] - detachSubmenu]; + detachSubmenu]; return [[candidateMenu menuRepresentation] - trackWithEvent: original]; + trackWithEvent: original]; } // 3b - Check if we enter the attached submenu windowUnderMouse = [[_menu attachedMenu] window]; if (windowUnderMouse != nil - && NSMouseInRect (locationInScreenCoordinates, - [windowUnderMouse frame], NO)) + && NSMouseInRect (locationInScreenCoordinates, + [windowUnderMouse frame], NO)) { BOOL wasTransient = [_menu isTransient]; BOOL subMenuResult; - + subMenuResult - = [[self attachedMenuView] trackWithEvent: original]; + = [[self attachedMenuView] trackWithEvent: original]; if (subMenuResult && wasTransient == [_menu isTransient]) { [self detachSubmenu]; @@ -1206,7 +1128,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) return subMenuResult; } } - + // 4 - We changed the selected item and should update. if (!justAttachedNewSubmenu && index != _highlightedItemIndex) { @@ -1222,15 +1144,15 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) delayCount = 0; } } - + // Update last seen location for the justAttachedNewSubmenu logic. lastLocation = location; - } + } event = [NSApp nextEventMatchingMask: eventMask - untilDate: theDistantFuture - inMode: NSEventTrackingRunLoopMode - dequeue: YES]; + untilDate: theDistantFuture + inMode: NSEventTrackingRunLoopMode + dequeue: YES]; type = [event type]; } while (type != end); @@ -1260,7 +1182,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) * 3 - Remove the Transient menus from the screen. * 4 - Perform the action if there is one. */ - + [NSEvent stopPeriodicEvents]; /* @@ -1268,36 +1190,36 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) * will not be valid after we removed this menu from the screen. */ indexOfActionToExecute = _highlightedItemIndex; - + // remove transient menus. -------------------------------------------- - { - NSMenu *currentMenu = _menu; + { + NSMenu *currentMenu = _menu; - while (currentMenu && ![currentMenu isTransient]) - { - currentMenu = [currentMenu attachedMenu]; - } - - while ([currentMenu isTransient] && - [currentMenu supermenu]) - { - currentMenu = [currentMenu supermenu]; - } + while (currentMenu && ![currentMenu isTransient]) + { + currentMenu = [currentMenu attachedMenu]; + } - [[currentMenu menuRepresentation] detachSubmenu]; - - if ([currentMenu isTransient]) - { - [currentMenu closeTransient]; - } - } + while ([currentMenu isTransient] && + [currentMenu supermenu]) + { + currentMenu = [currentMenu supermenu]; + } + + [[currentMenu menuRepresentation] detachSubmenu]; + + if ([currentMenu isTransient]) + { + [currentMenu closeTransient]; + } + } // --------------------------------------------------------------------- if (indexOfActionToExecute == -1) { return YES; } - + if (indexOfActionToExecute >= 0 && [_menu attachedMenu] != nil && [_menu attachedMenu] == [[_items_link objectAtIndex: indexOfActionToExecute] submenu]) @@ -1401,7 +1323,6 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) [encoder encodeObject: _itemCells]; [encoder encodeObject: _font]; - [encoder encodeValueOfObjCType: @encode(BOOL) at: &_horizontal]; [encoder encodeValueOfObjCType: @encode(float) at: &_horizontalEdgePad]; [encoder encodeValueOfObjCType: @encode(NSSize) at: &_cellSize]; } @@ -1416,7 +1337,6 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) withObject: self]; [decoder decodeValueOfObjCType: @encode(id) at: &_font]; - [decoder decodeValueOfObjCType: @encode(BOOL) at: &_horizontal]; [decoder decodeValueOfObjCType: @encode(float) at: &_horizontalEdgePad]; [decoder decodeValueOfObjCType: @encode(NSSize) at: &_cellSize]; @@ -1475,9 +1395,11 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) if (attr == nil) { attr = [[NSDictionary alloc] initWithObjectsAndKeys: - [NSFont boldSystemFontOfSize: 0], NSFontAttributeName, - [NSColor windowFrameTextColor], NSForegroundColorAttributeName, - nil]; + [NSFont boldSystemFontOfSize: 0], + NSFontAttributeName, + [NSColor windowFrameTextColor], + NSForegroundColorAttributeName, + nil]; } return [[menu title] sizeWithAttributes: attr]; @@ -1523,19 +1445,19 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) NSDebugLLog (@"NSMenu", @"Mouse down in title!"); lastLocation = [theEvent locationInWindow]; - + if (![menu isTornOff] && [menu supermenu]) { - [menu setTornOff: YES]; + [menu setTornOff: YES]; } - + while (!done) { theEvent = [NSApp nextEventMatchingMask: eventMask - untilDate: theDistantFuture - inMode: NSEventTrackingRunLoopMode - dequeue: YES]; - + untilDate: theDistantFuture + inMode: NSEventTrackingRunLoopMode + dequeue: YES]; + switch ([theEvent type]) { case NSRightMouseUp: @@ -1548,13 +1470,13 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) 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; } @@ -1600,6 +1522,7 @@ _addLeftBorderOffsetToRect(NSRect aRect, BOOL isHorizontal) [self setNeedsDisplay: YES]; } +// We do not need app menu over menu - (void) rightMouseDown: (NSEvent*)theEvent { }