Back out bug 373266 because of mochitest leaks

This commit is contained in:
Matt Brubeck 2012-03-07 17:15:57 -08:00
Родитель c4a5aa9dfa
Коммит a59d84c91f
14 изменённых файлов: 63 добавлений и 1214 удалений

Просмотреть файл

@ -68,12 +68,7 @@ function executeTests() {
button.getBoundingClientRect(); // Flush.
gNeedsPaint = true;
}
// On Vista+ we now support state transitions on themed
// content, so give the button time to normalize.
if (navigator.appVersion.indexOf("Win") != -1)
setTimeout(execNext, 500);
else
SimpleTest.executeSoon(execNext);
SimpleTest.executeSoon(execNext);
} catch (e) {}
}
execNext();

Просмотреть файл

@ -232,39 +232,6 @@ gfxWindowsNativeDrawing::IsDoublePass()
return false;
}
bool
gfxWindowsNativeDrawing::IsSecondPass()
{
return (mRenderState == RENDER_STATE_ALPHA_RECOVERY_WHITE ||
mRenderState == RENDER_STATE_ALPHA_RECOVERY_WHITE_DONE);
}
gfxWindowsSurface*
gfxWindowsNativeDrawing::GetCurrentSurface()
{
switch (mRenderState) {
case RENDER_STATE_NATIVE_DRAWING:
case RENDER_STATE_ALPHA_RECOVERY_WHITE:
case RENDER_STATE_ALPHA_RECOVERY_BLACK:
return mWinSurface;
case RENDER_STATE_NATIVE_DRAWING_DONE:
case RENDER_STATE_ALPHA_RECOVERY_BLACK_DONE:
case RENDER_STATE_ALPHA_RECOVERY_WHITE_DONE:
case RENDER_STATE_DONE:
NS_WARNING("GetCurrentSurface() called after "
"rendering operation complete. Returning nsnull.");
return nsnull;
default:
NS_ERROR("Invalid RenderState in"
"gfxWindowsNativeDrawing::GetCurrentSurface");
break;
}
return nsnull;
}
bool
gfxWindowsNativeDrawing::ShouldRenderAgain()
{
@ -284,7 +251,7 @@ gfxWindowsNativeDrawing::ShouldRenderAgain()
break;
}
return nsnull;
return false;
}
void

Просмотреть файл

@ -114,13 +114,6 @@ public:
/* Returns true if double pass alpha extraction is taking place. */
bool IsDoublePass();
/* Returns true if double pass alpha extraction is taking place
* and this is the second pass in the operation. */
bool IsSecondPass();
/* Returns the current surface in use for rendering. */
gfxWindowsSurface* GetCurrentSurface();
/* Places the result to the context, if necessary */
void PaintToContext();

Просмотреть файл

@ -67,7 +67,8 @@
#include "gfxPlatformGtk.h"
#include "gfxGdkNativeRenderer.h"
NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeGTK, nsNativeTheme, nsITheme)
NS_IMPL_ISUPPORTS_INHERITED2(nsNativeThemeGTK, nsNativeTheme, nsITheme,
nsIObserver)
static int gLastGdkError;
@ -81,7 +82,7 @@ nsNativeThemeGTK::nsNativeThemeGTK()
// We have to call moz_gtk_shutdown before the event loop stops running.
nsCOMPtr<nsIObserverService> obsServ =
mozilla::services::GetObserverService();
obsServ->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
obsServ->AddObserver(this, "xpcom-shutdown", false);
memset(mDisabledWidgetTypes, 0, sizeof(mDisabledWidgetTypes));
memset(mSafeWidgetStates, 0, sizeof(mSafeWidgetStates));
@ -94,10 +95,14 @@ NS_IMETHODIMP
nsNativeThemeGTK::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData)
{
if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
if (!nsCRT::strcmp(aTopic, "xpcom-shutdown")) {
moz_gtk_shutdown();
} else {
NS_NOTREACHED("unexpected topic");
return NS_ERROR_UNEXPECTED;
}
return nsNativeTheme::Observe(aSubject, aTopic, aData);
return NS_OK;
}
void

Просмотреть файл

@ -46,12 +46,12 @@
#include "gtkdrawing.h"
class nsNativeThemeGTK: private nsNativeTheme,
public nsITheme {
public nsITheme,
public nsIObserver {
public:
NS_DECL_ISUPPORTS_INHERITED
// Also implemented by nsNativeTheme
NS_SCRIPTABLE NS_IMETHOD Observe(nsISupports *aSubject, const char * aTopic,
const PRUnichar * aData);
NS_DECL_NSIOBSERVER
// The nsITheme interface.
NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext,

Просмотреть файл

@ -62,18 +62,6 @@
#include "nsIDOMMouseEvent.h"
#include "mozilla/Preferences.h"
#ifdef DEBUG
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#include <gdiplus.h>
#endif
namespace mozilla {
namespace widget {
@ -444,114 +432,5 @@ WinUtils::GetShellItemPath(IShellItem* aItem,
return !aResultString.IsEmpty();
}
#ifdef DEBUG
// Win xp and up
#pragma comment(lib, "gdiplus.lib")
static bool
GetEncoderClsid(const WCHAR* aFormat, CLSID* aClsid)
{
using namespace Gdiplus;
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return false;
pImageCodecInfo = (ImageCodecInfo*)(moz_malloc(size));
if (GetImageEncoders(num, size, pImageCodecInfo) != Ok)
return false;
for(UINT j = 0; j < num; ++j) {
if(!wcscmp(pImageCodecInfo[j].MimeType, aFormat)) {
*aClsid = pImageCodecInfo[j].Clsid;
moz_free(pImageCodecInfo);
return true;
}
}
moz_free(pImageCodecInfo);
return false;
}
/* static */
void
WinUtils::SaveDCToPng(HDC aHdc, const WCHAR* aFilePath, int aXPos, int aYPos,
int aWidth, int aHeight)
{
using namespace Gdiplus;
static ULONG_PTR sGiplusToken;
nsCOMPtr<nsILocalFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
if (!file || NS_FAILED(file->InitWithPath(nsDependentString(aFilePath)))) {
NS_WARNING("bad file path.");
return;
}
GdiplusStartupInput gdiplusStartupInput;
if (!sGiplusToken)
GdiplusStartup(&sGiplusToken, &gdiplusStartupInput, NULL);
HDC memdc;
HBITMAP membit;
memdc = CreateCompatibleDC(aHdc);
NS_WARN_IF_FALSE(memdc, "CreateCompatibleDC failed");
if (!memdc)
return;
membit = CreateCompatibleBitmap(aHdc, aWidth, aHeight);
NS_WARN_IF_FALSE(membit, "CreateCompatibleBitmap failed");
if (!membit) {
DeleteObject(memdc);
return;
}
HBITMAP hOldBitmap =(HBITMAP) SelectObject(memdc, membit);
if (!hOldBitmap || hOldBitmap == HGDI_ERROR) {
DeleteObject(memdc);
DeleteObject(membit);
return;
}
BitBlt(memdc, 0, 0, aWidth, aHeight, aHdc, aXPos, aYPos, SRCCOPY);
Gdiplus::Bitmap bitmap(membit, NULL);
CLSID clsid;
if (!GetEncoderClsid(L"image/png", &clsid)) {
NS_WARNING("GetEncoderClsid failed");
return;
}
file->Remove(false);
if (bitmap.Save(aFilePath, &clsid) != Ok) {
NS_WARNING("bitmap.Save faled.");
}
SelectObject(memdc, hOldBitmap);
DeleteObject(memdc);
DeleteObject(membit);
}
/* static */
void
WinUtils::SaveDCToPngIndexed(HDC aHdc, const WCHAR* aDirectory, const WCHAR* aAnnotation,
int aXPos, int aYPos, int aWidth, int aHeight)
{
static int sPngFileIndex;
WCHAR filename[512];
filename[0] = 0;
wsprintf(filename, L"%s\\%s_image-%d.png", aDirectory, aAnnotation,
sPngFileIndex);
sPngFileIndex++;
WinUtils::SaveDCToPng(aHdc, filename, aXPos, aYPos, aWidth, aHeight);
}
#endif // DEBUG
} // namespace widget
} // namespace mozilla

Просмотреть файл

@ -231,44 +231,6 @@ public:
static bool GetShellItemPath(IShellItem* aItem,
nsString& aResultString);
#ifdef DEBUG
/**
* (DEBUG ONLY)
* SaveDCToPng - Save the contents of an HDC to a local png image. Deletes
* the target before creating.
*
* aHdc HDC to save
* aFilePath file path to save to.
* aXPos X origin within the HDC.
* aYPos Y origin within the HDC.
* aWidth Width of the section to capture.
* aHeight height of the section to capture.
*/
static void SaveDCToPng(HDC hdc, const WCHAR* aFilePath,
int aXPos, int aYPos,
int aWidth, int aHeight);
/**
* (DEBUG ONLY)
* SaveDCToPngIndexed - Save the contents of an HDC to a local png image.
* Filenames are of the format:
* (dir)\\(annotation)_image-(index).png
* where index equals the call count. Calls SaveDCToPng.
*
* aHdc HDC to save
* aDirectory location to store mutliple images.
* aAnnotation filename safe annotation for the png.
* aXPos X origin within the HDC.
* aYPos Y origin within the HDC.
* aWidth Width of the section to capture.
* aHeight height of the section to capture.
*/
static void SaveDCToPngIndexed(HDC aHdc, const WCHAR* aDirectory,
const WCHAR* aAnnotation,
int aXPos, int aYPos,
int aWidth, int aHeight);
#endif
private:
typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath,
IBindCtx *pbc,

Просмотреть файл

@ -67,6 +67,7 @@
#include "gfxMatrix.h"
#include "gfxWindowsPlatform.h"
#include "gfxWindowsSurface.h"
#include "gfxWindowsNativeDrawing.h"
#include "nsUXThemeData.h"
#include "nsUXThemeConstants.h"
@ -77,9 +78,6 @@ using namespace mozilla::widget;
extern PRLogModuleInfo* gWindowsLog;
#endif
// Default fps when animating themed widgets.
#define DEFAULT_ANIMATION_FPS 30
NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeWin, nsNativeTheme, nsITheme)
static inline bool IsHTMLContent(nsIFrame *frame)
@ -227,330 +225,6 @@ static SIZE GetGutterSize(HANDLE theme, HDC hdc)
return ret;
}
/*
* RenderThemedAnimationFrame - renders a frame of widget animation
* for fadable widgets.
*
* @param aCtx gfxContext of the target composition surface.
* @param aNative gfxWindowsNativeDrawing associated with the rendering
* operation initiated in DrawWidgetBackground.
* @param aTheme An open theme handle used in rendering.
* @param aHdc HDC associated with the DIB we'll be rendering the final
* frame to.
* @param aPartsList The Win theme part(s) to render.
* @param aPartCount The number of parts listed in aPartsList.
* @param aBaseState Theme state that will act as the background graphic of
* the frame.
* @param aAlphaState The overlay theme graphic that is layered on top of
* aBaseState.
* @param aAlpha Alpha (0.0-1.0) value for the aAlphaState overlay.
* @param aDRect
* @param aDDirtyRect Device rects
* @param aWRect
* @param aWDirtyRect Native rects
* @returns true on success, false if the default theme was rendered
* without a fade or serious error. Callers should not
* queue animations for false results.
*/
static bool
RenderThemedAnimationFrame(gfxContext* aCtx,
gfxWindowsNativeDrawing* aNative,
HANDLE aTheme, HDC aHdc,
int aPartsList[], int aPartCount,
int aBaseState, int aAlphaState,
double aAlpha,
const gfxRect& aDRect, const gfxRect& aDDirtyRect,
const RECT& aWRect, const RECT& aWDirtyRect)
{
NS_ASSERTION(aPartCount > 0, "Bad parts array.");
NS_ASSERTION(aCtx, "Bad context.");
NS_ASSERTION(aNative, "Bad native pointer.");
#if 0
printf("rect:(%d %d %d %d) dirty:(%d %d %d %d) alpha=%f\n",
aWRect.left, aWRect.top, aWRect.right, aWRect.bottom,
aWDirtyRect.left, aWDirtyRect.top, aWDirtyRect.right, aWDirtyRect.bottom,
aAlpha);
#endif
// If false, we are rendering to the target surface, so use origin offsets.
// If true, we are rendering to back buffers with an origin of 0,0.
bool backBufferInUse = aNative->IsDoublePass();
nsRefPtr<gfxContext> paintCtx;
if (backBufferInUse) {
// In the case of alpha recovery, gfxWindowsNativeDrawing creates internal
// backing DIBs we render to, so get the current surface we are working
// with. (aHdc is already associated with the correct buffer.)
nsRefPtr<gfxASurface> currentSurf = aNative->GetCurrentSurface();
NS_ENSURE_TRUE(currentSurf, false);
// Wrap this in a gfxContext so we can work with it
paintCtx = new gfxContext(currentSurf);
NS_ENSURE_TRUE(paintCtx, false);
} else {
// Use the passed in context
paintCtx = aCtx;
}
int width = aWDirtyRect.right - aWDirtyRect.left;
int height = aWDirtyRect.bottom - aWDirtyRect.top;
RECT surfaceDrawRect = { 0, 0, width, height }; // left, top, right, bottom
// Create a temp base theme background surface
nsRefPtr<gfxWindowsSurface> surfBase =
new gfxWindowsSurface(gfxIntSize(width, height),
gfxASurface::ImageFormatRGB24);
NS_ENSURE_TRUE(surfBase, false);
// Copy the destination context over to our temporary surface. We'll render
// on top of what we copy.
if (backBufferInUse) {
// FillRect is about 35% faster than BitBlt
if (!aNative->IsSecondPass()) {
FillRect(surfBase->GetDC(), &surfaceDrawRect,
(HBRUSH)GetStockObject(BLACK_BRUSH));
} else {
FillRect(surfBase->GetDC(), &surfaceDrawRect,
(HBRUSH)GetStockObject(WHITE_BRUSH));
}
} else {
// XXX we might not need this?
BitBlt(surfBase->GetDC(), 0, 0, width, height, aHdc, aWDirtyRect.left,
aWDirtyRect.top, SRCCOPY);
}
// Render the theme's base graphic
for (int idx = 0; idx < aPartCount; idx++) {
DrawThemeBackground(aTheme, surfBase->GetDC(), aPartsList[idx],
aBaseState, &surfaceDrawRect, &surfaceDrawRect);
}
// Create a new highlight theme background surface
nsRefPtr<gfxWindowsSurface> surfAlpha =
new gfxWindowsSurface(gfxIntSize(width, height),
gfxASurface::ImageFormatRGB24);
NS_ENSURE_TRUE(surfAlpha, false);
if (backBufferInUse) {
if (!aNative->IsSecondPass()) {
FillRect(surfAlpha->GetDC(), &surfaceDrawRect,
(HBRUSH)GetStockObject(BLACK_BRUSH));
} else {
FillRect(surfAlpha->GetDC(), &surfaceDrawRect,
(HBRUSH)GetStockObject(WHITE_BRUSH));
}
} else {
BitBlt(surfAlpha->GetDC(), 0, 0, width, height, aHdc, aWDirtyRect.left,
aWDirtyRect.top, SRCCOPY);
}
// Render the theme's highlight graphic
for (int idx = 0; idx < aPartCount; idx++) {
DrawThemeBackground(aTheme, surfAlpha->GetDC(), aPartsList[idx],
aAlphaState, &surfaceDrawRect, &surfaceDrawRect);
}
// Blend the two images together using aAlpha for surfAlpha.
nsRefPtr<gfxImageSurface> imageBase = surfBase->GetAsImageSurface();
nsRefPtr<gfxImageSurface> imageAlpha = surfAlpha->GetAsImageSurface();
NS_ENSURE_TRUE(imageBase, false);
NS_ENSURE_TRUE(imageAlpha, false);
gfxContext::GraphicsOperator currentOp = paintCtx->CurrentOperator();
paintCtx->Save();
paintCtx->ResetClip();
if (!backBufferInUse) {
// In cairo we want to fall through and use BitBlt or AlphaBlend but
// won't unless we're aligned on pixel boundaries. Since our hdc rects
// are already snapped, round off the Translate parameter as well so
// they match.
gfxRect roundedRect = aDDirtyRect;
roundedRect.Round();
paintCtx->Clip(roundedRect);
paintCtx->Translate(roundedRect.TopLeft());
}
paintCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
paintCtx->SetSource(imageBase);
paintCtx->Paint();
paintCtx->SetOperator(gfxContext::OPERATOR_OVER);
paintCtx->SetSource(imageAlpha);
paintCtx->Paint(aAlpha);
paintCtx->Restore();
paintCtx->SetOperator(currentOp);
return true;
}
/*
* QueueAnimation - helper for queuing up a render callback via
* QueueAnimatedContentRefreshForFade.
*
* @param aNative gfxWindowsNativeDrawing associated with the rendering
* operation initiated in DrawWidgetBackground.
* @param aContent The element that will be invalidated.
* @param aDirection The FadeState direction of the fade. FADE_IN & FADE_OUT
* are valid values.
* @param aDuration The total duration of one phase (in/out) of the fade.
* @param aUserData User data passed to QueueAnimatedContentRefreshForFade.
*/
void
nsNativeThemeWin::QueueAnimation(gfxWindowsNativeDrawing* aNativeDrawing,
nsIContent* aContent, FadeState aDirection,
DWORD aDuration, PRUint32 aUserValue)
{
NS_ASSERTION(aNativeDrawing, "bad draw pointer");
NS_ASSERTION(aContent, "bad content pointer");
NS_ASSERTION((aDirection == FADE_IN ||
aDirection == FADE_OUT), "bad direction");
// Often content is rendered using alpha recovery which requires two passes,
// so only queue up another refresh if we are on the final (or single) pass
// of a render operation. This way QueueAnimatedContentRefreshForFade won't
// cancel our fade resulting in the second pass passing through fState ==
// FADE_NOTACTIVE rendering, which would screw up recovery.
if (!aNativeDrawing->IsDoublePass() || aNativeDrawing->IsSecondPass())
QueueAnimatedContentRefreshForFade(aContent, aDirection,
DEFAULT_ANIMATION_FPS, aDuration, aUserValue);
}
/*
* GetScrollbarButtonBasicState - translate vsstyle.h scrollbar button
* states to generic TS_* states.
*/
static int
GetScrollbarButtonBasicState(int aState)
{
switch(aState) {
case ABS_UPHOT:
case ABS_DOWNHOT:
case ABS_LEFTHOT:
case ABS_RIGHTHOT:
return TS_HOVER;
break;
case ABS_UPPRESSED:
case ABS_DOWNPRESSED:
case ABS_LEFTPRESSED:
case ABS_RIGHTPRESSED:
return TS_ACTIVE;
break;
case ABS_UPDISABLED:
case ABS_DOWNDISABLED:
case ABS_LEFTDISABLED:
case ABS_RIGHTDISABLED:
return TS_DISABLED;
break;
case ABS_UPHOVER:
case ABS_DOWNHOVER:
case ABS_LEFTHOVER:
case ABS_RIGHTHOVER:
return TS_FOCUSED;
break;
default:
return TS_NORMAL;
}
}
/*
* GetScrollbarButtonProperFadeStates - translate basic TS_* states to proper
* vsstyle.h scrollbar button states. Modifies aStartState and aFinalState.
*/
void
nsNativeThemeWin::GetScrollbarButtonProperFadeStates(int aBasicState,
nsIContent* aContent,
int aWidgetType,
int& aStartState,
int& aFinalState)
{
if (aBasicState == TS_FOCUSED) {
// gray highlight
switch(aWidgetType) {
case NS_THEME_SCROLLBAR_BUTTON_UP:
aStartState = ABS_UPNORMAL;
aFinalState = ABS_UPHOVER;
break;
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
aStartState = ABS_DOWNNORMAL;
aFinalState = ABS_DOWNHOVER;
break;
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
aStartState = ABS_LEFTNORMAL;
aFinalState = ABS_LEFTHOVER;
break;
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
aStartState = ABS_RIGHTNORMAL;
aFinalState = ABS_RIGHTHOVER;
break;
}
} else if (aBasicState == TS_HOVER) {
// hot blue hover
switch(aWidgetType) {
case NS_THEME_SCROLLBAR_BUTTON_UP:
aStartState = ABS_UPNORMAL;
aFinalState = ABS_UPHOT;
break;
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
aStartState = ABS_DOWNNORMAL;
aFinalState = ABS_DOWNHOT;
break;
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
aStartState = ABS_LEFTNORMAL;
aFinalState = ABS_LEFTHOT;
break;
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
aStartState = ABS_RIGHTNORMAL;
aFinalState = ABS_RIGHTHOT;
break;
}
} else if (aBasicState == TS_NORMAL) {
switch(aWidgetType) {
case NS_THEME_SCROLLBAR_BUTTON_UP:
aStartState = ABS_UPNORMAL;
break;
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
aStartState = ABS_DOWNNORMAL;
break;
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
aStartState = ABS_LEFTNORMAL;
break;
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
aStartState = ABS_RIGHTNORMAL;
break;
}
aFinalState = GetFadeUserData(aContent);
} else {
NS_NOTREACHED("Unexpected state for Win7/Vista scroll bar buttons");
}
}
/*
* GetThemedTransitionDuration - returns the duration of a fading
* widget transition in milliseconds.
*
* @param aTheme An open theme handle used in rendering.
* @param aStateIdFrom Theme state that will act as the starting point of an
* animation.
* @param aStateIdTo Theme state that will act as the ending point of an
* animation.
* @returns 0 if there is no fade sequence for aPartId between
* aStateIdFrom and aStateIdTo.
*/
static DWORD
GetThemedTransitionDuration(HANDLE aTheme, int aPartId,
int aStateIdFrom, int aStateIdTo)
{
DWORD duration = 0;
// XP does not support this call
if (!nsUXThemeData::getThemeTransitionDuration)
return 0;
nsUXThemeData::getThemeTransitionDuration(aTheme, aPartId,
aStateIdFrom,
aStateIdTo,
TMT_TRANSITIONDURATIONS,
&duration);
return duration;
}
static HRESULT DrawThemeBGRTLAware(HANDLE theme, HDC hdc, int part, int state,
const RECT *widgetRect, const RECT *clipRect,
bool isRTL)
@ -946,12 +620,6 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
}
}
// Note, radio buttons do not support a visual indeterminate state,
// check boxes do.
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775947%28v=vs.85%29.aspx
if (!isCheckbox && inputState == INDETERMINATE)
inputState = UNCHECKED;
// 4 unchecked states, 4 checked states, 4 indeterminate states.
aState += inputState * 4;
return NS_OK;
@ -1793,233 +1461,6 @@ RENDER_AGAIN:
DrawThemeBGRTLAware(theme, hdc, part, state,
&widgetRect, &clipRect, IsFrameRTL(aFrame));
}
else if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL ||
aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) {
// Calculate if we need a gripper layered on top of the background
SIZE gripSize;
MARGINS thumbMgns;
int gripPart = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) ?
SP_GRIPPERHOR : SP_GRIPPERVERT;
bool drawGripper =
(GetThemePartSize(theme, hdc, gripPart, state, NULL,
TS_TRUE, &gripSize) == S_OK &&
GetThemeMargins(theme, hdc, part, state,
TMT_CONTENTMARGINS, NULL,
&thumbMgns) == S_OK &&
gripSize.cx + thumbMgns.cxLeftWidth + thumbMgns.cxRightWidth <=
widgetRect.right - widgetRect.left &&
gripSize.cy + thumbMgns.cyTopHeight + thumbMgns.cyBottomHeight <=
widgetRect.bottom - widgetRect.top);
nsIContent* content = nsnull;
if (aFrame) {
content = aFrame->GetContent();
}
FadeState fState = GetFadeState(content);
DWORD duration = GetThemedTransitionDuration(theme, part,
TS_NORMAL,
TS_HOVER);
// Rendering the scrollbar
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ||
state == TS_ACTIVE || state == TS_DISABLED ||
(state == TS_NORMAL && fState == FADE_NOTACTIVE) ||
!aFrame || !duration || !content) {
// We only apply scrollbar fades to Vista and Win7, and on those os we
// have a fade active when the state is either TS_HOVER or TS_NORMAL.
// Everything else gets the standard rendering from the Win theme lib.
DrawThemeBackground(theme, hdc, part, state, &widgetRect, &clipRect);
if (drawGripper)
DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect,
&clipRect);
if (state == TS_ACTIVE) {
// Common transition, mid fade-in -> active state. Finish
// the fade-in here.
FinishFadeIn(content);
}
} else {
int partsList[2];
partsList[0] = part;
partsList[1] = gripPart;
int partCount = (drawGripper ? 2 : 1);
if (RenderThemedAnimationFrame(ctx, &nativeDrawing, theme, hdc,
partsList, partCount,
TS_NORMAL, TS_HOVER,
GetFadeAlpha(content),
tr, dr, widgetRect, clipRect)) {
QueueAnimation(&nativeDrawing, content,
(state == TS_HOVER ? FADE_IN : FADE_OUT), duration);
}
}
}
else if (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) {
int basicState = GetScrollbarButtonBasicState(state);
nsIContent* content = nsnull;
if (aFrame) {
content = aFrame->GetContent();
}
FadeState fState = GetFadeState(content);
// Cheating, but they are all the same
DWORD duration = GetThemedTransitionDuration(theme,
SBP_ARROWBTN,
ABS_UPNORMAL,
ABS_UPHOT);
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ||
basicState == TS_ACTIVE || basicState == TS_DISABLED ||
(basicState == TS_NORMAL && fState == FADE_NOTACTIVE) ||
!aFrame || !duration || !content) {
DrawThemeBackground(theme, hdc, part, state, &widgetRect, &clipRect);
} else {
int partsList[1];
partsList[0] = part;
int startState, finalState;
GetScrollbarButtonProperFadeStates(basicState, content, aWidgetType,
startState, finalState);
if (RenderThemedAnimationFrame(ctx, &nativeDrawing, theme, hdc,
partsList, 1,
startState, finalState,
GetFadeAlpha(content),
tr, dr, widgetRect, clipRect)) {
QueueAnimation(&nativeDrawing, content,
(basicState == TS_NORMAL ? FADE_OUT : FADE_IN),
duration, finalState);
}
}
}
else if (aWidgetType == NS_THEME_BUTTON) {
nsIContent* content = nsnull;
if (aFrame) {
content = aFrame->GetContent();
}
FadeState fState = GetFadeState(content);
DWORD duration = GetThemedTransitionDuration(theme,
BP_PUSHBUTTON,
PBS_NORMAL,
PBS_HOT);
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ||
state == PBS_PRESSED || state == PBS_DISABLED ||
((state == PBS_NORMAL || state == PBS_DEFAULTED) &&
fState == FADE_NOTACTIVE) || !aFrame || !duration || !content) {
DrawThemeBackground(theme, hdc, part, state, &widgetRect, &clipRect);
} else {
// The normal state for buttons is either TS_NORMAL or TS_FOCUSED.
// Either of these states can also be used for the default button
// selection. Make sure we use the right state constant for focused
// and default buttons when they are hovered over.
int startState, finalState;
nsEventStates eventState = GetContentState(aFrame, aWidgetType);
if (eventState.HasState(NS_EVENT_STATE_FOCUS) ||
IsDefaultButton(aFrame)) {
startState = PBS_DEFAULTED;
finalState = PBS_DEFAULTED_ANIMATING;
} else {
startState = PBS_NORMAL;
finalState = PBS_HOT;
}
int partsList[1];
partsList[0] = part;
if (RenderThemedAnimationFrame(ctx, &nativeDrawing, theme, hdc,
partsList, 1,
startState, finalState,
GetFadeAlpha(content),
tr, dr, widgetRect, clipRect)) {
QueueAnimation(&nativeDrawing, content,
((state == PBS_NORMAL || state == PBS_DEFAULTED) ?
FADE_OUT : FADE_IN), duration);
}
}
}
else if (aWidgetType == NS_THEME_RADIO ||
aWidgetType == NS_THEME_CHECKBOX) {
nsIContent* content = nsnull;
if (aFrame) {
content = aFrame->GetContent();
}
FadeState fState = GetFadeState(content);
DWORD duration = GetThemedTransitionDuration(theme,
BP_RADIOBUTTON,
RBS_UNCHECKEDNORMAL,
RBS_UNCHECKEDHOT);
// Radio buttons have two states, checkboxes have three. The
// checkbox constants work for both.
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ||
state == CBS_UNCHECKEDPRESSED || state == CBS_UNCHECKEDDISABLED ||
state == CBS_CHECKEDPRESSED || state == CBS_CHECKEDDISABLED ||
state == CBS_MIXEDPRESSED || state == CBS_MIXEDDISABLED ||
((state == CBS_UNCHECKEDNORMAL || state == CBS_CHECKEDNORMAL ||
state == CBS_MIXEDNORMAL) && fState == FADE_NOTACTIVE) ||
!aFrame || !duration || !content) {
DrawThemeBackground(theme, hdc, part, state, &widgetRect, &clipRect);
} else {
int partsList[1];
partsList[0] = part;
int startState, finalState;
switch(state) {
case CBS_UNCHECKEDNORMAL:
case CBS_UNCHECKEDHOT:
startState = CBS_UNCHECKEDNORMAL;
finalState = CBS_UNCHECKEDHOT;
break;
case CBS_CHECKEDNORMAL:
case CBS_CHECKEDHOT:
startState = CBS_CHECKEDNORMAL;
finalState = CBS_CHECKEDHOT;
break;
case CBS_MIXEDNORMAL:
case CBS_MIXEDHOT:
startState = CBS_MIXEDNORMAL;
finalState = CBS_MIXEDHOT;
break;
}
bool isNormal = (state == CBS_UNCHECKEDNORMAL ||
state == CBS_CHECKEDNORMAL ||
state == CBS_MIXEDNORMAL);
if (RenderThemedAnimationFrame(ctx, &nativeDrawing, theme, hdc,
partsList, 1,
startState, finalState,
GetFadeAlpha(content),
tr, dr, widgetRect, clipRect)) {
QueueAnimation(&nativeDrawing, content,
(isNormal ? FADE_OUT : FADE_IN), duration);
}
}
}
else if (aWidgetType == NS_THEME_TOOLBAR_BUTTON) {
nsIContent* content = nsnull;
if (aFrame) {
content = aFrame->GetContent();
}
FadeState fState = GetFadeState(content);
DWORD duration = GetThemedTransitionDuration(theme,
BP_PUSHBUTTON,
PBS_NORMAL,
PBS_HOT);
// similar to regular buttons, except there's no PBS_DEFAULTED
// state. There is however an additional TS_CHECKED state.
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ||
state == PBS_PRESSED || state == PBS_DISABLED ||
(state == PBS_NORMAL && fState == FADE_NOTACTIVE) ||
!aFrame || !duration || !content) {
DrawThemeBackground(theme, hdc, part, state, &widgetRect, &clipRect);
} else {
int partsList[1];
partsList[0] = part;
bool isChecked = (state == TS_CHECKED || state == TS_HOTCHECKED);
if (RenderThemedAnimationFrame(ctx, &nativeDrawing, theme, hdc,
partsList, 1,
(isChecked ? TS_CHECKED : TS_NORMAL),
(isChecked ? TS_HOTCHECKED : TS_HOT),
GetFadeAlpha(content),
tr, dr, widgetRect, clipRect)) {
QueueAnimation(&nativeDrawing, content,
(state == TS_NORMAL || state == TS_CHECKED ?
FADE_OUT : FADE_IN), duration);
}
}
}
// If part is negative, the element wishes us to not render a themed
// background, instead opting to be drawn specially below.
else if (part >= 0) {
@ -2087,6 +1528,24 @@ RENDER_AGAIN:
widgetRect.bottom = widgetRect.top + TB_SEPARATOR_HEIGHT;
DrawThemeEdge(theme, hdc, RP_BAND, 0, &widgetRect, EDGE_ETCHED, BF_TOP, NULL);
}
else if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL ||
aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL)
{
// Draw the decorative gripper for the scrollbar thumb button, if it fits
SIZE gripSize;
MARGINS thumbMgns;
int gripPart = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) ?
SP_GRIPPERHOR : SP_GRIPPERVERT;
if (GetThemePartSize(theme, hdc, gripPart, state, NULL, TS_TRUE, &gripSize) == S_OK &&
GetThemeMargins(theme, hdc, part, state, TMT_CONTENTMARGINS, NULL, &thumbMgns) == S_OK &&
gripSize.cx + thumbMgns.cxLeftWidth + thumbMgns.cxRightWidth <= widgetRect.right - widgetRect.left &&
gripSize.cy + thumbMgns.cyTopHeight + thumbMgns.cyBottomHeight <= widgetRect.bottom - widgetRect.top)
{
DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect, &clipRect);
}
}
else if ((aWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
nsUXThemeData::CheckForCompositor())
@ -2140,8 +1599,7 @@ RENDER_AGAIN:
if (indeterminate ||
WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(),
DEFAULT_ANIMATION_FPS)) {
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 30)) {
NS_WARNING("unable to animate progress widget!");
}
@ -3934,8 +3392,7 @@ RENDER_AGAIN:
* The indeterminate rendering is animated: the bar goes from one side to
* another.
*/
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(),
DEFAULT_ANIMATION_FPS)) {
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 30)) {
NS_WARNING("unable to animate progress widget!");
}

Просмотреть файл

@ -41,7 +41,6 @@
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include "nsNativeTheme.h"
#include "gfxWindowsNativeDrawing.h"
#include <windows.h>
struct nsIntRect;
@ -104,38 +103,39 @@ protected:
nsresult GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
PRInt32& aPart, PRInt32& aState);
nsresult ClassicGetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
PRInt32& aPart, PRInt32& aState, bool& aFocused);
PRInt32& aPart, PRInt32& aState, bool& aFocused);
nsresult ClassicDrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
const nsRect& aRect,
const nsRect& aClipRect);
nsresult ClassicGetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nsIntMargin* aResult);
const nsRect& aRect,
const nsRect& aClipRect);
nsresult ClassicGetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nsIntMargin* aResult);
bool ClassicGetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nsIntMargin* aResult);
nsIFrame* aFrame,
PRUint8 aWidgetType,
nsIntMargin* aResult);
nsresult ClassicGetMinimumWidgetSize(nsRenderingContext* aContext, nsIFrame* aFrame,
PRUint8 aWidgetType,
nsIntSize* aResult,
bool* aIsOverridable);
PRUint8 aWidgetType,
nsIntSize* aResult,
bool* aIsOverridable);
bool ClassicThemeSupportsWidget(nsPresContext* aPresContext,
nsIFrame* aFrame,
PRUint8 aWidgetType);
nsIFrame* aFrame,
PRUint8 aWidgetType);
void DrawCheckedRect(HDC hdc, const RECT& rc, PRInt32 fore, PRInt32 back,
HBRUSH defaultBack);
PRUint32 GetWidgetNativeDrawingFlags(PRUint8 aWidgetType);
PRInt32 StandardGetState(nsIFrame* aFrame, PRUint8 aWidgetType, bool wantFocused);
bool IsMenuActive(nsIFrame* aFrame, PRUint8 aWidgetType);
void QueueAnimation(gfxWindowsNativeDrawing* aNativeDrawing,
nsIContent* aContent, FadeState aDirection,
DWORD aDuration, PRUint32 aUserValue = 0);
void GetScrollbarButtonProperFadeStates(int aBasicState, nsIContent* aContent,
int aWidgetType, int& aStartState,
int& aFinalState);
};
// Creator function

Просмотреть файл

@ -43,9 +43,6 @@
* Windows' Theme API. For more information on theme parts and states see
* http://msdn.microsoft.com/en-us/library/bb773210(VS.85).aspx
*/
#include <vsstyle.h>
#define THEME_COLOR 204
#define THEME_FONT 210
@ -219,7 +216,6 @@
#define WS_EX_LAYOUTRTL 0x00400000L // Right to left mirroring
#endif
#define TMT_TRANSITIONDURATIONS 6000
// Our extra constants for passing a little bit more info to the renderer.
#define DFCS_RTL 0x00010000

Просмотреть файл

@ -70,8 +70,6 @@ bool nsUXThemeData::sTitlebarInfoPopulatedAero = false;
bool nsUXThemeData::sTitlebarInfoPopulatedThemed = false;
SIZE nsUXThemeData::sCommandButtons[4];
nsUXThemeData::GetThemeTransitionDurationPtr nsUXThemeData::getThemeTransitionDuration = NULL;
nsUXThemeData::DwmExtendFrameIntoClientAreaProc nsUXThemeData::dwmExtendFrameIntoClientAreaPtr = NULL;
nsUXThemeData::DwmIsCompositionEnabledProc nsUXThemeData::dwmIsCompositionEnabledPtr = NULL;
nsUXThemeData::DwmSetIconicThumbnailProc nsUXThemeData::dwmSetIconicThumbnailPtr = NULL;
@ -96,13 +94,6 @@ nsUXThemeData::Initialize()
::ZeroMemory(sThemes, sizeof(sThemes));
NS_ASSERTION(!sThemeDLL, "nsUXThemeData being initialized twice!");
if (GetThemeDLL()) {
// Vista and up entry points:
getThemeTransitionDuration =
(GetThemeTransitionDurationPtr)
GetProcAddress(sThemeDLL, "GetThemeTransitionDuration");
}
if (GetDwmDLL()) {
dwmExtendFrameIntoClientAreaPtr = (DwmExtendFrameIntoClientAreaProc)::GetProcAddress(sDwmDLL, "DwmExtendFrameIntoClientArea");
dwmIsCompositionEnabledPtr = (DwmIsCompositionEnabledProc)::GetProcAddress(sDwmDLL, "DwmIsCompositionEnabled");

Просмотреть файл

@ -141,13 +141,6 @@ public:
static mozilla::LookAndFeel::WindowsTheme GetNativeThemeId();
static bool IsDefaultWindowTheme();
// Vista and up theme library typedefs and entry points
typedef HRESULT (WINAPI*GetThemeTransitionDurationPtr)(HTHEME hTheme, int iPartId,
int iStateIdFrom, int iStateIdTo,
int iPropId, DWORD *pdwDuration);
static GetThemeTransitionDurationPtr getThemeTransitionDuration;
// dwmapi.dll function typedefs and declarations
typedef HRESULT (WINAPI*DwmExtendFrameIntoClientAreaProc)(HWND hWnd, const MARGINS *pMarInset);
typedef HRESULT (WINAPI*DwmIsCompositionEnabledProc)(BOOL *pfEnabled);

Просмотреть файл

@ -54,15 +54,13 @@
#include "nsProgressFrame.h"
#include "nsMenuFrame.h"
#include "mozilla/dom/Element.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
nsNativeTheme::nsNativeTheme()
: mAnimatedContentTimeout(PR_UINT32_MAX)
{
}
NS_IMPL_ISUPPORTS2(nsNativeTheme, nsITimerCallback, nsIObserver)
NS_IMPL_ISUPPORTS1(nsNativeTheme, nsITimerCallback)
nsIPresShell *
nsNativeTheme::GetPresShell(nsIFrame* aFrame)
@ -567,150 +565,6 @@ nsNativeTheme::QueueAnimatedContentForRefresh(nsIContent* aContent,
return true;
}
inline bool
IsFadeIn(nsNativeTheme::FadeState aState)
{
return (aState == nsNativeTheme::FADE_IN ||
aState == nsNativeTheme::FADE_IN_FINISHED);
}
inline bool
IsFadeOut(nsNativeTheme::FadeState aState)
{
return (aState == nsNativeTheme::FADE_OUT);
}
bool
nsNativeTheme::QueueAnimatedContentRefreshForFade(nsIContent* aContent,
FadeState aFadeDirection,
PRUint32 aMinimumFrameRate,
PRUint32 aMilliseconds,
PRUint32 aUserData)
{
NS_ASSERTION(aContent, "Null pointer!");
NS_ASSERTION((aFadeDirection == FADE_IN ||
aFadeDirection == FADE_OUT), "Bad initial fade direction.");
// Initialize our hash table and setup an observer for freeing its contents
// on shutdown.
if (NS_FAILED(InitFadeList()))
return false;
// Note, QueueAnimatedContentForRefresh failures in here can result in
// content getting stuck in mAnimatedFadesList until shutdown, so we
// warn loudly. Generally this should never happen.
FadeData* pFade = mAnimatedFadesList.Get(aContent);
if (pFade) {
// Update the user data
pFade->SetUserData(aUserData);
// Check for direction changes and update our fade data accordingly.
if (IsFadeIn(pFade->GetState()) != IsFadeIn(aFadeDirection)) {
if (pFade->GetState() != FADE_IN_FINISHED) {
// The amount of time we spent getting here equals the amount of
// time we spend getting back out.
pFade->Reset(pFade->TimeoutUsed(), aFadeDirection);
} else {
// Reset to transition timeout passed in.
//PRUint32 timeout =
// PR_IntervalToMilliseconds(PR_IntervalNow()) + aMilliseconds;
//pFade->Reset(timeout, aFadeDirection);
pFade->Reset(TimeDuration::FromMilliseconds(aMilliseconds),
aFadeDirection);
}
}
// Check for a timeout
if (pFade->GetTimeout() < TimeStamp::Now()) {
// If timed out and it's a fade up, set state to finished. We keep the
// fade data around until a corresponding fade out completes or the
// underlying frame is destroyed.
if (IsFadeIn(pFade->GetState())) {
pFade->FadeInFinished();
// Create a heartbeat (1 sec) animation timer so if the underlying
// frame is destroyed, Notify will free the content.
if (!QueueAnimatedContentForRefresh(aContent, 1)) {
NS_WARNING("QueueAnimatedContentForRefresh failed???");
return false;
}
} else if (IsFadeOut(pFade->GetState())) {
// If timed out and it's a fade out, clear it, we're done.
mAnimatedFadesList.Remove(aContent);
// Fire one last time to get the base graphic painted.
if (!QueueAnimatedContentForRefresh(aContent, aMinimumFrameRate)) {
NS_WARNING("QueueAnimatedContentForRefresh failed???");
return false;
}
}
} else {
// fading..
if (!QueueAnimatedContentForRefresh(aContent, aMinimumFrameRate)) {
NS_WARNING("QueueAnimatedContentForRefresh failed???");
return false;
}
}
return true;
}
// If we don't have a fade put together a FadeData, store it in
// mAnimatedFadesList, and kick things off.
TimeStamp timeout = TimeStamp::Now() +
TimeDuration::FromMilliseconds(aMilliseconds);
nsAutoPtr<FadeData> newFade(new FadeData(timeout, aFadeDirection, aUserData));
if (!newFade) {
NS_WARNING("Out of memory!");
return false;
}
// Call QueueAnimatedContentForRefresh to kick off the fade animation.
if (!QueueAnimatedContentForRefresh(aContent, aMinimumFrameRate)) {
NS_WARNING("QueueAnimatedContentForRefresh failed???");
return false;
}
mAnimatedFadesList.Put(aContent, newFade);
newFade.forget();
return true;
}
// mAnimatedFadesList management
nsresult
nsNativeTheme::InitFadeList()
{
if (mAnimatedFadesList.IsInitialized())
return NS_OK;
if (!mAnimatedFadesList.Init())
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
nsresult rv = NS_ERROR_UNEXPECTED;
if (obsSvc) {
rv = obsSvc->AddObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, false);
}
return rv;
}
NS_IMETHODIMP
nsNativeTheme::Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData)
{
if (strcmp(aTopic, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID) == 0) {
mAnimatedFadesList.Clear();
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
nsresult rv = NS_ERROR_UNEXPECTED;
if (obsSvc) {
rv = obsSvc->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
}
NS_ASSERTION(NS_SUCCEEDED(rv),
"nsNativeTheme RemoveObserver failed, this may cause a leak.");
}
return NS_OK;
}
// mAnimatedContentTimer callback for QueueAnimatedContentForRefresh
NS_IMETHODIMP
nsNativeTheme::Notify(nsITimer* aTimer)
{
@ -724,90 +578,14 @@ nsNativeTheme::Notify(nsITimer* aTimer)
nsIFrame* frame = mAnimatedContentList[index]->GetPrimaryFrame();
if (frame) {
frame->InvalidateOverflowRect();
} else {
// If this content has fade data associated with it, and the
// frame has gone away, free the data and cancel the fade.
if (mAnimatedFadesList.IsInitialized()) {
mAnimatedFadesList.Remove(mAnimatedContentList[index]);
}
}
}
mAnimatedContentList.Clear();
mAnimatedContentTimeout = PR_UINT32_MAX;
return NS_OK;
}
// Fade helpers
nsNativeTheme::FadeData*
nsNativeTheme::GetFade(nsIContent* aContent)
{
if (!aContent || !mAnimatedFadesList.IsInitialized())
return nsnull;
return mAnimatedFadesList.Get(reinterpret_cast<nsISupports*>(aContent));
}
nsNativeTheme::FadeState
nsNativeTheme::GetFadeState(nsIContent* aContent)
{
FadeData* pFade = GetFade(aContent);
if (!pFade)
return FADE_NOTACTIVE;
return pFade->GetState();
}
PRUint32
nsNativeTheme::GetFadeTicks(nsIContent* aContent)
{
FadeData* pFade = GetFade(aContent);
if (!pFade)
return 0;
return pFade->GetTicks();
}
double
nsNativeTheme::GetFadeAlpha(nsIContent* aContent)
{
return ((double)GetFadeTicks(aContent))/TICK_MAX;
}
PRUint32
nsNativeTheme::GetFadeUserData(nsIContent* aContent)
{
FadeData* pFade = GetFade(aContent);
if (!pFade)
return 0;
return pFade->GetUserData();
}
void
nsNativeTheme::SetFadeUserData(nsIContent* aContent, PRUint32 aUserData)
{
FadeData* pFade = GetFade(aContent);
if (pFade) {
pFade->SetUserData(aUserData);
}
}
void
nsNativeTheme::CancelFade(nsIContent* aContent)
{
if (aContent && mAnimatedFadesList.IsInitialized()) {
mAnimatedFadesList.Remove(reinterpret_cast<nsISupports*>(aContent));
}
}
void
nsNativeTheme::FinishFadeIn(nsIContent* aContent)
{
FadeData* pFade = GetFade(aContent);
if (pFade) {
pFade->FadeInFinished();
}
}
nsIFrame*
nsNativeTheme::GetAdjacentSiblingFrameWithSameAppearance(nsIFrame* aFrame,
bool aNextSibling)
@ -829,4 +607,3 @@ nsNativeTheme::GetAdjacentSiblingFrameWithSameAppearance(nsIFrame* aFrame,
return nsnull;
return sibling;
}

Просмотреть файл

@ -49,26 +49,18 @@
#include "nsEventStates.h"
#include "nsTArray.h"
#include "nsITimer.h"
#include "nsClassHashtable.h"
#include "nsIObserver.h"
#include "mozilla/TimeStamp.h"
class nsIContent;
class nsIFrame;
class nsIPresShell;
class nsPresContext;
class nsNativeTheme :
public nsITimerCallback,
public nsIObserver
class nsNativeTheme : public nsITimerCallback
{
protected:
typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration;
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSIOBSERVER
enum ScrollbarButtonType {
eScrollbarButton_UpTop = 0,
@ -197,172 +189,14 @@ class nsNativeTheme :
bool GetCheckedOrSelected(nsIFrame* aFrame, bool aCheckSelected);
bool GetIndeterminate(nsIFrame* aFrame);
bool QueueAnimatedContentForRefresh(nsIContent* aContent,
PRUint32 aMinimumFrameRate);
nsIFrame* GetAdjacentSiblingFrameWithSameAppearance(nsIFrame* aFrame,
bool aNextSibling);
// Queue a themed element for a redraw after a set interval.
bool QueueAnimatedContentForRefresh(nsIContent* aContent,
PRUint32 aMinimumFrameRate);
/*
* Simple two phase animations on themed widgets - 'Fades' transition from
* a base state to a highlighted state and back to the base state, at which
* point data associated with the fade is freed.
*
* Important notes:
*
* Consumers are responsible for triggering refresh calls by calling
* QueueAnimatedContentRefreshForFade on each redraw.
*
* Consumers are also responsible for switching fade transitions from
* FADE_IN/FADE_IN_FINISHED to FADE_OUT through calls to QACRFF. Failing
* to do so keeps content / fade data stored in mAnimatedFadesList until
* the content's underlying frame is destroyed or the application closes.
*/
// Fade states
typedef enum FadeState {
FADE_NOTACTIVE = 0, // Fade state not found, fade complete
FADE_IN = 1, // Fading in
FADE_IN_FINISHED = 2, // Fade-in is finished, waiting for fade-out
FADE_OUT = 3, // Fading out
};
/*
* QueueAnimatedContentRefreshForFade - creates a new fade or requests a
* refresh on an existing fade in progress.
*
* aContent The themed content element the animation is associated
* with.
* aFadeDirection The current direction of the fade. Valid values are
* FADE_IN or FADE_OUT.
* aMinimumFrameRate The minimum frame rate requested (30 is typical). Value
* is passed to QueueAnimatedContentForRefresh to trigger a
* refresh.
* aMilliseconds Duration of the fade-in or fade-out transition.
* aUserData Generic consumer data storage for state across rendering
* of individual frames. Updated on every call.
*/
bool
QueueAnimatedContentRefreshForFade(nsIContent* aContent,
FadeState aFadeDirection,
PRUint32 aMinimumFrameRate,
PRUint32 aMilliseconds,
PRUint32 aUserData = 0);
// Max ticks returned by FadeData->GetTicks().
#define TICK_MAX 100.0
// Internal data structure for storing fade data
class FadeData
{
public:
/*
* FadeData()
* aTimeout now + duration
* aState FADE_IN or FADE_OUT
* aUserData intial value for user data
*/
FadeData(TimeStamp aTimeout, FadeState aState, PRUint32 aUserData) :
mTimeout(aTimeout),
mStartTime(TimeStamp::Now()),
mState(aState),
mUserData(aUserData) {
}
~FadeData() {}
/*
* Reset - resets the to a new timeout value and direction.
* aTimeout msec(now) + duration
* aState FADE_IN or FADE_OUT
*/
void Reset(TimeDuration aTimeout, FadeState aState) {
NS_ASSERTION((aState == FADE_IN || aState == FADE_OUT),
"Bad fade direction.");
mStartTime = TimeStamp::Now();
mTimeout = TimeStamp::Now() + aTimeout;
mState = aState;
}
/*
* GetTicks - returns the number of ticks in this animation where
* ticks >= 0 && ticks <= TICK_MAX. FADE_IN has increasing ticks,
* FADE_OUT decreasing.
*/
PRUint32 GetTicks() {
TimeStamp now = TimeStamp::Now();
if (now >= mTimeout) {
return (mState == FADE_OUT ? 0 : (PRUint32)TICK_MAX);
}
TimeDuration diff = now - mStartTime;
PRUint32 tick =
(PRUint32)ceil((diff / (mTimeout - mStartTime)) * TICK_MAX);
// we want ticks to ascend and descend according to the direction.
if (mState == FADE_OUT) {
tick = (PRUint32)abs(tick - TICK_MAX);
}
return tick;
}
/*
* TimeoutUsed - for fades that have not completes, returns the
* amount of time used thus far in the current transition in msec.
*/
TimeDuration TimeoutUsed() {
TimeDuration used = TimeStamp::Now() - mStartTime;
TimeDuration totalTime = mTimeout - mStartTime;
return NS_MIN(used, totalTime);
}
/*
* Misc. data getters/setters
*/
TimeStamp GetTimeout() { return mTimeout; }
FadeState GetState() { return mState; }
void FadeInFinished() { mState = FADE_IN_FINISHED; }
PRUint32 GetUserData() { return mUserData; }
void SetUserData(PRUint32 aUserData) { mUserData = aUserData; }
private:
TimeStamp mTimeout;
TimeStamp mStartTime;
FadeState mState;
PRUint32 mUserData;
};
/*
* nsNativeTheme fade data helpers
*/
// Retrieves the FadeData object associated with this content, or null.
FadeData* GetFade(nsIContent* aContent);
// Retrieves the current fade state or FADE_NOTACTIVE.
FadeState GetFadeState(nsIContent* aContent);
// Retrieves the current tick count for a fade transition or 0. Ticks
// range from 0 -> TICK_MAX. For FADE_IN transitions ticks increase,
// for FADE_OUT transitions ticks decrease.
PRUint32 GetFadeTicks(nsIContent* aContent);
// Retrieves the alpha value (0->1) corresponding to the current tick
// count for a fade transition, or 0.
double GetFadeAlpha(nsIContent* aContent);
// Get/set consumer data. Valid across each call to QACRFF.
PRUint32 GetFadeUserData(nsIContent* aContent);
void SetFadeUserData(nsIContent* aContent, PRUint32 aUserData);
// Cancel an active fade and free its resources.
void CancelFade(nsIContent* aContent);
// Mark a fade as FADE_IN_FINISHED.
void FinishFadeIn(nsIContent* aContent);
private:
nsresult InitFadeList();
PRUint32 mAnimatedContentTimeout;
nsCOMPtr<nsITimer> mAnimatedContentTimer;
// Render refresh list - nsIContent contains the content
// that will be invalidated when mAnimatedContentTimer fires.
// Cleared on every call to mAnimatedContentTimer Notify.
nsAutoTArray<nsCOMPtr<nsIContent>, 20> mAnimatedContentList;
// Fade list data - nsISupportsHashKey contains the nsIContent
// associated with an active fade.
nsClassHashtable<nsISupportsHashKey, FadeData> mAnimatedFadesList;
};