Attachment #102654: nsNativeThemeWin patch 2 for bug #172751

View | Details | Raw Unified | Return to bug 172751
Collapse All | Expand All

(-)nsNativeThemeWin.cpp (-44 / +671 lines)
Line     Link Here 
 Lines 22-27    Link Here 
22
 * the Initial Developer. All Rights Reserved.
22
 * the Initial Developer. All Rights Reserved.
23
 *
23
 *
24
 * Contributor(s):
24
 * Contributor(s):
25
 *   Tim Hill (tim@prismelite.com)
25
 *
26
 *
26
 * Alternatively, the contents of this file may be used under the terms of
27
 * Alternatively, the contents of this file may be used under the terms of
27
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
28
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 Lines 172-187    Link Here 
172
    getThemePartSize = (GetThemePartSizePtr)GetProcAddress(mThemeDLL, "GetThemePartSize");
173
    getThemePartSize = (GetThemePartSizePtr)GetProcAddress(mThemeDLL, "GetThemePartSize");
173
    getThemeSysFont = (GetThemeSysFontPtr)GetProcAddress(mThemeDLL, "GetThemeSysFont");
174
    getThemeSysFont = (GetThemeSysFontPtr)GetProcAddress(mThemeDLL, "GetThemeSysFont");
174
    getThemeColor = (GetThemeColorPtr)GetProcAddress(mThemeDLL, "GetThemeColor");
175
    getThemeColor = (GetThemeColorPtr)GetProcAddress(mThemeDLL, "GetThemeColor");
175
176
    mCheckedAtom = getter_AddRefs(NS_NewAtom("checked"));
177
    mInputAtom = getter_AddRefs(NS_NewAtom("input"));
178
    mInputCheckedAtom = getter_AddRefs(NS_NewAtom("_moz-input-checked"));
179
    mDisabledAtom = getter_AddRefs(NS_NewAtom("disabled"));
180
    mSelectedAtom = getter_AddRefs(NS_NewAtom("selected"));
181
    mTypeAtom = getter_AddRefs(NS_NewAtom("type"));
182
    mReadOnlyAtom = getter_AddRefs(NS_NewAtom("readonly"));
183
    mDefaultAtom = getter_AddRefs(NS_NewAtom("default"));
184
  }
176
  }
177
178
  mCheckedAtom = getter_AddRefs(NS_NewAtom("checked"));
179
  mInputAtom = getter_AddRefs(NS_NewAtom("input"));
180
  mInputCheckedAtom = getter_AddRefs(NS_NewAtom("_moz-input-checked"));
181
  mDisabledAtom = getter_AddRefs(NS_NewAtom("disabled"));
182
  mSelectedAtom = getter_AddRefs(NS_NewAtom("selected"));
183
  mTypeAtom = getter_AddRefs(NS_NewAtom("type"));
184
  mReadOnlyAtom = getter_AddRefs(NS_NewAtom("readonly"));
185
  mDefaultAtom = getter_AddRefs(NS_NewAtom("default"));
185
}
186
}
186
187
187
nsNativeThemeWin::~nsNativeThemeWin() {
188
nsNativeThemeWin::~nsNativeThemeWin() {
 Lines 746-757    Link Here 
746
                                       const nsRect& aRect,
747
                                       const nsRect& aRect,
747
                                       const nsRect& aClipRect)
748
                                       const nsRect& aClipRect)
748
{
749
{
749
  if (!drawThemeBG)
750
    return NS_ERROR_FAILURE;
751
752
  HANDLE theme = GetTheme(aWidgetType);
750
  HANDLE theme = GetTheme(aWidgetType);
753
  if (!theme)
751
  if (!theme)
754
    return NS_ERROR_FAILURE;
752
    return OldDrawWidgetBackground(aContext, aFrame, aWidgetType, aRect, aClipRect); 
753
754
  if (!drawThemeBG)
755
    return NS_ERROR_FAILURE;    
755
756
756
  PRInt32 part, state;
757
  PRInt32 part, state;
757
  nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
758
  nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
 Lines 801-808    Link Here 
801
                                  PRUint8 aWidgetType,
802
                                  PRUint8 aWidgetType,
802
                                  nsMargin* aResult)
803
                                  nsMargin* aResult)
803
{
804
{
804
  if (!getThemeContentRect)
805
  HANDLE theme = GetTheme(aWidgetType);
805
    return NS_ERROR_FAILURE;
806
  if (!theme)
807
    return OldGetWidgetBorder(aContext, aFrame, aWidgetType, aResult); 
806
808
807
  (*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
809
  (*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
808
810
 Lines 812-819    Link Here 
812
      aWidgetType == NS_THEME_RESIZER || aWidgetType == NS_THEME_TAB_PANEL)
814
      aWidgetType == NS_THEME_RESIZER || aWidgetType == NS_THEME_TAB_PANEL)
813
    return NS_OK; // Don't worry about it.
815
    return NS_OK; // Don't worry about it.
814
816
815
  HANDLE theme = GetTheme(aWidgetType);
817
  if (!getThemeContentRect)
816
  if (!theme)
817
    return NS_ERROR_FAILURE;
818
    return NS_ERROR_FAILURE;
818
819
819
  PRInt32 part, state;
820
  PRInt32 part, state;
 Lines 865-884    Link Here 
865
                                       PRUint8 aWidgetType,
866
                                       PRUint8 aWidgetType,
866
                                       nsSize* aResult, PRBool* aIsOverridable)
867
                                       nsSize* aResult, PRBool* aIsOverridable)
867
{
868
{
868
  if (!getThemePartSize)
869
    return NS_ERROR_FAILURE;
870
871
  (*aResult).width = (*aResult).height = 0;
869
  (*aResult).width = (*aResult).height = 0;
872
  *aIsOverridable = PR_TRUE;
870
  *aIsOverridable = PR_TRUE;
873
871
872
  HANDLE theme = GetTheme(aWidgetType);
873
  if (!theme)
874
    return OldGetMinimumWidgetSize(aContext, aFrame, aWidgetType, aResult, aIsOverridable);
875
874
  if (aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR || 
876
  if (aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR || 
875
      aWidgetType == NS_THEME_STATUSBAR || aWidgetType == NS_THEME_PROGRESSBAR_CHUNK ||
877
      aWidgetType == NS_THEME_STATUSBAR || aWidgetType == NS_THEME_PROGRESSBAR_CHUNK ||
876
      aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL ||
878
      aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL ||
877
      aWidgetType == NS_THEME_TAB_PANELS || aWidgetType == NS_THEME_TAB_PANEL)
879
      aWidgetType == NS_THEME_TAB_PANELS || aWidgetType == NS_THEME_TAB_PANEL)
878
    return NS_OK; // Don't worry about it.
880
    return NS_OK; // Don't worry about it.
879
881
880
  HANDLE theme = GetTheme(aWidgetType);
882
  if (!getThemePartSize)
881
  if (!theme)
882
    return NS_ERROR_FAILURE;
883
    return NS_ERROR_FAILURE;
883
884
884
  PRInt32 part, state;
885
  PRInt32 part, state;
 Lines 1008-1035    Link Here 
1008
  return NS_OK;
1009
  return NS_OK;
1009
}
1010
}
1010
1011
1011
PRBool 
1012
static PRBool IsAlreadyStyled(nsIFrame* aFrame, PRUint8 aWidgetType) {
1012
nsNativeThemeWin::ThemeSupportsWidget(nsIPresContext* aPresContext,
1013
                                      nsIFrame* aFrame,
1014
                                      PRUint8 aWidgetType)
1015
{
1016
  if (aPresContext) {
1017
    nsCOMPtr<nsIPresShell> shell;
1018
    aPresContext->GetShell(getter_AddRefs(shell));
1019
    if (!shell->IsThemeSupportEnabled())
1020
      return PR_FALSE;
1021
  }
1022
1023
  HANDLE theme = NULL;
1024
  if (aWidgetType == NS_THEME_CHECKBOX_CONTAINER)
1025
    theme = GetTheme(NS_THEME_CHECKBOX);
1026
  else if (aWidgetType == NS_THEME_RADIO_CONTAINER)
1027
    theme = GetTheme(NS_THEME_RADIO);
1028
  else
1029
    theme = GetTheme(aWidgetType);
1030
  if (!theme)
1031
    return PR_FALSE;
1032
  
1033
  // Check for specific widgets to see if HTML has overridden the style.
1013
  // Check for specific widgets to see if HTML has overridden the style.
1034
  if (aFrame && (aWidgetType == NS_THEME_BUTTON || aWidgetType == NS_THEME_TEXTFIELD)) {
1014
  if (aFrame && (aWidgetType == NS_THEME_BUTTON || aWidgetType == NS_THEME_TEXTFIELD)) {
1035
    nsCOMPtr<nsIContent> content;
1015
    nsCOMPtr<nsIContent> content;
 Lines 1075-1080    Link Here 
1075
}
1055
}
1076
1056
1077
PRBool 
1057
PRBool 
1058
nsNativeThemeWin::ThemeSupportsWidget(nsIPresContext* aPresContext,
1059
                                      nsIFrame* aFrame,
1060
                                      PRUint8 aWidgetType)
1061
{
1062
  // XXXdwh We can go even further and call the API to ask if support exists for
1063
  // specific widgets.
1064
1065
  if (aPresContext) {
1066
    nsCOMPtr<nsIPresShell> shell;
1067
    aPresContext->GetShell(getter_AddRefs(shell));
1068
    if (!shell->IsThemeSupportEnabled())
1069
      return PR_FALSE;
1070
  }
1071
1072
  HANDLE theme = NULL;
1073
  if (aWidgetType == NS_THEME_CHECKBOX_CONTAINER)
1074
    theme = GetTheme(NS_THEME_CHECKBOX);
1075
  else if (aWidgetType == NS_THEME_RADIO_CONTAINER)
1076
    theme = GetTheme(NS_THEME_RADIO);
1077
  else
1078
    theme = GetTheme(aWidgetType);
1079
  if (!theme)
1080
    return OldThemeSupportsWidget(aPresContext, aFrame, aWidgetType);
1081
  
1082
  return IsAlreadyStyled(aFrame, aWidgetType);
1083
}
1084
1085
PRBool 
1078
nsNativeThemeWin::WidgetIsContainer(PRUint8 aWidgetType)
1086
nsNativeThemeWin::WidgetIsContainer(PRUint8 aWidgetType)
1079
{
1087
{
1080
  // XXXdwh At some point flesh all of this out.
1088
  // XXXdwh At some point flesh all of this out.
 Lines 1084-1089    Link Here 
1084
    return PR_FALSE;
1092
    return PR_FALSE;
1085
  return PR_TRUE;
1093
  return PR_TRUE;
1086
}
1094
}
1095
1096
1097
/* Windows 9x/NT/2000 Theme Support */
1098
1099
PRBool 
1100
nsNativeThemeWin::OldThemeSupportsWidget(nsIPresContext* aPresContext,
1101
                                      nsIFrame* aFrame,
1102
                                      PRUint8 aWidgetType)
1103
{
1104
  switch (aWidgetType) {
1105
    case NS_THEME_BUTTON:
1106
    case NS_THEME_TEXTFIELD:
1107
      return (IsAlreadyStyled(aFrame, aWidgetType));
1108
    case NS_THEME_CHECKBOX:
1109
    case NS_THEME_RADIO:
1110
    case NS_THEME_SCROLLBAR_BUTTON_UP:
1111
    case NS_THEME_SCROLLBAR_BUTTON_DOWN:
1112
    case NS_THEME_SCROLLBAR_BUTTON_LEFT:
1113
    case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
1114
    case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
1115
    case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
1116
    case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
1117
    case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
1118
    case NS_THEME_DROPDOWN_BUTTON:
1119
    case NS_THEME_SPINNER_UP_BUTTON:
1120
    case NS_THEME_SPINNER_DOWN_BUTTON:
1121
    case NS_THEME_LISTBOX:
1122
    case NS_THEME_TREEVIEW:
1123
    case NS_THEME_DROPDOWN_TEXTFIELD:
1124
    case NS_THEME_DROPDOWN:
1125
    case NS_THEME_TOOLTIP:
1126
    case NS_THEME_STATUSBAR:
1127
    case NS_THEME_STATUSBAR_PANEL:
1128
    case NS_THEME_STATUSBAR_RESIZER_PANEL:
1129
    case NS_THEME_RESIZER:
1130
    case NS_THEME_PROGRESSBAR:
1131
    case NS_THEME_PROGRESSBAR_VERTICAL:
1132
    case NS_THEME_PROGRESSBAR_CHUNK:
1133
    case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
1134
    case NS_THEME_TOOLBOX:
1135
    case NS_THEME_TAB:
1136
    case NS_THEME_TAB_LEFT_EDGE:
1137
    case NS_THEME_TAB_RIGHT_EDGE:
1138
    case NS_THEME_TAB_PANEL:
1139
    case NS_THEME_TAB_PANELS:
1140
      return PR_TRUE;
1141
  }
1142
  return PR_FALSE;
1143
}
1144
1145
nsresult
1146
nsNativeThemeWin::OldGetWidgetBorder(nsIDeviceContext* aContext, 
1147
                                  nsIFrame* aFrame,
1148
                                  PRUint8 aWidgetType,
1149
                                  nsMargin* aResult)
1150
{
1151
  switch (aWidgetType) {
1152
    case NS_THEME_BUTTON: {
1153
      const nsStyleUserInterface *uiData = nsnull;
1154
      aFrame->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)uiData);      
1155
      if (uiData && uiData->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE) {
1156
        // use different padding for non-focusable buttons
1157
        (*aResult).top = (*aResult).left = 1;
1158
        (*aResult).bottom = (*aResult).right = 2;
1159
      }
1160
      else
1161
        (*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 3; 
1162
      break;  
1163
    }
1164
    case NS_THEME_STATUSBAR:
1165
      (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
1166
      (*aResult).top = 2;
1167
      break;
1168
    case NS_THEME_LISTBOX:
1169
    case NS_THEME_TREEVIEW:
1170
    case NS_THEME_DROPDOWN:
1171
    case NS_THEME_DROPDOWN_TEXTFIELD:
1172
    case NS_THEME_TAB:
1173
    case NS_THEME_TAB_LEFT_EDGE:
1174
    case NS_THEME_TAB_RIGHT_EDGE:
1175
      (*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2;
1176
      break;
1177
    case NS_THEME_TEXTFIELD: {
1178
      (*aResult).top = (*aResult).bottom = 2;
1179
      nsCOMPtr<nsIContent> content;
1180
      aFrame->GetContent(getter_AddRefs(content));
1181
      if (content && content->IsContentOfType(nsIContent::eHTML))
1182
        // HTML text-fields need extra padding
1183
        (*aResult).left = (*aResult).right = 3;
1184
      else
1185
        (*aResult).left = (*aResult).right = 2;
1186
      break;
1187
    }
1188
    case NS_THEME_STATUSBAR_PANEL:
1189
    case NS_THEME_STATUSBAR_RESIZER_PANEL: {
1190
      (*aResult).top = 1;      
1191
      (*aResult).left = 1;
1192
      (*aResult).bottom = 1;
1193
      nsIFrame* hasSibling = nsnull;
1194
      aFrame->GetNextSibling(&hasSibling);
1195
      if (hasSibling)
1196
        (*aResult).right = 3;      
1197
      else
1198
        (*aResult).right = 1;
1199
      break;
1200
    }    
1201
    case NS_THEME_TOOLTIP:
1202
      (*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 1;
1203
      break;
1204
    default:
1205
      (*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
1206
      break;
1207
  }
1208
  return NS_OK;
1209
}
1210
1211
nsresult
1212
nsNativeThemeWin::OldGetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
1213
                                       PRUint8 aWidgetType,
1214
                                       nsSize* aResult, PRBool* aIsOverridable)
1215
{
1216
  (*aResult).width = (*aResult).height = 0;
1217
  *aIsOverridable = PR_TRUE;
1218
  switch (aWidgetType) {
1219
    case NS_THEME_RADIO:
1220
    case NS_THEME_CHECKBOX: 
1221
      (*aResult).width = (*aResult).height = 13;
1222
      break;
1223
    case NS_THEME_SCROLLBAR_BUTTON_UP:
1224
    case NS_THEME_SCROLLBAR_BUTTON_DOWN:
1225
      (*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
1226
      (*aResult).height = ::GetSystemMetrics(SM_CYVSCROLL);
1227
      break;
1228
    case NS_THEME_SCROLLBAR_BUTTON_LEFT:
1229
    case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
1230
      (*aResult).width = ::GetSystemMetrics(SM_CXHSCROLL);
1231
      (*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL);
1232
      break;
1233
    case NS_THEME_SCROLLBAR_THUMB_VERTICAL:        
1234
      (*aResult).width = ::GetSystemMetrics(SM_CYVTHUMB);
1235
      (*aResult).height = (*aResult).width >> 1; // half-height
1236
      break;
1237
    case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
1238
      (*aResult).height = ::GetSystemMetrics(SM_CXHTHUMB);
1239
      (*aResult).width = (*aResult).height >> 1; // half-width
1240
      break;
1241
    case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
1242
      (*aResult).height = ::GetSystemMetrics(SM_CYVTHUMB);
1243
      break;
1244
    case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
1245
      (*aResult).width = ::GetSystemMetrics(SM_CXHTHUMB);      
1246
      break;
1247
    case NS_THEME_DROPDOWN_BUTTON:
1248
      (*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
1249
      break;
1250
    case NS_THEME_BUTTON:
1251
    case NS_THEME_LISTBOX:
1252
    case NS_THEME_TREEVIEW:
1253
    case NS_THEME_TEXTFIELD:
1254
    case NS_THEME_DROPDOWN:      
1255
    case NS_THEME_DROPDOWN_TEXTFIELD:      
1256
    case NS_THEME_STATUSBAR:
1257
    case NS_THEME_STATUSBAR_PANEL:      
1258
    case NS_THEME_STATUSBAR_RESIZER_PANEL:
1259
    case NS_THEME_PROGRESSBAR_CHUNK:
1260
    case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
1261
    case NS_THEME_TOOLTIP:
1262
    case NS_THEME_TOOLBOX:
1263
    case NS_THEME_PROGRESSBAR:
1264
    case NS_THEME_PROGRESSBAR_VERTICAL:
1265
    case NS_THEME_TAB:
1266
    case NS_THEME_TAB_LEFT_EDGE:
1267
    case NS_THEME_TAB_RIGHT_EDGE:
1268
    case NS_THEME_TAB_PANEL:
1269
    case NS_THEME_TAB_PANELS:
1270
      break;
1271
    case NS_THEME_RESIZER: {     
1272
      NONCLIENTMETRICS nc;
1273
      nc.cbSize = sizeof(nc);
1274
      SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nc), &nc, 0);  
1275
      (*aResult).width = (*aResult).height = abs(nc.lfStatusFont.lfHeight) + 4;
1276
      break;
1277
    }
1278
    default:
1279
      return NS_ERROR_FAILURE;
1280
  }  
1281
  return NS_OK;
1282
}
1283
1284
1285
nsresult nsNativeThemeWin::OldGetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
1286
                                 PRInt32& aPart, PRInt32& aState, PRBool& aFocused)
1287
{  
1288
  switch (aWidgetType) {
1289
    case NS_THEME_BUTTON: {
1290
      PRInt32 contentState;
1291
      PRBool isDisabled = PR_FALSE;
1292
1293
      aPart = DFC_BUTTON;
1294
      aState = DFCS_BUTTONPUSH;
1295
1296
      contentState = GetContentState(aFrame);
1297
      if (IsDisabled(aFrame))
1298
        aState += DFCS_INACTIVE;
1299
      else {
1300
        if (contentState & NS_EVENT_STATE_ACTIVE && contentState & NS_EVENT_STATE_HOVER) {
1301
          aState += DFCS_PUSHED;
1302
          const nsStyleUserInterface *uiData = nsnull;
1303
          aFrame->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)uiData);
1304
          // The down state is flat if the button is focusable
1305
          if (uiData && uiData->mUserFocus == NS_STYLE_USER_FOCUS_NORMAL) {
1306
            nsCOMPtr<nsIContent> content;
1307
            aFrame->GetContent(getter_AddRefs(content));
1308
            if (!content->IsContentOfType(nsIContent::eHTML))
1309
              aState += DFCS_FLAT;
1310
            aFocused = PR_TRUE;
1311
          }
1312
        }
1313
        if ((contentState & NS_EVENT_STATE_FOCUS) || 
1314
           (aState == DFCS_BUTTONPUSH && CheckBooleanAttr(aFrame, mDefaultAtom)))
1315
          aFocused = PR_TRUE;
1316
      }
1317
1318
      return NS_OK;
1319
    }
1320
    case NS_THEME_CHECKBOX:
1321
    case NS_THEME_RADIO: {
1322
      PRInt32 contentState ;
1323
      PRBool isDisabled = PR_FALSE;
1324
      nsCOMPtr<nsIContent> content;
1325
1326
      aPart = DFC_BUTTON;
1327
      aState = (aWidgetType == NS_THEME_CHECKBOX) ? DFCS_BUTTONCHECK : DFCS_BUTTONRADIO;
1328
      aFrame->GetContent(getter_AddRefs(content));
1329
           
1330
      if (content->IsContentOfType(nsIContent::eXUL)) {
1331
        // XUL
1332
        aFrame->GetParent(&aFrame);
1333
        if (aWidgetType == NS_THEME_CHECKBOX) {
1334
          if (IsChecked(aFrame))
1335
            aState += DFCS_CHECKED;
1336
        }
1337
        else
1338
          if (CheckBooleanAttr(aFrame, mSelectedAtom))
1339
            aState += DFCS_CHECKED;
1340
        contentState = GetContentState(aFrame);
1341
      }
1342
      else {
1343
        // HTML
1344
1345
        nsCOMPtr<nsIDOMHTMLInputElement> inputElt(do_QueryInterface(content));
1346
        if (inputElt) {
1347
          PRBool isChecked = PR_FALSE;
1348
          inputElt->GetChecked(&isChecked);
1349
          if (isChecked)
1350
            aState += DFCS_CHECKED;
1351
        }
1352
        contentState = GetContentState(aFrame);
1353
        if (contentState & NS_EVENT_STATE_FOCUS)
1354
          aFocused = PR_TRUE;
1355
      }
1356
1357
      if (IsDisabled(aFrame))
1358
        aState += DFCS_INACTIVE;
1359
      else if (contentState & NS_EVENT_STATE_ACTIVE && contentState & NS_EVENT_STATE_HOVER)
1360
        aState += DFCS_PUSHED;
1361
      
1362
      return NS_OK;
1363
    }
1364
    case NS_THEME_LISTBOX:
1365
    case NS_THEME_TREEVIEW:
1366
    case NS_THEME_TEXTFIELD:
1367
    case NS_THEME_DROPDOWN:
1368
    case NS_THEME_DROPDOWN_TEXTFIELD:
1369
    case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
1370
    case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:      
1371
    case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
1372
    case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: 
1373
    case NS_THEME_STATUSBAR:
1374
    case NS_THEME_STATUSBAR_PANEL:
1375
    case NS_THEME_STATUSBAR_RESIZER_PANEL:
1376
    case NS_THEME_PROGRESSBAR_CHUNK:
1377
    case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
1378
    case NS_THEME_TOOLTIP:
1379
    case NS_THEME_TOOLBOX:
1380
    case NS_THEME_PROGRESSBAR:
1381
    case NS_THEME_PROGRESSBAR_VERTICAL:
1382
    case NS_THEME_TAB:
1383
    case NS_THEME_TAB_LEFT_EDGE:
1384
    case NS_THEME_TAB_RIGHT_EDGE:
1385
    case NS_THEME_TAB_PANEL:
1386
    case NS_THEME_TAB_PANELS:
1387
      return NS_OK;
1388
    case NS_THEME_DROPDOWN_BUTTON: {
1389
1390
      aPart = DFC_SCROLL;
1391
      aState = DFCS_SCROLLCOMBOBOX;
1392
      
1393
      nsCOMPtr<nsIContent> content;
1394
      aFrame->GetContent(getter_AddRefs(content));
1395
1396
      nsIFrame* parentFrame;
1397
      aFrame->GetParent(&parentFrame);
1398
      nsCOMPtr<nsIMenuFrame> menuFrame(do_QueryInterface(parentFrame));
1399
      if (menuFrame || (content && content->IsContentOfType(nsIContent::eHTML)) )
1400
         // XUL menu lists and HTML selects get state from parent         
1401
         aFrame = parentFrame;
1402
         // XXX the button really shouldn't depress when clicking the 
1403
         // parent, but the button frame is never :active for these controls..
1404
1405
      if (IsDisabled(aFrame))
1406
        aState += DFCS_INACTIVE;
1407
      else {     
1408
        PRInt32 eventState = GetContentState(aFrame);
1409
        if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
1410
        aState = aState | DFCS_PUSHED | DFCS_FLAT;
1411
      }
1412
1413
      return NS_OK;
1414
    }
1415
    case NS_THEME_SCROLLBAR_BUTTON_UP:
1416
    case NS_THEME_SCROLLBAR_BUTTON_DOWN:
1417
    case NS_THEME_SCROLLBAR_BUTTON_LEFT:
1418
    case NS_THEME_SCROLLBAR_BUTTON_RIGHT: {
1419
      PRInt32 contentState;
1420
1421
      aPart = DFC_SCROLL;
1422
      switch (aWidgetType) {
1423
        case NS_THEME_SCROLLBAR_BUTTON_UP:
1424
          aState = DFCS_SCROLLUP;
1425
          break;
1426
        case NS_THEME_SCROLLBAR_BUTTON_DOWN:
1427
          aState = DFCS_SCROLLDOWN;
1428
          break;
1429
        case NS_THEME_SCROLLBAR_BUTTON_LEFT:
1430
          aState = DFCS_SCROLLLEFT;
1431
          break;
1432
        case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
1433
          aState = DFCS_SCROLLRIGHT;
1434
          break;
1435
      }      
1436
      
1437
      if (IsDisabled(aFrame))
1438
        aState += DFCS_INACTIVE;
1439
      else {
1440
        contentState = GetContentState(aFrame);
1441
        if (contentState & NS_EVENT_STATE_HOVER && contentState & NS_EVENT_STATE_ACTIVE)
1442
          aState = aState | DFCS_PUSHED | DFCS_FLAT;      
1443
      }
1444
1445
      return NS_OK;
1446
    }
1447
    case NS_THEME_SPINNER_UP_BUTTON:
1448
    case NS_THEME_SPINNER_DOWN_BUTTON: {
1449
      PRInt32 contentState;
1450
1451
      aPart = DFC_SCROLL;
1452
      switch (aWidgetType) {
1453
        case NS_THEME_SPINNER_UP_BUTTON:
1454
          aState = DFCS_SCROLLUP;
1455
          break;
1456
        case NS_THEME_SPINNER_DOWN_BUTTON:
1457
          aState = DFCS_SCROLLDOWN;
1458
          break;
1459
      }      
1460
      
1461
      if (IsDisabled(aFrame))
1462
        aState += DFCS_INACTIVE;
1463
      else {
1464
        contentState = GetContentState(aFrame);
1465
        if (contentState & NS_EVENT_STATE_HOVER && contentState & NS_EVENT_STATE_ACTIVE)
1466
          aState += DFCS_PUSHED;
1467
      }
1468
1469
      return NS_OK;    
1470
    }
1471
    case NS_THEME_RESIZER:    
1472
      aPart = DFC_SCROLL;
1473
      aState = DFCS_SCROLLSIZEGRIP;
1474
      return NS_OK;
1475
  }
1476
  return NS_ERROR_FAILURE;
1477
}
1478
1479
nsresult nsNativeThemeWin::OldDrawWidgetBackground(nsIRenderingContext* aContext,
1480
                                  nsIFrame* aFrame,
1481
                                  PRUint8 aWidgetType,
1482
                                  const nsRect& aRect,
1483
                                  const nsRect& aClipRect)
1484
{         
1485
  PRInt32 part, state;
1486
  PRBool focused = PR_FALSE;
1487
  nsresult rv;
1488
  rv = OldGetThemePartAndState(aFrame, aWidgetType, part, state, focused);
1489
  if (NS_FAILED(rv))
1490
    return rv;
1491
1492
  nsTransform2D* transformMatrix;
1493
  aContext->GetCurrentTransform(transformMatrix);
1494
  RECT widgetRect;
1495
	nsRect tr(aRect);
1496
	transformMatrix->TransformCoord(&tr.x,&tr.y,&tr.width,&tr.height);
1497
  GetNativeRect(tr, widgetRect); 
1498
1499
  HDC hdc = ((nsRenderingContextWin*)aContext)->mDC;
1500
1501
  switch (aWidgetType) { 
1502
    // Draw button
1503
    case NS_THEME_BUTTON: {
1504
      if (focused) {
1505
        // draw dark button focus border first
1506
        HBRUSH brush;
1507
        brush = ::GetSysColorBrush(COLOR_3DDKSHADOW);
1508
        ::FrameRect(hdc, &widgetRect, brush);
1509
        widgetRect.left++; widgetRect.top++;
1510
        widgetRect.right--; widgetRect.bottom--;
1511
      }      
1512
    }
1513
    // Draw controls supported by DrawFrameControl
1514
    case NS_THEME_CHECKBOX:
1515
    case NS_THEME_RADIO:
1516
    case NS_THEME_SCROLLBAR_BUTTON_UP:
1517
    case NS_THEME_SCROLLBAR_BUTTON_DOWN:
1518
    case NS_THEME_SCROLLBAR_BUTTON_LEFT:
1519
    case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
1520
    case NS_THEME_SPINNER_UP_BUTTON:
1521
    case NS_THEME_SPINNER_DOWN_BUTTON:
1522
    case NS_THEME_DROPDOWN_BUTTON:
1523
    case NS_THEME_RESIZER: { 
1524
1525
      PRInt32 oldTA;
1526
      // need to set this to draw correctly
1527
      oldTA = ::SetTextAlign(hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP);
1528
      ::DrawFrameControl(hdc, &widgetRect, part, state);
1529
      ::SetTextAlign(hdc, oldTA);
1530
1531
      if (focused && (aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_RADIO)) {
1532
        // draw focus rectangle        
1533
1534
        ::DrawFocusRect(hdc, &widgetRect);        
1535
      }
1536
1537
      return NS_OK;
1538
    }
1539
    // Draw controls with 2px 3D inset border
1540
    case NS_THEME_LISTBOX:
1541
    case NS_THEME_TREEVIEW:
1542
    case NS_THEME_TEXTFIELD:
1543
    case NS_THEME_DROPDOWN:
1544
    case NS_THEME_DROPDOWN_TEXTFIELD: {
1545
      // Draw inset edge
1546
      ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1547
1548
      // Fill in window color background
1549
      ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_WINDOW+1));
1550
      
1551
      return NS_OK;
1552
    }
1553
    // Draw ToolTip background
1554
    case NS_THEME_TOOLTIP:
1555
      HBRUSH brush;
1556
      brush = ::GetSysColorBrush(COLOR_3DDKSHADOW);
1557
      ::FrameRect(hdc, &widgetRect, brush);
1558
      widgetRect.left++; widgetRect.top++;
1559
      widgetRect.right--; widgetRect.bottom--;
1560
      ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_INFOBK+1));
1561
      return NS_OK;
1562
    // Draw 3D face background controls
1563
    case NS_THEME_TOOLBOX:
1564
    case NS_THEME_TAB_PANEL:    
1565
    case NS_THEME_PROGRESSBAR:
1566
    case NS_THEME_PROGRESSBAR_VERTICAL:
1567
    case NS_THEME_STATUSBAR:
1568
    case NS_THEME_STATUSBAR_RESIZER_PANEL: {
1569
      ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_BTNFACE+1));
1570
      return NS_OK;
1571
    }
1572
    // Draw 3D inset statusbar panel
1573
    case NS_THEME_STATUSBAR_PANEL: {
1574
      nsIFrame* hasSibling = nsnull;
1575
      aFrame->GetNextSibling(&hasSibling);
1576
      if (hasSibling)
1577
        widgetRect.right -= 2; // space between sibling status panels
1578
1579
      ::DrawEdge(hdc, &widgetRect, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE);
1580
      return NS_OK;  
1581
    }
1582
    // Draw scrollbar thumb
1583
    case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
1584
    case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
1585
      ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
1586
      return NS_OK;
1587
    // Draw scrollbar track background
1588
    case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
1589
    case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: {
1590
1591
      // Windows fills in the scrollbar track differently 
1592
      // depending on whether these are equal
1593
      DWORD color3D, colorScrollbar, colorWindow;
1594
1595
      color3D = ::GetSysColor(COLOR_3DFACE);      
1596
      colorWindow = ::GetSysColor(COLOR_WINDOW);
1597
      colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
1598
      
1599
      if ((color3D != colorScrollbar) && (colorWindow != colorScrollbar))
1600
        // Use solid brush
1601
        ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_SCROLLBAR+1));      
1602
      else
1603
      {
1604
        // Use checkerboard pattern brush
1605
        HBRUSH brush, oldBrush;
1606
        HBITMAP patBmp;        
1607
        COLORREF oldBackColor, oldForeColor;
1608
        static WORD patBits[8] = {
1609
          0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
1610
        };
1611
1612
        patBmp = ::CreateBitmap(8, 8, 1, 1, patBits);
1613
        brush = (HBRUSH) ::CreatePatternBrush(patBmp);
1614
1615
        oldForeColor = ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
1616
        oldBackColor = ::SetBkColor(hdc, color3D);
1617
1618
        ::UnrealizeObject(brush);
1619
        ::SetBrushOrgEx(hdc, widgetRect.left, widgetRect.top, NULL);
1620
        oldBrush = (HBRUSH) ::SelectObject(hdc, brush);
1621
1622
        ::FillRect(hdc, &widgetRect, brush);
1623
1624
        ::SetTextColor(hdc, oldForeColor);
1625
        ::SetBkColor(hdc, oldBackColor);
1626
        ::SelectObject(hdc, oldBrush);
1627
        ::DeleteObject(brush);
1628
        ::DeleteObject(patBmp);
1629
      }
1630
      // XXX should invert the part of the track being clicked here
1631
      // but the track is never :active
1632
      return NS_OK;
1633
    }
1634
    case NS_THEME_PROGRESSBAR_CHUNK:
1635
    case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
1636
      ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_HIGHLIGHT+1));
1637
      return NS_OK;
1638
    // Draw Tab
1639
    case NS_THEME_TAB:
1640
    case NS_THEME_TAB_LEFT_EDGE:
1641
    case NS_THEME_TAB_RIGHT_EDGE: {
1642
      RECT cornerRect;
1643
      PRBool selected;
1644
      PRInt32 lOffset = 0;
1645
      PRInt32 rOffset = 0;
1646
1647
      // Tab background
1648
      ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_BTNFACE+1));
1649
1650
      selected = IsSelected(aFrame);
1651
1652
      // Tab bottom border, if not selected
1653
      if (!selected)
1654
        ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_BOTTOM);     
1655
1656
      if (aWidgetType != NS_THEME_TAB_RIGHT_EDGE) {
1657
        // Tab upper left corner
1658
        cornerRect.left = widgetRect.left;
1659
        cornerRect.top = widgetRect.top;
1660
        cornerRect.right = cornerRect.left+3;
1661
        cornerRect.bottom = cornerRect.top+3;
1662
        ::DrawEdge(hdc, &cornerRect, EDGE_RAISED, BF_SOFT | BF_DIAGONAL_ENDTOPRIGHT);
1663
        lOffset = 2;        
1664
1665
        // Tab left border
1666
        widgetRect.top += 2;
1667
        if (selected)
1668
          ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_LEFT);
1669
        else {
1670
          widgetRect.bottom-- ;
1671
          ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_LEFT);
1672
          widgetRect.bottom++;
1673
        }
1674
        widgetRect.top -= 2;        
1675
      }     
1676
      
1677
      if (aWidgetType != NS_THEME_TAB_LEFT_EDGE) {
1678
        // Tab upper right corner
1679
        cornerRect.left = widgetRect.right-2;
1680
        cornerRect.top = widgetRect.top+1;
1681
        cornerRect.right = cornerRect.left+1;
1682
        cornerRect.bottom = cornerRect.top+1;;
1683
        ::DrawEdge(hdc, &cornerRect, EDGE_RAISED, BF_SOFT | BF_DIAGONAL_ENDBOTTOMRIGHT);
1684
        rOffset = 2;
1685
1686
        // Tab right border
1687
        widgetRect.top += 2;
1688
        if (selected)
1689
          ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_RIGHT);
1690
        else {
1691
          widgetRect.bottom-- ;
1692
          ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_RIGHT);
1693
          widgetRect.bottom++;
1694
        }
1695
        widgetRect.top -= 2;        
1696
      }      
1697
1698
      // Tab top border, adjusted depending on which edges are drawn
1699
      widgetRect.left += lOffset;
1700
      widgetRect.right -= rOffset;
1701
      ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_TOP);
1702
1703
      return NS_OK;
1704
    }
1705
    case NS_THEME_TAB_PANELS:
1706
      ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_MIDDLE |
1707
          BF_LEFT | BF_RIGHT | BF_BOTTOM);
1708
      return NS_OK;
1709
1710
  }
1711
  return NS_ERROR_FAILURE;
1712
}
1713
1087
1714
1088
///////////////////////////////////////////
1715
///////////////////////////////////////////
1089
// Creation Routine
1716
// Creation Routine
(-)nsNativeThemeWin.h (+23 lines)
Line     Link Here 
 Lines 20-25    Link Here 
20
 * Original Author: David W. Hyatt (hyatt@netscape.com)
20
 * Original Author: David W. Hyatt (hyatt@netscape.com)
21
 * 
21
 * 
22
 * Contributors:
22
 * Contributors:
23
 *   Tim Hill (tim@prismelite.com)
23
 */
24
 */
24
25
25
#include "nsITheme.h"
26
#include "nsITheme.h"
 Lines 67-72    Link Here 
67
  HANDLE GetTheme(PRUint8 aWidgetType);
68
  HANDLE GetTheme(PRUint8 aWidgetType);
68
  nsresult GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
69
  nsresult GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
69
                                PRInt32& aPart, PRInt32& aState);
70
                                PRInt32& aPart, PRInt32& aState);
71
  nsresult OldGetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
72
                                   PRInt32& aPart, PRInt32& aState, PRBool& aFocused);
73
  nsresult OldDrawWidgetBackground(nsIRenderingContext* aContext,
74
                                  nsIFrame* aFrame,
75
                                  PRUint8 aWidgetType,
76
                                  const nsRect& aRect,
77
                                  const nsRect& aClipRect);
78
  nsresult OldGetWidgetBorder(nsIDeviceContext* aContext, 
79
                             nsIFrame* aFrame,
80
                             PRUint8 aWidgetType,
81
                             nsMargin* aResult);
82
83
  nsresult OldGetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
84
                                  PRUint8 aWidgetType,
85
                                  nsSize* aResult,
86
                                  PRBool* aIsOverridable);
87
88
  PRBool OldThemeSupportsWidget(nsIPresContext* aPresContext, 
89
                             nsIFrame* aFrame,
90
                             PRUint8 aWidgetType);
91
92
70
  PRBool IsDisabled(nsIFrame* aFrame);
93
  PRBool IsDisabled(nsIFrame* aFrame);
71
  PRBool IsReadOnly(nsIFrame* aFrame);
94
  PRBool IsReadOnly(nsIFrame* aFrame);
72
  PRBool IsChecked(nsIFrame* aFrame);
95
  PRBool IsChecked(nsIFrame* aFrame);

Return to bug 172751