Flutter Linux Embedder
fl_scrolling_manager_test.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <cstring>
8 #include <vector>
9 
10 #include "gtest/gtest.h"
11 namespace {
12 typedef std::function<void(FlutterPointerPhase phase,
13  size_t timestamp,
14  double x,
15  double y,
16  double scroll_delta_x,
17  double scroll_delta_y,
18  int64_t buttons)>
19  MousePointerCallHandler;
20 typedef std::function<void(size_t timestamp,
21  double x,
22  double y,
23  FlutterPointerPhase phase,
24  double pan_x,
25  double pan_y,
26  double scale,
27  double rotation)>
28  PointerPanZoomCallHandler;
29 
30 typedef struct {
31  FlutterPointerPhase phase;
32  size_t timestamp;
33  double x;
34  double y;
35  double scroll_delta_x;
36  double scroll_delta_y;
37  int64_t buttons;
38 } MousePointerEventRecord;
39 
40 typedef struct {
41  size_t timestamp;
42  double x;
43  double y;
44  FlutterPointerPhase phase;
45  double pan_x;
46  double pan_y;
47  double scale;
48  double rotation;
49 } PointerPanZoomEventRecord;
50 
51 G_BEGIN_DECLS
52 
53 G_DECLARE_FINAL_TYPE(FlMockScrollingViewDelegate,
54  fl_mock_scrolling_view_delegate,
55  FL,
56  MOCK_SCROLLING_VIEW_DELEGATE,
57  GObject)
58 
59 G_END_DECLS
60 
61 /***** FlMockScrollingViewDelegate *****/
62 
63 struct _FlMockScrollingViewDelegate {
64  GObject parent_instance;
65 
66  MousePointerCallHandler mouse_handler;
67  PointerPanZoomCallHandler pan_zoom_handler;
68 };
69 
70 static void fl_mock_view_scroll_delegate_iface_init(
71  FlScrollingViewDelegateInterface* iface);
72 
74  FlMockScrollingViewDelegate,
75  fl_mock_scrolling_view_delegate,
76  G_TYPE_OBJECT,
77  G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(),
78  fl_mock_view_scroll_delegate_iface_init))
79 
80 static void fl_mock_scrolling_view_delegate_init(
81  FlMockScrollingViewDelegate* self) {}
82 
83 static void fl_mock_scrolling_view_delegate_dispose(GObject* object) {
84  G_OBJECT_CLASS(fl_mock_scrolling_view_delegate_parent_class)->dispose(object);
85 }
86 
87 static void fl_mock_scrolling_view_delegate_class_init(
88  FlMockScrollingViewDelegateClass* klass) {
89  G_OBJECT_CLASS(klass)->dispose = fl_mock_scrolling_view_delegate_dispose;
90 }
91 
92 static void fl_mock_view_send_mouse_pointer_event(
93  FlScrollingViewDelegate* delegate,
94  FlutterPointerPhase phase,
95  size_t timestamp,
96  double x,
97  double y,
98  double scroll_delta_x,
99  double scroll_delta_y,
100  int64_t buttons) {
101  FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(delegate);
102  self->mouse_handler(phase, timestamp, x, y, scroll_delta_x, scroll_delta_y,
103  buttons);
104 }
105 
106 static void fl_mock_view_send_pointer_pan_zoom_event(
107  FlScrollingViewDelegate* delegate,
108  size_t timestamp,
109  double x,
110  double y,
111  FlutterPointerPhase phase,
112  double pan_x,
113  double pan_y,
114  double scale,
115  double rotation) {
116  FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(delegate);
117  self->pan_zoom_handler(timestamp, x, y, phase, pan_x, pan_y, scale, rotation);
118 }
119 
120 static void fl_mock_view_scroll_delegate_iface_init(
121  FlScrollingViewDelegateInterface* iface) {
122  iface->send_mouse_pointer_event = fl_mock_view_send_mouse_pointer_event;
123  iface->send_pointer_pan_zoom_event = fl_mock_view_send_pointer_pan_zoom_event;
124 }
125 
126 static FlMockScrollingViewDelegate* fl_mock_scrolling_view_delegate_new() {
127  FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(
128  g_object_new(fl_mock_scrolling_view_delegate_get_type(), nullptr));
129 
130  // Added to stop compiler complaining about an unused function.
131  FL_IS_MOCK_SCROLLING_VIEW_DELEGATE(self);
132 
133  return self;
134 }
135 
136 static void fl_mock_scrolling_view_set_mouse_handler(
137  FlMockScrollingViewDelegate* self,
138  MousePointerCallHandler handler) {
139  self->mouse_handler = std::move(handler);
140 }
141 
142 static void fl_mock_scrolling_view_set_pan_zoom_handler(
143  FlMockScrollingViewDelegate* self,
144  PointerPanZoomCallHandler handler) {
145  self->pan_zoom_handler = std::move(handler);
146 }
147 
148 /***** End FlMockScrollingViewDelegate *****/
149 
150 class ScrollingTester {
151  public:
152  ScrollingTester() {
153  view_ = fl_mock_scrolling_view_delegate_new();
154  manager_ = fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(view_));
155  fl_mock_scrolling_view_set_mouse_handler(
156  view_,
157  [](FlutterPointerPhase phase, size_t timestamp, double x, double y,
158  double scroll_delta_x, double scroll_delta_y, int64_t buttons) {
159  // do nothing
160  });
161  fl_mock_scrolling_view_set_pan_zoom_handler(
162  view_,
163  [](size_t timestamp, double x, double y, FlutterPointerPhase phase,
164  double pan_x, double pan_y, double scale, double rotation) {
165  // do nothing
166  });
167  }
168 
169  ~ScrollingTester() {
170  g_clear_object(&view_);
171  g_clear_object(&manager_);
172  }
173 
174  FlScrollingManager* manager() { return manager_; }
175 
176  void recordMousePointerCallsTo(
177  std::vector<MousePointerEventRecord>& storage) {
178  fl_mock_scrolling_view_set_mouse_handler(
179  view_, [&storage](FlutterPointerPhase phase, size_t timestamp, double x,
180  double y, double scroll_delta_x,
181  double scroll_delta_y, int64_t buttons) {
182  storage.push_back(MousePointerEventRecord{
183  .phase = phase,
184  .timestamp = timestamp,
185  .x = x,
186  .y = y,
187  .scroll_delta_x = scroll_delta_x,
188  .scroll_delta_y = scroll_delta_y,
189  .buttons = buttons,
190  });
191  });
192  }
193 
194  void recordPointerPanZoomCallsTo(
195  std::vector<PointerPanZoomEventRecord>& storage) {
196  fl_mock_scrolling_view_set_pan_zoom_handler(
197  view_, [&storage](size_t timestamp, double x, double y,
198  FlutterPointerPhase phase, double pan_x, double pan_y,
199  double scale, double rotation) {
200  storage.push_back(PointerPanZoomEventRecord{
201  .timestamp = timestamp,
202  .x = x,
203  .y = y,
204  .phase = phase,
205  .pan_x = pan_x,
206  .pan_y = pan_y,
207  .scale = scale,
208  .rotation = rotation,
209  });
210  });
211  }
212 
213  private:
214  FlMockScrollingViewDelegate* view_;
215  FlScrollingManager* manager_;
216 };
217 
218 // Disgusting hack but could not find any way to create a GdkDevice
219 struct _FakeGdkDevice {
220  GObject parent_instance;
221  gchar* name;
222  GdkInputSource source;
223 };
224 GdkDevice* makeFakeDevice(GdkInputSource source) {
225  _FakeGdkDevice* device =
226  static_cast<_FakeGdkDevice*>(g_malloc0(sizeof(_FakeGdkDevice)));
227  device->source = source;
228  // Bully the type checker
229  (reinterpret_cast<GTypeInstance*>(device))->g_class =
230  static_cast<GTypeClass*>(g_malloc0(sizeof(GTypeClass)));
231  (reinterpret_cast<GTypeInstance*>(device))->g_class->g_type = GDK_TYPE_DEVICE;
232  return reinterpret_cast<GdkDevice*>(device);
233 }
234 
235 TEST(FlScrollingManagerTest, DiscreteDirectionional) {
236  ScrollingTester tester;
237  std::vector<MousePointerEventRecord> mouse_records;
238  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
239  tester.recordMousePointerCallsTo(mouse_records);
240  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
241  GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE);
242  GdkEventScroll* event =
243  reinterpret_cast<GdkEventScroll*>(gdk_event_new(GDK_SCROLL));
244  event->time = 1;
245  event->x = 4.0;
246  event->y = 8.0;
247  event->device = mouse;
248  event->direction = GDK_SCROLL_UP;
249  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
250  EXPECT_EQ(pan_zoom_records.size(), 0u);
251  EXPECT_EQ(mouse_records.size(), 1u);
252  EXPECT_EQ(mouse_records[0].x, 4.0);
253  EXPECT_EQ(mouse_records[0].y, 8.0);
254  EXPECT_EQ(mouse_records[0].timestamp,
255  1000lu); // Milliseconds -> Microseconds
256  EXPECT_EQ(mouse_records[0].scroll_delta_x, 0);
257  EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * -1.0);
258  event->direction = GDK_SCROLL_DOWN;
259  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
260  EXPECT_EQ(pan_zoom_records.size(), 0u);
261  EXPECT_EQ(mouse_records.size(), 2u);
262  EXPECT_EQ(mouse_records[1].x, 4.0);
263  EXPECT_EQ(mouse_records[1].y, 8.0);
264  EXPECT_EQ(mouse_records[1].timestamp,
265  1000lu); // Milliseconds -> Microseconds
266  EXPECT_EQ(mouse_records[1].scroll_delta_x, 0);
267  EXPECT_EQ(mouse_records[1].scroll_delta_y, 53 * 1.0);
268  event->direction = GDK_SCROLL_LEFT;
269  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
270  EXPECT_EQ(pan_zoom_records.size(), 0u);
271  EXPECT_EQ(mouse_records.size(), 3u);
272  EXPECT_EQ(mouse_records[2].x, 4.0);
273  EXPECT_EQ(mouse_records[2].y, 8.0);
274  EXPECT_EQ(mouse_records[2].timestamp,
275  1000lu); // Milliseconds -> Microseconds
276  EXPECT_EQ(mouse_records[2].scroll_delta_x, 53 * -1.0);
277  EXPECT_EQ(mouse_records[2].scroll_delta_y, 0);
278  event->direction = GDK_SCROLL_RIGHT;
279  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
280  EXPECT_EQ(pan_zoom_records.size(), 0u);
281  EXPECT_EQ(mouse_records.size(), 4u);
282  EXPECT_EQ(mouse_records[3].x, 4.0);
283  EXPECT_EQ(mouse_records[3].y, 8.0);
284  EXPECT_EQ(mouse_records[3].timestamp,
285  1000lu); // Milliseconds -> Microseconds
286  EXPECT_EQ(mouse_records[3].scroll_delta_x, 53 * 1.0);
287  EXPECT_EQ(mouse_records[3].scroll_delta_y, 0);
288 }
289 
290 TEST(FlScrollingManagerTest, DiscreteScrolling) {
291  ScrollingTester tester;
292  std::vector<MousePointerEventRecord> mouse_records;
293  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
294  tester.recordMousePointerCallsTo(mouse_records);
295  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
296  GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE);
297  GdkEventScroll* event =
298  reinterpret_cast<GdkEventScroll*>(gdk_event_new(GDK_SCROLL));
299  event->time = 1;
300  event->x = 4.0;
301  event->y = 8.0;
302  event->delta_x = 1.0;
303  event->delta_y = 2.0;
304  event->device = mouse;
305  event->direction = GDK_SCROLL_SMOOTH;
306  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
307  EXPECT_EQ(pan_zoom_records.size(), 0u);
308  EXPECT_EQ(mouse_records.size(), 1u);
309  EXPECT_EQ(mouse_records[0].x, 4.0);
310  EXPECT_EQ(mouse_records[0].y, 8.0);
311  EXPECT_EQ(mouse_records[0].timestamp,
312  1000lu); // Milliseconds -> Microseconds
313  EXPECT_EQ(mouse_records[0].scroll_delta_x, 53 * 1.0);
314  EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * 2.0);
315 }
316 
317 TEST(FlScrollingManagerTest, Panning) {
318  ScrollingTester tester;
319  std::vector<MousePointerEventRecord> mouse_records;
320  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
321  tester.recordMousePointerCallsTo(mouse_records);
322  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
323  GdkDevice* touchpad = makeFakeDevice(GDK_SOURCE_TOUCHPAD);
324  GdkEventScroll* event =
325  reinterpret_cast<GdkEventScroll*>(gdk_event_new(GDK_SCROLL));
326  event->time = 1;
327  event->x = 4.0;
328  event->y = 8.0;
329  event->delta_x = 1.0;
330  event->delta_y = 2.0;
331  event->device = touchpad;
332  event->direction = GDK_SCROLL_SMOOTH;
333  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
334  EXPECT_EQ(pan_zoom_records.size(), 2u);
335  EXPECT_EQ(mouse_records.size(), 0u);
336  EXPECT_EQ(pan_zoom_records[0].x, 4.0);
337  EXPECT_EQ(pan_zoom_records[0].y, 8.0);
338  EXPECT_EQ(pan_zoom_records[0].timestamp,
339  1000lu); // Milliseconds -> Microseconds
340  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
341  EXPECT_EQ(pan_zoom_records[1].x, 4.0);
342  EXPECT_EQ(pan_zoom_records[1].y, 8.0);
343  EXPECT_EQ(pan_zoom_records[1].timestamp,
344  1000lu); // Milliseconds -> Microseconds
345  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
346  EXPECT_EQ(pan_zoom_records[1].pan_x, 53 * -1.0); // directions get swapped
347  EXPECT_EQ(pan_zoom_records[1].pan_y, 53 * -2.0);
348  EXPECT_EQ(pan_zoom_records[1].scale, 1.0);
349  EXPECT_EQ(pan_zoom_records[1].rotation, 0.0);
350  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
351  EXPECT_EQ(pan_zoom_records.size(), 3u);
352  EXPECT_EQ(mouse_records.size(), 0u);
353  EXPECT_EQ(pan_zoom_records[2].x, 4.0);
354  EXPECT_EQ(pan_zoom_records[2].y, 8.0);
355  EXPECT_EQ(pan_zoom_records[2].timestamp,
356  1000lu); // Milliseconds -> Microseconds
357  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
358  EXPECT_EQ(pan_zoom_records[2].pan_x, 53 * -2.0); // directions get swapped
359  EXPECT_EQ(pan_zoom_records[2].pan_y, 53 * -4.0);
360  EXPECT_EQ(pan_zoom_records[2].scale, 1.0);
361  EXPECT_EQ(pan_zoom_records[2].rotation, 0.0);
362  event->is_stop = true;
363  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
364  EXPECT_EQ(pan_zoom_records.size(), 4u);
365  EXPECT_EQ(mouse_records.size(), 0u);
366  EXPECT_EQ(pan_zoom_records[3].x, 4.0);
367  EXPECT_EQ(pan_zoom_records[3].y, 8.0);
368  EXPECT_EQ(pan_zoom_records[3].timestamp,
369  1000lu); // Milliseconds -> Microseconds
370  EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd);
371 }
372 
373 TEST(FlScrollingManagerTest, Zooming) {
374  ScrollingTester tester;
375  std::vector<MousePointerEventRecord> mouse_records;
376  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
377  tester.recordMousePointerCallsTo(mouse_records);
378  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
379  size_t time_start = g_get_real_time();
380  fl_scrolling_manager_handle_zoom_begin(tester.manager());
381  EXPECT_EQ(pan_zoom_records.size(), 1u);
382  EXPECT_EQ(mouse_records.size(), 0u);
383  EXPECT_EQ(pan_zoom_records[0].x, 0);
384  EXPECT_EQ(pan_zoom_records[0].y, 0);
385  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
386  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
387  fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
388  EXPECT_EQ(pan_zoom_records.size(), 2u);
389  EXPECT_EQ(mouse_records.size(), 0u);
390  EXPECT_EQ(pan_zoom_records[1].x, 0);
391  EXPECT_EQ(pan_zoom_records[1].y, 0);
392  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
393  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
394  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
395  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
396  EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
397  EXPECT_EQ(pan_zoom_records[1].rotation, 0);
398  fl_scrolling_manager_handle_zoom_end(tester.manager());
399  EXPECT_EQ(pan_zoom_records.size(), 3u);
400  EXPECT_EQ(mouse_records.size(), 0u);
401  EXPECT_EQ(pan_zoom_records[2].x, 0);
402  EXPECT_EQ(pan_zoom_records[2].y, 0);
403  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd);
404  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
405 }
406 
407 TEST(FlScrollingManagerTest, Rotating) {
408  ScrollingTester tester;
409  std::vector<MousePointerEventRecord> mouse_records;
410  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
411  tester.recordMousePointerCallsTo(mouse_records);
412  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
413  size_t time_start = g_get_real_time();
415  EXPECT_EQ(pan_zoom_records.size(), 1u);
416  EXPECT_EQ(mouse_records.size(), 0u);
417  EXPECT_EQ(pan_zoom_records[0].x, 0);
418  EXPECT_EQ(pan_zoom_records[0].y, 0);
419  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
420  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
421  fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
422  EXPECT_EQ(pan_zoom_records.size(), 2u);
423  EXPECT_EQ(mouse_records.size(), 0u);
424  EXPECT_EQ(pan_zoom_records[1].x, 0);
425  EXPECT_EQ(pan_zoom_records[1].y, 0);
426  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
427  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
428  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
429  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
430  EXPECT_EQ(pan_zoom_records[1].scale, 1.0);
431  EXPECT_EQ(pan_zoom_records[1].rotation, 0.5);
433  EXPECT_EQ(pan_zoom_records.size(), 3u);
434  EXPECT_EQ(mouse_records.size(), 0u);
435  EXPECT_EQ(pan_zoom_records[2].x, 0);
436  EXPECT_EQ(pan_zoom_records[2].y, 0);
437  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd);
438  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
439 }
440 
441 TEST(FlScrollingManagerTest, SynchronizedZoomingAndRotating) {
442  ScrollingTester tester;
443  std::vector<MousePointerEventRecord> mouse_records;
444  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
445  tester.recordMousePointerCallsTo(mouse_records);
446  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
447  size_t time_start = g_get_real_time();
448  fl_scrolling_manager_handle_zoom_begin(tester.manager());
449  EXPECT_EQ(pan_zoom_records.size(), 1u);
450  EXPECT_EQ(mouse_records.size(), 0u);
451  EXPECT_EQ(pan_zoom_records[0].x, 0);
452  EXPECT_EQ(pan_zoom_records[0].y, 0);
453  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
454  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
455  fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
456  EXPECT_EQ(pan_zoom_records.size(), 2u);
457  EXPECT_EQ(mouse_records.size(), 0u);
458  EXPECT_EQ(pan_zoom_records[1].x, 0);
459  EXPECT_EQ(pan_zoom_records[1].y, 0);
460  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
461  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
462  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
463  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
464  EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
465  EXPECT_EQ(pan_zoom_records[1].rotation, 0);
467  EXPECT_EQ(pan_zoom_records.size(), 2u);
468  EXPECT_EQ(mouse_records.size(), 0u);
469  fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
470  EXPECT_EQ(pan_zoom_records.size(), 3u);
471  EXPECT_EQ(pan_zoom_records[2].x, 0);
472  EXPECT_EQ(pan_zoom_records[2].y, 0);
473  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
474  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
475  EXPECT_EQ(pan_zoom_records[2].pan_x, 0);
476  EXPECT_EQ(pan_zoom_records[2].pan_y, 0);
477  EXPECT_EQ(pan_zoom_records[2].scale, 1.1);
478  EXPECT_EQ(pan_zoom_records[2].rotation, 0.5);
479  fl_scrolling_manager_handle_zoom_end(tester.manager());
480  // End event should only be sent after both zoom and rotate complete.
481  EXPECT_EQ(pan_zoom_records.size(), 3u);
483  EXPECT_EQ(pan_zoom_records.size(), 4u);
484  EXPECT_EQ(mouse_records.size(), 0u);
485  EXPECT_EQ(pan_zoom_records[3].x, 0);
486  EXPECT_EQ(pan_zoom_records[3].y, 0);
487  EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd);
488  EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp);
489 }
490 
491 // Make sure that zoom and rotate sequences which don't end at the same time
492 // don't cause any problems.
493 TEST(FlScrollingManagerTest, UnsynchronizedZoomingAndRotating) {
494  ScrollingTester tester;
495  std::vector<MousePointerEventRecord> mouse_records;
496  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
497  tester.recordMousePointerCallsTo(mouse_records);
498  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
499  size_t time_start = g_get_real_time();
500  fl_scrolling_manager_handle_zoom_begin(tester.manager());
501  EXPECT_EQ(pan_zoom_records.size(), 1u);
502  EXPECT_EQ(mouse_records.size(), 0u);
503  EXPECT_EQ(pan_zoom_records[0].x, 0);
504  EXPECT_EQ(pan_zoom_records[0].y, 0);
505  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
506  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
507  fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
508  EXPECT_EQ(pan_zoom_records.size(), 2u);
509  EXPECT_EQ(mouse_records.size(), 0u);
510  EXPECT_EQ(pan_zoom_records[1].x, 0);
511  EXPECT_EQ(pan_zoom_records[1].y, 0);
512  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
513  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
514  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
515  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
516  EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
517  EXPECT_EQ(pan_zoom_records[1].rotation, 0);
519  EXPECT_EQ(pan_zoom_records.size(), 2u);
520  EXPECT_EQ(mouse_records.size(), 0u);
521  fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
522  EXPECT_EQ(pan_zoom_records.size(), 3u);
523  EXPECT_EQ(pan_zoom_records[2].x, 0);
524  EXPECT_EQ(pan_zoom_records[2].y, 0);
525  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
526  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
527  EXPECT_EQ(pan_zoom_records[2].pan_x, 0);
528  EXPECT_EQ(pan_zoom_records[2].pan_y, 0);
529  EXPECT_EQ(pan_zoom_records[2].scale, 1.1);
530  EXPECT_EQ(pan_zoom_records[2].rotation, 0.5);
531  fl_scrolling_manager_handle_zoom_end(tester.manager());
532  EXPECT_EQ(pan_zoom_records.size(), 3u);
533  fl_scrolling_manager_handle_rotation_update(tester.manager(), 1.0);
534  EXPECT_EQ(pan_zoom_records.size(), 4u);
535  EXPECT_EQ(mouse_records.size(), 0u);
536  EXPECT_EQ(pan_zoom_records[3].x, 0);
537  EXPECT_EQ(pan_zoom_records[3].y, 0);
538  EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomUpdate);
539  EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp);
540  EXPECT_EQ(pan_zoom_records[3].pan_x, 0);
541  EXPECT_EQ(pan_zoom_records[3].pan_y, 0);
542  EXPECT_EQ(pan_zoom_records[3].scale, 1.1);
543  EXPECT_EQ(pan_zoom_records[3].rotation, 1.0);
545  EXPECT_EQ(pan_zoom_records.size(), 5u);
546  EXPECT_EQ(mouse_records.size(), 0u);
547  EXPECT_EQ(pan_zoom_records[4].x, 0);
548  EXPECT_EQ(pan_zoom_records[4].y, 0);
549  EXPECT_EQ(pan_zoom_records[4].phase, kPanZoomEnd);
550  EXPECT_GE(pan_zoom_records[4].timestamp, pan_zoom_records[3].timestamp);
551 }
552 
553 } // namespace
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
fl_scrolling_manager_handle_zoom_end
void fl_scrolling_manager_handle_zoom_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:174
G_DECLARE_FINAL_TYPE
G_BEGIN_DECLS G_DECLARE_FINAL_TYPE(FlAccessibilityPlugin, fl_accessibility_plugin, FL, ACCESSIBILITY_PLUGIN, GObject)
fl_scrolling_manager_new
FlScrollingManager * fl_scrolling_manager_new(FlScrollingViewDelegate *view_delegate)
Definition: fl_scrolling_manager.cc:41
fl_scrolling_manager.h
fl_scrolling_manager_handle_zoom_update
void fl_scrolling_manager_handle_zoom_update(FlScrollingManager *self, gdouble scale)
Definition: fl_scrolling_manager.cc:167
fl_scrolling_manager_handle_rotation_update
void fl_scrolling_manager_handle_rotation_update(FlScrollingManager *self, gdouble rotation)
Definition: fl_scrolling_manager.cc:141
FL
FL
Definition: fl_binary_messenger.cc:27
fl_scrolling_manager_handle_scroll_event
void fl_scrolling_manager_handle_scroll_event(FlScrollingManager *self, GdkEventScroll *event, gint scale_factor)
Definition: fl_scrolling_manager.cc:67
fl_scrolling_manager_handle_rotation_end
void fl_scrolling_manager_handle_rotation_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:148
TEST
TEST(FlAccessibleNodeTest, BuildTree)
Definition: fl_accessible_node_test.cc:12
fl_scrolling_manager_handle_rotation_begin
void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:130
fl_scrolling_manager_handle_zoom_begin
void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:157
G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE(FlAccessibleNode, fl_accessible_node, ATK_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT, fl_accessible_node_component_interface_init) G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION, fl_accessible_node_action_interface_init)) static gboolean flag_is_changed(FlutterSemanticsFlag old_flags