File: fullscreen_magnifier_controller.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (324 lines) | stat: -rw-r--r-- 12,855 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_ACCESSIBILITY_MAGNIFIER_FULLSCREEN_MAGNIFIER_CONTROLLER_H_
#define ASH_ACCESSIBILITY_MAGNIFIER_FULLSCREEN_MAGNIFIER_CONTROLLER_H_

#include <map>
#include <memory>

#include "ash/ash_export.h"
#include "ash/public/cpp/accessibility_controller_enums.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_rewriter.h"
#include "ui/events/gestures/gesture_types.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"

namespace aura {
class Window;
}  // namespace aura

namespace gfx {
class Transform;
}

namespace ui {
class GestureProviderAura;
}  // namespace ui

namespace ash {

// FullscreenMagnifierController implements GestureConsumer as it has its own
// GestureProvider to recognize gestures with screen coordinates of touches.
// Logical coordinates of touches cannot be used as they are changed with
// viewport change: scroll, zoom.
// FullscreenMagnifierController implements EventRewriter to see and rewrite
// touch events. Once the controller detects two fingers pinch or scroll, it
// starts consuming all touch events not to confuse an app or a browser on the
// screen. It needs to rewrite events to dispatch touch cancel events.
class ASH_EXPORT FullscreenMagnifierController
    : public ui::EventHandler,
      public ui::ImplicitAnimationObserver,
      public aura::WindowObserver,
      public ui::GestureConsumer,
      public ui::EventRewriter {
 public:
  enum ScrollDirection {
    SCROLL_NONE,
    SCROLL_LEFT,
    SCROLL_RIGHT,
    SCROLL_UP,
    SCROLL_DOWN
  };

  FullscreenMagnifierController();
  FullscreenMagnifierController(const FullscreenMagnifierController&) = delete;
  FullscreenMagnifierController& operator=(
      const FullscreenMagnifierController&) = delete;
  ~FullscreenMagnifierController() override;

  void set_mouse_following_mode(
      MagnifierMouseFollowingMode mouse_following_mode) {
    mouse_following_mode_ = mouse_following_mode;
  }

  MagnifierMouseFollowingMode mouse_following_mode() const {
    return mouse_following_mode_;
  }

  // Enables (or disables if |enabled| is false) screen magnifier feature.
  void SetEnabled(bool enabled);

  // Returns if the screen magnifier is enabled or not.
  bool IsEnabled() const;

  // Sets the magnification ratio. 1.0f means no magnification.
  void SetScale(float scale, bool animate);

  // Returns the current magnification ratio.
  float GetScale() const { return scale_; }

  // Maps the current scale value to an index in the range between the minimum
  // and maximum scale values, and steps up or down the scale depending on the
  // value of |delta_index|.
  void StepToNextScaleValue(int delta_index);

  // Set the top-left point of the magnification window.
  void MoveWindow(int x, int y, bool animate);
  void MoveWindow(const gfx::Point& point, bool animate);

  // Returns the current top-left point of the magnification window.
  gfx::Point GetWindowPosition() const;

  void SetScrollDirection(ScrollDirection direction);

  // Returns the viewport (i.e. the current visible window)'s Rect in root
  // window coordinates.
  gfx::Rect GetViewportRect() const;

  // Centers the viewport around the given point in screen coordinates.
  void CenterOnPoint(const gfx::Point& point_in_screen);

  // Move |rect_in_screen| within the magnifier viewport. If |rect_in_screen| is
  // already completely within the viewport, do nothing. If any edge of
  // |rect_in_screen| is outside the viewport (e.g. if rect is larger than or
  // extends partially beyond the viewport), center the overflowing dimensions
  // of the viewport on center of |rect_in_screen| (e.g. center viewport
  // vertically if |rect| extends beyond bottom of screen). Called from
  // Accessibility Common extension. Called from Accessibility Common extension.
  void HandleMoveMagnifierToRect(const gfx::Rect& rect_in_screen);

  // Switch the magnified root window to |new_root_window|. This does following:
  //  - Unzoom the current root_window.
  //  - Zoom the given new root_window |new_root_window|.
  //  - Switch the target window from current window to |new_root_window|.
  void SwitchTargetRootWindow(aura::Window* new_root_window,
                              bool redraw_original_root);

  // Returns the magnification transformation for the root window. If
  // magnification is disabled, return an empty Transform.
  gfx::Transform GetMagnifierTransform() const;

  // Returns the last mouse cursor (or last touched) location.
  gfx::Point GetPointOfInterestForTesting() {
    return point_of_interest_in_root_;
  }

  // Returns true if magnifier is still on animation for moving viewport.
  bool IsOnAnimationForTesting() const { return is_on_animation_; }

  // Returns the current number of touch points.
  int32_t GetTouchPointsForTesting() const { return touch_points_; }

  void set_cursor_moved_callback_for_testing(
      base::RepeatingCallback<void(const gfx::Point&)> callback) {
    cursor_moved_callback_for_testing_ = std::move(callback);
  }

 private:
  friend class FullscreenMagnifierControllerTest;
  class GestureProviderClient;

  // ui::ImplicitAnimationObserver overrides:
  void OnImplicitAnimationsCompleted() override;

  // aura::WindowObserver overrides:
  void OnWindowDestroying(aura::Window* root_window) override;
  void OnWindowBoundsChanged(aura::Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds,
                             ui::PropertyChangeReason reason) override;

  // ui::EventHandler overrides:
  void OnMouseEvent(ui::MouseEvent* event) override;
  void OnScrollEvent(ui::ScrollEvent* event) override;
  void OnTouchEvent(ui::TouchEvent* event) override;

  // ui::EventRewriter overrides:
  ui::EventDispatchDetails RewriteEvent(
      const ui::Event& event,
      const Continuation continuation) override;

  // ui::GestureConsumer:
  const std::string& GetName() const override;

  // Redraws the magnification window with the given origin position and the
  // given scale. Returns true if the window is changed; otherwise, false.
  // These methods should be called internally just after the scale and/or
  // the position are changed to redraw the window.
  bool Redraw(const gfx::PointF& position_in_pixels, float scale, bool animate);

  // Redraws the magnification window with the given origin position in dip and
  // the given scale. Returns true if the window is changed; otherwise, false.
  // The last two parameters specify the animation duration and tween type.
  // If |animation_in_ms| is zero, there will be no animation, and |tween_type|
  // will be ignored.
  bool RedrawDIP(const gfx::PointF& position_in_dip,
                 float scale,
                 int animation_in_ms,
                 gfx::Tween::Type tween_type);

  // 1) If the screen is scrolling (i.e. animating) and should scroll further,
  // it does nothing.
  // 2) If the screen is scrolling (i.e. animating) and the direction is NONE,
  // it stops the scrolling animation.
  // 3) If the direction is set to value other than NONE, it starts the
  // scrolling/ animation towards that direction.
  void StartOrStopScrollIfNecessary();

  // Redraw with the given zoom scale keeping the mouse cursor location. In
  // other words, zoom (or unzoom) centering around the cursor.
  // Ignore mouse position change after redrawing if |ignore_mouse_change| is
  // true.
  void RedrawKeepingMousePosition(float scale,
                                  bool animate,
                                  bool ignore_mouse_change);

  // Takes mouse root `location` in floating-point DIP. Note at higher zoom
  // levels, the floating point values matter more, because the ratio of px to
  // DIP increases.
  void OnMouseMove(const gfx::PointF& location);

  // Move the mouse cursot to the given point. Actual move will be done when
  // the animation is completed. This should be called after animation is
  // started.
  void AfterAnimationMoveCursorTo(const gfx::Point& location);

  // Returns if the magnification scale is 1.0 or not (larger then 1.0).
  bool IsMagnified() const;

  // Returns the rect of the magnification window.
  gfx::RectF GetWindowRectDIP(float scale) const;

  // Returns the size of the root window.
  gfx::Size GetHostSizeDIP() const;

  // Correct the given scale value if necessary.
  void ValidateScale(float* scale);

  // Process pending gestures in |gesture_provider_|. This method returns true
  // if the controller needs to cancel existing touches.
  bool ProcessGestures();

  // Moves the viewport when |point| is located within
  // |x_margin| and |y_margin| to the edge of the visible
  // window region. The viewport will be moved so that the |point| will be
  // moved to the point where it has |x_margin| and |y_margin|
  // to the edge of the visible region if possible (less if the mouse is closer
  // to the edge of the screen). If |reduce_bottom_margin| is true,
  // then a reduced value will be used as the |y_margin| and
  // |y_target_margin| for the bottom edge.
  void MoveMagnifierWindowFollowPoint(const gfx::Point& point,
                                      int x_margin,
                                      int y_margin,
                                      bool reduce_bottom_margin);

  // Moves the viewport to center |point| in magnifier screen.
  void MoveMagnifierWindowCenterPoint(const gfx::Point& point);

  // Moves the viewport so that |rect| is fully visible. If |rect| is larger
  // than the viewport horizontally or vertically, the viewport will be moved
  // to center the |rect| in that dimension.
  void MoveMagnifierWindowFollowRect(const gfx::Rect& rect);

  // Moves the cursor to the given location in the root window.
  void MoveCursorTo(const gfx::Point& root_location);

  // Target root window. This must not be NULL.
  raw_ptr<aura::Window> root_window_;

  // True if the magnified window is currently animating a change. Otherwise,
  // false.
  bool is_on_animation_ = false;

  bool is_enabled_ = false;

  bool keep_focus_centered_ = false;

  // The current mouse following mode (e.g. continuous, centered, edge).
  MagnifierMouseFollowingMode mouse_following_mode_ =
      MagnifierMouseFollowingMode::kEdge;

  // True if the cursor needs to move the given position after the animation
  // will be finished. When using this, set |position_after_animation_| as well.
  bool move_cursor_after_animation_ = false;

  // Stores the position of cursor to be moved after animation.
  gfx::Point position_after_animation_;

  // Stores the last mouse cursor (or last touched) location. This value is
  // used on zooming to keep this location visible.
  gfx::Point point_of_interest_in_root_;

  // Current scale, origin (left-top) position of the magnification window.
  float scale_;
  gfx::PointF origin_;

  float original_scale_;
  gfx::PointF original_origin_;

  ScrollDirection scroll_direction_ = SCROLL_NONE;

  // If true, FullscreenMagnifierController consumes all touch events.
  bool consume_touch_event_ = false;

  // Number of touch points on the screen.
  int32_t touch_points_ = 0;

  // Map for holding EventType::kTouchPress events. Those events are used to
  // dispatch EventType::kTouchCancelled events. Events will be removed from
  // this map when press events are cancelled, i.e. size of this map can be
  // different from number of touches on the screen. Key is pointer id.
  std::map<int32_t, std::unique_ptr<ui::TouchEvent>> press_event_map_;

  std::unique_ptr<GestureProviderClient> gesture_provider_client_;

  // MagnificationCotroller owns its GestureProvider to detect gestures with
  // screen coordinates of touch events. As FullscreenMagnifierController
  // changes zoom level and moves viewport, logical coordinates of touches
  // cannot be used for gesture detection as they are changed if the controller
  // reacts to gestures.
  std::unique_ptr<ui::GestureProviderAura> gesture_provider_;

  // Most recent caret position in |root_window_| coordinates.
  gfx::Point caret_point_;

  // Flag to draw a preview box around magnifier viewport area instead of
  // magnifying the screen for debugging.
  bool magnifier_debug_draw_rect_ = false;

  // Called every time MoveCursorTo is called, when set in tests.
  base::RepeatingCallback<void(const gfx::Point&)>
      cursor_moved_callback_for_testing_;
};

}  // namespace ash

#endif  // ASH_ACCESSIBILITY_MAGNIFIER_FULLSCREEN_MAGNIFIER_CONTROLLER_H_