Bug 574454 - Theme code for caption button box, content padding. r=vlad.

This commit is contained in:
Jim Mathies 2010-08-09 20:49:35 -05:00
parent edeba94749
commit 597d3e4c58
4 changed files with 106 additions and 24 deletions

View File

@ -139,8 +139,11 @@ static PRInt32 GetTopLevelWindowActiveState(nsIFrame *aFrame)
static PRInt32 GetWindowFrameButtonState(nsIFrame *aFrame, PRInt32 eventState) static PRInt32 GetWindowFrameButtonState(nsIFrame *aFrame, PRInt32 eventState)
{ {
if (GetTopLevelWindowActiveState(aFrame) == if (GetTopLevelWindowActiveState(aFrame) ==
mozilla::widget::themeconst::FS_INACTIVE) mozilla::widget::themeconst::FS_INACTIVE) {
if (eventState & NS_EVENT_STATE_HOVER)
return mozilla::widget::themeconst::BS_HOT;
return mozilla::widget::themeconst::BS_INACTIVE; return mozilla::widget::themeconst::BS_INACTIVE;
}
if (eventState & NS_EVENT_STATE_ACTIVE) if (eventState & NS_EVENT_STATE_ACTIVE)
return mozilla::widget::themeconst::BS_PUSHED; return mozilla::widget::themeconst::BS_PUSHED;
@ -160,6 +163,22 @@ static PRInt32 GetClassicWindowFrameButtonState(PRInt32 eventState)
return DFCS_BUTTONPUSH; return DFCS_BUTTONPUSH;
} }
static void QueryForButtonData(nsIFrame *aFrame)
{
if (nsUXThemeData::sTitlebarInfoPopulated)
return;
nsIWidget* widget = aFrame->GetNearestWidget();
nsWindow * window = static_cast<nsWindow*>(widget);
if (!window)
return;
if (!window->IsTopLevelWidget() &&
!(window = window->GetParentWindow(PR_FALSE)))
return;
nsUXThemeData::UpdateTitlebarInfo(window->GetWindowHandle());
}
nsNativeThemeWin::nsNativeThemeWin() { nsNativeThemeWin::nsNativeThemeWin() {
// If there is a relevant change in forms.css for windows platform, // If there is a relevant change in forms.css for windows platform,
// static widget style variables (e.g. sButtonBorderSize) should be // static widget style variables (e.g. sButtonBorderSize) should be
@ -415,6 +434,8 @@ nsNativeThemeWin::GetTheme(PRUint8 aWidgetType)
case NS_THEME_WINDOW_BUTTON_MINIMIZE: case NS_THEME_WINDOW_BUTTON_MINIMIZE:
case NS_THEME_WINDOW_BUTTON_MAXIMIZE: case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
case NS_THEME_WINDOW_BUTTON_RESTORE: case NS_THEME_WINDOW_BUTTON_RESTORE:
case NS_THEME_WINDOW_BUTTON_BOX:
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
return nsUXThemeData::GetTheme(eUXWindowFrame); return nsUXThemeData::GetTheme(eUXWindowFrame);
} }
return NULL; return NULL;
@ -1062,6 +1083,11 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
aPart = mozilla::widget::themeconst::WP_RESTOREBUTTON; aPart = mozilla::widget::themeconst::WP_RESTOREBUTTON;
aState = GetWindowFrameButtonState(aFrame, GetContentState(aFrame, aWidgetType)); aState = GetWindowFrameButtonState(aFrame, GetContentState(aFrame, aWidgetType));
return NS_OK; return NS_OK;
case NS_THEME_WINDOW_BUTTON_BOX:
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
aPart = -1;
aState = 0;
return NS_OK;
} }
aPart = 0; aPart = 0;
@ -1499,6 +1525,53 @@ nsNativeThemeWin::GetWidgetPadding(nsIDeviceContext* aContext,
} }
HANDLE theme = GetTheme(aWidgetType); HANDLE theme = GetTheme(aWidgetType);
if (aWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) {
aResult->SizeTo(0, 0, 0, 0);
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
// aero glass doesn't display custom buttons
if (nsUXThemeData::CheckForCompositor())
return PR_TRUE;
#endif
// button padding for standard windows
if (aWidgetType == NS_THEME_WINDOW_BUTTON_BOX) {
aResult->top = GetSystemMetrics(SM_CXFRAME);
if (nsUXThemeData::sIsVistaOrLater) {
aResult->right += 2;
} else {
aResult->right += 1;
}
}
// Adjust horizontal button padding for maximized windows on XP
if (aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED &&
!nsUXThemeData::sIsVistaOrLater) {
aResult->right += 1;
}
// Push buttons down
if (theme) {
aResult->top += 1;
} else {
aResult->top += 2;
}
return PR_TRUE;
}
// Content padding
if (aWidgetType == NS_THEME_WINDOW_TITLEBAR ||
aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED) {
aResult->SizeTo(0, 0, 0, 0);
// Maximized windows have an offscreen offset equal to
// the border padding. (windows quirk)
if (aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED)
aResult->top = GetSystemMetrics(SM_CXFRAME);
return PR_TRUE;
}
if (!theme) if (!theme)
return PR_FALSE; return PR_FALSE;
@ -1760,30 +1833,39 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame*
case NS_THEME_WINDOW_BUTTON_MAXIMIZE: case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
case NS_THEME_WINDOW_BUTTON_RESTORE: 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 // 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 // window w/buttons when it's visible. nsWindow takes care of this and
// stores that info in nsUXThemeData. // stores that info in nsUXThemeData.
QueryForButtonData(aFrame);
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cx; aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cx;
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cy; aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cy;
// For XP, subtract 4 from system metrics dimensions.
if (nsWindow::GetWindowsVersion() == WINXP_VERSION) {
aResult->width -= 4;
aResult->height -= 4;
}
*aIsOverridable = PR_FALSE; *aIsOverridable = PR_FALSE;
return NS_OK; return NS_OK;
case NS_THEME_WINDOW_BUTTON_MINIMIZE: case NS_THEME_WINDOW_BUTTON_MINIMIZE:
if (nsWindow::GetWindowsVersion() < VISTA_VERSION) QueryForButtonData(aFrame);
break;
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx; aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx;
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy; aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy;
if (nsWindow::GetWindowsVersion() == WINXP_VERSION) {
aResult->width -= 4;
aResult->height -= 4;
}
*aIsOverridable = PR_FALSE; *aIsOverridable = PR_FALSE;
return NS_OK; return NS_OK;
case NS_THEME_WINDOW_BUTTON_CLOSE: case NS_THEME_WINDOW_BUTTON_CLOSE:
if (nsWindow::GetWindowsVersion() < VISTA_VERSION) QueryForButtonData(aFrame);
break;
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx; aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx;
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy; aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy;
if (nsWindow::GetWindowsVersion() == WINXP_VERSION) {
aResult->width -= 4;
aResult->height -= 4;
}
*aIsOverridable = PR_FALSE; *aIsOverridable = PR_FALSE;
return NS_OK; return NS_OK;
@ -2068,6 +2150,8 @@ nsNativeThemeWin::ClassicThemeSupportsWidget(nsPresContext* aPresContext,
case NS_THEME_WINDOW_BUTTON_MINIMIZE: case NS_THEME_WINDOW_BUTTON_MINIMIZE:
case NS_THEME_WINDOW_BUTTON_MAXIMIZE: case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
case NS_THEME_WINDOW_BUTTON_RESTORE: case NS_THEME_WINDOW_BUTTON_RESTORE:
case NS_THEME_WINDOW_BUTTON_BOX:
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
return PR_TRUE; return PR_TRUE;
} }
return PR_FALSE; return PR_FALSE;

View File

@ -170,6 +170,8 @@ nsUXThemeData::Invalidate() {
// shall give WIN2K special treatment // shall give WIN2K special treatment
sFlatMenus = PR_FALSE; sFlatMenus = PR_FALSE;
} }
// Refresh titlebar button info
sTitlebarInfoPopulated = PR_FALSE;
} }
HANDLE HANDLE
@ -244,15 +246,23 @@ nsUXThemeData::InitTitlebarInfo()
sCommandButtons[0].cy = GetSystemMetrics(SM_CYSIZE); sCommandButtons[0].cy = GetSystemMetrics(SM_CYSIZE);
sCommandButtons[1].cx = sCommandButtons[2].cx = sCommandButtons[0].cx; sCommandButtons[1].cx = sCommandButtons[2].cx = sCommandButtons[0].cx;
sCommandButtons[1].cy = sCommandButtons[2].cy = sCommandButtons[0].cy; sCommandButtons[1].cy = sCommandButtons[2].cy = sCommandButtons[0].cy;
// Use system metrics for pre-vista
if (nsWindow::GetWindowsVersion() < VISTA_VERSION)
sTitlebarInfoPopulated = PR_TRUE;
} }
// static // static
void void
nsUXThemeData::UpdateTitlebarInfo(TITLEBARINFOEX& info) nsUXThemeData::UpdateTitlebarInfo(HWND aWnd)
{ {
if (sTitlebarInfoPopulated) if (sTitlebarInfoPopulated || !aWnd)
return; return;
TITLEBARINFOEX info = {0};
info.cbSize = sizeof(TITLEBARINFOEX);
SendMessage(aWnd, WM_GETTITLEBARINFOEX, 0, (LPARAM)&info);
// Only set if we have valid data for all three buttons we use. // Only set if we have valid data for all three buttons we use.
if ((info.rgrect[2].right - info.rgrect[2].left) == 0 || if ((info.rgrect[2].right - info.rgrect[2].left) == 0 ||
(info.rgrect[3].right - info.rgrect[3].left) == 0 || (info.rgrect[3].right - info.rgrect[3].left) == 0 ||

View File

@ -123,7 +123,7 @@ public:
// nsWindow calls this to update desktop settings info // nsWindow calls this to update desktop settings info
static void InitTitlebarInfo(); static void InitTitlebarInfo();
static void UpdateTitlebarInfo(TITLEBARINFOEX& info); static void UpdateTitlebarInfo(HWND aWnd);
static inline BOOL IsAppThemed() { static inline BOOL IsAppThemed() {
return isAppThemed && isAppThemed(); return isAppThemed && isAppThemed();

View File

@ -440,9 +440,7 @@ nsWindow::nsWindow() : nsBaseWidget()
#endif #endif
// Init titlebar button info for custom frames. // Init titlebar button info for custom frames.
if (GetWindowsVersion() >= VISTA_VERSION) { nsUXThemeData::InitTitlebarInfo();
nsUXThemeData::InitTitlebarInfo();
}
} // !sInstanceCount } // !sInstanceCount
mIdleService = nsnull; mIdleService = nsnull;
@ -1234,16 +1232,6 @@ NS_METHOD nsWindow::Show(PRBool bState)
Invalidate(PR_FALSE); Invalidate(PR_FALSE);
#endif #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; return NS_OK;
} }