Flutter Linux Embedder
fl_scrolling_manager.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 static constexpr int kMicrosecondsPerMillisecond = 1000;
8 
10  GObject parent_instance;
11 
12  FlScrollingViewDelegate* view_delegate;
13 
14  gdouble last_x;
15  gdouble last_y;
16 
17  gboolean pan_started;
18  gdouble pan_x;
19  gdouble pan_y;
20 
21  gboolean zoom_started;
22  gboolean rotate_started;
23  gdouble scale;
24  gdouble rotation;
25 };
26 
27 G_DEFINE_TYPE(FlScrollingManager, fl_scrolling_manager, G_TYPE_OBJECT);
28 
29 static void fl_scrolling_manager_dispose(GObject* object) {
30  FlScrollingManager* self = FL_SCROLLING_MANAGER(object);
31 
32  if (self->view_delegate != nullptr) {
33  g_object_remove_weak_pointer(
34  object, reinterpret_cast<gpointer*>(&self->view_delegate));
35  self->view_delegate = nullptr;
36  }
37 
38  G_OBJECT_CLASS(fl_scrolling_manager_parent_class)->dispose(object);
39 }
40 
41 static void fl_scrolling_manager_class_init(FlScrollingManagerClass* klass) {
42  G_OBJECT_CLASS(klass)->dispose = fl_scrolling_manager_dispose;
43 }
44 
45 static void fl_scrolling_manager_init(FlScrollingManager* self) {}
46 
47 FlScrollingManager* fl_scrolling_manager_new(
48  FlScrollingViewDelegate* view_delegate) {
49  g_return_val_if_fail(FL_IS_SCROLLING_VIEW_DELEGATE(view_delegate), nullptr);
50 
51  FlScrollingManager* self = FL_SCROLLING_MANAGER(
52  g_object_new(fl_scrolling_manager_get_type(), nullptr));
53 
54  self->view_delegate = view_delegate;
55  g_object_add_weak_pointer(
56  G_OBJECT(view_delegate),
57  reinterpret_cast<gpointer*>(&(self->view_delegate)));
58 
59  self->pan_started = FALSE;
60  self->zoom_started = FALSE;
61  self->rotate_started = FALSE;
62 
63  return self;
64 }
65 
66 void fl_scrolling_manager_set_last_mouse_position(FlScrollingManager* self,
67  gdouble x,
68  gdouble y) {
69  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
70  self->last_x = x;
71  self->last_y = y;
72 }
73 
74 void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self,
75  GdkEventScroll* scroll_event,
76  gint scale_factor) {
77  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
78 
79  GdkEvent* event = reinterpret_cast<GdkEvent*>(scroll_event);
80 
81  guint event_time = gdk_event_get_time(event);
82  gdouble event_x = 0.0, event_y = 0.0;
83  gdk_event_get_coords(event, &event_x, &event_y);
84  gdouble scroll_delta_x = 0.0, scroll_delta_y = 0.0;
85  GdkScrollDirection event_direction = GDK_SCROLL_SMOOTH;
86  if (gdk_event_get_scroll_direction(event, &event_direction)) {
87  if (event_direction == GDK_SCROLL_UP) {
88  scroll_delta_x = 0;
89  scroll_delta_y = -1;
90  } else if (event_direction == GDK_SCROLL_DOWN) {
91  scroll_delta_x = 0;
92  scroll_delta_y = 1;
93  } else if (event_direction == GDK_SCROLL_LEFT) {
94  scroll_delta_x = -1;
95  scroll_delta_y = 0;
96  } else if (event_direction == GDK_SCROLL_RIGHT) {
97  scroll_delta_x = 1;
98  scroll_delta_y = 0;
99  }
100  } else {
101  gdk_event_get_scroll_deltas(event, &scroll_delta_x, &scroll_delta_y);
102  }
103 
104  // The multiplier is taken from the Chromium source
105  // (ui/events/x/events_x_utils.cc).
106  const int kScrollOffsetMultiplier = 53;
107  scroll_delta_x *= kScrollOffsetMultiplier * scale_factor;
108  scroll_delta_y *= kScrollOffsetMultiplier * scale_factor;
109 
110  if (gdk_device_get_source(gdk_event_get_source_device(event)) ==
111  GDK_SOURCE_TOUCHPAD) {
112  scroll_delta_x *= -1;
113  scroll_delta_y *= -1;
114  if (gdk_event_is_scroll_stop_event(event)) {
116  self->view_delegate, event_time * kMicrosecondsPerMillisecond,
117  event_x * scale_factor, event_y * scale_factor, kPanZoomEnd,
118  self->pan_x, self->pan_y, 0, 0);
119  self->pan_started = FALSE;
120  } else {
121  if (!self->pan_started) {
122  self->pan_x = 0;
123  self->pan_y = 0;
125  self->view_delegate, event_time * kMicrosecondsPerMillisecond,
126  event_x * scale_factor, event_y * scale_factor, kPanZoomStart, 0, 0,
127  0, 0);
128  self->pan_started = TRUE;
129  }
130  self->pan_x += scroll_delta_x;
131  self->pan_y += scroll_delta_y;
133  self->view_delegate, event_time * kMicrosecondsPerMillisecond,
134  event_x * scale_factor, event_y * scale_factor, kPanZoomUpdate,
135  self->pan_x, self->pan_y, 1, 0);
136  }
137  } else {
138  self->last_x = event_x * scale_factor;
139  self->last_y = event_y * scale_factor;
141  self->view_delegate,
142  FlutterPointerPhase::kMove /* arbitrary value, phase will be ignored as
143  this is a discrete scroll event */
144  ,
145  event_time * kMicrosecondsPerMillisecond, event_x * scale_factor,
146  event_y * scale_factor, kFlutterPointerDeviceKindMouse, scroll_delta_x,
147  scroll_delta_y, 0);
148  }
149 }
150 
151 void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager* self) {
152  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
153 
154  self->rotate_started = TRUE;
155  if (!self->zoom_started) {
156  self->scale = 1;
157  self->rotation = 0;
159  self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
160  kPanZoomStart, 0, 0, 0, 0);
161  }
162 }
163 
164 void fl_scrolling_manager_handle_rotation_update(FlScrollingManager* self,
165  gdouble rotation) {
166  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
167 
168  self->rotation = rotation;
170  self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
171  kPanZoomUpdate, 0, 0, self->scale, self->rotation);
172 }
173 
174 void fl_scrolling_manager_handle_rotation_end(FlScrollingManager* self) {
175  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
176 
177  self->rotate_started = FALSE;
178  if (!self->zoom_started) {
180  self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
181  kPanZoomEnd, 0, 0, 0, 0);
182  }
183 }
184 
185 void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager* self) {
186  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
187 
188  self->zoom_started = TRUE;
189  if (!self->rotate_started) {
190  self->scale = 1;
191  self->rotation = 0;
193  self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
194  kPanZoomStart, 0, 0, 0, 0);
195  }
196 }
197 
198 void fl_scrolling_manager_handle_zoom_update(FlScrollingManager* self,
199  gdouble scale) {
200  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
201 
202  self->scale = scale;
204  self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
205  kPanZoomUpdate, 0, 0, self->scale, self->rotation);
206 }
207 
208 void fl_scrolling_manager_handle_zoom_end(FlScrollingManager* self) {
209  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
210 
211  self->zoom_started = FALSE;
212  if (!self->rotate_started) {
214  self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
215  kPanZoomEnd, 0, 0, 0, 0);
216  }
217 }
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
_FlScrollingManager
Definition: fl_scrolling_manager.cc:9
fl_scrolling_manager_handle_zoom_end
void fl_scrolling_manager_handle_zoom_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:208
fl_scrolling_manager_handle_scroll_event
void fl_scrolling_manager_handle_scroll_event(FlScrollingManager *self, GdkEventScroll *scroll_event, gint scale_factor)
Definition: fl_scrolling_manager.cc:74
_FlScrollingManager::pan_x
gdouble pan_x
Definition: fl_scrolling_manager.cc:18
_FlScrollingManager::pan_y
gdouble pan_y
Definition: fl_scrolling_manager.cc:19
_FlScrollingManager::zoom_started
gboolean zoom_started
Definition: fl_scrolling_manager.cc:21
fl_scrolling_manager_class_init
static void fl_scrolling_manager_class_init(FlScrollingManagerClass *klass)
Definition: fl_scrolling_manager.cc:41
G_DEFINE_TYPE
G_DEFINE_TYPE(FlScrollingManager, fl_scrolling_manager, G_TYPE_OBJECT)
fl_scrolling_manager_dispose
static void fl_scrolling_manager_dispose(GObject *object)
Definition: fl_scrolling_manager.cc:29
fl_scrolling_manager_new
FlScrollingManager * fl_scrolling_manager_new(FlScrollingViewDelegate *view_delegate)
Definition: fl_scrolling_manager.cc:47
_FlScrollingManager::scale
gdouble scale
Definition: fl_scrolling_manager.cc:23
fl_scrolling_manager_set_last_mouse_position
void fl_scrolling_manager_set_last_mouse_position(FlScrollingManager *self, gdouble x, gdouble y)
Definition: fl_scrolling_manager.cc:66
fl_scrolling_view_delegate_send_mouse_pointer_event
void fl_scrolling_view_delegate_send_mouse_pointer_event(FlScrollingViewDelegate *self, FlutterPointerPhase phase, size_t timestamp, double x, double y, FlutterPointerDeviceKind device_kind, double scroll_delta_x, double scroll_delta_y, int64_t buttons)
Definition: fl_scrolling_view_delegate.cc:14
_FlScrollingManager::pan_started
gboolean pan_started
Definition: fl_scrolling_manager.cc:17
_FlScrollingManager::rotation
gdouble rotation
Definition: fl_scrolling_manager.cc:24
fl_scrolling_manager.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_scrolling_manager_handle_zoom_update
void fl_scrolling_manager_handle_zoom_update(FlScrollingManager *self, gdouble scale)
Definition: fl_scrolling_manager.cc:198
_FlScrollingManager::view_delegate
FlScrollingViewDelegate * view_delegate
Definition: fl_scrolling_manager.cc:12
fl_scrolling_manager_init
static void fl_scrolling_manager_init(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:45
fl_scrolling_manager_handle_rotation_update
void fl_scrolling_manager_handle_rotation_update(FlScrollingManager *self, gdouble rotation)
Definition: fl_scrolling_manager.cc:164
_FlScrollingManager::parent_instance
GObject parent_instance
Definition: fl_scrolling_manager.cc:10
_FlScrollingManager::last_x
gdouble last_x
Definition: fl_scrolling_manager.cc:14
_FlScrollingManager::rotate_started
gboolean rotate_started
Definition: fl_scrolling_manager.cc:22
kMicrosecondsPerMillisecond
static constexpr int kMicrosecondsPerMillisecond
Definition: fl_scrolling_manager.cc:7
fl_scrolling_manager_handle_rotation_end
void fl_scrolling_manager_handle_rotation_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:174
fl_scrolling_manager_handle_rotation_begin
void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:151
_FlScrollingManager::last_y
gdouble last_y
Definition: fl_scrolling_manager.cc:15
fl_scrolling_manager_handle_zoom_begin
void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:185
fl_scrolling_view_delegate_send_pointer_pan_zoom_event
void fl_scrolling_view_delegate_send_pointer_pan_zoom_event(FlScrollingViewDelegate *self, size_t timestamp, double x, double y, FlutterPointerPhase phase, double pan_x, double pan_y, double scale, double rotation)
Definition: fl_scrolling_view_delegate.cc:30