mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 574454 - Implement frame rendering and metrics in native themeing. r=vlad.
This commit is contained in:
parent
338ca40404
commit
7ce80112ae
@ -23,6 +23,7 @@
|
||||
* Tim Hill (tim@prismelite.com)
|
||||
* James Ross (silver@warwickcompsoc.co.uk)
|
||||
* Simon Bünzli (zeniko@gmail.com)
|
||||
* Jim Mathies (jmathies@mozilla.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -105,8 +106,7 @@ static int FrameRect(HDC inDC, CONST RECT *inRect, HBRUSH inBrush)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
GetViewportOrgEx(HDC hdc, LPPOINT lpPoint)
|
||||
static BOOL GetViewportOrgEx(HDC hdc, LPPOINT lpPoint)
|
||||
{
|
||||
SetViewportOrgEx(hdc, 0, 0, lpPoint);
|
||||
if (lpPoint->x != 0 || lpPoint->y != 0)
|
||||
@ -115,12 +115,51 @@ GetViewportOrgEx(HDC hdc, LPPOINT lpPoint)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool IsHTMLContent(nsIFrame *frame)
|
||||
static inline PRBool IsHTMLContent(nsIFrame *frame)
|
||||
{
|
||||
nsIContent* content = frame->GetContent();
|
||||
return content && content->IsHTML();
|
||||
}
|
||||
|
||||
static PRInt32 GetTopLevelWindowActiveState(nsIFrame *aFrame)
|
||||
{
|
||||
// Get the widget. nsIFrame's GetNearestWidget walks up the view chain
|
||||
// until it finds a real window.
|
||||
nsIWidget* widget = aFrame->GetNearestWidget();
|
||||
nsWindow * window = static_cast<nsWindow*>(widget);
|
||||
if (widget && !window->IsTopLevelWidget() &&
|
||||
!(window = window->GetParentWindow(PR_FALSE)))
|
||||
return PR_FALSE;
|
||||
|
||||
if (window->GetWindowHandle() == ::GetActiveWindow())
|
||||
return mozilla::widget::themeconst::FS_ACTIVE;
|
||||
return mozilla::widget::themeconst::FS_INACTIVE;
|
||||
}
|
||||
|
||||
static PRInt32 GetWindowFrameButtonState(nsIFrame *aFrame, PRInt32 eventState)
|
||||
{
|
||||
if (GetTopLevelWindowActiveState(aFrame) ==
|
||||
mozilla::widget::themeconst::FS_INACTIVE)
|
||||
return mozilla::widget::themeconst::BS_INACTIVE;
|
||||
|
||||
if (eventState & NS_EVENT_STATE_ACTIVE)
|
||||
return mozilla::widget::themeconst::BS_PUSHED;
|
||||
else if (eventState & NS_EVENT_STATE_HOVER)
|
||||
return mozilla::widget::themeconst::BS_HOT;
|
||||
else
|
||||
return mozilla::widget::themeconst::BS_NORMAL;
|
||||
}
|
||||
|
||||
static PRInt32 GetClassicWindowFrameButtonState(PRInt32 eventState)
|
||||
{
|
||||
if (eventState & NS_EVENT_STATE_ACTIVE)
|
||||
return DFCS_BUTTONPUSH|DFCS_PUSHED;
|
||||
else if (eventState & NS_EVENT_STATE_HOVER)
|
||||
return DFCS_BUTTONPUSH|DFCS_HOT;
|
||||
else
|
||||
return DFCS_BUTTONPUSH;
|
||||
}
|
||||
|
||||
nsNativeThemeWin::nsNativeThemeWin() {
|
||||
// If there is a relevant change in forms.css for windows platform,
|
||||
// static widget style variables (e.g. sButtonBorderSize) should be
|
||||
@ -367,6 +406,16 @@ nsNativeThemeWin::GetTheme(PRUint8 aWidgetType)
|
||||
case NS_THEME_MENUIMAGE:
|
||||
case NS_THEME_MENUITEMTEXT:
|
||||
return nsUXThemeData::GetTheme(eUXMenu);
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
return nsUXThemeData::GetTheme(eUXWindowFrame);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -976,6 +1025,43 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
aPart = -1;
|
||||
aState = 0;
|
||||
return NS_OK;
|
||||
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
aPart = mozilla::widget::themeconst::WP_CAPTION;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
aPart = mozilla::widget::themeconst::WP_MAXCAPTION;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
aPart = mozilla::widget::themeconst::WP_FRAMELEFT;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
aPart = mozilla::widget::themeconst::WP_FRAMERIGHT;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
aPart = mozilla::widget::themeconst::WP_FRAMEBOTTOM;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
aPart = mozilla::widget::themeconst::WP_CLOSEBUTTON;
|
||||
aState = GetWindowFrameButtonState(aFrame, GetContentState(aFrame, aWidgetType));
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
aPart = mozilla::widget::themeconst::WP_MINBUTTON;
|
||||
aState = GetWindowFrameButtonState(aFrame, GetContentState(aFrame, aWidgetType));
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
aPart = mozilla::widget::themeconst::WP_MAXBUTTON;
|
||||
aState = GetWindowFrameButtonState(aFrame, GetContentState(aFrame, aWidgetType));
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
aPart = mozilla::widget::themeconst::WP_RESTOREBUTTON;
|
||||
aState = GetWindowFrameButtonState(aFrame, GetContentState(aFrame, aWidgetType));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aPart = 0;
|
||||
@ -1026,6 +1112,32 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
dr.size.height += 2.0;
|
||||
}
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
// ^^ without the right sdk, assume xp theming and fall through.
|
||||
if (nsUXThemeData::CheckForCompositor()) {
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
// Nothing to draw, these areas are glass. Minimum dimensions
|
||||
// should be set, so xul content should be layed out correctly.
|
||||
return NS_OK;
|
||||
break;
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
// Not conventional bitmaps, can't be retrieved. If we fall
|
||||
// through here and call the theme library we'll get aero
|
||||
// basic bitmaps.
|
||||
return NS_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
|
||||
nsRefPtr<gfxContext> ctx = aContext->ThebesContext();
|
||||
|
||||
gfxWindowsNativeDrawing nativeDrawing(ctx, dr, GetWidgetNativeDrawingFlags(aWidgetType));
|
||||
@ -1645,6 +1757,50 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame*
|
||||
sizeReq = TS_MIN;
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
// For XP, use the theme library dimensions, which seem to be accurate.
|
||||
if (nsWindow::GetWindowsVersion() < VISTA_VERSION)
|
||||
break;
|
||||
// The only way to get accurate titlebar button info is to query a
|
||||
// window w/buttons when it's visible. nsWindow takes care of this and
|
||||
// stores that info in nsUXThemeData.
|
||||
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cx;
|
||||
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cy;
|
||||
*aIsOverridable = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
if (nsWindow::GetWindowsVersion() < VISTA_VERSION)
|
||||
break;
|
||||
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx;
|
||||
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy;
|
||||
*aIsOverridable = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
if (nsWindow::GetWindowsVersion() < VISTA_VERSION)
|
||||
break;
|
||||
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx;
|
||||
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy;
|
||||
*aIsOverridable = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
aResult->height = GetSystemMetrics(SM_CYCAPTION);
|
||||
aResult->height += GetSystemMetrics(SM_CYFRAME);
|
||||
*aIsOverridable = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
aResult->width = GetSystemMetrics(SM_CXFRAME);
|
||||
aResult->height = GetSystemMetrics(SM_CYFRAME);
|
||||
*aIsOverridable = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 part, state;
|
||||
@ -1703,6 +1859,19 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aWidgetType == NS_THEME_WINDOW_TITLEBAR ||
|
||||
aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED ||
|
||||
aWidgetType == NS_THEME_WINDOW_FRAME_LEFT ||
|
||||
aWidgetType == NS_THEME_WINDOW_FRAME_RIGHT ||
|
||||
aWidgetType == NS_THEME_WINDOW_FRAME_BOTTOM ||
|
||||
aWidgetType == NS_THEME_WINDOW_BUTTON_CLOSE ||
|
||||
aWidgetType == NS_THEME_WINDOW_BUTTON_MINIMIZE ||
|
||||
aWidgetType == NS_THEME_WINDOW_BUTTON_MINIMIZE ||
|
||||
aWidgetType == NS_THEME_WINDOW_BUTTON_RESTORE) {
|
||||
*aShouldRepaint = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// On Vista, the scrollbar buttons need to change state when the track has/doesn't have hover
|
||||
if (!nsUXThemeData::sIsVistaOrLater &&
|
||||
(aWidgetType == NS_THEME_SCROLLBAR_TRACK_VERTICAL ||
|
||||
@ -1890,6 +2059,15 @@ nsNativeThemeWin::ClassicThemeSupportsWidget(nsPresContext* aPresContext,
|
||||
case NS_THEME_MENUARROW:
|
||||
case NS_THEME_MENUSEPARATOR:
|
||||
case NS_THEME_MENUITEMTEXT:
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
@ -2103,6 +2281,36 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIRenderingContext* aContext, nsI
|
||||
aResult->height = 10;
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
aResult->height = GetSystemMetrics(SM_CYCAPTION);
|
||||
aResult->height += GetSystemMetrics(SM_CYFRAME);
|
||||
aResult->width = 0;
|
||||
break;
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
aResult->width = GetSystemMetrics(SM_CXFRAME);
|
||||
aResult->height = 0;
|
||||
break;
|
||||
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
aResult->height = GetSystemMetrics(SM_CYFRAME);
|
||||
aResult->width = 0;
|
||||
break;
|
||||
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
aResult->width = GetSystemMetrics(SM_CXSIZE);
|
||||
aResult->height = GetSystemMetrics(SM_CYSIZE);
|
||||
// XXX I have no idea why these caption metrics are always off,
|
||||
// but they are.
|
||||
aResult->width -= 2;
|
||||
aResult->height -= 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -2387,6 +2595,50 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, PRUint8
|
||||
aPart = 0;
|
||||
aState = 0;
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
aPart = mozilla::widget::themeconst::WP_CAPTION;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
aPart = mozilla::widget::themeconst::WP_MAXCAPTION;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
aPart = mozilla::widget::themeconst::WP_FRAMELEFT;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
aPart = mozilla::widget::themeconst::WP_FRAMERIGHT;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
aPart = mozilla::widget::themeconst::WP_FRAMEBOTTOM;
|
||||
aState = GetTopLevelWindowActiveState(aFrame);
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
aPart = DFC_CAPTION;
|
||||
aState = DFCS_CAPTIONCLOSE |
|
||||
GetClassicWindowFrameButtonState(GetContentState(aFrame,
|
||||
aWidgetType));
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
aPart = DFC_CAPTION;
|
||||
aState = DFCS_CAPTIONMIN |
|
||||
GetClassicWindowFrameButtonState(GetContentState(aFrame,
|
||||
aWidgetType));
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
aPart = DFC_CAPTION;
|
||||
aState = DFCS_CAPTIONMAX |
|
||||
GetClassicWindowFrameButtonState(GetContentState(aFrame,
|
||||
aWidgetType));
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
aPart = DFC_CAPTION;
|
||||
aState = DFCS_CAPTIONRESTORE |
|
||||
GetClassicWindowFrameButtonState(GetContentState(aFrame,
|
||||
aWidgetType));
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -2858,6 +3110,87 @@ RENDER_AGAIN:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
||||
{
|
||||
// inset the caption area so it doesn't overflow.
|
||||
RECT rect = widgetRect;
|
||||
PRInt32 offset = GetSystemMetrics(SM_CXFRAME);
|
||||
rect.top += offset;
|
||||
rect.left += offset;
|
||||
rect.right -= offset;
|
||||
rect.bottom -= 1;
|
||||
|
||||
// if enabled, draw a gradient titlebar background, otherwise
|
||||
// fill with a solid color.
|
||||
BOOL bFlag = TRUE;
|
||||
SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &bFlag, NULL);
|
||||
if (!bFlag) {
|
||||
if (state == mozilla::widget::themeconst::FS_ACTIVE)
|
||||
FillRect(hdc, &rect, (HBRUSH)(COLOR_ACTIVECAPTION+1));
|
||||
else
|
||||
FillRect(hdc, &rect, (HBRUSH)(COLOR_INACTIVECAPTION+1));
|
||||
} else {
|
||||
DWORD startColor, endColor;
|
||||
if (state == mozilla::widget::themeconst::FS_ACTIVE) {
|
||||
startColor = GetSysColor(COLOR_ACTIVECAPTION);
|
||||
endColor = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
|
||||
} else {
|
||||
startColor = GetSysColor(COLOR_INACTIVECAPTION);
|
||||
endColor = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
|
||||
}
|
||||
|
||||
TRIVERTEX vertex[2];
|
||||
vertex[0].x = rect.left;
|
||||
vertex[0].y = rect.top;
|
||||
vertex[0].Red = GetRValue(startColor) << 8;
|
||||
vertex[0].Green = GetGValue(startColor) << 8;
|
||||
vertex[0].Blue = GetBValue(startColor) << 8;
|
||||
vertex[0].Alpha = 0;
|
||||
|
||||
vertex[1].x = rect.right;
|
||||
vertex[1].y = rect.bottom;
|
||||
vertex[1].Red = GetRValue(endColor) << 8;
|
||||
vertex[1].Green = GetGValue(endColor) << 8;
|
||||
vertex[1].Blue = GetBValue(endColor) << 8;
|
||||
vertex[1].Alpha = 0;
|
||||
|
||||
GRADIENT_RECT gRect;
|
||||
gRect.UpperLeft = 0;
|
||||
gRect.LowerRight = 1;
|
||||
// available on win2k & up
|
||||
GradientFill(hdc, vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_H);
|
||||
}
|
||||
|
||||
// frame things up with the left, top, and right raised borders.
|
||||
DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_RIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_THEME_WINDOW_FRAME_LEFT:
|
||||
DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_LEFT);
|
||||
break;
|
||||
|
||||
case NS_THEME_WINDOW_FRAME_RIGHT:
|
||||
DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RIGHT);
|
||||
break;
|
||||
|
||||
case NS_THEME_WINDOW_FRAME_BOTTOM:
|
||||
DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_BOTTOM);
|
||||
break;
|
||||
|
||||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
||||
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
||||
{
|
||||
PRInt32 oldTA = SetTextAlign(hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP);
|
||||
DrawFrameControl(hdc, &widgetRect, part, state);
|
||||
SetTextAlign(hdc, oldTA);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
|
@ -227,3 +227,63 @@
|
||||
// Toolbar separator dimension which can't be gotten from Windows
|
||||
#define TB_SEPARATOR_HEIGHT 2
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
namespace themeconst {
|
||||
|
||||
// Pulled from sdk/include/vsstyle.h
|
||||
enum {
|
||||
WP_CAPTION = 1,
|
||||
WP_SMALLCAPTION = 2,
|
||||
WP_MINCAPTION = 3,
|
||||
WP_SMALLMINCAPTION = 4,
|
||||
WP_MAXCAPTION = 5,
|
||||
WP_SMALLMAXCAPTION = 6,
|
||||
WP_FRAMELEFT = 7,
|
||||
WP_FRAMERIGHT = 8,
|
||||
WP_FRAMEBOTTOM = 9,
|
||||
WP_SMALLFRAMELEFT = 10,
|
||||
WP_SMALLFRAMERIGHT = 11,
|
||||
WP_SMALLFRAMEBOTTOM = 12,
|
||||
WP_SYSBUTTON = 13,
|
||||
WP_MDISYSBUTTON = 14,
|
||||
WP_MINBUTTON = 15,
|
||||
WP_MDIMINBUTTON = 16,
|
||||
WP_MAXBUTTON = 17,
|
||||
WP_CLOSEBUTTON = 18,
|
||||
WP_SMALLCLOSEBUTTON = 19,
|
||||
WP_MDICLOSEBUTTON = 20,
|
||||
WP_RESTOREBUTTON = 21,
|
||||
WP_MDIRESTOREBUTTON = 22,
|
||||
WP_HELPBUTTON = 23,
|
||||
WP_MDIHELPBUTTON = 24,
|
||||
WP_HORZSCROLL = 25,
|
||||
WP_HORZTHUMB = 26,
|
||||
WP_VERTSCROLL = 27,
|
||||
WP_VERTTHUMB = 28,
|
||||
WP_DIALOG = 29,
|
||||
WP_CAPTIONSIZINGTEMPLATE = 30,
|
||||
WP_SMALLCAPTIONSIZINGTEMPLATE = 31,
|
||||
WP_FRAMELEFTSIZINGTEMPLATE = 32,
|
||||
WP_SMALLFRAMELEFTSIZINGTEMPLATE = 33,
|
||||
WP_FRAMERIGHTSIZINGTEMPLATE = 34,
|
||||
WP_SMALLFRAMERIGHTSIZINGTEMPLATE = 35,
|
||||
WP_FRAMEBOTTOMSIZINGTEMPLATE = 36,
|
||||
WP_SMALLFRAMEBOTTOMSIZINGTEMPLATE = 37,
|
||||
WP_FRAME = 38,
|
||||
};
|
||||
|
||||
enum FRAMESTATES {
|
||||
FS_ACTIVE = 1,
|
||||
FS_INACTIVE = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
BS_NORMAL = 1,
|
||||
BS_HOT = 2,
|
||||
BS_PUSHED = 3,
|
||||
BS_DISABLED = 4,
|
||||
BS_INACTIVE = 5, /* undocumented, inactive caption button */
|
||||
};
|
||||
|
||||
}}} // mozilla::widget::themeconst
|
||||
|
@ -70,6 +70,9 @@ nsUXThemeData::sIsVistaOrLater = PR_FALSE;
|
||||
PRPackedBool
|
||||
nsUXThemeData::sHaveCompositor = PR_FALSE;
|
||||
|
||||
PRBool nsUXThemeData::sTitlebarInfoPopulated = PR_FALSE;
|
||||
SIZE nsUXThemeData::sCommandButtons[3];
|
||||
|
||||
nsUXThemeData::OpenThemeDataPtr nsUXThemeData::openTheme = NULL;
|
||||
nsUXThemeData::CloseThemeDataPtr nsUXThemeData::closeTheme = NULL;
|
||||
nsUXThemeData::DrawThemeBackgroundPtr nsUXThemeData::drawThemeBG = NULL;
|
||||
@ -223,8 +226,48 @@ const wchar_t *nsUXThemeData::GetClassName(nsUXThemeClass cls) {
|
||||
return L"Listview";
|
||||
case eUXMenu:
|
||||
return L"Menu";
|
||||
case eUXWindowFrame:
|
||||
return L"Window";
|
||||
default:
|
||||
NS_NOTREACHED("unknown uxtheme class");
|
||||
return L"";
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsUXThemeData::InitTitlebarInfo()
|
||||
{
|
||||
// Pre-populate with generic metrics. These likley will not match
|
||||
// the current theme, but they insure the buttons at least show up.
|
||||
sCommandButtons[0].cx = GetSystemMetrics(SM_CXSIZE);
|
||||
sCommandButtons[0].cy = GetSystemMetrics(SM_CYSIZE);
|
||||
sCommandButtons[1].cx = sCommandButtons[2].cx = sCommandButtons[0].cx;
|
||||
sCommandButtons[1].cy = sCommandButtons[2].cy = sCommandButtons[0].cy;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsUXThemeData::UpdateTitlebarInfo(TITLEBARINFOEX& info)
|
||||
{
|
||||
if (sTitlebarInfoPopulated)
|
||||
return;
|
||||
|
||||
// Only set if we have valid data for all three buttons we use.
|
||||
if ((info.rgrect[2].right - info.rgrect[2].left) == 0 ||
|
||||
(info.rgrect[3].right - info.rgrect[3].left) == 0 ||
|
||||
(info.rgrect[5].right - info.rgrect[5].left) == 0)
|
||||
return;
|
||||
|
||||
// minimize
|
||||
sCommandButtons[0].cx = info.rgrect[2].right - info.rgrect[2].left;
|
||||
sCommandButtons[0].cy = info.rgrect[2].bottom - info.rgrect[2].top;
|
||||
// maximize/restore
|
||||
sCommandButtons[1].cx = info.rgrect[3].right - info.rgrect[3].left;
|
||||
sCommandButtons[1].cy = info.rgrect[3].bottom - info.rgrect[3].top;
|
||||
// close
|
||||
sCommandButtons[2].cx = info.rgrect[5].right - info.rgrect[5].left;
|
||||
sCommandButtons[2].cy = info.rgrect[5].bottom - info.rgrect[5].top;
|
||||
|
||||
sTitlebarInfoPopulated = PR_TRUE;
|
||||
}
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include <dwmapi.h>
|
||||
#endif
|
||||
|
||||
#include "nsWindowDefs.h"
|
||||
|
||||
// These window messages are not defined in dwmapi.h
|
||||
#ifndef WM_DWMCOMPOSITIONCHANGED
|
||||
#define WM_DWMCOMPOSITIONCHANGED 0x031E
|
||||
@ -85,9 +87,13 @@ enum nsUXThemeClass {
|
||||
eUXHeader,
|
||||
eUXListview,
|
||||
eUXMenu,
|
||||
eUXWindowFrame,
|
||||
eUXNumClasses
|
||||
};
|
||||
|
||||
#define CMDBUTTONIDX_MINIMIZE 0
|
||||
#define CMDBUTTONIDX_RESTORE 1
|
||||
#define CMDBUTTONIDX_CLOSE 2
|
||||
|
||||
class nsUXThemeData {
|
||||
static HMODULE sThemeDLL;
|
||||
@ -107,11 +113,18 @@ public:
|
||||
static PRPackedBool sIsXPOrLater;
|
||||
static PRPackedBool sIsVistaOrLater;
|
||||
static PRPackedBool sHaveCompositor;
|
||||
static PRBool sTitlebarInfoPopulated;
|
||||
static SIZE sCommandButtons[3];
|
||||
|
||||
static void Initialize();
|
||||
static void Teardown();
|
||||
static void Invalidate();
|
||||
static HANDLE GetTheme(nsUXThemeClass cls);
|
||||
|
||||
// nsWindow calls this to update desktop settings info
|
||||
static void InitTitlebarInfo();
|
||||
static void UpdateTitlebarInfo(TITLEBARINFOEX& info);
|
||||
|
||||
static inline BOOL IsAppThemed() {
|
||||
return isAppThemed && isAppThemed();
|
||||
}
|
||||
|
@ -157,6 +157,7 @@
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsNativeThemeWin.h"
|
||||
|
||||
#if defined(WINCE)
|
||||
#include "nsWindowCE.h"
|
||||
@ -414,29 +415,34 @@ nsWindow::nsWindow() : nsBaseWidget()
|
||||
// Global initialization
|
||||
if (!sInstanceCount) {
|
||||
#if !defined(WINCE)
|
||||
gKbdLayout.LoadLayout(::GetKeyboardLayout(0));
|
||||
gKbdLayout.LoadLayout(::GetKeyboardLayout(0));
|
||||
#endif
|
||||
|
||||
// Init IME handler
|
||||
nsIMM32Handler::Initialize();
|
||||
// Init IME handler
|
||||
nsIMM32Handler::Initialize();
|
||||
|
||||
#ifdef NS_ENABLE_TSF
|
||||
nsTextStore::Initialize();
|
||||
nsTextStore::Initialize();
|
||||
#endif
|
||||
|
||||
#if !defined(WINCE)
|
||||
if (SUCCEEDED(::OleInitialize(NULL)))
|
||||
sIsOleInitialized = TRUE;
|
||||
NS_ASSERTION(sIsOleInitialized, "***** OLE is not initialized!\n");
|
||||
if (SUCCEEDED(::OleInitialize(NULL)))
|
||||
sIsOleInitialized = TRUE;
|
||||
NS_ASSERTION(sIsOleInitialized, "***** OLE is not initialized!\n");
|
||||
#endif
|
||||
|
||||
#if defined(HEAP_DUMP_EVENT)
|
||||
InitHeapDump();
|
||||
InitHeapDump();
|
||||
#endif
|
||||
|
||||
#if !defined(WINCE)
|
||||
InitTrackPointHack();
|
||||
InitTrackPointHack();
|
||||
#endif
|
||||
|
||||
// Init titlebar button info for custom frames.
|
||||
if (GetWindowsVersion() >= VISTA_VERSION) {
|
||||
nsUXThemeData::InitTitlebarInfo();
|
||||
}
|
||||
} // !sInstanceCount
|
||||
|
||||
mIdleService = nsnull;
|
||||
@ -1228,6 +1234,16 @@ NS_METHOD nsWindow::Show(PRBool bState)
|
||||
Invalidate(PR_FALSE);
|
||||
#endif
|
||||
|
||||
// Update titlebar metric info when the window is shown.
|
||||
if (!nsUXThemeData::sTitlebarInfoPopulated && bState &&
|
||||
GetWindowsVersion() >= VISTA_VERSION &&
|
||||
(mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog) &&
|
||||
(mBorderStyle == eBorderStyle_default || mBorderStyle == eBorderStyle_all)) {
|
||||
TITLEBARINFOEX info = {0};
|
||||
info.cbSize = sizeof(TITLEBARINFOEX);
|
||||
SendMessage(mWnd, WM_GETTITLEBARINFOEX, 0, (LPARAM)&info);
|
||||
nsUXThemeData::UpdateTitlebarInfo(info);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,7 @@ public:
|
||||
WNDPROC GetPrevWindowProc() { return mPrevWndProc; }
|
||||
static nsWindow* GetNSWindowPtr(HWND aWnd);
|
||||
WindowHook& GetWindowHook() { return mWindowHook; }
|
||||
nsWindow* GetParentWindow(PRBool aIncludeOwner);
|
||||
|
||||
/**
|
||||
* Misc.
|
||||
@ -297,7 +298,6 @@ protected:
|
||||
static BOOL SetNSWindowPtr(HWND aWnd, nsWindow * ptr);
|
||||
LPARAM lParamToScreen(LPARAM lParam);
|
||||
LPARAM lParamToClient(LPARAM lParam);
|
||||
nsWindow* GetParentWindow(PRBool aIncludeOwner);
|
||||
virtual void SubclassWindow(BOOL bState);
|
||||
PRBool CanTakeFocus();
|
||||
PRBool UpdateNonClientMargins(PRInt32 aSizeMode = -1, PRBool aReflowWindow = PR_TRUE);
|
||||
|
@ -394,6 +394,7 @@ EventMsgInfo gAllEvents[] = {
|
||||
{"WM_TABLET_QUERYSYSTEMGESTURESTATUS", 0x02CC},
|
||||
{"WM_GESTURE", 0x0119},
|
||||
{"WM_GESTURENOTIFY", 0x011A},
|
||||
{"WM_GETTITLEBARINFOEX", 0x033F},
|
||||
{NULL, 0x0}
|
||||
};
|
||||
|
||||
|
@ -110,6 +110,14 @@
|
||||
|
||||
#define FAPPCOMMAND_MASK 0xF000
|
||||
|
||||
#ifndef WM_GETTITLEBARINFOEX
|
||||
#define WM_GETTITLEBARINFOEX 0x033F
|
||||
#endif
|
||||
|
||||
#ifndef CCHILDREN_TITLEBAR
|
||||
#define CCHILDREN_TITLEBAR 5
|
||||
#endif
|
||||
|
||||
#ifndef APPCOMMAND_BROWSER_BACKWARD
|
||||
#define APPCOMMAND_BROWSER_BACKWARD 1
|
||||
#define APPCOMMAND_BROWSER_FORWARD 2
|
||||
@ -172,8 +180,6 @@
|
||||
#define MOUSE_INPUT_SOURCE() nsIDOMNSMouseEvent::MOZ_SOURCE_MOUSE
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* SECTION: enums
|
||||
@ -259,6 +265,16 @@ struct KeyPair {
|
||||
: mGeneral(PRUint8(aGeneral)), mSpecific(PRUint8(aSpecific)) {}
|
||||
};
|
||||
|
||||
#ifndef TITLEBARINFOEX
|
||||
struct TITLEBARINFOEX
|
||||
{
|
||||
DWORD cbSize;
|
||||
RECT rcTitleBar;
|
||||
DWORD rgstate[CCHILDREN_TITLEBAR + 1];
|
||||
RECT rgrect[CCHILDREN_TITLEBAR + 1];
|
||||
};
|
||||
#endif
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* SECTION: macros
|
||||
|
Loading…
Reference in New Issue
Block a user