widget/xpwidgets/nsXPLookAndFeel.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:dab1c7f1e112
1 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "mozilla/ArrayUtils.h"
7
8 #include "nscore.h"
9
10 #include "nsXPLookAndFeel.h"
11 #include "nsLookAndFeel.h"
12 #include "nsCRT.h"
13 #include "nsFont.h"
14 #include "nsThemeConstants.h"
15 #include "mozilla/Preferences.h"
16 #include "mozilla/gfx/2D.h"
17
18 #include "gfxPlatform.h"
19 #include "qcms.h"
20
21 #ifdef DEBUG
22 #include "nsSize.h"
23 #endif
24
25 using namespace mozilla;
26
27 nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
28 {
29 { "ui.caretBlinkTime",
30 eIntID_CaretBlinkTime,
31 false, 0 },
32 { "ui.caretWidth",
33 eIntID_CaretWidth,
34 false, 0 },
35 { "ui.caretVisibleWithSelection",
36 eIntID_ShowCaretDuringSelection,
37 false, 0 },
38 { "ui.submenuDelay",
39 eIntID_SubmenuDelay,
40 false, 0 },
41 { "ui.dragThresholdX",
42 eIntID_DragThresholdX,
43 false, 0 },
44 { "ui.dragThresholdY",
45 eIntID_DragThresholdY,
46 false, 0 },
47 { "ui.useAccessibilityTheme",
48 eIntID_UseAccessibilityTheme,
49 false, 0 },
50 { "ui.menusCanOverlapOSBar",
51 eIntID_MenusCanOverlapOSBar,
52 false, 0 },
53 { "ui.useOverlayScrollbars",
54 eIntID_UseOverlayScrollbars,
55 false, 0 },
56 { "ui.scrollbarDisplayOnMouseMove",
57 eIntID_ScrollbarDisplayOnMouseMove,
58 false, 0 },
59 { "ui.scrollbarFadeBeginDelay",
60 eIntID_ScrollbarFadeBeginDelay,
61 false, 0 },
62 { "ui.scrollbarFadeDuration",
63 eIntID_ScrollbarFadeDuration,
64 false, 0 },
65 { "ui.showHideScrollbars",
66 eIntID_ShowHideScrollbars,
67 false, 0 },
68 { "ui.skipNavigatingDisabledMenuItem",
69 eIntID_SkipNavigatingDisabledMenuItem,
70 false, 0 },
71 { "ui.treeOpenDelay",
72 eIntID_TreeOpenDelay,
73 false, 0 },
74 { "ui.treeCloseDelay",
75 eIntID_TreeCloseDelay,
76 false, 0 },
77 { "ui.treeLazyScrollDelay",
78 eIntID_TreeLazyScrollDelay,
79 false, 0 },
80 { "ui.treeScrollDelay",
81 eIntID_TreeScrollDelay,
82 false, 0 },
83 { "ui.treeScrollLinesMax",
84 eIntID_TreeScrollLinesMax,
85 false, 0 },
86 { "accessibility.tabfocus",
87 eIntID_TabFocusModel,
88 false, 0 },
89 { "ui.alertNotificationOrigin",
90 eIntID_AlertNotificationOrigin,
91 false, 0 },
92 { "ui.scrollToClick",
93 eIntID_ScrollToClick,
94 false, 0 },
95 { "ui.IMERawInputUnderlineStyle",
96 eIntID_IMERawInputUnderlineStyle,
97 false, 0 },
98 { "ui.IMESelectedRawTextUnderlineStyle",
99 eIntID_IMESelectedRawTextUnderlineStyle,
100 false, 0 },
101 { "ui.IMEConvertedTextUnderlineStyle",
102 eIntID_IMEConvertedTextUnderlineStyle,
103 false, 0 },
104 { "ui.IMESelectedConvertedTextUnderlineStyle",
105 eIntID_IMESelectedConvertedTextUnderline,
106 false, 0 },
107 { "ui.SpellCheckerUnderlineStyle",
108 eIntID_SpellCheckerUnderlineStyle,
109 false, 0 },
110 { "ui.scrollbarButtonAutoRepeatBehavior",
111 eIntID_ScrollbarButtonAutoRepeatBehavior,
112 false, 0 },
113 { "ui.tooltipDelay",
114 eIntID_TooltipDelay,
115 false, 0 },
116 { "ui.physicalHomeButton",
117 eIntID_PhysicalHomeButton,
118 false, 0 },
119 };
120
121 nsLookAndFeelFloatPref nsXPLookAndFeel::sFloatPrefs[] =
122 {
123 { "ui.IMEUnderlineRelativeSize",
124 eFloatID_IMEUnderlineRelativeSize,
125 false, 0 },
126 { "ui.SpellCheckerUnderlineRelativeSize",
127 eFloatID_SpellCheckerUnderlineRelativeSize,
128 false, 0 },
129 { "ui.caretAspectRatio",
130 eFloatID_CaretAspectRatio,
131 false, 0 },
132 };
133
134
135 // This array MUST be kept in the same order as the color list in LookAndFeel.h.
136 /* XXX If you add any strings longer than
137 * "ui.IMESelectedConvertedTextBackground"
138 * to the following array then you MUST update the
139 * sizes of the sColorPrefs array in nsXPLookAndFeel.h
140 */
141 const char nsXPLookAndFeel::sColorPrefs[][38] =
142 {
143 "ui.windowBackground",
144 "ui.windowForeground",
145 "ui.widgetBackground",
146 "ui.widgetForeground",
147 "ui.widgetSelectBackground",
148 "ui.widgetSelectForeground",
149 "ui.widget3DHighlight",
150 "ui.widget3DShadow",
151 "ui.textBackground",
152 "ui.textForeground",
153 "ui.textSelectBackground",
154 "ui.textSelectForeground",
155 "ui.textSelectBackgroundDisabled",
156 "ui.textSelectBackgroundAttention",
157 "ui.textHighlightBackground",
158 "ui.textHighlightForeground",
159 "ui.IMERawInputBackground",
160 "ui.IMERawInputForeground",
161 "ui.IMERawInputUnderline",
162 "ui.IMESelectedRawTextBackground",
163 "ui.IMESelectedRawTextForeground",
164 "ui.IMESelectedRawTextUnderline",
165 "ui.IMEConvertedTextBackground",
166 "ui.IMEConvertedTextForeground",
167 "ui.IMEConvertedTextUnderline",
168 "ui.IMESelectedConvertedTextBackground",
169 "ui.IMESelectedConvertedTextForeground",
170 "ui.IMESelectedConvertedTextUnderline",
171 "ui.SpellCheckerUnderline",
172 "ui.activeborder",
173 "ui.activecaption",
174 "ui.appworkspace",
175 "ui.background",
176 "ui.buttonface",
177 "ui.buttonhighlight",
178 "ui.buttonshadow",
179 "ui.buttontext",
180 "ui.captiontext",
181 "ui.graytext",
182 "ui.highlight",
183 "ui.highlighttext",
184 "ui.inactiveborder",
185 "ui.inactivecaption",
186 "ui.inactivecaptiontext",
187 "ui.infobackground",
188 "ui.infotext",
189 "ui.menu",
190 "ui.menutext",
191 "ui.scrollbar",
192 "ui.threeddarkshadow",
193 "ui.threedface",
194 "ui.threedhighlight",
195 "ui.threedlightshadow",
196 "ui.threedshadow",
197 "ui.window",
198 "ui.windowframe",
199 "ui.windowtext",
200 "ui.-moz-buttondefault",
201 "ui.-moz-field",
202 "ui.-moz-fieldtext",
203 "ui.-moz-dialog",
204 "ui.-moz-dialogtext",
205 "ui.-moz-dragtargetzone",
206 "ui.-moz-cellhighlight",
207 "ui.-moz_cellhighlighttext",
208 "ui.-moz-html-cellhighlight",
209 "ui.-moz-html-cellhighlighttext",
210 "ui.-moz-buttonhoverface",
211 "ui.-moz_buttonhovertext",
212 "ui.-moz_menuhover",
213 "ui.-moz_menuhovertext",
214 "ui.-moz_menubartext",
215 "ui.-moz_menubarhovertext",
216 "ui.-moz_eventreerow",
217 "ui.-moz_oddtreerow",
218 "ui.-moz_mac_chrome_active",
219 "ui.-moz_mac_chrome_inactive",
220 "ui.-moz-mac-focusring",
221 "ui.-moz-mac-menuselect",
222 "ui.-moz-mac-menushadow",
223 "ui.-moz-mac-menutextdisable",
224 "ui.-moz-mac-menutextselect",
225 "ui.-moz_mac_disabledtoolbartext",
226 "ui.-moz-mac-secondaryhighlight",
227 "ui.-moz-win-mediatext",
228 "ui.-moz-win-communicationstext",
229 "ui.-moz-nativehyperlinktext",
230 "ui.-moz-comboboxtext",
231 "ui.-moz-combobox"
232 };
233
234 int32_t nsXPLookAndFeel::sCachedColors[LookAndFeel::eColorID_LAST_COLOR] = {0};
235 int32_t nsXPLookAndFeel::sCachedColorBits[COLOR_CACHE_SIZE] = {0};
236
237 bool nsXPLookAndFeel::sInitialized = false;
238 bool nsXPLookAndFeel::sUseNativeColors = true;
239
240 nsLookAndFeel* nsXPLookAndFeel::sInstance = nullptr;
241 bool nsXPLookAndFeel::sShutdown = false;
242
243 // static
244 nsLookAndFeel*
245 nsXPLookAndFeel::GetInstance()
246 {
247 if (sInstance) {
248 return sInstance;
249 }
250
251 NS_ENSURE_TRUE(!sShutdown, nullptr);
252
253 sInstance = new nsLookAndFeel();
254 return sInstance;
255 }
256
257 // static
258 void
259 nsXPLookAndFeel::Shutdown()
260 {
261 if (sShutdown) {
262 return;
263 }
264 sShutdown = true;
265 delete sInstance;
266 sInstance = nullptr;
267 }
268
269 nsXPLookAndFeel::nsXPLookAndFeel() : LookAndFeel()
270 {
271 }
272
273 // static
274 void
275 nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref *data)
276 {
277 if (!data) {
278 return;
279 }
280
281 int32_t intpref;
282 nsresult rv = Preferences::GetInt(data->name, &intpref);
283 if (NS_FAILED(rv)) {
284 return;
285 }
286 data->intVar = intpref;
287 data->isSet = true;
288 #ifdef DEBUG_akkana
289 printf("====== Changed int pref %s to %d\n", data->name, data->intVar);
290 #endif
291 }
292
293 // static
294 void
295 nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref *data)
296 {
297 if (!data) {
298 return;
299 }
300
301 int32_t intpref;
302 nsresult rv = Preferences::GetInt(data->name, &intpref);
303 if (NS_FAILED(rv)) {
304 return;
305 }
306 data->floatVar = (float)intpref / 100.0f;
307 data->isSet = true;
308 #ifdef DEBUG_akkana
309 printf("====== Changed float pref %s to %f\n", data->name, data->floatVar);
310 #endif
311 }
312
313 // static
314 void
315 nsXPLookAndFeel::ColorPrefChanged (unsigned int index, const char *prefName)
316 {
317 nsAutoString colorStr;
318 nsresult rv = Preferences::GetString(prefName, &colorStr);
319 if (NS_FAILED(rv)) {
320 return;
321 }
322 if (!colorStr.IsEmpty()) {
323 nscolor thecolor;
324 if (colorStr[0] == char16_t('#')) {
325 if (NS_HexToRGB(nsDependentString(colorStr, 1), &thecolor)) {
326 int32_t id = NS_PTR_TO_INT32(index);
327 CACHE_COLOR(id, thecolor);
328 }
329 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
330 int32_t id = NS_PTR_TO_INT32(index);
331 CACHE_COLOR(id, thecolor);
332 #ifdef DEBUG_akkana
333 printf("====== Changed color pref %s to 0x%lx\n",
334 prefName, thecolor);
335 #endif
336 }
337 } else {
338 // Reset to the default color, by clearing the cache
339 // to force lookup when the color is next used
340 int32_t id = NS_PTR_TO_INT32(index);
341 CLEAR_COLOR_CACHE(id);
342 }
343 }
344
345 void
346 nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref* aPref)
347 {
348 int32_t intpref;
349 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
350 if (NS_SUCCEEDED(rv)) {
351 aPref->isSet = true;
352 aPref->intVar = intpref;
353 }
354 }
355
356 void
357 nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref* aPref)
358 {
359 int32_t intpref;
360 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
361 if (NS_SUCCEEDED(rv)) {
362 aPref->isSet = true;
363 aPref->floatVar = (float)intpref / 100.0f;
364 }
365 }
366
367 void
368 nsXPLookAndFeel::InitColorFromPref(int32_t i)
369 {
370 nsAutoString colorStr;
371 nsresult rv = Preferences::GetString(sColorPrefs[i], &colorStr);
372 if (NS_FAILED(rv) || colorStr.IsEmpty()) {
373 return;
374 }
375 nscolor thecolor;
376 if (colorStr[0] == char16_t('#')) {
377 nsAutoString hexString;
378 colorStr.Right(hexString, colorStr.Length() - 1);
379 if (NS_HexToRGB(hexString, &thecolor)) {
380 CACHE_COLOR(i, thecolor);
381 }
382 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
383 CACHE_COLOR(i, thecolor);
384 }
385 }
386
387 // static
388 void
389 nsXPLookAndFeel::OnPrefChanged(const char* aPref, void* aClosure)
390 {
391
392 // looping in the same order as in ::Init
393
394 nsDependentCString prefName(aPref);
395 unsigned int i;
396 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
397 if (prefName.Equals(sIntPrefs[i].name)) {
398 IntPrefChanged(&sIntPrefs[i]);
399 return;
400 }
401 }
402
403 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
404 if (prefName.Equals(sFloatPrefs[i].name)) {
405 FloatPrefChanged(&sFloatPrefs[i]);
406 return;
407 }
408 }
409
410 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
411 if (prefName.Equals(sColorPrefs[i])) {
412 ColorPrefChanged(i, sColorPrefs[i]);
413 return;
414 }
415 }
416 }
417
418 //
419 // Read values from the user's preferences.
420 // This is done once at startup, but since the user's preferences
421 // haven't actually been read yet at that time, we also have to
422 // set a callback to inform us of changes to each pref.
423 //
424 void
425 nsXPLookAndFeel::Init()
426 {
427 // Say we're already initialized, and take the chance that it might fail;
428 // protects against some other process writing to our static variables.
429 sInitialized = true;
430
431 // XXX If we could reorganize the pref names, we should separate the branch
432 // for each types. Then, we could reduce the unnecessary loop from
433 // nsXPLookAndFeel::OnPrefChanged().
434 Preferences::RegisterCallback(OnPrefChanged, "ui.");
435 Preferences::RegisterCallback(OnPrefChanged, "accessibility.tabfocus");
436
437 unsigned int i;
438 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
439 InitFromPref(&sIntPrefs[i]);
440 }
441
442 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
443 InitFromPref(&sFloatPrefs[i]);
444 }
445
446 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
447 InitColorFromPref(i);
448 }
449
450 bool val;
451 if (NS_SUCCEEDED(Preferences::GetBool("ui.use_native_colors", &val))) {
452 sUseNativeColors = val;
453 }
454 }
455
456 nsXPLookAndFeel::~nsXPLookAndFeel()
457 {
458 NS_ASSERTION(sInstance == this,
459 "This destroying instance isn't the singleton instance");
460 sInstance = nullptr;
461 }
462
463 bool
464 nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor &aColor)
465 {
466 switch (aID) {
467 case eColorID_TextSelectForeground:
468 return (aColor == NS_DONT_CHANGE_COLOR);
469 case eColorID_IMESelectedRawTextBackground:
470 case eColorID_IMESelectedConvertedTextBackground:
471 case eColorID_IMERawInputBackground:
472 case eColorID_IMEConvertedTextBackground:
473 case eColorID_IMESelectedRawTextForeground:
474 case eColorID_IMESelectedConvertedTextForeground:
475 case eColorID_IMERawInputForeground:
476 case eColorID_IMEConvertedTextForeground:
477 case eColorID_IMERawInputUnderline:
478 case eColorID_IMEConvertedTextUnderline:
479 case eColorID_IMESelectedRawTextUnderline:
480 case eColorID_IMESelectedConvertedTextUnderline:
481 case eColorID_SpellCheckerUnderline:
482 return NS_IS_SELECTION_SPECIAL_COLOR(aColor);
483 default:
484 /*
485 * In GetColor(), every color that is not a special color is color
486 * corrected. Use false to make other colors color corrected.
487 */
488 return false;
489 }
490 return false;
491 }
492
493 bool
494 nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID)
495 {
496 bool result = false;
497
498 switch (aID) {
499 case eColorID_WindowBackground:
500 case eColorID_WindowForeground:
501 case eColorID_WidgetBackground:
502 case eColorID_WidgetForeground:
503 case eColorID_WidgetSelectBackground:
504 case eColorID_WidgetSelectForeground:
505 case eColorID_Widget3DHighlight:
506 case eColorID_Widget3DShadow:
507 case eColorID_TextBackground:
508 case eColorID_TextForeground:
509 case eColorID_TextSelectBackground:
510 case eColorID_TextSelectForeground:
511 case eColorID_TextSelectBackgroundDisabled:
512 case eColorID_TextSelectBackgroundAttention:
513 case eColorID_TextHighlightBackground:
514 case eColorID_TextHighlightForeground:
515 case eColorID_IMERawInputBackground:
516 case eColorID_IMERawInputForeground:
517 case eColorID_IMERawInputUnderline:
518 case eColorID_IMESelectedRawTextBackground:
519 case eColorID_IMESelectedRawTextForeground:
520 case eColorID_IMESelectedRawTextUnderline:
521 case eColorID_IMEConvertedTextBackground:
522 case eColorID_IMEConvertedTextForeground:
523 case eColorID_IMEConvertedTextUnderline:
524 case eColorID_IMESelectedConvertedTextBackground:
525 case eColorID_IMESelectedConvertedTextForeground:
526 case eColorID_IMESelectedConvertedTextUnderline:
527 case eColorID_SpellCheckerUnderline:
528 result = true;
529 break;
530 default:
531 break;
532 }
533
534 return result;
535 }
536
537 nscolor
538 nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID)
539 {
540 nscolor result = NS_RGB(0xFF, 0xFF, 0xFF);
541
542 // The stand-in colors are taken from the Windows 7 Aero theme
543 // except Mac-specific colors which are taken from Mac OS 10.7.
544 switch (aID) {
545 // CSS 2 colors:
546 case eColorID_activeborder: result = NS_RGB(0xB4, 0xB4, 0xB4); break;
547 case eColorID_activecaption: result = NS_RGB(0x99, 0xB4, 0xD1); break;
548 case eColorID_appworkspace: result = NS_RGB(0xAB, 0xAB, 0xAB); break;
549 case eColorID_background: result = NS_RGB(0x00, 0x00, 0x00); break;
550 case eColorID_buttonface: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
551 case eColorID_buttonhighlight: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
552 case eColorID_buttonshadow: result = NS_RGB(0xA0, 0xA0, 0xA0); break;
553 case eColorID_buttontext: result = NS_RGB(0x00, 0x00, 0x00); break;
554 case eColorID_captiontext: result = NS_RGB(0x00, 0x00, 0x00); break;
555 case eColorID_graytext: result = NS_RGB(0x6D, 0x6D, 0x6D); break;
556 case eColorID_highlight: result = NS_RGB(0x33, 0x99, 0xFF); break;
557 case eColorID_highlighttext: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
558 case eColorID_inactiveborder: result = NS_RGB(0xF4, 0xF7, 0xFC); break;
559 case eColorID_inactivecaption: result = NS_RGB(0xBF, 0xCD, 0xDB); break;
560 case eColorID_inactivecaptiontext:
561 result = NS_RGB(0x43, 0x4E, 0x54); break;
562 case eColorID_infobackground: result = NS_RGB(0xFF, 0xFF, 0xE1); break;
563 case eColorID_infotext: result = NS_RGB(0x00, 0x00, 0x00); break;
564 case eColorID_menu: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
565 case eColorID_menutext: result = NS_RGB(0x00, 0x00, 0x00); break;
566 case eColorID_scrollbar: result = NS_RGB(0xC8, 0xC8, 0xC8); break;
567 case eColorID_threeddarkshadow: result = NS_RGB(0x69, 0x69, 0x69); break;
568 case eColorID_threedface: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
569 case eColorID_threedhighlight: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
570 case eColorID_threedlightshadow: result = NS_RGB(0xE3, 0xE3, 0xE3); break;
571 case eColorID_threedshadow: result = NS_RGB(0xA0, 0xA0, 0xA0); break;
572 case eColorID_window: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
573 case eColorID_windowframe: result = NS_RGB(0x64, 0x64, 0x64); break;
574 case eColorID_windowtext: result = NS_RGB(0x00, 0x00, 0x00); break;
575 case eColorID__moz_buttondefault:
576 result = NS_RGB(0x69, 0x69, 0x69); break;
577 case eColorID__moz_field: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
578 case eColorID__moz_fieldtext: result = NS_RGB(0x00, 0x00, 0x00); break;
579 case eColorID__moz_dialog: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
580 case eColorID__moz_dialogtext: result = NS_RGB(0x00, 0x00, 0x00); break;
581 case eColorID__moz_dragtargetzone:
582 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
583 case eColorID__moz_cellhighlight:
584 result = NS_RGB(0xF0, 0xF0, 0xF0); break;
585 case eColorID__moz_cellhighlighttext:
586 result = NS_RGB(0x00, 0x00, 0x00); break;
587 case eColorID__moz_html_cellhighlight:
588 result = NS_RGB(0x33, 0x99, 0xFF); break;
589 case eColorID__moz_html_cellhighlighttext:
590 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
591 case eColorID__moz_buttonhoverface:
592 result = NS_RGB(0xF0, 0xF0, 0xF0); break;
593 case eColorID__moz_buttonhovertext:
594 result = NS_RGB(0x00, 0x00, 0x00); break;
595 case eColorID__moz_menuhover:
596 result = NS_RGB(0x33, 0x99, 0xFF); break;
597 case eColorID__moz_menuhovertext:
598 result = NS_RGB(0x00, 0x00, 0x00); break;
599 case eColorID__moz_menubartext:
600 result = NS_RGB(0x00, 0x00, 0x00); break;
601 case eColorID__moz_menubarhovertext:
602 result = NS_RGB(0x00, 0x00, 0x00); break;
603 case eColorID__moz_oddtreerow:
604 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
605 case eColorID__moz_mac_chrome_active:
606 result = NS_RGB(0xB2, 0xB2, 0xB2); break;
607 case eColorID__moz_mac_chrome_inactive:
608 result = NS_RGB(0xE1, 0xE1, 0xE1); break;
609 case eColorID__moz_mac_focusring:
610 result = NS_RGB(0x60, 0x9D, 0xD7); break;
611 case eColorID__moz_mac_menuselect:
612 result = NS_RGB(0x38, 0x75, 0xD7); break;
613 case eColorID__moz_mac_menushadow:
614 result = NS_RGB(0xA3, 0xA3, 0xA3); break;
615 case eColorID__moz_mac_menutextdisable:
616 result = NS_RGB(0x88, 0x88, 0x88); break;
617 case eColorID__moz_mac_menutextselect:
618 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
619 case eColorID__moz_mac_disabledtoolbartext:
620 result = NS_RGB(0x3F, 0x3F, 0x3F); break;
621 case eColorID__moz_mac_secondaryhighlight:
622 result = NS_RGB(0xD4, 0xD4, 0xD4); break;
623 case eColorID__moz_win_mediatext:
624 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
625 case eColorID__moz_win_communicationstext:
626 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
627 case eColorID__moz_nativehyperlinktext:
628 result = NS_RGB(0x00, 0x66, 0xCC); break;
629 case eColorID__moz_comboboxtext:
630 result = NS_RGB(0x00, 0x00, 0x00); break;
631 case eColorID__moz_combobox:
632 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
633 default:
634 break;
635 }
636
637 return result;
638 }
639
640 //
641 // All these routines will return NS_OK if they have a value,
642 // in which case the nsLookAndFeel should use that value;
643 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
644 // platform-specific nsLookAndFeel should use its own values instead.
645 //
646 nsresult
647 nsXPLookAndFeel::GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
648 nscolor &aResult)
649 {
650 if (!sInitialized)
651 Init();
652
653 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
654 // use in a skin that uses them. When set, it will make all system
655 // color pairs that are appropriate for foreground/background
656 // pairing the same. This means if the skin is using system colors
657 // correctly you will not be able to see *any* text.
658 #undef DEBUG_SYSTEM_COLOR_USE
659
660 #ifdef DEBUG_SYSTEM_COLOR_USE
661 {
662 nsresult rv = NS_OK;
663 switch (aID) {
664 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
665 case eColorID_activecaption:
666 // active window caption background
667 case eColorID_captiontext:
668 // text in active window caption
669 aResult = NS_RGB(0xff, 0x00, 0x00);
670 break;
671
672 case eColorID_highlight:
673 // background of selected item
674 case eColorID_highlighttext:
675 // text of selected item
676 aResult = NS_RGB(0xff, 0xff, 0x00);
677 break;
678
679 case eColorID_inactivecaption:
680 // inactive window caption
681 case eColorID_inactivecaptiontext:
682 // text in inactive window caption
683 aResult = NS_RGB(0x66, 0x66, 0x00);
684 break;
685
686 case eColorID_infobackground:
687 // tooltip background color
688 case eColorID_infotext:
689 // tooltip text color
690 aResult = NS_RGB(0x00, 0xff, 0x00);
691 break;
692
693 case eColorID_menu:
694 // menu background
695 case eColorID_menutext:
696 // menu text
697 aResult = NS_RGB(0x00, 0xff, 0xff);
698 break;
699
700 case eColorID_threedface:
701 case eColorID_buttonface:
702 // 3-D face color
703 case eColorID_buttontext:
704 // text on push buttons
705 aResult = NS_RGB(0x00, 0x66, 0x66);
706 break;
707
708 case eColorID_window:
709 case eColorID_windowtext:
710 aResult = NS_RGB(0x00, 0x00, 0xff);
711 break;
712
713 // from the CSS3 working draft (not yet finalized)
714 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
715
716 case eColorID__moz_field:
717 case eColorID__moz_fieldtext:
718 aResult = NS_RGB(0xff, 0x00, 0xff);
719 break;
720
721 case eColorID__moz_dialog:
722 case eColorID__moz_dialogtext:
723 aResult = NS_RGB(0x66, 0x00, 0x66);
724 break;
725
726 default:
727 rv = NS_ERROR_NOT_AVAILABLE;
728 }
729 if (NS_SUCCEEDED(rv))
730 return rv;
731 }
732 #endif // DEBUG_SYSTEM_COLOR_USE
733
734 if (aUseStandinsForNativeColors && ColorIsNotCSSAccessible(aID))
735 aUseStandinsForNativeColors = false;
736
737 if (!aUseStandinsForNativeColors && IS_COLOR_CACHED(aID)) {
738 aResult = sCachedColors[aID];
739 return NS_OK;
740 }
741
742 // There are no system color settings for these, so set them manually
743 if (aID == eColorID_TextSelectBackgroundDisabled) {
744 // This is used to gray out the selection when it's not focused
745 // Used with nsISelectionController::SELECTION_DISABLED
746 aResult = NS_RGB(0xb0, 0xb0, 0xb0);
747 return NS_OK;
748 }
749
750 if (aID == eColorID_TextSelectBackgroundAttention) {
751 // This makes the selection stand out when typeaheadfind is on
752 // Used with nsISelectionController::SELECTION_ATTENTION
753 aResult = NS_RGB(0x38, 0xd8, 0x78);
754 return NS_OK;
755 }
756
757 if (aID == eColorID_TextHighlightBackground) {
758 // This makes the matched text stand out when findbar highlighting is on
759 // Used with nsISelectionController::SELECTION_FIND
760 aResult = NS_RGB(0xef, 0x0f, 0xff);
761 return NS_OK;
762 }
763
764 if (aID == eColorID_TextHighlightForeground) {
765 // The foreground color for the matched text in findbar highlighting
766 // Used with nsISelectionController::SELECTION_FIND
767 aResult = NS_RGB(0xff, 0xff, 0xff);
768 return NS_OK;
769 }
770
771 if (sUseNativeColors && aUseStandinsForNativeColors)
772 {
773 aResult = GetStandinForNativeColor(aID);
774 return NS_OK;
775 }
776
777 if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aResult))) {
778 if ((gfxPlatform::GetCMSMode() == eCMSMode_All) &&
779 !IsSpecialColor(aID, aResult)) {
780 qcms_transform *transform = gfxPlatform::GetCMSInverseRGBTransform();
781 if (transform) {
782 uint8_t color[3];
783 color[0] = NS_GET_R(aResult);
784 color[1] = NS_GET_G(aResult);
785 color[2] = NS_GET_B(aResult);
786 qcms_transform_data(transform, color, color, 1);
787 aResult = NS_RGB(color[0], color[1], color[2]);
788 }
789 }
790
791 CACHE_COLOR(aID, aResult);
792 return NS_OK;
793 }
794
795 return NS_ERROR_NOT_AVAILABLE;
796 }
797
798 nsresult
799 nsXPLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
800 {
801 if (!sInitialized)
802 Init();
803
804 // Set the default values for these prefs. but allow different platforms
805 // to override them in their nsLookAndFeel if desired.
806 switch (aID) {
807 case eIntID_ScrollButtonLeftMouseButtonAction:
808 aResult = 0;
809 return NS_OK;
810 case eIntID_ScrollButtonMiddleMouseButtonAction:
811 aResult = 3;
812 return NS_OK;
813 case eIntID_ScrollButtonRightMouseButtonAction:
814 aResult = 3;
815 return NS_OK;
816 default:
817 /*
818 * The metrics above are hardcoded platform defaults. All the other
819 * metrics are stored in sIntPrefs and can be changed at runtime.
820 */
821 break;
822 }
823
824 for (unsigned int i = 0; i < ArrayLength(sIntPrefs); ++i) {
825 if (sIntPrefs[i].isSet && (sIntPrefs[i].id == aID)) {
826 aResult = sIntPrefs[i].intVar;
827 return NS_OK;
828 }
829 }
830
831 return NS_ERROR_NOT_AVAILABLE;
832 }
833
834 nsresult
835 nsXPLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
836 {
837 if (!sInitialized)
838 Init();
839
840 for (unsigned int i = 0; i < ArrayLength(sFloatPrefs); ++i) {
841 if (sFloatPrefs[i].isSet && sFloatPrefs[i].id == aID) {
842 aResult = sFloatPrefs[i].floatVar;
843 return NS_OK;
844 }
845 }
846
847 return NS_ERROR_NOT_AVAILABLE;
848 }
849
850 void
851 nsXPLookAndFeel::RefreshImpl()
852 {
853 // Wipe out our color cache.
854 uint32_t i;
855 for (i = 0; i < eColorID_LAST_COLOR; i++)
856 sCachedColors[i] = 0;
857 for (i = 0; i < COLOR_CACHE_SIZE; i++)
858 sCachedColorBits[i] = 0;
859 }
860
861 namespace mozilla {
862
863 // static
864 nsresult
865 LookAndFeel::GetColor(ColorID aID, nscolor* aResult)
866 {
867 return nsLookAndFeel::GetInstance()->GetColorImpl(aID, false, *aResult);
868 }
869
870 nsresult
871 LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
872 nscolor* aResult)
873 {
874 return nsLookAndFeel::GetInstance()->GetColorImpl(aID,
875 aUseStandinsForNativeColors, *aResult);
876 }
877
878 // static
879 nsresult
880 LookAndFeel::GetColorForNativeAppearance(uint8_t aWidgetType, bool aIsDisabled,
881 nscolor* aResult)
882 {
883 NS_ENSURE_ARG_POINTER(aResult);
884
885 ColorID colorID = eColorID_LAST_COLOR;
886 switch (aWidgetType) {
887 case NS_THEME_TEXTFIELD:
888 case NS_THEME_TEXTFIELD_MULTILINE:
889 case NS_THEME_LISTBOX:
890 case NS_THEME_DROPDOWN:
891 case NS_THEME_DROPDOWN_TEXTFIELD:
892 case NS_THEME_TREEVIEW:
893 colorID = (aIsDisabled) ? eColorID_graytext : eColorID__moz_fieldtext;
894 break;
895
896 case NS_THEME_TOOLTIP:
897 colorID = eColorID_infotext;
898 break;
899
900 case NS_THEME_BUTTON:
901 case NS_THEME_GROUPBOX:
902 case NS_THEME_PROGRESSBAR:
903 case NS_THEME_PROGRESSBAR_VERTICAL:
904 case NS_THEME_TAB_PANEL:
905 case NS_THEME_STATUSBAR:
906 case NS_THEME_STATUSBAR_RESIZER_PANEL:
907 colorID = (aIsDisabled) ? eColorID_graytext : eColorID_buttontext;
908 break;
909 }
910
911 if (LookAndFeel::eColorID_LAST_COLOR == colorID)
912 return NS_ERROR_FAILURE;
913
914 *aResult = NS_RGB(0, 0, 0);
915 return nsLookAndFeel::GetInstance()->NativeGetColor(colorID, *aResult);
916 }
917
918 // static
919 nsresult
920 LookAndFeel::GetInt(IntID aID, int32_t* aResult)
921 {
922 return nsLookAndFeel::GetInstance()->GetIntImpl(aID, *aResult);
923 }
924
925 // static
926 nsresult
927 LookAndFeel::GetFloat(FloatID aID, float* aResult)
928 {
929 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID, *aResult);
930 }
931
932 // static
933 bool
934 LookAndFeel::GetFont(FontID aID, nsString& aName, gfxFontStyle& aStyle,
935 float aDevPixPerCSSPixel)
936 {
937 return nsLookAndFeel::GetInstance()->GetFontImpl(aID, aName, aStyle,
938 aDevPixPerCSSPixel);
939 }
940
941 // static
942 char16_t
943 LookAndFeel::GetPasswordCharacter()
944 {
945 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
946 }
947
948 // static
949 bool
950 LookAndFeel::GetEchoPassword()
951 {
952 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
953 }
954
955 // static
956 uint32_t
957 LookAndFeel::GetPasswordMaskDelay()
958 {
959 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
960 }
961
962 // static
963 void
964 LookAndFeel::Refresh()
965 {
966 nsLookAndFeel::GetInstance()->RefreshImpl();
967 }
968
969 } // namespace mozilla

mercurial