123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/display/touch_calibrator_view.h"
- #include <memory>
- #include "ash/public/cpp/shell_window_ids.h"
- #include "ash/resources/vector_icons/vector_icons.h"
- #include "ash/shell.h"
- #include "base/memory/ptr_util.h"
- #include "ui/aura/window.h"
- #include "ui/base/resource/resource_bundle.h"
- #include "ui/compositor/layer.h"
- #include "ui/compositor/scoped_layer_animation_settings.h"
- #include "ui/gfx/animation/throb_animation.h"
- #include "ui/gfx/canvas.h"
- #include "ui/gfx/paint_vector_icon.h"
- #include "ui/strings/grit/ui_strings.h"
- #include "ui/views/background.h"
- #include "ui/views/bubble/bubble_border.h"
- #include "ui/views/controls/label.h"
- #include "ui/views/widget/widget.h"
- namespace ash {
- namespace {
- constexpr char kWidgetName[] = "TouchCalibratorOverlay";
- constexpr int kAnimationFrameRate = 100;
- constexpr auto kFadeDuration = base::Milliseconds(150);
- constexpr auto kPointMoveDuration = base::Milliseconds(400);
- constexpr auto kPointMoveDurationLong = base::Milliseconds(500);
- const SkColor kExitLabelColor = SkColorSetARGB(255, 138, 138, 138);
- constexpr int kExitLabelWidth = 300;
- constexpr int kExitLabelHeight = 20;
- const SkColor kTapHereLabelColor = SK_ColorWHITE;
- constexpr int kHintBoxWidth = 298;
- constexpr int kHintBoxHeight = 180;
- constexpr int kHintBoxLabelTextSize = 5;
- constexpr int kHintBoxSublabelTextSize = 3;
- constexpr int kThrobberCircleViewWidth = 64;
- constexpr float kThrobberCircleRadiusFactor = 3.f / 8.f;
- constexpr auto kFinalMessageTransitionDuration = base::Milliseconds(200);
- constexpr int kCompleteMessageViewWidth = 427;
- constexpr int kCompleteMessageViewHeight = kThrobberCircleViewWidth;
- constexpr int kCompleteMessageTextSize = 16;
- constexpr int kTouchPointViewOffset = 100;
- constexpr int kTapLabelHeight = 48;
- constexpr int kTapLabelWidth = 80;
- const SkColor kHintLabelTextColor = SK_ColorBLACK;
- const SkColor kHintSublabelTextColor = SkColorSetARGB(255, 161, 161, 161);
- const SkColor kInnerCircleColor = SK_ColorWHITE;
- const SkColor kOuterCircleColor = SkColorSetA(kInnerCircleColor, 255 * 0.2);
- constexpr auto kCircleAnimationDuration = base::Milliseconds(900);
- constexpr int kHintRectBorderRadius = 4;
- constexpr float kBackgroundFinalOpacity = 0.75f;
- constexpr int kTouchTargetWidth = 64;
- constexpr int kTouchTargetHeight = kTouchTargetWidth + kTouchTargetWidth / 2;
- constexpr float kTouchTargetVerticalOffsetFactor = 11.f / 24.f;
- const SkColor kTouchTargetInnerCircleColor = SkColorSetARGB(255, 66, 133, 244);
- const SkColor kTouchTargetOuterCircleColor =
- SkColorSetA(kTouchTargetInnerCircleColor, 255 * 0.2);
- const SkColor kHandIconColor = SkColorSetARGB(255, 201, 201, 201);
- constexpr float kHandIconHorizontalOffsetFactor = 7.f / 32.f;
- // Returns the initialization params for the widget that contains the touch
- // calibrator view.
- views::Widget::InitParams GetWidgetParams(aura::Window* root_window) {
- views::Widget::InitParams params;
- params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
- params.name = kWidgetName;
- params.z_order = ui::ZOrderLevel::kFloatingWindow;
- params.accept_events = true;
- params.activatable = views::Widget::InitParams::Activatable::kNo;
- params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
- params.parent =
- Shell::GetContainer(root_window, kShellWindowId_OverlayContainer);
- return params;
- }
- // Returns the size of bounding box required for |text| of given |font_list|.
- gfx::Size GetSizeForString(const std::u16string& text,
- const gfx::FontList& font_list) {
- int height = 0, width = 0;
- gfx::Canvas::SizeStringInt(text, font_list, &width, &height, 0, 0);
- return gfx::Size(width, height);
- }
- void AnimateLayerToPosition(views::View* view,
- base::TimeDelta duration,
- gfx::Point end_position,
- float opacity = 1.f) {
- ui::ScopedLayerAnimationSettings slide_settings(view->layer()->GetAnimator());
- slide_settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- slide_settings.SetTransitionDuration(duration);
- view->SetBoundsRect(gfx::Rect(end_position, view->size()));
- view->layer()->SetOpacity(opacity);
- }
- } // namespace
- // Creates a throbbing animated view with two concentric circles. The radius of
- // the inner circle is fixed while that of the outer circle oscillates between a
- // min and max radius. The animation takes |animation_duration| milliseconds
- // to complete. The center of these circles are at the center of the view
- // element.
- class CircularThrobberView : public views::View,
- public views::AnimationDelegateViews {
- public:
- CircularThrobberView(int width,
- const SkColor& inner_circle_color,
- const SkColor& outer_circle_color,
- base::TimeDelta animation_duration);
- CircularThrobberView(const CircularThrobberView&) = delete;
- CircularThrobberView& operator=(const CircularThrobberView&) = delete;
- ~CircularThrobberView() override;
- // views::View:
- void OnPaint(gfx::Canvas* canvas) override;
- // views::AnimationDelegateViews:
- void AnimationProgressed(const gfx::Animation* animation) override;
- private:
- // Radius of the inner circle.
- const int inner_radius_;
- // Current radius of the outer circle.
- int outer_radius_;
- // Minimum radius for outer animated circle.
- const int smallest_radius_animated_circle_;
- // Maximum radius for outer animated circle.
- const int largest_radius_animated_circle_;
- cc::PaintFlags inner_circle_flags_;
- cc::PaintFlags outer_circle_flags_;
- std::unique_ptr<gfx::ThrobAnimation> animation_;
- // Center of the concentric circles.
- const gfx::Point center_;
- };
- CircularThrobberView::CircularThrobberView(int width,
- const SkColor& inner_circle_color,
- const SkColor& outer_circle_color,
- base::TimeDelta animation_duration)
- : views::AnimationDelegateViews(this),
- inner_radius_(width / 4),
- outer_radius_(inner_radius_),
- smallest_radius_animated_circle_(width * kThrobberCircleRadiusFactor),
- largest_radius_animated_circle_(width / 2),
- center_(gfx::Point(width / 2, width / 2)) {
- SetSize(gfx::Size(width, width));
- inner_circle_flags_.setColor(inner_circle_color);
- inner_circle_flags_.setAntiAlias(true);
- inner_circle_flags_.setStyle(cc::PaintFlags::kFill_Style);
- outer_circle_flags_.setColor(outer_circle_color);
- outer_circle_flags_.setAntiAlias(true);
- outer_circle_flags_.setStyle(cc::PaintFlags::kFill_Style);
- animation_ = std::make_unique<gfx::ThrobAnimation>(this);
- animation_->SetThrobDuration(animation_duration);
- animation_->StartThrobbing(-1);
- SchedulePaint();
- }
- CircularThrobberView::~CircularThrobberView() = default;
- void CircularThrobberView::OnPaint(gfx::Canvas* canvas) {
- canvas->DrawCircle(center_, outer_radius_, outer_circle_flags_);
- canvas->DrawCircle(center_, inner_radius_, inner_circle_flags_);
- }
- void CircularThrobberView::AnimationProgressed(
- const gfx::Animation* animation) {
- if (animation != animation_.get())
- return;
- outer_radius_ = animation->CurrentValueBetween(
- smallest_radius_animated_circle_, largest_radius_animated_circle_);
- SchedulePaint();
- }
- class TouchTargetThrobberView : public CircularThrobberView {
- public:
- TouchTargetThrobberView(const gfx::Rect& bounds,
- const SkColor& inner_circle_color,
- const SkColor& outer_circle_color,
- const SkColor& hand_icon_color,
- base::TimeDelta animation_duration);
- TouchTargetThrobberView(const TouchTargetThrobberView&) = delete;
- TouchTargetThrobberView& operator=(const TouchTargetThrobberView&) = delete;
- ~TouchTargetThrobberView() override;
- // views::View:
- void OnPaint(gfx::Canvas* canvas) override;
- private:
- const int horizontal_offset_;
- const int icon_width_;
- gfx::ImageSkia hand_icon_;
- };
- TouchTargetThrobberView::TouchTargetThrobberView(
- const gfx::Rect& bounds,
- const SkColor& inner_circle_color,
- const SkColor& outer_circle_color,
- const SkColor& hand_icon_color,
- base::TimeDelta animation_duration)
- : CircularThrobberView(bounds.width(),
- inner_circle_color,
- outer_circle_color,
- animation_duration),
- horizontal_offset_(bounds.width() * kHandIconHorizontalOffsetFactor),
- icon_width_(bounds.width() * 0.5f) {
- SetBoundsRect(bounds);
- hand_icon_ = gfx::CreateVectorIcon(kTouchCalibrationHandIcon, kHandIconColor);
- }
- TouchTargetThrobberView::~TouchTargetThrobberView() = default;
- void TouchTargetThrobberView::OnPaint(gfx::Canvas* canvas) {
- CircularThrobberView::OnPaint(canvas);
- canvas->DrawImageInt(hand_icon_, horizontal_offset_, icon_width_);
- }
- // Circular _________________________________
- // Throbber | |
- // View | |
- // ___________ | |
- // | | | |
- // | | | |
- // | . | | Hint Box |
- // | | | |
- // |___________| | |
- // | |
- // | |
- // |_________________________________|
- //
- // This view is set next to the throbber circle view such that their centers
- // align. The hint box has a label text and a sublabel text to assist the
- // user by informing them about the next step in the calibration process.
- class HintBox : public views::View {
- public:
- HintBox(const gfx::Rect& bounds, int border_radius);
- HintBox(const HintBox&) = delete;
- HintBox& operator=(const HintBox&) = delete;
- ~HintBox() override;
- // views::View:
- void OnPaint(gfx::Canvas* canvas) override;
- void SetLabel(const std::u16string& text, const SkColor& color);
- void SetSubLabel(const std::u16string& text, const SkColor& color);
- private:
- void UpdateWidth(int updated_width);
- std::u16string label_text_;
- std::u16string sublabel_text_;
- SkColor label_color_;
- SkColor sublabel_color_;
- const int border_radius_;
- int base_border_;
- int arrow_width_;
- int horizontal_offset_;
- gfx::Rect rounded_rect_bounds_;
- gfx::FontList label_font_list_;
- gfx::FontList sublabel_font_list_;
- gfx::Rect label_text_bounds_;
- gfx::Rect sublabel_text_bounds_;
- cc::PaintFlags flags_;
- };
- HintBox::HintBox(const gfx::Rect& bounds, int border_radius)
- : border_radius_(border_radius) {
- auto border = std::make_unique<views::BubbleBorder>(
- base::i18n::IsRTL() ? views::BubbleBorder::RIGHT_CENTER
- : views::BubbleBorder::LEFT_CENTER,
- views::BubbleBorder::NO_SHADOW);
- border->SetColor(SK_ColorWHITE);
- SetBorder(std::move(border));
- arrow_width_ = (GetInsets().right() - GetInsets().left()) *
- (base::i18n::IsRTL() ? 1 : -1);
- // Border on all sides are the same except on the side of the arrow, in which
- // case the width of the arrow is additional.
- base_border_ = base::i18n::IsRTL() ? GetInsets().left() : GetInsets().right();
- SetBounds(bounds.x(), bounds.y() - base_border_,
- bounds.width() + 2 * base_border_ + arrow_width_,
- bounds.height() + 2 * base_border_);
- rounded_rect_bounds_ = GetContentsBounds();
- flags_.setColor(SK_ColorWHITE);
- flags_.setStyle(cc::PaintFlags::kFill_Style);
- flags_.setAntiAlias(true);
- horizontal_offset_ =
- arrow_width_ + base_border_ + rounded_rect_bounds_.width() * 0.08f;
- int top_offset = horizontal_offset_;
- int line_gap = rounded_rect_bounds_.height() * 0.018f;
- int label_height = rounded_rect_bounds_.height() * 0.11f;
- label_text_bounds_.SetRect(horizontal_offset_, top_offset, 0, label_height);
- top_offset += label_text_bounds_.height() + line_gap;
- sublabel_text_bounds_.SetRect(horizontal_offset_, top_offset, 0,
- label_height);
- }
- HintBox::~HintBox() = default;
- void HintBox::UpdateWidth(int updated_width) {
- SetSize(gfx::Size(updated_width + 2 * base_border_ + arrow_width_, height()));
- rounded_rect_bounds_ = GetContentsBounds();
- }
- void HintBox::SetLabel(const std::u16string& text, const SkColor& color) {
- label_text_ = text;
- label_color_ = color;
- label_font_list_ =
- ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
- kHintBoxLabelTextSize);
- // Adjust size of label bounds based on text and font.
- gfx::Size size = GetSizeForString(label_text_, label_font_list_);
- label_text_bounds_.set_size(
- gfx::Size(size.width(), label_text_bounds_.height()));
- // Check if the width of hint box needs to be updated.
- int minimum_expected_width =
- size.width() + 2 * horizontal_offset_ - arrow_width_;
- if (minimum_expected_width > rounded_rect_bounds_.width())
- UpdateWidth(minimum_expected_width);
- }
- void HintBox::SetSubLabel(const std::u16string& text, const SkColor& color) {
- sublabel_text_ = text;
- sublabel_color_ = color;
- sublabel_font_list_ =
- ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
- kHintBoxSublabelTextSize);
- // Adjust size of sublabel label bounds based on text and font.
- gfx::Size size = GetSizeForString(sublabel_text_, sublabel_font_list_);
- sublabel_text_bounds_.set_size(
- gfx::Size(size.width(), sublabel_text_bounds_.height()));
- // Check if the width of hint box needs to be updated.
- int minimum_expected_width =
- size.width() + 2 * horizontal_offset_ - arrow_width_;
- if (minimum_expected_width > rounded_rect_bounds_.width())
- UpdateWidth(minimum_expected_width);
- }
- void HintBox::OnPaint(gfx::Canvas* canvas) {
- views::View::OnPaint(canvas);
- canvas->DrawRoundRect(rounded_rect_bounds_, border_radius_, flags_);
- canvas->DrawStringRectWithFlags(label_text_, label_font_list_, label_color_,
- label_text_bounds_, gfx::Canvas::NO_ELLIPSIS);
- canvas->DrawStringRectWithFlags(sublabel_text_, sublabel_font_list_,
- sublabel_color_, sublabel_text_bounds_,
- gfx::Canvas::NO_ELLIPSIS);
- }
- class CompletionMessageView : public views::View {
- public:
- CompletionMessageView(const gfx::Rect& bounds, const std::u16string& message);
- CompletionMessageView(const CompletionMessageView&) = delete;
- CompletionMessageView& operator=(const CompletionMessageView&) = delete;
- ~CompletionMessageView() override;
- // views::View:
- void OnPaint(gfx::Canvas* canvas) override;
- private:
- const std::u16string message_;
- gfx::FontList font_list_;
- gfx::Rect text_bounds_;
- gfx::ImageSkia check_icon_;
- cc::PaintFlags flags_;
- };
- CompletionMessageView::CompletionMessageView(const gfx::Rect& bounds,
- const std::u16string& message)
- : message_(message) {
- SetBoundsRect(bounds);
- int x_offset = height() * 5.f / 4.f;
- text_bounds_.SetRect(x_offset, 0, width() - x_offset, height());
- font_list_ = ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
- kCompleteMessageTextSize);
- // crbug/676513 moves this file to src/ash which will require an ash icon
- // file.
- check_icon_ =
- gfx::CreateVectorIcon(kTouchCalibrationCompleteCheckIcon, SK_ColorWHITE);
- flags_.setColor(SK_ColorWHITE);
- flags_.setStyle(cc::PaintFlags::kFill_Style);
- flags_.setAntiAlias(true);
- }
- CompletionMessageView::~CompletionMessageView() = default;
- void CompletionMessageView::OnPaint(gfx::Canvas* canvas) {
- canvas->DrawImageInt(check_icon_, 0, 0);
- // TODO(malaykeshav): Work with elizabethchiu@ to get better UX for RTL.
- canvas->DrawStringRectWithFlags(
- message_, font_list_, flags_.getColor(), text_bounds_,
- gfx::Canvas::TEXT_ALIGN_LEFT | gfx::Canvas::NO_SUBPIXEL_RENDERING);
- }
- // static
- views::UniqueWidgetPtr TouchCalibratorView::Create(
- const display::Display& target_display,
- bool is_primary_view) {
- aura::Window* root = Shell::GetRootWindowForDisplayId(target_display.id());
- views::UniqueWidgetPtr widget(
- std::make_unique<views::Widget>(GetWidgetParams(root)));
- widget->SetContentsView(base::WrapUnique(
- new TouchCalibratorView(target_display, is_primary_view)));
- widget->SetBounds(target_display.bounds());
- widget->Show();
- return widget;
- }
- TouchCalibratorView::TouchCalibratorView(const display::Display& target_display,
- bool is_primary_view)
- : views::AnimationDelegateViews(this),
- display_(target_display),
- is_primary_view_(is_primary_view),
- animator_(std::make_unique<gfx::LinearAnimation>(kFadeDuration,
- kAnimationFrameRate,
- this)) {
- InitViewContents();
- AdvanceToNextState();
- }
- TouchCalibratorView::~TouchCalibratorView() {
- state_ = UNKNOWN;
- animator_->End();
- }
- void TouchCalibratorView::InitViewContents() {
- // Initialize the background rect.
- background_rect_ =
- gfx::RectF(0, 0, display_.bounds().width(), display_.bounds().height());
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- // Initialize exit label that informs the user how to exit the touch
- // calibration setup.
- exit_label_ = AddChildView(std::make_unique<views::Label>(
- rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_EXIT_LABEL),
- views::Label::CustomFont{rb.GetFontListWithDelta(8)}));
- exit_label_->SetBounds((display_.bounds().width() - kExitLabelWidth) / 2,
- display_.bounds().height() * 3.f / 4, kExitLabelWidth,
- kExitLabelHeight);
- exit_label_->SetAutoColorReadabilityEnabled(false);
- exit_label_->SetEnabledColor(kExitLabelColor);
- exit_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
- exit_label_->SetSubpixelRenderingEnabled(false);
- exit_label_->SetVisible(false);
- // If this is not the screen that is being calibrated, then this is all we
- // need to display.
- if (!is_primary_view_)
- return;
- // Initialize the touch point view that contains the animated circle that the
- // user needs to tap.
- const int kTouchPointViewHeight = kThrobberCircleViewWidth + kTapLabelHeight;
- const int kThrobberCircleViewHorizontalOffset =
- (kTapLabelWidth - kThrobberCircleViewWidth) / 2;
- touch_point_view_ = AddChildView(std::make_unique<views::View>());
- touch_point_view_->SetBounds(kTouchPointViewOffset, kTouchPointViewOffset,
- kTapLabelWidth, kTouchPointViewHeight);
- touch_point_view_->SetVisible(false);
- touch_point_view_->SetPaintToLayer();
- touch_point_view_->layer()->SetFillsBoundsOpaquely(false);
- touch_point_view_->layer()->GetAnimator()->AddObserver(this);
- touch_point_view_->SetBackground(
- views::CreateSolidBackground(SK_ColorTRANSPARENT));
- throbber_circle_ =
- touch_point_view_->AddChildView(std::make_unique<CircularThrobberView>(
- kThrobberCircleViewWidth, kInnerCircleColor, kOuterCircleColor,
- kCircleAnimationDuration));
- throbber_circle_->SetPosition(
- gfx::Point(kThrobberCircleViewHorizontalOffset, 0));
- // Initialize the tap label.
- tap_label_ = touch_point_view_->AddChildView(std::make_unique<views::Label>(
- rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_TAP_HERE_LABEL),
- views::Label::CustomFont{rb.GetFontListWithDelta(6)}));
- tap_label_->SetBounds(0, kThrobberCircleViewWidth, kTapLabelWidth,
- kTapLabelHeight);
- tap_label_->SetEnabledColor(kTapHereLabelColor);
- tap_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
- tap_label_->SetAutoColorReadabilityEnabled(false);
- tap_label_->SetSubpixelRenderingEnabled(false);
- tap_label_->SetVisible(false);
- // Initialize the Hint Box view.
- std::u16string hint_label_text =
- rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_LABEL_TEXT);
- std::u16string hint_sublabel_text =
- rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_SUBLABEL_TEXT);
- int tpv_width = touch_point_view_->width();
- gfx::Size size(kHintBoxWidth, kHintBoxHeight);
- gfx::Point position(touch_point_view_->x() + tpv_width * 1.2f,
- touch_point_view_->y() +
- (kThrobberCircleViewWidth / 2.f) -
- (size.height() / 2.f));
- hint_box_view_ = AddChildView(std::make_unique<HintBox>(
- gfx::Rect(position, size), kHintRectBorderRadius));
- hint_box_view_->SetVisible(false);
- hint_box_view_->SetLabel(hint_label_text, kHintLabelTextColor);
- hint_box_view_->SetSubLabel(hint_sublabel_text, kHintSublabelTextColor);
- // Initialize the animated hint box throbber view.
- auto* target_view =
- hint_box_view_->AddChildView(std::make_unique<TouchTargetThrobberView>(
- gfx::Rect((hint_box_view_->width() - kTouchTargetWidth) / 2,
- hint_box_view_->height() * kTouchTargetVerticalOffsetFactor,
- kTouchTargetWidth, kTouchTargetHeight),
- kTouchTargetInnerCircleColor, kTouchTargetOuterCircleColor,
- kHandIconColor, kCircleAnimationDuration));
- target_view->SetVisible(true);
- // Initialize the view that contains the calibration complete message which
- // will be displayed at the end.
- std::u16string finish_msg_text =
- rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_FINISH_LABEL);
- gfx::Rect msg_view_bounds(
- (display_.bounds().width() - kCompleteMessageViewWidth) / 2,
- display_.bounds().height() / 3, kCompleteMessageViewWidth,
- kCompleteMessageViewHeight);
- completion_message_view_ =
- AddChildView(std::make_unique<CompletionMessageView>(msg_view_bounds,
- finish_msg_text));
- completion_message_view_->SetVisible(false);
- completion_message_view_->SetPaintToLayer();
- completion_message_view_->layer()->SetFillsBoundsOpaquely(false);
- completion_message_view_->layer()->GetAnimator()->AddObserver(this);
- completion_message_view_->SetBackground(
- views::CreateSolidBackground(SK_ColorTRANSPARENT));
- }
- void TouchCalibratorView::OnPaint(gfx::Canvas* canvas) {
- OnPaintBackground(canvas);
- }
- void TouchCalibratorView::OnPaintBackground(gfx::Canvas* canvas) {
- float opacity;
- // If current state is a fade in or fade out state then update opacity
- // based on how far the animation has progressed.
- if (animator_ && (state_ == TouchCalibratorView::BACKGROUND_FADING_OUT ||
- state_ == TouchCalibratorView::BACKGROUND_FADING_IN)) {
- opacity = static_cast<float>(animator_->CurrentValueBetween(
- start_opacity_value_, end_opacity_value_));
- } else {
- opacity = state_ == BACKGROUND_FADING_OUT ? 0.0f : kBackgroundFinalOpacity;
- }
- flags_.setColor(SkColorSetA(SK_ColorBLACK,
- std::numeric_limits<uint8_t>::max() * opacity));
- canvas->DrawRect(background_rect_, flags_);
- }
- void TouchCalibratorView::AnimationProgressed(const gfx::Animation* animation) {
- if (!is_primary_view_) {
- SchedulePaint();
- return;
- }
- }
- void TouchCalibratorView::AnimationCanceled(const gfx::Animation* animation) {
- AnimationEnded(animation);
- }
- void TouchCalibratorView::AnimationEnded(const gfx::Animation* animation) {
- switch (state_) {
- case BACKGROUND_FADING_IN:
- exit_label_->SetVisible(true);
- state_ = is_primary_view_ ? DISPLAY_POINT_1 : CALIBRATION_COMPLETE;
- if (is_primary_view_) {
- touch_point_view_->SetVisible(true);
- hint_box_view_->SetVisible(true);
- }
- break;
- case BACKGROUND_FADING_OUT:
- exit_label_->SetVisible(false);
- if (is_primary_view_)
- completion_message_view_->SetVisible(false);
- GetWidget()->Hide();
- break;
- default:
- break;
- }
- }
- void TouchCalibratorView::OnLayerAnimationStarted(
- ui::LayerAnimationSequence* sequence) {}
- void TouchCalibratorView::OnLayerAnimationEnded(
- ui::LayerAnimationSequence* sequence) {
- switch (state_) {
- case ANIMATING_1_TO_2:
- state_ = DISPLAY_POINT_2;
- tap_label_->SetVisible(true);
- break;
- case ANIMATING_2_TO_3:
- state_ = DISPLAY_POINT_3;
- break;
- case ANIMATING_3_TO_4:
- state_ = DISPLAY_POINT_4;
- break;
- case ANIMATING_FINAL_MESSAGE:
- state_ = CALIBRATION_COMPLETE;
- break;
- default:
- break;
- }
- }
- void TouchCalibratorView::OnLayerAnimationAborted(
- ui::LayerAnimationSequence* sequence) {
- OnLayerAnimationEnded(sequence);
- }
- void TouchCalibratorView::OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) {}
- void TouchCalibratorView::AdvanceToNextState() {
- // Stop any previous animations and skip them to the end.
- SkipCurrentAnimation();
- switch (state_) {
- case UNKNOWN:
- case BACKGROUND_FADING_IN:
- state_ = BACKGROUND_FADING_IN;
- start_opacity_value_ = 0.0f;
- end_opacity_value_ = kBackgroundFinalOpacity;
- flags_.setStyle(cc::PaintFlags::kFill_Style);
- animator_->SetDuration(kFadeDuration);
- animator_->Start();
- return;
- case DISPLAY_POINT_1:
- state_ = ANIMATING_1_TO_2;
- // The touch point has to be animated from the top left corner of the
- // screen to the top right corner.
- AnimateLayerToPosition(
- touch_point_view_, kPointMoveDuration,
- gfx::Point(display_.bounds().width() - kTouchPointViewOffset -
- touch_point_view_->width(),
- touch_point_view_->y()));
- hint_box_view_->SetVisible(false);
- return;
- case DISPLAY_POINT_2:
- state_ = ANIMATING_2_TO_3;
- // The touch point has to be animated from the top right corner of the
- // screen to the bottom left corner.
- AnimateLayerToPosition(
- touch_point_view_, kPointMoveDurationLong,
- gfx::Point(kTouchPointViewOffset, display_.bounds().height() -
- kTouchPointViewOffset -
- touch_point_view_->height()));
- return;
- case DISPLAY_POINT_3:
- state_ = ANIMATING_3_TO_4;
- // The touch point has to be animated from the bottom left corner of the
- // screen to the bottom right corner.
- AnimateLayerToPosition(
- touch_point_view_, kPointMoveDuration,
- gfx::Point(display_.bounds().width() - kTouchPointViewOffset -
- touch_point_view_->width(),
- touch_point_view_->y()));
- return;
- case DISPLAY_POINT_4:
- state_ = ANIMATING_FINAL_MESSAGE;
- completion_message_view_->layer()->SetOpacity(0.0f);
- completion_message_view_->SetVisible(true);
- touch_point_view_->SetVisible(false);
- AnimateLayerToPosition(completion_message_view_,
- kFinalMessageTransitionDuration,
- gfx::Point(completion_message_view_->x(),
- display_.bounds().height() / 2));
- return;
- case CALIBRATION_COMPLETE:
- state_ = BACKGROUND_FADING_OUT;
- if (is_primary_view_) {
- // In case of primary view, we also need to fade out the calibration
- // complete message view.
- AnimateLayerToPosition(
- completion_message_view_, kFadeDuration,
- gfx::Point(completion_message_view_->x(),
- completion_message_view_->y() +
- 2 * completion_message_view_->height()),
- 0.0f);
- }
- start_opacity_value_ = kBackgroundFinalOpacity;
- end_opacity_value_ = 0.0f;
- flags_.setStyle(cc::PaintFlags::kFill_Style);
- animator_->SetDuration(kFadeDuration);
- animator_->Start();
- return;
- default:
- return;
- }
- }
- bool TouchCalibratorView::GetDisplayPointLocation(gfx::Point* location) {
- DCHECK(location);
- if (!is_primary_view_)
- return false;
- if (state_ != DISPLAY_POINT_1 && state_ != DISPLAY_POINT_2 &&
- state_ != DISPLAY_POINT_3 && state_ != DISPLAY_POINT_4) {
- return false;
- }
- if (!touch_point_view_ || !throbber_circle_)
- return false;
- // TODO(malaykeshav): Can use views::ConvertPointToScreen()
- location->SetPoint(touch_point_view_->x() + touch_point_view_->width() / 2.f,
- touch_point_view_->y() + touch_point_view_->width() / 2.f);
- return true;
- }
- void TouchCalibratorView::SkipToFinalState() {
- state_ = CALIBRATION_COMPLETE;
- exit_label_->SetVisible(false);
- if (is_primary_view_) {
- touch_point_view_->SetVisible(false);
- hint_box_view_->SetVisible(false);
- }
- AdvanceToNextState();
- }
- void TouchCalibratorView::SkipCurrentAnimation() {
- if (animator_->is_animating())
- animator_->End();
- if (touch_point_view_ &&
- touch_point_view_->layer()->GetAnimator()->is_animating()) {
- touch_point_view_->layer()->GetAnimator()->StopAnimating();
- }
- }
- } // namespace ash
|