Merge lp:~cimi/overlay-scrollbar/fine-scroll into lp:overlay-scrollbar

Proposed by Andrea Cimitan
Status: Merged
Approved by: Ted Gould
Approved revision: 287
Merged at revision: 284
Proposed branch: lp:~cimi/overlay-scrollbar/fine-scroll
Merge into: lp:overlay-scrollbar
Diff against target: 479 lines (+188/-171)
2 files modified
os/os-private.h (+1/-1)
os/os-scrollbar.c (+187/-170)
To merge this branch: bzr merge lp:~cimi/overlay-scrollbar/fine-scroll
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+67079@code.launchpad.net
To post a comment you must log in.
286. By Andrea Cimitan

Readd tolerance on pageup/down

287. By Andrea Cimitan

whitespace

Revision history for this message
Ted Gould (ted) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'os/os-private.h'
2--- os/os-private.h 2011-06-27 17:03:25 +0000
3+++ os/os-private.h 2011-07-06 21:03:28 +0000
4@@ -71,7 +71,7 @@
5 } \
6 } G_STMT_END
7
8-/* Macro loggging an error message to stderr and breaking the program execution
9+/* Macro logging an error message to stderr and breaking the program execution
10 * if the assertion fails. */
11 #define OS_CHECK(cond) \
12 G_STMT_START { \
13
14=== modified file 'os/os-scrollbar.c'
15--- os/os-scrollbar.c 2011-07-05 18:13:09 +0000
16+++ os/os-scrollbar.c 2011-07-06 21:03:28 +0000
17@@ -98,6 +98,7 @@
18 gboolean active_window;
19 gboolean can_deactivate_pager;
20 gboolean can_hide;
21+ gboolean detached_scroll;
22 gboolean filter;
23 gboolean fullsize;
24 gboolean internal;
25@@ -368,10 +369,7 @@
26 priv = scrollbar->priv;
27
28 if (priv->can_hide)
29- {
30- priv->value_changed_event = FALSE;
31- gtk_widget_hide (priv->thumb);
32- }
33+ gtk_widget_hide (priv->thumb);
34 }
35
36 /* timeout before hiding the thumb */
37@@ -773,19 +771,6 @@
38 gtk_adjustment_set_value (priv->adjustment, new_value);
39 }
40
41-/* stop_func called by the set-scroll animation */
42-static void
43-set_scroll_stop_cb (gpointer user_data)
44-{
45- OsScrollbar *scrollbar;
46- OsScrollbarPrivate *priv;
47-
48- scrollbar = OS_SCROLLBAR (user_data);
49- priv = scrollbar->priv;
50-
51- priv->value = gtk_adjustment_get_value (priv->adjustment);
52-}
53-
54 /* swap adjustment pointer */
55 static void
56 swap_adjustment (OsScrollbar *scrollbar,
57@@ -939,6 +924,91 @@
58 move_pager (scrollbar);
59 }
60
61+/* update the visual connection between pager and thumb. */
62+static void
63+update_visual_connection (OsScrollbar *scrollbar)
64+{
65+ OsScrollbarPrivate *priv;
66+ gint x_pos, y_pos;
67+
68+ priv = scrollbar->priv;
69+
70+ gdk_window_get_origin (gtk_widget_get_window (priv->thumb), &x_pos, &y_pos);
71+
72+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
73+ {
74+ if (priv->win_y + priv->overlay.y >= y_pos + priv->slider.height)
75+ {
76+ GdkRectangle mask;
77+
78+ mask.x = 0;
79+ mask.y = y_pos + priv->slider.height / 2 - priv->win_y;
80+ mask.width = priv->pager_all.width;
81+ mask.height = priv->overlay.y - mask.y;
82+
83+ os_pager_connect (priv->pager, mask);
84+ os_pager_set_detached (priv->pager, TRUE);
85+
86+ os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
87+ }
88+ else if (priv->win_y + priv->overlay.y + priv->overlay.height <= y_pos)
89+ {
90+ GdkRectangle mask;
91+
92+ mask.x = 0;
93+ mask.y = priv->overlay.y + priv->overlay.height;
94+ mask.width = priv->pager_all.width;
95+ mask.height = y_pos + priv->slider.height / 2 - priv->win_y - mask.y;
96+
97+ os_pager_connect (priv->pager, mask);
98+ os_pager_set_detached (priv->pager, TRUE);
99+
100+ os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
101+ }
102+ else
103+ {
104+ os_pager_set_detached (priv->pager, FALSE);
105+ os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
106+ }
107+ }
108+ else
109+ {
110+ if (priv->win_x + priv->overlay.x >= x_pos + priv->slider.width)
111+ {
112+ GdkRectangle mask;
113+
114+ mask.x = x_pos + priv->slider.width / 2 - priv->win_x;
115+ mask.y = 0;
116+ mask.width = priv->overlay.x - mask.x;
117+ mask.height = priv->pager_all.height;
118+
119+ os_pager_connect (priv->pager, mask);
120+ os_pager_set_detached (priv->pager, TRUE);
121+
122+ os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
123+ }
124+ else if (priv->win_x + priv->overlay.x + priv->overlay.width <= x_pos)
125+ {
126+ GdkRectangle mask;
127+
128+ mask.x = priv->overlay.x + priv->overlay.width;
129+ mask.y = 0;
130+ mask.width = x_pos + priv->slider.width / 2 - priv->win_x - mask.x;
131+ mask.height = priv->pager_all.height;
132+
133+ os_pager_connect (priv->pager, mask);
134+ os_pager_set_detached (priv->pager, TRUE);
135+
136+ os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
137+ }
138+ else
139+ {
140+ os_pager_set_detached (priv->pager, FALSE);
141+ os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
142+ }
143+ }
144+}
145+
146 static void
147 adjustment_value_changed_cb (GtkAdjustment *adjustment,
148 gpointer user_data)
149@@ -964,83 +1034,7 @@
150 os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
151 }
152 else
153- {
154- gint x_pos, y_pos;
155- gdk_window_get_origin (gtk_widget_get_window (priv->thumb), &x_pos, &y_pos);
156-
157- if (priv->orientation == GTK_ORIENTATION_VERTICAL)
158- {
159- if (priv->win_y + priv->overlay.y > y_pos + priv->slider.height)
160- {
161- GdkRectangle mask;
162-
163- mask.x = 0;
164- mask.y = y_pos + priv->slider.height / 2 - priv->win_y;
165- mask.width = priv->pager_all.width;
166- mask.height = priv->overlay.y - mask.y;
167-
168- os_pager_connect (priv->pager, mask);
169- os_pager_set_detached (priv->pager, TRUE);
170-
171- os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
172- }
173- else if (priv->win_y + priv->overlay.y + priv->overlay.height < y_pos)
174- {
175- GdkRectangle mask;
176-
177- mask.x = 0;
178- mask.y = priv->overlay.y + priv->overlay.height;
179- mask.width = priv->pager_all.width;
180- mask.height = y_pos + priv->slider.height / 2 - priv->win_y - mask.y;
181-
182- os_pager_connect (priv->pager, mask);
183- os_pager_set_detached (priv->pager, TRUE);
184-
185- os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
186- }
187- else
188- {
189- os_pager_set_detached (priv->pager, FALSE);
190- os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
191- }
192- }
193- else
194- {
195- if (priv->win_x + priv->overlay.x > x_pos + priv->slider.width)
196- {
197- GdkRectangle mask;
198-
199- mask.x = x_pos + priv->slider.width / 2 - priv->win_x;
200- mask.y = 0;
201- mask.width = priv->overlay.x - mask.x;
202- mask.height = priv->pager_all.height;
203-
204- os_pager_connect (priv->pager, mask);
205- os_pager_set_detached (priv->pager, TRUE);
206-
207- os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
208- }
209- else if (priv->win_x + priv->overlay.x + priv->overlay.width < x_pos)
210- {
211- GdkRectangle mask;
212-
213- mask.x = priv->overlay.x + priv->overlay.width;
214- mask.y = 0;
215- mask.width = x_pos + priv->slider.width / 2 - priv->win_x - mask.x;
216- mask.height = priv->pager_all.height;
217-
218- os_pager_connect (priv->pager, mask);
219- os_pager_set_detached (priv->pager, TRUE);
220-
221- os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE);
222- }
223- else
224- {
225- os_pager_set_detached (priv->pager, FALSE);
226- os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE);
227- }
228- }
229- }
230+ update_visual_connection (scrollbar);
231 }
232
233 move_pager (scrollbar);
234@@ -1257,6 +1251,8 @@
235 priv->present_time = g_get_monotonic_time ();
236 present_gdk_window_with_timestamp (GTK_WIDGET (scrollbar), event->time);
237
238+ priv->detached_scroll = FALSE;
239+
240 priv->button_press_event = TRUE;
241 priv->motion_notify_event = FALSE;
242
243@@ -1352,7 +1348,7 @@
244
245 gtk_window_set_transient_for (GTK_WINDOW (widget), NULL);
246
247- if (!priv->motion_notify_event)
248+ if (!priv->motion_notify_event && !priv->detached_scroll)
249 {
250 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
251 {
252@@ -1586,46 +1582,6 @@
253 gtk_adjustment_set_value (priv->adjustment, new_value);
254 }
255
256-/* from pointer movement, store the right adjustment value */
257-static void
258-capture_movement_for_animation (OsScrollbar *scrollbar,
259- gint mouse_x,
260- gint mouse_y)
261-{
262- OsScrollbarPrivate *priv;
263- gint delta;
264- gint c;
265- gdouble current_value, old_value, new_value;
266-
267- priv = scrollbar->priv;
268-
269- if (priv->orientation == GTK_ORIENTATION_VERTICAL)
270- delta = mouse_y - priv->slide_initial_coordinate;
271- else
272- delta = mouse_x - priv->slide_initial_coordinate;
273-
274- c = priv->slide_initial_slider_position + delta;
275-
276- current_value = gtk_adjustment_get_value (priv->adjustment);
277- old_value = priv->value;
278- new_value = coord_to_value (scrollbar, c);
279-
280- /* stop the animation if we are connecting. */
281- if ((current_value > old_value &&
282- new_value > current_value) ||
283- (current_value < old_value &&
284- new_value < current_value))
285- {
286- os_animation_stop (priv->animation, NULL);
287-
288- gtk_adjustment_set_value (priv->adjustment, new_value);
289- }
290-
291- /* update the adjustment value for the reconnect animation:
292- * set_scroll_cb could be running at that time. */
293- priv->value = new_value;
294-}
295-
296 static gboolean
297 thumb_motion_notify_event_cb (GtkWidget *widget,
298 GdkEventMotion *event,
299@@ -1641,7 +1597,9 @@
300 {
301 gint x, y;
302
303- /* reconnect slider and overlay after key press */
304+ /* thumb and pager are detached.
305+ * Detached scroll: keep the thumb detached during the scroll,
306+ * update the visual connection when reaching an edge. */
307 if (priv->value_changed_event)
308 {
309 /* return if the mouse movement is small. */
310@@ -1649,59 +1607,114 @@
311 abs (priv->pointer_y - event->y) <= TOLERANCE_PIXELS)
312 return FALSE;
313
314- if (priv->orientation == GTK_ORIENTATION_VERTICAL)
315- {
316- priv->slide_initial_slider_position = event->y_root - priv->win_y - event->y;
317- priv->slide_initial_coordinate = event->y_root;
318- }
319- else
320- {
321- priv->slide_initial_slider_position = event->x_root - priv->win_x - event->x;
322- priv->slide_initial_coordinate = event->x_root;
323- }
324+ priv->detached_scroll = TRUE;
325
326 /* stop the scroll animation if it's running. */
327- os_animation_stop (priv->animation, set_scroll_stop_cb);
328-
329- /* set the initial adjustment value required for reconnect. */
330- capture_movement_for_animation (scrollbar, event->x_root, event->y_root);
331-
332- /* animate the reconnect, using the same animation object. */
333- os_animation_start (priv->animation);
334-
335- priv->value_changed_event = FALSE;
336- }
337-
338- /* only the reconnect animation can be running at that time. */
339- if (os_animation_is_running (priv->animation))
340- {
341- /* update the adjustment value. */
342- capture_movement_for_animation (scrollbar, event->x_root, event->y_root);
343-
344- /* limit x and y within the thumb allocation. */
345+ os_animation_stop (priv->animation, NULL);
346+
347+ /* limit x and y within the allocation. */
348 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
349 {
350 x = priv->win_x;
351 y = CLAMP (event->y_root - priv->pointer_y,
352 priv->win_y,
353- priv->win_y + priv->thumb_all.height);
354+ priv->win_y + priv->thumb_all.height - priv->slider.height);
355 }
356 else
357 {
358 x = CLAMP (event->x_root - priv->pointer_x,
359 priv->win_x,
360- priv->win_x + priv->thumb_all.width);
361+ priv->win_x + priv->thumb_all.width - priv->slider.width);
362 y = priv->win_y;
363 }
364
365+ /* fine scroll while detached,
366+ * do not scroll when hitting an edge. */
367+ if ((priv->orientation == GTK_ORIENTATION_VERTICAL &&
368+ y > priv->win_y &&
369+ y < priv->win_y + priv->thumb_all.height - priv->slider.height) ||
370+ (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
371+ x > priv->win_x &&
372+ x < priv->win_x + priv->thumb_all.width - priv->slider.width))
373+ capture_movement (scrollbar, event->x_root, event->y_root);
374+
375 move_thumb (scrollbar, x, y);
376
377- /* return if the reconnect animation is still running after
378- * capture_movement_for_animation. */
379- if (os_animation_is_running (priv->animation))
380- return FALSE;
381+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
382+ {
383+ if (gtk_adjustment_get_value (priv->adjustment) == 0)
384+ {
385+ update_visual_connection (scrollbar);
386+
387+ if (priv->overlay.height > priv->slider.height)
388+ {
389+ priv->slide_initial_slider_position = 0;
390+ priv->slide_initial_coordinate = MAX (event->y_root, priv->win_y + priv->pointer_y);
391+ }
392+ else
393+ {
394+ priv->slide_initial_slider_position = 0;
395+ priv->slide_initial_coordinate = event->y_root;
396+ }
397+ }
398+ else if (priv->overlay.y + priv->overlay.height >= priv->trough.height)
399+ {
400+ update_visual_connection (scrollbar);
401+
402+ if (priv->overlay.height > priv->slider.height)
403+ {
404+ priv->slide_initial_slider_position = priv->trough.height - priv->overlay.height;
405+ priv->slide_initial_coordinate = MAX (event->y_root, priv->win_y + priv->pointer_y);
406+ }
407+ else
408+ {
409+ priv->slide_initial_slider_position = priv->trough.height - priv->slider.height;
410+ priv->slide_initial_coordinate = event->y_root;
411+ }
412+ }
413+ }
414+ else
415+ {
416+ if (gtk_adjustment_get_value (priv->adjustment) == 0)
417+ {
418+ update_visual_connection (scrollbar);
419+
420+ if (priv->overlay.width > priv->slider.width)
421+ {
422+ priv->slide_initial_slider_position = 0;
423+ priv->slide_initial_coordinate = MAX (event->x_root, priv->win_x + priv->pointer_x);
424+ }
425+ else
426+ {
427+ priv->slide_initial_slider_position = 0;
428+ priv->slide_initial_coordinate = event->x_root;
429+ }
430+ }
431+ else if (priv->overlay.x + priv->overlay.width >= priv->trough.width)
432+ {
433+ update_visual_connection (scrollbar);
434+
435+ if (priv->overlay.width > priv->slider.width)
436+ {
437+ priv->slide_initial_slider_position = priv->trough.width - priv->overlay.width;
438+ priv->slide_initial_coordinate = MAX (event->x_root, priv->win_x + priv->pointer_x);
439+ }
440+ else
441+ {
442+ priv->slide_initial_slider_position = priv->trough.width - priv->slider.width;
443+ priv->slide_initial_coordinate = event->x_root;
444+ }
445+ }
446+ }
447+
448+ return FALSE;
449 }
450
451+ OS_DCHECK (!priv->detached_scroll);
452+
453+ /* thumb and pager are connected.
454+ * Normal scroll: keep the thumb in sync with the pager,
455+ * do not update the visual connection. */
456 priv->motion_notify_event = TRUE;
457
458 capture_movement (scrollbar, event->x_root, event->y_root);
459@@ -1821,9 +1834,12 @@
460 scrollbar = OS_SCROLLBAR (user_data);
461 priv = scrollbar->priv;
462
463+ priv->detached_scroll = FALSE;
464+
465 priv->button_press_event = FALSE;
466 priv->motion_notify_event = FALSE;
467 priv->enter_notify_event = FALSE;
468+ priv->value_changed_event = FALSE;
469
470 os_pager_set_detached (priv->pager, FALSE);
471 }
472@@ -2563,6 +2579,7 @@
473 priv->active_window = FALSE;
474 priv->can_deactivate_pager = TRUE;
475 priv->can_hide = TRUE;
476+ priv->detached_scroll = FALSE;
477 priv->filter = FALSE;
478 priv->fullsize = FALSE;
479 priv->internal = FALSE;

Subscribers

People subscribed via source and target branches