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

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: Tweaks. 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,
tiborg 2017/02/23 15:21:18 +1 for the templates!
cjgrant 2017/02/23 16:13:37 Acknowledged.
22 const std::string& key,
23 T* output) {
24 return dict.GetInteger(key, reinterpret_cast<int*>(output));
tiborg 2017/02/23 15:21:18 Is this safe when you use a different type than in
cjgrant 2017/02/23 16:13:37 Done. It was not, but it is now.
25 }
26
27 // Parse a floating point number to a float or double.
28 template <typename T>
19 bool ParseFloat(const base::DictionaryValue& dict, 29 bool ParseFloat(const base::DictionaryValue& dict,
20 const std::string& key, 30 const std::string& key,
21 float* output) { 31 T* output) {
22 double value; 32 double value;
23 if (!dict.GetDouble(key, &value)) { 33 if (!dict.GetDouble(key, &value)) {
24 return false; 34 return false;
25 } 35 }
26 *output = value; 36 *output = value;
27 return true; 37 return true;
28 } 38 }
29 39
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, 40 bool ParseColorf(const base::DictionaryValue& dict,
81 const std::string& key, 41 const std::string& key,
82 Colorf* output) { 42 Colorf* output) {
83 const base::DictionaryValue* item_dict; 43 const base::DictionaryValue* item_dict;
84 if (dict.GetDictionary(key, &item_dict)) { 44 if (dict.GetDictionary(key, &item_dict)) {
85 double value; 45 double value;
86 CHECK(item_dict->GetDouble("r", &value)); 46 CHECK(item_dict->GetDouble("r", &value));
87 output->r = value; 47 output->r = value;
88 CHECK(item_dict->GetDouble("g", &value)); 48 CHECK(item_dict->GetDouble("g", &value));
89 output->g = value; 49 output->g = value;
90 CHECK(item_dict->GetDouble("b", &value)); 50 CHECK(item_dict->GetDouble("b", &value));
91 output->b = value; 51 output->b = value;
92 CHECK(item_dict->GetDouble("a", &value)); 52 CHECK(item_dict->GetDouble("a", &value));
93 output->a = value; 53 output->a = value;
94 return true; 54 return true;
95 } else { 55 } else {
96 return false; 56 return false;
97 } 57 }
98 } 58 }
99 59
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, 60 void ParseFloats(const base::DictionaryValue& dict,
121 const std::vector<std::string>& keys, 61 const std::vector<std::string>& keys,
122 std::vector<float>* vec) { 62 std::vector<float>* vec) {
123 for (const auto& key : keys) { 63 for (const auto& key : keys) {
124 double value; 64 double value;
125 CHECK(dict.GetDouble(key, &value)) << "parsing tag " << key; 65 CHECK(dict.GetDouble(key, &value)) << "parsing tag " << key;
126 vec->push_back(value); 66 vec->push_back(value);
127 } 67 }
128 } 68 }
129 69
(...skipping 18 matching lines...) Expand all
148 return true; 88 return true;
149 case Animation::Property::OPACITY: 89 case Animation::Property::OPACITY:
150 ParseFloats(dict, {"x"}, vec); 90 ParseFloats(dict, {"x"}, vec);
151 return true; 91 return true;
152 } 92 }
153 return false; 93 return false;
154 } 94 }
155 95
156 std::unique_ptr<easing::Easing> ParseEasing(const base::DictionaryValue& dict) { 96 std::unique_ptr<easing::Easing> ParseEasing(const base::DictionaryValue& dict) {
157 easing::EasingType easingType; 97 easing::EasingType easingType;
158 CHECK(dict.GetInteger("type", reinterpret_cast<int*>(&easingType))); 98 CHECK(ParseInt(dict, "type", &easingType));
159 std::unique_ptr<easing::Easing> result; 99 std::unique_ptr<easing::Easing> result;
160 100
161 switch (easingType) { 101 switch (easingType) {
162 case easing::EasingType::LINEAR: { 102 case easing::EasingType::LINEAR: {
163 result.reset(new easing::Linear()); 103 result.reset(new easing::Linear());
164 break; 104 break;
165 } 105 }
166 case easing::EasingType::CUBICBEZIER: { 106 case easing::EasingType::CUBICBEZIER: {
167 double p1x, p1y, p2x, p2y; 107 double p1x, p1y, p2x, p2y;
168 CHECK(dict.GetDouble("p1x", &p1x)); 108 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); 169 CHECK_NE(GetUiElementById(element->parent_id), nullptr);
230 } else { 170 } else {
231 CHECK_EQ(element->x_anchoring, XAnchoring::XNONE); 171 CHECK_EQ(element->x_anchoring, XAnchoring::XNONE);
232 CHECK_EQ(element->y_anchoring, YAnchoring::YNONE); 172 CHECK_EQ(element->y_anchoring, YAnchoring::YNONE);
233 } 173 }
234 ui_elements_.push_back(std::move(element)); 174 ui_elements_.push_back(std::move(element));
235 } 175 }
236 176
237 void UiScene::AddUiElementFromDict(const base::DictionaryValue& dict) { 177 void UiScene::AddUiElementFromDict(const base::DictionaryValue& dict) {
238 int id; 178 int id;
239 CHECK(dict.GetInteger("id", &id)); 179 CHECK(ParseInt(dict, "id", &id));
240 CHECK_EQ(GetUiElementById(id), nullptr); 180 CHECK_EQ(GetUiElementById(id), nullptr);
241 181
242 std::unique_ptr<ContentRectangle> element(new ContentRectangle); 182 std::unique_ptr<ContentRectangle> element(new ContentRectangle);
243 element->id = id; 183 element->id = id;
244 184
245 ApplyDictToElement(dict, element.get()); 185 ApplyDictToElement(dict, element.get());
246 ui_elements_.push_back(std::move(element)); 186 ui_elements_.push_back(std::move(element));
247 } 187 }
248 188
249 void UiScene::UpdateUiElementFromDict(const base::DictionaryValue& dict) { 189 void UiScene::UpdateUiElementFromDict(const base::DictionaryValue& dict) {
250 int id; 190 int id;
251 CHECK(dict.GetInteger("id", &id)); 191 CHECK(ParseInt(dict, "id", &id));
252 ContentRectangle* element = GetUiElementById(id); 192 ContentRectangle* element = GetUiElementById(id);
253 CHECK_NE(element, nullptr); 193 CHECK_NE(element, nullptr);
254 ApplyDictToElement(dict, element); 194 ApplyDictToElement(dict, element);
255 } 195 }
256 196
257 void UiScene::RemoveUiElement(int element_id) { 197 void UiScene::RemoveUiElement(int element_id) {
258 for (auto it = ui_elements_.begin(); it != ui_elements_.end(); ++it) { 198 for (auto it = ui_elements_.begin(); it != ui_elements_.end(); ++it) {
259 if ((*it)->id == element_id) { 199 if ((*it)->id == element_id) {
260 if ((*it)->fill == Fill::CONTENT) { 200 if ((*it)->fill == Fill::CONTENT) {
261 content_element_ = nullptr; 201 content_element_ = nullptr;
(...skipping 21 matching lines...) Expand all
283 Animation::Property property; 223 Animation::Property property;
284 double start_time_ms; 224 double start_time_ms;
285 double duration_ms; 225 double duration_ms;
286 226
287 const base::DictionaryValue* easing_dict = nullptr; 227 const base::DictionaryValue* easing_dict = nullptr;
288 const base::DictionaryValue* from_dict = nullptr; 228 const base::DictionaryValue* from_dict = nullptr;
289 const base::DictionaryValue* to_dict = nullptr; 229 const base::DictionaryValue* to_dict = nullptr;
290 std::vector<float> from; 230 std::vector<float> from;
291 std::vector<float> to; 231 std::vector<float> to;
292 232
293 CHECK(dict.GetInteger("id", &animation_id)); 233 CHECK(ParseInt(dict, "id", &animation_id));
294 CHECK(dict.GetInteger("meshId", &element_id)); 234 CHECK(ParseInt(dict, "meshId", &element_id));
295 CHECK(dict.GetInteger("property", reinterpret_cast<int*>(&property))); 235 CHECK(ParseInt(dict, "property", &property));
296 CHECK(dict.GetDouble("startInMillis", &start_time_ms)); 236 CHECK(ParseFloat(dict, "startInMillis", &start_time_ms));
297 CHECK(dict.GetDouble("durationMillis", &duration_ms)); 237 CHECK(ParseFloat(dict, "durationMillis", &duration_ms));
298 238
299 CHECK(dict.GetDictionary("easing", &easing_dict)); 239 CHECK(dict.GetDictionary("easing", &easing_dict));
300 auto easing = ParseEasing(*easing_dict); 240 auto easing = ParseEasing(*easing_dict);
301 241
302 CHECK(dict.GetDictionary("to", &to_dict)); 242 CHECK(dict.GetDictionary("to", &to_dict));
303 ParseEndpointToFloats(property, *to_dict, &to); 243 ParseEndpointToFloats(property, *to_dict, &to);
304 244
305 // The start location is optional. If not specified, the animation will 245 // The start location is optional. If not specified, the animation will
306 // start from the element's current location. 246 // start from the element's current location.
307 dict.GetDictionary("from", &from_dict); 247 dict.GetDictionary("from", &from_dict);
(...skipping 30 matching lines...) Expand all
338 } 278 }
339 279
340 void UiScene::HandleCommands(std::unique_ptr<base::ListValue> commands, 280 void UiScene::HandleCommands(std::unique_ptr<base::ListValue> commands,
341 int64_t time_in_micro) { 281 int64_t time_in_micro) {
342 for (auto& item : *commands) { 282 for (auto& item : *commands) {
343 base::DictionaryValue* dict; 283 base::DictionaryValue* dict;
344 CHECK(item->GetAsDictionary(&dict)); 284 CHECK(item->GetAsDictionary(&dict));
345 285
346 Command type; 286 Command type;
347 base::DictionaryValue* data; 287 base::DictionaryValue* data;
348 CHECK(dict->GetInteger("type", reinterpret_cast<int*>(&type))); 288 CHECK(ParseInt(*dict, "type", &type));
349 CHECK(dict->GetDictionary("data", &data)); 289 CHECK(dict->GetDictionary("data", &data));
350 290
351 switch (type) { 291 switch (type) {
352 case Command::ADD_ELEMENT: 292 case Command::ADD_ELEMENT:
353 AddUiElementFromDict(*data); 293 AddUiElementFromDict(*data);
354 break; 294 break;
355 case Command::UPDATE_ELEMENT: 295 case Command::UPDATE_ELEMENT:
356 UpdateUiElementFromDict(*data); 296 UpdateUiElementFromDict(*data);
357 break; 297 break;
358 case Command::REMOVE_ELEMENT: { 298 case Command::REMOVE_ELEMENT: {
359 int element_id; 299 int element_id;
360 CHECK(data->GetInteger("id", &element_id)); 300 CHECK(ParseInt(*data, "id", &element_id));
361 RemoveUiElement(element_id); 301 RemoveUiElement(element_id);
362 break; 302 break;
363 } 303 }
364 case Command::ADD_ANIMATION: 304 case Command::ADD_ANIMATION:
365 AddAnimationFromDict(*data, time_in_micro); 305 AddAnimationFromDict(*data, time_in_micro);
366 break; 306 break;
367 case Command::REMOVE_ANIMATION: { 307 case Command::REMOVE_ANIMATION: {
368 int element_id, animation_id; 308 int element_id, animation_id;
369 CHECK(data->GetInteger("id", &animation_id)); 309 CHECK(ParseInt(*data, "id", &animation_id));
370 CHECK(data->GetInteger("meshId", &element_id)); 310 CHECK(ParseInt(*data, "meshId", &element_id));
371 RemoveAnimation(element_id, animation_id); 311 RemoveAnimation(element_id, animation_id);
372 break; 312 break;
373 } 313 }
374 case Command::UPDATE_BACKGROUND: 314 case Command::UPDATE_BACKGROUND:
375 UpdateBackgroundFromDict(*data); 315 UpdateBackgroundFromDict(*data);
376 break; 316 break;
377 } 317 }
378 } 318 }
379 } 319 }
380 320
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 CHECK(parent != nullptr); 374 CHECK(parent != nullptr);
435 ApplyAnchoring(*parent, element.x_anchoring, element.y_anchoring, 375 ApplyAnchoring(*parent, element.x_anchoring, element.y_anchoring,
436 transform); 376 transform);
437 ApplyRecursiveTransforms(*parent, transform, opacity); 377 ApplyRecursiveTransforms(*parent, transform, opacity);
438 } 378 }
439 } 379 }
440 380
441 void UiScene::ApplyDictToElement(const base::DictionaryValue& dict, 381 void UiScene::ApplyDictToElement(const base::DictionaryValue& dict,
442 ContentRectangle* element) { 382 ContentRectangle* element) {
443 int parent_id; 383 int parent_id;
444 if (dict.GetInteger("parentId", &parent_id)) { 384
385 if (ParseInt(dict, "parentId", &parent_id)) {
445 CHECK_GE(parent_id, 0); 386 CHECK_GE(parent_id, 0);
446 CHECK_NE(GetUiElementById(parent_id), nullptr); 387 CHECK_NE(GetUiElementById(parent_id), nullptr);
447 element->parent_id = parent_id; 388 element->parent_id = parent_id;
448 } 389 }
449 390
450 dict.GetBoolean("visible", &element->visible); 391 dict.GetBoolean("visible", &element->visible);
451 dict.GetBoolean("hitTestable", &element->hit_testable); 392 dict.GetBoolean("hitTestable", &element->hit_testable);
452 dict.GetBoolean("lockToFov", &element->lock_to_fov); 393 dict.GetBoolean("lockToFov", &element->lock_to_fov);
453 Parse2DVec3f(dict, "size", &element->size);
454 ParseVec3f(dict, "scale", &element->scale);
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 394
463 if (dict.GetInteger("xAnchoring", 395 ParseFloat(dict, "sizeX", &element->size.x);
464 reinterpret_cast<int*>(&element->x_anchoring))) { 396 ParseFloat(dict, "sizeY", &element->size.y);
397 ParseFloat(dict, "scaleX", &element->scale.x);
398 ParseFloat(dict, "scaleY", &element->scale.y);
399 ParseFloat(dict, "scaleZ", &element->scale.z);
400 ParseFloat(dict, "rotationX", &element->rotation.x);
401 ParseFloat(dict, "rotationY", &element->rotation.y);
402 ParseFloat(dict, "rotationZ", &element->rotation.z);
403 ParseFloat(dict, "rotationAngle", &element->rotation.angle);
404 ParseFloat(dict, "translationX", &element->translation.x);
405 ParseFloat(dict, "translationY", &element->translation.y);
406 ParseFloat(dict, "translationZ", &element->translation.z);
407
408 ParseInt(dict, "drawPhase", &element->draw_phase);
409
410 ParseFloat(dict, "opacity", &element->opacity);
tiborg 2017/02/23 15:21:18 Remove new lines or move the ParseFloat to the oth
cjgrant 2017/02/23 16:13:37 Done.
411 if (ParseInt(dict, "xAnchoring", &element->x_anchoring)) {
465 CHECK_GE(element->parent_id, 0); 412 CHECK_GE(element->parent_id, 0);
466 } 413 }
467 if (dict.GetInteger("yAnchoring", 414 if (ParseInt(dict, "yAnchoring", &element->y_anchoring)) {
468 reinterpret_cast<int*>(&element->y_anchoring))) {
469 CHECK_GE(element->parent_id, 0); 415 CHECK_GE(element->parent_id, 0);
470 } 416 }
471 417
472 // Parse the element fill. 418 // Parse the element fill.
473 if (dict.GetInteger("fillType", reinterpret_cast<int*>(&element->fill))) { 419 if (ParseInt(dict, "fillType", &element->fill)) {
474 // If the previous content element has a new filling now make sure this is 420 // If the previous content element has a new filling now make sure this is
475 // tracked correctly. 421 // tracked correctly.
476 if (content_element_ == element && element->fill != Fill::CONTENT) { 422 if (content_element_ == element && element->fill != Fill::CONTENT) {
477 content_element_ = nullptr; 423 content_element_ = nullptr;
478 } 424 }
479 425
480 switch (element->fill) { 426 switch (element->fill) {
481 case Fill::SPRITE: 427 case Fill::SPRITE:
482 CHECK(ParseRecti(dict, "copyRect", &element->copy_rect)); 428 CHECK(ParseInt(dict, "copyRectX", &element->copy_rect.x));
429 CHECK(ParseInt(dict, "copyRectY", &element->copy_rect.y));
430 CHECK(ParseInt(dict, "copyRectWidth", &element->copy_rect.width));
431 CHECK(ParseInt(dict, "copyRectHeight", &element->copy_rect.height));
483 break; 432 break;
484 case Fill::OPAQUE_GRADIENT: 433 case Fill::OPAQUE_GRADIENT:
485 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color)); 434 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color));
486 CHECK(ParseColorf(dict, "centerColor", &element->center_color)); 435 CHECK(ParseColorf(dict, "centerColor", &element->center_color));
487 break; 436 break;
488 case Fill::GRID_GRADIENT: 437 case Fill::GRID_GRADIENT:
489 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color)); 438 CHECK(ParseColorf(dict, "edgeColor", &element->edge_color));
490 CHECK(ParseColorf(dict, "centerColor", &element->center_color)); 439 CHECK(ParseColorf(dict, "centerColor", &element->center_color));
491 CHECK(dict.GetInteger("gridlineCount", &element->gridline_count)); 440 CHECK(ParseInt(dict, "gridlineCount", &element->gridline_count));
492 CHECK_GE(element->gridline_count, 0); 441 CHECK_GE(element->gridline_count, 0);
493 break; 442 break;
494 case Fill::CONTENT: 443 case Fill::CONTENT:
495 CHECK_EQ(content_element_, nullptr); 444 CHECK_EQ(content_element_, nullptr);
496 content_element_ = element; 445 content_element_ = element;
497 break; 446 break;
498 default: 447 default:
499 element->fill = Fill::NONE; 448 element->fill = Fill::NONE;
500 break; 449 break;
501 } 450 }
502 } 451 }
503 } 452 }
504 453
505 } // namespace vr_shell 454 } // 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