зеркало из https://github.com/mozilla/pjs.git
Bug 656909 - Use a native rendering for vertical progress bar on Windows. r=jimm
This commit is contained in:
Родитель
acb390760f
Коммит
0b8057d177
|
@ -349,10 +349,14 @@ static CaptionButtonPadding buttonData[3] = {
|
|||
* These values are found by experimenting and comparing against native widgets
|
||||
* used by the system. They are very unlikely exact but try to not be too wrong.
|
||||
*/
|
||||
// The width of the overlay used to animate the progress bar (Vista and later).
|
||||
static const PRInt32 kProgressVistaOverlayWidth = 120;
|
||||
// The width of the overlay used to for indeterminate progress bars on XP.
|
||||
static const PRInt32 kProgressXPOverlayWidth = 55;
|
||||
// The width of the overlay used to animate the horizontal progress bar (Vista and later).
|
||||
static const PRInt32 kProgressHorizontalVistaOverlaySize = 120;
|
||||
// The width of the overlay used for the horizontal indeterminate progress bars on XP.
|
||||
static const PRInt32 kProgressHorizontalXPOverlaySize = 55;
|
||||
// The height of the overlay used to animate the vertical progress bar (Vista and later).
|
||||
static const PRInt32 kProgressVerticalOverlaySize = 45;
|
||||
// The height of the overlay used for the vertical indeterminate progress bar (Vista and later).
|
||||
static const PRInt32 kProgressVerticalIndeterminateOverlaySize = 60;
|
||||
// Speed (px per ms) of the animation for determined Vista and later progress bars.
|
||||
static const double kProgressDeterminedVistaSpeed = 0.225;
|
||||
// Speed (px per ms) of the animation for indeterminate progress bars.
|
||||
|
@ -672,17 +676,24 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
|||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_PROGRESSBAR: {
|
||||
aPart = PP_BAR;
|
||||
aPart = IsVerticalProgress(aFrame) ? PP_BARVERT : PP_BAR;
|
||||
aState = TS_NORMAL;
|
||||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_PROGRESSBAR_CHUNK: {
|
||||
nsIFrame* stateFrame = aFrame->GetParent();
|
||||
nsEventStates eventStates = GetContentState(stateFrame, aWidgetType);
|
||||
// If the element is indeterminate, we are going to render it ourself so
|
||||
// we have to return aPart = -1.
|
||||
aPart = IsIndeterminateProgress(stateFrame, eventStates)
|
||||
? -1 : nsUXThemeData::sIsVistaOrLater ? PP_FILL : PP_CHUNK;
|
||||
|
||||
if (IsIndeterminateProgress(stateFrame, eventStates)) {
|
||||
// If the element is indeterminate, we are going to render it ourself so
|
||||
// we have to return aPart = -1.
|
||||
aPart = -1;
|
||||
} else if (IsVerticalProgress(stateFrame)) {
|
||||
aPart = nsUXThemeData::sIsVistaOrLater ? PP_FILLVERT : PP_CHUNKVERT;
|
||||
} else {
|
||||
aPart = nsUXThemeData::sIsVistaOrLater ? PP_FILL : PP_CHUNK;
|
||||
}
|
||||
|
||||
aState = TS_NORMAL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1567,43 +1578,75 @@ RENDER_AGAIN:
|
|||
nsIFrame* stateFrame = aFrame->GetParent();
|
||||
nsEventStates eventStates = GetContentState(stateFrame, aWidgetType);
|
||||
bool indeterminate = IsIndeterminateProgress(stateFrame, eventStates);
|
||||
bool vertical = IsVerticalProgress(stateFrame);
|
||||
|
||||
if (indeterminate || nsUXThemeData::sIsVistaOrLater) {
|
||||
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 60)) {
|
||||
NS_WARNING("unable to animate progress widget!");
|
||||
}
|
||||
|
||||
const PRInt32 overlayWidth = nsUXThemeData::sIsVistaOrLater
|
||||
? kProgressVistaOverlayWidth
|
||||
: kProgressXPOverlayWidth;
|
||||
/**
|
||||
* Unfortunately, vertical progress bar support on Windows seems weak and
|
||||
* PP_MOVEOVERLAYRECT looks really different from PP_MOVEOVERLAY.
|
||||
* Thus, we have to change the size and even don't use it for vertical
|
||||
* indeterminate progress bars.
|
||||
*/
|
||||
PRInt32 overlaySize;
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
if (vertical) {
|
||||
overlaySize = indeterminate ? kProgressVerticalIndeterminateOverlaySize
|
||||
: kProgressVerticalOverlaySize;
|
||||
} else {
|
||||
overlaySize = kProgressHorizontalVistaOverlaySize;
|
||||
}
|
||||
} else {
|
||||
overlaySize = kProgressHorizontalXPOverlaySize;
|
||||
}
|
||||
|
||||
const double pixelsPerMillisecond = indeterminate
|
||||
? kProgressIndeterminateSpeed
|
||||
: kProgressDeterminedVistaSpeed;
|
||||
const PRInt32 delay = indeterminate ? kProgressIndeterminateDelay
|
||||
: kProgressDeterminedVistaDelay;
|
||||
|
||||
const PRInt32 frameWidth = widgetRect.right - widgetRect.left;
|
||||
const PRInt32 animationWidth = frameWidth + overlayWidth +
|
||||
const PRInt32 frameSize = vertical ? widgetRect.bottom - widgetRect.top
|
||||
: widgetRect.right - widgetRect.left;
|
||||
const PRInt32 animationSize = frameSize + overlaySize +
|
||||
static_cast<PRInt32>(pixelsPerMillisecond * delay);
|
||||
const double interval = animationWidth / pixelsPerMillisecond;
|
||||
const double interval = animationSize / pixelsPerMillisecond;
|
||||
// We have to pass a double* to modf and we can't pass NULL.
|
||||
double tempValue;
|
||||
double ratio = modf(PR_IntervalToMilliseconds(PR_IntervalNow())/interval,
|
||||
&tempValue);
|
||||
// If the frame direction is RTL, we want to have the animation going RTL.
|
||||
// ratio is in [0.0; 1.0[ range, inverting it reverse the animation.
|
||||
if (IsFrameRTL(aFrame)) {
|
||||
if (!vertical && IsFrameRTL(aFrame)) {
|
||||
ratio = 1.0 - ratio;
|
||||
}
|
||||
PRInt32 dx = static_cast<PRInt32>(animationWidth * ratio) - overlayWidth;
|
||||
PRInt32 dx = static_cast<PRInt32>(animationSize * ratio) - overlaySize;
|
||||
|
||||
RECT overlayRect = widgetRect;
|
||||
overlayRect.left += dx;
|
||||
overlayRect.right = overlayRect.left + overlayWidth;
|
||||
nsUXThemeData::drawThemeBG(theme, hdc,
|
||||
nsUXThemeData::sIsVistaOrLater ? PP_MOVEOVERLAY
|
||||
: PP_CHUNK,
|
||||
state, &overlayRect, &clipRect);
|
||||
if (vertical) {
|
||||
overlayRect.bottom -= dx;
|
||||
overlayRect.top = overlayRect.bottom - overlaySize;
|
||||
} else {
|
||||
overlayRect.left += dx;
|
||||
overlayRect.right = overlayRect.left + overlaySize;
|
||||
}
|
||||
|
||||
PRInt32 overlayPart;
|
||||
if (vertical) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
overlayPart = indeterminate ? PP_MOVEOVERLAY : PP_MOVEOVERLAYVERT;
|
||||
} else {
|
||||
overlayPart = PP_CHUNKVERT;
|
||||
}
|
||||
} else {
|
||||
overlayPart = nsUXThemeData::sIsVistaOrLater ? PP_MOVEOVERLAY : PP_CHUNK;
|
||||
}
|
||||
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, overlayPart, state, &overlayRect,
|
||||
&clipRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,9 @@
|
|||
#define PP_CHUNK 3
|
||||
#define PP_CHUNKVERT 4
|
||||
#define PP_FILL 5
|
||||
#define PP_FILLVERT 6
|
||||
#define PP_MOVEOVERLAY 8
|
||||
#define PP_MOVEOVERLAYVERT 9
|
||||
|
||||
// Tab constants
|
||||
#define TABP_TAB 4
|
||||
|
|
|
@ -472,6 +472,13 @@ nsNativeTheme::IsIndeterminateProgress(nsIFrame* aFrame,
|
|||
eCaseMatters);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNativeTheme::IsVerticalProgress(nsIFrame* aFrame)
|
||||
{
|
||||
return aFrame &&
|
||||
aFrame->GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
|
||||
}
|
||||
|
||||
// menupopup:
|
||||
PRBool
|
||||
nsNativeTheme::IsSubmenu(nsIFrame* aFrame, PRBool* aLeftOfParent)
|
||||
|
|
|
@ -161,6 +161,7 @@ class nsNativeTheme : public nsITimerCallback
|
|||
|
||||
// progressbar:
|
||||
PRBool IsIndeterminateProgress(nsIFrame* aFrame, nsEventStates aEventStates);
|
||||
PRBool IsVerticalProgress(nsIFrame* aFrame);
|
||||
|
||||
// textfield:
|
||||
PRBool IsReadOnly(nsIFrame* aFrame) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче