diff --git a/toolkit/themes/pinstripe/global/menulist.css b/toolkit/themes/pinstripe/global/menulist.css index 12b90e06b97..3c28b2612fb 100644 --- a/toolkit/themes/pinstripe/global/menulist.css +++ b/toolkit/themes/pinstripe/global/menulist.css @@ -57,6 +57,7 @@ menulist { -moz-appearance: menulist-text; -moz-box-align: center; -moz-box-pack: center; + margin-bottom: 1px; } .menulist-label { diff --git a/widget/src/cocoa/nsNativeThemeCocoa.h b/widget/src/cocoa/nsNativeThemeCocoa.h index 63088e67b71..457402f853e 100644 --- a/widget/src/cocoa/nsNativeThemeCocoa.h +++ b/widget/src/cocoa/nsNativeThemeCocoa.h @@ -121,6 +121,8 @@ protected: const HIRect& inBoxRect, PRBool inIsDefault, PRBool inDisabled, ThemeButtonValue inValue, ThemeButtonAdornment inAdornment, PRInt32 inState, nsIFrame* aFrame); + void DrawDropdown(CGContextRef context, const HIRect& inBoxRect, PRInt32 inState, + nsIFrame* aFrame); void DrawSpinButtons(CGContextRef context, ThemeButtonKind inKind, const HIRect& inBoxRect, PRBool inDisabled, ThemeDrawState inDrawState, @@ -143,6 +145,7 @@ private: NSButtonCell* mRadioButtonCell; NSButtonCell* mCheckboxCell; NSSearchFieldCell* mSearchFieldCell; + NSPopUpButtonCell* mDropdownCell; }; #endif // nsNativeThemeCocoa_h_ diff --git a/widget/src/cocoa/nsNativeThemeCocoa.mm b/widget/src/cocoa/nsNativeThemeCocoa.mm index 218ba6c5331..b38f2ed4dcc 100644 --- a/widget/src/cocoa/nsNativeThemeCocoa.mm +++ b/widget/src/cocoa/nsNativeThemeCocoa.mm @@ -224,6 +224,8 @@ nsNativeThemeCocoa::nsNativeThemeCocoa() [mSearchFieldCell setEditable:YES]; [mSearchFieldCell setFocusRingType:NSFocusRingTypeExterior]; + mDropdownCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]; + NS_OBJC_END_TRY_ABORT_BLOCK; } @@ -235,6 +237,7 @@ nsNativeThemeCocoa::~nsNativeThemeCocoa() [mRadioButtonCell release]; [mCheckboxCell release]; [mSearchFieldCell release]; + [mDropdownCell release]; NS_OBJC_END_TRY_ABORT_BLOCK; } @@ -728,7 +731,7 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind, else { if (inKind == kThemeArrowButton) bdi.state = kThemeStateUnavailable; // these are always drawn as unavailable - else if (!isActive && (inKind == kThemeListHeaderButton || inKind == kThemePopupButton)) + else if (!isActive && inKind == kThemeListHeaderButton) bdi.state = kThemeStateInactive; else bdi.state = kThemeStateActive; @@ -744,8 +747,6 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind, } HIRect drawFrame = inBoxRect; - PRBool needsScaling = PR_FALSE; - int drawWidth = 0, drawHeight = 0; if (inKind == kThemePushButton) { drawFrame.size.height -= 2; @@ -759,49 +760,7 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind, drawFrame.size.width -= 2; } } - else if (inKind == kThemePopupButton) { - /* popup buttons draw outside their frame by 1 pixel on each side and - * two on the bottom but of the bottom two pixels one is a 'shadow' - * and not the frame itself. That extra pixel should be handled - * by GetWidgetOverflow, but we already extend each widget's overflow - * by 4px to handle a potential focus ring. - */ - - if (nsToolkit::OnLeopardOrLater()) { - /* Leopard will happily scale up for buttons that are sized 20px or higher, - * drawing 1px below the actual requested area. (So 20px == 21px.) - * but anything below that will be clamped: - * requested: 20 actual: 21 (handled above) - * requested: 19 actual: 18 <- note that there is no way to draw a dropdown that's exactly 20 px in size - * requested: 18 actual: 18 - * requested: 17 actual: 18 - * requested: 16 actual: 15 (min size) - * For those, draw to a buffer and scale - */ - if (drawFrame.size.height != 18 && drawFrame.size.height != 15) { - if (drawFrame.size.height > 20) { - drawFrame.size.width -= 2; - drawFrame.origin.x += 1; - drawFrame.size.height -= 1; - } - else { - // pick which native height to use for the small scale - float nativeHeight = 15.0f; - if (drawFrame.size.height > 16) - nativeHeight = 18.0f; - - drawWidth = (int) drawFrame.size.width; - drawHeight = (int) nativeHeight; - - needsScaling = PR_TRUE; - } - } - } - else { - // leave things alone on Tiger - drawFrame.size.height -= 1; - } - } else if (inKind == kThemeListHeaderButton) { + else if (inKind == kThemeListHeaderButton) { CGContextClipToRect(cgContext, inBoxRect); // Always remove the top border. drawFrame.origin.y -= 1; @@ -815,49 +774,7 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind, drawFrame.origin.x -= 1; } - // Fall back to no bitmap buffer (and no scaling) if the area of our button - // (in pixels^2) is too large. - if (!needsScaling || (drawWidth * drawHeight > BITMAP_MAX_AREA)) { - HIThemeDrawButton(&drawFrame, &bdi, cgContext, kHIThemeOrientationNormal, NULL); - } else { - int w = drawWidth + MAX_FOCUS_RING_WIDTH*2; - int h = drawHeight + MAX_FOCUS_RING_WIDTH*2; - - CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); - CGContextRef ctx = CGBitmapContextCreate(NULL, w, h, 8, w * 4, - rgb, kCGImageAlphaPremultipliedFirst); - CGColorSpaceRelease(rgb); - - // Flip the context - CGContextTranslateCTM(ctx, 0.0f, h); - CGContextScaleCTM(ctx, 1.0f, -1.0f); - - // then draw the button (offset by the focus ring size - CGRect tmpFrame = CGRectMake(MAX_FOCUS_RING_WIDTH, MAX_FOCUS_RING_WIDTH, drawWidth, drawHeight); - HIThemeDrawButton(&tmpFrame, &bdi, ctx, kHIThemeOrientationNormal, NULL); - - CGImageRef img = CGBitmapContextCreateImage(ctx); - CGRect imgRect = CGRectMake(drawFrame.origin.x - MAX_FOCUS_RING_WIDTH, - drawFrame.origin.y - MAX_FOCUS_RING_WIDTH, - drawFrame.size.width + MAX_FOCUS_RING_WIDTH * 2.0, - drawFrame.size.height + MAX_FOCUS_RING_WIDTH * 2.0); - - // And then flip the main context here so that the image gets drawn right-side up - CGAffineTransform ctm = CGContextGetCTM (cgContext); - - CGContextTranslateCTM (cgContext, imgRect.origin.x, imgRect.origin.y + imgRect.size.height); - CGContextScaleCTM (cgContext, 1.0, -1.0); - - imgRect.origin.x = imgRect.origin.y = 0.0f; - - // See comment about why we don't scale MAX_FOCUS_RING in DrawCellWithScaling - CGContextDrawImage(cgContext, imgRect, img); - - CGContextSetCTM (cgContext, ctm); - - CGImageRelease(img); - CGContextRelease(ctx); - } + HIThemeDrawButton(&drawFrame, &bdi, cgContext, kHIThemeOrientationNormal, NULL); #if DRAW_IN_FRAME_DEBUG CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.25); @@ -868,6 +785,50 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind, } +static const CellRenderSettings dropdownSettings = { + { + NSMakeSize(0, 16), // mini + NSMakeSize(0, 19), // small + NSMakeSize(0, 22) // regular + }, + { + NSMakeSize(18, 0), // mini + NSMakeSize(38, 0), // small + NSMakeSize(44, 0) // regular + }, + { + { // Tiger + {1, 1, 2, 1}, // mini + {3, 0, 3, 1}, // small + {3, 0, 3, 0} // regular + }, + { // Leopard + {1, 1, 2, 1}, // mini + {3, 0, 3, 1}, // small + {3, 0, 3, 0} // regular + } + } +}; + + +void +nsNativeThemeCocoa::DrawDropdown(CGContextRef cgContext, const HIRect& inBoxRect, + PRInt32 inState, nsIFrame* aFrame) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK; + + [mDropdownCell setEnabled:!IsDisabled(aFrame)]; + [mDropdownCell setShowsFirstResponder:(inState & NS_EVENT_STATE_FOCUS)]; + [mDropdownCell setHighlighted:((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))]; + [mDropdownCell setControlTint:(FrameIsInActiveWindow(aFrame) ? [NSColor currentControlTint] : NSClearControlTint)]; + + DrawCellWithSnapping(mDropdownCell, cgContext, inBoxRect, dropdownSettings, + 0.5f, NativeViewForFrame(aFrame)); + + NS_OBJC_END_TRY_ABORT_BLOCK; +} + + void nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKind, const HIRect& inBoxRect, PRBool inDisabled, @@ -1652,9 +1613,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame break; case NS_THEME_DROPDOWN: - DrawButton(cgContext, kThemePopupButton, macRect, - IsDefaultButton(aFrame), IsDisabled(aFrame), - kThemeButtonOn, kThemeAdornmentNone, eventState, aFrame); + DrawDropdown(cgContext, macRect, eventState, aFrame); break; case NS_THEME_DROPDOWN_BUTTON: @@ -1888,7 +1847,7 @@ nsNativeThemeCocoa::GetWidgetBorder(nsIDeviceContext* aContext, case NS_THEME_DROPDOWN: case NS_THEME_DROPDOWN_BUTTON: - aResult->SizeTo(kAquaDropdownLeftBorder, 2, kAquaDropdownRightBorder, 2); + aResult->SizeTo(kAquaDropdownLeftBorder, 1, kAquaDropdownRightBorder, 2); break; case NS_THEME_TEXTFIELD: