OLD | NEW |
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/accelerators/accelerator_controller.h" | 7 #include "ash/accelerators/accelerator_controller.h" |
8 #include "ash/accessibility_delegate.h" | 8 #include "ash/accessibility_delegate.h" |
9 #include "ash/ash_switches.h" | 9 #include "ash/ash_switches.h" |
10 #include "ash/display/root_window_transformers.h" | 10 #include "ash/display/root_window_transformers.h" |
11 #include "ash/host/ash_window_tree_host.h" | 11 #include "ash/host/ash_window_tree_host.h" |
12 #include "ash/host/root_window_transformer.h" | 12 #include "ash/host/root_window_transformer.h" |
13 #include "ash/root_window_controller.h" | 13 #include "ash/root_window_controller.h" |
14 #include "ash/screen_util.h" | 14 #include "ash/screen_util.h" |
15 #include "ash/shell.h" | 15 #include "ash/shell.h" |
16 #include "ash/system/tray/system_tray_delegate.h" | 16 #include "ash/system/tray/system_tray_delegate.h" |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
| 19 #include "base/timer/timer.h" |
19 #include "ui/aura/client/aura_constants.h" | 20 #include "ui/aura/client/aura_constants.h" |
20 #include "ui/aura/client/cursor_client.h" | 21 #include "ui/aura/client/cursor_client.h" |
21 #include "ui/aura/window.h" | 22 #include "ui/aura/window.h" |
22 #include "ui/aura/window_tree_host.h" | 23 #include "ui/aura/window_tree_host.h" |
23 #include "ui/base/ime/input_method.h" | 24 #include "ui/base/ime/input_method.h" |
24 #include "ui/base/ime/input_method_observer.h" | 25 #include "ui/base/ime/input_method_observer.h" |
25 #include "ui/base/ime/text_input_client.h" | 26 #include "ui/base/ime/text_input_client.h" |
26 #include "ui/compositor/dip_util.h" | 27 #include "ui/compositor/dip_util.h" |
27 #include "ui/compositor/layer.h" | 28 #include "ui/compositor/layer.h" |
28 #include "ui/compositor/layer_animation_observer.h" | 29 #include "ui/compositor/layer_animation_observer.h" |
(...skipping 11 matching lines...) Expand all Loading... |
40 namespace { | 41 namespace { |
41 | 42 |
42 const float kMaxMagnifiedScale = 4.0f; | 43 const float kMaxMagnifiedScale = 4.0f; |
43 const float kMaxMagnifiedScaleThreshold = 4.0f; | 44 const float kMaxMagnifiedScaleThreshold = 4.0f; |
44 const float kMinMagnifiedScaleThreshold = 1.1f; | 45 const float kMinMagnifiedScaleThreshold = 1.1f; |
45 const float kNonMagnifiedScale = 1.0f; | 46 const float kNonMagnifiedScale = 1.0f; |
46 | 47 |
47 const float kInitialMagnifiedScale = 2.0f; | 48 const float kInitialMagnifiedScale = 2.0f; |
48 const float kScrollScaleChangeFactor = 0.05f; | 49 const float kScrollScaleChangeFactor = 0.05f; |
49 | 50 |
| 51 // Default animation parameters for redrawing the magnification window. |
| 52 const gfx::Tween::Type kDefaultAnimationTweenType = gfx::Tween::EASE_OUT; |
| 53 const int kDefaultAnimationDurationInMs = 100; |
| 54 |
| 55 // Use linear transformation to make the magnifier window move smoothly |
| 56 // to center the focus when user types in a text input field. |
| 57 const gfx::Tween::Type kCenterCaretAnimationTweenType = gfx::Tween::LINEAR; |
| 58 |
| 59 // The delay of the timer for moving magnifier window for centering the text |
| 60 // input focus. |
| 61 const int kMoveMagnifierDelayInMs = 10; |
| 62 |
50 // Threadshold of panning. If the cursor moves to within pixels (in DIP) of | 63 // Threadshold of panning. If the cursor moves to within pixels (in DIP) of |
51 // |kPanningMergin| from the edge, the view-port moves. | 64 // |kCursorPanningMargin| from the edge, the view-port moves. |
52 const int kPanningMergin = 100; | 65 const int kCursorPanningMargin = 100; |
53 | 66 |
54 // Gives a little panning margin for following caret, so that we will move the | 67 // Threadshold of panning. If the caret moves to within pixels (in DIP) of |
55 // view-port before the caret is completely out of sight. | 68 // |kCaretPanningMargin| from the edge, the view-port moves. |
56 const int kCaretPanningMargin = 10; | 69 const int kCaretPanningMargin = 50; |
57 | 70 |
58 void MoveCursorTo(aura::WindowTreeHost* host, const gfx::Point& root_location) { | 71 void MoveCursorTo(aura::WindowTreeHost* host, const gfx::Point& root_location) { |
59 gfx::Point3F host_location_3f(root_location); | 72 gfx::Point3F host_location_3f(root_location); |
60 host->GetRootTransform().TransformPoint(&host_location_3f); | 73 host->GetRootTransform().TransformPoint(&host_location_3f); |
61 host->MoveCursorToHostLocation( | 74 host->MoveCursorToHostLocation( |
62 gfx::ToCeiledPoint(host_location_3f.AsPointF())); | 75 gfx::ToCeiledPoint(host_location_3f.AsPointF())); |
63 } | 76 } |
64 | 77 |
65 } // namespace | 78 } // namespace |
66 | 79 |
67 namespace ash { | 80 namespace ash { |
68 | 81 |
69 //////////////////////////////////////////////////////////////////////////////// | 82 //////////////////////////////////////////////////////////////////////////////// |
70 // MagnificationControllerImpl: | 83 // MagnificationControllerImpl: |
71 | 84 |
72 class MagnificationControllerImpl : virtual public MagnificationController, | 85 class MagnificationControllerImpl : virtual public MagnificationController, |
73 public ui::EventHandler, | 86 public ui::EventHandler, |
74 public ui::ImplicitAnimationObserver, | 87 public ui::ImplicitAnimationObserver, |
75 public aura::WindowObserver, | 88 public aura::WindowObserver, |
76 public ui::InputMethodObserver { | 89 public ui::InputMethodObserver { |
77 public: | 90 public: |
78 MagnificationControllerImpl(); | 91 MagnificationControllerImpl(); |
79 ~MagnificationControllerImpl() override; | 92 ~MagnificationControllerImpl() override; |
80 | 93 |
81 // MagnificationController overrides: | 94 // MagnificationController overrides: |
82 void SetEnabled(bool enabled) override; | 95 void SetEnabled(bool enabled) override; |
83 bool IsEnabled() const override; | 96 bool IsEnabled() const override; |
| 97 void SetKeepFocusCentered(bool keep_focus_centered) override; |
| 98 bool KeepFocusCentered() const override; |
84 void SetScale(float scale, bool animate) override; | 99 void SetScale(float scale, bool animate) override; |
85 float GetScale() const override { return scale_; } | 100 float GetScale() const override { return scale_; } |
86 void MoveWindow(int x, int y, bool animate) override; | 101 void MoveWindow(int x, int y, bool animate) override; |
87 void MoveWindow(const gfx::Point& point, bool animate) override; | 102 void MoveWindow(const gfx::Point& point, bool animate) override; |
88 gfx::Point GetWindowPosition() const override { | 103 gfx::Point GetWindowPosition() const override { |
89 return gfx::ToFlooredPoint(origin_); | 104 return gfx::ToFlooredPoint(origin_); |
90 } | 105 } |
91 void SetScrollDirection(ScrollDirection direction) override; | 106 void SetScrollDirection(ScrollDirection direction) override; |
92 gfx::Rect GetViewportRect() const override; | 107 gfx::Rect GetViewportRect() const override; |
93 void HandleFocusedNodeChanged( | 108 void HandleFocusedNodeChanged( |
94 bool is_editable_node, | 109 bool is_editable_node, |
95 const gfx::Rect& node_bounds_in_screen) override; | 110 const gfx::Rect& node_bounds_in_screen) override; |
96 void SwitchTargetRootWindow(aura::Window* new_root_window, | 111 void SwitchTargetRootWindow(aura::Window* new_root_window, |
97 bool redraw_original_root_window) override; | 112 bool redraw_original_root_window) override; |
98 | 113 |
99 // For test | 114 // For test |
100 gfx::Point GetPointOfInterestForTesting() override { | 115 gfx::Point GetPointOfInterestForTesting() override { |
101 return point_of_interest_; | 116 return point_of_interest_; |
102 } | 117 } |
103 | 118 |
104 bool IsOnAnimationForTesting() const override { return is_on_animation_; } | 119 bool IsOnAnimationForTesting() const override { return is_on_animation_; } |
105 | 120 |
| 121 void DisableMoveMagnifierDelayForTesting() override { |
| 122 disable_move_magnifier_delay_ = true; |
| 123 } |
| 124 |
106 private: | 125 private: |
107 // ui::ImplicitAnimationObserver overrides: | 126 // ui::ImplicitAnimationObserver overrides: |
108 void OnImplicitAnimationsCompleted() override; | 127 void OnImplicitAnimationsCompleted() override; |
109 | 128 |
110 // aura::WindowObserver overrides: | 129 // aura::WindowObserver overrides: |
111 void OnWindowDestroying(aura::Window* root_window) override; | 130 void OnWindowDestroying(aura::Window* root_window) override; |
112 void OnWindowBoundsChanged(aura::Window* window, | 131 void OnWindowBoundsChanged(aura::Window* window, |
113 const gfx::Rect& old_bounds, | 132 const gfx::Rect& old_bounds, |
114 const gfx::Rect& new_bounds) override; | 133 const gfx::Rect& new_bounds) override; |
115 | 134 |
116 // Redraws the magnification window with the given origin position and the | 135 // Redraws the magnification window with the given origin position and the |
117 // given scale. Returns true if the window is changed; otherwise, false. | 136 // given scale. Returns true if the window is changed; otherwise, false. |
118 // These methods should be called internally just after the scale and/or | 137 // These methods should be called internally just after the scale and/or |
119 // the position are changed to redraw the window. | 138 // the position are changed to redraw the window. |
120 bool Redraw(const gfx::PointF& position, float scale, bool animate); | 139 bool Redraw(const gfx::PointF& position, float scale, bool animate); |
121 bool RedrawDIP(const gfx::PointF& position, float scale, bool animate); | 140 |
| 141 // Redraws the magnification window with the given origin position in dip and |
| 142 // the given scale. Returns true if the window is changed; otherwise, false. |
| 143 // The last two parameters specify the animation duration and tween type. |
| 144 // If |animation_in_ms| is zero, there will be no animation, and |tween_type| |
| 145 // will be ignored. |
| 146 bool RedrawDIP(const gfx::PointF& position_in_dip, |
| 147 float scale, |
| 148 int animation_in_ms, |
| 149 gfx::Tween::Type tween_type); |
122 | 150 |
123 // 1) If the screen is scrolling (i.e. animating) and should scroll further, | 151 // 1) If the screen is scrolling (i.e. animating) and should scroll further, |
124 // it does nothing. | 152 // it does nothing. |
125 // 2) If the screen is scrolling (i.e. animating) and the direction is NONE, | 153 // 2) If the screen is scrolling (i.e. animating) and the direction is NONE, |
126 // it stops the scrolling animation. | 154 // it stops the scrolling animation. |
127 // 3) If the direction is set to value other than NONE, it starts the | 155 // 3) If the direction is set to value other than NONE, it starts the |
128 // scrolling/ animation towards that direction. | 156 // scrolling/ animation towards that direction. |
129 void StartOrStopScrollIfNecessary(); | 157 void StartOrStopScrollIfNecessary(); |
130 | 158 |
131 // Redraw with the given zoom scale keeping the mouse cursor location. In | 159 // Redraw with the given zoom scale keeping the mouse cursor location. In |
(...skipping 27 matching lines...) Expand all Loading... |
159 // |x_panning_margin| and |y_pannin_margin| to the edge of the visible | 187 // |x_panning_margin| and |y_pannin_margin| to the edge of the visible |
160 // window region. The view port will be moved so that the |point| will be | 188 // window region. The view port will be moved so that the |point| will be |
161 // moved to the point where it has |x_target_margin| and |y_target_margin| | 189 // moved to the point where it has |x_target_margin| and |y_target_margin| |
162 // to the edge of the visible region. | 190 // to the edge of the visible region. |
163 void MoveMagnifierWindowFollowPoint(const gfx::Point& point, | 191 void MoveMagnifierWindowFollowPoint(const gfx::Point& point, |
164 int x_panning_margin, | 192 int x_panning_margin, |
165 int y_panning_margin, | 193 int y_panning_margin, |
166 int x_target_margin, | 194 int x_target_margin, |
167 int y_target_margin); | 195 int y_target_margin); |
168 | 196 |
| 197 // Moves the view port to center |point| in magnifier screen. |
| 198 void MoveMagnifierWindowCenterPoint(const gfx::Point& point); |
| 199 |
169 // Moves the viewport so that |rect| is fully visible. If |rect| is larger | 200 // Moves the viewport so that |rect| is fully visible. If |rect| is larger |
170 // than the viewport horizontally or vertically, the viewport will be moved | 201 // than the viewport horizontally or vertically, the viewport will be moved |
171 // to center the |rect| in that dimension. | 202 // to center the |rect| in that dimension. |
172 void MoveMagnifierWindowFollowRect(const gfx::Rect& rect); | 203 void MoveMagnifierWindowFollowRect(const gfx::Rect& rect); |
173 | 204 |
| 205 // Invoked when |move_magnifier_timer_| fires to move the magnifier window to |
| 206 // follow the caret. |
| 207 void OnMoveMagnifierTimer(); |
| 208 |
174 // ui::InputMethodObserver: | 209 // ui::InputMethodObserver: |
175 void OnTextInputTypeChanged(const ui::TextInputClient* client) override {} | 210 void OnTextInputTypeChanged(const ui::TextInputClient* client) override {} |
176 void OnFocus() override {} | 211 void OnFocus() override {} |
177 void OnBlur() override {} | 212 void OnBlur() override {} |
178 void OnTextInputStateChanged(const ui::TextInputClient* client) override {} | 213 void OnTextInputStateChanged(const ui::TextInputClient* client) override {} |
179 void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {} | 214 void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {} |
180 void OnShowImeIfNeeded() override {} | 215 void OnShowImeIfNeeded() override {} |
181 void OnCaretBoundsChanged(const ui::TextInputClient* client) override; | 216 void OnCaretBoundsChanged(const ui::TextInputClient* client) override; |
182 | 217 |
183 // Target root window. This must not be NULL. | 218 // Target root window. This must not be NULL. |
184 aura::Window* root_window_; | 219 aura::Window* root_window_; |
185 | 220 |
186 // True if the magnified window is currently animating a change. Otherwise, | 221 // True if the magnified window is currently animating a change. Otherwise, |
187 // false. | 222 // false. |
188 bool is_on_animation_; | 223 bool is_on_animation_; |
189 | 224 |
190 bool is_enabled_; | 225 bool is_enabled_; |
191 | 226 |
| 227 bool keep_focus_centered_; |
| 228 |
192 // True if the cursor needs to move the given position after the animation | 229 // True if the cursor needs to move the given position after the animation |
193 // will be finished. When using this, set |position_after_animation_| as well. | 230 // will be finished. When using this, set |position_after_animation_| as well. |
194 bool move_cursor_after_animation_; | 231 bool move_cursor_after_animation_; |
195 // Stores the position of cursor to be moved after animation. | 232 // Stores the position of cursor to be moved after animation. |
196 gfx::Point position_after_animation_; | 233 gfx::Point position_after_animation_; |
197 | 234 |
198 // Stores the last mouse cursor (or last touched) location. This value is | 235 // Stores the last mouse cursor (or last touched) location. This value is |
199 // used on zooming to keep this location visible. | 236 // used on zooming to keep this location visible. |
200 gfx::Point point_of_interest_; | 237 gfx::Point point_of_interest_; |
201 | 238 |
202 // Current scale, origin (left-top) position of the magnification window. | 239 // Current scale, origin (left-top) position of the magnification window. |
203 float scale_; | 240 float scale_; |
204 gfx::PointF origin_; | 241 gfx::PointF origin_; |
205 | 242 |
206 ScrollDirection scroll_direction_; | 243 ScrollDirection scroll_direction_; |
207 | 244 |
208 ui::InputMethod* input_method_; // Not owned. | 245 ui::InputMethod* input_method_; // Not owned. |
209 | 246 |
| 247 // Timer for moving magnifier window when it fires. |
| 248 base::OneShotTimer<MagnificationControllerImpl> move_magnifier_timer_; |
| 249 |
| 250 // Most recent caret position in |root_window_| coordinates. |
| 251 gfx::Point caret_point_; |
| 252 |
| 253 // Flag for disabling moving magnifier delay. It can only be true in testing |
| 254 // mode. |
| 255 bool disable_move_magnifier_delay_; |
| 256 |
210 DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl); | 257 DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl); |
211 }; | 258 }; |
212 | 259 |
213 //////////////////////////////////////////////////////////////////////////////// | 260 //////////////////////////////////////////////////////////////////////////////// |
214 // MagnificationControllerImpl: | 261 // MagnificationControllerImpl: |
215 | 262 |
216 MagnificationControllerImpl::MagnificationControllerImpl() | 263 MagnificationControllerImpl::MagnificationControllerImpl() |
217 : root_window_(Shell::GetPrimaryRootWindow()), | 264 : root_window_(Shell::GetPrimaryRootWindow()), |
218 is_on_animation_(false), | 265 is_on_animation_(false), |
219 is_enabled_(false), | 266 is_enabled_(false), |
| 267 keep_focus_centered_(false), |
220 move_cursor_after_animation_(false), | 268 move_cursor_after_animation_(false), |
221 scale_(kNonMagnifiedScale), | 269 scale_(kNonMagnifiedScale), |
222 scroll_direction_(SCROLL_NONE), | 270 scroll_direction_(SCROLL_NONE), |
223 input_method_(NULL) { | 271 input_method_(NULL), |
| 272 disable_move_magnifier_delay_(false) { |
224 Shell::GetInstance()->AddPreTargetHandler(this); | 273 Shell::GetInstance()->AddPreTargetHandler(this); |
225 root_window_->AddObserver(this); | 274 root_window_->AddObserver(this); |
226 point_of_interest_ = root_window_->bounds().CenterPoint(); | 275 point_of_interest_ = root_window_->bounds().CenterPoint(); |
227 } | 276 } |
228 | 277 |
229 MagnificationControllerImpl::~MagnificationControllerImpl() { | 278 MagnificationControllerImpl::~MagnificationControllerImpl() { |
230 if (input_method_) | 279 if (input_method_) |
231 input_method_->RemoveObserver(this); | 280 input_method_->RemoveObserver(this); |
232 | 281 |
233 root_window_->RemoveObserver(this); | 282 root_window_->RemoveObserver(this); |
234 | 283 |
235 Shell::GetInstance()->RemovePreTargetHandler(this); | 284 Shell::GetInstance()->RemovePreTargetHandler(this); |
236 } | 285 } |
237 | 286 |
238 void MagnificationControllerImpl::RedrawKeepingMousePosition( | 287 void MagnificationControllerImpl::RedrawKeepingMousePosition( |
239 float scale, bool animate) { | 288 float scale, bool animate) { |
240 gfx::Point mouse_in_root = point_of_interest_; | 289 gfx::Point mouse_in_root = point_of_interest_; |
241 | 290 |
242 // mouse_in_root is invalid value when the cursor is hidden. | 291 // mouse_in_root is invalid value when the cursor is hidden. |
243 if (!root_window_->bounds().Contains(mouse_in_root)) | 292 if (!root_window_->bounds().Contains(mouse_in_root)) |
244 mouse_in_root = root_window_->bounds().CenterPoint(); | 293 mouse_in_root = root_window_->bounds().CenterPoint(); |
245 | 294 |
246 const gfx::PointF origin = | 295 const gfx::PointF origin = |
247 gfx::PointF(mouse_in_root.x() - | 296 gfx::PointF(mouse_in_root.x() - |
248 (scale_ / scale) * (mouse_in_root.x() - origin_.x()), | 297 (scale_ / scale) * (mouse_in_root.x() - origin_.x()), |
249 mouse_in_root.y() - | 298 mouse_in_root.y() - |
250 (scale_ / scale) * (mouse_in_root.y() - origin_.y())); | 299 (scale_ / scale) * (mouse_in_root.y() - origin_.y())); |
251 bool changed = RedrawDIP(origin, scale, animate); | 300 bool changed = RedrawDIP(origin, scale, |
| 301 animate ? kDefaultAnimationDurationInMs : 0, |
| 302 kDefaultAnimationTweenType); |
252 if (changed) | 303 if (changed) |
253 AfterAnimationMoveCursorTo(mouse_in_root); | 304 AfterAnimationMoveCursorTo(mouse_in_root); |
254 } | 305 } |
255 | 306 |
256 bool MagnificationControllerImpl::Redraw(const gfx::PointF& position, | 307 bool MagnificationControllerImpl::Redraw(const gfx::PointF& position, |
257 float scale, | 308 float scale, |
258 bool animate) { | 309 bool animate) { |
259 const gfx::PointF position_in_dip = | 310 const gfx::PointF position_in_dip = |
260 ui::ConvertPointToDIP(root_window_->layer(), position); | 311 ui::ConvertPointToDIP(root_window_->layer(), position); |
261 return RedrawDIP(position_in_dip, scale, animate); | 312 return RedrawDIP(position_in_dip, scale, |
| 313 animate ? kDefaultAnimationDurationInMs : 0, |
| 314 kDefaultAnimationTweenType); |
262 } | 315 } |
263 | 316 |
264 bool MagnificationControllerImpl::RedrawDIP(const gfx::PointF& position_in_dip, | 317 bool MagnificationControllerImpl::RedrawDIP(const gfx::PointF& position_in_dip, |
265 float scale, | 318 float scale, |
266 bool animate) { | 319 int duration_in_ms, |
| 320 gfx::Tween::Type tween_type) { |
267 DCHECK(root_window_); | 321 DCHECK(root_window_); |
268 | 322 |
269 float x = position_in_dip.x(); | 323 float x = position_in_dip.x(); |
270 float y = position_in_dip.y(); | 324 float y = position_in_dip.y(); |
271 | 325 |
272 ValidateScale(&scale); | 326 ValidateScale(&scale); |
273 | 327 |
274 if (x < 0) | 328 if (x < 0) |
275 x = 0; | 329 x = 0; |
276 if (y < 0) | 330 if (y < 0) |
(...skipping 24 matching lines...) Expand all Loading... |
301 // Flips the signs intentionally to convert them from the position of the | 355 // Flips the signs intentionally to convert them from the position of the |
302 // magnification window. | 356 // magnification window. |
303 transform.Scale(scale_, scale_); | 357 transform.Scale(scale_, scale_); |
304 transform.Translate(-origin_.x(), -origin_.y()); | 358 transform.Translate(-origin_.x(), -origin_.y()); |
305 | 359 |
306 ui::ScopedLayerAnimationSettings settings( | 360 ui::ScopedLayerAnimationSettings settings( |
307 root_window_->layer()->GetAnimator()); | 361 root_window_->layer()->GetAnimator()); |
308 settings.AddObserver(this); | 362 settings.AddObserver(this); |
309 settings.SetPreemptionStrategy( | 363 settings.SetPreemptionStrategy( |
310 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 364 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
311 settings.SetTweenType(gfx::Tween::EASE_OUT); | 365 settings.SetTweenType(tween_type); |
312 settings.SetTransitionDuration( | 366 settings.SetTransitionDuration( |
313 base::TimeDelta::FromMilliseconds(animate ? 100 : 0)); | 367 base::TimeDelta::FromMilliseconds(duration_in_ms)); |
314 | 368 |
315 gfx::Display display = | 369 gfx::Display display = |
316 Shell::GetScreen()->GetDisplayNearestWindow(root_window_); | 370 Shell::GetScreen()->GetDisplayNearestWindow(root_window_); |
317 scoped_ptr<RootWindowTransformer> transformer( | 371 scoped_ptr<RootWindowTransformer> transformer( |
318 CreateRootWindowTransformerForDisplay(root_window_, display)); | 372 CreateRootWindowTransformerForDisplay(root_window_, display)); |
319 GetRootWindowController(root_window_)->ash_host()->SetRootWindowTransformer( | 373 GetRootWindowController(root_window_)->ash_host()->SetRootWindowTransformer( |
320 transformer.Pass()); | 374 transformer.Pass()); |
321 | 375 |
322 if (animate) | 376 if (duration_in_ms > 0) |
323 is_on_animation_ = true; | 377 is_on_animation_ = true; |
324 | 378 |
325 return true; | 379 return true; |
326 } | 380 } |
327 | 381 |
328 void MagnificationControllerImpl::StartOrStopScrollIfNecessary() { | 382 void MagnificationControllerImpl::StartOrStopScrollIfNecessary() { |
329 // This value controls the scrolling speed. | 383 // This value controls the scrolling speed. |
330 const int kMoveOffset = 40; | 384 const int kMoveOffset = 40; |
331 if (is_on_animation_) { | 385 if (is_on_animation_) { |
332 if (scroll_direction_ == SCROLL_NONE) | 386 if (scroll_direction_ == SCROLL_NONE) |
(...skipping 12 matching lines...) Expand all Loading... |
345 case SCROLL_RIGHT: | 399 case SCROLL_RIGHT: |
346 new_origin.Offset(kMoveOffset, 0); | 400 new_origin.Offset(kMoveOffset, 0); |
347 break; | 401 break; |
348 case SCROLL_UP: | 402 case SCROLL_UP: |
349 new_origin.Offset(0, -kMoveOffset); | 403 new_origin.Offset(0, -kMoveOffset); |
350 break; | 404 break; |
351 case SCROLL_DOWN: | 405 case SCROLL_DOWN: |
352 new_origin.Offset(0, kMoveOffset); | 406 new_origin.Offset(0, kMoveOffset); |
353 break; | 407 break; |
354 } | 408 } |
355 RedrawDIP(new_origin, scale_, true); | 409 RedrawDIP(new_origin, scale_, kDefaultAnimationDurationInMs, |
| 410 kDefaultAnimationTweenType); |
356 } | 411 } |
357 | 412 |
358 void MagnificationControllerImpl::OnMouseMove(const gfx::Point& location) { | 413 void MagnificationControllerImpl::OnMouseMove(const gfx::Point& location) { |
359 DCHECK(root_window_); | 414 DCHECK(root_window_); |
360 | 415 |
361 gfx::Point mouse(location); | 416 gfx::Point mouse(location); |
362 int margin = kPanningMergin / scale_; // No need to consider DPI. | 417 int margin = kCursorPanningMargin / scale_; // No need to consider DPI. |
363 MoveMagnifierWindowFollowPoint(mouse, margin, margin, margin, margin); | 418 MoveMagnifierWindowFollowPoint(mouse, margin, margin, margin, margin); |
364 } | 419 } |
365 | 420 |
366 gfx::Rect MagnificationControllerImpl::GetViewportRect() const { | 421 gfx::Rect MagnificationControllerImpl::GetViewportRect() const { |
367 return gfx::ToEnclosingRect(GetWindowRectDIP(scale_)); | 422 return gfx::ToEnclosingRect(GetWindowRectDIP(scale_)); |
368 } | 423 } |
369 | 424 |
370 void MagnificationControllerImpl::HandleFocusedNodeChanged( | 425 void MagnificationControllerImpl::HandleFocusedNodeChanged( |
371 bool is_editable_node, | 426 bool is_editable_node, |
372 const gfx::Rect& node_bounds_in_screen) { | 427 const gfx::Rect& node_bounds_in_screen) { |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 | 618 |
564 RedrawKeepingMousePosition(kNonMagnifiedScale, true); | 619 RedrawKeepingMousePosition(kNonMagnifiedScale, true); |
565 is_enabled_ = enabled; | 620 is_enabled_ = enabled; |
566 } | 621 } |
567 } | 622 } |
568 | 623 |
569 bool MagnificationControllerImpl::IsEnabled() const { | 624 bool MagnificationControllerImpl::IsEnabled() const { |
570 return is_enabled_; | 625 return is_enabled_; |
571 } | 626 } |
572 | 627 |
| 628 void MagnificationControllerImpl::SetKeepFocusCentered( |
| 629 bool keep_focus_centered) { |
| 630 keep_focus_centered_ = keep_focus_centered; |
| 631 } |
| 632 |
| 633 bool MagnificationControllerImpl::KeepFocusCentered() const { |
| 634 return keep_focus_centered_; |
| 635 } |
| 636 |
573 //////////////////////////////////////////////////////////////////////////////// | 637 //////////////////////////////////////////////////////////////////////////////// |
574 // MagnificationControllerImpl: aura::EventFilter implementation | 638 // MagnificationControllerImpl: aura::EventFilter implementation |
575 | 639 |
576 void MagnificationControllerImpl::OnMouseEvent(ui::MouseEvent* event) { | 640 void MagnificationControllerImpl::OnMouseEvent(ui::MouseEvent* event) { |
577 aura::Window* target = static_cast<aura::Window*>(event->target()); | 641 aura::Window* target = static_cast<aura::Window*>(event->target()); |
578 aura::Window* current_root = target->GetRootWindow(); | 642 aura::Window* current_root = target->GetRootWindow(); |
579 gfx::Rect root_bounds = current_root->bounds(); | 643 gfx::Rect root_bounds = current_root->bounds(); |
580 | 644 |
581 if (root_bounds.Contains(event->root_location())) { | 645 if (root_bounds.Contains(event->root_location())) { |
582 // This must be before |SwitchTargetRootWindow()|. | 646 // This must be before |SwitchTargetRootWindow()|. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 // Panning up. | 719 // Panning up. |
656 y_diff = point.y() - (top + y_target_margin); | 720 y_diff = point.y() - (top + y_target_margin); |
657 start_zoom = true; | 721 start_zoom = true; |
658 } else if (bottom - y_panning_margin < point.y()) { | 722 } else if (bottom - y_panning_margin < point.y()) { |
659 // Panning down. | 723 // Panning down. |
660 y_diff = point.y() - (bottom - y_target_margin); | 724 y_diff = point.y() - (bottom - y_target_margin); |
661 start_zoom = true; | 725 start_zoom = true; |
662 } | 726 } |
663 int y = top + y_diff; | 727 int y = top + y_diff; |
664 if (start_zoom && !is_on_animation_) { | 728 if (start_zoom && !is_on_animation_) { |
665 // No animation on panning. | 729 bool ret = RedrawDIP(gfx::Point(x, y), scale_, |
666 bool animate = false; | 730 0, // No animation on panning. |
667 bool ret = RedrawDIP(gfx::Point(x, y), scale_, animate); | 731 kDefaultAnimationTweenType); |
668 | 732 |
669 if (ret) { | 733 if (ret) { |
670 // If the magnified region is moved, hides the mouse cursor and moves it. | 734 // If the magnified region is moved, hides the mouse cursor and moves it. |
671 if (x_diff != 0 || y_diff != 0) | 735 if (x_diff != 0 || y_diff != 0) |
672 MoveCursorTo(root_window_->GetHost(), point); | 736 MoveCursorTo(root_window_->GetHost(), point); |
673 } | 737 } |
674 } | 738 } |
675 } | 739 } |
676 | 740 |
| 741 void MagnificationControllerImpl::MoveMagnifierWindowCenterPoint( |
| 742 const gfx::Point& point) { |
| 743 DCHECK(root_window_); |
| 744 |
| 745 const gfx::Rect window_rect = GetViewportRect(); |
| 746 if (point == window_rect.CenterPoint()) |
| 747 return; |
| 748 |
| 749 if (!is_on_animation_) { |
| 750 // With animation on panning. |
| 751 RedrawDIP(window_rect.origin() + (point - window_rect.CenterPoint()), |
| 752 scale_, kDefaultAnimationDurationInMs, |
| 753 kCenterCaretAnimationTweenType); |
| 754 } |
| 755 } |
| 756 |
677 void MagnificationControllerImpl::MoveMagnifierWindowFollowRect( | 757 void MagnificationControllerImpl::MoveMagnifierWindowFollowRect( |
678 const gfx::Rect& rect) { | 758 const gfx::Rect& rect) { |
679 DCHECK(root_window_); | 759 DCHECK(root_window_); |
680 bool should_pan = false; | 760 bool should_pan = false; |
681 | 761 |
682 const gfx::Rect viewport_rect = GetViewportRect(); | 762 const gfx::Rect viewport_rect = GetViewportRect(); |
683 const int left = viewport_rect.x(); | 763 const int left = viewport_rect.x(); |
684 const int right = viewport_rect.right(); | 764 const int right = viewport_rect.right(); |
685 const gfx::Point rect_center = rect.CenterPoint(); | 765 const gfx::Point rect_center = rect.CenterPoint(); |
686 const gfx::Point window_center = viewport_rect.CenterPoint(); | 766 const gfx::Point window_center = viewport_rect.CenterPoint(); |
(...skipping 13 matching lines...) Expand all Loading... |
700 // Panning vertically. | 780 // Panning vertically. |
701 y = rect_center.y() - viewport_rect.height() / 2; | 781 y = rect_center.y() - viewport_rect.height() / 2; |
702 should_pan = true; | 782 should_pan = true; |
703 } | 783 } |
704 | 784 |
705 if (should_pan) { | 785 if (should_pan) { |
706 if (is_on_animation_) { | 786 if (is_on_animation_) { |
707 root_window_->layer()->GetAnimator()->StopAnimating(); | 787 root_window_->layer()->GetAnimator()->StopAnimating(); |
708 is_on_animation_ = false; | 788 is_on_animation_ = false; |
709 } | 789 } |
710 RedrawDIP(gfx::Point(x, y), scale_, false); // No animation on panning. | 790 RedrawDIP(gfx::Point(x, y), scale_, |
| 791 0, // No animation on panning. |
| 792 kDefaultAnimationTweenType); |
711 } | 793 } |
712 } | 794 } |
713 | 795 |
| 796 void MagnificationControllerImpl::OnMoveMagnifierTimer() { |
| 797 MoveMagnifierWindowCenterPoint(caret_point_); |
| 798 } |
| 799 |
714 void MagnificationControllerImpl::OnCaretBoundsChanged( | 800 void MagnificationControllerImpl::OnCaretBoundsChanged( |
715 const ui::TextInputClient* client) { | 801 const ui::TextInputClient* client) { |
716 // caret bounds in screen coordinates. | 802 // caret bounds in screen coordinates. |
717 const gfx::Rect caret_bounds = client->GetCaretBounds(); | 803 const gfx::Rect caret_bounds = client->GetCaretBounds(); |
718 // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during | 804 // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during |
719 // which the caret position is not set a meaning position, and we do not | 805 // which the caret position is not set a meaning position, and we do not |
720 // need to adjust the view port position based on the bogus caret position. | 806 // need to adjust the view port position based on the bogus caret position. |
721 // This is only a transition period, the caret position will be fixed upon | 807 // This is only a transition period, the caret position will be fixed upon |
722 // focusing right after. | 808 // focusing right after. |
723 if (caret_bounds.width() == 0 && caret_bounds.height() == 0) | 809 if (caret_bounds.width() == 0 && caret_bounds.height() == 0) |
724 return; | 810 return; |
725 | 811 |
726 gfx::Point caret_origin = caret_bounds.origin(); | 812 caret_point_ = caret_bounds.CenterPoint(); |
727 // caret_origin in |root_window_| coordinates. | 813 // |caret_point_| in |root_window_| coordinates. |
728 wm::ConvertPointFromScreen(root_window_, &caret_origin); | 814 wm::ConvertPointFromScreen(root_window_, &caret_point_); |
729 | 815 |
730 // Visible window_rect in |root_window_| coordinates. | 816 // If the feature for centering the text input focus is disabled, the |
731 const gfx::Rect visible_window_rect = GetViewportRect(); | 817 // magnifier window will be moved to follow the focus with a panning margin. |
| 818 if (!KeepFocusCentered()) { |
| 819 // Visible window_rect in |root_window_| coordinates. |
| 820 const gfx::Rect visible_window_rect = GetViewportRect(); |
| 821 const int panning_margin = kCaretPanningMargin / scale_; |
| 822 MoveMagnifierWindowFollowPoint(caret_point_, |
| 823 panning_margin, |
| 824 panning_margin, |
| 825 visible_window_rect.width() / 2, |
| 826 visible_window_rect.height() / 2); |
| 827 return; |
| 828 } |
732 | 829 |
733 const int panning_margin = kCaretPanningMargin / scale_; | 830 // Move the magnifier window to center the focus with a little delay. |
734 MoveMagnifierWindowFollowPoint(caret_origin, panning_margin, panning_margin, | 831 // In Gmail compose window, when user types a blank space, it will insert |
735 visible_window_rect.width() / 2, | 832 // a non-breaking space(NBSP). NBSP will be replaced with a blank space |
736 visible_window_rect.height() / 2); | 833 // character when user types a non-blank space character later, which causes |
| 834 // OnCaretBoundsChanged be called twice. The first call moves the caret back |
| 835 // to the character position just before NBSP, replaces the NBSP with blank |
| 836 // space plus the new character, then the second call will move caret to the |
| 837 // position after the new character. In order to avoid the magnifier window |
| 838 // being moved back and forth with these two OnCaretBoundsChanged events, we |
| 839 // defer moving magnifier window until the |move_magnifier_timer_| fires, |
| 840 // when the caret settles eventually. |
| 841 move_magnifier_timer_.Stop(); |
| 842 move_magnifier_timer_.Start( |
| 843 FROM_HERE, |
| 844 base::TimeDelta::FromMilliseconds( |
| 845 disable_move_magnifier_delay_ ? 0 : kMoveMagnifierDelayInMs), |
| 846 this, &MagnificationControllerImpl::OnMoveMagnifierTimer); |
737 } | 847 } |
738 | 848 |
739 //////////////////////////////////////////////////////////////////////////////// | 849 //////////////////////////////////////////////////////////////////////////////// |
740 // MagnificationController: | 850 // MagnificationController: |
741 | 851 |
742 // static | 852 // static |
743 MagnificationController* MagnificationController::CreateInstance() { | 853 MagnificationController* MagnificationController::CreateInstance() { |
744 return new MagnificationControllerImpl(); | 854 return new MagnificationControllerImpl(); |
745 } | 855 } |
746 | 856 |
747 } // namespace ash | 857 } // namespace ash |
OLD | NEW |