OLD | NEW |
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 "ash/laser/laser_pointer_view.h" | 5 #include "ash/laser/laser_pointer_view.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "ash/common/shell_window_ids.h" | 9 #include "ash/common/shell_window_ids.h" |
10 #include "ash/laser/laser_pointer_points.h" | 10 #include "ash/laser/laser_pointer_points.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 // points) or keep the old points. See http://crbug.com/647793. | 80 // points) or keep the old points. See http://crbug.com/647793. |
81 Stop(); | 81 Stop(); |
82 views::Widget::ReparentNativeView( | 82 views::Widget::ReparentNativeView( |
83 widget_->GetNativeView(), | 83 widget_->GetNativeView(), |
84 Shell::GetContainer(new_root_window, kShellWindowId_OverlayContainer)); | 84 Shell::GetContainer(new_root_window, kShellWindowId_OverlayContainer)); |
85 } | 85 } |
86 } | 86 } |
87 | 87 |
88 void LaserPointerView::AddNewPoint(const gfx::Point& new_point) { | 88 void LaserPointerView::AddNewPoint(const gfx::Point& new_point) { |
89 laser_points_.AddPoint(new_point); | 89 laser_points_.AddPoint(new_point); |
| 90 OnPointsUpdated(); |
| 91 } |
90 | 92 |
| 93 void LaserPointerView::UpdateTime() { |
| 94 // Do not add the point but advance the time if the view is in process of |
| 95 // fading away. |
| 96 laser_points_.MoveForwardToTime(base::Time::Now()); |
| 97 OnPointsUpdated(); |
| 98 } |
| 99 |
| 100 void LaserPointerView::OnPointsUpdated() { |
91 // The bounding box should be relative to the screen. | 101 // The bounding box should be relative to the screen. |
92 gfx::Point screen_offset = | 102 gfx::Point screen_offset = |
93 widget_->GetNativeView()->GetRootWindow()->GetBoundsInScreen().origin(); | 103 widget_->GetNativeView()->GetRootWindow()->GetBoundsInScreen().origin(); |
94 | 104 |
95 // Expand the bounding box so that it includes the radius of the points on the | 105 // Expand the bounding box so that it includes the radius of the points on the |
96 // edges. | 106 // edges. |
97 gfx::Rect bounding_box; | 107 gfx::Rect bounding_box; |
98 bounding_box = laser_points_.GetBoundingBox(); | 108 bounding_box = laser_points_.GetBoundingBox(); |
99 bounding_box.Offset(-kPointInitialRadius, -kPointInitialRadius); | 109 bounding_box.Offset(-kPointInitialRadius, -kPointInitialRadius); |
100 bounding_box.Offset(screen_offset.x(), screen_offset.y()); | 110 bounding_box.Offset(screen_offset.x(), screen_offset.y()); |
101 bounding_box.set_width(bounding_box.width() + (kPointInitialRadius * 2)); | 111 bounding_box.set_width(bounding_box.width() + (kPointInitialRadius * 2)); |
102 bounding_box.set_height(bounding_box.height() + (kPointInitialRadius * 2)); | 112 bounding_box.set_height(bounding_box.height() + (kPointInitialRadius * 2)); |
103 widget_->SetBounds(bounding_box); | 113 widget_->SetBounds(bounding_box); |
104 SchedulePaint(); | 114 SchedulePaint(); |
105 } | 115 } |
106 | 116 |
107 void LaserPointerView::OnPaint(gfx::Canvas* canvas) { | 117 void LaserPointerView::OnPaint(gfx::Canvas* canvas) { |
108 if (laser_points_.IsEmpty()) | 118 if (laser_points_.IsEmpty()) |
109 return; | 119 return; |
110 | 120 |
111 SkPaint paint; | 121 SkPaint paint; |
112 paint.setStyle(SkPaint::kStroke_Style); | 122 paint.setStyle(SkPaint::kStroke_Style); |
113 paint.setAntiAlias(true); | 123 paint.setAntiAlias(true); |
114 paint.setStrokeJoin(SkPaint::kBevel_Join); | 124 paint.setStrokeJoin(SkPaint::kBevel_Join); |
115 | 125 |
116 base::Time oldest = laser_points_.GetOldest().creation_time; | |
117 base::Time newest = laser_points_.GetNewest().creation_time; | |
118 gfx::Point previous_point = laser_points_.GetOldest().location; | |
119 gfx::Point current_point; | |
120 | |
121 // Compute the offset of the current widget. | 126 // Compute the offset of the current widget. |
122 gfx::Point widget_offset = | 127 gfx::Point widget_offset = |
123 widget_->GetNativeView()->GetBoundsInRootWindow().origin(); | 128 widget_->GetNativeView()->GetBoundsInRootWindow().origin(); |
| 129 |
| 130 gfx::Point previous_point( |
| 131 (laser_points_.GetOldest().location - widget_offset).x(), |
| 132 (laser_points_.GetOldest().location - widget_offset).y()); |
| 133 gfx::Point current_point; |
| 134 |
124 int num_points_ = laser_points_.GetNumberOfPoints(); | 135 int num_points_ = laser_points_.GetNumberOfPoints(); |
125 int point_count = 0; | 136 int point_count = 0; |
| 137 int current_opacity = 0; |
126 for (const LaserPointerPoints::LaserPoint& point : | 138 for (const LaserPointerPoints::LaserPoint& point : |
127 laser_points_.laser_points()) { | 139 laser_points_.laser_points()) { |
128 // relative_time is a value between [0,1] where 0 means the point is about | |
129 // to be removed and 1 means that the point was just added. | |
130 double relative_time = 1.0; | |
131 if (oldest != newest) { | |
132 relative_time = 1.0 - ((point.creation_time - oldest).InMillisecondsF() / | |
133 (newest - oldest).InMillisecondsF()); | |
134 } | |
135 | |
136 // Set the radius and opacity based on the distance. | 140 // Set the radius and opacity based on the distance. |
137 double radius = LinearInterpolate(kPointInitialRadius, kPointFinalRadius, | 141 double current_radius = |
138 relative_time); | 142 LinearInterpolate(kPointInitialRadius, kPointFinalRadius, point.age); |
| 143 current_opacity = int{LinearInterpolate( |
| 144 double{kPointInitialOpacity}, double{kPointFinalOpacity}, point.age)}; |
139 | 145 |
140 gfx::Vector2d center = point.location - widget_offset; | 146 gfx::Vector2d center = point.location - widget_offset; |
141 current_point = gfx::Point(center.x(), center.y()); | 147 current_point = gfx::Point(center.x(), center.y()); |
142 | 148 |
143 // If we draw laser_points_ that are within a stroke width of each other, | 149 // If we draw laser_points_ that are within a stroke width of each other, |
144 // the result will be very jagged, unless we are on the last point, then we | 150 // the result will be very jagged, unless we are on the last point, then we |
145 // draw regardless. | 151 // draw regardless. |
146 point_count++; | 152 point_count++; |
147 float distance_threshold = float{radius * 2}; | 153 float distance_threshold = float{current_radius * 2}; |
148 if (DistanceBetweenPoints(previous_point, current_point) <= | 154 if (DistanceBetweenPoints(previous_point, current_point) <= |
149 distance_threshold && | 155 distance_threshold && |
150 point_count != num_points_) { | 156 point_count != num_points_) { |
151 continue; | 157 continue; |
152 } | 158 } |
153 | 159 |
154 int opacity = | 160 paint.setColor(SkColorSetA(kPointColor, current_opacity)); |
155 int{LinearInterpolate(double{kPointInitialOpacity}, | 161 paint.setStrokeWidth(current_radius * 2); |
156 double{kPointFinalOpacity}, relative_time)}; | |
157 paint.setColor(SkColorSetA(kPointColor, opacity)); | |
158 paint.setStrokeWidth(radius * 2); | |
159 canvas->DrawLine(previous_point, current_point, paint); | 162 canvas->DrawLine(previous_point, current_point, paint); |
160 previous_point = current_point; | 163 previous_point = current_point; |
161 } | 164 } |
162 // Draw the last point as a circle. | 165 // Draw the last point as a circle. |
163 paint.setColor(SkColorSetA(kPointColor, kPointInitialOpacity)); | 166 paint.setColor(SkColorSetA(kPointColor, current_opacity)); |
164 paint.setStyle(SkPaint::kFill_Style); | 167 paint.setStyle(SkPaint::kFill_Style); |
165 canvas->DrawCircle(current_point, kPointInitialRadius, paint); | 168 canvas->DrawCircle(current_point, kPointInitialRadius, paint); |
166 } | 169 } |
167 } // namespace ash | 170 } // namespace ash |
OLD | NEW |