зеркало из https://github.com/mozilla/gecko-dev.git
[re-landing] allow buttons to render at smaller sizes than Mac OS X itself will draw using HITheme. Also fixes 376695, allow buttons to accept padding. b=379297 r=cbarrett r=mano sr=pinkerton
This commit is contained in:
Родитель
eb14eb6945
Коммит
a9dddfe17f
|
@ -1121,7 +1121,8 @@ sidebarheader > .tabs-closebutton > .toolbarbutton-text {
|
|||
#feed-button {
|
||||
-moz-binding: url("chrome://global/content/bindings/button.xml#menu");
|
||||
-moz-appearance: none;
|
||||
min-width: 0px;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
margin-right: 1px !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ button {
|
|||
/* The margin used here come from the Aqua Human Interface Guidelines,
|
||||
there should be 12 pixels between two buttons. */
|
||||
margin: 6px;
|
||||
min-width: 79px;
|
||||
min-height: 22px;
|
||||
color: ButtonText;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=371080
|
|||
width="5"
|
||||
id="button1"
|
||||
height="5"/>
|
||||
<!-- This Mac OS X native button should be 68 pixels wide from
|
||||
the dark border line on the left to the dark border line on
|
||||
the right. It should be 18 pixels tall from the dark border
|
||||
line on the top to the dark border line on the bottom -->
|
||||
<button class="smallbutton"
|
||||
style="-moz-appearance: button-small;"
|
||||
label="OK"
|
||||
width="5"
|
||||
id="button2"
|
||||
height="5"/>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
@ -50,10 +40,8 @@ function checkButtonDimensions() {
|
|||
dump("TEST DEBUG: function 'is()' defined as: " + is + "\n");
|
||||
|
||||
try {
|
||||
is($("button1").boxObject.width, 68, "mac button has correct width");
|
||||
is($("button1").boxObject.height, 22, "mac button has correct height");
|
||||
is($("button2").boxObject.width, 68, "mac small button has correct width");
|
||||
is($("button2").boxObject.height, 19, "mac small button has correct height");
|
||||
is($("button1").boxObject.width, 79, "mac button width");
|
||||
is($("button1").boxObject.height, 22, "mac button height");
|
||||
} catch (ex) {
|
||||
dump("TEST DEBUG: " + ex + "\n");
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
#include "gfxContext.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#define DRAW_IN_FRAME_DEBUG 0
|
||||
#define SCROLLBARS_VISUAL_DEBUG 0
|
||||
|
||||
|
@ -111,6 +113,14 @@ nsNativeThemeCocoa::DrawCheckboxRadio(CGContextRef cgContext, ThemeButtonKind in
|
|||
HIThemeDrawButton(&inBoxRect, &bdi, cgContext, HITHEME_ORIENTATION, NULL);
|
||||
}
|
||||
|
||||
// We use an offscreen buffer and image scaling to make HITheme draw buttons at any height.
|
||||
// Minimum height that HITheme will draw a normal push button:
|
||||
#define MIN_UNSCALED_BUTTON_HEIGHT 22
|
||||
// Minimum size for buttons that we can create with scaling:
|
||||
#define MIN_SCALED_BUTTON_WIDTH 28
|
||||
#define MIN_SCALED_BUTTON_HEIGHT 12
|
||||
// Difference between the height given to HITheme for a button and the button it actually draws:
|
||||
#define NATIVE_BUTTON_HEIGHT_DIFF 2
|
||||
|
||||
void
|
||||
nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind,
|
||||
|
@ -118,13 +128,16 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind,
|
|||
ThemeButtonValue inValue, ThemeButtonAdornment inAdornment,
|
||||
PRInt32 inState)
|
||||
{
|
||||
HIThemeButtonDrawInfo bdi;
|
||||
if (inBoxRect.size.width < MIN_SCALED_BUTTON_WIDTH ||
|
||||
inBoxRect.size.height < MIN_SCALED_BUTTON_HEIGHT)
|
||||
return;
|
||||
|
||||
HIThemeButtonDrawInfo bdi;
|
||||
bdi.version = 0;
|
||||
bdi.kind = inKind;
|
||||
bdi.value = inValue;
|
||||
bdi.adornment = inAdornment;
|
||||
|
||||
|
||||
if (inDisabled)
|
||||
bdi.state = kThemeStateUnavailable;
|
||||
else if ((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))
|
||||
|
@ -138,27 +151,58 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind,
|
|||
if (inIsDefault && !inDisabled)
|
||||
bdi.adornment |= kThemeAdornmentDefault;
|
||||
|
||||
// Certain buttons draw outside their frame with nsITheme, we adjust for that here.
|
||||
HIRect drawRect = inBoxRect;
|
||||
if (inKind == kThemePushButton ||
|
||||
inKind == kThemePopupButton) {
|
||||
// These kinds of buttons draw 2 pixels too tall.
|
||||
drawRect.size.height -= 2;
|
||||
// If any of the origin and size offset arithmatic seems strange here, check out the
|
||||
// actual dimensions of an HITheme button compared to the rect you pass to HIThemeDrawButton.
|
||||
if (inBoxRect.size.height < MIN_UNSCALED_BUTTON_HEIGHT) {
|
||||
// We'll use these two values to size the button we draw offscreen
|
||||
float offscreenWidth = inBoxRect.size.width;
|
||||
float offscreenHeight = MIN_UNSCALED_BUTTON_HEIGHT;
|
||||
if (inBoxRect.size.height > offscreenHeight)
|
||||
offscreenHeight = inBoxRect.size.height;
|
||||
|
||||
// create an offscreen image
|
||||
NSImage* image = [[NSImage alloc] initWithSize:NSMakeSize(offscreenWidth, offscreenHeight)];
|
||||
[image setDataRetained:YES];
|
||||
[image setScalesWhenResized:YES];
|
||||
|
||||
// set up HITheme button to draw
|
||||
HIRect drawFrame;
|
||||
drawFrame.origin.x = 0;
|
||||
drawFrame.origin.y = NATIVE_BUTTON_HEIGHT_DIFF;
|
||||
drawFrame.size.width = offscreenWidth;
|
||||
drawFrame.size.height = offscreenHeight - NATIVE_BUTTON_HEIGHT_DIFF;
|
||||
|
||||
// draw into offscreen image
|
||||
[image lockFocus];
|
||||
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationLow];
|
||||
HIThemeDrawButton(&drawFrame, &bdi, (CGContext*)[[NSGraphicsContext currentContext] graphicsPort], kHIThemeOrientationInverted, NULL);
|
||||
[image unlockFocus];
|
||||
|
||||
// resize vertically
|
||||
[image setSize:NSMakeSize(offscreenWidth, inBoxRect.size.height)];
|
||||
|
||||
// render to the given CGContextRef
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]];
|
||||
[image compositeToPoint:NSMakePoint(inBoxRect.origin.x, inBoxRect.origin.y + inBoxRect.size.height)
|
||||
operation:NSCompositeSourceOver];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
[image release];
|
||||
}
|
||||
else if (inKind == kThemePushButtonSmall) {
|
||||
// These kinds of buttons draw 2 pixels too wide, one pixel too far down, and
|
||||
// two pixels too tall.
|
||||
drawRect.origin.x += 1;
|
||||
drawRect.origin.y -= 1;
|
||||
drawRect.size.width -= 2;
|
||||
else {
|
||||
HIRect drawFrame;
|
||||
drawFrame.origin.x = inBoxRect.origin.x;
|
||||
drawFrame.origin.y = inBoxRect.origin.y;
|
||||
drawFrame.size.width = inBoxRect.size.width;
|
||||
drawFrame.size.height = inBoxRect.size.height - NATIVE_BUTTON_HEIGHT_DIFF;
|
||||
|
||||
HIThemeDrawButton(&drawFrame, &bdi, cgContext, kHIThemeOrientationNormal, NULL);
|
||||
}
|
||||
|
||||
#if DRAW_IN_FRAME_DEBUG
|
||||
CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.8);
|
||||
CGContextFillRect(cgContext, inBoxRect);
|
||||
#endif
|
||||
|
||||
HIThemeDrawButton(&drawRect, &bdi, cgContext, HITHEME_ORIENTATION, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -594,17 +638,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame
|
|||
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_BUTTON_SMALL: {
|
||||
// Normal push buttons can only draw with a height of 20+ pixels. Small push
|
||||
// buttons can only draw at a height of 17 pixels. We can't draw buttons with
|
||||
// a height of 18 or 19 pixels, at least not with HITheme. So, we go down to
|
||||
// 17 pixel buttons when asked to draw 18 or 19 so that we don't draw outside
|
||||
// the frame. We just have to live with this until we switch to another API
|
||||
// for control rendering. Remember that the frame for a 20 pixel tall button
|
||||
// is 22 pixels because of the border and shadow.
|
||||
ThemeButtonKind buttonKind = kThemePushButton;
|
||||
if (macRect.size.height < 22)
|
||||
buttonKind = kThemePushButtonSmall;
|
||||
DrawButton(cgContext, buttonKind, macRect,
|
||||
DrawButton(cgContext, kThemePushButton, macRect,
|
||||
IsDefaultButton(aFrame), IsDisabled(aFrame),
|
||||
kThemeButtonOn, kThemeAdornmentNone, eventState);
|
||||
}
|
||||
|
@ -887,20 +921,6 @@ nsNativeThemeCocoa::GetWidgetPadding(nsIDeviceContext* aContext,
|
|||
aResult->SizeTo(nativePadding, nativePadding, nativePadding, nativePadding);
|
||||
return PR_TRUE;
|
||||
}
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_DROPDOWN:
|
||||
case NS_THEME_DROPDOWN_BUTTON:
|
||||
{
|
||||
// The border/shadow on the bottom of the button means we have to
|
||||
// draw the text a little higher than normal.
|
||||
aResult->SizeTo(0, -1, 0, 1);
|
||||
return PR_TRUE;
|
||||
}
|
||||
case NS_THEME_BUTTON_SMALL:
|
||||
{
|
||||
aResult->SizeTo(0, 0, 0, 0);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
|
@ -954,20 +974,9 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
|||
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON:
|
||||
{
|
||||
// Height value is adjusted for shadow and border.
|
||||
SInt32 buttonHeight = 0;
|
||||
::GetThemeMetric(kThemeMetricPushButtonHeight, &buttonHeight);
|
||||
aResult->SizeTo(kAquaMinButtonWidth, buttonHeight + 2);
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_THEME_BUTTON_SMALL:
|
||||
{
|
||||
// Height value is adjusted for shadow and border.
|
||||
SInt32 buttonHeight = 0;
|
||||
::GetThemeMetric(kThemeMetricSmallPushButtonHeight, &buttonHeight);
|
||||
aResult->SizeTo(kAquaMinButtonWidth, buttonHeight + 2);
|
||||
aResult->SizeTo(MIN_SCALED_BUTTON_WIDTH, MIN_SCALED_BUTTON_HEIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче