Bug 206636 - Throbbing default buttons, r=josh r=Enn sr=roc

This commit is contained in:
Markus Stange 2009-01-18 12:05:38 +01:00
parent 2c2f89b2c3
commit 10fc7c3b4e
4 changed files with 67 additions and 10 deletions

View File

@ -208,7 +208,7 @@
<content>
<children includes="observes|template|menupopup|tooltip"/>
<xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
align="center" pack="center" flex="1">
align="center" pack="center" flex="1" anonid="button-box">
<children>
<xul:image class="button-icon" xbl:inherits="src=image"/>
<xul:label class="button-text" xbl:inherits="value=label,accesskey,crop"/>
@ -217,6 +217,37 @@
</content>
</binding>
<binding id="button-periodic-redraw"
extends="chrome://global/content/bindings/button.xml#button">
<implementation>
<field name="_alive">true</field>
<method name="_init">
<body><![CDATA[
var step = 0;
var self = this;
var hbox = document.getAnonymousElementByAttribute(this, "anonid", "button-box");
var interval = setInterval(function nextStep() {
try {
// Only bother redrawing when we're visible
if (!hbox.getBoundingClientRect().width) {
// Maybe we've been removed from the document.
if (!self._alive)
clearInterval(interval);
return;
}
// Trigger redraw by changing the step attribute
step = 1 - step;
self.setAttribute('step', step);
} catch (e) {
clearInterval(interval);
}
}, 100);
]]></body>
</method>
<constructor>this._init();</constructor>
</implementation>
</binding>
<binding id="menu" display="xul:menu"
extends="chrome://global/content/bindings/button.xml#button">
<content>

View File

@ -112,6 +112,12 @@ button {
-moz-binding: url("chrome://global/content/bindings/button.xml#button");
}
%ifdef XP_MACOSX
button[default="true"] {
-moz-binding: url("chrome://global/content/bindings/button.xml#button-periodic-redraw");
}
%endif
button[type="repeat"] {
-moz-binding: url("chrome://global/content/bindings/button.xml#button-repeat");
}

View File

@ -115,7 +115,7 @@ protected:
const HIRect& inBoxRect, PRBool inSelected,
PRBool inDisabled, PRInt32 inState, nsIFrame* aFrame);
void DrawSearchField(CGContextRef cgContext, const HIRect& inBoxRect, nsIFrame* aFrame);
void DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect, PRBool inIsDefault,
void DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect,
PRBool inDisabled, PRInt32 inState, nsIFrame* aFrame);
void DrawButton(CGContextRef context, ThemeButtonKind inKind,
const HIRect& inBoxRect, PRBool inIsDefault,

View File

@ -662,7 +662,7 @@ static const CellRenderSettings pushButtonSettings = {
#define DO_SQUARE_BUTTON_HEIGHT 26
void
nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect, PRBool inIsDefault,
nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect,
PRBool inDisabled, PRInt32 inState, nsIFrame* aFrame)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@ -670,9 +670,8 @@ nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRe
BOOL isActive = FrameIsInActiveWindow(aFrame);
[mPushButtonCell setEnabled:!inDisabled];
[mPushButtonCell setHighlighted:(((inState & NS_EVENT_STATE_ACTIVE) &&
(inState & NS_EVENT_STATE_HOVER) ||
(inIsDefault && !inDisabled)) &&
[mPushButtonCell setHighlighted:((inState & NS_EVENT_STATE_ACTIVE) &&
(inState & NS_EVENT_STATE_HOVER) &&
isActive)];
[mPushButtonCell setShowsFirstResponder:(inState & NS_EVENT_STATE_FOCUS) && !inDisabled && isActive];
@ -732,14 +731,29 @@ nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind,
if (inState & NS_EVENT_STATE_FOCUS && isActive)
bdi.adornment |= kThemeAdornmentFocus;
if (inIsDefault && !inDisabled)
if (inIsDefault && !inDisabled && isActive && !(inState & NS_EVENT_STATE_ACTIVE)) {
bdi.adornment |= kThemeAdornmentDefault;
bdi.animation.time.start = 0;
bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
}
HIRect drawFrame = inBoxRect;
PRBool needsScaling = PR_FALSE;
int drawWidth = 0, drawHeight = 0;
if (inKind == kThemePopupButton) {
if (inKind == kThemePushButton) {
drawFrame.size.height -= 2;
if (inBoxRect.size.height < pushButtonSettings.naturalSizes[smallControlSize].height) {
bdi.kind = kThemePushButtonMini;
}
else if (inBoxRect.size.height < pushButtonSettings.naturalSizes[regularControlSize].height) {
bdi.kind = kThemePushButtonSmall;
drawFrame.origin.y -= 1;
drawFrame.origin.x += 1;
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
@ -1554,7 +1568,12 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame
break;
case NS_THEME_BUTTON:
DrawPushButton(cgContext, macRect, IsDefaultButton(aFrame), IsDisabled(aFrame), eventState, aFrame);
if (IsDefaultButton(aFrame)) {
DrawButton(cgContext, kThemePushButton, macRect, true, IsDisabled(aFrame),
kThemeButtonOff, kThemeAdornmentNone, eventState, aFrame);
} else {
DrawPushButton(cgContext, macRect, IsDisabled(aFrame), eventState, aFrame);
}
break;
case NS_THEME_BUTTON_BEVEL:
@ -2247,7 +2266,8 @@ nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
aAttribute == nsWidgetAtoms::mozmenuactive ||
aAttribute == nsWidgetAtoms::sortdirection ||
aAttribute == nsWidgetAtoms::focused ||
aAttribute == nsWidgetAtoms::_default)
aAttribute == nsWidgetAtoms::_default ||
aAttribute == nsWidgetAtoms::step)
*aShouldRepaint = PR_TRUE;
}