Back to index

lightning-sunbird  0.9+nobinonly
nsXPLookAndFeel.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nscore.h"
00039 
00040 static int PR_CALLBACK colorPrefChanged(const char* aPref, void* aData);
00041 
00042 #include "nsXPLookAndFeel.h"
00043 #include "nsIServiceManager.h"
00044 #include "nsIPref.h"
00045 #include "nsCRT.h"
00046 #include "nsFont.h"
00047 
00048 #ifdef DEBUG
00049 #include "nsSize.h"
00050 #endif
00051  
00052 static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
00053 
00054 NS_IMPL_ISUPPORTS1(nsXPLookAndFeel, nsILookAndFeel)
00055 
00056 nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
00057 {
00058   { "ui.windowTitleHeight", eMetric_WindowTitleHeight, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00059   { "ui.windowBorderWidth", eMetric_WindowBorderWidth, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00060   { "ui.windowBorderHeight", eMetric_WindowBorderHeight, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00061   { "ui.widget3DBorder", eMetric_Widget3DBorder, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00062   { "ui.textFieldBorder", eMetric_TextFieldBorder, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00063   { "ui.textFieldHeight", eMetric_TextFieldHeight, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00064   { "ui.buttonHorizontalInsidePaddingNavQuirks",
00065     eMetric_ButtonHorizontalInsidePaddingNavQuirks, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00066   { "ui.buttonHorizontalInsidePaddingOffsetNavQuirks",
00067     eMetric_ButtonHorizontalInsidePaddingOffsetNavQuirks, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00068   { "ui.checkboxSize", eMetric_CheckboxSize, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00069   { "ui.radioboxSize", eMetric_RadioboxSize, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00070   { "ui.textHorizontalInsideMinimumPadding",
00071     eMetric_TextHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00072   { "ui.textVerticalInsidePadding", eMetric_TextVerticalInsidePadding,
00073     PR_FALSE, nsLookAndFeelTypeInt, 0 },
00074   { "ui.textShouldUseVerticalInsidePadding",
00075     eMetric_TextShouldUseVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00076   { "ui.textShouldUseHorizontalInsideMinimumPadding",
00077     eMetric_TextShouldUseHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00078   { "ui.listShouldUseHorizontalInsideMinimumPadding",
00079     eMetric_ListShouldUseHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00080   { "ui.listHorizontalInsideMinimumPadding",
00081     eMetric_ListHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00082   { "ui.listShouldUseVerticalInsidePadding",
00083     eMetric_ListShouldUseVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00084   { "ui.listVerticalInsidePadding", eMetric_ListVerticalInsidePadding,
00085     PR_FALSE, nsLookAndFeelTypeInt, 0 },
00086   { "ui.caretBlinkTime", eMetric_CaretBlinkTime, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00087   { "ui.caretWidth", eMetric_CaretWidth, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00088   { "ui.caretVisibleWithSelection", eMetric_ShowCaretDuringSelection, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00089   { "ui.submenuDelay", eMetric_SubmenuDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00090   { "ui.dragFullWindow", eMetric_DragFullWindow, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00091   { "ui.dragThresholdX", eMetric_DragThresholdX, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00092   { "ui.dragThresholdY", eMetric_DragThresholdY, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00093   { "ui.useAccessibilityTheme", eMetric_UseAccessibilityTheme, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00094   { "ui.isScreenReaderActive", eMetric_IsScreenReaderActive, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00095   { "ui.menusCanOverlapOSBar", eMetric_MenusCanOverlapOSBar,
00096     PR_FALSE, nsLookAndFeelTypeInt, 0 },
00097   { "ui.skipNavigatingDisabledMenuItem", eMetric_SkipNavigatingDisabledMenuItem, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00098   { "ui.treeOpenDelay",
00099     eMetric_TreeOpenDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00100   { "ui.treeCloseDelay",
00101     eMetric_TreeCloseDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00102   { "ui.treeLazyScrollDelay",
00103     eMetric_TreeLazyScrollDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00104   { "ui.treeScrollDelay",
00105     eMetric_TreeScrollDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00106   { "ui.treeScrollLinesMax",
00107     eMetric_TreeScrollLinesMax, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00108   { "accessibility.tabfocus",
00109     eMetric_TabFocusModel, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00110   { "ui.alertNotificationOrigin",
00111     eMetric_AlertNotificationOrigin, PR_FALSE, nsLookAndFeelTypeInt, 0 },
00112 };
00113 
00114 nsLookAndFeelFloatPref nsXPLookAndFeel::sFloatPrefs[] =
00115 {
00116   { "ui.textFieldVerticalInsidePadding",
00117     eMetricFloat_TextFieldVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00118   { "ui.textFieldHorizontalInsidePadding",
00119     eMetricFloat_TextFieldHorizontalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00120   { "ui.textAreaVerticalInsidePadding", eMetricFloat_TextAreaVerticalInsidePadding,
00121     PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00122   { "ui.textAreaHorizontalInsidePadding",
00123     eMetricFloat_TextAreaHorizontalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00124   { "ui.listVerticalInsidePadding",
00125     eMetricFloat_ListVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00126   { "ui.listHorizontalInsidePadding",
00127     eMetricFloat_ListHorizontalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00128   { "ui.buttonVerticalInsidePadding", eMetricFloat_ButtonVerticalInsidePadding,
00129     PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00130   { "ui.buttonHorizontalInsidePadding", eMetricFloat_ButtonHorizontalInsidePadding,
00131     PR_FALSE, nsLookAndFeelTypeFloat, 0 },
00132 };
00133 
00134 
00135 // This array MUST be kept in the same order as the color list in nsILookAndFeel.h.
00136 /* XXX If you add any strings longer than
00137  * "ui.-moz-mac-accentlightesthighlight"
00138  * to the following array then you MUST update the
00139  * sizes of the sColorPrefs array in nsXPLookAndFeel.h
00140  */
00141 const char nsXPLookAndFeel::sColorPrefs[][36] =
00142 {
00143   "ui.windowBackground",
00144   "ui.windowForeground",
00145   "ui.widgetBackground",
00146   "ui.widgetForeground",
00147   "ui.widgetSelectBackground",
00148   "ui.widgetSelectForeground",
00149   "ui.widget3DHighlight",
00150   "ui.widget3DShadow",
00151   "ui.textBackground",
00152   "ui.textForeground",
00153   "ui.textSelectBackground",
00154   "ui.textSelectForeground",
00155   "ui.textSelectBackgroundDisabled",
00156   "ui.textSelectBackgroundAttention",
00157   "ui.activeborder",
00158   "ui.activecaption",
00159   "ui.appworkspace",
00160   "ui.background",
00161   "ui.buttonface",
00162   "ui.buttonhighlight",
00163   "ui.buttonshadow",
00164   "ui.buttontext",
00165   "ui.captiontext",
00166   "ui.graytext",
00167   "ui.highlight",
00168   "ui.highlighttext",
00169   "ui.inactiveborder",
00170   "ui.inactivecaption",
00171   "ui.inactivecaptiontext",
00172   "ui.infobackground",
00173   "ui.infotext",
00174   "ui.menu",
00175   "ui.menutext",
00176   "ui.scrollbar",
00177   "ui.threeddarkshadow",
00178   "ui.threedface",
00179   "ui.threedhighlight",
00180   "ui.threedlightshadow",
00181   "ui.threedshadow",
00182   "ui.window",
00183   "ui.windowframe",
00184   "ui.windowtext",
00185   "ui.-moz-buttondefault",
00186   "ui.-moz-field",
00187   "ui.-moz-fieldtext",
00188   "ui.-moz-dialog",
00189   "ui.-moz-dialogtext",
00190   "ui.-moz-dragtargetzone",
00191   "ui.-moz-mac-focusring",
00192   "ui.-moz-mac-menuselect",
00193   "ui.-moz-mac-menushadow",
00194   "ui.-moz-mac-menutextdisable",
00195   "ui.-moz-mac-menutextselect",
00196   "ui.-moz-mac-accentlightesthighlight",
00197   "ui.-moz-mac-accentregularhighlight",
00198   "ui.-moz-mac-accentface",
00199   "ui.-moz-mac-accentlightshadow",
00200   "ui.-moz-mac-accentregularshadow",
00201   "ui.-moz-mac-accentdarkshadow",
00202   "ui.-moz-mac-accentdarkestshadow"
00203 };
00204 
00205 PRInt32 nsXPLookAndFeel::sCachedColors[nsILookAndFeel::eColor_LAST_COLOR] = {0};
00206 PRInt32 nsXPLookAndFeel::sCachedColorBits[COLOR_CACHE_SIZE] = {0};
00207 
00208 PRBool nsXPLookAndFeel::sInitialized = PR_FALSE;
00209 
00210 nsXPLookAndFeel::nsXPLookAndFeel() : nsILookAndFeel()
00211 {
00212 }
00213 
00214 static int PR_CALLBACK intPrefChanged (const char *newpref, void *data)
00215 {
00216   nsLookAndFeelIntPref* np = (nsLookAndFeelIntPref*)data;
00217   if (np)
00218   {
00219     nsresult rv;
00220     nsCOMPtr<nsIPref> prefService(do_GetService(kPrefServiceCID, &rv));
00221     if (NS_SUCCEEDED(rv) && prefService)
00222     {
00223       PRInt32 intpref;
00224       rv = prefService->GetIntPref(np->name, &intpref);
00225       if (NS_SUCCEEDED(rv))
00226       {
00227         np->intVar = intpref;
00228         np->isSet = PR_TRUE;
00229 #ifdef DEBUG_akkana
00230         printf("====== Changed int pref %s to %d\n", np->name, np->intVar);
00231 #endif
00232       }
00233     }
00234   }
00235   return 0;
00236 }
00237 
00238 static int PR_CALLBACK floatPrefChanged (const char *newpref, void *data)
00239 {
00240   nsLookAndFeelFloatPref* np = (nsLookAndFeelFloatPref*)data;
00241   if (np)
00242   {
00243     nsresult rv;
00244     nsCOMPtr<nsIPref> prefService(do_GetService(kPrefServiceCID, &rv));
00245     if (NS_SUCCEEDED(rv) && prefService)
00246     {
00247       PRInt32 intpref;
00248       rv = prefService->GetIntPref(np->name, &intpref);
00249       if (NS_SUCCEEDED(rv))
00250       {
00251         np->floatVar = (float)intpref / 100.;
00252         np->isSet = PR_TRUE;
00253 #ifdef DEBUG_akkana
00254         printf("====== Changed float pref %s to %f\n", np->name, np->floatVar);
00255 #endif
00256       }
00257     }
00258   }
00259   return 0;
00260 }
00261 
00262 static int PR_CALLBACK colorPrefChanged (const char *newpref, void *data)
00263 {
00264   nsresult rv;
00265   nsCOMPtr<nsIPref> prefService(do_GetService(kPrefServiceCID, &rv));
00266   if (NS_SUCCEEDED(rv) && prefService) {
00267     nsXPIDLCString colorStr;
00268     rv = prefService->CopyCharPref(newpref, getter_Copies(colorStr));
00269     if (NS_SUCCEEDED(rv) && colorStr[0]) {
00270       nscolor thecolor;
00271       if (colorStr[0] == '#') {
00272         if (NS_SUCCEEDED(NS_HexToRGB(NS_ConvertASCIItoUCS2(Substring(colorStr, 1, colorStr.Length() - 1)),
00273                                      &thecolor))) {
00274           PRInt32 id = NS_PTR_TO_INT32(data);
00275           CACHE_COLOR(id, thecolor);
00276         }
00277       }
00278       else if (NS_SUCCEEDED(NS_ColorNameToRGB(NS_ConvertASCIItoUCS2(colorStr),
00279                                          &thecolor))) {
00280         PRInt32 id = NS_PTR_TO_INT32(data);
00281         CACHE_COLOR(id, thecolor);
00282 #ifdef DEBUG_akkana
00283         printf("====== Changed color pref %s to 0x%lx\n",
00284                newpref, thecolor);
00285 #endif
00286       }
00287     }
00288   }
00289   return 0;
00290 }
00291 
00292 nsresult
00293 nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref* aPref, nsIPref* aPrefService)
00294 {
00295   PRInt32 intpref;
00296   nsresult rv = aPrefService->GetIntPref(aPref->name, &intpref);
00297   if (NS_SUCCEEDED(rv))
00298   {
00299     aPref->isSet = PR_TRUE;
00300     aPref->intVar = intpref;
00301   }
00302   aPrefService->RegisterCallback(aPref->name, intPrefChanged, aPref);
00303   return rv;
00304 }
00305 
00306 nsresult
00307 nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref* aPref, nsIPref* aPrefService)
00308 {
00309   PRInt32 intpref;
00310   nsresult rv = aPrefService->GetIntPref(aPref->name, &intpref);
00311   if (NS_SUCCEEDED(rv))
00312   {
00313     aPref->isSet = PR_TRUE;
00314     aPref->floatVar = (float)intpref / 100.;
00315   }
00316   aPrefService->RegisterCallback(aPref->name, floatPrefChanged, aPref);
00317   return rv;
00318 }
00319 
00320 nsresult
00321 nsXPLookAndFeel::InitColorFromPref(PRInt32 i, nsIPref* aPrefService)
00322 {
00323   char *colorStr = 0;
00324   nsresult rv = aPrefService->CopyCharPref(sColorPrefs[i], &colorStr);
00325   if (NS_SUCCEEDED(rv) && colorStr[0])
00326   {
00327     nsAutoString colorNSStr; colorNSStr.AssignWithConversion(colorStr);
00328     nscolor thecolor;
00329     if (colorNSStr[0] == '#') {
00330       nsAutoString hexString;
00331       colorNSStr.Right(hexString, colorNSStr.Length() - 1);
00332       if (NS_SUCCEEDED(NS_HexToRGB(hexString, &thecolor))) {
00333         CACHE_COLOR(i, thecolor);
00334         PL_strfree(colorStr);
00335       }
00336     }
00337     else if (NS_SUCCEEDED(NS_ColorNameToRGB(colorNSStr, &thecolor)))
00338     {
00339       CACHE_COLOR(i, thecolor);
00340       PL_strfree(colorStr);
00341     }
00342   }
00343 
00344   aPrefService->RegisterCallback(sColorPrefs[i], colorPrefChanged, (void*)i);
00345   return rv;
00346 }
00347 
00348 //
00349 // Read values from the user's preferences.
00350 // This is done once at startup, but since the user's preferences
00351 // haven't actually been read yet at that time, we also have to
00352 // set a callback to inform us of changes to each pref.
00353 //
00354 void
00355 nsXPLookAndFeel::Init()
00356 {
00357   // Say we're already initialized, and take the chance that it might fail;
00358   // protects against some other process writing to our static variables.
00359   sInitialized = PR_TRUE;
00360 
00361   nsresult rv;
00362   nsCOMPtr<nsIPref> prefService(do_GetService(kPrefServiceCID, &rv));
00363   if (NS_FAILED(rv) || !prefService)
00364     return;
00365 
00366   unsigned int i;
00367   for (i = 0; i < ((sizeof (sIntPrefs) / sizeof (*sIntPrefs))); ++i)
00368     InitFromPref(&sIntPrefs[i], prefService);
00369 
00370   for (i = 0; i < ((sizeof (sFloatPrefs) / sizeof (*sFloatPrefs))); ++i)
00371     InitFromPref(&sFloatPrefs[i], prefService);
00372 
00373   for (i = 0; i < (sizeof(sColorPrefs) / sizeof (*sColorPrefs)); ++i)
00374     InitColorFromPref(i, prefService);
00375 }
00376 
00377 nsXPLookAndFeel::~nsXPLookAndFeel()
00378 {
00379 }
00380 
00381 //
00382 // All these routines will return NS_OK if they have a value,
00383 // in which case the nsLookAndFeel should use that value;
00384 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
00385 // platform-specific nsLookAndFeel should use its own values instead.
00386 //
00387 NS_IMETHODIMP nsXPLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor)
00388 {
00389   if (!sInitialized)
00390     Init();
00391 
00392   // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
00393   // use in a skin that uses them.  When set, it will make all system
00394   // color pairs that are appropriate for foreground/background
00395   // pairing the same.  This means if the skin is using system colors
00396   // correctly you will not be able to see *any* text.
00397 #undef DEBUG_SYSTEM_COLOR_USE
00398 
00399 #ifdef DEBUG_SYSTEM_COLOR_USE
00400   {
00401     nsresult rv = NS_OK;
00402     switch (aID) {
00403         // css2  http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
00404       case eColor_activecaption:
00405           // active window caption background
00406       case eColor_captiontext:
00407           // text in active window caption
00408         aColor = NS_RGB(0xff, 0x00, 0x00);
00409         break;
00410 
00411       case eColor_highlight:
00412           // background of selected item
00413       case eColor_highlighttext:
00414           // text of selected item
00415         aColor = NS_RGB(0xff, 0xff, 0x00);
00416         break;
00417 
00418       case eColor_inactivecaption:
00419           // inactive window caption
00420       case eColor_inactivecaptiontext:
00421           // text in inactive window caption
00422         aColor = NS_RGB(0x66, 0x66, 0x00);
00423         break;
00424 
00425       case eColor_infobackground:
00426           // tooltip background color
00427       case eColor_infotext:
00428           // tooltip text color
00429         aColor = NS_RGB(0x00, 0xff, 0x00);
00430         break;
00431 
00432       case eColor_menu:
00433           // menu background
00434       case eColor_menutext:
00435           // menu text
00436         aColor = NS_RGB(0x00, 0xff, 0xff);
00437         break;
00438 
00439       case eColor_threedface:
00440       case eColor_buttonface:
00441           // 3-D face color
00442       case eColor_buttontext:
00443           // text on push buttons
00444         aColor = NS_RGB(0x00, 0x66, 0x66);
00445         break;
00446 
00447       case eColor_window:
00448       case eColor_windowtext:
00449         aColor = NS_RGB(0x00, 0x00, 0xff);
00450         break;
00451 
00452       // from the CSS3 working draft (not yet finalized)
00453       // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
00454 
00455       case eColor__moz_field:
00456       case eColor__moz_fieldtext:
00457         aColor = NS_RGB(0xff, 0x00, 0xff);
00458         break;
00459 
00460       case eColor__moz_dialog:
00461       case eColor__moz_dialogtext:
00462         aColor = NS_RGB(0x66, 0x00, 0x66);
00463         break;
00464 
00465       default:
00466         rv = NS_ERROR_NOT_AVAILABLE;
00467     }
00468     if (NS_SUCCEEDED(rv))
00469       return rv;
00470   }
00471 #endif // DEBUG_SYSTEM_COLOR_USE
00472 
00473   if (IS_COLOR_CACHED(aID)) {
00474     aColor = sCachedColors[aID];
00475     return NS_OK;
00476   }
00477 
00478   // There are no system color settings for these, so set them manually
00479   if (aID == eColor_TextSelectBackgroundDisabled) {
00480     // This is used to gray out the selection when it's not focused
00481     // Used with nsISelectionController::SELECTION_DISABLED
00482     aColor = NS_RGB(0xb0, 0xb0, 0xb0);
00483     return NS_OK;
00484   }
00485 
00486   if (aID == eColor_TextSelectBackgroundAttention) {
00487     // This makes the selection stand out when typeaheadfind is on
00488     // Used with nsISelectionController::SELECTION_ATTENTION
00489     aColor = NS_RGB(0x38, 0xd8, 0x78);
00490     return NS_OK;
00491   }
00492 
00493   if (NS_SUCCEEDED(NativeGetColor(aID, aColor))) {
00494     CACHE_COLOR(aID, aColor);
00495     return NS_OK;
00496   }
00497 
00498   return NS_ERROR_NOT_AVAILABLE;
00499 }
00500   
00501 NS_IMETHODIMP nsXPLookAndFeel::GetMetric(const nsMetricID aID, PRInt32& aMetric)
00502 {
00503   if (!sInitialized)
00504     Init();
00505 
00506   for (unsigned int i = 0; i < ((sizeof (sIntPrefs) / sizeof (*sIntPrefs))); ++i)
00507     if (sIntPrefs[i].isSet && (sIntPrefs[i].id == aID))
00508     {
00509       aMetric = sIntPrefs[i].intVar;
00510       return NS_OK;
00511     }
00512 
00513   return NS_ERROR_NOT_AVAILABLE;
00514 }
00515 
00516 NS_IMETHODIMP
00517 nsXPLookAndFeel::GetMetric(const nsMetricFloatID aID, float& aMetric)
00518 {
00519   if (!sInitialized)
00520     Init();
00521 
00522   for (unsigned int i = 0; i < ((sizeof (sFloatPrefs) / sizeof (*sFloatPrefs))); ++i)
00523     if (sFloatPrefs[i].isSet && sFloatPrefs[i].id == aID)
00524     {
00525       aMetric = sFloatPrefs[i].floatVar;
00526       return NS_OK;
00527     }
00528 
00529   return NS_ERROR_NOT_AVAILABLE;
00530 }
00531 
00532 NS_IMETHODIMP
00533 nsXPLookAndFeel::LookAndFeelChanged()
00534 {
00535   // Wipe out our color cache.
00536   PRUint32 i;
00537   for (i = 0; i < nsILookAndFeel::eColor_LAST_COLOR; i++)
00538     sCachedColors[i] = 0;
00539   for (i = 0; i < COLOR_CACHE_SIZE; i++)
00540     sCachedColorBits[i] = 0;
00541   return NS_OK;
00542 }
00543 
00544 
00545 #ifdef DEBUG
00546   // This method returns the actual (or nearest estimate) 
00547   // of the Navigator size for a given form control for a given font
00548   // and font size. This is used in NavQuirks mode to see how closely
00549   // we match its size
00550 NS_IMETHODIMP
00551 nsXPLookAndFeel::GetNavSize(const nsMetricNavWidgetID aWidgetID,
00552                             const nsMetricNavFontID   aFontID, 
00553                             const PRInt32             aFontSize, 
00554                             nsSize &aSize)
00555 {
00556   aSize.width  = 0;
00557   aSize.height = 0;
00558   return NS_ERROR_NOT_IMPLEMENTED;
00559 }
00560 #endif