Bug 449442 - Change -moz-appearance: statusbar on Mac OS X to draw a dark chrome statusbar with a gradient. ui-r=faaborg r=josh sr=roc
authorMarkus Stange <mstange@themasta.com>
Tue, 06 Jan 2009 16:46:59 +0100
changeset 23367 e666dabedee5a7002c565e10914eb32890a842ab
parent 23366 1283369519f3d17b31d96680a99e2c87097da0fc
child 23368 c7538401b1c942584ea04613693fff0ca99f5122
push idunknown
push userunknown
push dateunknown
reviewersfaaborg, josh, roc
bugs449442
milestone1.9.2a1pre
Bug 449442 - Change -moz-appearance: statusbar on Mac OS X to draw a dark chrome statusbar with a gradient. ui-r=faaborg r=josh sr=roc
widget/src/cocoa/nsNativeThemeCocoa.h
widget/src/cocoa/nsNativeThemeCocoa.mm
widget/src/cocoa/nsNativeThemeColors.h
--- a/widget/src/cocoa/nsNativeThemeCocoa.h
+++ b/widget/src/cocoa/nsNativeThemeCocoa.h
@@ -123,16 +123,18 @@ protected:
                   ThemeButtonAdornment inAdornment, PRInt32 inState, nsIFrame* aFrame);
   void DrawSpinButtons(CGContextRef context, ThemeButtonKind inKind,
                        const HIRect& inBoxRect,
                        PRBool inDisabled, ThemeDrawState inDrawState,
                        ThemeButtonAdornment inAdornment, PRInt32 inState,
                        nsIFrame* aFrame);
   void DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inBoxRect,
                           nsIFrame *aFrame);
+  void DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
+                     nsIFrame *aFrame);
 
   // Scrollbars
   void DrawScrollbar(CGContextRef aCGContext, const HIRect& aBoxRect, nsIFrame *aFrame);
   void GetScrollbarPressStates (nsIFrame *aFrame, PRInt32 aButtonStates[]);
   void GetScrollbarDrawInfo (HIThemeTrackDrawInfo& aTdi, nsIFrame *aFrame, 
                              const HIRect& aRect, PRBool aShouldGetButtonStates);
   nsIFrame* GetParentScrollbarFrame(nsIFrame *aFrame);
 
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -1363,16 +1363,86 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(C
   [NativeGreyColorAsNSColor(headerBorderGrey, isMain) set];
   NSRectFill(NSMakeRect(inBoxRect.origin.x, inBoxRect.origin.y +
                         inBoxRect.size.height - 1.0f, inBoxRect.size.width, 1.0f));
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 
+struct GreyGradientInfo {
+  float startGrey;
+  float endGrey;
+};
+
+
+static void GreyGradientCallback(void* aInfo, const float* aIn, float* aOut)
+{
+  GreyGradientInfo* info = static_cast<GreyGradientInfo*>(aInfo);
+  float result = (1.0f - *aIn) * info->startGrey + *aIn * info->endGrey;
+  aOut[0] = result;
+  aOut[1] = result;
+  aOut[2] = result;
+  aOut[3] = 1.0f;
+}
+
+
+static void DrawGreyGradient(CGContextRef cgContext, const HIRect& rect,
+                             float startGrey, float endGrey)
+{
+  if (rect.size.height <= 0.0f)
+    return;
+
+  GreyGradientInfo info = { startGrey, endGrey };
+  struct CGFunctionCallbacks callbacks = { 0, GreyGradientCallback, NULL };
+  CGFunctionRef function = CGFunctionCreate(&info, 1,  NULL, 4, NULL, &callbacks);
+  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+  CGShadingRef shading = CGShadingCreateAxial(colorSpace,
+                                              CGPointMake(0, CGRectGetMinY(rect)),
+                                              CGPointMake(0, CGRectGetMaxY(rect)),
+                                              function, false, false);
+  CGColorSpaceRelease(colorSpace);
+  CGFunctionRelease(function);
+  CGContextSaveGState(cgContext);
+  CGContextClipToRect(cgContext, rect);
+  CGContextDrawShading(cgContext, shading);
+  CGContextRestoreGState(cgContext);
+  CGShadingRelease(shading);
+}
+
+
+void
+nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
+                                  nsIFrame *aFrame)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+  if (inBoxRect.size.height < 2.0f)
+    return;
+
+  BOOL isMain = [NativeWindowForFrame(aFrame) isMainWindow];
+
+  // Draw the borders at the top of the statusbar.
+  [NativeGreyColorAsNSColor(statusbarFirstTopBorderGrey, isMain) set];
+  NSRectFill(NSMakeRect(inBoxRect.origin.x, inBoxRect.origin.y,
+                        inBoxRect.size.width, 1.0f));
+  [NativeGreyColorAsNSColor(statusbarSecondTopBorderGrey, isMain) set];
+  NSRectFill(NSMakeRect(inBoxRect.origin.x, inBoxRect.origin.y + 1.0f,
+                        inBoxRect.size.width, 1.0f));
+
+  // Draw the gradient.
+  DrawGreyGradient(cgContext, CGRectMake(inBoxRect.origin.x, inBoxRect.origin.y + 2.0f,
+                                         inBoxRect.size.width, inBoxRect.size.height - 2.0f),
+                   NativeGreyColorAsFloat(statusbarGradientStartGrey, isMain),
+                   NativeGreyColorAsFloat(statusbarGradientEndGrey, isMain));
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
+
 NS_IMETHODIMP
 nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame* aFrame,
                                          PRUint8 aWidgetType, const nsRect& aRect,
                                          const nsRect& aDirtyRect)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   // setup to draw into the correct port
@@ -1557,23 +1627,26 @@ nsNativeThemeCocoa::DrawWidgetBackground
 
       // bottom border
       [NativeGreyColorAsNSColor(headerBorderGrey, isMain) set];
       NSRectFill(NSMakeRect(macRect.origin.x, macRect.origin.y +
                             macRect.size.height - 1.0f, macRect.size.width, 1.0f));
     }
       break;
 
-    case NS_THEME_TOOLBOX:
-    case NS_THEME_STATUSBAR: {
+    case NS_THEME_TOOLBOX: {
       HIThemeHeaderDrawInfo hdi = { 0, kThemeStateActive, kHIThemeHeaderKindWindow };
       HIThemeDrawHeader(&macRect, &hdi, cgContext, HITHEME_ORIENTATION);
     }
       break;
-      
+
+    case NS_THEME_STATUSBAR: 
+      DrawStatusBar(cgContext, macRect, aFrame);
+      break;
+
     case NS_THEME_DROPDOWN:
       DrawButton(cgContext, kThemePopupButton, macRect,
                  IsDefaultButton(aFrame), IsDisabled(aFrame), 
                  kThemeButtonOn, kThemeAdornmentNone, eventState, aFrame);
       break;
 
     case NS_THEME_DROPDOWN_BUTTON:
       DrawButton(cgContext, kThemeArrowButton, macRect, PR_FALSE,
@@ -1859,18 +1932,18 @@ nsNativeThemeCocoa::GetWidgetBorder(nsID
         if (isHorizontal)
           aResult->SizeTo(endcapSize, 0, 0, 0);
         else
           aResult->SizeTo(0, endcapSize, 0, 0);
       }
       break;
     }
 
-    case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
-      aResult->SizeTo(0, 0, 1, 0);
+    case NS_THEME_STATUSBAR:
+      aResult->SizeTo(0, 1, 0, 0);
       break;
   }
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
--- a/widget/src/cocoa/nsNativeThemeColors.h
+++ b/widget/src/cocoa/nsNativeThemeColors.h
@@ -39,26 +39,35 @@
 #define nsNativeThemeColors_h_
 
 #import <Cocoa/Cocoa.h>
 
 enum ColorName {
   headerStartGrey,
   headerEndGrey,
   headerBorderGrey,
-  toolbarTopBorderGrey
+  toolbarTopBorderGrey,
+  statusbarFirstTopBorderGrey,
+  statusbarSecondTopBorderGrey,
+  statusbarGradientStartGrey,
+  statusbarGradientEndGrey
 };
 
 static const int sLeopardThemeColors[][2] = {
   /* { active window, inactive window } */
-  // unified titlebar and toolbar gradient:
+  // titlebar and toolbar:
   { 0xC5, 0xE9 }, // start grey
   { 0x96, 0xCA }, // end grey
-  { 0x42, 0x89 }, // separator line
-  { 0xC0, 0xE2 }  // top separator line of a toolbar
+  { 0x42, 0x89 }, // bottom separator line
+  { 0xC0, 0xE2 }, // top separator line
+  // statusbar:
+  { 0x42, 0x86 }, // first top border
+  { 0xD8, 0xEE }, // second top border
+  { 0xBD, 0xE4 }, // gradient start
+  { 0x96, 0xCF }  // gradient end
 };
 
 
 static int NativeGreyColorAsInt(ColorName name, BOOL isMain)
 {
   return sLeopardThemeColors[name][isMain ? 0 : 1];
 }