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

Side by Side Diff: chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view.cc

Issue 2634553003: Animates touch points on screen tap during touch calibration (Closed)
Patch Set: Resolving Comments Created 3 years, 11 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
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/chromeos/display/touch_calibrator/touch_calibrator_view .h" 5 #include "chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view .h"
6 6
7 #include "ash/display/window_tree_host_manager.h" 7 #include "ash/display/window_tree_host_manager.h"
8 #include "ash/public/cpp/shell_window_ids.h" 8 #include "ash/public/cpp/shell_window_ids.h"
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ui/aura/window.h" 10 #include "ui/aura/window.h"
11 #include "ui/base/resource/resource_bundle.h" 11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/compositor/scoped_layer_animation_settings.h"
12 #include "ui/gfx/animation/linear_animation.h" 13 #include "ui/gfx/animation/linear_animation.h"
13 #include "ui/gfx/animation/throb_animation.h" 14 #include "ui/gfx/animation/throb_animation.h"
14 #include "ui/gfx/canvas.h" 15 #include "ui/gfx/canvas.h"
15 #include "ui/strings/grit/ui_strings.h" 16 #include "ui/strings/grit/ui_strings.h"
17 #include "ui/views/background.h"
16 #include "ui/views/controls/label.h" 18 #include "ui/views/controls/label.h"
17 #include "ui/views/widget/widget.h" 19 #include "ui/views/widget/widget.h"
18 20
19 namespace chromeos { 21 namespace chromeos {
20 22
21 namespace { 23 namespace {
22 24
23 constexpr char kWidgetName[] = "TouchCalibratorOverlay"; 25 constexpr char kWidgetName[] = "TouchCalibratorOverlay";
24 26
25 constexpr int kAnimationFrameRate = 100; 27 constexpr int kAnimationFrameRate = 100;
26 constexpr int kFadeDurationInMs = 150; 28 constexpr int kFadeDurationInMs = 150;
29 constexpr int kPointMoveDurationInMs = 600;
30 constexpr int kPointMoveDurationLongInMs = 700;
27 31
28 const SkColor kExitLabelColor = SkColorSetARGBInline(255, 96, 96, 96); 32 const SkColor kExitLabelColor = SkColorSetARGBInline(255, 96, 96, 96);
29 const SkColor kExitLabelShadowColor = SkColorSetARGBInline(255, 11, 11, 11); 33 const SkColor kExitLabelShadowColor = SkColorSetARGBInline(255, 11, 11, 11);
30 constexpr int kExitLabelWidth = 300; 34 constexpr int kExitLabelWidth = 300;
31 constexpr int kExitLabelHeight = 20; 35 constexpr int kExitLabelHeight = 20;
32 36
37 const SkColor kTapHereLabelColor = SK_ColorWHITE;
38
33 constexpr int kHintBoxWidth = 298; 39 constexpr int kHintBoxWidth = 298;
34 constexpr int kHintBoxHeight = 180; 40 constexpr int kHintBoxHeight = 180;
35 constexpr int kHintBoxLabelTextSize = 5; 41 constexpr int kHintBoxLabelTextSize = 5;
36 constexpr int kHintBoxSublabelTextSize = 3; 42 constexpr int kHintBoxSublabelTextSize = 3;
37 43
38 constexpr int kThrobberCircleViewWidth = 128; 44 constexpr int kThrobberCircleViewWidth = 64;
39 constexpr float kThrobberCircleRadiusFactor = 3.f / 8.f; 45 constexpr float kThrobberCircleRadiusFactor = 3.f / 8.f;
40 46
41 constexpr int kTouchPointViewOffset = 100; 47 constexpr int kTouchPointViewOffset = 100;
42 48
43 constexpr int kTapLabelHeight = 48; 49 constexpr int kTapLabelHeight = 48;
50 constexpr int kTapLabelWidth = 80;
44 51
45 const SkColor kHintLabelTextColor = SK_ColorBLACK; 52 const SkColor kHintLabelTextColor = SK_ColorBLACK;
46 const SkColor kHintSublabelTextColor = SkColorSetARGBInline(255, 161, 161, 161); 53 const SkColor kHintSublabelTextColor = SkColorSetARGBInline(255, 161, 161, 161);
47 54
48 const SkColor kInnerCircleColor = SK_ColorWHITE; 55 const SkColor kInnerCircleColor = SK_ColorWHITE;
49 const SkColor kOuterCircleColor = SkColorSetA(kInnerCircleColor, 128); 56 const SkColor kOuterCircleColor = SkColorSetA(kInnerCircleColor, 128);
50 57
51 constexpr int kCircleAnimationDurationMs = 900; 58 constexpr int kCircleAnimationDurationMs = 900;
52 59
53 constexpr int kHintRectBorderRadius = 8; 60 constexpr int kHintRectBorderRadius = 4;
54 61
55 constexpr float kBackgroundFinalOpacity = 0.75f; 62 constexpr float kBackgroundFinalOpacity = 0.75f;
56 63
57 // Returns the initialization params for the widget that contains the touch 64 // Returns the initialization params for the widget that contains the touch
58 // calibrator view. 65 // calibrator view.
59 views::Widget::InitParams GetWidgetParams(aura::Window* root_window) { 66 views::Widget::InitParams GetWidgetParams(aura::Window* root_window) {
60 views::Widget::InitParams params; 67 views::Widget::InitParams params;
61 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; 68 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
62 params.name = kWidgetName; 69 params.name = kWidgetName;
63 params.keep_on_top = true; 70 params.keep_on_top = true;
64 params.accept_events = true; 71 params.accept_events = true;
65 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; 72 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
66 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 73 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
67 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 74 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
68 params.parent = ash::Shell::GetContainer( 75 params.parent = ash::Shell::GetContainer(
69 root_window, ash::kShellWindowId_OverlayContainer); 76 root_window, ash::kShellWindowId_OverlayContainer);
70 return params; 77 return params;
71 } 78 }
72 79
73 // Returns the size of bounding box required for |text| of given |font_list|. 80 // Returns the size of bounding box required for |text| of given |font_list|.
74 gfx::Size GetSizeForString(const base::string16& text, 81 gfx::Size GetSizeForString(const base::string16& text,
75 const gfx::FontList& font_list) { 82 const gfx::FontList& font_list) {
76 int height = 0, width = 0; 83 int height = 0, width = 0;
77 gfx::Canvas::SizeStringInt(text, font_list, &width, &height, 0, 0); 84 gfx::Canvas::SizeStringInt(text, font_list, &width, &height, 0, 0);
78 return gfx::Size(width, height); 85 return gfx::Size(width, height);
79 } 86 }
80 87
88 void AnimateLayerToPosition(views::View* view,
89 int duration,
90 gfx::Point end_position) {
91 ui::ScopedLayerAnimationSettings slide_settings(view->layer()->GetAnimator());
92 slide_settings.SetPreemptionStrategy(
93 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
94 slide_settings.SetTransitionDuration(
95 base::TimeDelta::FromMilliseconds(duration));
96 view->SetBoundsRect(gfx::Rect(end_position, view->size()));
97 }
98
81 } // namespace 99 } // namespace
82 100
83 // Creates a throbbing animated view with two concentric circles. The radius of 101 // Creates a throbbing animated view with two concentric circles. The radius of
84 // the inner circle is fixed while that of the outer circle oscillates between a 102 // the inner circle is fixed while that of the outer circle oscillates between a
85 // min and max radius. The animation takes |animation_duration| milliseconds 103 // min and max radius. The animation takes |animation_duration| milliseconds
86 // to complete. The center of these circles are at the center of the view 104 // to complete. The center of these circles are at the center of the view
87 // element. 105 // element.
88 class CircularThrobberView : public views::View, public gfx::AnimationDelegate { 106 class CircularThrobberView : public views::View, public gfx::AnimationDelegate {
89 public: 107 public:
90 CircularThrobberView(int width, 108 CircularThrobberView(int width,
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 canvas->DrawStringRectWithFlags(sublabel_text_, sublabel_font_list_, 302 canvas->DrawStringRectWithFlags(sublabel_text_, sublabel_font_list_,
285 sublabel_color_, sublabel_text_bounds_, 303 sublabel_color_, sublabel_text_bounds_,
286 gfx::Canvas::NO_ELLIPSIS); 304 gfx::Canvas::NO_ELLIPSIS);
287 } 305 }
288 306
289 TouchCalibratorView::TouchCalibratorView(const display::Display& target_display, 307 TouchCalibratorView::TouchCalibratorView(const display::Display& target_display,
290 bool is_primary_view) 308 bool is_primary_view)
291 : display_(target_display), 309 : display_(target_display),
292 is_primary_view_(is_primary_view), 310 is_primary_view_(is_primary_view),
293 exit_label_(nullptr), 311 exit_label_(nullptr),
312 tap_label_(nullptr),
294 throbber_circle_(nullptr), 313 throbber_circle_(nullptr),
295 hint_box_view_(nullptr), 314 hint_box_view_(nullptr),
296 touch_point_view_(nullptr) { 315 touch_point_view_(nullptr) {
297 aura::Window* root = ash::Shell::GetInstance() 316 aura::Window* root = ash::Shell::GetInstance()
298 ->window_tree_host_manager() 317 ->window_tree_host_manager()
299 ->GetRootWindowForDisplayId(display_.id()); 318 ->GetRootWindowForDisplayId(display_.id());
300 widget_.reset(new views::Widget); 319 widget_.reset(new views::Widget);
301 widget_->Init(GetWidgetParams(root)); 320 widget_->Init(GetWidgetParams(root));
302 widget_->SetContentsView(this); 321 widget_->SetContentsView(this);
303 widget_->SetBounds(display_.bounds()); 322 widget_->SetBounds(display_.bounds());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 AddChildView(exit_label_); 361 AddChildView(exit_label_);
343 362
344 // If this is not the screen that is being calibrated, then this is all we 363 // If this is not the screen that is being calibrated, then this is all we
345 // need to display. 364 // need to display.
346 if (!is_primary_view_) 365 if (!is_primary_view_)
347 return; 366 return;
348 367
349 // Initialize the touch point view that contains the animated circle that the 368 // Initialize the touch point view that contains the animated circle that the
350 // user needs to tap. 369 // user needs to tap.
351 const int kTouchPointViewHeight = kThrobberCircleViewWidth + kTapLabelHeight; 370 const int kTouchPointViewHeight = kThrobberCircleViewWidth + kTapLabelHeight;
371 const int kThrobberCircleViewHorizontalOffset =
372 (kTapLabelWidth - kThrobberCircleViewWidth) / 2;
352 373
353 throbber_circle_ = 374 throbber_circle_ =
354 new CircularThrobberView(kThrobberCircleViewWidth, kInnerCircleColor, 375 new CircularThrobberView(kThrobberCircleViewWidth, kInnerCircleColor,
355 kOuterCircleColor, kCircleAnimationDurationMs); 376 kOuterCircleColor, kCircleAnimationDurationMs);
356 throbber_circle_->SetPosition(gfx::Point(0, 0)); 377 throbber_circle_->SetPosition(
378 gfx::Point(kThrobberCircleViewHorizontalOffset, 0));
379
380 // Initialize the tap label.
381 tap_label_ = new views::Label(
382 rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_TAP_HERE_LABEL),
383 rb.GetFontListWithDelta(6, gfx::Font::FontStyle::NORMAL,
384 gfx::Font::Weight::NORMAL));
385 tap_label_->SetBounds(0, kThrobberCircleViewWidth, kTapLabelWidth,
386 kTapLabelHeight);
387 tap_label_->SetEnabledColor(kTapHereLabelColor);
388 tap_label_->SetDisabledColor(kTapHereLabelColor);
389 tap_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
390 tap_label_->SetAutoColorReadabilityEnabled(false);
391 tap_label_->SetSubpixelRenderingEnabled(false);
392 tap_label_->SetVisible(false);
357 393
358 touch_point_view_ = new views::View; 394 touch_point_view_ = new views::View;
359 touch_point_view_->SetBounds(kTouchPointViewOffset, kTouchPointViewOffset, 395 touch_point_view_->SetBounds(kTouchPointViewOffset, kTouchPointViewOffset,
360 kThrobberCircleViewWidth, kTouchPointViewHeight); 396 kTapLabelWidth, kTouchPointViewHeight);
361 touch_point_view_->SetVisible(false); 397 touch_point_view_->SetVisible(false);
398 touch_point_view_->SetPaintToLayer(true);
399 touch_point_view_->layer()->SetFillsBoundsOpaquely(false);
400 touch_point_view_->layer()->GetAnimator()->AddObserver(this);
401 touch_point_view_->set_background(
402 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT));
362 403
363 touch_point_view_->AddChildView(throbber_circle_); 404 touch_point_view_->AddChildView(throbber_circle_);
405 touch_point_view_->AddChildView(tap_label_);
364 406
365 AddChildView(touch_point_view_); 407 AddChildView(touch_point_view_);
366 408
367 // Initialize the Hint Box view. 409 // Initialize the Hint Box view.
368 base::string16 hint_label_text = 410 base::string16 hint_label_text =
369 rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_LABEL_TEXT); 411 rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_LABEL_TEXT);
370 base::string16 hint_sublabel_text = 412 base::string16 hint_sublabel_text =
371 rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_SUBLABEL_TEXT); 413 rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_SUBLABEL_TEXT);
372 414
373 int tpv_width = touch_point_view_->width(); 415 int tpv_width = touch_point_view_->width();
(...skipping 30 matching lines...) Expand all
404 } else { 446 } else {
405 opacity = state_ == BACKGROUND_FADING_OUT ? 0.f : kBackgroundFinalOpacity; 447 opacity = state_ == BACKGROUND_FADING_OUT ? 0.f : kBackgroundFinalOpacity;
406 } 448 }
407 449
408 paint_.setColor(SkColorSetA(SK_ColorBLACK, 450 paint_.setColor(SkColorSetA(SK_ColorBLACK,
409 std::numeric_limits<uint8_t>::max() * opacity)); 451 std::numeric_limits<uint8_t>::max() * opacity));
410 canvas->DrawRect(background_rect_, paint_); 452 canvas->DrawRect(background_rect_, paint_);
411 } 453 }
412 454
413 void TouchCalibratorView::AnimationProgressed(const gfx::Animation* animation) { 455 void TouchCalibratorView::AnimationProgressed(const gfx::Animation* animation) {
414 SchedulePaint(); 456 if (!is_primary_view_) {
457 SchedulePaint();
458 return;
459 }
415 } 460 }
416 461
417 void TouchCalibratorView::AnimationCanceled(const gfx::Animation* animation) { 462 void TouchCalibratorView::AnimationCanceled(const gfx::Animation* animation) {
418 AnimationEnded(animation); 463 AnimationEnded(animation);
419 } 464 }
420 465
421 void TouchCalibratorView::AnimationEnded(const gfx::Animation* animation) { 466 void TouchCalibratorView::AnimationEnded(const gfx::Animation* animation) {
422 switch (state_) { 467 switch (state_) {
423 case BACKGROUND_FADING_IN: 468 case BACKGROUND_FADING_IN:
424 exit_label_->SetVisible(true); 469 exit_label_->SetVisible(true);
425 state_ = is_primary_view_ ? DISPLAY_POINT_1 : CALIBRATION_COMPLETE; 470 state_ = is_primary_view_ ? DISPLAY_POINT_1 : CALIBRATION_COMPLETE;
426 if (is_primary_view_) { 471 if (is_primary_view_) {
427 touch_point_view_->SetVisible(true); 472 touch_point_view_->SetVisible(true);
428 hint_box_view_->SetVisible(true); 473 hint_box_view_->SetVisible(true);
429 } 474 }
430 break; 475 break;
431 default: 476 default:
432 break; 477 break;
433 } 478 }
434 } 479 }
435 480
481 void TouchCalibratorView::OnLayerAnimationStarted(
482 ui::LayerAnimationSequence* sequence) {}
483
484 void TouchCalibratorView::OnLayerAnimationEnded(
485 ui::LayerAnimationSequence* sequence) {
486 switch (state_) {
487 case ANIMATING_1_TO_2:
488 state_ = DISPLAY_POINT_2;
489 tap_label_->SetVisible(true);
490 break;
491 case ANIMATING_2_TO_3:
492 state_ = DISPLAY_POINT_3;
493 break;
494 case ANIMATING_3_TO_4:
495 state_ = DISPLAY_POINT_4;
496 break;
497 default:
498 break;
499 }
500 }
501
502 void TouchCalibratorView::OnLayerAnimationAborted(
503 ui::LayerAnimationSequence* sequence) {
504 OnLayerAnimationEnded(sequence);
505 }
506
507 void TouchCalibratorView::OnLayerAnimationScheduled(
508 ui::LayerAnimationSequence* sequence) {}
509
436 void TouchCalibratorView::AdvanceToNextState() { 510 void TouchCalibratorView::AdvanceToNextState() {
437 // Stop any previous animations and skip them to the end. 511 // Stop any previous animations and skip them to the end.
438 animator_->End(); 512 SkipCurrentAnimation();
439 513
440 switch (state_) { 514 switch (state_) {
441 case UNKNOWN: 515 case UNKNOWN:
442 case BACKGROUND_FADING_IN: 516 case BACKGROUND_FADING_IN:
443 state_ = BACKGROUND_FADING_IN; 517 state_ = BACKGROUND_FADING_IN;
444 start_opacity_value_ = 0.f; 518 start_opacity_value_ = 0.f;
445 end_opacity_value_ = kBackgroundFinalOpacity; 519 end_opacity_value_ = kBackgroundFinalOpacity;
446 520
447 paint_.setStyle(SkPaint::kFill_Style); 521 paint_.setStyle(SkPaint::kFill_Style);
522 animator_->SetDuration(kFadeDurationInMs);
523 animator_->Start();
524 return;
525 case DISPLAY_POINT_1:
526 state_ = ANIMATING_1_TO_2;
448 527
449 animator_->SetDuration(kFadeDurationInMs); 528 // The touch point has to be animated from the top left corner of the
450 break; 529 // screen to the top right corner.
530 AnimateLayerToPosition(
531 touch_point_view_, kPointMoveDurationInMs,
532 gfx::Point(display_.bounds().width() - kTouchPointViewOffset -
533 touch_point_view_->width(),
534 touch_point_view_->y()));
535 hint_box_view_->SetVisible(false);
536 return;
537 case DISPLAY_POINT_2:
538 state_ = ANIMATING_2_TO_3;
539
540 // The touch point has to be animated from the top right corner of the
541 // screen to the bottom left corner.
542 AnimateLayerToPosition(
543 touch_point_view_, kPointMoveDurationLongInMs,
544 gfx::Point(kTouchPointViewOffset, display_.bounds().height() -
545 kTouchPointViewOffset -
546 touch_point_view_->height()));
547 return;
548 case DISPLAY_POINT_3:
549 state_ = ANIMATING_3_TO_4;
550
551 // The touch point has to be animated from the bottom left corner of the
552 // screen to the bottom right corner.
553 AnimateLayerToPosition(
554 touch_point_view_, kPointMoveDurationInMs,
555 gfx::Point(display_.bounds().width() - kTouchPointViewOffset -
556 touch_point_view_->width(),
557 touch_point_view_->y()));
558 return;
451 default: 559 default:
452 break; 560 return;
453 } 561 }
454 animator_->Start();
455 } 562 }
456 563
457 bool TouchCalibratorView::GetDisplayPointLocation(gfx::Point* location) { 564 bool TouchCalibratorView::GetDisplayPointLocation(gfx::Point* location) {
565 DCHECK(location);
458 if (!is_primary_view_) 566 if (!is_primary_view_)
459 return false; 567 return false;
460 return false; 568
569 if (state_ != DISPLAY_POINT_1 && state_ != DISPLAY_POINT_2 &&
570 state_ != DISPLAY_POINT_3 && state_ != DISPLAY_POINT_4) {
571 return false;
572 }
573
574 if (!touch_point_view_ || !throbber_circle_)
575 return false;
576 // TODO(malaykeshav): Can use views::ConvertPointToScreen()
577 location->SetPoint(touch_point_view_->x() + touch_point_view_->width() / 2.f,
578 touch_point_view_->y() + touch_point_view_->width() / 2.f);
579 return true;
461 } 580 }
462 581
463 void TouchCalibratorView::SkipToFinalState() {} 582 void TouchCalibratorView::SkipToFinalState() {}
464 583
465 void TouchCalibratorView::SkipCurrentAnimationForTest() { 584 void TouchCalibratorView::SkipCurrentAnimation() {
466 if (animator_->is_animating()) 585 if (animator_->is_animating())
467 animator_->End(); 586 animator_->End();
587 if (touch_point_view_ &&
588 touch_point_view_->layer()->GetAnimator()->is_animating()) {
589 touch_point_view_->layer()->GetAnimator()->StopAnimating();
590 }
468 } 591 }
469 592
470 } // namespace chromeos 593 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view.h ('k') | ui/strings/ui_strings.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698