mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 243078 - Native Theme Rendering for Windows XP Menus, toolbars
patch by silver@warwickcompsoc.co.uk r=dougt sr=neil
This commit is contained in:
parent
491b4ef092
commit
c644049326
@ -261,7 +261,7 @@
|
||||
|
||||
<toolbaritem id="personal-bookmarks" title="&bookmarksItem.title;" flex="1"
|
||||
class="chromeclass-directories">
|
||||
<stack id="bookmarks-stack" flex="1" style="min-width:0px; width:0px;"
|
||||
<stack id="bookmarks-stack" flex="1" style="min-width:0px; width:0px; overflow: hidden;"
|
||||
onpopupshowing="BookmarksToolbar.setOpenedMenu(event);"
|
||||
onpopuphidden="BookmarksToolbar.unsetOpenedMenu(event);">
|
||||
<hbox id="bookmarks-ptf" class="bookmarks-toolbar-items" contextmenu="bookmarks-context-menu"
|
||||
|
@ -979,36 +979,29 @@ var BookmarksToolbar =
|
||||
if (!buttons)
|
||||
return;
|
||||
var chevron = document.getElementById("bookmarks-chevron");
|
||||
var width = window.innerWidth;
|
||||
if (width == 0) { // hack for bug 266737
|
||||
var myToolbarItem = buttons.parentNode.parentNode;
|
||||
|
||||
var width = myToolbarItem.boxObject.width;
|
||||
if (width <= 0) { // hack for bug 266737
|
||||
window.addEventListener('focus', BookmarksToolbar.resizeFunc, false);
|
||||
return;
|
||||
}
|
||||
var myToolbar = buttons.parentNode.parentNode.parentNode;
|
||||
for (var i = myToolbar.childNodes.length-1; i >= 0; i--){
|
||||
var anItem = myToolbar.childNodes[i];
|
||||
if (anItem.id == "personal-bookmarks") {
|
||||
break;
|
||||
}
|
||||
width -= anItem.boxObject.width;
|
||||
}
|
||||
|
||||
var chevronWidth = 0;
|
||||
chevron.collapsed = false;
|
||||
chevronWidth = chevron.boxObject.width;
|
||||
chevron.collapsed = true;
|
||||
var overflowed = false;
|
||||
|
||||
var isLTR=window.getComputedStyle(document.getElementById("PersonalToolbar"),'').direction=='ltr';
|
||||
|
||||
// This 3 is to account for the 'padding-left: 3px;' in browser.xul.
|
||||
var usedWidth = 3;
|
||||
for (var i=0; i<buttons.childNodes.length; i++) {
|
||||
var button = buttons.childNodes[i];
|
||||
button.collapsed = overflowed;
|
||||
|
||||
if (i == buttons.childNodes.length - 1) // last ptf item...
|
||||
chevronWidth = 0;
|
||||
var offset = isLTR ? button.boxObject.x
|
||||
: width - button.boxObject.x;
|
||||
if (offset + button.boxObject.width + chevronWidth > width) {
|
||||
if (usedWidth + button.boxObject.width + chevronWidth > width) {
|
||||
overflowed = true;
|
||||
// This button doesn't fit. Show it in the menu. Hide it in the toolbar.
|
||||
if (!button.collapsed)
|
||||
@ -1016,11 +1009,10 @@ var BookmarksToolbar =
|
||||
if (chevron.collapsed) {
|
||||
chevron.collapsed = false;
|
||||
var overflowPadder = document.getElementById("overflow-padder");
|
||||
offset = isLTR ? buttons.boxObject.x
|
||||
: width - buttons.boxObject.x - buttons.boxObject.width;
|
||||
overflowPadder.width = width - chevron.boxObject.width - offset;
|
||||
overflowPadder.width = width - chevron.boxObject.width;
|
||||
}
|
||||
}
|
||||
usedWidth += button.boxObject.width;
|
||||
}
|
||||
BookmarksToolbarRDFObserver._overflowTimerInEffect = false;
|
||||
},
|
||||
|
@ -55,6 +55,11 @@
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
#navigator-toolbox {
|
||||
border-bottom-width: 1px;
|
||||
-moz-border-bottom-colors: ThreeDShadow;
|
||||
}
|
||||
|
||||
/* ..... fix searchbar "add engine" padding issue ..... */
|
||||
|
||||
#searchbar .searchbar-dropmarker menuseparator + menuitem {
|
||||
@ -106,6 +111,8 @@ toolbarbutton.bookmark-item[open="true"] {
|
||||
.bookmarks-toolbar-customize {
|
||||
display: none;
|
||||
max-width: 15em !important;
|
||||
border: none !important;
|
||||
-moz-appearance: none !important;
|
||||
}
|
||||
|
||||
toolbarpaletteitem[place="toolbar"] .bookmarks-toolbar-customize {
|
||||
@ -136,12 +143,12 @@ menuitem.bookmark-item {
|
||||
|
||||
/* ..... fix bookmarks padding issue ..... */
|
||||
|
||||
#menu_BookmarksPopup menuitem {
|
||||
-moz-padding-start: 4px;
|
||||
#menu_BookmarksPopup menuitem, .openintabs-menuitem {
|
||||
-moz-padding-start: 3px;
|
||||
}
|
||||
|
||||
#menu_BookmarksPopup menuitem.menuitem-iconic {
|
||||
-moz-padding-start: 0px;
|
||||
-moz-padding-start: 0px;
|
||||
}
|
||||
|
||||
|
||||
|
@ -144,6 +144,7 @@ CSS_KEY(-moz-malayalam, _moz_malayalam)
|
||||
CSS_KEY(-moz-marker, _moz_marker) // Disabled because not supported correctly.
|
||||
CSS_KEY(-moz-menuhover, _moz_menuhover)
|
||||
CSS_KEY(-moz-menuhovertext, _moz_menuhovertext)
|
||||
CSS_KEY(-moz-menubarhovertext, _moz_menubarhovertext)
|
||||
CSS_KEY(-moz-middle-with-baseline, _moz_middle_with_baseline)
|
||||
CSS_KEY(-moz-myanmar, _moz_myanmar)
|
||||
CSS_KEY(-moz-none, _moz_none)
|
||||
|
@ -437,6 +437,7 @@ const PRInt32 nsCSSProps::kColorKTable[] = {
|
||||
eCSSKeyword__moz_mac_accentdarkestshadow, nsILookAndFeel::eColor__moz_mac_accentdarkestshadow,
|
||||
eCSSKeyword__moz_menuhover, nsILookAndFeel::eColor__moz_menuhover,
|
||||
eCSSKeyword__moz_menuhovertext, nsILookAndFeel::eColor__moz_menuhovertext,
|
||||
eCSSKeyword__moz_menubarhovertext, nsILookAndFeel::eColor__moz_menubarhovertext,
|
||||
eCSSKeyword__moz_visitedhyperlinktext, NS_COLOR_MOZ_VISITEDHYPERLINKTEXT,
|
||||
eCSSKeyword_currentcolor, NS_COLOR_CURRENTCOLOR,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
|
@ -100,6 +100,7 @@ textbox.padded {
|
||||
|
||||
popup[type="autocomplete"],
|
||||
.autocomplete-history-popup {
|
||||
-moz-appearance: none;
|
||||
border-width: 1px;
|
||||
-moz-border-top-colors: ThreeDDarkShadow;
|
||||
-moz-border-right-colors: ThreeDDarkShadow;
|
||||
|
@ -171,8 +171,6 @@ sidebarheader {
|
||||
height: 25px;
|
||||
background-color: -moz-Dialog;
|
||||
-moz-appearance: toolbox;
|
||||
border-bottom: 1px solid ThreeDShadow;
|
||||
border-top: 1px solid ThreeDHighlight;
|
||||
}
|
||||
|
||||
sidebarheader > label {
|
||||
|
@ -46,14 +46,22 @@
|
||||
|
||||
menu,
|
||||
menuitem {
|
||||
-moz-appearance: menuitem;
|
||||
-moz-box-align: center;
|
||||
border: 1px solid transparent;
|
||||
color: MenuText;
|
||||
font: menu;
|
||||
list-style-image: none;
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
menuitem[type="checkbox"] {
|
||||
-moz-appearance: checkmenuitem;
|
||||
}
|
||||
|
||||
menuitem[type="radio"] {
|
||||
-moz-appearance: radiomenuitem;
|
||||
}
|
||||
|
||||
menuitem[default="true"] {
|
||||
font-weight: bold;
|
||||
}
|
||||
@ -70,10 +78,10 @@ menuitem[_moz-menuactive="true"][disabled="true"] {
|
||||
.menu-iconic-accel,
|
||||
.menu-text,
|
||||
.menu-iconic-text {
|
||||
margin-top: 2px !important;
|
||||
margin-top: 1px !important;
|
||||
margin-bottom: 2px !important;
|
||||
-moz-margin-start: 1px !important;
|
||||
-moz-margin-end: 2px !important;
|
||||
-moz-margin-start: 0px !important;
|
||||
-moz-margin-end: 0px !important;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@ -84,99 +92,64 @@ menuitem[_moz-menuactive="true"][disabled="true"] {
|
||||
|
||||
.menu-accel,
|
||||
.menu-iconic-accel {
|
||||
-moz-padding-end: 17px;
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 19px !important;
|
||||
-moz-margin-start: 8px !important;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.menu-iconic-text {
|
||||
-moz-margin-start: 2px !important;
|
||||
}
|
||||
|
||||
.menu-iconic-left {
|
||||
min-width: 12px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: 2px;
|
||||
padding: 1px;
|
||||
min-width: 15px;
|
||||
min-height: 15px;
|
||||
}
|
||||
|
||||
/* ..... menu arrow box ..... */
|
||||
|
||||
.menu-right {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 1px;
|
||||
-moz-margin-start: 0px;
|
||||
-moz-margin-end: 6px;
|
||||
list-style-image: url("chrome://global/skin/menu/Menu-arrow.png");
|
||||
margin-top: 2px;
|
||||
margin-bottom: 3px;
|
||||
-moz-padding-end: 6px;
|
||||
list-style-image: none;
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
.menu-right[_moz-menuactive="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/Menu-arrow-hover.png");
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
.menu-right[disabled="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/Menu-arrow-disabled.png") !important;
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
.menu-right[chromedir="rtl"] {
|
||||
list-style-image: url("chrome://global/skin/menu/Menu-arrow-rtl.png");
|
||||
}
|
||||
|
||||
.menu-right[chromedir="rtl"][_moz-menuactive="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/Menu-arrow-hover-rtl.png");
|
||||
}
|
||||
|
||||
.menu-right[chromedir="rtl"][disabled="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/Menu-arrow-disabled-rtl.png") !important;
|
||||
}
|
||||
|
||||
/* ::::: menu/menuitems in menubar ::::: */
|
||||
|
||||
menubar > menu {
|
||||
border: 1px solid transparent !important;
|
||||
padding-top: 1px;
|
||||
-moz-padding-end: 3px;
|
||||
padding-bottom: 1px;
|
||||
-moz-padding-start: 2px;
|
||||
margin-top: 0px !important;
|
||||
margin-bottom: 1px !important;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
menubar > menu[_moz-menuactive="true"],
|
||||
menubar > menu[_moz-menuactive="true"][open="true"] {
|
||||
color: -moz-MenuBarHoverText;
|
||||
}
|
||||
menubar > menu[_moz-menuactive="true"] {
|
||||
padding: 1px 3px 1px 2px !important;
|
||||
background-color : Highlight !important;
|
||||
color: HighlightText !important;
|
||||
border-top: 1px solid ThreeDHighlight;
|
||||
border-right: 1px solid ThreeDShadow;
|
||||
border-bottom: 1px solid ThreeDShadow;
|
||||
border-left: 1px solid ThreeDHighlight;
|
||||
border-top-color: ThreeDHighlight;
|
||||
border-left-color: ThreeDHighlight;
|
||||
border-right-color: ThreeDShadow;
|
||||
border-bottom-color: ThreeDShadow;
|
||||
}
|
||||
menubar > menu[_moz-menuactive="true"][open="true"] {
|
||||
border-top: 1px solid ThreeDShadow;
|
||||
border-right: 1px solid ThreeDHighlight;
|
||||
border-bottom: 1px solid ThreeDHighlight;
|
||||
border-left: 1px solid ThreeDShadow;
|
||||
padding-top: 1px;
|
||||
-moz-padding-end: 2px;
|
||||
padding-bottom: 0px;
|
||||
-moz-padding-start: 3px;
|
||||
border-top-color: ThreeDShadow;
|
||||
border-left-color: ThreeDShadow;
|
||||
border-right-color: ThreeDHighlight;
|
||||
border-bottom-color: ThreeDHighlight;
|
||||
}
|
||||
|
||||
/* ..... internal content .... */
|
||||
|
||||
.menubar-left {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
-moz-margin-start: 0px;
|
||||
-moz-margin-end: 2px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.menubar-text {
|
||||
margin-top: 1px;
|
||||
-moz-margin-end: 4px !important;
|
||||
margin-bottom: 1px;
|
||||
-moz-margin-start: 5px !important;
|
||||
-moz-margin-end: 4px !important;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 3px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@ -193,7 +166,7 @@ menupopup > menu[_moz-menuactive="true"],
|
||||
menupopup > menuitem[_moz-menuactive="true"],
|
||||
popup > menu[_moz-menuactive="true"],
|
||||
popup > menuitem[_moz-menuactive="true"] {
|
||||
background-color: Highlight;
|
||||
background: Highlight;
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
@ -228,40 +201,6 @@ menulist > menupopup > menuitem > .menu-iconic-text {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* ::::: checkbox menuitem ::::: */
|
||||
|
||||
menuitem[checked="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/menu-check.gif");
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
menuitem[checked="true"][disabled="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/menu-check-disabled.gif");
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
menuitem[checked="true"][_moz-menuactive="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/menu-check-hover.gif");
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
/* ::::: radio menuitem ::::: */
|
||||
|
||||
menuitem[checked="true"][type="radio"] {
|
||||
list-style-image: url("chrome://global/skin/menu/menu-radio.gif");
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
menuitem[checked="true"][type="radio"][disabled="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/menu-radio-disabled.gif");
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
menuitem[checked="true"][type="radio"][_moz-menuactive="true"] {
|
||||
list-style-image: url("chrome://global/skin/menu/menu-radio-hover.gif");
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
/* ::::: menuseparator ::::: */
|
||||
|
||||
menuseparator {
|
||||
|
@ -46,14 +46,15 @@
|
||||
|
||||
menupopup,
|
||||
popup {
|
||||
border: 1px solid ThreeDShadow;
|
||||
-moz-border-top-colors: ThreeDShadow;
|
||||
-moz-border-right-colors: ThreeDShadow;
|
||||
-moz-border-bottom-colors: ThreeDShadow;
|
||||
-moz-border-left-colors: ThreeDShadow;
|
||||
padding: 2px;
|
||||
min-width: 1px;
|
||||
-moz-appearance: menupopup;
|
||||
border: 2px solid;
|
||||
-moz-border-top-colors: ThreeDLightShadow ThreeDHighlight;
|
||||
-moz-border-left-colors: ThreeDLightShadow ThreeDHighlight;
|
||||
-moz-border-right-colors: ThreeDDarkShadow ThreeDShadow;
|
||||
-moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow;
|
||||
padding: 1px;
|
||||
background-color: Menu;
|
||||
min-width: 1px;
|
||||
}
|
||||
|
||||
menupopup > menu > menupopup,
|
||||
@ -91,6 +92,7 @@ tooltip[titletip="true"] {
|
||||
|
||||
menulist > menupopup,
|
||||
.menulist-menupopup {
|
||||
-moz-appearance: none;
|
||||
border-width: 1px;
|
||||
-moz-border-top-colors: -moz-FieldText;
|
||||
-moz-border-right-colors: -moz-FieldText;
|
||||
|
@ -46,24 +46,27 @@
|
||||
|
||||
toolbox {
|
||||
-moz-appearance: toolbox;
|
||||
background-color: -moz-Dialog;
|
||||
border-top: 2px solid;
|
||||
border: 2px solid black;
|
||||
-moz-border-top-colors: ThreeDShadow ThreeDHighlight;
|
||||
-moz-border-left-colors: ThreeDShadow ThreeDHighlight;
|
||||
-moz-border-right-colors: ThreeDHighlight ThreeDShadow;
|
||||
-moz-border-bottom-colors: ThreeDHighlight ThreeDShadow;
|
||||
background-color: ThreeDFace;
|
||||
color: ButtonText;
|
||||
}
|
||||
|
||||
/* ::::: toolbar & menubar ::::: */
|
||||
|
||||
toolbar {
|
||||
min-width: 1px;
|
||||
min-height: 19px;
|
||||
border-top: 1px solid ThreeDHighlight;
|
||||
border-bottom: 1px solid ThreeDShadow;
|
||||
toolbar,
|
||||
toolbar[type="menubar"], menubar {
|
||||
-moz-appearance: toolbar;
|
||||
border-top: 2px solid black;
|
||||
-moz-border-top-colors: ThreeDShadow ThreeDHighlight;
|
||||
}
|
||||
|
||||
toolbar[type="menubar"], menubar {
|
||||
min-width: 1px;
|
||||
border-bottom: 1px solid ThreeDShadow;
|
||||
border-top: 0px !important;
|
||||
toolbar:first-child,
|
||||
toolbar[type="menubar"], menubar:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
/* ::::: toolbar decorations ::::: */
|
||||
|
@ -133,6 +133,7 @@ public:
|
||||
eColor__moz_buttonhovertext, //used to button text, when mouse is over
|
||||
eColor__moz_menuhover, //used to menu item background, when mouse is over
|
||||
eColor__moz_menuhovertext, //used to menu item text, when mouse is over
|
||||
eColor__moz_menubarhovertext, //used to menu bar item text, when mouse is over
|
||||
|
||||
//colours needed by Mac Classic skin
|
||||
eColor__moz_mac_focusring, //ring around text fields and lists
|
||||
|
@ -41,6 +41,14 @@
|
||||
#include <windows.h>
|
||||
#include "nsWindow.h"
|
||||
|
||||
// Constants only found in new (98+, 2K+, XP+, etc.) Windows.
|
||||
#ifndef COLOR_MENUHILIGHT
|
||||
#define COLOR_MENUHILIGHT 29
|
||||
#endif
|
||||
#ifndef SPI_GETFLATMENU
|
||||
#define SPI_GETFLATMENU 0x1022
|
||||
#endif
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
|
||||
{
|
||||
}
|
||||
@ -221,6 +229,19 @@ nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor)
|
||||
case eColor__moz_buttondefault:
|
||||
idx = COLOR_3DDKSHADOW;
|
||||
break;
|
||||
case eColor__moz_menubarhovertext: {
|
||||
BOOL isFlatMenus;
|
||||
HRESULT rv;
|
||||
|
||||
// This will simply fail on Windows versions prior to XP, so we get
|
||||
// non-flat as desired.
|
||||
rv = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlatMenus, 0);
|
||||
if (rv && isFlatMenus)
|
||||
idx = COLOR_HIGHLIGHTTEXT; /* flat menus (XP themes and later only) */
|
||||
else
|
||||
idx = COLOR_MENUTEXT; /* 3d menus (pre-XP, some themes) */
|
||||
break;
|
||||
}
|
||||
default:
|
||||
idx = COLOR_WINDOW;
|
||||
break;
|
||||
|
@ -21,6 +21,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tim Hill (tim@prismelite.com)
|
||||
* James Ross (silver@warwickcompsoc.co.uk)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -54,6 +55,7 @@
|
||||
#include "nsILookAndFeel.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIMenuFrame.h"
|
||||
#include "nsIMenuParent.h"
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
@ -120,6 +122,26 @@
|
||||
// Dropdown constants
|
||||
#define CBP_DROPMARKER 1
|
||||
|
||||
// Constants only found in new (98+, 2K+, XP+, etc.) Windows.
|
||||
#ifdef DFCS_HOT
|
||||
#undef DFCS_HOT
|
||||
#endif
|
||||
#define DFCS_HOT 0x00001000
|
||||
|
||||
#ifdef COLOR_MENUHILIGHT
|
||||
#undef COLOR_MENUHILIGHT
|
||||
#endif
|
||||
#define COLOR_MENUHILIGHT 29
|
||||
|
||||
#ifdef SPI_GETFLATMENU
|
||||
#undef SPI_GETFLATMENU
|
||||
#endif
|
||||
#define SPI_GETFLATMENU 0x1022
|
||||
|
||||
// Our extra constants for passing a little but more info to the renderer.
|
||||
#define DFCS_RTL 0x00010000
|
||||
#define DFCS_CONTAINER 0x00020000
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsNativeThemeWin, nsITheme)
|
||||
|
||||
typedef HANDLE (WINAPI*OpenThemeDataPtr)(HWND hwnd, LPCWSTR pszClassList);
|
||||
@ -127,6 +149,10 @@ typedef HRESULT (WINAPI*CloseThemeDataPtr)(HANDLE hTheme);
|
||||
typedef HRESULT (WINAPI*DrawThemeBackgroundPtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, const RECT *pRect,
|
||||
const RECT* pClipRect);
|
||||
typedef HRESULT (WINAPI*DrawThemeEdgePtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, const RECT *pRect,
|
||||
uint uEdge, uint uFlags,
|
||||
const RECT* pClipRect);
|
||||
typedef HRESULT (WINAPI*GetThemeContentRectPtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, const RECT* pRect,
|
||||
RECT* pContentRect);
|
||||
@ -140,6 +166,7 @@ typedef HRESULT (WINAPI*GetThemeColorPtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
static OpenThemeDataPtr openTheme = NULL;
|
||||
static CloseThemeDataPtr closeTheme = NULL;
|
||||
static DrawThemeBackgroundPtr drawThemeBG = NULL;
|
||||
static DrawThemeEdgePtr drawThemeEdge = NULL;
|
||||
static GetThemeContentRectPtr getThemeContentRect = NULL;
|
||||
static GetThemePartSizePtr getThemePartSize = NULL;
|
||||
static GetThemeSysFontPtr getThemeSysFont = NULL;
|
||||
@ -167,6 +194,7 @@ nsNativeThemeWin::nsNativeThemeWin() {
|
||||
openTheme = (OpenThemeDataPtr)GetProcAddress(mThemeDLL, "OpenThemeData");
|
||||
closeTheme = (CloseThemeDataPtr)GetProcAddress(mThemeDLL, "CloseThemeData");
|
||||
drawThemeBG = (DrawThemeBackgroundPtr)GetProcAddress(mThemeDLL, "DrawThemeBackground");
|
||||
drawThemeEdge = (DrawThemeEdgePtr)GetProcAddress(mThemeDLL, "DrawThemeEdge");
|
||||
getThemeContentRect = (GetThemeContentRectPtr)GetProcAddress(mThemeDLL, "GetThemeBackgroundContentRect");
|
||||
getThemePartSize = (GetThemePartSizePtr)GetProcAddress(mThemeDLL, "GetThemePartSize");
|
||||
getThemeSysFont = (GetThemeSysFontPtr)GetProcAddress(mThemeDLL, "GetThemeSysFont");
|
||||
@ -176,6 +204,9 @@ nsNativeThemeWin::nsNativeThemeWin() {
|
||||
mInputAtom = do_GetAtom("input");
|
||||
mInputCheckedAtom = do_GetAtom("_moz-input-checked");
|
||||
mTypeAtom = do_GetAtom("type");
|
||||
mMenuActiveAtom = do_GetAtom("_moz-menuactive");
|
||||
|
||||
UpdateConfig();
|
||||
|
||||
// If there is a relevant change in forms.css for windows platform,
|
||||
// static widget style variables (e.g. sButtonBorderSize) should be
|
||||
@ -200,6 +231,21 @@ static void GetNativeRect(const nsRect& aSrc, RECT& aDst)
|
||||
aDst.right = aSrc.x + aSrc.width;
|
||||
}
|
||||
|
||||
void
|
||||
nsNativeThemeWin::UpdateConfig()
|
||||
{
|
||||
// Check for Windows XP (or later), and check if 'flat menus' are enabled.
|
||||
BOOL isFlatMenus;
|
||||
HRESULT rv;
|
||||
mFlatMenus = PR_FALSE;
|
||||
|
||||
// This will simply fail on Windows versions prior to XP, so we get
|
||||
// non-flat as desired.
|
||||
rv = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlatMenus, 0);
|
||||
if (rv)
|
||||
mFlatMenus = isFlatMenus;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
nsNativeThemeWin::GetTheme(PRUint8 aWidgetType)
|
||||
{
|
||||
@ -547,6 +593,21 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
aPart = aState = 0;
|
||||
return NS_OK; // These have no part or state.
|
||||
}
|
||||
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();
|
||||
if (parent && parent->GetChildAt(0) == content) {
|
||||
aState = 1;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_STATUSBAR_PANEL:
|
||||
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
||||
case NS_THEME_RESIZER: {
|
||||
@ -745,8 +806,18 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
// The left edge should not be drawn. Move the widget rect's left coord back.
|
||||
widgetRect.left -= edgeSize;
|
||||
}
|
||||
else if (aWidgetType == NS_THEME_TOOLBOX) {
|
||||
// The toolbox's toolbar elements will show a 1px border top and bottom.
|
||||
// We want the toolbox's background to end right up against the bottom
|
||||
// border of the last toolbar, so we simply make it leave a 1px gap at the
|
||||
// bottom. This gap will get the bottom border of the last toolbar in it.
|
||||
widgetRect.bottom -= 1;
|
||||
}
|
||||
|
||||
drawThemeBG(theme, hdc, part, state, &widgetRect, &clipRect);
|
||||
// If part is negative, the element wishes us to not render a themed
|
||||
// background, instead opting to be drawn specially below.
|
||||
if (part >= 0)
|
||||
drawThemeBG(theme, hdc, part, state, &widgetRect, &clipRect);
|
||||
|
||||
// Draw focus rectangles for XP HTML checkboxes and radio buttons
|
||||
// XXX it'd be nice to draw these outside of the frame
|
||||
@ -765,6 +836,15 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
::SetTextColor(hdc, oldColor);
|
||||
}
|
||||
}
|
||||
else if (aWidgetType == NS_THEME_TOOLBAR) {
|
||||
// state == 1 iff this toolbar is the first inside the toolbox, which
|
||||
// means we should omit the top border for correct rendering.
|
||||
if (state == 1) {
|
||||
drawThemeEdge(theme, hdc, 0, 0, &widgetRect, BDR_RAISEDINNER, BF_BOTTOM, &clipRect);
|
||||
} else {
|
||||
drawThemeEdge(theme, hdc, 0, 0, &widgetRect, BDR_RAISEDINNER, BF_TOP | BF_BOTTOM, &clipRect);
|
||||
}
|
||||
}
|
||||
|
||||
RestoreDC(hdc, -1);
|
||||
|
||||
@ -784,11 +864,26 @@ nsNativeThemeWin::GetWidgetBorder(nsIDeviceContext* aContext,
|
||||
(*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
|
||||
|
||||
if (!WidgetIsContainer(aWidgetType) ||
|
||||
aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR ||
|
||||
aWidgetType == NS_THEME_TOOLBOX ||
|
||||
aWidgetType == NS_THEME_STATUSBAR ||
|
||||
aWidgetType == NS_THEME_RESIZER || aWidgetType == NS_THEME_TAB_PANEL)
|
||||
return NS_OK; // Don't worry about it.
|
||||
|
||||
if (aWidgetType == NS_THEME_TOOLBAR) {
|
||||
// A normal toolbar has a 1px border above and below it, with 2px of
|
||||
// space either size. If it is the first toolbar, no top border is needed.
|
||||
aResult->top = aResult->bottom = 1;
|
||||
aResult->left = 2;
|
||||
if (aFrame) {
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
nsIContent* parent = content->GetParent();
|
||||
if (parent && parent->GetChildAt(0) == content) {
|
||||
aResult->top = 0;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!getThemeContentRect)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@ -940,7 +1035,8 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
// disabled, checked, dlgtype, default, etc.
|
||||
*aShouldRepaint = PR_FALSE;
|
||||
if (aAttribute == mDisabledAtom || aAttribute == mCheckedAtom ||
|
||||
aAttribute == mSelectedAtom || aAttribute == mReadOnlyAtom)
|
||||
aAttribute == mSelectedAtom || aAttribute == mReadOnlyAtom ||
|
||||
aAttribute == mMenuActiveAtom)
|
||||
*aShouldRepaint = PR_TRUE;
|
||||
}
|
||||
|
||||
@ -1004,6 +1100,7 @@ NS_IMETHODIMP
|
||||
nsNativeThemeWin::ThemeChanged()
|
||||
{
|
||||
CloseData();
|
||||
UpdateConfig();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1086,6 +1183,11 @@ nsNativeThemeWin::ClassicThemeSupportsWidget(nsPresContext* aPresContext,
|
||||
case NS_THEME_TAB_RIGHT_EDGE:
|
||||
case NS_THEME_TAB_PANEL:
|
||||
case NS_THEME_TAB_PANELS:
|
||||
case NS_THEME_MENUBAR:
|
||||
case NS_THEME_MENUPOPUP:
|
||||
case NS_THEME_MENUITEM:
|
||||
case NS_THEME_CHECKMENUITEM:
|
||||
case NS_THEME_RADIOMENUITEM:
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
@ -1147,6 +1249,39 @@ nsNativeThemeWin::ClassicGetWidgetBorder(nsIDeviceContext* aContext,
|
||||
case NS_THEME_PROGRESSBAR_VERTICAL:
|
||||
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 1;
|
||||
break;
|
||||
case NS_THEME_MENUBAR:
|
||||
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 0;
|
||||
break;
|
||||
case NS_THEME_MENUPOPUP:
|
||||
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2;
|
||||
break;
|
||||
case NS_THEME_MENUITEM:
|
||||
case NS_THEME_CHECKMENUITEM:
|
||||
case NS_THEME_RADIOMENUITEM: {
|
||||
PRBool isTopLevel = PR_FALSE;
|
||||
nsIMenuFrame *menuFrame = nsnull;
|
||||
CallQueryInterface(aFrame, &menuFrame);
|
||||
|
||||
if (menuFrame) {
|
||||
// If this is a real menu item, we should check if it is part of the
|
||||
// main menu bar or not, as this affects rendering.
|
||||
nsIMenuParent *menuParent = menuFrame->GetMenuParent();
|
||||
if (menuParent)
|
||||
menuParent->IsMenuBar(isTopLevel);
|
||||
}
|
||||
|
||||
// These values are obtained from visual inspection of equivelant
|
||||
// native components.
|
||||
if (isTopLevel) {
|
||||
(*aResult).top = (*aResult).bottom = 1;
|
||||
(*aResult).left = 3;
|
||||
(*aResult).right = 4;
|
||||
} else {
|
||||
(*aResult).top = 0;
|
||||
(*aResult).bottom = (*aResult).left = (*aResult).right = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
(*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
|
||||
break;
|
||||
@ -1318,6 +1453,58 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, PRUint8
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_MENUITEM:
|
||||
case NS_THEME_CHECKMENUITEM:
|
||||
case NS_THEME_RADIOMENUITEM: {
|
||||
PRBool isTopLevel = PR_FALSE;
|
||||
PRBool isOpen = PR_FALSE;
|
||||
PRBool isContainer = PR_FALSE;
|
||||
nsIMenuFrame *menuFrame = nsnull;
|
||||
CallQueryInterface(aFrame, &menuFrame);
|
||||
|
||||
// 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.
|
||||
nsIMenuParent *menuParent = menuFrame->GetMenuParent();
|
||||
if (menuParent)
|
||||
menuParent->IsMenuBar(isTopLevel);
|
||||
menuFrame->MenuIsOpen(isOpen);
|
||||
menuFrame->MenuIsContainer(isContainer);
|
||||
}
|
||||
|
||||
if (IsDisabled(aFrame))
|
||||
aState |= DFCS_INACTIVE;
|
||||
|
||||
if (isTopLevel) {
|
||||
aPart = 1;
|
||||
if (isOpen)
|
||||
aState |= DFCS_PUSHED;
|
||||
} else {
|
||||
if (isContainer)
|
||||
aState |= DFCS_CONTAINER;
|
||||
if (aFrame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL)
|
||||
aState |= DFCS_RTL;
|
||||
}
|
||||
|
||||
if (CheckBooleanAttr(aFrame, mMenuActiveAtom))
|
||||
aState |= DFCS_HOT;
|
||||
|
||||
// Only menu items of the appropriate type may have tick or bullet marks.
|
||||
if (aWidgetType == NS_THEME_CHECKMENUITEM ||
|
||||
aWidgetType == NS_THEME_RADIOMENUITEM) {
|
||||
if (IsCheckedButton(aFrame))
|
||||
aState |= DFCS_CHECKED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_LISTBOX:
|
||||
case NS_THEME_TREEVIEW:
|
||||
case NS_THEME_TEXTFIELD:
|
||||
@ -1340,6 +1527,8 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, PRUint8
|
||||
case NS_THEME_TAB_RIGHT_EDGE:
|
||||
case NS_THEME_TAB_PANEL:
|
||||
case NS_THEME_TAB_PANELS:
|
||||
case NS_THEME_MENUBAR:
|
||||
case NS_THEME_MENUPOPUP:
|
||||
// these don't use DrawFrameControl
|
||||
return NS_OK;
|
||||
case NS_THEME_DROPDOWN_BUTTON: {
|
||||
@ -1524,6 +1713,49 @@ static void DrawTab(HDC hdc, const RECT& R, PRInt32 aPosition, PRBool aSelected,
|
||||
::DrawEdge(hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
::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);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsNativeThemeWin::ClassicDrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
@ -1775,6 +2007,80 @@ nsresult nsNativeThemeWin::ClassicDrawWidgetBackground(nsIRenderingContext* aCon
|
||||
|
||||
RestoreDC(hdc, -1);
|
||||
return NS_OK;
|
||||
case NS_THEME_MENUBAR:
|
||||
return NS_OK;
|
||||
case NS_THEME_MENUPOPUP:
|
||||
if (mFlatMenus) {
|
||||
::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_MENU+1));
|
||||
::FrameRect(hdc, &widgetRect, ::GetSysColorBrush(COLOR_BTNSHADOW));
|
||||
} else {
|
||||
::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
|
||||
}
|
||||
return NS_OK;
|
||||
case NS_THEME_MENUITEM:
|
||||
case NS_THEME_CHECKMENUITEM:
|
||||
case NS_THEME_RADIOMENUITEM: {
|
||||
// part == 0 for normal items
|
||||
// part == 1 for top-level menu items
|
||||
if (mFlatMenus) {
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((state & DFCS_CHECKED) != 0) || ((state & DFCS_CONTAINER) != 0)) {
|
||||
RECT menuRectStart, menuRectEnd;
|
||||
PRUint32 color = COLOR_MENUTEXT;
|
||||
|
||||
if ((state & DFCS_INACTIVE) != 0)
|
||||
color = COLOR_GRAYTEXT;
|
||||
else if ((state & DFCS_HOT) != 0)
|
||||
color = COLOR_HIGHLIGHTTEXT;
|
||||
|
||||
::CopyRect(&menuRectStart, &widgetRect);
|
||||
::InflateRect(&menuRectStart, -1, -1);
|
||||
::CopyRect(&menuRectEnd, &menuRectStart);
|
||||
|
||||
// WARNING: This value of 15 must match the value in menu.css for the min-width of .menu-iconic-left
|
||||
if ((state & DFCS_RTL) == 0) {
|
||||
menuRectStart.right = menuRectStart.left + 15; // Left box
|
||||
menuRectEnd.left = menuRectEnd.right - 15; // Right box
|
||||
} else {
|
||||
menuRectStart.left = menuRectStart.right - 15; // Right box
|
||||
menuRectEnd.right = menuRectEnd.left + 15; // left box
|
||||
}
|
||||
|
||||
if ((state & DFCS_CHECKED) != 0) {
|
||||
if (aWidgetType == NS_THEME_CHECKMENUITEM) {
|
||||
DrawMenuImage(hdc, menuRectStart, DFCS_MENUCHECK, color);
|
||||
} else if (aWidgetType == NS_THEME_RADIOMENUITEM) {
|
||||
DrawMenuImage(hdc, menuRectStart, DFCS_MENUBULLET, color);
|
||||
}
|
||||
}
|
||||
if ((state & DFCS_CONTAINER) != 0) {
|
||||
if ((state & DFCS_RTL) == 0)
|
||||
DrawMenuImage(hdc, menuRectEnd, DFCS_MENUARROW, color);
|
||||
else
|
||||
DrawMenuImage(hdc, menuRectEnd, DFCS_MENUARROWRIGHT, color);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
RestoreDC(hdc, -1);
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
virtual ~nsNativeThemeWin();
|
||||
|
||||
protected:
|
||||
void UpdateConfig();
|
||||
void CloseData();
|
||||
HANDLE GetTheme(PRUint8 aWidgetType);
|
||||
nsresult GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
@ -125,9 +126,12 @@ private:
|
||||
HANDLE mComboBoxTheme;
|
||||
HANDLE mHeaderTheme;
|
||||
|
||||
BOOL mFlatMenus;
|
||||
|
||||
nsCOMPtr<nsIAtom> mInputAtom;
|
||||
nsCOMPtr<nsIAtom> mInputCheckedAtom;
|
||||
nsCOMPtr<nsIAtom> mTypeAtom;
|
||||
nsCOMPtr<nsIAtom> mMenuActiveAtom;
|
||||
};
|
||||
|
||||
// Creator function
|
||||
|
Loading…
Reference in New Issue
Block a user