Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: chrome/browser/android/vr_shell/ui_scene.cc

Issue 2706343005: Allow individual UI element properties to be modified. (Closed)
Patch Set: Use a safer cast on integer conversions. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/android/vr_shell/ui_scene_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/vr_shell/ui_scene.h" 5 #include "chrome/browser/android/vr_shell/ui_scene.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "chrome/browser/android/vr_shell/animation.h" 11 #include "chrome/browser/android/vr_shell/animation.h"
12 #include "chrome/browser/android/vr_shell/easing.h" 12 #include "chrome/browser/android/vr_shell/easing.h"
13 #include "chrome/browser/android/vr_shell/ui_elements.h" 13 #include "chrome/browser/android/vr_shell/ui_elements.h"
14 14
15 namespace vr_shell { 15 namespace vr_shell {
16 16
17 namespace { 17 namespace {
18 18
19 // Parse an integer to an int or enum value.
20 template <typename T>
21 bool ParseInt(const base::DictionaryValue& dict,
22 const std::string& key,
23 T* output) {
24 int value;
25 if (!dict.GetInteger(key, &value)) {
26 return false;
27 }
28 *output = static_cast<T>(value);
29 return true;
30 }
31
32 // Parse a floating point number to a float or double.
33 template <typename T>
19 bool ParseFloat(const base::DictionaryValue& dict, 34 bool ParseFloat(const base::DictionaryValue& dict,
20 const std::string& key, 35 const std::string& key,
21 float* output) { 36 T* output) {
22 double value; 37 double value;
23 if (!dict.GetDouble(key, &value)) { 38 if (!dict.GetDouble(key, &value)) {
24 return false; 39 return false;
25 } 40 }
26 *output = value; 41 *output = value;
27 return true; 42 return true;
28 } 43 }
29 44
30 bool ParseRecti(const base::DictionaryValue& dict,
31 const std::string& key,
32 Recti* output) {
33 const base::DictionaryValue* item_dict;
34 if (dict.GetDictionary(key, &item_dict)) {
35 CHECK(item_dict->GetInteger("x", &output->x));
36 CHECK(item_dict->GetInteger("y", &output->y));
37 CHECK(item_dict->GetInteger("width", &output->width));
38 CHECK(item_dict->GetInteger("height", &output->height));
39 return true;
40 } else {
41 return false;
42 }
43 }
44
45 bool Parse2DVec3f(const base::DictionaryValue& dict,
46 const std::string& key,
47 gvr::Vec3f* output) {
48 const base::DictionaryValue* item_dict;
49 if (dict.GetDictionary(key, &item_dict)) {
50 double value;
51 CHECK(item_dict->GetDouble("x", &value));
52 output->x = value;
53 CHECK(item_dict->GetDouble("y", &value));
54 output->y = value;
55 output->z = 1.0f;
56 return true;
57 } else {
58 return false;
59 }
60 }
61
62 bool ParseVec3f(const base::DictionaryValue& dict,
63 const std::string& key,
64 gvr::Vec3f* output) {
65 const base::DictionaryValue* item_dict;
66 if (dict.GetDictionary(key, &item_dict)) {
67 double value;
68 CHECK(item_dict->GetDouble("x", &value));
69 output->x = value;
70 CHECK(item_dict->GetDouble("y", &value));
71 output->y = value;
72 CHECK(item_dict->GetDouble("z", &value));
73 output->z = value;
74 return true;
75 } else {
76 return false;
77 }
78 }
79
80 bool ParseColorf(const base::DictionaryValue& dict, 45 bool ParseColorf(const base::DictionaryValue& dict,
81 const std::string& key, 46 const std::string& key,
82 Colorf* output) { 47 Colorf* output) {
83 const base::DictionaryValue* item_dict; 48 const base::DictionaryValue* item_dict;
84 if (dict.GetDictionary(key, &item_dict)) { 49 if (dict.GetDictionary(key, &item_dict)) {
85 double value; 50 double value;
86 CHECK(item_dict->GetDouble("r", &value)); 51 CHECK(item_dict->GetDouble("r", &value));
87 output->r = value; 52 output->r = value;
88 CHECK(item_dict->GetDouble("g", &value)); 53 CHECK(item_dict->GetDouble("g", &value));
89 output->g = value; 54 output->g = value;
90 CHECK(item_dict->GetDouble("b", &value)); 55 CHECK(item_dict->GetDouble("b", &value));
91 output->b = value; 56 output->b = value;
92 CHECK(item_dict->GetDouble("a", &value)); 57 CHECK(item_dict->GetDouble("a", &value));
93 output->a = value; 58 output->a = value;
94 return true; 59 return true;
95 } else { 60 } else {
96 return false; 61 return false;
97 } 62 }
98 } 63 }
99 64
100 bool ParseRotationAxisAngle(const base::DictionaryValue& dict,
101 const std::string& key,
102 RotationAxisAngle* output) {
103 const base::DictionaryValue* item_dict;
104 if (dict.GetDictionary(key, &item_dict)) {
105 double value;
106 CHECK(item_dict->GetDouble("x", &value));
107 output->x = value;
108 CHECK(item_dict->GetDouble("y", &value));
109 output->y = value;
110 CHECK(item_dict->GetDouble("z", &value));
111 output->z = value;
112 CHECK(item_dict->GetDouble("a", &value));
113 output->angle = value;
114 return true;
115 } else {
116 return false;
117 }
118 }
119
120 void ParseFloats(const base::DictionaryValue& dict, 65 void ParseFloats(const base::DictionaryValue& dict,
121 const std::vector<std::string>& keys, 66 const std::vector<std::string>& keys,
122 std::vector<float>* vec) { 67 std::vector<float>* vec) {
123 for (const auto& key : keys) { 68 for (const auto& key : keys) {
124 double value; 69 double value;
125 CHECK(dict.GetDouble(key, &value)) << "parsing tag " << key; 70 CHECK(dict.GetDouble(key, &value)) << "parsing tag " << key;
126 vec->push_back(value); 71 vec->push_back(value);
127 } 72 }
128 } 73 }
129 74
(...skipping 18 matching lines...) Expand all
148 return true; 93 return true;
149 case Animation::Property::OPACITY: 94 case Animation::Property::OPACITY:
150 ParseFloats(dict, {"x"}, vec); 95 ParseFloats(dict, {"x"}, vec);
151 return true; 96 return true;
152 } 97 }
153 return false; 98 return false;
154 } 99 }
155 100
156 std::unique_ptr<easing::Easing> ParseEasing(const base::DictionaryValue& dict) { 101 std::unique_ptr<easing::Easing> ParseEasing(const base::DictionaryValue& dict) {
157 easing::EasingType easingType; 102 easing::EasingType easingType;
158 CHECK(dict.GetInteger("type", reinterpret_cast<int*>(&easingType))); 103 CHECK(ParseInt(dict, "type", &easingType));
159 std::unique_ptr<easing::Easing> result; 104 std::unique_ptr<easing::Easing> result;
160 105
161 switch (easingType) { 106 switch (easingType) {
162 case easing::EasingType::LINEAR: { 107 case easing::EasingType::LINEAR: {
163 result.reset(new easing::Linear()); 108 result.reset(new easing::Linear());
164 break; 109 break;
165 } 110 }
166 case easing::EasingType::CUBICBEZIER: { 111 case easing::EasingType::CUBICBEZIER: {
167 double p1x, p1y, p2x, p2y; 112 double p1x, p1y, p2x, p2y;
168 CHECK(dict.GetDouble("p1x", &p1x)); 113 CHECK(dict.GetDouble("p1x", &p1x));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 CHECK_NE(GetUiElementById(element->parent_id), nullptr); 174 CHECK_NE(GetUiElementById(element->parent_id), nullptr);
230 } else { 175 } else {
231 CHECK_EQ(element->x_anchoring, XAnchoring::XNONE); 176 CHECK_EQ(element->x_anchoring, XAnchoring::XNONE);
232 CHECK_EQ(element->y_anchoring, YAnchoring::YNONE); 177 CHECK_EQ(element->y_anchoring, YAnchoring::YNONE);
233 } 178 }
234 ui_elements_.push_back(std::move(element)); 179 ui_elements_.push_back(std::move(element));
235 } 180 }
236 181
237 void UiScene::AddUiElementFromDict(const base::DictionaryValue& dict) { 182 void UiScene::AddUiElementFromDict(const base::DictionaryValue& dict) {
238 int id; 183 int id;
239 CHECK(dict.GetInteger("id", &id)); 184 CHECK(ParseInt(dict, "id", &id));
240 CHECK_EQ(GetUiElementById(id), nullptr); 185 CHECK_EQ(GetUiElementById(id), nullptr);
241 186
242 std::unique_ptr<ContentRectangle> element(new ContentRectangle); 187 std::unique_ptr<ContentRectangle> element(new ContentRectangle);
243 element->id = id; 188 element->id = id;
244 189
245 ApplyDictToElement(dict, element.get()); 190 ApplyDictToElement(dict, element.get());
246 ui_elements_.push_back(std::move(element)); 191 ui_elements_.push_back(std::move(element));
247 } 192 }
248 193
249 void UiScene::UpdateUiElementFromDict(const base::DictionaryValue& dict) { 194 void UiScene::UpdateUiElementFromDict(const base::DictionaryValue& dict) {
250 int id; 195 int id;
251 CHECK(dict.GetInteger("id", &id)); 196 CHECK(ParseInt(dict, "id", &id));
252 ContentRectangle* element = GetUiElementById(id); 197 ContentRectangle* element = GetUiElementById(id);
253 CHECK_NE(element, nullptr); 198 CHECK_NE(element, nullptr);
254 ApplyDictToElement(dict, element); 199 ApplyDictToElement(dict, element);
255 } 200 }
256 201
257 void UiScene::RemoveUiElement(int element_id) { 202 void UiScene::RemoveUiElement(int element_id) {
258 for (auto it = ui_elements_.begin(); it != ui_elements_.end(); ++it) { 203 for (auto it = ui_elements_.begin(); it != ui_elements_.end(); ++it) {
259 if ((*it)->id == element_id) { 204 if ((*it)->id == element_id) {
260 if ((*it)->fill == Fill::CONTENT) { 205 if ((*it)->fill == Fill::CONTENT) {
261 content_element_ = nullptr; 206 content_element_ = nullptr;
(...skipping 21 matching lines...) Expand all
283 Animation::Property property; 228 Animation::Property property;
284 double start_time_ms; 229 double start_time_ms;
285 double duration_ms; 230 double duration_ms;
286 231
287 const base::DictionaryValue* easing_dict = nullptr; 232 const base::DictionaryValue* easing_dict = nullptr;
288 const base::DictionaryValue* from_dict = nullptr; 233 const base::DictionaryValue* from_dict = nullptr;
289 const base::DictionaryValue* to_dict = nullptr; 234 const base::DictionaryValue* to_dict = nullptr;
290 std::vector<float> from; 235 std::vector<float> from;
291 std::vector<float> to; 236 std::vector<float> to;
292 237
293 CHECK(dict.GetInteger("id", &animation_id)); 238 CHECK(ParseInt(dict, "id", &animation_id));
294 CHECK(dict.GetInteger("meshId", &element_id)); 239 CHECK(ParseInt(dict, "meshId", &element_id));
295 CHECK(dict.GetInteger("property", reinterpret_cast<int*>(&property))); 240 CHECK(ParseInt(dict, "property", &property));
296 CHECK(dict.GetDouble("startInMillis", &start_time_ms)); 241 CHECK(ParseFloat(dict, "startInMillis", &start_time_ms));
297 CHECK(dict.GetDouble("durationMillis", &duration_ms)); 242 CHECK(ParseFloat(dict, "durationMillis", &duration_ms));
298 243
299 CHECK(dict.GetDictionary("easing", &easing_dict)); 244 CHECK(dict.GetDictionary("easing", &easing_dict));
300 auto easing = ParseEasing(*easing_dict); 245 auto easing = ParseEasing(*easing_dict);
301 246
302 CHECK(dict.GetDictionary("to", &to_dict)); 247 CHECK(dict.GetDictionary("to", &to_dict));
303 ParseEndpointToFloats(property, *to_dict, &to); 248 ParseEndpointToFloats(property, *to_dict, &to);
304 249
305 // The start location is optional. If not specified, the animation will 250 // The start location is optional. If not specified, the animation will
306 // start from the element's current location. 251 // start from the element's current location.
307 dict.GetDictionary("from", &from_dict); 252 dict.GetDictionary("from", &from_dict);
(...skipping 30 matching lines...) Expand all
338 } 283 }
339 284
340 void UiScene::HandleCommands(std::unique_ptr<base::ListValue> commands, 285 void UiScene::HandleCommands(std::unique_ptr<base::ListValue> commands,
341 int64_t time_in_micro) { 286 int64_t time_in_micro) {
342 for (auto& item : *commands) { 287 for (auto& item : *commands) {
343 base::DictionaryValue* dict; 288 base::DictionaryValue* dict;
344 CHECK(item->GetAsDictionary(&dict)); 289 CHECK(item->GetAsDictionary(&dict));
345 290
346 Command type; 291 Command type;
347 base::DictionaryValue* data; 292 base::DictionaryValue* data;
348 CHECK(dict->GetInteger("type", reinterpret_cast<int*>(&type))); 293 CHECK(ParseInt(*dict, "type", &type));
349 CHECK(dict->GetDictionary("data", &data)); 294 CHECK(dict->GetDictionary("data", &data));
350 295
351 switch (type) { 296 switch (type) {
352 case Command::ADD_ELEMENT: 297 case Command::ADD_ELEMENT:
353 AddUiElementFromDict(*data); 298 AddUiElementFromDict(*data);
354 break; 299 break;
355 case Command::UPDATE_ELEMENT: 300 case Command::UPDATE_ELEMENT:
356 UpdateUiElementFromDict(*data); 301 UpdateUiElementFromDict(*data);
357 break; 302 break;
358 case Command::REMOVE_ELEMENT: { 303 case Command::REMOVE_ELEMENT: {
359 int element_id; 304 int element_id;
360 CHECK(data->GetInteger("id", &element_id)); 305 CHECK(ParseInt(*data, "id", &element_id));
361 RemoveUiElement(element_id); 306 RemoveUiElement(element_id);
362 break; 307 break;
363 } 308 }
364 case Command::ADD_ANIMATION: 309 case Command::ADD_ANIMATION:
365 AddAnimationFromDict(*data, time_in_micro); 310 AddAnimationFromDict(*data, time_in_micro);
366 break; 311 break;
367 case Command::REMOVE_ANIMATION: { 312 case Command::REMOVE_ANIMATION: {
368 int element_id, animation_id; 313 int element_id, animation_id;
369 CHECK(data->GetInteger("id", &animation_id)); 314 CHECK(ParseInt(*data, "id", &animation_id));
370 CHECK(data->GetInteger("meshId", &element_id)); 315 CHECK(ParseInt(*data, "meshId", &element_id));
371 RemoveAnimation(element_id, animation_id); 316 RemoveAnimation(element_id, animation_id);
372 break; 317 break;
373 } 318 }
374 case Command::UPDATE_BACKGROUND: 319 case Command::UPDATE_BACKGROUND:
375 UpdateBackgroundFromDict(*data); 320 UpdateBackgroundFromDict(*data);
376 break; 321 break;
377 } 322 }
378 } 323 }
379 } 324 }
380 325
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 CHECK(parent != nullptr); 379 CHECK(parent != nullptr);
435 ApplyAnchoring(*parent, element.x_anchoring, element.y_anchoring, 380 ApplyAnchoring(*parent, element.x_anchoring, element.y_anchoring,
436 transform); 381 transform);
437 ApplyRecursiveTransforms(*parent, transform, opacity); 382 ApplyRecursiveTransforms(*parent, transform, opacity);
438 } 383 }
439 } 384 }
440 385
441 void UiScene::ApplyDictToElement(const base::DictionaryValue& dict, 386 void UiScene::ApplyDictToElement(const base::DictionaryValue& dict,
442 ContentRectangle* element) { 387 ContentRectangle* element) {
443 int parent_id; 388 int parent_id;
444 if (dict.GetInteger("parentId", &parent_id)) { 389
390 if (ParseInt(dict, "parentId", &parent_id)) {
445 CHECK_GE(parent_id, 0); 391 CHECK_GE(parent_id, 0);
446 CHECK_NE(GetUiElementById(parent_id), nullptr); 392 CHECK_NE(GetUiElementById(parent_id), nullptr);
447 element->parent_id = parent_id; 393 element->parent_id = parent_id;
448 } 394 }
449 395
450 dict.GetBoolean("visible", &element->visible); 396 dict.GetBoolean("visible", &element->visible);
451 dict.GetBoolean("hitTestable", &element->hit_testable); 397 dict.GetBoolean("hitTestable", &element->hit_testable);
452 dict.GetBoolean("lockToFov", &element->lock_to_fov); 398 dict.GetBoolean("lockToFov", &element->lock_to_fov);
453 Parse2DVec3f(dict, "size", &element->size); 399 ParseInt(dict, "drawPhase", &element->draw_phase);
454 ParseVec3f(dict, "scale", &element->scale); 400 ParseFloat(dict, "opacity", &element->opacity);
455 ParseRotationAxisAngle(dict, "rotation", &element->rotation);
456 ParseVec3f(dict, "translation", &element->translation);
457 double opacity;
458 if (dict.GetDouble("opacity", &opacity)) {
459 element->opacity = opacity;
460 }
461 dict.GetInteger("drawPhase", &element->draw_phase);
462 401
463 if (dict.GetInteger("xAnchoring", 402 ParseFloat(dict, "sizeX", &element->size.x);
464 reinterpret_cast<int*>(&element->x_anchoring))) { 403 ParseFloat(dict, "sizeY", &element->size.y);
404 ParseFloat(dict, "scaleX", &element->scale.x);
405 ParseFloat(dict, "scaleY", &element->scale.y);
406 ParseFloat(dict, "scaleZ", &element->scale.z);
407 ParseFloat(dict, "rotationX", &element->rotation.x);
408 ParseFloat(dict, "rotationY", &element->rotation.y);
409 ParseFloat(dict, "rotationZ", &element->rotation.z);
410 ParseFloat(dict, "rotationAngle", &element->rotation.angle);
411 ParseFloat(dict, "translationX", &element->translation.x);
412 ParseFloat(dict, "translationY", &element->translation.y);
413 ParseFloat(dict, "translationZ", &element->translation.z);
414
415 if (ParseInt(dict, "xAnchoring", &element->x_anchoring)) {
465 CHECK_GE(element->parent_id, 0); 416 CHECK_GE(element->parent_id, 0);
466 } 417 }
467 if (dict.GetInteger("yAnchoring", 418 if (ParseInt(dict, "yAnchoring", &element->y_anchoring)) {
468 reinterpret_cast<int*>(&element->y_anchoring))) {
469 CHECK_GE(element->parent_id, 0); 419 CHECK_GE(element->parent_id, 0);
470 } 420 }
471 421
472 // Parse the element fill. 422 // Parse the element fill.
473 if (dict.GetInteger("fillType", reinterpret_cast<int*>(&element->fill))) { 423 if (ParseInt(dict, "fillType", &element->fill)) {
474 // If the previous content element has a new filling now make sure this is 424 // If the previous content element has a new filling now make sure this is
475 // tracked correctly. 425 // tracked correctly.
476 if (content_element_ == element && element->fill != Fill::CONTENT) { 426 if (content_element_ == element && element->fill != Fill::CONTENT) {
477 content_element_ = nullptr; 427 content_element_ = nullptr;
478 } 428 }
479 429
480 switch (element->fill) { 430 switch (element->fill) {
481 case Fill::SPRITE: 431 case Fill::SPRITE:
482 CHECK(ParseRecti(dict, "copyRect", &element->copy_rect)); 432 CHECK(ParseInt(dict, "copyRectX", &element->copy_rect.x));
433 CHECK(ParseInt(dict, "copyRectY", &element->copy_rect.y));
434 CHECK(ParseInt(dict, "copyRectWidth", &element->copy_rect.width));
435 CHECK(ParseInt(dict, "copyRectHeight", &element->copy_rect.height));
483 break; 436 break;
484 case Fill::OPAQUE_GRADIENT: 437 case Fill::OPAQUE_GRADIENT:
485 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color)); 438 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color));
486 CHECK(ParseColorf(dict, "centerColor", &element->center_color)); 439 CHECK(ParseColorf(dict, "centerColor", &element->center_color));
487 break; 440 break;
488 case Fill::GRID_GRADIENT: 441 case Fill::GRID_GRADIENT:
489 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color)); 442 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color));
490 CHECK(ParseColorf(dict, "centerColor", &element->center_color)); 443 CHECK(ParseColorf(dict, "centerColor", &element->center_color));
491 CHECK(dict.GetInteger("gridlineCount", &element->gridline_count)); 444 CHECK(ParseInt(dict, "gridlineCount", &element->gridline_count));
492 CHECK_GE(element->gridline_count, 0); 445 CHECK_GE(element->gridline_count, 0);
493 break; 446 break;
494 case Fill::CONTENT: 447 case Fill::CONTENT:
495 CHECK_EQ(content_element_, nullptr); 448 CHECK_EQ(content_element_, nullptr);
496 content_element_ = element; 449 content_element_ = element;
497 break; 450 break;
498 default: 451 default:
499 element->fill = Fill::NONE; 452 element->fill = Fill::NONE;
500 break; 453 break;
501 } 454 }
502 } 455 }
503 } 456 }
504 457
505 } // namespace vr_shell 458 } // namespace vr_shell
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/android/vr_shell/ui_scene_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698