gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Button Cell Images


From: Christopher Armstrong
Subject: Re: Button Cell Images
Date: Mon, 25 Jun 2007 22:34:02 +1000
User-agent: Thunderbird 1.5.0.12 (Windows/20070509)

Hi

Richard Frith-Macdonald wrote:

On 25 Jun 2007, at 12:15, Christopher Armstrong wrote:
Do we really need to match Apple's behaviour? This is an undocumented API so it shouldn't need to conform anyway as third party developers shouldn't depend on it, especially if they're are porting code to GNUstep.

Certainly we need to match Apple's behavior if we want to make porting easy (the alternative is that we accept the lousy press when people who try to port from Apple just say GNUstep is no good because code that works on MacOS-X doesn't work with GNUstep). Especially because Apple have a habit of updating/improving their documentation to include explicit descriptions of behaviors that were previously there but not mentioned... So while implementing undocumented behaviors is not high on my priority list, I try to ensure that GNUstep matches Apple when I can.
Sorry I didn't think that Apple would expose this behaviour considering it is such a clumsy way of doing things. I don't have access to an Apple machine to experiment with. I am more inclined to just guess the behaviour and fix it later, even though it isn't the ideal solution as you outline above. The results of your experimentation would be most welcome.
5. Modify GSTheme to handle this. Shouldn't be too difficult with the theme image loading code already in place (although it really shouldn't put all the theme images in the default namespace - that feature is incompatible with this solution.

I agree ... the image sup[port in GSTheme needs to be enhanced to correctly differentiate between system images (which should be named and in the global namespace) and images used for tiling etc
I was thinking it shouldn't put any images in the global namespace at all, and instead the theme provides an API to access them from GSTheme.

6. Modify NSButtonCell to handle NSButtonImageSource instances. This would involve storing them when nibs are serialized (should we bump the class version?) and loading them out when they are inflated again. We also need to handle the theme changed events so they redraw.

Okay that reads more like an action plan but we probably want to get this right and coding for GNUstep on Windows is painful (this is what I'm trying to theme).

I had thought that it would be good to develop a windows theme under gnu/linux to start with, then add backend specific features later. By backend specific features I meant things like the ability to get the system colors from windows APIs and make them appear as a system color list in the theme, and to sample things like button images from the windows api, and make sections of a button image appear as tile images for tiling within the theme. Such extensions could mean that a windows theme, when running on windows, could adapt itsself to conform to the native windows theming mechanisms.
I have considered doing things this way but I am currently going the way I am for a few reasons:

* In order to draw like a Windows machine, we have the option of using the theming API on windows (aka "Visual Styles") or using custom drawing to do everything manually. Unfortunately we have to do both, as the theming API is not available on Win2K and on WinXP/Vista the theme API deliberately fails when the Win98/2K theme is enabled so that controls fall back on their normal drawing which is the old style.

* We just can't sample on Windows and create tiles as it supports quite a number of themes that we will want to be compatible with.

* Windows visual styles API doesn't let you retrieve the images that make up the visual style; it only lets you draw with them (under WinXP anyway).

* For the parts where the visual styles fail, and I need to fall back on manual drawing, it is easier to confirm the results of drawing output on the OS I am targeting. I can also separate these parts and port the result back to other OS's.

All that said, given that I don't have access to a Mac for development, I think I will go ahead and implement something along the lines I specified above so that I can get themeing working better.

On another note, please find attached a patch that contains what I have so far in terms of theming. It is the same as last time but I've cleaned it up somewhat.

Regards
Chris
Index: Source/GSTheme.m
===================================================================
--- Source/GSTheme.m    (revision 25290)
+++ Source/GSTheme.m    (working copy)
@@ -43,6 +43,7 @@
 #include "AppKit/NSImageView.h"
 #include "AppKit/NSMatrix.h"
 #include "AppKit/NSMenu.h"
+#include "AppKit/NSMenuView.h"
 #include "AppKit/NSPanel.h"
 #include "AppKit/NSScrollView.h"
 #include "AppKit/NSTextContainer.h"
@@ -613,7 +614,7 @@
        * VerticalDivision      Where to divide the image into rows.
        */
       info = [self infoDictionary];
-      info = [[info objectForKey: @"GSThemeTiles"] objectForKey: aName];
+      info = [(NSDictionary*)[info objectForKey: @"GSThemeTiles"] 
objectForKey: aName];
       if ([info isKindOfClass: [NSDictionary class]] == YES)
         {
          float         x;
@@ -692,8 +693,72 @@
 
 @end
 
+// This is the default scrollbar width
+static const float defaultScrollerWidth = 18;
 
+// This is the default scrollbar color.
+static NSColor *scrollBarColor = nil;
+
 @implementation        GSTheme (Drawing)
+- (void) customizeButtonCell:(NSButtonCell*)cell
+                   withType:(NSButtonType)type
+{
+  switch (type)
+    {
+      case NSMomentaryLightButton: 
+        [cell setHighlightsBy: NSChangeBackgroundCellMask];
+        [cell setShowsStateBy: NSNoCellMask];
+        [cell setImageDimsWhenDisabled: YES];
+        break;
+      case NSMomentaryPushInButton: 
+        [cell setHighlightsBy: NSPushInCellMask | NSChangeGrayCellMask];
+        [cell setShowsStateBy: NSNoCellMask];
+        [cell setImageDimsWhenDisabled: YES];
+        break;
+      case NSMomentaryChangeButton: 
+        [cell setHighlightsBy: NSContentsCellMask];
+        [cell setShowsStateBy: NSNoCellMask];
+        [cell setImageDimsWhenDisabled: YES];
+        break;
+      case NSPushOnPushOffButton: 
+        [cell setHighlightsBy: NSPushInCellMask | NSChangeGrayCellMask];
+        [cell setShowsStateBy: NSChangeBackgroundCellMask];
+        [cell setImageDimsWhenDisabled: YES];
+        break;
+      case NSOnOffButton: 
+        [cell setHighlightsBy: NSChangeBackgroundCellMask];
+        [cell setShowsStateBy: NSChangeBackgroundCellMask];
+        [cell setImageDimsWhenDisabled: YES];
+        break;
+      case NSToggleButton: 
+        [cell setHighlightsBy: NSPushInCellMask | NSContentsCellMask];
+        [cell setShowsStateBy: NSContentsCellMask];
+        [cell setImageDimsWhenDisabled: YES];
+        break;
+      case NSSwitchButton: 
+        [cell setHighlightsBy: NSContentsCellMask];
+        [cell setShowsStateBy: NSContentsCellMask];
+        [cell setImage: [NSImage imageNamed: @"NSSwitch"]];
+        [cell setAlternateImage: [NSImage imageNamed: @"NSHighlightedSwitch"]];
+        [cell setImagePosition: NSImageLeft];
+        [cell setAlignment: NSLeftTextAlignment];
+        [cell setBordered: NO];
+        [cell setBezeled: NO];
+        [cell setImageDimsWhenDisabled: NO];
+        break;
+      case NSRadioButton: 
+        [cell setHighlightsBy: NSContentsCellMask];
+        [cell setShowsStateBy: NSContentsCellMask];
+        [cell setImage: [NSImage imageNamed: @"NSRadioButton"]];
+        [cell setAlternateImage: [NSImage imageNamed: 
@"NSHighlightedRadioButton"]];
+        [cell setImagePosition: NSImageLeft];
+        [cell setAlignment: NSLeftTextAlignment];
+        [cell setBordered: NO];
+        [cell setBezeled: NO];
+        [cell setImageDimsWhenDisabled: NO];
+        break;
+    }
+}
 
 - (void) drawButton: (NSRect)frame 
                  in: (NSButtonCell*)cell 
@@ -786,6 +851,16 @@
     }
 }
 
+- (NSRect) buttonContentRect:(NSRect)frame
+              forStyle:(int)style
+              state:(GSThemeControlState)state
+{
+  NSSize borderSize;
+
+  borderSize = [self buttonBorderForStyle:style state:state];
+  return NSInsetRect(frame, borderSize.width, borderSize.height);
+}
+
 - (NSSize) buttonBorderForStyle: (int)style 
                          state: (GSThemeControlState)state
 {
@@ -858,10 +933,129 @@
   NSRectFill (frame);
 }
 
address@hidden
+- (void) drawMenuViewBackground:(NSRect) frame view:(NSMenuView*)view
+{
+  NSRectEdge sides[2]; 
+  float      grays[] = {NSDarkGray, NSDarkGray};
 
+  if ([view isHorizontal] == YES)
+    {
+      sides[0] = NSMinYEdge;
+      sides[1] = NSMinYEdge;
+      NSDrawTiledRects(frame, frame, sides, grays, 2);
+    }
+  else
+    {
+      sides[0] = NSMinXEdge;
+      sides[1] = NSMaxYEdge;
+      // Draw the dark gray upper left lines.
+      NSDrawTiledRects(frame, frame, sides, grays, 2);
+    }
+}
 
+- (void) drawMenuItemBorderAndBackground:(NSRect)frame 
+                                      in:(NSMenuItemCell*)cell
+                                    view:(NSView*) view
+                                   state:(GSThemeControlState)state 
+{
 
+  if ([[cell menuView] isHorizontal] == YES)
+    {
+      frame = [cell drawingRectForBounds: frame];
+      [[cell backgroundColor] set];
+      NSRectFill(frame);
+      return;
+    }
+
+  // Set cell's background color
+  [[cell backgroundColor] set];
+  NSRectFill(frame);
+
+  if (![cell isBordered])
+    return;
+
+  if (state==GSThemeHighlightedState && ([cell cellAttribute:NSPushInCell] & 
NSPushInCellMask))
+    {
+      [[GSTheme theme] drawGrayBezel: frame withClip: NSZeroRect];
+    }
+  else
+    {
+      [[GSTheme theme] drawButton: frame withClip: NSZeroRect];
+    }
+
+}
+
+- (float) defaultScrollerWidth
+{
+  return defaultScrollerWidth;
+}
+
+- (NSButtonCell*) cellForScrollerArrow:(NSScrollerArrow)arrow 
horizontal:(BOOL)horizontal
+{
+  NSButtonCell* cell;
+  
+  cell = [NSButtonCell new];
+  if (horizontal)
+    {
+      if (arrow==NSScrollerDecrementArrow)
+        {
+          [cell setHighlightsBy: NSChangeBackgroundCellMask | 
NSContentsCellMask];
+          [cell setImage: [NSImage imageNamed: @"common_ArrowLeft"]];
+          [cell setAlternateImage: [NSImage imageNamed: @"common_ArrowLeftH"]];
+          [cell setImagePosition: NSImageOnly];
+        }
+      else
+        {
+          [cell setHighlightsBy: NSChangeBackgroundCellMask | 
NSContentsCellMask];
+          [cell setImage: [NSImage imageNamed: @"common_ArrowRight"]];
+          [cell setAlternateImage: [NSImage imageNamed: 
@"common_ArrowRightH"]];
+          [cell setImagePosition: NSImageOnly];
+        }
+    }
+  else
+    {
+      if (arrow==NSScrollerDecrementArrow)
+        {
+          [cell setHighlightsBy: NSChangeBackgroundCellMask | 
NSContentsCellMask];
+          [cell setImage: [NSImage imageNamed: @"common_ArrowUp"]];
+          [cell setAlternateImage: [NSImage imageNamed: @"common_ArrowUpH"]];
+          [cell setImagePosition: NSImageOnly];
+        }
+      else
+        {
+          [cell setHighlightsBy: NSChangeBackgroundCellMask | 
NSContentsCellMask];
+          [cell setImage: [NSImage imageNamed: @"common_ArrowDown"]];
+          [cell setAlternateImage: [NSImage imageNamed: @"common_ArrowDownH"]];
+          [cell setImagePosition: NSImageOnly];
+        }
+    }
+  return AUTORELEASE(cell);
+}
+
+- (NSCell*) cellForScrollerKnob:(BOOL)horizontal
+{
+  NSButtonCell* knobCell;
+  knobCell = [NSButtonCell new];
+  [knobCell setButtonType: NSMomentaryChangeButton];
+  [knobCell setImage: [NSImage imageNamed: @"common_Dimple"]];
+  [knobCell setImagePosition: NSImageOnly];
+  return knobCell;
+}
+
+- (NSCell*) cellForScrollerKnobSlot:(BOOL)horizontal
+{
+  NSButtonCell *cell;
+  if (scrollBarColor==nil)
+    scrollBarColor = [NSColor scrollBarColor];
+
+  cell = [NSButtonCell new];
+  [cell setBordered:NO];
+  [cell setBackgroundColor:scrollBarColor];
+  return AUTORELEASE(cell);
+}
+
address@hidden
+
 @implementation        GSTheme (MidLevelDrawing)
 
 - (NSRect) drawButton: (NSRect)border withClip: (NSRect)clip
Index: Source/NSButtonCell.m
===================================================================
--- Source/NSButtonCell.m       (revision 25290)
+++ Source/NSButtonCell.m       (working copy)
@@ -687,8 +687,6 @@
 
 - (void) setButtonType: (NSButtonType)buttonType
 {
-  // Don't store the button type anywhere
-
   switch (buttonType)
     {
       case NSMomentaryLightButton: 
Index: Source/NSMenuItemCell.m
===================================================================
--- Source/NSMenuItemCell.m     (revision 25290)
+++ Source/NSMenuItemCell.m     (working copy)
@@ -594,30 +594,16 @@
 - (void) drawBorderAndBackgroundWithFrame: (NSRect)cellFrame
                                   inView: (NSView *)controlView
 {
-  if ([_menuView isHorizontal] == YES)
-    {
-      cellFrame = [self drawingRectForBounds: cellFrame];
-      [[self backgroundColor] set];
-      NSRectFill(cellFrame);
-      return;
-    }
-
-  // Set cell's background color
-  [[self backgroundColor] set];
-  NSRectFill(cellFrame);
-
-  if (!_cell.is_bordered)
-    return;
-
-  if (_cell.is_highlighted && (_highlightsByMask & NSPushInCellMask))
-    {
-      [[GSTheme theme] drawGrayBezel: cellFrame withClip: NSZeroRect];
-    }
+  GSThemeControlState state;
+  if (_cell.is_highlighted)
+    state = GSThemeHighlightedState;
   else
-    {
-      [[GSTheme theme] drawButton: cellFrame withClip: NSZeroRect];
+    state = GSThemeNormalState;
+  [[GSTheme theme] drawMenuItemBorderAndBackground:cellFrame
+                                                in:self
+                                              view:controlView
+                                             state:state]; 
     }
-}
 
 - (void) drawImageWithFrame: (NSRect)cellFrame
                      inView: (NSView *)controlView
Index: Source/NSButtonImageSource.h
===================================================================
--- Source/NSButtonImageSource.h        (revision 25290)
+++ Source/NSButtonImageSource.h        (working copy)
@@ -45,7 +45,7 @@
 + (id) buttonImageSourceWithName: (NSString*)name;
 - (id) copyWithZone: (NSZone*)zone;
 - (void) dealloc;
-- (void) encodeWithCode: (NSCoder*)aCoder;
+- (void) encodeWithCoder: (NSCoder*)aCoder;
 - (id) imageForState: (struct NSButtonState)state;
 - (id) initWithCoder: (NSCoder*)aCoder;
 @end
Index: Source/NSScroller.m
===================================================================
--- Source/NSScroller.m (revision 25290)
+++ Source/NSScroller.m (working copy)
@@ -42,6 +42,8 @@
 #include "AppKit/NSColor.h"
 #include "AppKit/NSGraphics.h"
 
+#include "GNUstepGUI/GSTheme.h"
+
 /**<p>TODO Description</p>
  */
 @implementation NSScroller
@@ -55,13 +57,13 @@
 static NSButtonCell* downCell = nil;
 static NSButtonCell* leftCell = nil;
 static NSButtonCell* rightCell = nil;
-static NSButtonCell* knobCell = nil;
+static NSCell* horizontalKnobCell = nil;
+static NSCell* verticalKnobCell = nil;
+static NSCell* horizontalKnobSlotCell = nil;
+static NSCell* verticalKnobSlotCell = nil;
 
-static const float scrollerWidth = 18;
 static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
 
-static NSColor *scrollBarColor = nil;
-
 /*
  * Class methods
  */
@@ -70,7 +72,6 @@
   if (self == [NSScroller class])
     {
       [self setVersion: 1];
-      ASSIGN (scrollBarColor, [NSColor scrollBarColor]);
     }
 }
 
@@ -80,7 +81,7 @@
  */
 + (float) scrollerWidth
 {
-  return scrollerWidth;
+  return [[GSTheme theme] defaultScrollerWidth];  
 }
 
 - (BOOL) isFlipped
@@ -320,52 +321,35 @@
  */
 - (void) drawParts
 {
-  /*
-   * Create the class variable button cells if they do not yet exist.
-   */
-  if (knobCell)
+  GSTheme *theme = [GSTheme theme] ;
+
+  if (upCell)
     return;
 
-  upCell = [NSButtonCell new];
-  [upCell setHighlightsBy: NSChangeBackgroundCellMask | NSContentsCellMask];
-  [upCell setImage: [NSImage imageNamed: @"common_ArrowUp"]];
-  [upCell setAlternateImage: [NSImage imageNamed: @"common_ArrowUpH"]];
-  [upCell setImagePosition: NSImageOnly];
-  [upCell setContinuous: YES];
-  [upCell sendActionOn: (NSLeftMouseDownMask | NSPeriodicMask)];
-  [upCell setPeriodicDelay: 0.3 interval: 0.03];
+  upCell = RETAIN([theme cellForScrollerArrow:NSScrollerDecrementArrow 
horizontal:NO]);
+  downCell = RETAIN([theme cellForScrollerArrow:NSScrollerIncrementArrow 
horizontal:NO]);
+  leftCell = RETAIN([theme cellForScrollerArrow:NSScrollerDecrementArrow 
horizontal:YES]);
+  rightCell = RETAIN([theme cellForScrollerArrow:NSScrollerIncrementArrow 
horizontal:YES]);
+  verticalKnobCell = RETAIN([theme cellForScrollerKnob:NO]);
+  horizontalKnobCell = RETAIN([theme cellForScrollerKnob:YES]);
+  verticalKnobSlotCell = RETAIN([theme cellForScrollerKnobSlot:NO]);
+  horizontalKnobSlotCell = RETAIN([theme cellForScrollerKnobSlot:YES]);
 
-  downCell = [NSButtonCell new];
-  [downCell setHighlightsBy: NSChangeBackgroundCellMask | NSContentsCellMask];
-  [downCell setImage: [NSImage imageNamed: @"common_ArrowDown"]];
-  [downCell setAlternateImage: [NSImage imageNamed: @"common_ArrowDownH"]];
-  [downCell setImagePosition: NSImageOnly];
   [downCell setContinuous: YES];
   [downCell sendActionOn: (NSLeftMouseDownMask | NSPeriodicMask)];
   [downCell setPeriodicDelay: 0.3 interval: 0.03];
 
-  leftCell = [NSButtonCell new];
-  [leftCell setHighlightsBy: NSChangeBackgroundCellMask | NSContentsCellMask];
-  [leftCell setImage: [NSImage imageNamed: @"common_ArrowLeft"]];
-  [leftCell setAlternateImage: [NSImage imageNamed: @"common_ArrowLeftH"]];
-  [leftCell setImagePosition: NSImageOnly];
   [leftCell setContinuous: YES];
   [leftCell sendActionOn: (NSLeftMouseDownMask | NSPeriodicMask)];
   [leftCell setPeriodicDelay: 0.3 interval: 0.03];
 
-  rightCell = [NSButtonCell new];
-  [rightCell setHighlightsBy: NSChangeBackgroundCellMask | NSContentsCellMask];
-  [rightCell setImage: [NSImage imageNamed: @"common_ArrowRight"]];
-  [rightCell setAlternateImage: [NSImage imageNamed: @"common_ArrowRightH"]];
-  [rightCell setImagePosition: NSImageOnly];
   [rightCell setContinuous: YES];
   [rightCell sendActionOn: (NSLeftMouseDownMask | NSPeriodicMask)];
   [rightCell setPeriodicDelay: 0.3 interval: 0.03];
 
-  knobCell = [NSButtonCell new];
-  [knobCell setButtonType: NSMomentaryChangeButton];
-  [knobCell setImage: [NSImage imageNamed: @"common_Dimple"]];
-  [knobCell setImagePosition: NSImageOnly];
+  [upCell setContinuous: YES];
+  [upCell sendActionOn: (NSLeftMouseDownMask | NSPeriodicMask)];
+  [upCell setPeriodicDelay: 0.3 interval: 0.03];
 }
 
 - (void) _setTargetAndActionToCells
@@ -382,8 +366,11 @@
   [rightCell setTarget: _target];
   [rightCell setAction: _action];
 
-  [knobCell setTarget: _target];
-  [knobCell setAction: _action];
+  [horizontalKnobCell setTarget: _target];
+  [horizontalKnobCell setAction: _action];
+  
+  [verticalKnobCell setTarget:_target];
+  [horizontalKnobCell setTarget:_target];
 }
 
 - (void) checkSpaceForParts
@@ -945,7 +932,14 @@
  */
 - (void) drawKnob
 {
-  [knobCell drawWithFrame: [self rectForPart: NSScrollerKnob] inView: self];
+  if (_isHorizontal)
+    {
+      [horizontalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob] 
inView: self];
+    }
+  else
+    {
+      [verticalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob] 
inView: self];
+    }
 }
 
 - (void) drawKnobSlot
@@ -957,8 +951,14 @@
       rect = [self rectForPart: NSScrollerKnobSlot];
     }
 
-  [scrollBarColor set];
-  NSRectFill (rect);
+  if (_isHorizontal)
+    {
+      [horizontalKnobSlotCell drawWithFrame:rect inView:self];
+    }
+   else
+    {
+      [verticalKnobSlotCell drawWithFrame:rect inView:self];
+    }
 }
 
 /**<p>Highlights the button whose under the mouse. Does nothing if the mouse
@@ -984,15 +984,37 @@
 }
 
 /**
+  * Gets the bounds based rectangle that specifies the location and size 
+  * for the part specified by partCode.
  */
 - (NSRect) rectForPart: (NSScrollerPart)partCode
 {
   NSRect scrollerFrame = _frame;
-  float x = 1, y = 1;
+  float x, y;
   float width, height;
-  float buttonsWidth = ([isa scrollerWidth] - buttonsOffset);
-  float buttonsSize = 2 * buttonsWidth + 2;
+  float buttonsWidth;
+  float buttonsSize;  
   NSUsableScrollerParts usableParts;
+
+  NSInterfaceStyle interfaceStyle = 
NSInterfaceStyleForKey(@"NSScrollerInterfaceStyle",self);
+
+
+  /* We use the button offset if we in the NeXTstep interface style. */
+  if (interfaceStyle==NSNextStepInterfaceStyle || 
interfaceStyle==GSWindowMakerInterfaceStyle)
+    { 
+      buttonsWidth = ([isa scrollerWidth] - buttonsOffset);
+      x = y = 1.0;
+      buttonsSize = 2 * buttonsWidth + 2;
+    }
+  else
+    {
+      buttonsWidth = [isa scrollerWidth];
+      x = 1.0;
+      y = 1.0;
+      buttonsSize = 2 * buttonsWidth;
+    }
+
+
   /*
    * If the scroller is disabled then the scroller buttons and the
    * knob are not displayed at all.
@@ -1052,13 +1074,23 @@
          knobPosition = _floatValue * (slotHeight - knobHeight);
          knobPosition = floor(knobPosition);
 
-
          /* calc actual position */
-         y += knobPosition + ((_arrowsPosition == NSScrollerArrowsMaxEnd
+          if (interfaceStyle==NSNextStepInterfaceStyle || 
+              interfaceStyle==GSWindowMakerInterfaceStyle)
+            {
+             y += knobPosition + ((_arrowsPosition == NSScrollerArrowsMaxEnd
                               || _arrowsPosition == NSScrollerArrowsNone)
                               ?  0 : buttonsSize);
+             width = buttonsWidth;
+            }
+          else
+            {
+              y += knobPosition + ((_arrowsPosition == NSScrollerArrowsNone)
+                               ? 0 : buttonsWidth); 
+              width = buttonsWidth ;
+            }
+
          height = knobHeight;
-         width = buttonsWidth;
          break;
        }
 
@@ -1073,10 +1105,18 @@
            break;
          }
        height -= buttonsSize;
-       if (_arrowsPosition == NSScrollerArrowsMinEnd)
+       if ( (interfaceStyle==NSNextStepInterfaceStyle || 
+              interfaceStyle==GSWindowMakerInterfaceStyle) 
+            && _arrowsPosition == NSScrollerArrowsMinEnd)
          {
            y += buttonsSize;
          }
+        else if (interfaceStyle!=NSNextStepInterfaceStyle &&
+            interfaceStyle!=GSWindowMakerInterfaceStyle)
+          {
+            y += buttonsWidth;
+            width = buttonsWidth;
+          }
        break;
 
       case NSScrollerDecrementLine:
@@ -1086,7 +1126,9 @@
          {
            return NSZeroRect;
          }
-       else if (_arrowsPosition == NSScrollerArrowsMaxEnd)
+       else if ((interfaceStyle==NSNextStepInterfaceStyle || 
+                  interfaceStyle==GSWindowMakerInterfaceStyle)
+              && _arrowsPosition == NSScrollerArrowsMaxEnd)
          {
            y += (height - buttonsSize + 1);
          }
@@ -1101,14 +1143,22 @@
          {
            return NSZeroRect;
          }
-       else if (_arrowsPosition == NSScrollerArrowsMaxEnd)
+        else if (interfaceStyle==NSNextStepInterfaceStyle 
+            || interfaceStyle==GSWindowMakerInterfaceStyle)
          {
-           y += (height - buttonsWidth);
+           if (_arrowsPosition == NSScrollerArrowsMaxEnd)
+             {
+                y += (height - buttonsWidth);
+             }
          }
        else if (_arrowsPosition == NSScrollerArrowsMinEnd)
          {
            y += (buttonsWidth + 1);
          }
+        else 
+          {
+            y += (height - buttonsWidth);
+          }
        height = buttonsWidth;
        width = buttonsWidth;
        break;
@@ -1130,7 +1180,7 @@
 + (float) scrollerWidthForControlSize: (NSControlSize)controlSize
 {
   // FIXME
-  return scrollerWidth;
+  return [self scrollerWidth];
 }
 
 - (void) setControlSize: (NSControlSize)controlSize
Index: Source/NSMenuView.m
===================================================================
--- Source/NSMenuView.m (revision 25290)
+++ Source/NSMenuView.m (working copy)
@@ -41,6 +41,7 @@
 #include "AppKit/NSImage.h"
 
 #include "GNUstepGUI/GSTitleView.h"
+#include "GNUstepGUI/GSTheme.h"
 
 #include <Foundation/Foundation.h>
 
@@ -1097,22 +1098,8 @@
 {
   int        i;
   int        howMany = [_itemCells count];
-  NSRectEdge sides[2]; 
-  float      grays[] = {NSDarkGray, NSDarkGray};
 
-  if (_horizontal == YES)
-    {
-      sides[0] = NSMinYEdge;
-      sides[1] = NSMinYEdge;
-      NSDrawTiledRects(_bounds, rect, sides, grays, 2);
-    }
-  else
-    {
-      sides[0] = NSMinXEdge;
-      sides[1] = NSMaxYEdge;
-      // Draw the dark gray upper left lines.
-      NSDrawTiledRects(_bounds, rect, sides, grays, 2);
-    }
+  [[GSTheme theme] drawMenuViewBackground:_bounds view:self]; 
   
   // Draw the menu cells.
   for (i = 0; i < howMany; i++)
Index: Headers/Additions/GNUstepGUI/GSTheme.h
===================================================================
--- Headers/Additions/GNUstepGUI/GSTheme.h      (revision 25290)
+++ Headers/Additions/GNUstepGUI/GSTheme.h      (working copy)
@@ -136,16 +136,22 @@
 #include <Foundation/NSObject.h>
 #include <Foundation/NSGeometry.h>
 // For gradient types
-#include "AppKit/NSButtonCell.h"
+#include <AppKit/NSButtonCell.h>
+#include <AppKit/NSScroller.h> 
 
 #if    OS_API_VERSION(GS_API_NONE,GS_API_NONE)
 @class NSArray;
 @class NSBundle;
+
 @class NSColor;
 @class NSDictionary;
 @class NSImage;
 @class GSDrawTiles;
 
address@hidden NSButton;
address@hidden NSMenuView;
address@hidden NSMenuItemCell;
+
 /**
  * This defines how the values in a tile array should be used when
  * drawing a rectangle.  Mostly this just effects the center, middle
@@ -190,7 +196,7 @@
   This is a class used for 'theming', which is mostly a matter of
   encapsulating common drawing behaviors so that GUI appearance can
   be easily modified, but also includes mechanisms for altering
-  some GUI behavior (such mas orientation and position of menus).
+  some GUI behavior (such mass orientation and position of menus).
   </p>
   <p>
   Methods in this class standardize drawing of buttons, borders
@@ -377,6 +383,11 @@
 @interface     GSTheme (Drawing)
 
 /**
+ * Customize a button cell for the specified button type
+ */
+- (void) customizeButtonCell: (NSButtonCell*)cell
+                   withType: (NSButtonType)type;
+/**
  * Draws a button frame and background (not its content) for the specified
  * cell and view.
  */
@@ -393,6 +404,14 @@
                           state: (GSThemeControlState)state;
 
 /** 
+ * The drawing frame for button content. Defaults to the amount inset by
+ * the button border.
+ */
+- (NSRect) buttonContentRect: (NSRect)frame
+                    forStyle: (int)style
+                       state: (GSThemeControlState)state;
+
+/** 
  * Draws the indicator (normally a dotted rectangle) to show that
  * the view currently has keyboard focus.
  */
@@ -404,6 +423,26 @@
  */
 - (void) drawWindowBackground: (NSRect)frame view: (NSView*)view;
 
+/**
+ * Draw the background for a menu view. This is normally a fill with the
+ * default window background colour and a standard button border. 
+ */
+- (void) drawMenuViewBackground: (NSRect)frame view: (NSMenuView*)view;
+
+/**
+ * Draw the border for a menu item. 
+ */
+- (void) drawMenuItemBorderAndBackground: (NSRect)frame 
+                        in: (NSMenuItemCell*)cell
+                      view: (NSView*)view  
+                     state: (GSThemeControlState)state;
+
+- (float) defaultScrollerWidth;
+
+- (NSButtonCell*) cellForScrollerArrow:(NSScrollerArrow)part 
horizontal:(BOOL)horizontal;
+- (NSCell*) cellForScrollerKnob:(BOOL)horizontal;
+- (NSCell*) cellForScrollerKnobSlot:(BOOL)horizontal;
+
 @end
 
 /**
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 25290)
+++ ChangeLog   (working copy)
@@ -1,3 +1,15 @@
+2007-06-25 10:16-AEST Christopher Armstrong <address@hidden>
+
+       * Source/NSButtonCell.m: Extended support for button cell theming to 
+       allow asymmetric interiors/button borders.
+       * Source/NSMenuItemCell.m: Added theming support for menu cells.
+       * Source/NSMenuView.m: Added theming support for menu view backgrounds.
+       * Source/NSScroller.m: Added theming support for scrollbars and added 
+       interface style support for NSWindows95InterfaceStyle.
+       * Headers/Additions/GNUstepGUI/GSTheme.h
+       * Source/GSTheme.m: Extended theme API to support menus, scrollbars and
+       integrated code for their normal drawing.
+       
 2007-06-23 10:43-EDT Gregory John Casamento <address@hidden>
 
        * Headers/AppKit/NSObjectController.h

reply via email to

[Prev in Thread] Current Thread [Next in Thread]