cvs server: Diffing .
Index: NSApplication.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSApplication.m,v
retrieving revision 1.194
diff -u -r1.194 NSApplication.m
--- NSApplication.m	26 Jan 2002 04:14:38 -0000	1.194
+++ NSApplication.m	20 Feb 2002 12:12:52 -0000
@@ -1947,8 +1947,10 @@
       
       if ([item target] == aWindow)
 	{
-	  [_windows_menu removeItem: item];
-	  break;
+	  /*
+	   * If our menu already exists we need not continue.
+	   */
+	  return;
 	}
     }
 
Index: NSMenu.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSMenu.m,v
retrieving revision 1.92
diff -u -r1.92 NSMenu.m
--- NSMenu.m	23 Jan 2002 16:32:20 -0000	1.92
+++ NSMenu.m	20 Feb 2002 12:12:55 -0000
@@ -344,6 +344,8 @@
   NSDictionary   *d;
   int index = [self indexOfItem: anObject];
 
+  NSDebugLog(@"NSMenu: itemChanged: %d\n", index);
+
   if (-1 == index)
     return;
 
@@ -363,6 +365,9 @@
 
   // Update the menu.
   [self update];
+
+  // Set our updated item alone for redisplay.
+  [_view setNeedsDisplayForItemAtIndex: index];
 }
 
 /*
@@ -831,31 +836,42 @@
   if (_popUpButtonCell == nil)
     {
       float height = [[_view class] menuBarHeight];
-
       size.height += height;
-      [_aWindow setContentSize: size];
-      [_aWindow setFrameTopLeftPoint:
-	NSMakePoint(NSMinX(windowFrame),NSMaxY(windowFrame))];
 
-      windowFrame = [_bWindow frame];
-      [_bWindow setContentSize: size];
-      [_bWindow setFrameTopLeftPoint:
-	NSMakePoint(NSMinX(windowFrame),NSMaxY(windowFrame))];
+      // If we are equal we need not proceed. This improves performance of 
+      // multiple itemChanged: messages (many of which cause no size 
+      // changes, for example setTarget: triggers all of this, perhaps 
+      // that should also be addressed?)
+      if (NSEqualSizes(size, windowFrame.size))
+	{
+	  _changed = NO;
+	  return;
+	}
 
+      // Temporary disable auto display so all the sizing can occur before 
+      // redrawing menuitems. We will only have to draw once instead of 
+      // twice.
+      [_aWindow setAutodisplay: NO];
+      [_aWindow setFrame: NSMakeRect (NSMinX(windowFrame), 
+	NSMaxY(windowFrame) - size.height, size.width, size.height) display: NO];
       [_view setFrameOrigin: NSMakePoint (0, 0)];
       [_titleView setFrame: NSMakeRect (0, size.height - height, 
 				       size.width, height)];
-      [_titleView setNeedsDisplay: YES];
+      [_aWindow setAutodisplay: YES];
+
+      windowFrame = [_bWindow frame];
+      [_bWindow setAutodisplay: NO];
+      [_bWindow setContentSize: size];
+      [_bWindow setFrameTopLeftPoint:
+	NSMakePoint(NSMinX(windowFrame),NSMaxY(windowFrame))];
+      [_bWindow setAutodisplay: YES];
     }
   else
     {
-      [_aWindow setContentSize: size];
-      [_aWindow setFrameTopLeftPoint:
-	NSMakePoint(NSMinX(windowFrame),NSMaxY(windowFrame))];
+      [_aWindow setFrame: NSMakeRect(NSMinX(windowFrame),NSMinY(windowFrame),size.width,size.height) 
+		display: NO];
     }
 
-  [_view setNeedsDisplay: YES];
-
   _changed = NO;
 }
 
@@ -1297,6 +1313,11 @@
     }
   else
     _isPartlyOffScreen = NO;
+}
+
+- (NSPopUpButtonCell*) _popUpButtonCell
+{
+  return _popUpButtonCell;
 }
 
 - (BOOL)_ownedByPopUp
Index: NSMenuItemCell.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSMenuItemCell.m,v
retrieving revision 1.27
diff -u -r1.27 NSMenuItemCell.m
--- NSMenuItemCell.m	14 Feb 2002 13:36:37 -0000	1.27
+++ NSMenuItemCell.m	20 Feb 2002 12:12:57 -0000
@@ -43,6 +43,19 @@
 
 #include <AppKit/PSOperators.h>
 
+/* Special NSPopUpCell/NSMenu setup */
+
+#include <AppKit/NSPopUpButtonCell.h>
+
+@interface NSMenu (GNUstepPrivate)
+- (NSPopUpButtonCell *) _popUpButtonCell;
+@end
+
+/* The image to use in a specific popupbutton is
+ * _pbc_image[_pbcFlags.pullsDown]; that is, _pbc_image[0] if it is a
+ * popup menu, _pbc_image[1] if it is a pulls down list.  */
+static NSImage *_pbc_image[2];
+
 @implementation NSMenuItemCell
 
 static Class	colorClass = 0;		/* Cache color class.	*/
@@ -58,6 +71,10 @@
       colorClass = [NSColor class];
       arrowImage = [[NSImage imageNamed: @"common_3DArrowRight"] copy];
       arrowImageH = [[NSImage imageNamed: @"common_3DArrowRightH"] copy];
+
+      /* Cache out popup icons */
+      ASSIGN(_pbc_image[0], [NSImage imageNamed: @"common_Nibble"]);
+      ASSIGN(_pbc_image[1], [NSImage imageNamed: @"common_3DArrowDown"]);
     }
 }
 
@@ -249,17 +266,10 @@
 //
 - (NSRect) imageRectForBounds:(NSRect)cellFrame
 {
-  if (_mcell_belongs_to_popupbutton && _cell.image_position)
-    {
-      /* Special case: draw image on the extreme right [FIXME check the distance]*/
-      cellFrame.origin.x  += cellFrame.size.width - _imageWidth - 4;
-      cellFrame.size.width = _imageWidth;
-      return cellFrame;
-    }
-
   // Calculate the image part of cell frame from NSMenuView
   cellFrame.origin.x  += [_menuView imageAndTitleOffset];
   cellFrame.size.width = [_menuView imageAndTitleWidth];
+
   /* If the state image has no width we do not add additional padding.  */
   if ([_menuItem changesState]  &&  _stateImageWidth > 0)
     {
@@ -322,6 +332,7 @@
   // Calculate the image part of cell frame from NSMenuView
   cellFrame.origin.x  += [_menuView imageAndTitleOffset];
   cellFrame.size.width = [_menuView imageAndTitleWidth];
+
   /* If the state image has no width we do not add additional padding.  */
   if ([_menuItem changesState]  &&  _stateImageWidth > 0)
     {
@@ -389,6 +400,8 @@
   [controlView unlockFocus];
 }
 
+#define IMAGE_DISSOLVE_VALUE 0.3
+
 - (void) drawImageWithFrame: (NSRect)cellFrame
 		     inView: (NSView *)controlView
 {
@@ -408,7 +421,11 @@
 
   if (nil != _backgroundColor)
     [_imageToDisplay setBackgroundColor: _backgroundColor];
-  [_imageToDisplay compositeToPoint: position operation: NSCompositeSourceOver];
+
+  if ([_menuItem isEnabled])
+    [_imageToDisplay compositeToPoint: position operation: NSCompositeSourceOver];
+  else
+    [_imageToDisplay dissolveToPoint: position fraction: IMAGE_DISSOLVE_VALUE];
 }
 
 - (void) drawKeyEquivalentWithFrame:(NSRect)cellFrame
@@ -451,6 +468,37 @@
   // Maybe somebody wants to support this (Lazaro).
 }
 
+- (void) _drawPopUpIconWithFrame: (NSRect)cellFrame
+			  inView: (NSView*)controlView
+{
+  NSSize	size;
+  NSPoint	position;
+  NSImage	*imageToDisplay;
+
+  if ([[[_menuView menu] _popUpButtonCell] pullsDown])
+    imageToDisplay = _pbc_image[1];
+  else
+    imageToDisplay = _pbc_image[0];
+
+  size = [imageToDisplay size];
+
+  cellFrame.origin.x  += cellFrame.size.width - size.width - 4;
+  cellFrame.size.width = size.width;
+
+  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;
+
+  if (nil != _backgroundColor)
+    [imageToDisplay setBackgroundColor: _backgroundColor];
+  [imageToDisplay compositeToPoint: position operation: NSCompositeSourceOver];
+}
+
 - (void) drawStateImageWithFrame: (NSRect)cellFrame
 			  inView: (NSView*)controlView
 {
@@ -632,6 +680,13 @@
   // Draw the key equivalent
   if (_keyEquivalentWidth > 0)
     [self drawKeyEquivalentWithFrame: cellFrame inView: controlView];
+
+  // Draw NSPopUpButton icon
+  if (_mcell_belongs_to_popupbutton 
+    && [[[_menuView menu] _popUpButtonCell] selectedItem] == _menuItem)
+    {
+      [self _drawPopUpIconWithFrame: cellFrame inView: controlView];
+    }
 
   [controlView unlockFocus];
   _backgroundColor = nil;
Index: NSMenuView.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSMenuView.m,v
retrieving revision 1.55
diff -u -r1.55 NSMenuView.m
--- NSMenuView.m	11 Feb 2002 14:06:00 -0000	1.55
+++ NSMenuView.m	20 Feb 2002 12:13:00 -0000
@@ -465,7 +465,14 @@
 
   if (_horizontal == NO)
     {
-      [self setFrameSize: NSMakeSize(_cellSize.width + 1, 
+      // An NSPopUpButton does not need this extra pixel. Otherwise the 
+      // NSMenuWindow expands one pixel larger than the NSPopUpButton 
+      // itself.
+      if (![_menu _ownedByPopUp])
+        [self setFrameSize: NSMakeSize(_cellSize.width + 1, 
+				     (howMany * _cellSize.height))];
+      else
+        [self setFrameSize: NSMakeSize(_cellSize.width, 
 				     (howMany * _cellSize.height))];
     }
   else
@@ -755,6 +762,7 @@
       if (NSIntersectsRect(rect, aRect) == YES)
         {
           aCell = [_itemCells objectAtIndex: i];
+	  NSDebugLog(@"NSMenuView: drawCell for: %@ at index: %d", [_menu title], i);
 	  [aCell drawWithFrame: aRect inView: self];
         }
     }
Index: NSPopUpButtonCell.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSPopUpButtonCell.m,v
retrieving revision 1.38
diff -u -r1.38 NSPopUpButtonCell.m
--- NSPopUpButtonCell.m	14 Feb 2002 13:41:34 -0000	1.38
+++ NSPopUpButtonCell.m	20 Feb 2002 12:13:12 -0000
@@ -35,19 +35,12 @@
 #include <AppKit/NSPopUpButtonCell.h>
 #include <AppKit/PSOperators.h>
 
-/* The image to use in a specific popupbutton is
- * _pbc_image[_pbcFlags.pullsDown]; that is, _pbc_image[0] if it is a
- * popup menu, _pbc_image[1] if it is a pulls down list.  */
-static NSImage *_pbc_image[2];
-
 @implementation NSPopUpButtonCell
 + (void) initialize
 {
   if (self == [NSPopUpButtonCell class])
     {
       [self setVersion: 1];
-      ASSIGN(_pbc_image[0], [NSImage imageNamed: @"common_Nibble"]);
-      ASSIGN(_pbc_image[1], [NSImage imageNamed: @"common_3DArrowDown"]);
     }
 }
 
@@ -277,7 +270,6 @@
 	{
 	  [_selectedItem setState: NSOffState];
 	}
-      [_selectedItem setImage: nil];
     }
 
   _selectedItem = item;
@@ -288,7 +280,6 @@
         {
 	  [_selectedItem setState: NSOnState];
         }
-      [_selectedItem setImage: _pbc_image[_pbcFlags.pullsDown]];
     }
 
   /* Set the item in the menu */
@@ -437,7 +428,7 @@
       onScreen: [cvWin screen]
       preferredEdge: _pbcFlags.preferredEdge
       popUpSelectedItem: selectedItem];
-  
+
   // Last, display the window
   [[mr window] orderFrontRegardless];
 }
@@ -486,66 +477,51 @@
  * that is used to draw cells in the menu.
  * This looks like a mess to do in this framework.
  */
+- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
+{
+  NSMenuItemCell    *aCell;
+  
+  /* Get the NSMenuItemCell of the selected item */
+
+  aCell = [[_menu menuRepresentation] menuItemCellForItemAtIndex: [self indexOfSelectedItem]];
+
+  /* Turn off highlighting so the NSPopUpButton looks right */
+
+  [aCell setHighlighted: NO];
+
+  /* Minor cellFrame fix for an assumption made in the NSMenuItemCell 
+   * drawing.
+   */
+
+  cellFrame.origin.x++;
+  [aCell drawWithFrame: cellFrame inView: controlView];
+
+  /* Draw the interior so we pick up our dotted frame */
+
+  [self drawInteriorWithFrame: cellFrame inView: controlView];
+
+  /* Rehighlight item for consistency */
+
+  [aCell setHighlighted: YES];
+}
+
 - (void) drawInteriorWithFrame: (NSRect)cellFrame
 			inView: (NSView*)view
 {
-  NSSize   size;
-  NSPoint  position;
-  NSImage *anImage;
-  
   // Save last view drawn to
   if (_control_view != view)
     _control_view = view;
 
   [view lockFocus];
 
-  //  [super drawWithFrame: cellFrame inView: view];
-
   cellFrame = [self drawingRectForBounds: cellFrame];
   if (_cell.is_bordered || _cell.is_bezeled)
     {
-      cellFrame.origin.x += 3;
-      cellFrame.size.width -= 6;
+      cellFrame.size.width -= 2;
       cellFrame.origin.y += 1;
       cellFrame.size.height -= 2;
     }
-  // Skip 5 points from left side
-  //  cellFrame.origin.x += 5;
-  //  cellFrame.size.width -= 5;
-
-  cellFrame.origin.x += 2;
-  cellFrame.size.width -= 2;
-
-  [self _drawText: [self titleOfSelectedItem] inFrame: cellFrame];
-
-  cellFrame.origin.x -= 4;
-  cellFrame.size.width += 4;
-  
-  anImage = _pbc_image[_pbcFlags.pullsDown];
-
-  /* NB: If we are drawing here, then the control can't be selected */
-  [anImage setBackgroundColor: [NSColor controlBackgroundColor]];
-
-  size = [anImage 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 ([view isFlipped])
-    position.y += size.height;
-  [anImage  compositeToPoint: position operation: NSCompositeCopy];
-
-  if (_cell.is_bordered || _cell.is_bezeled)
-    {
-      cellFrame.origin.x -= 1;
-      cellFrame.size.width += 2;
-    }
 
-  cellFrame.origin.y -= 1;
-  cellFrame.size.height += 2;
-  cellFrame.size.width += 2;
   if (_cell.shows_first_responder
       && [[view window] firstResponder] == view)
     NSDottedFrameRect(cellFrame);
@@ -566,7 +542,8 @@
   if (count == 0)
     return NSZeroSize;
   
-  imageSize = [_pbc_image[_pbcFlags.pullsDown] size];
+  // This still needs to be worked on.
+  imageSize = [[[_menu itemAtIndex: i] image] size];
   s = NSMakeSize(0, imageSize.height);
   
   for (i = 0; i < count; i++)
Index: NSTabView.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSTabView.m,v
retrieving revision 1.34
diff -u -r1.34 NSTabView.m
--- NSTabView.m	17 Dec 2001 16:51:50 -0000	1.34
+++ NSTabView.m	20 Feb 2002 12:13:15 -0000
@@ -639,6 +639,17 @@
 
 // Event handling.
 
+- (void) mouseDown: (NSEvent *)theEvent
+{
+  NSPoint location = [theEvent locationInWindow];
+  NSTabViewItem *anItem = [self tabViewItemAtPoint: location];
+
+  if (anItem && ![anItem isEqual: _selected])
+    {
+      [self selectTabViewItem: anItem];
+    }
+}
+
 - (NSTabViewItem*) tabViewItemAtPoint: (NSPoint)point
 {
   int		howMany = [_items count];
@@ -655,18 +666,6 @@
     }
 
   return nil;
-}
-
-- (NSView*) hitTest: (NSPoint)aPoint
-{
-  NSTabViewItem *anItem = [self tabViewItemAtPoint: aPoint];
-
-  if (anItem && ![anItem isEqual: _selected])
-    {
-      [self selectTabViewItem: anItem];
-    }
-
-  return [super hitTest: aPoint];
 }
 
 - (NSControlSize)controlSize
