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

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

Powered by Google App Engine
This is Rietveld 408576698