1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/vr/model/color_scheme.h"
6 
7 #include "base/check_op.h"
8 #include "base/lazy_instance.h"
9 #include "chrome/browser/vr/assets_loader.h"
10 #include "ui/gfx/color_palette.h"
11 
12 namespace vr {
13 
14 namespace {
15 
BuildColor(uint32_t color,int percentage)16 SkColor BuildColor(uint32_t color, int percentage) {
17   DCHECK_GE(percentage, 0);
18   DCHECK_LE(percentage, 100);
19   return (static_cast<uint8_t>((2.55f * percentage + 0.5)) << 24) | color;
20 }
21 
MakeColor(uint32_t color,int percentage)22 SkColor MakeColor(uint32_t color, int percentage) {
23   DCHECK(!(color & 0xFF000000));
24   return BuildColor(color, percentage);
25 }
26 
MakeBlack(int percentage)27 SkColor MakeBlack(int percentage) {
28   return BuildColor(0, percentage);
29 }
30 
MakeWhite(int percentage)31 SkColor MakeWhite(int percentage) {
32   return BuildColor(0xFFFFFF, percentage);
33 }
34 
35 base::LazyInstance<ColorScheme>::Leaky g_normal_scheme =
36     LAZY_INSTANCE_INITIALIZER;
37 base::LazyInstance<ColorScheme>::Leaky g_fullscreen_scheme =
38     LAZY_INSTANCE_INITIALIZER;
39 base::LazyInstance<ColorScheme>::Leaky g_incognito_scheme =
40     LAZY_INSTANCE_INITIALIZER;
41 
InitializeColorSchemes()42 void InitializeColorSchemes() {
43   static bool initialized = false;
44   if (initialized)
45     return;
46 
47   ColorScheme& normal_scheme = g_normal_scheme.Get();
48   normal_scheme.world_background = 0xFF999999;
49   normal_scheme.floor = 0xFF8C8C8C;
50   normal_scheme.ceiling = normal_scheme.floor;
51   normal_scheme.floor_grid = 0x26FFFFFF;
52   normal_scheme.web_vr_background = SK_ColorBLACK;
53   normal_scheme.disc_button_colors.foreground = 0x87000000;
54   normal_scheme.disc_button_colors.foreground_disabled = 0x33333333;
55   normal_scheme.disc_button_colors.background = 0xCCB3B3B3;
56   normal_scheme.disc_button_colors.background_hover = 0xCCE3E3E3;
57   normal_scheme.disc_button_colors.background_down = 0xCCF3F3F3;
58   normal_scheme.web_vr_floor_edge = SK_ColorBLACK;
59   normal_scheme.web_vr_floor_center = 0xD9212121;
60   normal_scheme.web_vr_floor_grid = 0xD9212121;
61   normal_scheme.loading_indicator_foreground = MakeColor(0x4285F4, 100);
62   normal_scheme.loading_indicator_background = MakeColor(0xD1E1FC, 100);
63   normal_scheme.exit_warning_foreground = SK_ColorWHITE;
64   normal_scheme.exit_warning_background = 0xCC1A1A1A;
65   normal_scheme.web_vr_transient_toast_foreground = 0xFFF3F3F3;
66   normal_scheme.web_vr_transient_toast_background = SK_ColorBLACK;
67   normal_scheme.toast_foreground = 0xCCFFFFFF;
68   normal_scheme.toast_background = 0xCC2F2F2F;
69   normal_scheme.modal_prompt_icon_foreground = 0xFF4285F4;
70   normal_scheme.modal_prompt_background = 0xFFF5F5F5;
71   normal_scheme.modal_prompt_foreground = 0xFF333333;
72   normal_scheme.modal_prompt_secondary_button_colors.foreground = 0xFF4285F4;
73   normal_scheme.modal_prompt_secondary_button_colors.foreground_disabled =
74       normal_scheme.disc_button_colors.foreground_disabled;
75   normal_scheme.modal_prompt_secondary_button_colors.background =
76       normal_scheme.modal_prompt_background;
77   normal_scheme.modal_prompt_secondary_button_colors.background_hover =
78       0x19999999;
79   normal_scheme.modal_prompt_secondary_button_colors.background_down =
80       0x33999999;
81   normal_scheme.modal_prompt_primary_button_colors.foreground =
82       normal_scheme.modal_prompt_background;
83   normal_scheme.modal_prompt_secondary_button_colors.foreground_disabled =
84       normal_scheme.disc_button_colors.foreground_disabled;
85   normal_scheme.modal_prompt_primary_button_colors.background = 0xFF4285F4;
86   normal_scheme.modal_prompt_primary_button_colors.background_hover =
87       0xFF3E7DE6;
88   normal_scheme.modal_prompt_primary_button_colors.background_down = 0xFF3E7DE6;
89   normal_scheme.prompt_foreground = 0xCC000000;
90   normal_scheme.prompt_primary_button_colors.foreground = 0xA6000000;
91   normal_scheme.prompt_primary_button_colors.foreground_disabled = 0xA6000000;
92   normal_scheme.prompt_primary_button_colors.background = 0xBFFFFFFF;
93   normal_scheme.prompt_primary_button_colors.background_hover = 0xFFFFFFFF;
94   normal_scheme.prompt_primary_button_colors.background_down = 0xE6FFFFFF;
95   normal_scheme.prompt_secondary_button_colors.foreground = 0xA6000000;
96   normal_scheme.prompt_secondary_button_colors.foreground_disabled = 0xA6000000;
97   normal_scheme.prompt_secondary_button_colors.background = 0x66FFFFFF;
98   normal_scheme.prompt_secondary_button_colors.background_hover = 0xFFFFFFFF;
99   normal_scheme.prompt_secondary_button_colors.background_down = 0xE6FFFFFF;
100 
101   normal_scheme.url_bar_background = 0xCCB3B3B3;
102   normal_scheme.url_bar_separator = MakeBlack(12);
103   normal_scheme.url_bar_text = MakeBlack(65);
104   normal_scheme.url_bar_hint_text = MakeBlack(50);
105   normal_scheme.url_bar_dangerous_icon = gfx::kGoogleRed700;
106   normal_scheme.url_bar_button.background = SK_ColorTRANSPARENT;
107   normal_scheme.url_bar_button.background_hover = MakeBlack(8);
108   normal_scheme.url_bar_button.background_down = MakeBlack(8);
109   normal_scheme.url_bar_button.foreground = MakeBlack(65);
110   normal_scheme.url_bar_button.foreground_disabled = MakeBlack(24);
111   normal_scheme.url_text_emphasized = MakeBlack(80);
112   normal_scheme.url_text_deemphasized = MakeBlack(30);
113   normal_scheme.menu_text = MakeBlack(87);
114   normal_scheme.omnibox_background = 0xFFEEEEEE;
115   normal_scheme.omnibox_text_selection.cursor = 0xFF5595FE;      // TODO
116   normal_scheme.omnibox_text_selection.background = 0xFFC6DAFC;  // TODO
117   normal_scheme.omnibox_text_selection.foreground = normal_scheme.url_bar_text;
118   normal_scheme.hyperlink = MakeColor(0x4285F4, 100);
119 
120   normal_scheme.dimmer_inner = 0xCC0D0D0D;
121   normal_scheme.dimmer_outer = 0xE6000000;
122   normal_scheme.splash_screen_background = SK_ColorBLACK;
123   normal_scheme.splash_screen_text_color = 0xA6FFFFFF;
124   normal_scheme.web_vr_timeout_spinner = 0xFFF3F3F3;
125   normal_scheme.web_vr_timeout_message_background = 0xFF444444;
126   normal_scheme.web_vr_timeout_message_foreground =
127       normal_scheme.web_vr_timeout_spinner;
128   normal_scheme.speech_recognition_circle_background = 0xFF4285F4;
129   normal_scheme.snackbar_foreground = 0xFFEEEEEE;
130   normal_scheme.snackbar_background = 0xDD212121;
131   normal_scheme.snackbar_button_colors.background =
132       normal_scheme.snackbar_background;
133   normal_scheme.snackbar_button_colors.foreground = 0xFFFFD500;
134   normal_scheme.snackbar_button_colors.background_hover = 0xDD2D2D2D;
135   normal_scheme.snackbar_button_colors.background_down = 0xDD2D2D2D;
136 
137   normal_scheme.controller_label_callout = SK_ColorWHITE;
138   normal_scheme.controller_button = 0xFFEFEFEF;
139   normal_scheme.controller_button_down = 0xFF2979FF;
140   normal_scheme.controller_battery_full = 0xFFEFEFEF;
141   normal_scheme.controller_battery_empty = 0xCCB3B3B3;
142 
143   normal_scheme.reposition_label = SK_ColorWHITE;
144   normal_scheme.reposition_label_background = 0xAA333333;
145 
146   normal_scheme.normal_factor = 1.0f;
147   normal_scheme.incognito_factor = 0.0f;
148   normal_scheme.fullscreen_factor = 0.0f;
149 
150   normal_scheme.content_reposition_frame = 0x66FFFFFF;
151 
152   normal_scheme.cursor_background_center = 0x66000000;
153   normal_scheme.cursor_background_edge = SK_ColorTRANSPARENT;
154   normal_scheme.cursor_foreground = SK_ColorWHITE;
155 
156   normal_scheme.webvr_permission_background = 0xD9212121;
157   normal_scheme.webvr_permission_foreground = SK_ColorWHITE;
158 
159   normal_scheme.indicator.background = 0x73212121;
160   normal_scheme.indicator.background_hover = 0xDE212121;
161   normal_scheme.indicator.background_down = 0xDE212121;
162   normal_scheme.indicator.foreground = SK_ColorWHITE;
163   normal_scheme.indicator.foreground_disabled = SK_ColorWHITE;
164 
165   g_fullscreen_scheme.Get() = normal_scheme;
166   ColorScheme& fullscreen_scheme = g_fullscreen_scheme.Get();
167   fullscreen_scheme.world_background = 0xFF000714;
168   fullscreen_scheme.floor = 0xFF070F1C;
169   fullscreen_scheme.ceiling = 0xFF04080F;
170   fullscreen_scheme.floor_grid = 0x40A3E0FF;
171 
172   fullscreen_scheme.disc_button_colors.foreground = 0x80FFFFFF;
173   fullscreen_scheme.disc_button_colors.foreground_disabled = 0x80FFFFFF;
174   fullscreen_scheme.disc_button_colors.background = 0xCC2B3E48;
175   fullscreen_scheme.disc_button_colors.background_hover = 0xCC536B77;
176   fullscreen_scheme.disc_button_colors.background_down = 0xCC96AFBB;
177 
178   fullscreen_scheme.normal_factor = 0.0f;
179   fullscreen_scheme.incognito_factor = 0.0f;
180   fullscreen_scheme.fullscreen_factor = 1.0f;
181 
182   g_incognito_scheme.Get() = normal_scheme;
183   ColorScheme& incognito_scheme = g_incognito_scheme.Get();
184   incognito_scheme.world_background = 0xFF2E2E2E;
185   incognito_scheme.floor = 0xFF282828;
186   incognito_scheme.ceiling = 0xFF2F2F2F;
187   incognito_scheme.floor_grid = 0xCC595959;
188 
189   incognito_scheme.disc_button_colors.foreground = 0x80FFFFFF;
190   incognito_scheme.disc_button_colors.foreground_disabled = 0x33E6E6E6;
191   incognito_scheme.disc_button_colors.background = 0xCC2B3E48;
192   incognito_scheme.disc_button_colors.background_hover = 0xCC505050;
193   incognito_scheme.disc_button_colors.background_down = 0xCC888888;
194 
195   incognito_scheme.prompt_foreground = 0xCCFFFFFF;
196   incognito_scheme.prompt_primary_button_colors.foreground = 0xD9000000;
197   incognito_scheme.prompt_primary_button_colors.foreground_disabled =
198       0xD9000000;
199   incognito_scheme.prompt_primary_button_colors.background = 0xD9FFFFFF;
200   incognito_scheme.prompt_primary_button_colors.background_hover = 0xFF8C8C8C;
201   incognito_scheme.prompt_primary_button_colors.background_down = 0xE6FFFFFF;
202   incognito_scheme.prompt_secondary_button_colors.foreground = 0xD9000000;
203   incognito_scheme.prompt_secondary_button_colors.foreground_disabled =
204       0xD9000000;
205   incognito_scheme.prompt_secondary_button_colors.background = 0x80FFFFFF;
206   incognito_scheme.prompt_secondary_button_colors.background_hover = 0xFF8C8C8C;
207   incognito_scheme.prompt_secondary_button_colors.background_down = 0xE6FFFFFF;
208 
209   incognito_scheme.url_bar_background = 0xFF454545;
210   incognito_scheme.url_bar_separator = MakeWhite(12);
211   incognito_scheme.url_bar_text = MakeWhite(65);
212   incognito_scheme.url_bar_hint_text = MakeWhite(50);
213   incognito_scheme.url_bar_dangerous_icon = SK_ColorWHITE;
214   incognito_scheme.url_bar_button.background_hover = MakeWhite(8);
215   incognito_scheme.url_bar_button.background_down = MakeWhite(8);
216   incognito_scheme.url_bar_button.foreground = MakeWhite(65);
217   incognito_scheme.url_bar_button.foreground_disabled = MakeWhite(24);
218   incognito_scheme.url_text_emphasized = MakeWhite(80);
219   incognito_scheme.url_text_deemphasized = MakeWhite(30);
220   incognito_scheme.menu_text = MakeWhite(87);
221   incognito_scheme.omnibox_background = incognito_scheme.url_bar_background;
222   incognito_scheme.omnibox_text_selection.foreground =
223       incognito_scheme.url_bar_text;
224   incognito_scheme.omnibox_text_selection.background = MakeWhite(8);
225 
226   incognito_scheme.normal_factor = 0.0f;
227   incognito_scheme.incognito_factor = 1.0f;
228   incognito_scheme.fullscreen_factor = 0.0f;
229 
230   initialized = true;
231 }
232 
233 static constexpr size_t kButtonColorsSize = 20;
234 
235 }  // namespace
236 
237 ColorScheme::ColorScheme() = default;
ColorScheme(const ColorScheme & other)238 ColorScheme::ColorScheme(const ColorScheme& other) {
239   *this = other;
240 }
241 
242 static_assert(kButtonColorsSize == sizeof(ButtonColors),
243               "If the new colors are added to ButtonColors, we must explicitly "
244               "bump this size and update operator== below");
245 
operator ==(const ButtonColors & other) const246 bool ButtonColors::operator==(const ButtonColors& other) const {
247   return background == other.background &&
248          background_hover == other.background_hover &&
249          background_down == other.background_down &&
250          foreground == other.foreground &&
251          foreground_disabled == other.foreground_disabled;
252 }
253 
operator !=(const ButtonColors & other) const254 bool ButtonColors::operator!=(const ButtonColors& other) const {
255   return !(*this == other);
256 }
257 
GetBackgroundColor(bool hovered,bool pressed) const258 SkColor ButtonColors::GetBackgroundColor(bool hovered, bool pressed) const {
259   if (pressed)
260     return background_down;
261   if (hovered)
262     return background_hover;
263   return background;
264 }
265 
GetForegroundColor(bool disabled) const266 SkColor ButtonColors::GetForegroundColor(bool disabled) const {
267   return disabled ? foreground_disabled : foreground;
268 }
269 
operator ==(const TextSelectionColors & other) const270 bool TextSelectionColors::operator==(const TextSelectionColors& other) const {
271   return cursor == other.cursor && background == other.background &&
272          foreground == other.foreground;
273 }
274 
operator !=(const TextSelectionColors & other) const275 bool TextSelectionColors::operator!=(const TextSelectionColors& other) const {
276   return !(*this == other);
277 }
278 
GetColorScheme(ColorScheme::Mode mode)279 const ColorScheme& ColorScheme::GetColorScheme(ColorScheme::Mode mode) {
280   InitializeColorSchemes();
281   if (mode == kModeIncognito)
282     return g_incognito_scheme.Get();
283   if (mode == kModeFullscreen)
284     return g_fullscreen_scheme.Get();
285   return g_normal_scheme.Get();
286 }
287 
UpdateForComponent(const base::Version & component_version)288 void ColorScheme::UpdateForComponent(const base::Version& component_version) {
289   if (component_version >= AssetsLoader::MinVersionWithGradients()) {
290     ColorScheme& normal_scheme = g_normal_scheme.Get();
291     normal_scheme.disc_button_colors.foreground = 0xA6000000;
292     normal_scheme.disc_button_colors.foreground_disabled = 0x33000000;
293     normal_scheme.disc_button_colors.background = 0xFFEEEEEE;
294     normal_scheme.disc_button_colors.background_hover = SK_ColorWHITE;
295     normal_scheme.modal_prompt_secondary_button_colors.foreground_disabled =
296         normal_scheme.disc_button_colors.foreground_disabled;
297     normal_scheme.modal_prompt_secondary_button_colors.background =
298         normal_scheme.modal_prompt_background;
299     normal_scheme.url_bar_background = MakeColor(0xEEEEEE, 87);
300     normal_scheme.omnibox_background = MakeColor(0xEEEEEE, 100);
301 
302     ColorScheme& incognito_scheme = g_incognito_scheme.Get();
303     incognito_scheme.disc_button_colors.background = MakeColor(0x263238, 100);
304     incognito_scheme.disc_button_colors.background_hover = 0xCC404A50;
305     incognito_scheme.disc_button_colors.background_down = 0xCC212B31;
306     incognito_scheme.url_bar_background = MakeColor(0x263238, 87);
307     incognito_scheme.omnibox_background = MakeColor(0x263238, 100);
308   }
309 }
310 
311 }  // namespace vr
312