blob: 02fa8978a533ccd27712627a12b9e804ff7a358f [file] [log] [blame]
// Copyright 2019 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/autoclick/autoclick_scroll_position_handler.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/animation/linear_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/transform.h"
#include "ui/views/view.h"
namespace ash {
namespace {
constexpr int kScrollBackgroundSizeInDips = 32;
constexpr int kScrollIconSizeInDips = 24;
constexpr SkColor kIconBackgroundColor = SkColorSetARGB(255, 128, 134, 139);
constexpr base::TimeDelta kAnimationTime =
base::TimeDelta::FromMilliseconds(500);
constexpr float kFadedOpacity = 0.5;
} // namespace
// View of the AutoclickScrollPositionHandler. Draws the actual contents and
// maintains the views::Widget that the animation is shown in.
class AutoclickScrollPositionView : public views::View {
public:
AutoclickScrollPositionView(const gfx::Point& event_location,
views::Widget* widget)
: views::View(), widget_(widget) {
image_ = gfx::CreateVectorIcon(kAutoclickScrollIcon, kScrollIconSizeInDips,
SK_ColorWHITE);
widget_->SetContentsView(this);
SetSize(
gfx::Size(kScrollBackgroundSizeInDips, kScrollBackgroundSizeInDips));
// Owned by the AutoclickScrollPositionHandler.
set_owned_by_client();
SetLocation(event_location);
}
~AutoclickScrollPositionView() override = default;
void SetLocation(const gfx::Point& new_event_location) {
gfx::Point point = new_event_location;
widget_->SetBounds(gfx::Rect(point.x() - kScrollBackgroundSizeInDips / 2,
point.y() - kScrollBackgroundSizeInDips / 2,
kScrollBackgroundSizeInDips,
kScrollBackgroundSizeInDips));
widget_->Show();
widget_->SetOpacity(1.0);
SchedulePaint();
}
void UpdateForAnimationStep(gfx::Animation* animation) {
widget_->SetOpacity(animation->CurrentValueBetween(1.0, kFadedOpacity));
}
private:
void OnPaint(gfx::Canvas* canvas) override {
gfx::Point center(kScrollBackgroundSizeInDips / 2,
kScrollBackgroundSizeInDips / 2);
canvas->Save();
cc::PaintFlags flags;
flags.setAntiAlias(true);
// Draw the grey background.
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(kIconBackgroundColor);
canvas->DrawCircle(center, kScrollBackgroundSizeInDips / 2, flags);
// Draw the icon on top.
canvas->DrawImageInt(image_, center.x() - kScrollIconSizeInDips / 2,
center.y() - kScrollIconSizeInDips / 2);
canvas->Restore();
}
views::Widget* widget_;
gfx::ImageSkia image_;
DISALLOW_COPY_AND_ASSIGN(AutoclickScrollPositionView);
};
AutoclickScrollPositionHandler::AutoclickScrollPositionHandler(
const gfx::Point& center_point_in_screen,
views::Widget* widget)
: gfx::LinearAnimation(nullptr) {
view_ = std::make_unique<AutoclickScrollPositionView>(center_point_in_screen,
widget);
SetDuration(kAnimationTime);
animation_state_ = AnimationState::kWait;
Start();
}
AutoclickScrollPositionHandler::~AutoclickScrollPositionHandler() {
view_.reset();
}
void AutoclickScrollPositionHandler::SetCenter(
const gfx::Point& center_point_in_screen,
views::Widget* widget) {
view_->SetLocation(center_point_in_screen);
animation_state_ = AnimationState::kWait;
Start();
}
void AutoclickScrollPositionHandler::AnimateToState(double state) {
if (animation_state_ == AnimationState::kFade)
view_->UpdateForAnimationStep(this);
}
void AutoclickScrollPositionHandler::AnimationStopped() {
if (animation_state_ == AnimationState::kWait) {
animation_state_ = AnimationState::kFade;
Start();
} else if (animation_state_ == AnimationState::kFade) {
animation_state_ = AnimationState::kDone;
}
}
} // namespace ash