|
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 |