Merge lp:~cimi/overlay-scrollbar/fine-scroll into lp:overlay-scrollbar
- fine-scroll
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Review via email: mp+67079@code.launchpad.net |
Commit message
Description of the change
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; |