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

Side by Side Diff: ash/magnifier/magnification_controller.cc

Issue 10388141: Full-screen Magnifier: Support warping the cursor on the edge (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Make MagnificationController virtual class. Created 8 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/magnifier/magnification_controller.h" 5 #include "ash/magnifier/magnification_controller.h"
6 6
7 #include "ash/magnifier/magnified_cursor.h"
7 #include "ash/shell.h" 8 #include "ash/shell.h"
9 #include "ui/aura/event.h"
8 #include "ui/aura/root_window.h" 10 #include "ui/aura/root_window.h"
9 #include "ui/aura/window.h" 11 #include "ui/aura/window.h"
10 #include "ui/aura/window_property.h" 12 #include "ui/aura/window_property.h"
13 #include "ui/compositor/dip_util.h"
11 #include "ui/compositor/layer.h" 14 #include "ui/compositor/layer.h"
12 #include "ui/compositor/scoped_layer_animation_settings.h" 15 #include "ui/compositor/scoped_layer_animation_settings.h"
13 16
14 namespace { 17 namespace {
15 18
16 const float kMaximumMagnifiScale = 4.0f; 19 const float kMaximumMagnifiScale = 4.0f;
17 const float kMaximumMagnifiScaleThreshold = 4.0f; 20 const float kMaximumMagnifiScaleThreshold = 4.0f;
18 const float kMinimumMagnifiScale = 1.0f; 21 const float kMinimumMagnifiScale = 1.0f;
19 const float kMinimumMagnifiScaleThreshold = 1.1f; 22 const float kMinimumMagnifiScaleThreshold = 1.1f;
20 23
21 } // namespace 24 } // namespace
22 25
23 namespace ash { 26 namespace ash {
24 namespace internal { 27 namespace internal {
25 28
26 MagnificationController::MagnificationController() 29 ////////////////////////////////////////////////////////////////////////////////
30 // MagnificationControllerImpl:
31
32 class MagnificationControllerImpl : virtual public MagnificationController {
33 public:
34 MagnificationControllerImpl();
35 virtual ~MagnificationControllerImpl() {}
36
37 // MagnificationController overrides:
38 void SetScale(float scale, bool animation);
39 float GetScale() const { return scale_; }
40 void MoveWindow(int x, int y, bool animation);
41 void MoveWindow(const gfx::Point& point, bool animation);
42 gfx::Point GetWindowPosition() const { return gfx::Point(x_, y_); }
43 void EnsureShowRect(const gfx::Rect& rect, bool animation);
44 void EnsureShowPoint(const gfx::Point& point, bool animation);
45
46 private:
47 aura::RootWindow* root_window_;
48
49 // Current scale, position of the magnification window.
50 float scale_;
51 int x_;
52 int y_;
53
54 scoped_ptr<MagnifiedCursor> cursor_;
55
56 // should be called internally just after the scale and/or the position are
57 // changed.
58 void Redraw(const gfx::Point& position, float scale, bool animation);
59 void RedrawDPI(const gfx::Point& position, float scale, bool animation);
60
61 // Ensures that the given point, rect or last mouse location is inside
62 // magnification window. If not, the controller moves the window to contain
63 // the given point/rect.
64 void EnsureShowRectWithScale(
65 const gfx::Rect& target_rect, float scale, bool animation);
66 void EnsureShowRectDPI(
67 const gfx::Rect& target_rect_in_dpi, float scale, bool animation);
68 void EnsureShowPointWithScale(
69 const gfx::Point& point, float scale, bool animation);
70 void EnsureShowLastMouseLocation(float scale, bool animation);
71
72 // Returns if the magnification scale is 1.0 or not (larger then 1.0).
73 bool IsMagnified() const;
74
75 // Returns the rect of the magnification window.
76 gfx::Rect GetWindowRect(float scale) const;
77
78 void OnStartMagnification();
79 void OnStopMagnification();
80
81 // Correct the givin scale value if nessesary.
82 void CorrectScale(float* scale);
83
84 // aura::EventFilter overrides:
85 virtual bool PreHandleKeyEvent(aura::Window* target,
86 aura::KeyEvent* event) OVERRIDE;
87 virtual bool PreHandleMouseEvent(aura::Window* target,
88 aura::MouseEvent* event) OVERRIDE;
89 virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target,
90 aura::TouchEvent* event) OVERRIDE;
91 virtual ui::GestureStatus PreHandleGestureEvent(
92 aura::Window* target,
93 aura::GestureEvent* event) OVERRIDE;
94
95 DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl);
96 };
97
98 ////////////////////////////////////////////////////////////////////////////////
99 // MagnificationControllerImpl:
100
101 MagnificationControllerImpl::MagnificationControllerImpl()
27 : scale_(1.0f), x_(0), y_(0) { 102 : scale_(1.0f), x_(0), y_(0) {
28 root_window_ = ash::Shell::GetRootWindow(); 103 root_window_ = ash::Shell::GetRootWindow();
29 } 104 cursor_.reset(new MagnifiedCursor(root_window_));
30 105
31 void MagnificationController::SetScale(float scale) { 106 root_window_->magnification_layer()->Add(cursor_->layer());
107 root_window_->magnification_layer()->StackAtTop(cursor_->layer());
108 }
109
110 void MagnificationControllerImpl::Redraw(
111 const gfx::Point& position, float scale, bool animation) {
112 const gfx::Point position_in_dpi =
113 ui::ConvertPointToDIP(root_window_->magnification_layer(), position);
114 RedrawDPI(position_in_dpi, scale, animation);
115 }
116
117 void MagnificationControllerImpl::RedrawDPI(
118 const gfx::Point& position_in_dpi, float scale, bool animation) {
119 int x = position_in_dpi.x();
120 int y = position_in_dpi.y();
121
122 CorrectScale(&scale);
123
124 if (scale_ == kMinimumMagnifiScale && scale != kMinimumMagnifiScale)
125 OnStartMagnification();
126 else if (scale_ != kMinimumMagnifiScale && scale == kMinimumMagnifiScale)
127 OnStopMagnification();
128
32 scale_ = scale; 129 scale_ = scale;
33 RedrawScreen(true); 130
34 } 131 if (x < 0)
35 132 x = 0;
36 void MagnificationController::MoveWindow(int x, int y) { 133 if (y < 0)
134 y = 0;
135
136 const gfx::Size host_size_in_dip =
137 ui::ConvertSizeToDIP(root_window_->magnification_layer(),
138 root_window_->GetHostSize());
139 const gfx::Size window_size_in_dip = GetWindowRect(scale).size();
140 int max_x = host_size_in_dip.width() - window_size_in_dip.width();
141 int max_y = host_size_in_dip.height() - window_size_in_dip.height();
142 if (x > max_x)
143 x = max_x;
144 if (y > max_y)
145 y = max_y;
146
147 x_ = x;
37 y_ = y; 148 y_ = y;
38 x_ = x;
39 RedrawScreen(true);
40 }
41
42 void MagnificationController::MoveWindow(const gfx::Point& point) {
43 MoveWindow(point.x(), point.y());
44 }
45
46 void MagnificationController::EnsureShowRect(const gfx::Rect& target_rect) {
47 gfx::Rect rect = GetWindowRect().AdjustToFit(target_rect);
48 MoveWindow(rect.x(), rect.y());
49 }
50
51 void MagnificationController::EnsureShowPoint(const gfx::Point& point,
52 bool animation) {
53 gfx::Rect rect = GetWindowRect();
54
55 if (rect.Contains(point))
56 return;
57
58 if (point.x() < rect.x())
59 x_ = point.x();
60 else if(rect.right() < point.x())
61 x_ = point.x() - rect.width();
62
63 if (point.y() < rect.y())
64 y_ = point.y();
65 else if(rect.bottom() < point.y())
66 y_ = point.y() - rect.height();
67
68 RedrawScreen(animation);
69 }
70
71 void MagnificationController::RedrawScreen(bool animation) {
72
73 // Adjust the scale to just |kMinimumMagnifiScale| if scale is smaller than
74 // |kMinimumMagnifiScaleThreshold|;
75 if (scale_ < kMinimumMagnifiScaleThreshold)
76 scale_ = kMinimumMagnifiScale;
77 // Adjust the scale to just |kMinimumMagnifiScale| if scale is bigger than
78 // |kMinimumMagnifiScaleThreshold|;
79 if (scale_ > kMaximumMagnifiScaleThreshold)
80 scale_ = kMaximumMagnifiScale;
81
82 if (x_ < 0)
83 x_ = 0;
84 if (y_ < 0)
85 y_ = 0;
86
87 gfx::Size host_size = root_window_->GetHostSize();
88 gfx::Size window_size = GetWindowRect().size();
89 int max_x = host_size.width() - window_size.width();
90 int max_y = host_size.height() - window_size.height();
91 if (x_ > max_x)
92 x_ = max_x;
93 if (y_ > max_y)
94 y_ = max_y;
95
96
97 float scale = scale_;
98 int x = x_;
99 int y = y_;
100 149
101 // Creates transform matrix. 150 // Creates transform matrix.
102 ui::Transform transform; 151 ui::Transform transform;
103 // Flips the signs intentionally to convert them from the position of the 152 // Flips the signs intentionally to convert them from the position of the
104 // magnification window. 153 // magnification window.
105 transform.ConcatTranslate(-x, -y); 154 transform.ConcatTranslate(-x_, -y_);
106 transform.ConcatScale(scale, scale); 155 transform.ConcatScale(scale_, scale_);
107 156
108 if (animation) { 157 ui::ScopedLayerAnimationSettings settings(
109 ui::ScopedLayerAnimationSettings settings( 158 root_window_->magnification_layer()->GetAnimator());
110 root_window_->layer()->GetAnimator()); 159 settings.SetPreemptionStrategy(
111 settings.SetPreemptionStrategy( 160 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
112 ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); 161 settings.SetTweenType(ui::Tween::EASE_IN_OUT);
113 settings.SetTweenType(ui::Tween::EASE_IN_OUT); 162 settings.SetTransitionDuration(
114 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100)); 163 base::TimeDelta::FromMilliseconds(animation ? 100 : 0));
164
165 root_window_->magnification_layer()->SetTransform(transform);
166 }
167
168 void MagnificationControllerImpl::EnsureShowRectWithScale(
169 const gfx::Rect& target_rect, float scale, bool animation) {
170 const gfx::Rect target_rect_in_dip =
171 ui::ConvertRectToDIP(root_window_->magnification_layer(), target_rect);
172 EnsureShowRectDPI(target_rect_in_dip, scale, animation);
173 }
174
175 void MagnificationControllerImpl::EnsureShowRectDPI(
176 const gfx::Rect& target_rect, float scale, bool animation) {
177 CorrectScale(&scale);
178
179 const gfx::Rect window_rect = GetWindowRect(scale);
180 if (scale == scale_ && window_rect.Contains(target_rect))
181 return;
182
183 gfx::Rect rect = window_rect;
184 if (target_rect.width() > rect.width())
185 rect.set_x(target_rect.CenterPoint().x() - rect.x() / 2);
186 else if (target_rect.right() < rect.x())
187 rect.set_x(target_rect.right());
188 else if (rect.right() < target_rect.x())
189 rect.set_x(target_rect.x() - rect.width());
190
191 if (rect.height() > window_rect.height())
192 rect.set_y(target_rect.CenterPoint().y() - rect.y() / 2);
193 else if (target_rect.bottom() < rect.y())
194 rect.set_y(target_rect.bottom());
195 else if (rect.bottom() < target_rect.y())
196 rect.set_y(target_rect.y() - rect.height());
197
198 RedrawDPI(rect.origin(), scale, animation);
199 }
200
201 void MagnificationControllerImpl::EnsureShowPointWithScale(
202 const gfx::Point& point, float scale, bool animation) {
203 EnsureShowRectWithScale(gfx::Rect(point, gfx::Size(0, 0)), scale, animation);
204 }
205
206 void MagnificationControllerImpl::EnsureShowLastMouseLocation(
207 float scale, bool animation) {
208 EnsureShowRectDPI(
209 gfx::Rect(root_window_->last_mouse_location(), gfx::Size(0, 0)),
210 scale, animation);
211 }
212
213 gfx::Rect MagnificationControllerImpl::GetWindowRect(float scale) const {
214 const gfx::Size size_in_dip =
215 ui::ConvertSizeToDIP(root_window_->magnification_layer(),
216 root_window_->GetHostSize());
217 const int width = size_in_dip.width() / scale;
218 const int height = size_in_dip.height() / scale;
219
220 return gfx::Rect(x_, y_, width, height);
221 }
222
223 bool MagnificationControllerImpl::IsMagnified() const {
224 return scale_ >= kMinimumMagnifiScaleThreshold;
225 }
226
227 void MagnificationControllerImpl::OnStartMagnification() {
228 cursor_->SetVisible(true);
229 root_window_->SetForceHideCursor(true);
230 root_window_->ShowCursor(false);
231 cursor_->MovePointer(root_window_->last_mouse_location());
232 }
233
234 void MagnificationControllerImpl::OnStopMagnification() {
235 cursor_->SetVisible(false);
236 root_window_->SetForceHideCursor(false);
237 root_window_->ShowCursor(true);
238 }
239
240 void MagnificationControllerImpl::CorrectScale(float* scale) {
241 // Adjust the scale to just |kMinimumMagnifiScale| if scale is smaller than
242 // |kMinimumMagnifiScaleThreshold|;
243 if (*scale < kMinimumMagnifiScaleThreshold)
244 *scale = kMinimumMagnifiScale;
245
246 // Adjust the scale to just |kMinimumMagnifiScale| if scale is bigger than
247 // |kMinimumMagnifiScaleThreshold|;
248 if (*scale > kMaximumMagnifiScaleThreshold)
249 *scale = kMaximumMagnifiScale;
250 }
251
252 ////////////////////////////////////////////////////////////////////////////////
253 // MagnificationControllerImpl: MagnificationController implementation
254
255 void MagnificationControllerImpl::SetScale(float scale, bool animation) {
256 EnsureShowLastMouseLocation(scale, animation);
257 }
258
259 void MagnificationControllerImpl::MoveWindow(int x, int y, bool animation) {
260 Redraw(gfx::Point(x, y), scale_, animation);
261 }
262
263 void MagnificationControllerImpl::MoveWindow(
264 const gfx::Point& point, bool animation) {
265 Redraw(point, scale_, animation);
266 }
267
268 void MagnificationControllerImpl::EnsureShowRect(
269 const gfx::Rect& target_rect, bool animation) {
270 EnsureShowRectWithScale(target_rect, scale_, animation);
271 }
272
273 void MagnificationControllerImpl::EnsureShowPoint(
274 const gfx::Point& point, bool animation) {
275 EnsureShowPointWithScale(point, scale_, animation);
276 }
277
278 ////////////////////////////////////////////////////////////////////////////////
279 // MagnificationControllerImpl: aura::EventFilter implementation
280
281 bool MagnificationControllerImpl::PreHandleKeyEvent(
282 aura::Window* target, aura::KeyEvent* event) {
283 return false;
284 }
285
286 bool MagnificationControllerImpl::PreHandleMouseEvent(
287 aura::Window* target, aura::MouseEvent* event) {
288 if (IsMagnified()) {
289 EnsureShowLastMouseLocation(scale_, false);
290 cursor_->MovePointer(root_window_->last_mouse_location());
115 } 291 }
116 292 return false;
117 root_window_->layer()->SetTransform(transform); 293 }
118 } 294
119 295 ui::TouchStatus MagnificationControllerImpl::PreHandleTouchEvent(
120 gfx::Rect MagnificationController::GetWindowRect() { 296 aura::Window* target, aura::TouchEvent* event) {
121 gfx::Size size = root_window_->GetHostSize(); 297 return ui::TOUCH_STATUS_UNKNOWN;
122 int width = size.width() / scale_; 298 }
123 int height = size.height() / scale_; 299
124 300 ui::GestureStatus MagnificationControllerImpl::PreHandleGestureEvent(
125 return gfx::Rect(x_, y_, width, height); 301 aura::Window* target,
302 aura::GestureEvent* event) {
303 return ui::GESTURE_STATUS_UNKNOWN;
304 }
305
306 ////////////////////////////////////////////////////////////////////////////////
307 // MagnificationController:
308
309 // static
310 MagnificationController* MagnificationController::CreateInstance() {
311 return new MagnificationControllerImpl();
126 } 312 }
127 313
128 } // namespace internal 314 } // namespace internal
129 } // namespace ash 315 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698