2006-02-09 01:24:30 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2005-08-20 07:11:56 +00:00
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2005-08-20 07:13:53 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
2005-08-20 07:11:56 +00:00
|
|
|
*
|
2005-08-20 07:13:53 +00:00
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
2005-08-20 07:11:56 +00:00
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
2005-08-20 07:13:53 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* David Hyatt (hyatt@netscape.com).
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2001
|
2005-08-20 07:11:56 +00:00
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2005-08-20 07:13:11 +00:00
|
|
|
* Tim Hill (tim@prismelite.com)
|
2005-10-07 00:31:36 +00:00
|
|
|
* James Ross (silver@warwickcompsoc.co.uk)
|
2007-07-14 15:11:37 +00:00
|
|
|
* Simon Bünzli (zeniko@gmail.com)
|
2005-08-20 07:11:56 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2005-08-20 07:13:53 +00:00
|
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
2005-08-20 07:11:56 +00:00
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
2005-08-20 07:13:53 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2005-08-20 07:11:56 +00:00
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
2005-08-20 07:13:53 +00:00
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2005-08-20 07:11:56 +00:00
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
#include "nsNativeThemeWin.h"
|
2005-08-23 02:11:54 +00:00
|
|
|
#include "nsIRenderingContext.h"
|
|
|
|
#include "nsIDeviceContext.h"
|
2005-08-20 07:11:56 +00:00
|
|
|
#include "nsRect.h"
|
|
|
|
#include "nsSize.h"
|
|
|
|
#include "nsTransform2D.h"
|
|
|
|
#include "nsThemeConstants.h"
|
|
|
|
#include "nsIPresShell.h"
|
2005-08-20 07:14:04 +00:00
|
|
|
#include "nsPresContext.h"
|
2005-08-20 07:11:56 +00:00
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIFrame.h"
|
|
|
|
#include "nsIEventStateManager.h"
|
|
|
|
#include "nsINameSpaceManager.h"
|
|
|
|
#include "nsILookAndFeel.h"
|
2005-08-20 07:12:55 +00:00
|
|
|
#include "nsIDOMHTMLInputElement.h"
|
2005-08-20 07:12:08 +00:00
|
|
|
#include "nsIMenuFrame.h"
|
2006-06-09 06:02:30 +00:00
|
|
|
#include "nsWidgetAtoms.h"
|
2005-08-20 07:11:57 +00:00
|
|
|
#include <malloc.h>
|
2007-08-17 20:47:33 +00:00
|
|
|
#include "nsWindow.h"
|
2008-03-06 00:23:38 +00:00
|
|
|
#include "nsIComboboxControlFrame.h"
|
2005-08-20 07:11:56 +00:00
|
|
|
|
2007-08-06 17:45:57 +00:00
|
|
|
#include "gfxPlatform.h"
|
2005-10-06 04:02:10 +00:00
|
|
|
#include "gfxContext.h"
|
|
|
|
#include "gfxMatrix.h"
|
2006-04-04 21:54:22 +00:00
|
|
|
#include "gfxWindowsSurface.h"
|
2007-03-03 00:18:34 +00:00
|
|
|
#include "gfxWindowsNativeDrawing.h"
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
#include "nsUXThemeData.h"
|
|
|
|
#include "nsUXThemeConstants.h"
|
2005-10-07 00:31:36 +00:00
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(nsNativeThemeWin, nsITheme)
|
|
|
|
|
2009-01-05 18:17:44 +00:00
|
|
|
#ifdef WINCE
|
2009-02-10 23:10:07 +00:00
|
|
|
|
|
|
|
/* These functions might or might not be present; FrameRect probably isn't,
|
|
|
|
* but GetViewportOrgEx might be -- so #define them to avoid name collisions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define FrameRect moz_FrameRect
|
|
|
|
#define GetViewportOrgEx moz_GetViewportOrgEx
|
|
|
|
|
2009-01-05 18:17:44 +00:00
|
|
|
static int FrameRect(HDC inDC, CONST RECT *inRect, HBRUSH inBrush)
|
|
|
|
{
|
|
|
|
HBRUSH oldBrush = (HBRUSH)SelectObject(inDC, inBrush);
|
|
|
|
RECT myRect = *inRect;
|
|
|
|
InflateRect(&myRect, 1, 1);
|
|
|
|
|
|
|
|
// The width and height of the border are always one
|
|
|
|
// logical unit.
|
2009-02-10 23:10:07 +00:00
|
|
|
|
|
|
|
// move to top-left, and go clockwise.
|
2009-01-05 18:17:44 +00:00
|
|
|
MoveToEx(inDC, myRect.left, myRect.top, (LPPOINT) NULL);
|
|
|
|
// 1 -> 2
|
|
|
|
LineTo(inDC, myRect.right, myRect.top);
|
|
|
|
// 2 -> 3
|
|
|
|
LineTo(inDC, myRect.right, myRect.bottom);
|
|
|
|
// 3 -> 4
|
|
|
|
LineTo(inDC, myRect.left, myRect.bottom);
|
2009-02-10 23:10:07 +00:00
|
|
|
// 4 -> 1
|
|
|
|
LineTo(inDC, myRect.left, myRect.top);
|
|
|
|
|
2009-01-05 18:17:44 +00:00
|
|
|
SelectObject(inDC, oldBrush);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-02-10 23:10:07 +00:00
|
|
|
static BOOL
|
|
|
|
GetViewportOrgEx(HDC hdc, LPPOINT lpPoint)
|
|
|
|
{
|
|
|
|
SetViewportOrgEx(hdc, 0, 0, lpPoint);
|
|
|
|
if (lpPoint->x != 0 || lpPoint->y != 0)
|
|
|
|
SetViewportOrgEx(hdc, lpPoint->x, lpPoint->y, NULL);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2009-01-05 18:17:44 +00:00
|
|
|
#endif
|
|
|
|
|
2008-02-29 05:10:12 +00:00
|
|
|
static inline bool IsHTMLContent(nsIFrame *frame)
|
|
|
|
{
|
|
|
|
nsIContent* content = frame->GetContent();
|
2009-08-24 20:02:07 +00:00
|
|
|
return content && content->IsHTML();
|
2008-02-29 05:10:12 +00:00
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
nsNativeThemeWin::nsNativeThemeWin() {
|
2005-08-20 07:14:17 +00:00
|
|
|
// If there is a relevant change in forms.css for windows platform,
|
2005-08-20 07:13:56 +00:00
|
|
|
// static widget style variables (e.g. sButtonBorderSize) should be
|
|
|
|
// reinitialized here.
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsNativeThemeWin::~nsNativeThemeWin() {
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::Invalidate();
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
|
2009-01-15 03:27:09 +00:00
|
|
|
static void GetNativeRect(const nsIntRect& aSrc, RECT& aDst)
|
2005-08-20 07:11:56 +00:00
|
|
|
{
|
|
|
|
aDst.top = aSrc.y;
|
|
|
|
aDst.bottom = aSrc.y + aSrc.height;
|
|
|
|
aDst.left = aSrc.x;
|
|
|
|
aDst.right = aSrc.x + aSrc.width;
|
|
|
|
}
|
|
|
|
|
2007-08-06 17:45:57 +00:00
|
|
|
static PRBool IsTopLevelMenu(nsIFrame *aFrame)
|
|
|
|
{
|
|
|
|
PRBool isTopLevel(PR_FALSE);
|
2009-01-12 19:20:59 +00:00
|
|
|
nsIMenuFrame *menuFrame = do_QueryFrame(aFrame);
|
2007-08-06 17:45:57 +00:00
|
|
|
if (menuFrame) {
|
|
|
|
isTopLevel = menuFrame->IsOnMenuBar();
|
|
|
|
}
|
|
|
|
return isTopLevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SIZE GetCheckboxSize(HANDLE theme, HDC hdc)
|
|
|
|
{
|
|
|
|
SIZE checkboxSize;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPCHECK, MC_CHECKMARKNORMAL, NULL, TS_TRUE, &checkboxSize);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
MARGINS checkboxSizing;
|
|
|
|
MARGINS checkboxContent;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_SIZINGMARGINS, NULL, &checkboxSizing);
|
|
|
|
nsUXThemeData::getThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_CONTENTMARGINS, NULL, &checkboxContent);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
int leftMargin = checkboxSizing.cxLeftWidth;
|
|
|
|
int rightMargin = checkboxSizing.cxRightWidth;
|
|
|
|
int topMargin = checkboxSizing.cyTopHeight;
|
|
|
|
int bottomMargin = checkboxSizing.cyBottomHeight;
|
|
|
|
|
|
|
|
int width = leftMargin + checkboxSize.cx + rightMargin;
|
|
|
|
int height = topMargin + checkboxSize.cy + bottomMargin;
|
|
|
|
SIZE ret;
|
|
|
|
ret.cx = width;
|
|
|
|
ret.cy = height;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
static SIZE GetCheckboxBounds(HANDLE theme, HDC hdc)
|
|
|
|
{
|
|
|
|
MARGINS checkboxSizing;
|
|
|
|
MARGINS checkboxContent;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_SIZINGMARGINS, NULL, &checkboxSizing);
|
|
|
|
nsUXThemeData::getThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_CONTENTMARGINS, NULL, &checkboxContent);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
#define posdx(d) ((d) > 0 ? d : 0)
|
|
|
|
|
|
|
|
int dx = posdx(checkboxContent.cxRightWidth - checkboxSizing.cxRightWidth) + posdx(checkboxContent.cxLeftWidth - checkboxSizing.cxLeftWidth);
|
|
|
|
int dy = posdx(checkboxContent.cyTopHeight - checkboxSizing.cyTopHeight) + posdx(checkboxContent.cyBottomHeight - checkboxSizing.cyBottomHeight);
|
|
|
|
|
|
|
|
#undef posdx
|
|
|
|
|
|
|
|
SIZE ret(GetCheckboxSize(theme,hdc));
|
|
|
|
ret.cx += dx;
|
|
|
|
ret.cy += dy;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
static SIZE GetGutterSize(HANDLE theme, HDC hdc)
|
|
|
|
{
|
|
|
|
SIZE gutterSize;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPGUTTER, 0, NULL, TS_TRUE, &gutterSize);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
SIZE checkboxSize(GetCheckboxBounds(theme, hdc));
|
|
|
|
|
|
|
|
SIZE itemSize;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPITEM, MPI_NORMAL, NULL, TS_TRUE, &itemSize);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
2007-11-28 22:37:40 +00:00
|
|
|
int width = PR_MAX(itemSize.cx, checkboxSize.cx + gutterSize.cx);
|
|
|
|
int height = PR_MAX(itemSize.cy, checkboxSize.cy);
|
2007-08-06 17:45:57 +00:00
|
|
|
SIZE ret;
|
|
|
|
ret.cx = width;
|
|
|
|
ret.cy = height;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-07-18 20:50:21 +00:00
|
|
|
static HRESULT DrawThemeBGRTLAware(HANDLE theme, HDC hdc, int part, int state,
|
|
|
|
const RECT *widgetRect, const RECT *clipRect,
|
|
|
|
PRBool isRTL)
|
|
|
|
{
|
|
|
|
/* Some widgets are not direction-neutral and need to be drawn reversed for
|
|
|
|
* RTL. Windows provides a way to do this with SetLayout, but this reverses
|
|
|
|
* the entire drawing area of a given device context, which means that its
|
|
|
|
* use will also affect the positioning of the widget. There are two ways
|
|
|
|
* to work around this:
|
|
|
|
*
|
|
|
|
* Option 1: Alter the position of the rect that we send so that we cancel
|
|
|
|
* out the positioning effects of SetLayout
|
|
|
|
* Option 2: Create a memory DC with the widgetRect's dimensions, draw onto
|
|
|
|
* that, and then transfer the results back to our DC
|
|
|
|
*
|
|
|
|
* This function tries to implement option 1, under the assumption that the
|
|
|
|
* correct way to reverse the effects of SetLayout is to translate the rect
|
|
|
|
* such that the offset from the DC bitmap's left edge to the old rect's
|
|
|
|
* left edge is equal to the offset from the DC bitmap's right edge to the
|
|
|
|
* new rect's right edge. In other words,
|
|
|
|
* (oldRect.left + vpOrg.x) == ((dcBMP.width - vpOrg.x) - newRect.right)
|
|
|
|
*
|
|
|
|
* I am not 100% sure that this is the correct approach, but I have yet to
|
|
|
|
* find a problem with it.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (isRTL) {
|
|
|
|
HGDIOBJ hObj = GetCurrentObject(hdc, OBJ_BITMAP);
|
|
|
|
BITMAP bitmap;
|
|
|
|
POINT vpOrg;
|
|
|
|
|
|
|
|
if (hObj &&
|
|
|
|
GetObject(hObj, sizeof(bitmap), &bitmap) &&
|
|
|
|
GetViewportOrgEx(hdc, &vpOrg))
|
|
|
|
{
|
|
|
|
RECT newWRect(*widgetRect);
|
|
|
|
newWRect.left = bitmap.bmWidth - (widgetRect->right + 2*vpOrg.x);
|
|
|
|
newWRect.right = bitmap.bmWidth - (widgetRect->left + 2*vpOrg.x);
|
|
|
|
|
|
|
|
RECT newCRect;
|
|
|
|
RECT *newCRectPtr = NULL;
|
|
|
|
|
|
|
|
if (clipRect) {
|
|
|
|
newCRect.top = clipRect->top;
|
|
|
|
newCRect.bottom = clipRect->bottom;
|
|
|
|
newCRect.left = bitmap.bmWidth - (clipRect->right + 2*vpOrg.x);
|
|
|
|
newCRect.right = bitmap.bmWidth - (clipRect->left + 2*vpOrg.x);
|
|
|
|
newCRectPtr = &newCRect;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLayout(hdc, LAYOUT_RTL);
|
|
|
|
HRESULT hr = nsUXThemeData::drawThemeBG(theme, hdc, part, state, &newWRect, newCRectPtr);
|
|
|
|
SetLayout(hdc, 0);
|
|
|
|
|
|
|
|
if (hr == S_OK)
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw normally if LTR or if anything went wrong
|
|
|
|
return nsUXThemeData::drawThemeBG(theme, hdc, part, state, widgetRect, clipRect);
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
HANDLE
|
|
|
|
nsNativeThemeWin::GetTheme(PRUint8 aWidgetType)
|
2005-08-20 07:12:56 +00:00
|
|
|
{
|
2008-07-17 17:19:10 +00:00
|
|
|
if (!nsUXThemeData::sIsVistaOrLater) {
|
2008-04-25 23:12:45 +00:00
|
|
|
// On XP or earlier, render dropdowns as textfields;
|
|
|
|
// doing it the right way works fine with the MS themes,
|
|
|
|
// but breaks on a lot of custom themes (presumably because MS
|
|
|
|
// apps do the textfield border business as well).
|
|
|
|
if (aWidgetType == NS_THEME_DROPDOWN)
|
|
|
|
aWidgetType = NS_THEME_TEXTFIELD;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
case NS_THEME_RADIO:
|
2007-05-09 19:17:17 +00:00
|
|
|
case NS_THEME_CHECKBOX:
|
2009-03-12 02:11:01 +00:00
|
|
|
case NS_THEME_GROUPBOX:
|
2008-07-17 17:19:10 +00:00
|
|
|
return nsUXThemeData::GetTheme(eUXButton);
|
2005-08-20 07:12:07 +00:00
|
|
|
case NS_THEME_TEXTFIELD:
|
2008-07-17 17:19:10 +00:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
|
|
|
return nsUXThemeData::GetTheme(eUXEdit);
|
|
|
|
case NS_THEME_TOOLTIP:
|
2008-05-08 15:17:23 +00:00
|
|
|
// BUG #161600: XP/2K3 should force a classic treatment of tooltips
|
2008-07-17 17:19:10 +00:00
|
|
|
return nsUXThemeData::sIsVistaOrLater ? nsUXThemeData::GetTheme(eUXTooltip) : NULL;
|
|
|
|
case NS_THEME_TOOLBOX:
|
|
|
|
return nsUXThemeData::GetTheme(eUXRebar);
|
|
|
|
case NS_THEME_WIN_MEDIA_TOOLBOX:
|
|
|
|
return nsUXThemeData::GetTheme(eUXMediaRebar);
|
|
|
|
case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX:
|
|
|
|
return nsUXThemeData::GetTheme(eUXCommunicationsRebar);
|
|
|
|
case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX:
|
|
|
|
return nsUXThemeData::GetTheme(eUXBrowserTabBarRebar);
|
2005-08-20 07:11:56 +00:00
|
|
|
case NS_THEME_TOOLBAR:
|
2007-08-25 20:30:43 +00:00
|
|
|
case NS_THEME_TOOLBAR_BUTTON:
|
2008-07-17 17:19:10 +00:00
|
|
|
case NS_THEME_TOOLBAR_SEPARATOR:
|
|
|
|
return nsUXThemeData::GetTheme(eUXToolbar);
|
2005-08-20 07:11:59 +00:00
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
2008-07-17 17:19:10 +00:00
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
return nsUXThemeData::GetTheme(eUXProgress);
|
2005-08-20 07:11:56 +00:00
|
|
|
case NS_THEME_TAB:
|
2005-08-20 07:12:02 +00:00
|
|
|
case NS_THEME_TAB_PANEL:
|
2008-07-17 17:19:10 +00:00
|
|
|
case NS_THEME_TAB_PANELS:
|
|
|
|
return nsUXThemeData::GetTheme(eUXTab);
|
2005-08-20 07:11:56 +00:00
|
|
|
case NS_THEME_SCROLLBAR:
|
2007-07-13 21:46:28 +00:00
|
|
|
case NS_THEME_SCROLLBAR_SMALL:
|
2005-08-20 07:11:57 +00:00
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
2008-07-17 17:19:10 +00:00
|
|
|
return nsUXThemeData::GetTheme(eUXScrollbar);
|
2006-05-30 13:50:48 +00:00
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
2008-07-17 17:19:10 +00:00
|
|
|
return nsUXThemeData::GetTheme(eUXTrackbar);
|
2006-07-13 17:40:49 +00:00
|
|
|
case NS_THEME_SPINNER_UP_BUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
2008-07-17 17:19:10 +00:00
|
|
|
return nsUXThemeData::GetTheme(eUXSpin);
|
2005-08-20 07:11:57 +00:00
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
|
|
|
case NS_THEME_RESIZER:
|
2008-07-17 17:19:10 +00:00
|
|
|
return nsUXThemeData::GetTheme(eUXStatus);
|
2008-02-29 05:10:12 +00:00
|
|
|
case NS_THEME_DROPDOWN:
|
2008-07-17 17:19:10 +00:00
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
return nsUXThemeData::GetTheme(eUXCombobox);
|
2005-08-20 07:13:09 +00:00
|
|
|
case NS_THEME_TREEVIEW_HEADER_CELL:
|
2008-07-17 17:19:10 +00:00
|
|
|
case NS_THEME_TREEVIEW_HEADER_SORTARROW:
|
|
|
|
return nsUXThemeData::GetTheme(eUXHeader);
|
2005-08-20 07:12:55 +00:00
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_LISTBOX_LISTITEM:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_TREEVIEW_TWISTY_OPEN:
|
2008-07-17 17:19:10 +00:00
|
|
|
case NS_THEME_TREEVIEW_TREEITEM:
|
|
|
|
return nsUXThemeData::GetTheme(eUXListview);
|
2007-08-06 17:45:57 +00:00
|
|
|
case NS_THEME_MENUBAR:
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
case NS_THEME_MENUARROW:
|
|
|
|
case NS_THEME_MENUIMAGE:
|
|
|
|
case NS_THEME_MENUITEMTEXT:
|
2008-07-17 17:19:10 +00:00
|
|
|
return nsUXThemeData::GetTheme(eUXMenu);
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-02-29 05:10:12 +00:00
|
|
|
PRInt32
|
|
|
|
nsNativeThemeWin::StandardGetState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
|
|
|
PRBool wantFocused)
|
|
|
|
{
|
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
|
|
|
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
|
|
|
|
return TS_ACTIVE;
|
|
|
|
if (wantFocused && eventState & NS_EVENT_STATE_FOCUS)
|
|
|
|
return TS_FOCUSED;
|
|
|
|
if (eventState & NS_EVENT_STATE_HOVER)
|
|
|
|
return TS_HOVER;
|
|
|
|
|
|
|
|
return TS_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
2008-03-06 20:56:47 +00:00
|
|
|
nsNativeThemeWin::IsMenuActive(nsIFrame *aFrame, PRUint8 aWidgetType)
|
2008-02-29 05:10:12 +00:00
|
|
|
{
|
2009-07-25 13:10:17 +00:00
|
|
|
nsIContent* content = aFrame->GetContent();
|
2009-08-24 20:02:07 +00:00
|
|
|
if (content->IsXUL() &&
|
2009-07-25 13:10:17 +00:00
|
|
|
content->NodeInfo()->Equals(nsWidgetAtoms::richlistitem))
|
|
|
|
return CheckBooleanAttr(aFrame, nsWidgetAtoms::selected);
|
|
|
|
|
2008-03-06 20:56:47 +00:00
|
|
|
return CheckBooleanAttr(aFrame, nsWidgetAtoms::mozmenuactive);
|
2008-02-29 05:10:12 +00:00
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
nsresult
|
|
|
|
nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
|
|
|
PRInt32& aPart, PRInt32& aState)
|
|
|
|
{
|
2008-07-17 17:19:10 +00:00
|
|
|
if (!nsUXThemeData::sIsVistaOrLater) {
|
2008-04-25 23:12:45 +00:00
|
|
|
// See GetTheme
|
|
|
|
if (aWidgetType == NS_THEME_DROPDOWN)
|
|
|
|
aWidgetType = NS_THEME_TEXTFIELD;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON: {
|
2005-08-20 07:11:59 +00:00
|
|
|
aPart = BP_BUTTON;
|
2005-08-20 07:11:56 +00:00
|
|
|
if (!aFrame) {
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame)) {
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_DISABLED;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
2009-03-13 12:23:26 +00:00
|
|
|
} else if (IsOpenButton(aFrame) ||
|
|
|
|
IsCheckedButton(aFrame)) {
|
2008-07-12 09:15:07 +00:00
|
|
|
aState = TS_ACTIVE;
|
|
|
|
return NS_OK;
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
2008-02-29 05:10:12 +00:00
|
|
|
|
|
|
|
aState = StandardGetState(aFrame, aWidgetType, PR_TRUE);
|
2005-08-20 07:11:56 +00:00
|
|
|
|
2005-08-20 07:12:06 +00:00
|
|
|
// Check for default dialog buttons. These buttons should always look
|
|
|
|
// focused.
|
2005-08-20 07:13:56 +00:00
|
|
|
if (aState == TS_NORMAL && IsDefaultButton(aFrame))
|
2005-08-20 07:12:06 +00:00
|
|
|
aState = TS_FOCUSED;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_CHECKBOX:
|
2008-11-03 13:12:59 +00:00
|
|
|
case NS_THEME_RADIO: {
|
|
|
|
bool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
|
2007-05-09 19:17:17 +00:00
|
|
|
aPart = isCheckbox ? BP_CHECKBOX : BP_RADIO;
|
2005-08-20 07:12:47 +00:00
|
|
|
|
2009-02-05 08:17:08 +00:00
|
|
|
enum InputState {
|
|
|
|
UNCHECKED = 0, CHECKED, INDETERMINATE
|
|
|
|
};
|
|
|
|
InputState inputState = UNCHECKED;
|
2005-08-20 07:13:56 +00:00
|
|
|
PRBool isXULCheckboxRadio = PR_FALSE;
|
2009-02-05 08:17:08 +00:00
|
|
|
|
|
|
|
if (!aFrame) {
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2009-02-05 08:17:08 +00:00
|
|
|
} else {
|
|
|
|
if (GetCheckedOrSelected(aFrame, !isCheckbox)) {
|
|
|
|
inputState = CHECKED;
|
|
|
|
} if (isCheckbox && GetIndeterminate(aFrame)) {
|
|
|
|
inputState = INDETERMINATE;
|
2005-08-20 07:12:47 +00:00
|
|
|
}
|
|
|
|
|
2009-02-05 08:17:08 +00:00
|
|
|
if (IsDisabled(isXULCheckboxRadio ? aFrame->GetParent() : aFrame)) {
|
2005-08-20 07:12:08 +00:00
|
|
|
aState = TS_DISABLED;
|
2009-02-05 08:17:08 +00:00
|
|
|
} else {
|
2008-03-21 22:27:41 +00:00
|
|
|
aState = StandardGetState(aFrame, aWidgetType, PR_FALSE);
|
2005-08-20 07:12:08 +00:00
|
|
|
}
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
|
2009-02-05 08:17:08 +00:00
|
|
|
// 4 unchecked states, 4 checked states, 4 indeterminate states.
|
|
|
|
aState += inputState * 4;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2009-03-12 02:11:01 +00:00
|
|
|
case NS_THEME_GROUPBOX: {
|
|
|
|
aPart = BP_GROUPBOX;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
// Since we don't support groupbox disabled and GBS_DISABLED looks the
|
|
|
|
// same as GBS_NORMAL don't bother supporting GBS_DISABLED.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:12:07 +00:00
|
|
|
case NS_THEME_TEXTFIELD:
|
2008-02-29 05:10:12 +00:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE: {
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sIsVistaOrLater) {
|
2008-02-29 05:10:12 +00:00
|
|
|
/* Note: the NOSCROLL type has a rounded corner in each
|
|
|
|
* corner. The more specific HSCROLL, VSCROLL, HVSCROLL types
|
|
|
|
* have side and/or top/bottom edges rendered as straight
|
2009-01-11 19:13:26 +00:00
|
|
|
* horizontal lines with sharp corners to accommodate a
|
2008-02-29 05:10:12 +00:00
|
|
|
* scrollbar. However, the scrollbar gets rendered on top of
|
|
|
|
* this for us, so we don't care, and can just use NOSCROLL
|
|
|
|
* here.
|
|
|
|
*/
|
|
|
|
aPart = TFP_EDITBORDER_NOSCROLL;
|
2005-08-20 07:12:06 +00:00
|
|
|
|
2008-03-06 00:23:38 +00:00
|
|
|
if (!aFrame) {
|
|
|
|
aState = TFS_EDITBORDER_NORMAL;
|
|
|
|
} else if (IsDisabled(aFrame)) {
|
|
|
|
aState = TFS_EDITBORDER_DISABLED;
|
|
|
|
} else if (IsReadOnly(aFrame)) {
|
|
|
|
/* no special read-only state */
|
|
|
|
aState = TFS_EDITBORDER_NORMAL;
|
|
|
|
} else {
|
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
|
|
|
nsIContent* content = aFrame->GetContent();
|
|
|
|
|
|
|
|
/* XUL textboxes don't get focused themselves, because they have child
|
|
|
|
* html:input.. but we can check the XUL focused attributes on them
|
|
|
|
*/
|
2009-08-24 20:02:07 +00:00
|
|
|
if (content && content->IsXUL() && IsFocused(aFrame))
|
2008-03-06 00:23:38 +00:00
|
|
|
aState = TFS_EDITBORDER_FOCUSED;
|
|
|
|
else if (eventState & NS_EVENT_STATE_ACTIVE || eventState & NS_EVENT_STATE_FOCUS)
|
|
|
|
aState = TFS_EDITBORDER_FOCUSED;
|
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER)
|
|
|
|
aState = TFS_EDITBORDER_HOVER;
|
|
|
|
else
|
|
|
|
aState = TFS_EDITBORDER_NORMAL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
aPart = TFP_TEXTFIELD;
|
|
|
|
|
|
|
|
if (!aFrame)
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
else if (IsDisabled(aFrame))
|
|
|
|
aState = TS_DISABLED;
|
|
|
|
else if (IsReadOnly(aFrame))
|
|
|
|
aState = TFS_READONLY;
|
|
|
|
else
|
|
|
|
aState = StandardGetState(aFrame, aWidgetType, PR_TRUE);
|
2005-08-20 07:12:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:12:00 +00:00
|
|
|
case NS_THEME_TOOLTIP: {
|
|
|
|
aPart = TTP_STANDARD;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:11:59 +00:00
|
|
|
case NS_THEME_PROGRESSBAR: {
|
|
|
|
aPart = PP_BAR;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK: {
|
|
|
|
aPart = PP_CHUNK;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL: {
|
|
|
|
aPart = PP_BARVERT;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: {
|
|
|
|
aPart = PP_CHUNKVERT;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:11:56 +00:00
|
|
|
case NS_THEME_TOOLBAR_BUTTON: {
|
2005-08-20 07:11:59 +00:00
|
|
|
aPart = BP_BUTTON;
|
2005-08-20 07:11:56 +00:00
|
|
|
if (!aFrame) {
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame)) {
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_DISABLED;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2009-03-13 12:23:26 +00:00
|
|
|
if (IsOpenButton(aFrame)) {
|
|
|
|
aState = TS_ACTIVE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:13:56 +00:00
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
2005-08-20 07:11:56 +00:00
|
|
|
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_ACTIVE;
|
2005-08-20 07:14:26 +00:00
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER) {
|
|
|
|
if (IsCheckedButton(aFrame))
|
|
|
|
aState = TB_HOVER_CHECKED;
|
|
|
|
else
|
|
|
|
aState = TS_HOVER;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (IsCheckedButton(aFrame))
|
|
|
|
aState = TB_CHECKED;
|
|
|
|
else
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-08-25 20:30:43 +00:00
|
|
|
case NS_THEME_TOOLBAR_SEPARATOR: {
|
|
|
|
aPart = TP_SEPARATOR;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:11:57 +00:00
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT: {
|
2005-08-20 07:11:56 +00:00
|
|
|
aPart = SP_BUTTON;
|
2005-08-20 07:11:57 +00:00
|
|
|
aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP)*4;
|
2005-08-20 07:11:56 +00:00
|
|
|
if (!aFrame)
|
2005-08-20 07:11:59 +00:00
|
|
|
aState += TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
else if (IsDisabled(aFrame))
|
2005-08-20 07:11:59 +00:00
|
|
|
aState += TS_DISABLED;
|
2005-08-20 07:11:56 +00:00
|
|
|
else {
|
2005-08-20 07:13:56 +00:00
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
2007-08-17 20:47:33 +00:00
|
|
|
nsIFrame *parent = aFrame->GetParent();
|
|
|
|
PRInt32 parentState = GetContentState(parent, parent->GetStyleDisplay()->mAppearance);
|
2005-08-20 07:11:56 +00:00
|
|
|
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
|
2005-08-20 07:11:59 +00:00
|
|
|
aState += TS_ACTIVE;
|
2005-08-20 07:11:56 +00:00
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER)
|
2005-08-20 07:11:59 +00:00
|
|
|
aState += TS_HOVER;
|
2008-07-17 17:19:10 +00:00
|
|
|
else if (nsUXThemeData::sIsVistaOrLater && parentState & NS_EVENT_STATE_HOVER)
|
2007-08-17 20:47:33 +00:00
|
|
|
aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE;
|
2005-08-20 07:13:11 +00:00
|
|
|
else
|
2005-08-20 07:11:59 +00:00
|
|
|
aState += TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:11:57 +00:00
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL: {
|
|
|
|
aPart = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL) ?
|
|
|
|
SP_TRACKSTARTHOR : SP_TRACKSTARTVERT;
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:11:57 +00:00
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL: {
|
|
|
|
aPart = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) ?
|
|
|
|
SP_THUMBHOR : SP_THUMBVERT;
|
2005-08-20 07:11:56 +00:00
|
|
|
if (!aFrame)
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
else if (IsDisabled(aFrame))
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_DISABLED;
|
2005-08-20 07:11:56 +00:00
|
|
|
else {
|
2005-08-20 07:13:56 +00:00
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
2005-08-20 07:11:56 +00:00
|
|
|
if (eventState & NS_EVENT_STATE_ACTIVE) // Hover is not also a requirement for
|
|
|
|
// the thumb, since the drag is not canceled
|
|
|
|
// when you move outside the thumb.
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_ACTIVE;
|
2005-08-20 07:11:56 +00:00
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER)
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_HOVER;
|
2005-08-20 07:11:56 +00:00
|
|
|
else
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2006-05-30 13:50:48 +00:00
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_VERTICAL: {
|
|
|
|
aPart = (aWidgetType == NS_THEME_SCALE_HORIZONTAL) ?
|
|
|
|
TKP_TRACK : TKP_TRACKVERT;
|
|
|
|
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL: {
|
|
|
|
aPart = (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL) ?
|
|
|
|
TKP_THUMB : TKP_THUMBVERT;
|
|
|
|
if (!aFrame)
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
else if (IsDisabled(aFrame)) {
|
|
|
|
aState = TKP_DISABLED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
|
|
|
if (eventState & NS_EVENT_STATE_ACTIVE) // Hover is not also a requirement for
|
|
|
|
// the thumb, since the drag is not canceled
|
|
|
|
// when you move outside the thumb.
|
|
|
|
aState = TS_ACTIVE;
|
|
|
|
else if (eventState & NS_EVENT_STATE_FOCUS)
|
|
|
|
aState = TKP_FOCUSED;
|
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER)
|
|
|
|
aState = TS_HOVER;
|
|
|
|
else
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2006-07-13 17:40:49 +00:00
|
|
|
case NS_THEME_SPINNER_UP_BUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWN_BUTTON: {
|
|
|
|
aPart = (aWidgetType == NS_THEME_SPINNER_UP_BUTTON) ?
|
|
|
|
SPNP_UP : SPNP_DOWN;
|
|
|
|
if (!aFrame)
|
|
|
|
aState = TS_NORMAL;
|
2008-02-29 05:10:12 +00:00
|
|
|
else if (IsDisabled(aFrame))
|
2006-07-13 17:40:49 +00:00
|
|
|
aState = TS_DISABLED;
|
2008-02-29 05:10:12 +00:00
|
|
|
else
|
|
|
|
aState = StandardGetState(aFrame, aWidgetType, PR_FALSE);
|
2006-07-13 17:40:49 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:11:56 +00:00
|
|
|
case NS_THEME_TOOLBOX:
|
2008-05-08 09:29:38 +00:00
|
|
|
case NS_THEME_WIN_MEDIA_TOOLBOX:
|
|
|
|
case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX:
|
|
|
|
case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX:
|
2005-08-20 07:11:57 +00:00
|
|
|
case NS_THEME_STATUSBAR:
|
2007-07-13 21:46:28 +00:00
|
|
|
case NS_THEME_SCROLLBAR:
|
|
|
|
case NS_THEME_SCROLLBAR_SMALL: {
|
2008-02-29 05:10:38 +00:00
|
|
|
aState = 0;
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sIsVistaOrLater) {
|
2008-02-29 05:10:38 +00:00
|
|
|
// On vista, they have a part
|
|
|
|
aPart = RP_BACKGROUND;
|
|
|
|
} else {
|
|
|
|
// Otherwise, they don't. (But I bet
|
|
|
|
// RP_BACKGROUND would work here, too);
|
|
|
|
aPart = 0;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_TOOLBAR: {
|
|
|
|
// Use -1 to indicate we don't wish to have the theme background drawn
|
|
|
|
// for this item. We will pass any nessessary information via aState,
|
|
|
|
// and will render the item using separate code.
|
|
|
|
aPart = -1;
|
|
|
|
aState = 0;
|
|
|
|
if (aFrame) {
|
|
|
|
nsIContent* content = aFrame->GetContent();
|
|
|
|
nsIContent* parent = content->GetParent();
|
2007-07-14 15:11:37 +00:00
|
|
|
// XXXzeniko hiding the first toolbar will result in an unwanted margin
|
2005-10-07 00:31:36 +00:00
|
|
|
if (parent && parent->GetChildAt(0) == content) {
|
|
|
|
aState = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:11:57 +00:00
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
|
|
|
case NS_THEME_RESIZER: {
|
|
|
|
aPart = (aWidgetType - NS_THEME_STATUSBAR_PANEL) + 1;
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2005-08-20 07:11:57 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:12:55 +00:00
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_LISTBOX: {
|
|
|
|
aPart = TREEVIEW_BODY;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:12:02 +00:00
|
|
|
case NS_THEME_TAB_PANELS: {
|
|
|
|
aPart = TABP_PANELS;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_TAB_PANEL: {
|
|
|
|
aPart = TABP_PANEL;
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2009-01-04 14:01:48 +00:00
|
|
|
case NS_THEME_TAB: {
|
2005-08-20 07:11:56 +00:00
|
|
|
aPart = TABP_TAB;
|
|
|
|
if (!aFrame) {
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_NORMAL;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame)) {
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_DISABLED;
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:13:56 +00:00
|
|
|
if (IsSelectedTab(aFrame)) {
|
2005-08-20 07:11:56 +00:00
|
|
|
aPart = TABP_TAB_SELECTED;
|
2005-08-20 07:11:59 +00:00
|
|
|
aState = TS_ACTIVE; // The selected tab is always "pressed".
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
2008-02-29 05:10:12 +00:00
|
|
|
else
|
|
|
|
aState = StandardGetState(aFrame, aWidgetType, PR_TRUE);
|
2005-08-20 07:11:56 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:13:09 +00:00
|
|
|
case NS_THEME_TREEVIEW_HEADER_SORTARROW: {
|
|
|
|
// XXX Probably will never work due to a bug in the Luna theme.
|
|
|
|
aPart = 4;
|
|
|
|
aState = 1;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_TREEVIEW_HEADER_CELL: {
|
|
|
|
aPart = 1;
|
|
|
|
if (!aFrame) {
|
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-02-29 05:10:12 +00:00
|
|
|
aState = StandardGetState(aFrame, aWidgetType, PR_TRUE);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_DROPDOWN: {
|
|
|
|
nsIContent* content = aFrame->GetContent();
|
2009-08-24 20:02:07 +00:00
|
|
|
PRBool isHTML = content && content->IsHTML();
|
2008-03-06 00:23:38 +00:00
|
|
|
|
|
|
|
/* On vista, in HTML, we use CBP_DROPBORDER instead of DROPFRAME for HTML content;
|
|
|
|
* this gives us the thin outline in HTML content, instead of the gradient-filled
|
|
|
|
* background */
|
|
|
|
if (isHTML)
|
2008-02-29 05:10:12 +00:00
|
|
|
aPart = CBP_DROPBORDER;
|
|
|
|
else
|
|
|
|
aPart = CBP_DROPFRAME;
|
|
|
|
|
2008-03-12 00:54:51 +00:00
|
|
|
if (IsDisabled(aFrame)) {
|
|
|
|
aState = TS_DISABLED;
|
|
|
|
} else if (IsReadOnly(aFrame)) {
|
|
|
|
aState = TS_NORMAL;
|
2009-03-13 12:23:26 +00:00
|
|
|
} else if (IsOpenButton(aFrame)) {
|
2008-02-29 05:10:12 +00:00
|
|
|
aState = TS_ACTIVE;
|
2008-03-06 00:23:38 +00:00
|
|
|
} else {
|
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
|
|
|
if (isHTML && eventState & NS_EVENT_STATE_FOCUS)
|
|
|
|
aState = TS_ACTIVE;
|
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
|
|
|
|
aState = TS_ACTIVE;
|
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER)
|
|
|
|
aState = TS_HOVER;
|
|
|
|
else
|
|
|
|
aState = TS_NORMAL;
|
2008-02-29 05:10:12 +00:00
|
|
|
}
|
|
|
|
|
2005-08-20 07:13:09 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-20 07:12:07 +00:00
|
|
|
case NS_THEME_DROPDOWN_BUTTON: {
|
2008-02-29 05:10:12 +00:00
|
|
|
PRBool isHTML = IsHTMLContent(aFrame);
|
2005-08-20 07:13:33 +00:00
|
|
|
nsIFrame* parentFrame = aFrame->GetParent();
|
2009-03-13 12:23:26 +00:00
|
|
|
PRBool isMenulist = !isHTML && parentFrame->GetType() == nsWidgetAtoms::menuFrame;
|
|
|
|
PRBool isOpen = PR_FALSE;
|
|
|
|
|
|
|
|
// HTML select and XUL menulist dropdown buttons get state from the parent.
|
|
|
|
if (isHTML || isMenulist)
|
2008-02-29 05:10:12 +00:00
|
|
|
aFrame = parentFrame;
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
aPart = nsUXThemeData::sIsVistaOrLater ? CBP_DROPMARKER_VISTA : CBP_DROPMARKER;
|
2008-03-06 00:23:38 +00:00
|
|
|
|
2008-07-12 09:08:23 +00:00
|
|
|
// For HTML controls with author styling, we should fall
|
|
|
|
// back to the old dropmarker style to avoid clashes with
|
|
|
|
// author-specified backgrounds and borders (bug #441034)
|
|
|
|
if (isHTML && IsWidgetStyled(aFrame->PresContext(), aFrame, NS_THEME_DROPDOWN))
|
|
|
|
aPart = CBP_DROPMARKER;
|
|
|
|
|
2008-03-06 00:23:38 +00:00
|
|
|
if (IsDisabled(aFrame)) {
|
|
|
|
aState = TS_DISABLED;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-03-13 12:23:26 +00:00
|
|
|
if (isHTML) {
|
|
|
|
nsIComboboxControlFrame* ccf = do_QueryFrame(aFrame);
|
|
|
|
isOpen = (ccf && ccf->IsDroppedDown());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
isOpen = IsOpenButton(aFrame);
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sIsVistaOrLater) {
|
2008-04-23 21:01:16 +00:00
|
|
|
if (isHTML) {
|
2009-03-13 12:23:26 +00:00
|
|
|
if (isOpen) {
|
|
|
|
/* Hover is propagated, but we need to know whether we're
|
|
|
|
* hovering just the combobox frame, not the dropdown frame.
|
|
|
|
* But, we can't get that information, since hover is on the
|
|
|
|
* content node, and they share the same content node. So,
|
|
|
|
* instead, we cheat -- if the dropdown is open, we always
|
|
|
|
* show the hover state. This looks fine in practice.
|
|
|
|
*/
|
2008-04-23 21:01:16 +00:00
|
|
|
aState = TS_HOVER;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* On Vista, the dropdown indicator on a menulist button in
|
|
|
|
* chrome is not given a hover effect. When the frame isn't
|
|
|
|
* isn't HTML content, we cheat and force the dropdown state
|
|
|
|
* to be normal. (Bug 430434)
|
|
|
|
*/
|
2009-03-13 12:23:26 +00:00
|
|
|
aState = TS_NORMAL;
|
|
|
|
return NS_OK;
|
2008-03-06 00:23:38 +00:00
|
|
|
}
|
2005-08-20 07:12:07 +00:00
|
|
|
}
|
2008-03-06 00:23:38 +00:00
|
|
|
|
2009-03-13 12:23:26 +00:00
|
|
|
aState = TS_NORMAL;
|
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
|
|
|
|
|
|
|
// Dropdown button active state doesn't need :hover.
|
|
|
|
if (eventState & NS_EVENT_STATE_ACTIVE) {
|
|
|
|
if (isOpen && (isHTML || isMenulist)) {
|
|
|
|
// XXX Button should look active until the mouse is released, but
|
|
|
|
// without making it look active when the popup is clicked.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
aState = TS_ACTIVE;
|
|
|
|
}
|
|
|
|
else if (eventState & NS_EVENT_STATE_HOVER) {
|
|
|
|
// No hover effect for XUL menulists and autocomplete dropdown buttons
|
|
|
|
// while the dropdown menu is open.
|
|
|
|
if (isOpen) {
|
|
|
|
// XXX HTML select dropdown buttons should have the hover effect when
|
|
|
|
// hovering the combobox frame, but not the popup frame.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
aState = TS_HOVER;
|
|
|
|
}
|
2005-08-20 07:12:07 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-08-06 17:45:57 +00:00
|
|
|
case NS_THEME_MENUPOPUP: {
|
|
|
|
aPart = MENU_POPUPBACKGROUND;
|
|
|
|
aState = MB_ACTIVE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM: {
|
|
|
|
PRBool isTopLevel = PR_FALSE;
|
|
|
|
PRBool isOpen = PR_FALSE;
|
|
|
|
PRBool isHover = PR_FALSE;
|
2009-01-12 19:20:59 +00:00
|
|
|
nsIMenuFrame *menuFrame = do_QueryFrame(aFrame);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
isTopLevel = IsTopLevelMenu(aFrame);
|
|
|
|
|
|
|
|
if (menuFrame)
|
|
|
|
isOpen = menuFrame->IsOpen();
|
2008-02-29 05:10:12 +00:00
|
|
|
|
2008-03-06 20:56:47 +00:00
|
|
|
isHover = IsMenuActive(aFrame, aWidgetType);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
if (isTopLevel) {
|
|
|
|
aPart = MENU_BARITEM;
|
|
|
|
|
|
|
|
if (isOpen)
|
|
|
|
aState = MBI_PUSHED;
|
|
|
|
else if (isHover)
|
|
|
|
aState = MBI_HOT;
|
|
|
|
else
|
|
|
|
aState = MBI_NORMAL;
|
|
|
|
|
|
|
|
// the disabled states are offset by 3
|
|
|
|
if (IsDisabled(aFrame))
|
|
|
|
aState += 3;
|
|
|
|
} else {
|
|
|
|
aPart = MENU_POPUPITEM;
|
|
|
|
|
|
|
|
if (isHover)
|
|
|
|
aState = MPI_HOT;
|
|
|
|
else
|
|
|
|
aState = MPI_NORMAL;
|
|
|
|
|
|
|
|
// the disabled states are offset by 2
|
|
|
|
if (IsDisabled(aFrame))
|
|
|
|
aState += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
aPart = MENU_POPUPSEPARATOR;
|
|
|
|
aState = 0;
|
|
|
|
return NS_OK;
|
|
|
|
case NS_THEME_MENUARROW:
|
|
|
|
aPart = MENU_POPUPSUBMENU;
|
|
|
|
aState = IsDisabled(aFrame) ? MSM_DISABLED : MSM_NORMAL;
|
|
|
|
return NS_OK;
|
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
|
|
|
{
|
|
|
|
PRBool isChecked;
|
|
|
|
PRBool isDisabled;
|
|
|
|
|
|
|
|
isChecked = CheckBooleanAttr(aFrame, nsWidgetAtoms::checked);
|
|
|
|
isDisabled = CheckBooleanAttr(aFrame, nsWidgetAtoms::disabled);
|
|
|
|
|
|
|
|
aPart = MENU_POPUPCHECK;
|
|
|
|
aState = MC_CHECKMARKNORMAL;
|
|
|
|
|
|
|
|
// Radio states are offset by 2
|
|
|
|
if (aWidgetType == NS_THEME_MENURADIO)
|
|
|
|
aState += 2;
|
|
|
|
|
|
|
|
// the disabled states are offset by 1
|
|
|
|
if (isDisabled)
|
|
|
|
aState += 1;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_MENUITEMTEXT:
|
|
|
|
case NS_THEME_MENUIMAGE:
|
|
|
|
aPart = -1;
|
|
|
|
aState = 0;
|
|
|
|
return NS_OK;
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
aPart = 0;
|
|
|
|
aState = 0;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
|
|
|
const nsRect& aRect,
|
2008-07-24 23:01:59 +00:00
|
|
|
const nsRect& aDirtyRect)
|
2005-08-20 07:11:56 +00:00
|
|
|
{
|
|
|
|
HANDLE theme = GetTheme(aWidgetType);
|
|
|
|
if (!theme)
|
2008-07-24 23:01:59 +00:00
|
|
|
return ClassicDrawWidgetBackground(aContext, aFrame, aWidgetType, aRect, aDirtyRect);
|
2005-08-20 07:13:11 +00:00
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
if (!nsUXThemeData::drawThemeBG)
|
2005-08-20 07:13:11 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-20 07:11:56 +00:00
|
|
|
|
|
|
|
PRInt32 part, state;
|
|
|
|
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2005-08-23 02:11:54 +00:00
|
|
|
nsCOMPtr<nsIDeviceContext> dc;
|
|
|
|
aContext->GetDeviceContext(*getter_AddRefs(dc));
|
2007-06-27 16:42:37 +00:00
|
|
|
gfxFloat p2a = gfxFloat(dc->AppUnitsPerDevPixel());
|
2005-08-20 07:11:56 +00:00
|
|
|
RECT widgetRect;
|
|
|
|
RECT clipRect;
|
2007-06-27 16:42:37 +00:00
|
|
|
gfxRect tr(aRect.x, aRect.y, aRect.width, aRect.height),
|
2008-07-24 23:01:59 +00:00
|
|
|
dr(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-06-27 16:42:37 +00:00
|
|
|
tr.ScaleInverse(p2a);
|
2008-07-24 23:01:59 +00:00
|
|
|
dr.ScaleInverse(p2a);
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2008-07-12 09:08:23 +00:00
|
|
|
/* See GetWidgetOverflow */
|
|
|
|
if (aWidgetType == NS_THEME_DROPDOWN_BUTTON &&
|
|
|
|
part == CBP_DROPMARKER_VISTA && IsHTMLContent(aFrame))
|
|
|
|
{
|
|
|
|
tr.pos.y -= 1.0;
|
|
|
|
tr.size.width += 1.0;
|
|
|
|
tr.size.height += 2.0;
|
2008-02-29 05:10:12 +00:00
|
|
|
|
2008-07-24 23:01:59 +00:00
|
|
|
dr.pos.y -= 1.0;
|
|
|
|
dr.size.width += 1.0;
|
|
|
|
dr.size.height += 2.0;
|
2008-02-29 05:10:12 +00:00
|
|
|
}
|
|
|
|
|
2007-12-18 23:01:15 +00:00
|
|
|
nsRefPtr<gfxContext> ctx = aContext->ThebesContext();
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2008-07-24 23:01:59 +00:00
|
|
|
gfxWindowsNativeDrawing nativeDrawing(ctx, dr, GetWidgetNativeDrawingFlags(aWidgetType));
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
RENDER_AGAIN:
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
HDC hdc = nativeDrawing.BeginNativeDrawing();
|
2007-08-09 18:54:17 +00:00
|
|
|
if (!hdc)
|
|
|
|
return NS_ERROR_FAILURE;
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
nativeDrawing.TransformToNativeRect(tr, widgetRect);
|
2008-07-24 23:01:59 +00:00
|
|
|
nativeDrawing.TransformToNativeRect(dr, clipRect);
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2006-06-05 23:16:25 +00:00
|
|
|
#if 0
|
2007-03-03 00:18:34 +00:00
|
|
|
{
|
|
|
|
fprintf (stderr, "xform: %f %f %f %f [%f %f]\n", m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
|
2008-07-24 23:01:59 +00:00
|
|
|
fprintf (stderr, "tr: [%d %d %d %d]\ndr: [%d %d %d %d]\noff: [%f %f]\n",
|
|
|
|
tr.x, tr.y, tr.width, tr.height, dr.x, dr.y, dr.width, dr.height,
|
2007-03-03 00:18:34 +00:00
|
|
|
offset.x, offset.y);
|
|
|
|
}
|
2006-06-05 23:16:25 +00:00
|
|
|
#endif
|
|
|
|
|
2005-08-20 07:12:01 +00:00
|
|
|
// For left edge and right edge tabs, we need to adjust the widget
|
|
|
|
// rects and clip rects so that the edges don't get drawn.
|
2009-01-04 14:01:48 +00:00
|
|
|
if (aWidgetType == NS_THEME_TAB) {
|
|
|
|
PRBool isLeft = IsLeftToSelectedTab(aFrame);
|
|
|
|
PRBool isRight = !isLeft && IsRightToSelectedTab(aFrame);
|
|
|
|
|
|
|
|
if (isLeft || isRight) {
|
|
|
|
// HACK ALERT: There appears to be no way to really obtain this value, so we're forced
|
|
|
|
// to just use the default value for Luna (which also happens to be correct for
|
|
|
|
// all the other skins I've tried).
|
|
|
|
PRInt32 edgeSize = 2;
|
2005-08-20 07:12:01 +00:00
|
|
|
|
2009-01-04 14:01:48 +00:00
|
|
|
// Armed with the size of the edge, we now need to either shift to the left or to the
|
|
|
|
// right. The clip rect won't include this extra area, so we know that we're
|
|
|
|
// effectively shifting the edge out of view (such that it won't be painted).
|
|
|
|
if (isLeft)
|
|
|
|
// The right edge should not be drawn. Extend our rect by the edge size.
|
|
|
|
widgetRect.right += edgeSize;
|
|
|
|
else
|
|
|
|
// The left edge should not be drawn. Move the widget rect's left coord back.
|
|
|
|
widgetRect.left -= edgeSize;
|
|
|
|
}
|
2005-08-20 07:12:01 +00:00
|
|
|
}
|
2005-10-07 00:31:36 +00:00
|
|
|
|
2006-05-30 13:50:48 +00:00
|
|
|
// widgetRect is the bounding box for a widget, yet the scale track is only
|
|
|
|
// a small portion of this size, so the edges of the scale need to be
|
|
|
|
// adjusted to the real size of the track.
|
|
|
|
if (aWidgetType == NS_THEME_SCALE_HORIZONTAL ||
|
|
|
|
aWidgetType == NS_THEME_SCALE_VERTICAL) {
|
|
|
|
RECT contentRect;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemeContentRect(theme, hdc, part, state, &widgetRect, &contentRect);
|
2006-05-30 13:50:48 +00:00
|
|
|
|
|
|
|
SIZE siz;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemePartSize(theme, hdc, part, state, &widgetRect, 1, &siz);
|
2006-05-30 13:50:48 +00:00
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_SCALE_HORIZONTAL) {
|
|
|
|
PRInt32 adjustment = (contentRect.bottom - contentRect.top - siz.cy) / 2 + 1;
|
|
|
|
contentRect.top += adjustment;
|
|
|
|
contentRect.bottom -= adjustment;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
PRInt32 adjustment = (contentRect.right - contentRect.left - siz.cx) / 2 + 1;
|
|
|
|
// need to subtract one from the left position, otherwise the scale's
|
|
|
|
// border isn't visible
|
|
|
|
contentRect.left += adjustment - 1;
|
|
|
|
contentRect.right -= adjustment;
|
|
|
|
}
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, part, state, &contentRect, &clipRect);
|
2006-05-30 13:50:48 +00:00
|
|
|
}
|
2007-08-06 17:45:57 +00:00
|
|
|
else if (aWidgetType == NS_THEME_MENUCHECKBOX || aWidgetType == NS_THEME_MENURADIO)
|
|
|
|
{
|
|
|
|
PRBool isChecked = PR_FALSE;
|
|
|
|
isChecked = CheckBooleanAttr(aFrame, nsWidgetAtoms::checked);
|
|
|
|
|
|
|
|
if (isChecked)
|
|
|
|
{
|
|
|
|
int bgState = MCB_NORMAL;
|
|
|
|
PRBool isDisabled = IsDisabled(aFrame);
|
|
|
|
|
|
|
|
// the disabled states are offset by 1
|
|
|
|
if (isDisabled)
|
|
|
|
bgState += 1;
|
|
|
|
|
|
|
|
SIZE checkboxSize(GetCheckboxSize(theme,hdc));
|
|
|
|
|
|
|
|
RECT checkRect = widgetRect;
|
2008-07-18 20:55:25 +00:00
|
|
|
if (IsFrameRTL(aFrame)) {
|
|
|
|
checkRect.left = checkRect.right-checkboxSize.cx;
|
|
|
|
} else {
|
|
|
|
checkRect.right = checkRect.left+checkboxSize.cx;
|
|
|
|
}
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
// Center the checkbox vertically in the menuitem
|
|
|
|
checkRect.top += (checkRect.bottom - checkRect.top)/2 - checkboxSize.cy/2;
|
|
|
|
checkRect.bottom = checkRect.top + checkboxSize.cy;
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPCHECKBACKGROUND, bgState, &checkRect, &clipRect);
|
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPCHECK, state, &checkRect, &clipRect);
|
2007-08-06 17:45:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aWidgetType == NS_THEME_MENUPOPUP)
|
|
|
|
{
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPBORDERS, /* state */ 0, &widgetRect, &clipRect);
|
2007-08-06 17:45:57 +00:00
|
|
|
SIZE borderSize;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPBORDERS, 0, NULL, TS_TRUE, &borderSize);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
RECT bgRect = widgetRect;
|
|
|
|
bgRect.top += borderSize.cy;
|
|
|
|
bgRect.bottom -= borderSize.cy;
|
|
|
|
bgRect.left += borderSize.cx;
|
|
|
|
bgRect.right -= borderSize.cx;
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPBACKGROUND, /* state */ 0, &bgRect, &clipRect);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
|
|
|
SIZE gutterSize(GetGutterSize(theme, hdc));
|
|
|
|
|
|
|
|
RECT gutterRect;
|
|
|
|
gutterRect.top = bgRect.top;
|
|
|
|
gutterRect.bottom = bgRect.bottom;
|
2008-07-18 20:55:25 +00:00
|
|
|
if (IsFrameRTL(aFrame)) {
|
|
|
|
gutterRect.right = bgRect.right;
|
|
|
|
gutterRect.left = gutterRect.right-gutterSize.cx;
|
|
|
|
} else {
|
|
|
|
gutterRect.left = bgRect.left;
|
|
|
|
gutterRect.right = gutterRect.left+gutterSize.cx;
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawThemeBGRTLAware(theme, hdc, MENU_POPUPGUTTER, /* state */ 0,
|
|
|
|
&gutterRect, &clipRect, IsFrameRTL(aFrame));
|
2007-08-06 17:45:57 +00:00
|
|
|
}
|
|
|
|
else if (aWidgetType == NS_THEME_MENUSEPARATOR)
|
|
|
|
{
|
|
|
|
SIZE gutterSize(GetGutterSize(theme,hdc));
|
|
|
|
|
|
|
|
RECT sepRect = widgetRect;
|
2008-07-18 20:55:25 +00:00
|
|
|
if (IsFrameRTL(aFrame))
|
|
|
|
sepRect.right -= gutterSize.cx;
|
|
|
|
else
|
|
|
|
sepRect.left += gutterSize.cx;
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPSEPARATOR, /* state */ 0, &sepRect, &clipRect);
|
2007-08-06 17:45:57 +00:00
|
|
|
}
|
2008-07-18 20:55:25 +00:00
|
|
|
// The following widgets need to be RTL-aware
|
2009-01-18 10:28:19 +00:00
|
|
|
else if (aWidgetType == NS_THEME_MENUARROW ||
|
|
|
|
aWidgetType == NS_THEME_RESIZER)
|
|
|
|
{
|
2008-07-18 20:55:25 +00:00
|
|
|
DrawThemeBGRTLAware(theme, hdc, part, state,
|
|
|
|
&widgetRect, &clipRect, IsFrameRTL(aFrame));
|
|
|
|
}
|
2005-10-07 00:31:36 +00:00
|
|
|
// If part is negative, the element wishes us to not render a themed
|
|
|
|
// background, instead opting to be drawn specially below.
|
2006-05-30 13:50:48 +00:00
|
|
|
else if (part >= 0) {
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, part, state, &widgetRect, &clipRect);
|
2006-05-30 13:50:48 +00:00
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
|
|
|
|
// Draw focus rectangles for XP HTML checkboxes and radio buttons
|
|
|
|
// XXX it'd be nice to draw these outside of the frame
|
2008-11-03 13:12:59 +00:00
|
|
|
if ((aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_RADIO) &&
|
2009-08-24 20:02:07 +00:00
|
|
|
aFrame->GetContent()->IsHTML() ||
|
2006-05-30 13:50:48 +00:00
|
|
|
aWidgetType == NS_THEME_SCALE_HORIZONTAL ||
|
|
|
|
aWidgetType == NS_THEME_SCALE_VERTICAL) {
|
2009-02-18 23:56:51 +00:00
|
|
|
PRInt32 contentState;
|
2005-08-20 07:13:56 +00:00
|
|
|
contentState = GetContentState(aFrame, aWidgetType);
|
2009-02-18 23:56:51 +00:00
|
|
|
|
2005-08-20 07:13:11 +00:00
|
|
|
if (contentState & NS_EVENT_STATE_FOCUS) {
|
2006-07-11 23:13:21 +00:00
|
|
|
POINT vpOrg;
|
2009-02-18 23:56:51 +00:00
|
|
|
HPEN hPen = nsnull;
|
|
|
|
|
|
|
|
PRUint8 id = SaveDC(hdc);
|
|
|
|
|
|
|
|
::SelectClipRgn(hdc, NULL);
|
2006-07-11 23:13:21 +00:00
|
|
|
::GetViewportOrgEx(hdc, &vpOrg);
|
|
|
|
::SetBrushOrgEx(hdc, vpOrg.x + widgetRect.left, vpOrg.y + widgetRect.top, NULL);
|
2009-02-18 23:56:51 +00:00
|
|
|
|
2009-02-19 00:17:15 +00:00
|
|
|
#ifndef WINCE
|
2009-02-18 23:56:51 +00:00
|
|
|
// On vista, choose our own colors and draw an XP style half focus rect
|
|
|
|
// for focused checkboxes and a full rect when active.
|
|
|
|
if (nsUXThemeData::sIsVistaOrLater && aWidgetType == NS_THEME_CHECKBOX) {
|
|
|
|
LOGBRUSH lb;
|
|
|
|
lb.lbStyle = BS_SOLID;
|
|
|
|
lb.lbColor = RGB(255,255,255);
|
|
|
|
lb.lbHatch = 0;
|
|
|
|
|
|
|
|
hPen = ::ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, NULL);
|
|
|
|
::SelectObject(hdc, hPen);
|
|
|
|
|
|
|
|
// If pressed, draw the upper left corner of the dotted rect.
|
|
|
|
if (contentState & NS_EVENT_STATE_ACTIVE) {
|
|
|
|
::MoveToEx(hdc, widgetRect.left, widgetRect.bottom-1, NULL);
|
|
|
|
::LineTo(hdc, widgetRect.left, widgetRect.top);
|
|
|
|
::LineTo(hdc, widgetRect.right-1, widgetRect.top);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw the lower right corner of the dotted rect.
|
|
|
|
::MoveToEx(hdc, widgetRect.right-1, widgetRect.top, NULL);
|
|
|
|
::LineTo(hdc, widgetRect.right-1, widgetRect.bottom-1);
|
|
|
|
::LineTo(hdc, widgetRect.left, widgetRect.bottom-1);
|
|
|
|
} else {
|
|
|
|
::SetTextColor(hdc, 0);
|
|
|
|
::DrawFocusRect(hdc, &widgetRect);
|
|
|
|
}
|
2009-02-19 00:17:15 +00:00
|
|
|
#else
|
|
|
|
::SetTextColor(hdc, 0);
|
|
|
|
::DrawFocusRect(hdc, &widgetRect);
|
|
|
|
#endif
|
2009-02-18 23:56:51 +00:00
|
|
|
::RestoreDC(hdc, id);
|
|
|
|
if (hPen) {
|
|
|
|
::DeleteObject(hPen);
|
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
}
|
2007-07-14 15:11:37 +00:00
|
|
|
else if (aWidgetType == NS_THEME_TOOLBAR && state == 0) {
|
|
|
|
// Draw toolbar separator lines above all toolbars except the first one.
|
|
|
|
// The lines are part of the Rebar theme, which is loaded for NS_THEME_TOOLBOX.
|
|
|
|
theme = GetTheme(NS_THEME_TOOLBOX);
|
|
|
|
if (!theme)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
widgetRect.bottom = widgetRect.top + TB_SEPARATOR_HEIGHT;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::drawThemeEdge(theme, hdc, RP_BAND, 0, &widgetRect, EDGE_ETCHED, BF_TOP, NULL);
|
2005-10-07 00:31:36 +00:00
|
|
|
}
|
2008-08-13 06:15:27 +00:00
|
|
|
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 (nsUXThemeData::getThemePartSize(theme, hdc, gripPart, state, NULL, TS_TRUE, &gripSize) == S_OK &&
|
|
|
|
nsUXThemeData::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)
|
|
|
|
{
|
|
|
|
nsUXThemeData::drawThemeBG(theme, hdc, gripPart, state, &widgetRect, &clipRect);
|
|
|
|
}
|
|
|
|
}
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
nativeDrawing.EndNativeDrawing();
|
2006-08-09 20:25:07 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
if (nativeDrawing.ShouldRenderAgain())
|
|
|
|
goto RENDER_AGAIN;
|
2006-08-09 20:25:07 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
nativeDrawing.PaintToContext();
|
2006-01-18 22:42:30 +00:00
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-08-20 07:11:57 +00:00
|
|
|
nsNativeThemeWin::GetWidgetBorder(nsIDeviceContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
2009-01-15 03:27:09 +00:00
|
|
|
nsIntMargin* aResult)
|
2005-08-20 07:11:56 +00:00
|
|
|
{
|
2005-08-20 07:13:11 +00:00
|
|
|
HANDLE theme = GetTheme(aWidgetType);
|
|
|
|
if (!theme)
|
|
|
|
return ClassicGetWidgetBorder(aContext, aFrame, aWidgetType, aResult);
|
2005-08-20 07:11:56 +00:00
|
|
|
|
2005-08-20 07:11:59 +00:00
|
|
|
(*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
|
|
|
|
|
2005-08-20 07:12:07 +00:00
|
|
|
if (!WidgetIsContainer(aWidgetType) ||
|
2005-10-07 00:31:36 +00:00
|
|
|
aWidgetType == NS_THEME_TOOLBOX ||
|
2008-05-08 09:29:38 +00:00
|
|
|
aWidgetType == NS_THEME_WIN_MEDIA_TOOLBOX ||
|
|
|
|
aWidgetType == NS_THEME_WIN_COMMUNICATIONS_TOOLBOX ||
|
|
|
|
aWidgetType == NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX ||
|
2005-08-20 07:11:57 +00:00
|
|
|
aWidgetType == NS_THEME_STATUSBAR ||
|
2006-08-07 22:45:56 +00:00
|
|
|
aWidgetType == NS_THEME_RESIZER || aWidgetType == NS_THEME_TAB_PANEL ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL ||
|
2007-08-06 17:45:57 +00:00
|
|
|
aWidgetType == NS_THEME_SCROLLBAR_TRACK_VERTICAL ||
|
|
|
|
aWidgetType == NS_THEME_MENUITEM || aWidgetType == NS_THEME_CHECKMENUITEM ||
|
|
|
|
aWidgetType == NS_THEME_RADIOMENUITEM || aWidgetType == NS_THEME_MENUPOPUP ||
|
2007-08-25 20:30:43 +00:00
|
|
|
aWidgetType == NS_THEME_MENUIMAGE || aWidgetType == NS_THEME_MENUITEMTEXT ||
|
|
|
|
aWidgetType == NS_THEME_TOOLBAR_SEPARATOR)
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK; // Don't worry about it.
|
2005-10-07 00:31:36 +00:00
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
if (!nsUXThemeData::getThemeContentRect)
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
PRInt32 part, state;
|
|
|
|
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2007-07-14 15:11:37 +00:00
|
|
|
if (aWidgetType == NS_THEME_TOOLBAR) {
|
|
|
|
// make space for the separator line above all toolbars but the first
|
|
|
|
if (state == 0)
|
|
|
|
aResult->top = TB_SEPARATOR_HEIGHT;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
// Get our info.
|
|
|
|
RECT outerRect; // Create a fake outer rect.
|
|
|
|
outerRect.top = outerRect.left = 100;
|
|
|
|
outerRect.right = outerRect.bottom = 200;
|
|
|
|
RECT contentRect(outerRect);
|
2008-07-17 17:19:10 +00:00
|
|
|
HRESULT res = nsUXThemeData::getThemeContentRect(theme, NULL, part, state, &outerRect, &contentRect);
|
2005-08-20 07:11:56 +00:00
|
|
|
|
|
|
|
if (FAILED(res))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// Now compute the delta in each direction and place it in our
|
2009-01-15 03:27:09 +00:00
|
|
|
// nsIntMargin struct.
|
2005-08-20 07:11:56 +00:00
|
|
|
aResult->top = contentRect.top - outerRect.top;
|
|
|
|
aResult->bottom = outerRect.bottom - contentRect.bottom;
|
|
|
|
aResult->left = contentRect.left - outerRect.left;
|
|
|
|
aResult->right = outerRect.right - contentRect.right;
|
2005-08-20 07:12:01 +00:00
|
|
|
|
|
|
|
// Remove the edges for tabs that are before or after the selected tab,
|
2009-01-04 14:01:48 +00:00
|
|
|
if (aWidgetType == NS_THEME_TAB) {
|
|
|
|
if (IsLeftToSelectedTab(aFrame))
|
|
|
|
// Remove the right edge, since we won't be drawing it.
|
|
|
|
aResult->right = 0;
|
|
|
|
else if (IsRightToSelectedTab(aFrame))
|
|
|
|
// Remove the left edge, since we won't be drawing it.
|
|
|
|
aResult->left = 0;
|
|
|
|
}
|
2005-08-20 07:12:01 +00:00
|
|
|
|
2007-05-07 02:06:58 +00:00
|
|
|
if (aFrame && (aWidgetType == NS_THEME_TEXTFIELD || aWidgetType == NS_THEME_TEXTFIELD_MULTILINE)) {
|
2005-08-20 07:13:33 +00:00
|
|
|
nsIContent* content = aFrame->GetContent();
|
2009-08-24 20:02:07 +00:00
|
|
|
if (content && content->IsHTML()) {
|
2005-08-20 07:13:10 +00:00
|
|
|
// We need to pad textfields by 1 pixel, since the caret will draw
|
|
|
|
// flush against the edge by default if we don't.
|
2006-03-15 11:59:22 +00:00
|
|
|
aResult->top++;
|
2005-08-20 07:13:10 +00:00
|
|
|
aResult->left++;
|
2006-03-15 11:59:22 +00:00
|
|
|
aResult->bottom++;
|
2005-08-20 07:13:10 +00:00
|
|
|
aResult->right++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:14:07 +00:00
|
|
|
PRBool
|
|
|
|
nsNativeThemeWin::GetWidgetPadding(nsIDeviceContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
2009-01-15 03:27:09 +00:00
|
|
|
nsIntMargin* aResult)
|
2005-08-20 07:14:07 +00:00
|
|
|
{
|
2008-03-07 17:57:34 +00:00
|
|
|
switch (aWidgetType) {
|
|
|
|
// Radios and checkboxes return a fixed size in GetMinimumWidgetSize
|
|
|
|
// and have a meaningful baseline, so they can't have
|
|
|
|
// author-specified padding.
|
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_RADIO:
|
|
|
|
aResult->SizeTo(0, 0, 0, 0);
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-08-06 17:45:57 +00:00
|
|
|
HANDLE theme = GetTheme(aWidgetType);
|
2008-05-09 00:18:46 +00:00
|
|
|
if (!theme)
|
2007-08-06 17:45:57 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_MENUPOPUP)
|
|
|
|
{
|
|
|
|
SIZE popupSize;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemePartSize(theme, NULL, MENU_POPUPBORDERS, /* state */ 0, NULL, TS_TRUE, &popupSize);
|
2007-08-06 17:45:57 +00:00
|
|
|
aResult->top = aResult->bottom = popupSize.cy;
|
|
|
|
aResult->left = aResult->right = popupSize.cx;
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sIsVistaOrLater) {
|
2008-04-25 23:12:45 +00:00
|
|
|
if (aWidgetType == NS_THEME_TEXTFIELD ||
|
|
|
|
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
|
|
|
aWidgetType == NS_THEME_DROPDOWN)
|
|
|
|
{
|
|
|
|
/* If we have author-specified padding for these elements, don't do the fixups below */
|
|
|
|
if (aFrame->PresContext()->HasAuthorSpecifiedRules(aFrame, NS_AUTHOR_SPECIFIED_PADDING))
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2008-04-22 19:56:10 +00:00
|
|
|
/* textfields need extra pixels on all sides, otherwise they
|
2008-02-29 05:10:12 +00:00
|
|
|
* wrap their content too tightly. The actual border is drawn 1px
|
|
|
|
* inside the specified rectangle, so Gecko will end up making the
|
2008-04-22 19:56:10 +00:00
|
|
|
* contents look too small. Instead, we add 2px padding for the
|
|
|
|
* contents and fix this. (Used to be 1px added, see bug 430212)
|
2008-02-29 05:10:12 +00:00
|
|
|
*/
|
|
|
|
if (aWidgetType == NS_THEME_TEXTFIELD || aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
|
2008-04-22 19:56:10 +00:00
|
|
|
aResult->top = aResult->bottom = 2;
|
|
|
|
aResult->left = aResult->right = 2;
|
2008-02-29 05:10:12 +00:00
|
|
|
return PR_TRUE;
|
2008-04-25 23:12:45 +00:00
|
|
|
} else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_DROPDOWN) {
|
2008-03-04 11:21:47 +00:00
|
|
|
/* For content menulist controls, we need an extra pixel so
|
|
|
|
* that we have room to draw our focus rectangle stuff.
|
|
|
|
* Otherwise, the focus rect might overlap the control's
|
|
|
|
* border.
|
|
|
|
*/
|
|
|
|
aResult->top = aResult->bottom = 1;
|
|
|
|
aResult->left = aResult->right = 1;
|
|
|
|
return PR_TRUE;
|
2008-02-29 05:10:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-06 17:45:57 +00:00
|
|
|
PRInt32 right, left, top, bottom;
|
|
|
|
right = left = top = bottom = 0;
|
|
|
|
switch (aWidgetType)
|
|
|
|
{
|
|
|
|
case NS_THEME_MENUIMAGE:
|
2008-05-09 00:18:46 +00:00
|
|
|
right = 8;
|
2007-08-06 17:45:57 +00:00
|
|
|
left = 3;
|
|
|
|
break;
|
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
2007-08-17 21:07:26 +00:00
|
|
|
right = 8;
|
2007-08-06 17:45:57 +00:00
|
|
|
left = 0;
|
|
|
|
break;
|
|
|
|
case NS_THEME_MENUITEMTEXT:
|
2008-05-09 00:18:46 +00:00
|
|
|
// There seem to be exactly 4 pixels from the edge
|
|
|
|
// of the gutter to the text: 2px margin (CSS) + 2px padding (here)
|
2008-06-19 18:32:52 +00:00
|
|
|
{
|
|
|
|
SIZE size(GetGutterSize(theme, NULL));
|
|
|
|
left = size.cx + 2;
|
|
|
|
}
|
2007-08-06 17:45:57 +00:00
|
|
|
break;
|
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
{
|
|
|
|
SIZE size(GetGutterSize(theme, NULL));
|
|
|
|
left = size.cx + 5;
|
|
|
|
top = 10;
|
|
|
|
bottom = 7;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsFrameRTL(aFrame))
|
|
|
|
{
|
|
|
|
aResult->right = left;
|
|
|
|
aResult->left = right;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aResult->right = right;
|
|
|
|
aResult->left = left;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_TRUE;
|
2005-08-20 07:14:07 +00:00
|
|
|
}
|
|
|
|
|
2008-02-29 05:10:12 +00:00
|
|
|
PRBool
|
|
|
|
nsNativeThemeWin::GetWidgetOverflow(nsIDeviceContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
2008-04-01 23:34:20 +00:00
|
|
|
PRUint8 aOverflowRect,
|
2008-02-29 05:10:12 +00:00
|
|
|
nsRect* aResult)
|
|
|
|
{
|
2008-03-03 06:59:06 +00:00
|
|
|
/* This is disabled for now, because it causes invalidation problems --
|
|
|
|
* see bug 402381. The effect of not updating the overflow area is that
|
|
|
|
* for dropdown buttons in content areas, there is a 1px border on 3 sides
|
|
|
|
* where, if invalidated, the dropdown control probably won't be repainted.
|
|
|
|
* This is fairly minor, as by default there is nothing in that area, and
|
|
|
|
* a border only shows up if the widget is being hovered.
|
|
|
|
*/
|
|
|
|
#if 0
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sIsVistaOrLater) {
|
2008-02-29 05:10:12 +00:00
|
|
|
/* We explicitly draw dropdown buttons in HTML content 1px bigger
|
|
|
|
* up, right, and bottom so that they overlap the dropdown's border
|
|
|
|
* like they're supposed to.
|
|
|
|
*/
|
|
|
|
if (aWidgetType == NS_THEME_DROPDOWN_BUTTON &&
|
2008-07-12 09:08:23 +00:00
|
|
|
IsHTMLContent(aFrame) &&
|
|
|
|
!IsWidgetStyled(aFrame->GetParent()->PresContext(),
|
|
|
|
aFrame->GetParent(),
|
|
|
|
NS_THEME_DROPDOWN))
|
2008-02-29 05:10:12 +00:00
|
|
|
{
|
|
|
|
PRInt32 p2a = aContext->AppUnitsPerDevPixel();
|
|
|
|
/* Note: no overflow on the left */
|
|
|
|
nsMargin m(0, p2a, p2a, p2a);
|
2008-04-01 23:34:20 +00:00
|
|
|
aOverflowRect->Inflate (m);
|
2008-02-29 05:10:12 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
2008-03-03 06:59:06 +00:00
|
|
|
#endif
|
2008-02-29 05:10:12 +00:00
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeWin::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
2009-01-15 03:27:09 +00:00
|
|
|
nsIntSize* aResult, PRBool* aIsOverridable)
|
2005-08-20 07:11:56 +00:00
|
|
|
{
|
2005-08-20 07:11:59 +00:00
|
|
|
(*aResult).width = (*aResult).height = 0;
|
2005-08-20 07:12:10 +00:00
|
|
|
*aIsOverridable = PR_TRUE;
|
2005-08-20 07:11:59 +00:00
|
|
|
|
2005-08-20 07:13:11 +00:00
|
|
|
HANDLE theme = GetTheme(aWidgetType);
|
|
|
|
if (!theme)
|
|
|
|
return ClassicGetMinimumWidgetSize(aContext, aFrame, aWidgetType, aResult, aIsOverridable);
|
2007-08-06 17:45:57 +00:00
|
|
|
|
2009-03-21 20:38:24 +00:00
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_TEXTFIELD:
|
|
|
|
case NS_THEME_TOOLBOX:
|
|
|
|
case NS_THEME_WIN_MEDIA_TOOLBOX:
|
|
|
|
case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX:
|
|
|
|
case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX:
|
|
|
|
case NS_THEME_TOOLBAR:
|
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
case NS_THEME_TAB_PANELS:
|
|
|
|
case NS_THEME_TAB_PANEL:
|
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_MENUITEMTEXT:
|
|
|
|
return NS_OK; // Don't worry about it.
|
|
|
|
}
|
2005-08-20 07:11:56 +00:00
|
|
|
|
2007-08-06 17:45:57 +00:00
|
|
|
if (aWidgetType == NS_THEME_MENUITEM && IsTopLevelMenu(aFrame))
|
|
|
|
return NS_OK; // Don't worry about it for top level menus
|
|
|
|
|
2008-07-17 17:19:10 +00:00
|
|
|
if (!nsUXThemeData::getThemePartSize)
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-20 07:13:11 +00:00
|
|
|
|
|
|
|
// Call GetSystemMetrics to determine size for WinXP scrollbars
|
|
|
|
// (GetThemeSysSize API returns the optimal size for the theme, but
|
|
|
|
// Windows appears to always use metrics when drawing standard scrollbars)
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
2008-02-29 05:10:12 +00:00
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
2005-08-20 07:13:11 +00:00
|
|
|
return ClassicGetMinimumWidgetSize(aContext, aFrame, aWidgetType, aResult, aIsOverridable);
|
2007-08-06 17:45:57 +00:00
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
|
|
|
if(!IsTopLevelMenu(aFrame))
|
|
|
|
{
|
|
|
|
SIZE gutterSize(GetGutterSize(theme, NULL));
|
|
|
|
aResult->width = gutterSize.cx;
|
|
|
|
aResult->height = gutterSize.cy;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NS_THEME_MENUIMAGE:
|
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
|
|
|
{
|
|
|
|
SIZE boxSize(GetGutterSize(theme, NULL));
|
2008-05-09 00:18:46 +00:00
|
|
|
aResult->width = boxSize.cx+2;
|
2007-08-06 17:45:57 +00:00
|
|
|
aResult->height = boxSize.cy;
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
}
|
|
|
|
case NS_THEME_MENUITEMTEXT:
|
|
|
|
return NS_OK;
|
|
|
|
case NS_THEME_MENUARROW:
|
|
|
|
aResult->width = 26;
|
|
|
|
aResult->height = 16;
|
|
|
|
return NS_OK;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
2005-08-20 07:11:56 +00:00
|
|
|
|
2006-05-30 13:50:48 +00:00
|
|
|
if (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL ||
|
|
|
|
aWidgetType == NS_THEME_SCALE_THUMB_VERTICAL) {
|
2008-02-06 14:12:24 +00:00
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
// on Vista, GetThemePartAndState returns odd values for
|
|
|
|
// scale thumbs, so use a hardcoded size instead.
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sIsVistaOrLater) {
|
2008-02-06 14:12:24 +00:00
|
|
|
if (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL) {
|
|
|
|
aResult->width = 12;
|
|
|
|
aResult->height = 20;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aResult->width = 20;
|
|
|
|
aResult->height = 12;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2006-05-30 13:50:48 +00:00
|
|
|
}
|
2007-08-25 20:30:43 +00:00
|
|
|
else if (aWidgetType == NS_THEME_TOOLBAR_SEPARATOR) {
|
|
|
|
// that's 2px left margin, 2px right margin and 2px separator
|
|
|
|
// (the margin is drawn as part of the separator, though)
|
|
|
|
aResult->width = 6;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2006-05-30 13:50:48 +00:00
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
PRInt32 part, state;
|
|
|
|
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2005-08-23 02:11:54 +00:00
|
|
|
HDC hdc = (HDC)aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_WINDOWS_DC);
|
2005-08-20 07:11:56 +00:00
|
|
|
if (!hdc)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2007-11-15 18:11:03 +00:00
|
|
|
PRInt32 sizeReq = 1; // Best-fit size. (TS_TRUE)
|
2005-08-20 07:13:11 +00:00
|
|
|
if (aWidgetType == NS_THEME_PROGRESSBAR ||
|
2005-08-20 07:12:01 +00:00
|
|
|
aWidgetType == NS_THEME_PROGRESSBAR_VERTICAL)
|
2005-08-20 07:13:11 +00:00
|
|
|
sizeReq = 0; // Best-fit size for progress meters is too large for most
|
2005-08-20 07:12:01 +00:00
|
|
|
// themes.
|
|
|
|
// In our app, we want these widgets to be able to really shrink down,
|
2005-08-20 07:11:56 +00:00
|
|
|
// so use the min-size request value (of 0).
|
2006-07-13 17:40:49 +00:00
|
|
|
|
2007-11-15 18:11:03 +00:00
|
|
|
// We should let HTML buttons shrink to their min size.
|
2007-11-15 19:33:08 +00:00
|
|
|
// FIXME bug 403934: We should probably really separate
|
|
|
|
// GetPreferredWidgetSize from GetMinimumWidgetSize, so callers can
|
|
|
|
// use the one they want.
|
2007-11-15 18:11:03 +00:00
|
|
|
if (aWidgetType == NS_THEME_BUTTON &&
|
2009-08-24 20:02:07 +00:00
|
|
|
aFrame->GetContent()->IsHTML())
|
2007-11-15 18:11:03 +00:00
|
|
|
sizeReq = 0; /* TS_MIN */
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
SIZE sz;
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::getThemePartSize(theme, hdc, part, state, NULL, sizeReq, &sz);
|
2005-08-20 07:11:56 +00:00
|
|
|
aResult->width = sz.cx;
|
|
|
|
aResult->height = sz.cy;
|
2005-08-20 07:13:09 +00:00
|
|
|
|
2006-07-13 17:40:49 +00:00
|
|
|
if (aWidgetType == NS_THEME_SPINNER_UP_BUTTON ||
|
|
|
|
aWidgetType == NS_THEME_SPINNER_DOWN_BUTTON) {
|
|
|
|
aResult->width++;
|
|
|
|
aResult->height = aResult->height / 2 + 1;
|
|
|
|
}
|
2007-08-06 17:45:57 +00:00
|
|
|
else if (aWidgetType == NS_THEME_MENUSEPARATOR)
|
|
|
|
{
|
|
|
|
SIZE gutterSize(GetGutterSize(theme,hdc));
|
|
|
|
aResult->width += gutterSize.cx;
|
|
|
|
}
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
|
|
|
|
nsIAtom* aAttribute, PRBool* aShouldRepaint)
|
|
|
|
{
|
|
|
|
// Some widget types just never change state.
|
2008-02-29 05:10:38 +00:00
|
|
|
if (aWidgetType == NS_THEME_TOOLBOX ||
|
2008-05-08 09:29:38 +00:00
|
|
|
aWidgetType == NS_THEME_WIN_MEDIA_TOOLBOX ||
|
|
|
|
aWidgetType == NS_THEME_WIN_COMMUNICATIONS_TOOLBOX ||
|
|
|
|
aWidgetType == NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX ||
|
2008-02-29 05:10:38 +00:00
|
|
|
aWidgetType == NS_THEME_TOOLBAR ||
|
2005-08-20 07:11:57 +00:00
|
|
|
aWidgetType == NS_THEME_STATUSBAR || aWidgetType == NS_THEME_STATUSBAR_PANEL ||
|
2005-08-20 07:11:59 +00:00
|
|
|
aWidgetType == NS_THEME_STATUSBAR_RESIZER_PANEL ||
|
|
|
|
aWidgetType == NS_THEME_PROGRESSBAR_CHUNK ||
|
|
|
|
aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL ||
|
|
|
|
aWidgetType == NS_THEME_PROGRESSBAR ||
|
2005-08-20 07:12:00 +00:00
|
|
|
aWidgetType == NS_THEME_PROGRESSBAR_VERTICAL ||
|
2005-08-20 07:12:02 +00:00
|
|
|
aWidgetType == NS_THEME_TOOLTIP ||
|
|
|
|
aWidgetType == NS_THEME_TAB_PANELS ||
|
2007-08-25 20:30:43 +00:00
|
|
|
aWidgetType == NS_THEME_TAB_PANEL ||
|
|
|
|
aWidgetType == NS_THEME_TOOLBAR_SEPARATOR) {
|
2005-08-20 07:11:56 +00:00
|
|
|
*aShouldRepaint = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-08-17 20:47:33 +00:00
|
|
|
// On Vista, the scrollbar buttons need to change state when the track has/doesn't have hover
|
2008-07-17 17:19:10 +00:00
|
|
|
if (!nsUXThemeData::sIsVistaOrLater &&
|
2007-08-17 20:47:33 +00:00
|
|
|
(aWidgetType == NS_THEME_SCROLLBAR_TRACK_VERTICAL ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL)) {
|
|
|
|
*aShouldRepaint = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-03-06 00:23:38 +00:00
|
|
|
// We need to repaint the dropdown arrow in vista HTML combobox controls when
|
|
|
|
// the control is closed to get rid of the hover effect.
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sIsVistaOrLater &&
|
2008-03-06 00:23:38 +00:00
|
|
|
(aWidgetType == NS_THEME_DROPDOWN || aWidgetType == NS_THEME_DROPDOWN_BUTTON) &&
|
|
|
|
IsHTMLContent(aFrame))
|
|
|
|
{
|
|
|
|
*aShouldRepaint = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
// XXXdwh Not sure what can really be done here. Can at least guess for
|
|
|
|
// specific widgets that they're highly unlikely to have certain states.
|
|
|
|
// For example, a toolbar doesn't care about any states.
|
|
|
|
if (!aAttribute) {
|
|
|
|
// Hover/focus/active changed. Always repaint.
|
|
|
|
*aShouldRepaint = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Check the attribute to see if it's relevant.
|
|
|
|
// disabled, checked, dlgtype, default, etc.
|
|
|
|
*aShouldRepaint = PR_FALSE;
|
2006-06-09 06:02:30 +00:00
|
|
|
if (aAttribute == nsWidgetAtoms::disabled ||
|
|
|
|
aAttribute == nsWidgetAtoms::checked ||
|
|
|
|
aAttribute == nsWidgetAtoms::selected ||
|
|
|
|
aAttribute == nsWidgetAtoms::readonly ||
|
2008-02-29 05:10:12 +00:00
|
|
|
aAttribute == nsWidgetAtoms::open ||
|
2008-03-06 00:23:38 +00:00
|
|
|
aAttribute == nsWidgetAtoms::mozmenuactive ||
|
|
|
|
aAttribute == nsWidgetAtoms::focused)
|
2005-08-20 07:11:56 +00:00
|
|
|
*aShouldRepaint = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeWin::ThemeChanged()
|
|
|
|
{
|
2008-07-17 17:19:10 +00:00
|
|
|
nsUXThemeData::Invalidate();
|
2005-08-20 07:11:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:13:11 +00:00
|
|
|
PRBool
|
2005-08-20 07:14:04 +00:00
|
|
|
nsNativeThemeWin::ThemeSupportsWidget(nsPresContext* aPresContext,
|
2005-08-20 07:13:11 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
// XXXdwh We can go even further and call the API to ask if support exists for
|
|
|
|
// specific widgets.
|
|
|
|
|
2005-08-20 07:13:36 +00:00
|
|
|
if (aPresContext && !aPresContext->PresShell()->IsThemeSupportEnabled())
|
|
|
|
return PR_FALSE;
|
2005-08-20 07:13:11 +00:00
|
|
|
|
|
|
|
HANDLE theme = NULL;
|
|
|
|
if (aWidgetType == NS_THEME_CHECKBOX_CONTAINER)
|
|
|
|
theme = GetTheme(NS_THEME_CHECKBOX);
|
|
|
|
else if (aWidgetType == NS_THEME_RADIO_CONTAINER)
|
|
|
|
theme = GetTheme(NS_THEME_RADIO);
|
|
|
|
else
|
|
|
|
theme = GetTheme(aWidgetType);
|
|
|
|
|
|
|
|
if ((theme) || (!theme && ClassicThemeSupportsWidget(aPresContext, aFrame, aWidgetType)))
|
|
|
|
// turn off theming for some HTML widgets styled by the page
|
2005-08-20 07:13:24 +00:00
|
|
|
return (!IsWidgetStyled(aPresContext, aFrame, aWidgetType));
|
2005-08-20 07:13:11 +00:00
|
|
|
|
|
|
|
return PR_FALSE;
|
2005-08-20 07:11:56 +00:00
|
|
|
}
|
|
|
|
|
2005-08-20 07:12:07 +00:00
|
|
|
PRBool
|
|
|
|
nsNativeThemeWin::WidgetIsContainer(PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
// XXXdwh At some point flesh all of this out.
|
|
|
|
if (aWidgetType == NS_THEME_DROPDOWN_BUTTON ||
|
2008-11-03 13:12:59 +00:00
|
|
|
aWidgetType == NS_THEME_RADIO ||
|
|
|
|
aWidgetType == NS_THEME_CHECKBOX)
|
2005-08-20 07:12:07 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-02-16 01:53:43 +00:00
|
|
|
PRBool
|
|
|
|
nsNativeThemeWin::ThemeDrawsFocusForWidget(nsPresContext* aPresContext, nsIFrame* aFrame, PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
|
2007-05-18 03:04:04 +00:00
|
|
|
PRBool
|
|
|
|
nsNativeThemeWin::ThemeNeedsComboboxDropmarker()
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2008-12-11 14:37:38 +00:00
|
|
|
nsTransparencyMode
|
|
|
|
nsNativeThemeWin::GetWidgetTransparency(PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
return eTransparencyOpaque;
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:13:11 +00:00
|
|
|
/* Windows 9x/NT/2000/Classic XP Theme Support */
|
|
|
|
|
|
|
|
PRBool
|
2005-08-20 07:14:04 +00:00
|
|
|
nsNativeThemeWin::ClassicThemeSupportsWidget(nsPresContext* aPresContext,
|
2005-08-20 07:13:11 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
switch (aWidgetType) {
|
2007-07-14 15:11:37 +00:00
|
|
|
case NS_THEME_MENUBAR:
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
// Classic non-flat menus are handled almost entirely through CSS.
|
2008-07-17 17:19:10 +00:00
|
|
|
if (!nsUXThemeData::sFlatMenus)
|
2007-07-14 15:11:37 +00:00
|
|
|
return PR_FALSE;
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-07 02:06:58 +00:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_RADIO:
|
2009-03-12 02:11:01 +00:00
|
|
|
case NS_THEME_GROUPBOX:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
2006-05-30 13:50:48 +00:00
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
case NS_THEME_SPINNER_UP_BUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_DROPDOWN_TEXTFIELD:
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
|
|
|
case NS_THEME_RESIZER:
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
case NS_THEME_TAB:
|
|
|
|
case NS_THEME_TAB_PANEL:
|
|
|
|
case NS_THEME_TAB_PANELS:
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
2007-07-14 15:11:37 +00:00
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
|
|
|
case NS_THEME_MENUARROW:
|
2007-08-06 17:45:57 +00:00
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
case NS_THEME_MENUITEMTEXT:
|
2005-08-20 07:13:11 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsNativeThemeWin::ClassicGetWidgetBorder(nsIDeviceContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
2009-01-15 03:27:09 +00:00
|
|
|
nsIntMargin* aResult)
|
2005-08-20 07:13:11 +00:00
|
|
|
{
|
|
|
|
switch (aWidgetType) {
|
2009-03-12 02:11:01 +00:00
|
|
|
case NS_THEME_GROUPBOX:
|
2007-10-01 16:40:35 +00:00
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2;
|
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
(*aResult).bottom = (*aResult).left = (*aResult).right = 0;
|
|
|
|
(*aResult).top = 2;
|
|
|
|
break;
|
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_TEXTFIELD:
|
|
|
|
case NS_THEME_TAB:
|
2006-03-15 11:59:22 +00:00
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-07 02:06:58 +00:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2005-08-20 07:13:11 +00:00
|
|
|
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2;
|
|
|
|
break;
|
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL: {
|
|
|
|
(*aResult).top = 1;
|
|
|
|
(*aResult).left = 1;
|
|
|
|
(*aResult).bottom = 1;
|
2005-08-20 07:13:33 +00:00
|
|
|
(*aResult).right = aFrame->GetNextSibling() ? 3 : 1;
|
2005-08-20 07:13:11 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 1;
|
|
|
|
break;
|
2005-08-20 07:14:29 +00:00
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 1;
|
|
|
|
break;
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_MENUBAR:
|
|
|
|
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 0;
|
|
|
|
break;
|
|
|
|
case NS_THEME_MENUPOPUP:
|
2007-07-14 15:11:37 +00:00
|
|
|
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 3;
|
2005-10-07 00:31:36 +00:00
|
|
|
break;
|
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM: {
|
2007-07-14 15:11:37 +00:00
|
|
|
PRInt32 part, state;
|
|
|
|
PRBool focused;
|
|
|
|
nsresult rv;
|
2005-10-07 00:31:36 +00:00
|
|
|
|
2007-07-14 15:11:37 +00:00
|
|
|
rv = ClassicGetThemePartAndState(aFrame, aWidgetType, part, state, focused);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2005-10-07 00:31:36 +00:00
|
|
|
|
2007-07-14 15:11:37 +00:00
|
|
|
if (part == 1) { // top level menu
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sFlatMenus || !(state & DFCS_PUSHED)) {
|
2007-07-14 15:11:37 +00:00
|
|
|
(*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// make top-level menus look sunken when pushed in the Classic look
|
|
|
|
(*aResult).top = (*aResult).left = 3;
|
|
|
|
(*aResult).bottom = (*aResult).right = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2008-09-05 03:20:18 +00:00
|
|
|
(*aResult).top = 0;
|
|
|
|
(*aResult).bottom = (*aResult).left = (*aResult).right = 2;
|
2005-10-07 00:31:36 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
default:
|
|
|
|
(*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
2009-01-15 03:27:09 +00:00
|
|
|
nsIntSize* aResult, PRBool* aIsOverridable)
|
2005-08-20 07:13:11 +00:00
|
|
|
{
|
|
|
|
(*aResult).width = (*aResult).height = 0;
|
|
|
|
*aIsOverridable = PR_TRUE;
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_RADIO:
|
2007-05-09 19:17:17 +00:00
|
|
|
case NS_THEME_CHECKBOX:
|
2005-08-20 07:13:11 +00:00
|
|
|
(*aResult).width = (*aResult).height = 13;
|
|
|
|
break;
|
2007-07-14 15:11:37 +00:00
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
|
|
|
case NS_THEME_MENUARROW:
|
2008-02-21 20:57:22 +00:00
|
|
|
#ifdef WINCE
|
|
|
|
(*aResult).width = 16;
|
|
|
|
(*aResult).height = 16;
|
2008-02-21 21:33:24 +00:00
|
|
|
#else
|
2007-07-14 15:11:37 +00:00
|
|
|
(*aResult).width = ::GetSystemMetrics(SM_CXMENUCHECK);
|
|
|
|
(*aResult).height = ::GetSystemMetrics(SM_CYMENUCHECK);
|
2008-02-21 20:57:22 +00:00
|
|
|
#endif
|
2007-07-14 15:11:37 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
(*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
|
|
|
|
(*aResult).height = ::GetSystemMetrics(SM_CYVSCROLL);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
(*aResult).width = ::GetSystemMetrics(SM_CXHSCROLL);
|
|
|
|
(*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
2005-08-20 07:13:32 +00:00
|
|
|
// XXX HACK We should be able to have a minimum height for the scrollbar
|
|
|
|
// track. However, this causes problems when uncollapsing a scrollbar
|
|
|
|
// inside a tree. See bug 201379 for details.
|
|
|
|
|
|
|
|
// (*aResult).height = ::GetSystemMetrics(SM_CYVTHUMB) << 1;
|
2005-08-20 07:13:11 +00:00
|
|
|
break;
|
2006-05-30 13:50:48 +00:00
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
(*aResult).width = 12;
|
|
|
|
(*aResult).height = 20;
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
|
|
|
(*aResult).width = 20;
|
|
|
|
(*aResult).height = 12;
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
(*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
|
|
|
|
break;
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_BUTTON:
|
2009-03-12 02:11:01 +00:00
|
|
|
case NS_THEME_GROUPBOX:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_TREEVIEW:
|
2007-05-07 02:06:58 +00:00
|
|
|
case NS_THEME_TEXTFIELD:
|
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_DROPDOWN_TEXTFIELD:
|
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
case NS_THEME_TAB:
|
|
|
|
case NS_THEME_TAB_PANEL:
|
|
|
|
case NS_THEME_TAB_PANELS:
|
|
|
|
// no minimum widget size
|
|
|
|
break;
|
|
|
|
case NS_THEME_RESIZER: {
|
2005-08-20 07:14:27 +00:00
|
|
|
#ifndef WINCE
|
2005-08-20 07:13:11 +00:00
|
|
|
NONCLIENTMETRICS nc;
|
|
|
|
nc.cbSize = sizeof(nc);
|
|
|
|
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nc), &nc, 0))
|
|
|
|
(*aResult).width = (*aResult).height = abs(nc.lfStatusFont.lfHeight) + 4;
|
|
|
|
else
|
2005-08-20 07:14:27 +00:00
|
|
|
#endif
|
2005-08-20 07:13:11 +00:00
|
|
|
(*aResult).width = (*aResult).height = 15;
|
|
|
|
break;
|
2009-08-24 02:03:03 +00:00
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
2009-01-05 18:17:44 +00:00
|
|
|
#ifndef WINCE
|
2009-08-24 02:03:03 +00:00
|
|
|
(*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
|
|
|
|
(*aResult).height = ::GetSystemMetrics(SM_CYVTHUMB);
|
2009-01-05 18:17:44 +00:00
|
|
|
#else
|
|
|
|
(*aResult).width = 15;
|
2009-08-24 02:03:03 +00:00
|
|
|
(*aResult).height = 15;
|
2009-01-05 18:17:44 +00:00
|
|
|
#endif
|
2009-08-24 02:03:03 +00:00
|
|
|
// Without theming, divide the thumb size by two in order to look more
|
|
|
|
// native
|
|
|
|
if (!GetTheme(aWidgetType))
|
|
|
|
(*aResult).height >>= 1;
|
2005-08-20 07:14:19 +00:00
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
2009-01-05 18:17:44 +00:00
|
|
|
#ifndef WINCE
|
2009-08-24 02:03:03 +00:00
|
|
|
(*aResult).width = ::GetSystemMetrics(SM_CXHTHUMB);
|
|
|
|
(*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL);
|
2009-01-05 18:17:44 +00:00
|
|
|
#else
|
2009-08-24 02:03:03 +00:00
|
|
|
(*aResult).width = 15;
|
2009-01-05 18:17:44 +00:00
|
|
|
(*aResult).height = 15;
|
|
|
|
#endif
|
2009-08-24 02:03:03 +00:00
|
|
|
// Without theming, divide the thumb size by two in order to look more
|
|
|
|
// native
|
|
|
|
if (!GetTheme(aWidgetType))
|
|
|
|
(*aResult).width >>= 1;
|
2005-08-20 07:14:19 +00:00
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
2009-01-05 18:17:44 +00:00
|
|
|
#ifndef WINCE
|
2005-08-20 07:14:19 +00:00
|
|
|
(*aResult).width = ::GetSystemMetrics(SM_CXHTHUMB) << 1;
|
2009-01-05 18:17:44 +00:00
|
|
|
#else
|
|
|
|
(*aResult).width = 10;
|
|
|
|
#endif
|
2005-08-20 07:14:19 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
2007-08-06 17:45:57 +00:00
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
{
|
|
|
|
aResult->width = 0;
|
|
|
|
aResult->height = 10;
|
|
|
|
break;
|
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
default:
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
|
|
|
PRInt32& aPart, PRInt32& aState, PRBool& aFocused)
|
|
|
|
{
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON: {
|
|
|
|
PRInt32 contentState;
|
|
|
|
|
|
|
|
aPart = DFC_BUTTON;
|
|
|
|
aState = DFCS_BUTTONPUSH;
|
|
|
|
aFocused = PR_FALSE;
|
|
|
|
|
2005-08-20 07:13:56 +00:00
|
|
|
contentState = GetContentState(aFrame, aWidgetType);
|
2005-08-20 07:13:11 +00:00
|
|
|
if (IsDisabled(aFrame))
|
|
|
|
aState |= DFCS_INACTIVE;
|
2009-03-13 12:23:26 +00:00
|
|
|
else if (IsOpenButton(aFrame))
|
2008-07-12 09:15:07 +00:00
|
|
|
aState |= DFCS_PUSHED;
|
2009-03-13 12:23:26 +00:00
|
|
|
else if (IsCheckedButton(aFrame))
|
2008-07-12 09:15:07 +00:00
|
|
|
aState |= DFCS_CHECKED;
|
2005-08-20 07:13:11 +00:00
|
|
|
else {
|
|
|
|
if (contentState & NS_EVENT_STATE_ACTIVE && contentState & NS_EVENT_STATE_HOVER) {
|
|
|
|
aState |= DFCS_PUSHED;
|
2005-08-20 07:13:26 +00:00
|
|
|
const nsStyleUserInterface *uiData = aFrame->GetStyleUserInterface();
|
2005-08-20 07:13:11 +00:00
|
|
|
// The down state is flat if the button is focusable
|
2005-08-20 07:13:26 +00:00
|
|
|
if (uiData->mUserFocus == NS_STYLE_USER_FOCUS_NORMAL) {
|
2005-08-20 07:14:19 +00:00
|
|
|
#ifndef WINCE
|
2009-08-24 20:02:07 +00:00
|
|
|
if (!aFrame->GetContent()->IsHTML())
|
2005-08-20 07:13:11 +00:00
|
|
|
aState |= DFCS_FLAT;
|
2005-08-20 07:14:19 +00:00
|
|
|
#endif
|
2005-08-20 07:13:11 +00:00
|
|
|
aFocused = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((contentState & NS_EVENT_STATE_FOCUS) ||
|
2005-08-20 07:13:56 +00:00
|
|
|
(aState == DFCS_BUTTONPUSH && IsDefaultButton(aFrame))) {
|
2005-08-20 07:13:11 +00:00
|
|
|
aFocused = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_CHECKBOX:
|
2008-11-03 13:12:59 +00:00
|
|
|
case NS_THEME_RADIO: {
|
2009-02-05 08:17:08 +00:00
|
|
|
PRInt32 contentState;
|
2005-08-20 07:13:11 +00:00
|
|
|
aFocused = PR_FALSE;
|
|
|
|
|
|
|
|
aPart = DFC_BUTTON;
|
2009-02-05 08:17:08 +00:00
|
|
|
aState = 0;
|
2005-08-20 07:13:33 +00:00
|
|
|
nsIContent* content = aFrame->GetContent();
|
2009-02-05 08:17:08 +00:00
|
|
|
PRBool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
|
|
|
|
PRBool isChecked = GetCheckedOrSelected(aFrame, !isCheckbox);
|
|
|
|
PRBool isIndeterminate = isCheckbox && GetIndeterminate(aFrame);
|
|
|
|
|
|
|
|
if (isCheckbox) {
|
|
|
|
// indeterminate state takes precedence over checkedness.
|
|
|
|
if (isIndeterminate) {
|
|
|
|
aState = DFCS_BUTTON3STATE | DFCS_CHECKED;
|
|
|
|
} else {
|
|
|
|
aState = DFCS_BUTTONCHECK;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
2009-02-05 08:17:08 +00:00
|
|
|
} else {
|
|
|
|
aState = DFCS_BUTTONRADIO;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
2009-02-05 08:17:08 +00:00
|
|
|
if (isChecked) {
|
|
|
|
aState |= DFCS_CHECKED;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
|
2009-02-05 08:17:08 +00:00
|
|
|
contentState = GetContentState(aFrame, aWidgetType);
|
2009-08-24 20:02:07 +00:00
|
|
|
if (!content->IsXUL() &&
|
2009-02-05 08:17:08 +00:00
|
|
|
(contentState & NS_EVENT_STATE_FOCUS)) {
|
|
|
|
aFocused = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame)) {
|
2005-08-20 07:13:11 +00:00
|
|
|
aState |= DFCS_INACTIVE;
|
2009-02-05 08:17:08 +00:00
|
|
|
} else if (contentState & NS_EVENT_STATE_ACTIVE &&
|
|
|
|
contentState & NS_EVENT_STATE_HOVER) {
|
2005-08-20 07:13:11 +00:00
|
|
|
aState |= DFCS_PUSHED;
|
2009-02-05 08:17:08 +00:00
|
|
|
}
|
|
|
|
|
2005-08-20 07:13:11 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM: {
|
|
|
|
PRBool isTopLevel = PR_FALSE;
|
|
|
|
PRBool isOpen = PR_FALSE;
|
|
|
|
PRBool isContainer = PR_FALSE;
|
2009-01-12 19:20:59 +00:00
|
|
|
nsIMenuFrame *menuFrame = do_QueryFrame(aFrame);
|
2005-10-07 00:31:36 +00:00
|
|
|
|
|
|
|
// We indicate top-level-ness using aPart. 0 is a normal menu item,
|
|
|
|
// 1 is a top-level menu item. The state of the item is composed of
|
|
|
|
// DFCS_* flags only.
|
|
|
|
aPart = 0;
|
|
|
|
aState = 0;
|
|
|
|
|
|
|
|
if (menuFrame) {
|
|
|
|
// If this is a real menu item, we should check if it is part of the
|
|
|
|
// main menu bar or not, and if it is a container, as these affect
|
|
|
|
// rendering.
|
2007-07-04 15:49:38 +00:00
|
|
|
isTopLevel = menuFrame->IsOnMenuBar();
|
|
|
|
isOpen = menuFrame->IsOpen();
|
|
|
|
isContainer = menuFrame->IsMenu();
|
2005-10-07 00:31:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame))
|
|
|
|
aState |= DFCS_INACTIVE;
|
|
|
|
|
|
|
|
if (isTopLevel) {
|
|
|
|
aPart = 1;
|
|
|
|
if (isOpen)
|
|
|
|
aState |= DFCS_PUSHED;
|
|
|
|
}
|
|
|
|
|
2008-03-06 20:56:47 +00:00
|
|
|
if (IsMenuActive(aFrame, aWidgetType))
|
2005-10-07 00:31:36 +00:00
|
|
|
aState |= DFCS_HOT;
|
|
|
|
|
2007-07-14 15:11:37 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
2008-02-29 05:10:12 +00:00
|
|
|
case NS_THEME_MENUARROW: {
|
2007-07-14 15:11:37 +00:00
|
|
|
aState = 0;
|
|
|
|
if (IsDisabled(aFrame))
|
|
|
|
aState |= DFCS_INACTIVE;
|
2008-03-06 20:56:47 +00:00
|
|
|
if (IsMenuActive(aFrame, aWidgetType))
|
2007-07-14 15:11:37 +00:00
|
|
|
aState |= DFCS_HOT;
|
2008-02-29 05:10:12 +00:00
|
|
|
|
2007-07-14 15:11:37 +00:00
|
|
|
if (aWidgetType == NS_THEME_MENUCHECKBOX || aWidgetType == NS_THEME_MENURADIO) {
|
2005-10-07 00:31:36 +00:00
|
|
|
if (IsCheckedButton(aFrame))
|
|
|
|
aState |= DFCS_CHECKED;
|
2008-07-18 20:55:25 +00:00
|
|
|
} else if (IsFrameRTL(aFrame)) {
|
2007-07-14 15:11:37 +00:00
|
|
|
aState |= DFCS_RTL;
|
2005-10-07 00:31:36 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
2008-02-29 05:10:12 +00:00
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-07 02:06:58 +00:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_TEXTFIELD:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
2006-05-30 13:50:48 +00:00
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
case NS_THEME_TAB:
|
|
|
|
case NS_THEME_TAB_PANEL:
|
|
|
|
case NS_THEME_TAB_PANELS:
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_MENUBAR:
|
|
|
|
case NS_THEME_MENUPOPUP:
|
2009-03-12 02:11:01 +00:00
|
|
|
case NS_THEME_GROUPBOX:
|
2005-08-20 07:13:11 +00:00
|
|
|
// these don't use DrawFrameControl
|
|
|
|
return NS_OK;
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON: {
|
|
|
|
|
|
|
|
aPart = DFC_SCROLL;
|
|
|
|
aState = DFCS_SCROLLCOMBOBOX;
|
2009-03-13 12:23:26 +00:00
|
|
|
|
2005-08-20 07:13:33 +00:00
|
|
|
nsIFrame* parentFrame = aFrame->GetParent();
|
2009-03-13 12:23:26 +00:00
|
|
|
PRBool isHTML = IsHTMLContent(aFrame);
|
|
|
|
PRBool isMenulist = !isHTML && parentFrame->GetType() == nsWidgetAtoms::menuFrame;
|
|
|
|
PRBool isOpen = PR_FALSE;
|
2005-08-20 07:13:11 +00:00
|
|
|
|
2009-03-13 12:23:26 +00:00
|
|
|
// HTML select and XUL menulist dropdown buttons get state from the parent.
|
|
|
|
if (isHTML || isMenulist)
|
|
|
|
aFrame = parentFrame;
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame)) {
|
2005-08-20 07:13:11 +00:00
|
|
|
aState |= DFCS_INACTIVE;
|
2009-03-13 12:23:26 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-03-14 09:20:38 +00:00
|
|
|
#ifndef WINCE
|
2009-03-13 12:23:26 +00:00
|
|
|
if (isHTML) {
|
|
|
|
nsIComboboxControlFrame* ccf = do_QueryFrame(aFrame);
|
|
|
|
isOpen = (ccf && ccf->IsDroppedDown());
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
2009-03-13 12:23:26 +00:00
|
|
|
else
|
|
|
|
isOpen = IsOpenButton(aFrame);
|
|
|
|
|
|
|
|
// XXX Button should look active until the mouse is released, but
|
|
|
|
// without making it look active when the popup is clicked.
|
|
|
|
if (isOpen && (isHTML || isMenulist))
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
|
|
|
|
|
|
|
// Dropdown button active state doesn't need :hover.
|
|
|
|
if (eventState & NS_EVENT_STATE_ACTIVE)
|
|
|
|
aState |= DFCS_PUSHED | DFCS_FLAT;
|
2009-03-14 09:20:38 +00:00
|
|
|
#endif
|
2005-08-20 07:13:11 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT: {
|
|
|
|
PRInt32 contentState;
|
|
|
|
|
|
|
|
aPart = DFC_SCROLL;
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
aState = DFCS_SCROLLUP;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
aState = DFCS_SCROLLDOWN;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
aState = DFCS_SCROLLLEFT;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
aState = DFCS_SCROLLRIGHT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame))
|
|
|
|
aState |= DFCS_INACTIVE;
|
|
|
|
else {
|
2005-08-20 07:13:56 +00:00
|
|
|
contentState = GetContentState(aFrame, aWidgetType);
|
2005-08-20 07:14:19 +00:00
|
|
|
#ifndef WINCE
|
2005-08-20 07:13:11 +00:00
|
|
|
if (contentState & NS_EVENT_STATE_HOVER && contentState & NS_EVENT_STATE_ACTIVE)
|
|
|
|
aState |= DFCS_PUSHED | DFCS_FLAT;
|
2005-08-20 07:14:19 +00:00
|
|
|
#endif
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_SPINNER_UP_BUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWN_BUTTON: {
|
|
|
|
PRInt32 contentState;
|
|
|
|
|
|
|
|
aPart = DFC_SCROLL;
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_SPINNER_UP_BUTTON:
|
|
|
|
aState = DFCS_SCROLLUP;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
|
|
|
aState = DFCS_SCROLLDOWN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsDisabled(aFrame))
|
|
|
|
aState |= DFCS_INACTIVE;
|
|
|
|
else {
|
2005-08-20 07:13:56 +00:00
|
|
|
contentState = GetContentState(aFrame, aWidgetType);
|
2005-08-20 07:13:11 +00:00
|
|
|
if (contentState & NS_EVENT_STATE_HOVER && contentState & NS_EVENT_STATE_ACTIVE)
|
|
|
|
aState |= DFCS_PUSHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
case NS_THEME_RESIZER:
|
|
|
|
aPart = DFC_SCROLL;
|
2009-01-05 18:17:44 +00:00
|
|
|
#ifndef WINCE
|
2009-01-18 10:28:19 +00:00
|
|
|
aState = (IsFrameRTL(aFrame)) ?
|
|
|
|
DFCS_SCROLLSIZEGRIPRIGHT : DFCS_SCROLLSIZEGRIP;
|
2009-01-05 18:17:44 +00:00
|
|
|
#else
|
|
|
|
aState = 0;
|
|
|
|
#endif
|
2005-08-20 07:13:11 +00:00
|
|
|
return NS_OK;
|
2007-08-06 17:45:57 +00:00
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
aPart = 0;
|
|
|
|
aState = 0;
|
|
|
|
return NS_OK;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw classic Windows tab
|
|
|
|
// (no system API for this, but DrawEdge can draw all the parts of a tab)
|
|
|
|
static void DrawTab(HDC hdc, const RECT& R, PRInt32 aPosition, PRBool aSelected,
|
|
|
|
PRBool aDrawLeft, PRBool aDrawRight)
|
|
|
|
{
|
|
|
|
PRInt32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
|
|
|
|
RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
|
|
|
|
PRInt32 selectedOffset, lOffset, rOffset;
|
|
|
|
|
|
|
|
selectedOffset = aSelected ? 1 : 0;
|
|
|
|
lOffset = aDrawLeft ? 2 : 0;
|
|
|
|
rOffset = aDrawRight ? 2 : 0;
|
|
|
|
|
|
|
|
// Get info for tab orientation/position (Left, Top, Right, Bottom)
|
|
|
|
switch (aPosition) {
|
|
|
|
case BF_LEFT:
|
|
|
|
leftFlag = BF_TOP; topFlag = BF_LEFT;
|
|
|
|
rightFlag = BF_BOTTOM;
|
|
|
|
lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
|
|
|
|
shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
|
|
|
|
|
|
|
|
::SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
|
|
|
|
::SetRect(&sideRect, R.left+2, R.top, R.right-2+selectedOffset, R.bottom);
|
|
|
|
::SetRect(&bottomRect, R.right-2, R.top, R.right, R.bottom);
|
|
|
|
::SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
|
|
|
|
::SetRect(&shadeRect, R.left+1, R.bottom-2, R.left+2, R.bottom-1);
|
|
|
|
break;
|
|
|
|
case BF_TOP:
|
|
|
|
leftFlag = BF_LEFT; topFlag = BF_TOP;
|
|
|
|
rightFlag = BF_RIGHT;
|
|
|
|
lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
|
|
|
|
shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
|
|
|
|
|
|
|
|
::SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
|
|
|
|
::SetRect(&sideRect, R.left, R.top+2, R.right, R.bottom-1+selectedOffset);
|
|
|
|
::SetRect(&bottomRect, R.left, R.bottom-1, R.right, R.bottom);
|
|
|
|
::SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
|
|
|
|
::SetRect(&shadeRect, R.right-2, R.top+1, R.right-1, R.top+2);
|
|
|
|
break;
|
|
|
|
case BF_RIGHT:
|
|
|
|
leftFlag = BF_TOP; topFlag = BF_RIGHT;
|
|
|
|
rightFlag = BF_BOTTOM;
|
|
|
|
lightFlag = BF_DIAGONAL_ENDTOPLEFT;
|
|
|
|
shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
|
|
|
|
|
|
|
|
::SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
|
|
|
|
::SetRect(&sideRect, R.left+2-selectedOffset, R.top, R.right-2, R.bottom);
|
|
|
|
::SetRect(&bottomRect, R.left, R.top, R.left+2, R.bottom);
|
|
|
|
::SetRect(&lightRect, R.right-3, R.top, R.right-1, R.top+2);
|
|
|
|
::SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
|
|
|
|
break;
|
|
|
|
case BF_BOTTOM:
|
|
|
|
leftFlag = BF_LEFT; topFlag = BF_BOTTOM;
|
|
|
|
rightFlag = BF_RIGHT;
|
|
|
|
lightFlag = BF_DIAGONAL_ENDTOPLEFT;
|
|
|
|
shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
|
|
|
|
|
|
|
|
::SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
|
|
|
|
::SetRect(&sideRect, R.left, R.top+2-selectedOffset, R.right, R.bottom-2);
|
|
|
|
::SetRect(&bottomRect, R.left, R.top, R.right, R.top+2);
|
|
|
|
::SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
|
|
|
|
::SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Background
|
|
|
|
::FillRect(hdc, &R, (HBRUSH) (COLOR_3DFACE+1) );
|
|
|
|
|
|
|
|
// Tab "Top"
|
|
|
|
::DrawEdge(hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
|
|
|
|
|
|
|
|
// Tab "Bottom"
|
|
|
|
if (!aSelected)
|
|
|
|
::DrawEdge(hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
|
|
|
|
|
|
|
|
// Tab "Sides"
|
|
|
|
if (!aDrawLeft)
|
|
|
|
leftFlag = 0;
|
|
|
|
if (!aDrawRight)
|
|
|
|
rightFlag = 0;
|
|
|
|
::DrawEdge(hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
|
|
|
|
|
|
|
|
// Tab Diagonal Corners
|
|
|
|
if (aDrawLeft)
|
|
|
|
::DrawEdge(hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
|
|
|
|
|
|
|
|
if (aDrawRight)
|
|
|
|
::DrawEdge(hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
|
|
|
|
}
|
|
|
|
|
2005-10-13 15:07:56 +00:00
|
|
|
#ifndef WINCE
|
2005-10-07 00:31:36 +00:00
|
|
|
static void DrawMenuImage(HDC hdc, const RECT& rc, PRInt32 aComponent, PRUint32 aColor)
|
|
|
|
{
|
|
|
|
// This procedure creates a memory bitmap to contain the check mark, draws
|
|
|
|
// it into the bitmap (it is a mask image), then composes it onto the menu
|
|
|
|
// item in appropriate colors.
|
|
|
|
HDC hMemoryDC = ::CreateCompatibleDC(hdc);
|
|
|
|
if (hMemoryDC) {
|
|
|
|
// XXXjgr We should ideally be caching these, but we wont be notified when
|
|
|
|
// they change currently, so we can't do so easily. Same for the bitmap.
|
|
|
|
int checkW = ::GetSystemMetrics(SM_CXMENUCHECK);
|
|
|
|
int checkH = ::GetSystemMetrics(SM_CYMENUCHECK);
|
|
|
|
|
|
|
|
HBITMAP hMonoBitmap = ::CreateBitmap(checkW, checkH, 1, 1, NULL);
|
|
|
|
if (hMonoBitmap) {
|
|
|
|
|
|
|
|
HBITMAP hPrevBitmap = (HBITMAP) ::SelectObject(hMemoryDC, hMonoBitmap);
|
|
|
|
if (hPrevBitmap) {
|
|
|
|
|
|
|
|
// XXXjgr This will go pear-shaped if the image is bigger than the
|
|
|
|
// provided rect. What should we do?
|
|
|
|
RECT imgRect = { 0, 0, checkW, checkH };
|
|
|
|
POINT imgPos = {
|
|
|
|
rc.left + (rc.right - rc.left - checkW) / 2,
|
|
|
|
rc.top + (rc.bottom - rc.top - checkH) / 2
|
|
|
|
};
|
|
|
|
|
2007-07-14 15:11:37 +00:00
|
|
|
// XXXzeniko Windows renders these 1px lower than you'd expect
|
|
|
|
if (aComponent == DFCS_MENUCHECK || aComponent == DFCS_MENUBULLET)
|
|
|
|
imgPos.y++;
|
|
|
|
|
2005-10-07 00:31:36 +00:00
|
|
|
::DrawFrameControl(hMemoryDC, &imgRect, DFC_MENU, aComponent);
|
|
|
|
COLORREF oldTextCol = ::SetTextColor(hdc, 0x00000000);
|
|
|
|
COLORREF oldBackCol = ::SetBkColor(hdc, 0x00FFFFFF);
|
|
|
|
::BitBlt(hdc, imgPos.x, imgPos.y, checkW, checkH, hMemoryDC, 0, 0, SRCAND);
|
|
|
|
::SetTextColor(hdc, ::GetSysColor(aColor));
|
|
|
|
::SetBkColor(hdc, 0x00000000);
|
|
|
|
::BitBlt(hdc, imgPos.x, imgPos.y, checkW, checkH, hMemoryDC, 0, 0, SRCPAINT);
|
|
|
|
::SetTextColor(hdc, oldTextCol);
|
|
|
|
::SetBkColor(hdc, oldBackCol);
|
|
|
|
::SelectObject(hMemoryDC, hPrevBitmap);
|
|
|
|
}
|
|
|
|
::DeleteObject(hMonoBitmap);
|
|
|
|
}
|
|
|
|
::DeleteDC(hMemoryDC);
|
|
|
|
}
|
|
|
|
}
|
2005-10-13 15:07:56 +00:00
|
|
|
#endif
|
2005-10-07 00:31:36 +00:00
|
|
|
|
2006-05-30 13:50:48 +00:00
|
|
|
void nsNativeThemeWin::DrawCheckedRect(HDC hdc, const RECT& rc, PRInt32 fore, PRInt32 back,
|
|
|
|
HBRUSH defaultBack)
|
|
|
|
{
|
|
|
|
static WORD patBits[8] = {
|
|
|
|
0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
|
|
|
|
};
|
|
|
|
|
|
|
|
HBITMAP patBmp = ::CreateBitmap(8, 8, 1, 1, patBits);
|
|
|
|
if (patBmp) {
|
|
|
|
HBRUSH brush = (HBRUSH) ::CreatePatternBrush(patBmp);
|
|
|
|
if (brush) {
|
|
|
|
COLORREF oldForeColor = ::SetTextColor(hdc, ::GetSysColor(fore));
|
|
|
|
COLORREF oldBackColor = ::SetBkColor(hdc, ::GetSysColor(back));
|
2006-07-11 23:13:21 +00:00
|
|
|
POINT vpOrg;
|
2006-05-30 13:50:48 +00:00
|
|
|
|
|
|
|
#ifndef WINCE
|
|
|
|
::UnrealizeObject(brush);
|
|
|
|
#endif
|
2006-07-11 23:13:21 +00:00
|
|
|
::GetViewportOrgEx(hdc, &vpOrg);
|
|
|
|
::SetBrushOrgEx(hdc, vpOrg.x + rc.left, vpOrg.y + rc.top, NULL);
|
2006-05-30 13:50:48 +00:00
|
|
|
HBRUSH oldBrush = (HBRUSH) ::SelectObject(hdc, brush);
|
|
|
|
::FillRect(hdc, &rc, brush);
|
|
|
|
::SetTextColor(hdc, oldForeColor);
|
|
|
|
::SetBkColor(hdc, oldBackColor);
|
|
|
|
::SelectObject(hdc, oldBrush);
|
|
|
|
::DeleteObject(brush);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
::FillRect(hdc, &rc, defaultBack);
|
|
|
|
|
|
|
|
::DeleteObject(patBmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-20 07:13:11 +00:00
|
|
|
nsresult nsNativeThemeWin::ClassicDrawWidgetBackground(nsIRenderingContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
|
|
|
const nsRect& aRect,
|
2008-07-24 23:01:59 +00:00
|
|
|
const nsRect& aDirtyRect)
|
2007-03-03 00:18:34 +00:00
|
|
|
{
|
2005-08-20 07:13:11 +00:00
|
|
|
PRInt32 part, state;
|
|
|
|
PRBool focused;
|
|
|
|
nsresult rv;
|
|
|
|
rv = ClassicGetThemePartAndState(aFrame, aWidgetType, part, state, focused);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2005-08-23 02:11:54 +00:00
|
|
|
nsCOMPtr<nsIDeviceContext> dc;
|
|
|
|
aContext->GetDeviceContext(*getter_AddRefs(dc));
|
2007-06-27 16:42:37 +00:00
|
|
|
gfxFloat p2a = gfxFloat(dc->AppUnitsPerDevPixel());
|
2005-08-20 07:13:11 +00:00
|
|
|
RECT widgetRect;
|
2007-06-27 16:42:37 +00:00
|
|
|
gfxRect tr(aRect.x, aRect.y, aRect.width, aRect.height),
|
2008-07-24 23:01:59 +00:00
|
|
|
dr(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
|
2005-08-20 07:13:11 +00:00
|
|
|
|
2007-06-27 16:42:37 +00:00
|
|
|
tr.ScaleInverse(p2a);
|
2008-07-24 23:01:59 +00:00
|
|
|
dr.ScaleInverse(p2a);
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-12-18 23:01:15 +00:00
|
|
|
nsRefPtr<gfxContext> ctx = aContext->ThebesContext();
|
2006-06-06 19:01:58 +00:00
|
|
|
|
2008-07-24 23:01:59 +00:00
|
|
|
gfxWindowsNativeDrawing nativeDrawing(ctx, dr, GetWidgetNativeDrawingFlags(aWidgetType));
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
RENDER_AGAIN:
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
HDC hdc = nativeDrawing.BeginNativeDrawing();
|
2007-08-09 18:54:17 +00:00
|
|
|
if (!hdc)
|
|
|
|
return NS_ERROR_FAILURE;
|
2006-02-09 01:24:30 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
nativeDrawing.TransformToNativeRect(tr, widgetRect);
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
rv = NS_OK;
|
2005-08-20 07:13:11 +00:00
|
|
|
switch (aWidgetType) {
|
|
|
|
// Draw button
|
|
|
|
case NS_THEME_BUTTON: {
|
|
|
|
if (focused) {
|
|
|
|
// draw dark button focus border first
|
|
|
|
HBRUSH brush;
|
|
|
|
brush = ::GetSysColorBrush(COLOR_3DDKSHADOW);
|
|
|
|
if (brush)
|
|
|
|
::FrameRect(hdc, &widgetRect, brush);
|
|
|
|
InflateRect(&widgetRect, -1, -1);
|
|
|
|
}
|
|
|
|
// fall-through...
|
|
|
|
}
|
|
|
|
// Draw controls supported by DrawFrameControl
|
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_RADIO:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
case NS_THEME_SPINNER_UP_BUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_RESIZER: {
|
2005-08-20 07:13:11 +00:00
|
|
|
PRInt32 oldTA;
|
|
|
|
// setup DC to make DrawFrameControl draw correctly
|
|
|
|
oldTA = ::SetTextAlign(hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP);
|
|
|
|
::DrawFrameControl(hdc, &widgetRect, part, state);
|
|
|
|
::SetTextAlign(hdc, oldTA);
|
|
|
|
|
|
|
|
// Draw focus rectangles for HTML checkboxes and radio buttons
|
|
|
|
// XXX it'd be nice to draw these outside of the frame
|
2008-11-03 13:12:59 +00:00
|
|
|
if (focused && (aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_RADIO)) {
|
2005-08-20 07:13:11 +00:00
|
|
|
// setup DC to make DrawFocusRect draw correctly
|
2006-07-11 23:13:21 +00:00
|
|
|
POINT vpOrg;
|
|
|
|
::GetViewportOrgEx(hdc, &vpOrg);
|
|
|
|
::SetBrushOrgEx(hdc, vpOrg.x + widgetRect.left, vpOrg.y + widgetRect.top, NULL);
|
2005-08-20 07:13:11 +00:00
|
|
|
PRInt32 oldColor;
|
|
|
|
oldColor = ::SetTextColor(hdc, 0);
|
|
|
|
// draw focus rectangle
|
|
|
|
::DrawFocusRect(hdc, &widgetRect);
|
|
|
|
::SetTextColor(hdc, oldColor);
|
|
|
|
}
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
// Draw controls with 2px 3D inset border
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-07 02:06:58 +00:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2005-08-20 07:13:56 +00:00
|
|
|
case NS_THEME_LISTBOX:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_TEXTFIELD: {
|
|
|
|
// Draw inset edge
|
|
|
|
::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
|
|
|
|
2005-08-20 07:13:24 +00:00
|
|
|
// Fill in background
|
2005-08-20 07:13:33 +00:00
|
|
|
if (IsDisabled(aFrame) ||
|
2009-08-24 20:02:07 +00:00
|
|
|
(aFrame->GetContent()->IsXUL() &&
|
2005-08-20 07:13:33 +00:00
|
|
|
IsReadOnly(aFrame)))
|
2005-08-20 07:13:24 +00:00
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_BTNFACE+1));
|
|
|
|
else
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_WINDOW+1));
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:24 +00:00
|
|
|
}
|
|
|
|
case NS_THEME_TREEVIEW: {
|
|
|
|
// Draw inset edge
|
|
|
|
::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
|
|
|
|
2005-08-20 07:13:11 +00:00
|
|
|
// Fill in window color background
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_WINDOW+1));
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
// Draw ToolTip background
|
|
|
|
case NS_THEME_TOOLTIP:
|
2007-06-30 05:00:02 +00:00
|
|
|
::FrameRect(hdc, &widgetRect, ::GetSysColorBrush(COLOR_WINDOWFRAME));
|
2005-08-20 07:13:11 +00:00
|
|
|
InflateRect(&widgetRect, -1, -1);
|
2007-06-30 05:00:02 +00:00
|
|
|
::FillRect(hdc, &widgetRect, ::GetSysColorBrush(COLOR_INFOBK));
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2009-03-12 02:11:01 +00:00
|
|
|
break;
|
|
|
|
case NS_THEME_GROUPBOX:
|
|
|
|
::DrawEdge(hdc, &widgetRect, EDGE_ETCHED, BF_RECT | BF_ADJUST);
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_BTNFACE+1));
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
// Draw 3D face background controls
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
2005-08-20 07:14:29 +00:00
|
|
|
// Draw 3D border
|
|
|
|
::DrawEdge(hdc, &widgetRect, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE);
|
|
|
|
InflateRect(&widgetRect, -1, -1);
|
|
|
|
// fall through
|
|
|
|
case NS_THEME_TAB_PANEL:
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL: {
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_BTNFACE+1));
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
// Draw 3D inset statusbar panel
|
|
|
|
case NS_THEME_STATUSBAR_PANEL: {
|
2005-08-20 07:13:33 +00:00
|
|
|
if (aFrame->GetNextSibling())
|
2005-08-20 07:13:11 +00:00
|
|
|
widgetRect.right -= 2; // space between sibling status panels
|
|
|
|
|
|
|
|
::DrawEdge(hdc, &widgetRect, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE);
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
// Draw scrollbar thumb
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2006-05-30 13:50:48 +00:00
|
|
|
break;
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
|
|
|
|
if (IsDisabled(aFrame)) {
|
|
|
|
DrawCheckedRect(hdc, widgetRect, COLOR_3DFACE, COLOR_3DHILIGHT,
|
|
|
|
(HBRUSH) COLOR_3DHILIGHT);
|
|
|
|
}
|
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
// Draw scrollbar track background
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: {
|
|
|
|
|
|
|
|
// Windows fills in the scrollbar track differently
|
|
|
|
// depending on whether these are equal
|
|
|
|
DWORD color3D, colorScrollbar, colorWindow;
|
|
|
|
|
|
|
|
color3D = ::GetSysColor(COLOR_3DFACE);
|
|
|
|
colorWindow = ::GetSysColor(COLOR_WINDOW);
|
|
|
|
colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
|
|
|
|
|
|
|
|
if ((color3D != colorScrollbar) && (colorWindow != colorScrollbar))
|
|
|
|
// Use solid brush
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_SCROLLBAR+1));
|
|
|
|
else
|
|
|
|
{
|
2006-05-30 13:50:48 +00:00
|
|
|
DrawCheckedRect(hdc, widgetRect, COLOR_3DHILIGHT, COLOR_3DFACE,
|
|
|
|
(HBRUSH) COLOR_SCROLLBAR+1);
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
// XXX should invert the part of the track being clicked here
|
|
|
|
// but the track is never :active
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
2006-05-30 13:50:48 +00:00
|
|
|
// Draw scale track background
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
case NS_THEME_SCALE_HORIZONTAL: {
|
|
|
|
if (aWidgetType == NS_THEME_SCALE_HORIZONTAL) {
|
|
|
|
PRInt32 adjustment = (widgetRect.bottom - widgetRect.top) / 2 - 2;
|
|
|
|
widgetRect.top += adjustment;
|
|
|
|
widgetRect.bottom -= adjustment;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
PRInt32 adjustment = (widgetRect.right - widgetRect.left) / 2 - 2;
|
|
|
|
widgetRect.left += adjustment;
|
|
|
|
widgetRect.right -= adjustment;
|
|
|
|
}
|
|
|
|
|
|
|
|
::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) GetStockObject(GRAY_BRUSH));
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_HIGHLIGHT+1));
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
// Draw Tab
|
2009-01-04 14:01:48 +00:00
|
|
|
case NS_THEME_TAB: {
|
2005-08-20 07:13:11 +00:00
|
|
|
DrawTab(hdc, widgetRect,
|
|
|
|
IsBottomTab(aFrame) ? BF_BOTTOM : BF_TOP,
|
2005-08-20 07:13:56 +00:00
|
|
|
IsSelectedTab(aFrame),
|
2009-01-04 14:01:48 +00:00
|
|
|
!IsRightToSelectedTab(aFrame),
|
|
|
|
!IsLeftToSelectedTab(aFrame));
|
2005-08-20 07:13:11 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
case NS_THEME_TAB_PANELS:
|
|
|
|
::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_MIDDLE |
|
|
|
|
BF_LEFT | BF_RIGHT | BF_BOTTOM);
|
2005-10-06 04:02:10 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_MENUBAR:
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_MENUPOPUP:
|
2008-07-17 17:19:10 +00:00
|
|
|
NS_ASSERTION(nsUXThemeData::sFlatMenus, "Classic menus are styled entirely through CSS");
|
2007-07-14 15:11:37 +00:00
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_MENU+1));
|
|
|
|
::FrameRect(hdc, &widgetRect, ::GetSysColorBrush(COLOR_BTNSHADOW));
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-10-07 00:31:36 +00:00
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
2007-07-14 15:11:37 +00:00
|
|
|
case NS_THEME_RADIOMENUITEM:
|
2005-10-07 00:31:36 +00:00
|
|
|
// part == 0 for normal items
|
|
|
|
// part == 1 for top-level menu items
|
2008-07-17 17:19:10 +00:00
|
|
|
if (nsUXThemeData::sFlatMenus) {
|
2005-10-07 00:31:36 +00:00
|
|
|
// Not disabled and hot/pushed.
|
|
|
|
if ((state & (DFCS_HOT | DFCS_PUSHED)) != 0) {
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_MENUHILIGHT+1));
|
|
|
|
::FrameRect(hdc, &widgetRect, ::GetSysColorBrush(COLOR_HIGHLIGHT));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (part == 1) {
|
|
|
|
if ((state & DFCS_INACTIVE) == 0) {
|
|
|
|
if ((state & DFCS_PUSHED) != 0) {
|
|
|
|
::DrawEdge(hdc, &widgetRect, BDR_SUNKENOUTER, BF_RECT);
|
|
|
|
} else if ((state & DFCS_HOT) != 0) {
|
|
|
|
::DrawEdge(hdc, &widgetRect, BDR_RAISEDINNER, BF_RECT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((state & (DFCS_HOT | DFCS_PUSHED)) != 0) {
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_HIGHLIGHT+1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-07-14 15:11:37 +00:00
|
|
|
break;
|
2005-10-13 15:07:56 +00:00
|
|
|
#ifndef WINCE
|
2007-07-14 15:11:37 +00:00
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
|
|
|
if (!(state & DFCS_CHECKED))
|
|
|
|
break; // nothin' to do
|
|
|
|
case NS_THEME_MENUARROW: {
|
|
|
|
PRUint32 color = COLOR_MENUTEXT;
|
|
|
|
if ((state & DFCS_INACTIVE))
|
|
|
|
color = COLOR_GRAYTEXT;
|
|
|
|
else if ((state & DFCS_HOT))
|
|
|
|
color = COLOR_HIGHLIGHTTEXT;
|
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_MENUCHECKBOX)
|
|
|
|
DrawMenuImage(hdc, widgetRect, DFCS_MENUCHECK, color);
|
|
|
|
else if (aWidgetType == NS_THEME_MENURADIO)
|
|
|
|
DrawMenuImage(hdc, widgetRect, DFCS_MENUBULLET, color);
|
|
|
|
else if (aWidgetType == NS_THEME_MENUARROW)
|
|
|
|
DrawMenuImage(hdc, widgetRect,
|
|
|
|
(state & DFCS_RTL) ? DFCS_MENUARROWRIGHT : DFCS_MENUARROW,
|
|
|
|
color);
|
2005-11-16 13:51:47 +00:00
|
|
|
break;
|
2005-10-07 00:31:36 +00:00
|
|
|
}
|
2007-08-06 17:45:57 +00:00
|
|
|
case NS_THEME_MENUSEPARATOR: {
|
|
|
|
// separators are offset by a bit (see menu.css)
|
|
|
|
widgetRect.left++;
|
|
|
|
widgetRect.right--;
|
|
|
|
|
|
|
|
// This magic number is brought to you by the value in menu.css
|
|
|
|
widgetRect.top += 4;
|
|
|
|
// Our rectangles are 1 pixel high (see border size in menu.css)
|
|
|
|
widgetRect.bottom = widgetRect.top+1;
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_3DSHADOW+1));
|
|
|
|
widgetRect.top++;
|
|
|
|
widgetRect.bottom++;
|
|
|
|
::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_3DHILIGHT+1));
|
|
|
|
break;
|
|
|
|
}
|
2007-07-14 15:11:37 +00:00
|
|
|
#endif
|
2005-11-16 13:51:47 +00:00
|
|
|
default:
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
break;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
2006-01-20 04:14:05 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
nativeDrawing.EndNativeDrawing();
|
2006-08-09 20:25:07 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2006-08-09 20:25:07 +00:00
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
if (nativeDrawing.ShouldRenderAgain())
|
|
|
|
goto RENDER_AGAIN;
|
|
|
|
|
|
|
|
nativeDrawing.PaintToContext();
|
2006-01-20 04:14:05 +00:00
|
|
|
|
2005-11-16 13:51:47 +00:00
|
|
|
return rv;
|
2005-08-20 07:13:11 +00:00
|
|
|
}
|
|
|
|
|
2007-03-03 00:18:34 +00:00
|
|
|
PRUint32
|
|
|
|
nsNativeThemeWin::GetWidgetNativeDrawingFlags(PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-07 02:06:58 +00:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2007-03-03 00:18:34 +00:00
|
|
|
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_TEXTFIELD:
|
|
|
|
return
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_DRAW_TO_COLOR_ALPHA |
|
|
|
|
gfxWindowsNativeDrawing::CAN_AXIS_ALIGNED_SCALE |
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_COMPLEX_TRANSFORM;
|
|
|
|
|
|
|
|
// need to check these others
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SPINNER_UP_BUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
|
|
|
case NS_THEME_RESIZER:
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
case NS_THEME_TAB:
|
|
|
|
case NS_THEME_TAB_PANEL:
|
|
|
|
case NS_THEME_TAB_PANELS:
|
|
|
|
case NS_THEME_MENUBAR:
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
break;
|
|
|
|
|
|
|
|
// the dropdown button /almost/ renders correctly with scaling,
|
|
|
|
// except that the graphic in the dropdown button (the downward arrow)
|
|
|
|
// doesn't get scaled up.
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
// these are definitely no; they're all graphics that don't get scaled up
|
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_RADIO:
|
2009-03-12 02:11:01 +00:00
|
|
|
case NS_THEME_GROUPBOX:
|
2007-03-03 00:18:34 +00:00
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
2007-07-14 15:11:37 +00:00
|
|
|
case NS_THEME_MENUCHECKBOX:
|
|
|
|
case NS_THEME_MENURADIO:
|
|
|
|
case NS_THEME_MENUARROW:
|
2007-03-03 00:18:34 +00:00
|
|
|
return
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_DRAW_TO_COLOR_ALPHA |
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_AXIS_ALIGNED_SCALE |
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_COMPLEX_TRANSFORM;
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_DRAW_TO_COLOR_ALPHA |
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_AXIS_ALIGNED_SCALE |
|
|
|
|
gfxWindowsNativeDrawing::CANNOT_COMPLEX_TRANSFORM;
|
|
|
|
}
|
2005-08-20 07:13:11 +00:00
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
///////////////////////////////////////////
|
|
|
|
// Creation Routine
|
|
|
|
///////////////////////////////////////////
|
2009-02-18 18:38:37 +00:00
|
|
|
|
|
|
|
// from nsWindow.cpp
|
|
|
|
extern PRBool gDisableNativeTheme;
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
NS_METHOD NS_NewNativeTheme(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
|
|
{
|
2009-02-18 18:38:37 +00:00
|
|
|
if (gDisableNativeTheme)
|
|
|
|
return NS_ERROR_NO_INTERFACE;
|
|
|
|
|
2005-08-20 07:11:56 +00:00
|
|
|
if (aOuter)
|
|
|
|
return NS_ERROR_NO_AGGREGATION;
|
|
|
|
|
|
|
|
nsNativeThemeWin* theme = new nsNativeThemeWin();
|
|
|
|
if (!theme)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
return theme->QueryInterface(aIID, aResult);
|
2005-08-20 07:13:13 +00:00
|
|
|
}
|