Merge lp:~cimi/overlay-scrollbar/visual-connection into lp:overlay-scrollbar
- visual-connection
- Merge into trunk
Proposed by
Andrea Cimitan
Status: | Merged |
---|---|
Merged at revision: | 233 |
Proposed branch: | lp:~cimi/overlay-scrollbar/visual-connection |
Merge into: | lp:overlay-scrollbar |
Diff against target: |
543 lines (+253/-28) 4 files modified
os/os-pager.c (+174/-5) os/os-private.h (+6/-0) os/os-scrollbar.c (+73/-14) os/os-thumb.c (+0/-9) |
To merge this branch: | bzr merge lp:~cimi/overlay-scrollbar/visual-connection |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Review via email:
|
Commit message
Description of the change
Add a visual connection between pager and thumb when detached
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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-pager.c' |
2 | --- os/os-pager.c 2011-04-27 00:44:09 +0000 |
3 | +++ os/os-pager.c 2011-05-12 23:41:31 +0000 |
4 | @@ -39,11 +39,14 @@ |
5 | |
6 | struct _OsPagerPrivate { |
7 | GdkWindow *pager_window; |
8 | + GdkWindow *connection_window; |
9 | GtkWidget *parent; |
10 | GdkRectangle mask; |
11 | + GdkRectangle connection_mask; /* in theory not needed, but easier to read. */ |
12 | GdkRectangle allocation; |
13 | OsAnimation *animation; |
14 | gboolean active; |
15 | + gboolean detached; |
16 | gboolean visible; |
17 | gfloat weight; |
18 | gint width; |
19 | @@ -57,6 +60,7 @@ |
20 | static void os_pager_change_state_cb (gfloat weight, gpointer user_data); |
21 | static void os_pager_create (OsPager *pager); |
22 | static void os_pager_draw (OsPager *pager); |
23 | +static void os_pager_draw_connection (OsPager *pager); |
24 | static void os_pager_mask (OsPager *pager); |
25 | static void os_pager_notify_gtk_theme_name_cb (GObject *object, GParamSpec* pspec, gpointer user_data); |
26 | |
27 | @@ -85,7 +89,21 @@ |
28 | |
29 | /* Instead reparenting, |
30 | * which doesn't seem to work well, |
31 | - * destroy the window. */ |
32 | + * destroy the two windows. */ |
33 | + if (priv->connection_window != NULL) |
34 | + { |
35 | + /* From the Gdk documentation: |
36 | + * "Note that a window will not be destroyed |
37 | + * automatically when its reference count |
38 | + * reaches zero. You must call |
39 | + * gdk_window_destroy () |
40 | + * yourself before that happens". */ |
41 | + gdk_window_destroy (priv->connection_window); |
42 | + |
43 | + g_object_unref (priv->connection_window); |
44 | + priv->connection_window = NULL; |
45 | + } |
46 | + |
47 | if (priv->pager_window != NULL) |
48 | { |
49 | /* From the Gdk documentation: |
50 | @@ -107,14 +125,30 @@ |
51 | attributes.visual = gtk_widget_get_visual (priv->parent); |
52 | attributes.colormap = gtk_widget_get_colormap (priv->parent); |
53 | |
54 | + /* connection_window */ |
55 | + priv->connection_window = gdk_window_new (gtk_widget_get_window (priv->parent), |
56 | + &attributes, |
57 | + GDK_WA_VISUAL | GDK_WA_COLORMAP); |
58 | + |
59 | + g_object_ref_sink (priv->connection_window); |
60 | + |
61 | + gdk_window_set_transient_for (priv->connection_window, |
62 | + gtk_widget_get_window (priv->parent)); |
63 | + |
64 | + gdk_window_input_shape_combine_region (priv->connection_window, |
65 | + gdk_region_new (), |
66 | + 0, 0); |
67 | + |
68 | + /* pager_window */ |
69 | priv->pager_window = gdk_window_new (gtk_widget_get_window (priv->parent), |
70 | &attributes, |
71 | GDK_WA_VISUAL | GDK_WA_COLORMAP); |
72 | |
73 | g_object_ref_sink (priv->pager_window); |
74 | |
75 | + /* stay above the connection_window */ |
76 | gdk_window_set_transient_for (priv->pager_window, |
77 | - gtk_widget_get_window (priv->parent)); |
78 | + priv->connection_window); |
79 | |
80 | gdk_window_input_shape_combine_region (priv->pager_window, |
81 | gdk_region_new (), |
82 | @@ -137,10 +171,11 @@ |
83 | if (priv->parent == NULL) |
84 | return; |
85 | |
86 | + os_pager_draw_connection (pager); |
87 | os_pager_draw (pager); |
88 | } |
89 | |
90 | -/* Draw on the pager. */ |
91 | +/* Draw on the pager_window. */ |
92 | static void |
93 | os_pager_draw (OsPager *pager) |
94 | { |
95 | @@ -179,7 +214,30 @@ |
96 | gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE); |
97 | } |
98 | |
99 | -/* Mask the pager. */ |
100 | +/* Draw on the connection_window. */ |
101 | +static void |
102 | +os_pager_draw_connection (OsPager *pager) |
103 | +{ |
104 | + GdkColor color; |
105 | + OsPagerPrivate *priv; |
106 | + |
107 | + priv = pager->priv; |
108 | + |
109 | + /* 0.6 is taken from os_thumb_expose. */ |
110 | + color.red = 65535 * 0.6; |
111 | + color.green = 65535 * 0.6; |
112 | + color.blue = 65535 * 0.6; |
113 | + |
114 | + gdk_colormap_alloc_color (gdk_drawable_get_colormap (priv->connection_window), &color, FALSE, TRUE); |
115 | + |
116 | + gdk_window_set_background (priv->connection_window, &color); |
117 | + |
118 | + gdk_window_clear (priv->connection_window); |
119 | + |
120 | + gdk_window_invalidate_rect (gtk_widget_get_window (priv->parent), &priv->allocation, TRUE); |
121 | +} |
122 | + |
123 | +/* Mask the pager_window. */ |
124 | static void |
125 | os_pager_mask (OsPager *pager) |
126 | { |
127 | @@ -194,6 +252,21 @@ |
128 | gdk_window_clear (priv->pager_window); |
129 | } |
130 | |
131 | +/* Mask the connection_window. */ |
132 | +static void |
133 | +os_pager_mask_connection (OsPager *pager) |
134 | +{ |
135 | + OsPagerPrivate *priv; |
136 | + |
137 | + priv = pager->priv; |
138 | + |
139 | + gdk_window_shape_combine_region (priv->connection_window, |
140 | + gdk_region_rectangle (&priv->connection_mask), |
141 | + 0, 0); |
142 | + |
143 | + gdk_window_clear (priv->connection_window); |
144 | +} |
145 | + |
146 | static void |
147 | os_pager_notify_gtk_theme_name_cb (GObject* gobject, |
148 | GParamSpec* pspec, |
149 | @@ -205,9 +278,12 @@ |
150 | pager = OS_PAGER (user_data); |
151 | priv = pager->priv; |
152 | |
153 | - if (priv->parent == NULL || priv->pager_window == NULL) |
154 | + if (priv->parent == NULL || |
155 | + priv->pager_window == NULL || |
156 | + priv->connection_window == NULL) |
157 | return; |
158 | |
159 | + os_pager_draw_connection (pager); |
160 | os_pager_draw (pager); |
161 | } |
162 | |
163 | @@ -249,9 +325,11 @@ |
164 | mask.width = 1; |
165 | mask.height = 1; |
166 | |
167 | + priv->connection_mask = mask; |
168 | priv->mask = mask; |
169 | |
170 | priv->active = FALSE; |
171 | + priv->detached = FALSE; |
172 | priv->visible = FALSE; |
173 | |
174 | priv->weight = 1.0f; |
175 | @@ -278,6 +356,20 @@ |
176 | priv->animation = NULL; |
177 | } |
178 | |
179 | + if (priv->connection_window != NULL) |
180 | + { |
181 | + /* From the Gdk documentation: |
182 | + * "Note that a window will not be destroyed |
183 | + * automatically when its reference count |
184 | + * reaches zero. You must call |
185 | + * gdk_window_destroy () |
186 | + * yourself before that happens". */ |
187 | + gdk_window_destroy (priv->connection_window); |
188 | + |
189 | + g_object_unref (priv->connection_window); |
190 | + priv->connection_window = NULL; |
191 | + } |
192 | + |
193 | if (priv->pager_window != NULL) |
194 | { |
195 | /* From the Gdk documentation: |
196 | @@ -322,6 +414,34 @@ |
197 | } |
198 | |
199 | /** |
200 | + * os_pager_connect: |
201 | + * @pager: a #OsPager |
202 | + * @mask: a #GdkRectangle with the position and dimension of the connection |
203 | + * |
204 | + * Moves and resizes connection. |
205 | + **/ |
206 | +void |
207 | +os_pager_connect (OsPager *pager, |
208 | + GdkRectangle mask) |
209 | +{ |
210 | + OsPagerPrivate *priv; |
211 | + |
212 | + g_return_if_fail (OS_PAGER (pager)); |
213 | + |
214 | + priv = pager->priv; |
215 | + |
216 | + if (!rectangle_changed (priv->connection_mask, mask)) |
217 | + return; |
218 | + |
219 | + priv->connection_mask = mask; |
220 | + |
221 | + if (priv->parent == NULL) |
222 | + return; |
223 | + |
224 | + os_pager_mask_connection (pager); |
225 | +} |
226 | + |
227 | +/** |
228 | * os_pager_hide: |
229 | * @pager: a #OsPager |
230 | * |
231 | @@ -344,6 +464,7 @@ |
232 | /* if there's an animation currently running, stop it. */ |
233 | os_animation_stop (priv->animation); |
234 | |
235 | + gdk_window_hide (priv->connection_window); |
236 | gdk_window_hide (priv->pager_window); |
237 | } |
238 | |
239 | @@ -419,6 +540,41 @@ |
240 | } |
241 | |
242 | /** |
243 | + * os_pager_set_detached: |
244 | + * @pager: a #OsPager |
245 | + * @detached: whether the pager is detached or not |
246 | + * |
247 | + * Changes the detached state of @pager. |
248 | + **/ |
249 | +void |
250 | +os_pager_set_detached (OsPager *pager, |
251 | + gboolean detached) |
252 | +{ |
253 | + OsPagerPrivate *priv; |
254 | + |
255 | + g_return_if_fail (OS_PAGER (pager)); |
256 | + |
257 | + priv = pager->priv; |
258 | + |
259 | + if (priv->detached != detached) |
260 | + { |
261 | + priv->detached = detached; |
262 | + |
263 | + if (priv->parent == NULL) |
264 | + return; |
265 | + |
266 | + if (priv->detached) |
267 | + { |
268 | + gdk_window_show (priv->connection_window); |
269 | + |
270 | + gdk_window_clear (priv->connection_window); |
271 | + } |
272 | + else |
273 | + gdk_window_hide (priv->connection_window); |
274 | + } |
275 | +} |
276 | + |
277 | +/** |
278 | * os_pager_set_parent: |
279 | * @pager: a #OsPager |
280 | * @parent: a #GtkWidget |
281 | @@ -453,9 +609,16 @@ |
282 | priv->weight = 1.0f; |
283 | |
284 | os_pager_create (pager); |
285 | + os_pager_draw_connection (pager); |
286 | os_pager_draw (pager); |
287 | os_pager_mask (pager); |
288 | |
289 | + gdk_window_move_resize (priv->connection_window, |
290 | + priv->allocation.x, |
291 | + priv->allocation.y, |
292 | + priv->allocation.width, |
293 | + priv->allocation.height); |
294 | + |
295 | gdk_window_move_resize (priv->pager_window, |
296 | priv->allocation.x, |
297 | priv->allocation.y, |
298 | @@ -521,6 +684,12 @@ |
299 | if (priv->parent == NULL) |
300 | return; |
301 | |
302 | + gdk_window_move_resize (priv->connection_window, |
303 | + rectangle.x, |
304 | + rectangle.y, |
305 | + rectangle.width, |
306 | + rectangle.height); |
307 | + |
308 | gdk_window_move_resize (priv->pager_window, |
309 | rectangle.x, |
310 | rectangle.y, |
311 | |
312 | === modified file 'os/os-private.h' |
313 | --- os/os-private.h 2011-05-06 15:46:50 +0000 |
314 | +++ os/os-private.h 2011-05-12 23:41:31 +0000 |
315 | @@ -208,12 +208,18 @@ |
316 | |
317 | void os_pager_hide (OsPager *overlay); |
318 | |
319 | +void os_pager_connect (OsPager *overlay, |
320 | + GdkRectangle mask); |
321 | + |
322 | void os_pager_move_resize (OsPager *overlay, |
323 | GdkRectangle mask); |
324 | |
325 | void os_pager_set_active (OsPager *overlay, |
326 | gboolean active); |
327 | |
328 | +void os_pager_set_detached (OsPager *overlay, |
329 | + gboolean detached); |
330 | + |
331 | void os_pager_set_parent (OsPager *pager, |
332 | GtkWidget *parent); |
333 | |
334 | |
335 | === modified file 'os/os-scrollbar.c' |
336 | --- os/os-scrollbar.c 2011-05-08 14:06:01 +0000 |
337 | +++ os/os-scrollbar.c 2011-05-12 23:41:31 +0000 |
338 | @@ -494,10 +494,8 @@ |
339 | gpointer user_data) |
340 | { |
341 | OsScrollbar *scrollbar; |
342 | - OsScrollbarPrivate *priv; |
343 | |
344 | scrollbar = OS_SCROLLBAR (object); |
345 | - priv = scrollbar->priv; |
346 | |
347 | os_scrollbar_swap_adjustment (scrollbar, gtk_range_get_adjustment (GTK_RANGE (object))); |
348 | } |
349 | @@ -854,14 +852,12 @@ |
350 | { |
351 | Display *display; |
352 | OsScrollbar *scrollbar; |
353 | - OsScrollbarPrivate *priv; |
354 | XWindowChanges changes; |
355 | guint32 xid, xid_parent; |
356 | unsigned int value_mask = CWSibling | CWStackMode; |
357 | int res; |
358 | |
359 | scrollbar = OS_SCROLLBAR (user_data); |
360 | - priv = scrollbar->priv; |
361 | |
362 | xid = GDK_WINDOW_XID (gtk_widget_get_window (widget)); |
363 | xid_parent = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (scrollbar))); |
364 | @@ -1027,6 +1023,8 @@ |
365 | scrollbar = OS_SCROLLBAR (user_data); |
366 | priv = scrollbar->priv; |
367 | |
368 | + priv->value_changed_event = TRUE; |
369 | + |
370 | delta = os_scrollbar_get_wheel_delta (scrollbar, event->direction); |
371 | |
372 | gtk_adjustment_set_value (priv->adjustment, |
373 | @@ -1051,6 +1049,8 @@ |
374 | priv->button_press_event = FALSE; |
375 | priv->motion_notify_event = FALSE; |
376 | priv->enter_notify_event = FALSE; |
377 | + |
378 | + os_pager_set_detached (OS_PAGER (priv->pager), FALSE); |
379 | } |
380 | |
381 | /* Move the pager to the right position. */ |
382 | @@ -1169,7 +1169,10 @@ |
383 | { |
384 | /* if we're dragging the thumb, it can't be detached. */ |
385 | if (priv->motion_notify_event) |
386 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
387 | + { |
388 | + os_pager_set_detached (OS_PAGER (priv->pager), FALSE); |
389 | + os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
390 | + } |
391 | else |
392 | { |
393 | gint x_pos, y_pos; |
394 | @@ -1177,19 +1180,73 @@ |
395 | |
396 | if (priv->orientation == GTK_ORIENTATION_VERTICAL) |
397 | { |
398 | - if ((priv->win_y + priv->overlay.y > y_pos + priv->slider.height) || |
399 | - (priv->win_y + priv->overlay.y + priv->overlay.height < y_pos)) |
400 | - os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
401 | - else |
402 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
403 | + if (priv->win_y + priv->overlay.y > y_pos + priv->slider.height) |
404 | + { |
405 | + GdkRectangle mask; |
406 | + |
407 | + mask.x = 0; |
408 | + mask.y = y_pos + priv->slider.height / 2 - priv->win_y; |
409 | + mask.width = DEFAULT_PAGER_WIDTH; |
410 | + mask.height = priv->overlay.y - mask.y; |
411 | + |
412 | + os_pager_connect (OS_PAGER (priv->pager), mask); |
413 | + os_pager_set_detached (OS_PAGER (priv->pager), TRUE); |
414 | + |
415 | + os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
416 | + } |
417 | + else if (priv->win_y + priv->overlay.y + priv->overlay.height < y_pos) |
418 | + { |
419 | + GdkRectangle mask; |
420 | + |
421 | + mask.x = 0; |
422 | + mask.y = priv->overlay.y + priv->overlay.height; |
423 | + mask.width = DEFAULT_PAGER_WIDTH; |
424 | + mask.height = y_pos + priv->slider.height / 2 - priv->win_y - mask.y; |
425 | + |
426 | + os_pager_connect (OS_PAGER (priv->pager), mask); |
427 | + os_pager_set_detached (OS_PAGER (priv->pager), TRUE); |
428 | + |
429 | + os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
430 | + } |
431 | + else |
432 | + { |
433 | + os_pager_set_detached (OS_PAGER (priv->pager), FALSE); |
434 | + os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
435 | + } |
436 | } |
437 | else |
438 | { |
439 | - if ((priv->win_x + priv->overlay.x > x_pos + priv->slider.width) || |
440 | - (priv->win_x + priv->overlay.x + priv->overlay.width < x_pos)) |
441 | - os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
442 | + if (priv->win_x + priv->overlay.x > x_pos + priv->slider.width) |
443 | + { |
444 | + GdkRectangle mask; |
445 | + |
446 | + mask.x = x_pos + priv->slider.width / 2 - priv->win_x; |
447 | + mask.y = 0; |
448 | + mask.width = priv->overlay.x - mask.x; |
449 | + mask.height = DEFAULT_PAGER_WIDTH; |
450 | + |
451 | + os_pager_connect (OS_PAGER (priv->pager), mask); |
452 | + os_pager_set_detached (OS_PAGER (priv->pager), TRUE); |
453 | + |
454 | + os_thumb_set_detached (OS_THUMB (priv->thumb), TRUE); |
455 | + } |
456 | + else if (priv->win_x + priv->overlay.x + priv->overlay.width < x_pos) |
457 | + { |
458 | + GdkRectangle mask; |
459 | + |
460 | + mask.x = priv->overlay.y + priv->overlay.height; |
461 | + mask.y = 0; |
462 | + mask.width = x_pos + priv->slider.width / 2 - priv->win_x - mask.x; |
463 | + mask.height = DEFAULT_PAGER_WIDTH; |
464 | + |
465 | + os_pager_connect (OS_PAGER (priv->pager), mask); |
466 | + os_pager_set_detached (OS_PAGER (priv->pager), TRUE); |
467 | + } |
468 | else |
469 | - os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
470 | + { |
471 | + os_pager_set_detached (OS_PAGER (priv->pager), FALSE); |
472 | + os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
473 | + } |
474 | } |
475 | } |
476 | } |
477 | @@ -1431,6 +1488,7 @@ |
478 | os_scrollbar_move_thumb (scrollbar, priv->win_x, priv->win_y + priv->slider.y); |
479 | } |
480 | |
481 | + os_pager_set_detached (OS_PAGER (priv->pager), FALSE); |
482 | os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
483 | gtk_widget_show (GTK_WIDGET (priv->thumb)); |
484 | } |
485 | @@ -1471,6 +1529,7 @@ |
486 | os_scrollbar_move_thumb (scrollbar, priv->win_x + priv->slider.x, priv->win_y); |
487 | } |
488 | |
489 | + os_pager_set_detached (OS_PAGER (priv->pager), FALSE); |
490 | os_thumb_set_detached (OS_THUMB (priv->thumb), FALSE); |
491 | gtk_widget_show (GTK_WIDGET (priv->thumb)); |
492 | } |
493 | |
494 | === modified file 'os/os-thumb.c' |
495 | --- os/os-thumb.c 2011-05-08 14:06:01 +0000 |
496 | +++ os/os-thumb.c 2011-05-12 23:41:31 +0000 |
497 | @@ -138,12 +138,9 @@ |
498 | gpointer user_data) |
499 | { |
500 | OsThumb *thumb; |
501 | - OsThumbPrivate *priv; |
502 | |
503 | thumb = OS_THUMB (user_data); |
504 | |
505 | - priv = thumb->priv; |
506 | - |
507 | if (weight < 1.0f) |
508 | gtk_window_set_opacity (GTK_WINDOW (thumb), fabs (weight - 1.0f)); |
509 | else |
510 | @@ -379,7 +376,6 @@ |
511 | GdkEventExpose *event) |
512 | { |
513 | GtkAllocation allocation; |
514 | - GtkStateType state_type_down, state_type_up; |
515 | GtkStyle *style; |
516 | OsThumb *thumb; |
517 | OsThumbPrivate *priv; |
518 | @@ -393,9 +389,6 @@ |
519 | thumb = OS_THUMB (widget); |
520 | priv = thumb->priv; |
521 | |
522 | - state_type_down = GTK_STATE_NORMAL; |
523 | - state_type_up = GTK_STATE_NORMAL; |
524 | - |
525 | gtk_widget_get_allocation (widget, &allocation); |
526 | |
527 | x = 0; |
528 | @@ -445,7 +438,6 @@ |
529 | if ((priv->orientation == GTK_ORIENTATION_VERTICAL && (priv->pointer_y < height / 2)) || |
530 | (priv->orientation == GTK_ORIENTATION_HORIZONTAL && (priv->pointer_x < width / 2))) |
531 | { |
532 | - state_type_up = GTK_STATE_ACTIVE; |
533 | cairo_pattern_add_color_stop_rgba (pat, 0.0, 0.8, 0.8, 0.8, 0.8); |
534 | cairo_pattern_add_color_stop_rgba (pat, 0.49, 1.0, 1.0, 1.0, 0.0); |
535 | cairo_pattern_add_color_stop_rgba (pat, 0.49, 0.8, 0.8, 0.8, 0.5); |
536 | @@ -453,7 +445,6 @@ |
537 | } |
538 | else |
539 | { |
540 | - state_type_down = GTK_STATE_ACTIVE; |
541 | cairo_pattern_add_color_stop_rgba (pat, 0.0, 1.0, 1.0, 1.0, 0.8); |
542 | cairo_pattern_add_color_stop_rgba (pat, 0.49, 1.0, 1.0, 1.0, 0.0); |
543 | cairo_pattern_add_color_stop_rgba (pat, 0.49, 0.8, 0.8, 0.8, 0.5); |