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

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

Issue 1157553003: Center the focus of the text input in magnifier screen. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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/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
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 = 5;
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(
(...skipping 16 matching lines...) Expand all
110 // aura::WindowObserver overrides: 125 // aura::WindowObserver overrides:
111 void OnWindowDestroying(aura::Window* root_window) override; 126 void OnWindowDestroying(aura::Window* root_window) override;
112 void OnWindowBoundsChanged(aura::Window* window, 127 void OnWindowBoundsChanged(aura::Window* window,
113 const gfx::Rect& old_bounds, 128 const gfx::Rect& old_bounds,
114 const gfx::Rect& new_bounds) override; 129 const gfx::Rect& new_bounds) override;
115 130
116 // Redraws the magnification window with the given origin position and the 131 // Redraws the magnification window with the given origin position and the
117 // given scale. Returns true if the window is changed; otherwise, false. 132 // given scale. Returns true if the window is changed; otherwise, false.
118 // These methods should be called internally just after the scale and/or 133 // These methods should be called internally just after the scale and/or
119 // the position are changed to redraw the window. 134 // the position are changed to redraw the window.
120 bool Redraw(const gfx::PointF& position, float scale, bool animate); 135 bool Redraw(const gfx::PointF& position, float scale, bool animate);
oshima 2015/05/28 22:41:35 nit: new line
jennyz 2015/05/29 21:41:24 Done.
121 bool RedrawDIP(const gfx::PointF& position, float scale, bool animate); 136 // Redraws the magnification window with the given origin position in dip and
137 // the given scale. Returns true if the window is changed; otherwise, false.
138 // The last two parameters specify the animation duration and tween type.
139 // If |animation_in_ms| is zero, there will be no animation, and |tween_type|
140 // will be ignored.
141 bool RedrawDIP(const gfx::PointF& position_in_dip,
142 float scale,
143 int animation_in_ms,
144 gfx::Tween::Type tween_type);
122 145
123 // 1) If the screen is scrolling (i.e. animating) and should scroll further, 146 // 1) If the screen is scrolling (i.e. animating) and should scroll further,
124 // it does nothing. 147 // it does nothing.
125 // 2) If the screen is scrolling (i.e. animating) and the direction is NONE, 148 // 2) If the screen is scrolling (i.e. animating) and the direction is NONE,
126 // it stops the scrolling animation. 149 // it stops the scrolling animation.
127 // 3) If the direction is set to value other than NONE, it starts the 150 // 3) If the direction is set to value other than NONE, it starts the
128 // scrolling/ animation towards that direction. 151 // scrolling/ animation towards that direction.
129 void StartOrStopScrollIfNecessary(); 152 void StartOrStopScrollIfNecessary();
130 153
131 // Redraw with the given zoom scale keeping the mouse cursor location. In 154 // Redraw with the given zoom scale keeping the mouse cursor location. In
(...skipping 27 matching lines...) Expand all
159 // |x_panning_margin| and |y_pannin_margin| to the edge of the visible 182 // |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 183 // 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| 184 // moved to the point where it has |x_target_margin| and |y_target_margin|
162 // to the edge of the visible region. 185 // to the edge of the visible region.
163 void MoveMagnifierWindowFollowPoint(const gfx::Point& point, 186 void MoveMagnifierWindowFollowPoint(const gfx::Point& point,
164 int x_panning_margin, 187 int x_panning_margin,
165 int y_panning_margin, 188 int y_panning_margin,
166 int x_target_margin, 189 int x_target_margin,
167 int y_target_margin); 190 int y_target_margin);
168 191
192 // Moves the view port to center |point| in magnifier screen.
193 void MoveMagnifierWindowCenterPoint(const gfx::Point& point);
194
169 // Moves the viewport so that |rect| is fully visible. If |rect| is larger 195 // 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 196 // than the viewport horizontally or vertically, the viewport will be moved
171 // to center the |rect| in that dimension. 197 // to center the |rect| in that dimension.
172 void MoveMagnifierWindowFollowRect(const gfx::Rect& rect); 198 void MoveMagnifierWindowFollowRect(const gfx::Rect& rect);
173 199
200 // Invoked when |move_magnifier_timer_| fires to move the magnifier window to
201 // follow the caret.
202 void OnMoveMagnifierTimer();
203
174 // ui::InputMethodObserver: 204 // ui::InputMethodObserver:
175 void OnTextInputTypeChanged(const ui::TextInputClient* client) override {} 205 void OnTextInputTypeChanged(const ui::TextInputClient* client) override {}
176 void OnFocus() override {} 206 void OnFocus() override {}
177 void OnBlur() override {} 207 void OnBlur() override {}
178 void OnTextInputStateChanged(const ui::TextInputClient* client) override {} 208 void OnTextInputStateChanged(const ui::TextInputClient* client) override {}
179 void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {} 209 void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {}
180 void OnShowImeIfNeeded() override {} 210 void OnShowImeIfNeeded() override {}
181 void OnCaretBoundsChanged(const ui::TextInputClient* client) override; 211 void OnCaretBoundsChanged(const ui::TextInputClient* client) override;
182 212
183 // Target root window. This must not be NULL. 213 // Target root window. This must not be NULL.
184 aura::Window* root_window_; 214 aura::Window* root_window_;
185 215
186 // True if the magnified window is currently animating a change. Otherwise, 216 // True if the magnified window is currently animating a change. Otherwise,
187 // false. 217 // false.
188 bool is_on_animation_; 218 bool is_on_animation_;
189 219
190 bool is_enabled_; 220 bool is_enabled_;
191 221
222 bool keep_focus_centered_;
223
192 // True if the cursor needs to move the given position after the animation 224 // 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. 225 // will be finished. When using this, set |position_after_animation_| as well.
194 bool move_cursor_after_animation_; 226 bool move_cursor_after_animation_;
195 // Stores the position of cursor to be moved after animation. 227 // Stores the position of cursor to be moved after animation.
196 gfx::Point position_after_animation_; 228 gfx::Point position_after_animation_;
197 229
198 // Stores the last mouse cursor (or last touched) location. This value is 230 // Stores the last mouse cursor (or last touched) location. This value is
199 // used on zooming to keep this location visible. 231 // used on zooming to keep this location visible.
200 gfx::Point point_of_interest_; 232 gfx::Point point_of_interest_;
201 233
202 // Current scale, origin (left-top) position of the magnification window. 234 // Current scale, origin (left-top) position of the magnification window.
203 float scale_; 235 float scale_;
204 gfx::PointF origin_; 236 gfx::PointF origin_;
205 237
206 ScrollDirection scroll_direction_; 238 ScrollDirection scroll_direction_;
207 239
208 ui::InputMethod* input_method_; // Not owned. 240 ui::InputMethod* input_method_; // Not owned.
209 241
242 // Timer for moving magnifier window when it fires.
243 base::OneShotTimer<MagnificationControllerImpl> move_magnifier_timer_;
244
245 // Most recent caret position in |root_window_| coordinates.
246 gfx::Point caret_point_;
247
210 DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl); 248 DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl);
211 }; 249 };
212 250
213 //////////////////////////////////////////////////////////////////////////////// 251 ////////////////////////////////////////////////////////////////////////////////
214 // MagnificationControllerImpl: 252 // MagnificationControllerImpl:
215 253
216 MagnificationControllerImpl::MagnificationControllerImpl() 254 MagnificationControllerImpl::MagnificationControllerImpl()
217 : root_window_(Shell::GetPrimaryRootWindow()), 255 : root_window_(Shell::GetPrimaryRootWindow()),
218 is_on_animation_(false), 256 is_on_animation_(false),
219 is_enabled_(false), 257 is_enabled_(false),
258 keep_focus_centered_(false),
220 move_cursor_after_animation_(false), 259 move_cursor_after_animation_(false),
221 scale_(kNonMagnifiedScale), 260 scale_(kNonMagnifiedScale),
222 scroll_direction_(SCROLL_NONE), 261 scroll_direction_(SCROLL_NONE),
223 input_method_(NULL) { 262 input_method_(NULL) {
224 Shell::GetInstance()->AddPreTargetHandler(this); 263 Shell::GetInstance()->AddPreTargetHandler(this);
225 root_window_->AddObserver(this); 264 root_window_->AddObserver(this);
226 point_of_interest_ = root_window_->bounds().CenterPoint(); 265 point_of_interest_ = root_window_->bounds().CenterPoint();
227 } 266 }
228 267
229 MagnificationControllerImpl::~MagnificationControllerImpl() { 268 MagnificationControllerImpl::~MagnificationControllerImpl() {
(...skipping 11 matching lines...) Expand all
241 280
242 // mouse_in_root is invalid value when the cursor is hidden. 281 // mouse_in_root is invalid value when the cursor is hidden.
243 if (!root_window_->bounds().Contains(mouse_in_root)) 282 if (!root_window_->bounds().Contains(mouse_in_root))
244 mouse_in_root = root_window_->bounds().CenterPoint(); 283 mouse_in_root = root_window_->bounds().CenterPoint();
245 284
246 const gfx::PointF origin = 285 const gfx::PointF origin =
247 gfx::PointF(mouse_in_root.x() - 286 gfx::PointF(mouse_in_root.x() -
248 (scale_ / scale) * (mouse_in_root.x() - origin_.x()), 287 (scale_ / scale) * (mouse_in_root.x() - origin_.x()),
249 mouse_in_root.y() - 288 mouse_in_root.y() -
250 (scale_ / scale) * (mouse_in_root.y() - origin_.y())); 289 (scale_ / scale) * (mouse_in_root.y() - origin_.y()));
251 bool changed = RedrawDIP(origin, scale, animate); 290 bool changed = RedrawDIP(origin, scale,
291 animate ? kDefaultAnimationDurationInMs : 0,
292 kDefaultAnimationTweenType);
252 if (changed) 293 if (changed)
253 AfterAnimationMoveCursorTo(mouse_in_root); 294 AfterAnimationMoveCursorTo(mouse_in_root);
254 } 295 }
255 296
256 bool MagnificationControllerImpl::Redraw(const gfx::PointF& position, 297 bool MagnificationControllerImpl::Redraw(const gfx::PointF& position,
257 float scale, 298 float scale,
258 bool animate) { 299 bool animate) {
259 const gfx::PointF position_in_dip = 300 const gfx::PointF position_in_dip =
260 ui::ConvertPointToDIP(root_window_->layer(), position); 301 ui::ConvertPointToDIP(root_window_->layer(), position);
261 return RedrawDIP(position_in_dip, scale, animate); 302 return RedrawDIP(position_in_dip, scale,
303 animate ? kDefaultAnimationDurationInMs : 0,
304 kDefaultAnimationTweenType);
262 } 305 }
263 306
264 bool MagnificationControllerImpl::RedrawDIP(const gfx::PointF& position_in_dip, 307 bool MagnificationControllerImpl::RedrawDIP(const gfx::PointF& position_in_dip,
265 float scale, 308 float scale,
266 bool animate) { 309 int duration_in_ms,
310 gfx::Tween::Type tween_type) {
267 DCHECK(root_window_); 311 DCHECK(root_window_);
268 312
269 float x = position_in_dip.x(); 313 float x = position_in_dip.x();
270 float y = position_in_dip.y(); 314 float y = position_in_dip.y();
271 315
272 ValidateScale(&scale); 316 ValidateScale(&scale);
273 317
274 if (x < 0) 318 if (x < 0)
275 x = 0; 319 x = 0;
276 if (y < 0) 320 if (y < 0)
(...skipping 24 matching lines...) Expand all
301 // Flips the signs intentionally to convert them from the position of the 345 // Flips the signs intentionally to convert them from the position of the
302 // magnification window. 346 // magnification window.
303 transform.Scale(scale_, scale_); 347 transform.Scale(scale_, scale_);
304 transform.Translate(-origin_.x(), -origin_.y()); 348 transform.Translate(-origin_.x(), -origin_.y());
305 349
306 ui::ScopedLayerAnimationSettings settings( 350 ui::ScopedLayerAnimationSettings settings(
307 root_window_->layer()->GetAnimator()); 351 root_window_->layer()->GetAnimator());
308 settings.AddObserver(this); 352 settings.AddObserver(this);
309 settings.SetPreemptionStrategy( 353 settings.SetPreemptionStrategy(
310 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 354 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
311 settings.SetTweenType(gfx::Tween::EASE_OUT); 355 settings.SetTweenType(tween_type);
312 settings.SetTransitionDuration( 356 settings.SetTransitionDuration(
313 base::TimeDelta::FromMilliseconds(animate ? 100 : 0)); 357 base::TimeDelta::FromMilliseconds(duration_in_ms));
314 358
315 gfx::Display display = 359 gfx::Display display =
316 Shell::GetScreen()->GetDisplayNearestWindow(root_window_); 360 Shell::GetScreen()->GetDisplayNearestWindow(root_window_);
317 scoped_ptr<RootWindowTransformer> transformer( 361 scoped_ptr<RootWindowTransformer> transformer(
318 CreateRootWindowTransformerForDisplay(root_window_, display)); 362 CreateRootWindowTransformerForDisplay(root_window_, display));
319 GetRootWindowController(root_window_)->ash_host()->SetRootWindowTransformer( 363 GetRootWindowController(root_window_)->ash_host()->SetRootWindowTransformer(
320 transformer.Pass()); 364 transformer.Pass());
321 365
322 if (animate) 366 if (duration_in_ms > 0)
323 is_on_animation_ = true; 367 is_on_animation_ = true;
324 368
325 return true; 369 return true;
326 } 370 }
327 371
328 void MagnificationControllerImpl::StartOrStopScrollIfNecessary() { 372 void MagnificationControllerImpl::StartOrStopScrollIfNecessary() {
329 // This value controls the scrolling speed. 373 // This value controls the scrolling speed.
330 const int kMoveOffset = 40; 374 const int kMoveOffset = 40;
331 if (is_on_animation_) { 375 if (is_on_animation_) {
332 if (scroll_direction_ == SCROLL_NONE) 376 if (scroll_direction_ == SCROLL_NONE)
(...skipping 12 matching lines...) Expand all
345 case SCROLL_RIGHT: 389 case SCROLL_RIGHT:
346 new_origin.Offset(kMoveOffset, 0); 390 new_origin.Offset(kMoveOffset, 0);
347 break; 391 break;
348 case SCROLL_UP: 392 case SCROLL_UP:
349 new_origin.Offset(0, -kMoveOffset); 393 new_origin.Offset(0, -kMoveOffset);
350 break; 394 break;
351 case SCROLL_DOWN: 395 case SCROLL_DOWN:
352 new_origin.Offset(0, kMoveOffset); 396 new_origin.Offset(0, kMoveOffset);
353 break; 397 break;
354 } 398 }
355 RedrawDIP(new_origin, scale_, true); 399 RedrawDIP(new_origin, scale_, kDefaultAnimationDurationInMs,
400 kDefaultAnimationTweenType);
356 } 401 }
357 402
358 void MagnificationControllerImpl::OnMouseMove(const gfx::Point& location) { 403 void MagnificationControllerImpl::OnMouseMove(const gfx::Point& location) {
359 DCHECK(root_window_); 404 DCHECK(root_window_);
360 405
361 gfx::Point mouse(location); 406 gfx::Point mouse(location);
362 int margin = kPanningMergin / scale_; // No need to consider DPI. 407 int margin = kCursorPanningMargin / scale_; // No need to consider DPI.
363 MoveMagnifierWindowFollowPoint(mouse, margin, margin, margin, margin); 408 MoveMagnifierWindowFollowPoint(mouse, margin, margin, margin, margin);
364 } 409 }
365 410
366 gfx::Rect MagnificationControllerImpl::GetViewportRect() const { 411 gfx::Rect MagnificationControllerImpl::GetViewportRect() const {
367 return gfx::ToEnclosingRect(GetWindowRectDIP(scale_)); 412 return gfx::ToEnclosingRect(GetWindowRectDIP(scale_));
368 } 413 }
369 414
370 void MagnificationControllerImpl::HandleFocusedNodeChanged( 415 void MagnificationControllerImpl::HandleFocusedNodeChanged(
371 bool is_editable_node, 416 bool is_editable_node,
372 const gfx::Rect& node_bounds_in_screen) { 417 const gfx::Rect& node_bounds_in_screen) {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 608
564 RedrawKeepingMousePosition(kNonMagnifiedScale, true); 609 RedrawKeepingMousePosition(kNonMagnifiedScale, true);
565 is_enabled_ = enabled; 610 is_enabled_ = enabled;
566 } 611 }
567 } 612 }
568 613
569 bool MagnificationControllerImpl::IsEnabled() const { 614 bool MagnificationControllerImpl::IsEnabled() const {
570 return is_enabled_; 615 return is_enabled_;
571 } 616 }
572 617
618 void MagnificationControllerImpl::SetKeepFocusCentered(
619 bool keep_focus_centered) {
620 keep_focus_centered_ = keep_focus_centered;
621 }
622
623 bool MagnificationControllerImpl::KeepFocusCentered() const {
624 return keep_focus_centered_;
625 }
626
573 //////////////////////////////////////////////////////////////////////////////// 627 ////////////////////////////////////////////////////////////////////////////////
574 // MagnificationControllerImpl: aura::EventFilter implementation 628 // MagnificationControllerImpl: aura::EventFilter implementation
575 629
576 void MagnificationControllerImpl::OnMouseEvent(ui::MouseEvent* event) { 630 void MagnificationControllerImpl::OnMouseEvent(ui::MouseEvent* event) {
577 aura::Window* target = static_cast<aura::Window*>(event->target()); 631 aura::Window* target = static_cast<aura::Window*>(event->target());
578 aura::Window* current_root = target->GetRootWindow(); 632 aura::Window* current_root = target->GetRootWindow();
579 gfx::Rect root_bounds = current_root->bounds(); 633 gfx::Rect root_bounds = current_root->bounds();
580 634
581 if (root_bounds.Contains(event->root_location())) { 635 if (root_bounds.Contains(event->root_location())) {
582 // This must be before |SwitchTargetRootWindow()|. 636 // This must be before |SwitchTargetRootWindow()|.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 // Panning up. 709 // Panning up.
656 y_diff = point.y() - (top + y_target_margin); 710 y_diff = point.y() - (top + y_target_margin);
657 start_zoom = true; 711 start_zoom = true;
658 } else if (bottom - y_panning_margin < point.y()) { 712 } else if (bottom - y_panning_margin < point.y()) {
659 // Panning down. 713 // Panning down.
660 y_diff = point.y() - (bottom - y_target_margin); 714 y_diff = point.y() - (bottom - y_target_margin);
661 start_zoom = true; 715 start_zoom = true;
662 } 716 }
663 int y = top + y_diff; 717 int y = top + y_diff;
664 if (start_zoom && !is_on_animation_) { 718 if (start_zoom && !is_on_animation_) {
665 // No animation on panning. 719 bool ret = RedrawDIP(gfx::Point(x, y), scale_,
666 bool animate = false; 720 0, // No animation on panning.
667 bool ret = RedrawDIP(gfx::Point(x, y), scale_, animate); 721 kDefaultAnimationTweenType);
668 722
669 if (ret) { 723 if (ret) {
670 // If the magnified region is moved, hides the mouse cursor and moves it. 724 // If the magnified region is moved, hides the mouse cursor and moves it.
671 if (x_diff != 0 || y_diff != 0) 725 if (x_diff != 0 || y_diff != 0)
672 MoveCursorTo(root_window_->GetHost(), point); 726 MoveCursorTo(root_window_->GetHost(), point);
673 } 727 }
674 } 728 }
675 } 729 }
676 730
731 void MagnificationControllerImpl::MoveMagnifierWindowCenterPoint(
732 const gfx::Point& point) {
733 DCHECK(root_window_);
734
735 const gfx::Rect window_rect = GetViewportRect();
736 if (point == window_rect.CenterPoint())
737 return;
738
739 int x = window_rect.x() + point.x() - window_rect.CenterPoint().x();
740 int y = window_rect.y() + point.y() - window_rect.CenterPoint().y();
oshima 2015/05/28 22:41:35 window_rect.origin() + point - window_rect.CenterP
jennyz 2015/05/29 21:41:24 Done.
741
742 if (!is_on_animation_) {
743 // With animation on panning.
744 RedrawDIP(gfx::Point(x, y), scale_, kDefaultAnimationDurationInMs,
745 kCenterCaretAnimationTweenType);
746 }
747 }
748
677 void MagnificationControllerImpl::MoveMagnifierWindowFollowRect( 749 void MagnificationControllerImpl::MoveMagnifierWindowFollowRect(
678 const gfx::Rect& rect) { 750 const gfx::Rect& rect) {
679 DCHECK(root_window_); 751 DCHECK(root_window_);
680 bool should_pan = false; 752 bool should_pan = false;
681 753
682 const gfx::Rect viewport_rect = GetViewportRect(); 754 const gfx::Rect viewport_rect = GetViewportRect();
683 const int left = viewport_rect.x(); 755 const int left = viewport_rect.x();
684 const int right = viewport_rect.right(); 756 const int right = viewport_rect.right();
685 const gfx::Point rect_center = rect.CenterPoint(); 757 const gfx::Point rect_center = rect.CenterPoint();
686 const gfx::Point window_center = viewport_rect.CenterPoint(); 758 const gfx::Point window_center = viewport_rect.CenterPoint();
(...skipping 13 matching lines...) Expand all
700 // Panning vertically. 772 // Panning vertically.
701 y = rect_center.y() - viewport_rect.height() / 2; 773 y = rect_center.y() - viewport_rect.height() / 2;
702 should_pan = true; 774 should_pan = true;
703 } 775 }
704 776
705 if (should_pan) { 777 if (should_pan) {
706 if (is_on_animation_) { 778 if (is_on_animation_) {
707 root_window_->layer()->GetAnimator()->StopAnimating(); 779 root_window_->layer()->GetAnimator()->StopAnimating();
708 is_on_animation_ = false; 780 is_on_animation_ = false;
709 } 781 }
710 RedrawDIP(gfx::Point(x, y), scale_, false); // No animation on panning. 782 RedrawDIP(gfx::Point(x, y), scale_,
783 0, // No animation on panning.
784 kDefaultAnimationTweenType);
711 } 785 }
712 } 786 }
713 787
788 void MagnificationControllerImpl::OnMoveMagnifierTimer() {
789 MoveMagnifierWindowCenterPoint(caret_point_);
790 }
791
714 void MagnificationControllerImpl::OnCaretBoundsChanged( 792 void MagnificationControllerImpl::OnCaretBoundsChanged(
715 const ui::TextInputClient* client) { 793 const ui::TextInputClient* client) {
716 // caret bounds in screen coordinates. 794 // caret bounds in screen coordinates.
717 const gfx::Rect caret_bounds = client->GetCaretBounds(); 795 const gfx::Rect caret_bounds = client->GetCaretBounds();
718 // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during 796 // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during
719 // which the caret position is not set a meaning position, and we do not 797 // 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. 798 // 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 799 // This is only a transition period, the caret position will be fixed upon
722 // focusing right after. 800 // focusing right after.
723 if (caret_bounds.width() == 0 && caret_bounds.height() == 0) 801 if (caret_bounds.width() == 0 && caret_bounds.height() == 0)
724 return; 802 return;
725 803
726 gfx::Point caret_origin = caret_bounds.origin(); 804 caret_point_ = caret_bounds.CenterPoint();
727 // caret_origin in |root_window_| coordinates. 805 // |caret_point_| in |root_window_| coordinates.
728 wm::ConvertPointFromScreen(root_window_, &caret_origin); 806 wm::ConvertPointFromScreen(root_window_, &caret_point_);
729 807
730 // Visible window_rect in |root_window_| coordinates. 808 // If the feature for centering the text input focus is disabled, the
731 const gfx::Rect visible_window_rect = GetViewportRect(); 809 // magnifier window will be moved to follow the focus with a panning margin.
810 if (!KeepFocusCentered()) {
811 // Visible window_rect in |root_window_| coordinates.
812 const gfx::Rect visible_window_rect = GetViewportRect();
813 const int panning_margin = kCaretPanningMargin / scale_;
814 MoveMagnifierWindowFollowPoint(caret_point_,
815 panning_margin,
816 panning_margin,
817 visible_window_rect.width() / 2,
818 visible_window_rect.height() / 2);
819 return;
820 }
732 821
733 const int panning_margin = kCaretPanningMargin / scale_; 822 // Move the magnifier window to center the focus with a little delay.
734 MoveMagnifierWindowFollowPoint(caret_origin, panning_margin, panning_margin, 823 // In Gmail compose window, when user types a blank space, it will insert
735 visible_window_rect.width() / 2, 824 // a non-breaking space(NBSP). NBSP will be replaced with a blank space
736 visible_window_rect.height() / 2); 825 // character when user types a non-blank space character later, which causes
826 // OnCaretBoundsChanged be called twice. The first call moves the caret back
827 // to the character position just before NBSP, replaces the NBSP with blank
828 // space plus the new character, then the second call will move caret to the
829 // position after the new character. In order to avoid the magnifier window
830 // being moved back and forth with these two OnCaretBoundsChanged events, we
831 // defer moving magnifier window until the |move_magnifier_timer_| fires,
832 // when the caret settles eventually.
833 move_magnifier_timer_.Stop();
834 move_magnifier_timer_.Start(
835 FROM_HERE, base::TimeDelta::FromMilliseconds(kMoveMagnifierDelayInMs),
836 this, &MagnificationControllerImpl::OnMoveMagnifierTimer);
oshima 2015/05/28 22:41:35 Am I correct that this depends on the timing and m
jennyz 2015/05/29 21:41:23 Well, I guess it depends on how gmail code is impl
oshima 2015/05/29 22:34:25 I just wanted to double check if my understanding
jennyz 2015/05/30 00:12:58 Done.
737 } 837 }
738 838
739 //////////////////////////////////////////////////////////////////////////////// 839 ////////////////////////////////////////////////////////////////////////////////
740 // MagnificationController: 840 // MagnificationController:
741 841
742 // static 842 // static
743 MagnificationController* MagnificationController::CreateInstance() { 843 MagnificationController* MagnificationController::CreateInstance() {
744 return new MagnificationControllerImpl(); 844 return new MagnificationControllerImpl();
745 } 845 }
746 846
747 } // namespace ash 847 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698