| Index: ash/common/system/chromeos/palette/tools/laser_pointer_view.cc
|
| diff --git a/ash/common/system/chromeos/palette/tools/laser_pointer_view.cc b/ash/common/system/chromeos/palette/tools/laser_pointer_view.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e4ea524e1351abe0830eb646be176f52e2028b92
|
| --- /dev/null
|
| +++ b/ash/common/system/chromeos/palette/tools/laser_pointer_view.cc
|
| @@ -0,0 +1,153 @@
|
| +// 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/common/system/chromeos/palette/tools/laser_pointer_view.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "ash/common/shell_window_ids.h"
|
| +#include "ash/common/wm_root_window_controller.h"
|
| +#include "ash/common/wm_shell.h"
|
| +#include "ash/common/wm_window.h"
|
| +#include "third_party/skia/include/core/SkColor.h"
|
| +#include "third_party/skia/include/core/SkPaint.h"
|
| +#include "third_party/skia/include/core/SkRect.h"
|
| +#include "ui/compositor/layer.h"
|
| +#include "ui/gfx/canvas.h"
|
| +#include "ui/gfx/transform.h"
|
| +#include "ui/wm/core/coordinate_conversion.h"
|
| +
|
| +namespace ash {
|
| +namespace {
|
| +
|
| +const double kMouselaserUiStartRadius = 4;
|
| +const double kMouselaserUiEndRadius = 0.25;
|
| +const int kMouselaserUiStartOpacityValue = 200;
|
| +const int kMouselaserUiEndOpacityValue = 0;
|
| +
|
| +views::Widget* CreateLaserPointerWidget() {
|
| + views::Widget* widget = new views::Widget;
|
| + views::Widget::InitParams params;
|
| + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
|
| + params.name = "LaserOverlay";
|
| + params.accept_events = false;
|
| + params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
|
| + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
|
| + WmShell::Get()
|
| + ->GetRootWindowForNewWindows()
|
| + ->GetRootWindowController()
|
| + ->ConfigureWidgetInitParamsForContainer(
|
| + widget, kShellWindowId_OverlayContainer, ¶ms);
|
| +
|
| + widget->Init(params);
|
| + widget->SetOpacity(1.f);
|
| + return widget;
|
| +}
|
| +
|
| +float DistanceBetweenPoints(const gfx::Point& point1,
|
| + const gfx::Point& point2) {
|
| + float deltaX = point1.x() - point2.x();
|
| + float deltaY = point1.y() - point2.y();
|
| + return deltaX * deltaX + deltaY * deltaY;
|
| +}
|
| +
|
| +void PaintLaser(gfx::Canvas* canvas,
|
| + const LaserPointerPoints& points,
|
| + const gfx::Rect& widget_bounds) {
|
| + SkPaint paint;
|
| + paint.setStyle(SkPaint::kStroke_Style);
|
| + paint.setAntiAlias(true);
|
| + paint.setStrokeJoin(SkPaint::kBevel_Join);
|
| + SkColor paintColor;
|
| +
|
| + if (!points.IsEmpty()) {
|
| + base::Time oldest = points.GetOldest().creationTime_;
|
| + base::Time most_recent = points.GetMostRecent().creationTime_;
|
| + gfx::Point last_point, current_point;
|
| + int point_count = 0;
|
| + int num_points = points.GetNumberOfPoints();
|
| + for (auto it = points.PointsStart(); it != points.PointsEnd();
|
| + it++, point_count++) {
|
| + float normalized;
|
| + // Only one point, the regular normalization will return undefined for
|
| + // this case.
|
| + if (oldest == most_recent)
|
| + normalized = 1.0;
|
| + else { // Normalize the distance.
|
| + normalized = float{(it->creationTime_ - oldest).InMillisecondsF()} /
|
| + float{(most_recent - oldest).InMillisecondsF()};
|
| + normalized = 1.0 - normalized;
|
| + }
|
| +
|
| + float radius =
|
| + float{kMouselaserUiStartRadius} -
|
| + normalized * float{kMouselaserUiStartRadius - kMouselaserUiEndRadius};
|
| + int opacity = kMouselaserUiStartOpacityValue -
|
| + int{normalized * float{kMouselaserUiStartOpacityValue -
|
| + kMouselaserUiEndOpacityValue}};
|
| + gfx::Vector2d center = it->location_ - widget_bounds.origin();
|
| + current_point = gfx::Point(center.x(), center.y());
|
| + paintColor = SkColorSetARGB(opacity, 255, 0, 0);
|
| + paint.setColor(paintColor);
|
| + paint.setStrokeWidth(radius * 2);
|
| + if (point_count == 0) {
|
| + last_point = current_point;
|
| + } else if (DistanceBetweenPoints(last_point, current_point) >
|
| + radius * 4 * radius) {
|
| + canvas->DrawLine(last_point, current_point, paint);
|
| + last_point = current_point;
|
| + } else if (point_count == num_points - 1) {
|
| + canvas->DrawLine(last_point, current_point, paint);
|
| + }
|
| + }
|
| + paintColor = SkColorSetARGB(kMouselaserUiStartOpacityValue, 255, 0, 0);
|
| + paint.setColor(paintColor);
|
| + paint.setStyle(SkPaint::kFill_Style);
|
| + canvas->DrawCircle(current_point, kMouselaserUiStartRadius, paint);
|
| + }
|
| +}
|
| +} // namespace
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +// LaserPointerView
|
| +LaserPointerView::LaserPointerView()
|
| + : views::View(), laser_points_(base::TimeDelta()) {
|
| + gfx::Rect newBoundingBox;
|
| + newBoundingBox.SetRect(0, 0, 1388, 768);
|
| + widget_.reset(CreateLaserPointerWidget());
|
| + widget_->SetBounds(newBoundingBox);
|
| + widget_->Show();
|
| + widget_->SetContentsView(this);
|
| +}
|
| +
|
| +LaserPointerView::~LaserPointerView() {
|
| + Stop();
|
| +}
|
| +
|
| +void LaserPointerView::Stop() {
|
| + laser_points_.Clear();
|
| + SetNewPoints(laser_points_);
|
| +}
|
| +
|
| +void LaserPointerView::SetNewPoints(const LaserPointerPoints& laser_points) {
|
| + laser_points_ = laser_points;
|
| + gfx::Rect oldBoundingBox, newBoundingBox;
|
| + oldBoundingBox = laser_points.GetBoundingBox();
|
| + newBoundingBox.SetRect(
|
| + oldBoundingBox.x() - kMouselaserUiStartRadius,
|
| + oldBoundingBox.y() - kMouselaserUiStartRadius,
|
| + oldBoundingBox.width() + 2 * kMouselaserUiStartRadius,
|
| + oldBoundingBox.height() + 2 * kMouselaserUiStartRadius);
|
| + widget_->SetBounds(newBoundingBox);
|
| + SchedulePaint();
|
| +}
|
| +
|
| +void LaserPointerView::OnPaint(gfx::Canvas* canvas) {
|
| + canvas->Save();
|
| + PaintLaser(canvas, laser_points_, widget_->GetWindowBoundsInScreen());
|
| + canvas->Restore();
|
| +}
|
| +} // namespace ash
|
|
|