Merge lp:~docky-core/plank/item-foreground-buffer into lp:plank

Proposed by Rico Tzschichholz
Status: Merged
Approved by: Robert Dyer
Approved revision: 812
Merged at revision: 816
Proposed branch: lp:~docky-core/plank/item-foreground-buffer
Merge into: lp:plank
Prerequisite: lp:~docky-core/plank/item-shadows
Diff against target: 363 lines (+151/-57)
3 files modified
lib/DockRenderer.vala (+62/-27)
lib/Drawing/DockSurface.vala (+16/-0)
lib/Items/DockItem.vala (+73/-30)
To merge this branch: bzr merge lp:~docky-core/plank/item-foreground-buffer
Reviewer Review Type Date Requested Status
Robert Dyer (community) Approve
Review via email: mp+160124@code.launchpad.net

Description of the change

* Refactor the way item-layers are drawn.

* Draw item-shadows behind the dock-background. (The theme should disable the shadows if TopPadding isn't < 0)

* Puts the badge/progress-bar onto a foreground_surface owned by the dock-item. This avoids the redraw from scratch of the badge/progress-bar on every dock-redraw.

To post a comment you must log in.
805. By Rico Tzschichholz

build: Use LT_LIB_M instead of hardcoding -lm

806. By Rico Tzschichholz

Add theme-configurable icon-shaped shadows

This adds new DockTheme preference "IconShadowSize" to adjust the shadow
with a default of 1.0

Revision history for this message
Robert Dyer (psybers) wrote :

Lines 9-13 - this check shouldnt be here. Always pass in the func and instead do this check inside the item itself (let the item decide if it needs to draw overlay, based on its own count/progress)

review: Needs Fixing
Revision history for this message
Robert Dyer (psybers) wrote :

the blocks 194-200 and 210-217 are the same, arent they? you can refactor this code to eliminate this duplication

review: Needs Fixing
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

> Lines 9-13 - this check shouldnt be here. Always pass in the func and instead
> do this check inside the item itself (let the item decide if it needs to draw
> overlay, based on its own count/progress)

Checking it that early and passing null as func saves a cr.set_source_surface () call, same for checking the shadow-size above that.

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

> the blocks 194-200 and 210-217 are the same, arent they? you can refactor this
> code to eliminate this duplication

It is nearly identical except for their sizes which depend on the func==null condition, an alternative might be to put it in an extra inline function.

Suggest a diff then.

807. By Rico Tzschichholz

positionmanager: Refactor get_background_position to get_background_region

This makes its usage in DockRenderer easier.

808. By Rico Tzschichholz

Use compact way to initialize structs

Note that all fields need be qualified in their defined order.

809. By Rico Tzschichholz

titledseparatormenuitem: Don't use deprecated gtk+ api

It didn't work before and doesnt completely now either.

811. By Rico Tzschichholz

Draw item-shadows separately behind the dock background

812. By Rico Tzschichholz

Refactor the item drawing

Revision history for this message
Robert Dyer (psybers) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/DockRenderer.vala'
--- lib/DockRenderer.vala 2013-04-24 07:55:37 +0000
+++ lib/DockRenderer.vala 2013-04-25 12:50:31 +0000
@@ -40,6 +40,7 @@
40 Gdk.Rectangle background_rect;40 Gdk.Rectangle background_rect;
41 DockSurface? main_buffer;41 DockSurface? main_buffer;
42 DockSurface? indicator_buffer;42 DockSurface? indicator_buffer;
43 DockSurface? shadow_buffer;
43 DockSurface? urgent_indicator_buffer;44 DockSurface? urgent_indicator_buffer;
44 DockSurface? urgent_glow_buffer;45 DockSurface? urgent_glow_buffer;
45 46
@@ -236,6 +237,7 @@
236 main_buffer = null;237 main_buffer = null;
237 background_buffer = null;238 background_buffer = null;
238 indicator_buffer = null;239 indicator_buffer = null;
240 shadow_buffer = null;
239 urgent_indicator_buffer = null;241 urgent_indicator_buffer = null;
240 urgent_glow_buffer = null;242 urgent_glow_buffer = null;
241 243
@@ -276,13 +278,19 @@
276 var start = new DateTime.now_local ();278 var start = new DateTime.now_local ();
277#endif279#endif
278 280
281 var width = position_manager.DockWidth;
282 var height = position_manager.DockHeight;
283
279 if (main_buffer == null) {284 if (main_buffer == null) {
280 var width = position_manager.DockWidth;
281 var height = position_manager.DockHeight;
282 main_buffer = new DockSurface.with_surface (width, height, cr.get_target ());285 main_buffer = new DockSurface.with_surface (width, height, cr.get_target ());
283 }286 }
284 287
288 if (shadow_buffer == null) {
289 shadow_buffer = new DockSurface.with_surface (width, height, cr.get_target ());
290 }
291
285 main_buffer.clear ();292 main_buffer.clear ();
293 shadow_buffer.clear ();
286 294
287#if BENCHMARK295#if BENCHMARK
288 var start2 = new DateTime.now_local ();296 var start2 = new DateTime.now_local ();
@@ -316,6 +324,9 @@
316 324
317 // draw the dock on the window325 // draw the dock on the window
318 cr.set_operator (Operator.SOURCE);326 cr.set_operator (Operator.SOURCE);
327 cr.set_source_surface (shadow_buffer.Internal, x_offset, y_offset);
328 cr.paint ();
329 cr.set_operator (Operator.OVER);
319 cr.set_source_surface (main_buffer.Internal, x_offset, y_offset);330 cr.set_source_surface (main_buffer.Internal, x_offset, y_offset);
320 cr.paint ();331 cr.paint ();
321 332
@@ -363,6 +374,7 @@
363 unowned DragManager drag_manager = controller.drag_manager;374 unowned DragManager drag_manager = controller.drag_manager;
364 375
365 unowned Context main_cr = main_buffer.Context;376 unowned Context main_cr = main_buffer.Context;
377 unowned Context shadow_cr = shadow_buffer.Context;
366 var icon_size = position_manager.IconSize;378 var icon_size = position_manager.IconSize;
367 var shadow_size = controller.position_manager.IconShadowSize;379 var shadow_size = controller.position_manager.IconShadowSize;
368 380
@@ -370,12 +382,20 @@
370#if BENCHMARK382#if BENCHMARK
371 var start = new DateTime.now_local ();383 var start = new DateTime.now_local ();
372#endif384#endif
373 unowned DrawItemFunc? shadow_func = null;385 var icon_surface = item.get_surface_copy (icon_size, icon_size, main_buffer);
386 unowned Context icon_cr = icon_surface.Context;
387
388 DockSurface? icon_shadow_surface = null;
374 if (shadow_size > 0)389 if (shadow_size > 0)
375 shadow_func = draw_item_shadow;390 icon_shadow_surface = item.get_background_surface (draw_item_shadow);
376 391
377 var icon_surface = item.get_surface_copy (icon_size, icon_size, main_buffer, shadow_func);392 DockSurface? icon_overlay_surface = null;
378 unowned Context icon_cr = icon_surface.Context;393 if (item.CountVisible || item.ProgressVisible)
394 icon_overlay_surface = item.get_foreground_surface (draw_item_overlay);
395
396 if (icon_overlay_surface != null)
397 icon_cr.set_source_surface (icon_overlay_surface.Internal, 0, 0);
398
379#if BENCHMARK399#if BENCHMARK
380 var end = new DateTime.now_local ();400 var end = new DateTime.now_local ();
381 benchmark.add (" item.get_surface time - %f ms".printf (end.difference (start) / 1000.0));401 benchmark.add (" item.get_surface time - %f ms".printf (end.difference (start) / 1000.0));
@@ -444,22 +464,6 @@
444 icon_cr.set_operator (Cairo.Operator.OVER);464 icon_cr.set_operator (Cairo.Operator.OVER);
445 }465 }
446 466
447
448 // TODO put them onto a cached icon_overlay_surface for performance reasons?
449 // maybe even draw outside of the item-draw-area (considering the hover-area)
450
451 var urgent_color = get_styled_color ();
452 urgent_color.add_hue (theme.UrgentHueShift);
453
454 // draw item's count
455 if (item.CountVisible)
456 theme.draw_item_count (icon_surface, icon_size, urgent_color, item.Count);
457
458 // draw item's progress
459 if (item.ProgressVisible)
460 theme.draw_item_progress (icon_surface, icon_size, urgent_color, item.Progress);
461
462
463 // darken the icon467 // darken the icon
464 if (darken > 0) {468 if (darken > 0) {
465 icon_cr.rectangle (0, 0, icon_surface.Width, icon_surface.Height);469 icon_cr.rectangle (0, 0, icon_surface.Width, icon_surface.Height);
@@ -501,8 +505,14 @@
501 theme.draw_active_glow (main_buffer, background_rect, glow_rect, item.AverageIconColor, opacity, controller.prefs.Position);505 theme.draw_active_glow (main_buffer, background_rect, glow_rect, item.AverageIconColor, opacity, controller.prefs.Position);
502 }506 }
503 507
508 // draw the icon shadow
509 if (icon_shadow_surface != null) {
510 shadow_cr.set_source_surface (icon_shadow_surface.Internal, draw_rect.x - shadow_size, draw_rect.y - shadow_size);
511 shadow_cr.paint ();
512 }
513
504 // draw the icon514 // draw the icon
505 main_cr.set_source_surface (icon_surface.Internal, draw_rect.x - shadow_size, draw_rect.y - shadow_size);515 main_cr.set_source_surface (icon_surface.Internal, draw_rect.x, draw_rect.y);
506 main_cr.paint ();516 main_cr.paint ();
507 517
508 // draw indicators518 // draw indicators
@@ -510,6 +520,34 @@
510 draw_indicator_state (hover_rect, item.Indicator, item.State);520 draw_indicator_state (hover_rect, item.Indicator, item.State);
511 }521 }
512 522
523 DockSurface draw_item_overlay (DockItem item, DockSurface icon_surface, DockSurface? current_surface)
524 {
525 unowned PositionManager position_manager = controller.position_manager;
526 var width = icon_surface.Width;
527 var height = icon_surface.Height;
528
529 if (current_surface != null
530 && width == current_surface.Width && height == current_surface.Height)
531 return current_surface;
532
533 Logger.verbose ("DockItem.draw_item_overlay (width = %i, height = %i)", width, height);
534 var surface = new DockSurface.with_dock_surface (width, height, icon_surface);
535
536 var icon_size = position_manager.IconSize;
537 var urgent_color = get_styled_color ();
538 urgent_color.add_hue (theme.UrgentHueShift);
539
540 // draw item's count
541 if (item.CountVisible)
542 theme.draw_item_count (surface, icon_size, urgent_color, item.Count);
543
544 // draw item's progress
545 if (item.ProgressVisible)
546 theme.draw_item_progress (surface, icon_size, urgent_color, item.Progress);
547
548 return surface;
549 }
550
513 DockSurface draw_item_shadow (DockItem item, DockSurface icon_surface, DockSurface? current_surface)551 DockSurface draw_item_shadow (DockItem item, DockSurface icon_surface, DockSurface? current_surface)
514 {552 {
515 var shadow_size = controller.position_manager.IconShadowSize;553 var shadow_size = controller.position_manager.IconShadowSize;
@@ -548,9 +586,6 @@
548 cr.paint_with_alpha (0.44);586 cr.paint_with_alpha (0.44);
549 surface.gaussian_blur (shadow_size);587 surface.gaussian_blur (shadow_size);
550 588
551 cr.set_source_surface (icon_surface.Internal, shadow_size, shadow_size);
552 cr.paint ();
553
554 return surface;589 return surface;
555 }590 }
556 591
557592
=== modified file 'lib/Drawing/DockSurface.vala'
--- lib/Drawing/DockSurface.vala 2013-04-19 12:37:27 +0000
+++ lib/Drawing/DockSurface.vala 2013-04-25 12:50:31 +0000
@@ -111,6 +111,22 @@
111 }111 }
112 112
113 /**113 /**
114 * Create a copy of the surface
115 *
116 * @return copy of this surface
117 */
118 public DockSurface copy ()
119 {
120 var copy = new DockSurface.with_dock_surface (Width, Height, this);
121 unowned Cairo.Context cr = copy.Context;
122
123 cr.set_source_surface (Internal, 0, 0);
124 cr.paint ();
125
126 return copy;
127 }
128
129 /**
114 * Saves the current dock surface to a {@link Gdk.Pixbuf}.130 * Saves the current dock surface to a {@link Gdk.Pixbuf}.
115 *131 *
116 * @return the {@link Gdk.Pixbuf}132 * @return the {@link Gdk.Pixbuf}
117133
=== modified file 'lib/Items/DockItem.vala'
--- lib/Items/DockItem.vala 2013-04-22 13:19:32 +0000
+++ lib/Items/DockItem.vala 2013-04-25 12:50:31 +0000
@@ -29,7 +29,7 @@
29 * Draws a modified surface onto another newly created or given surface29 * Draws a modified surface onto another newly created or given surface
30 *30 *
31 * @param item the dock-item31 * @param item the dock-item
32 * @param source original surface32 * @param source original surface which may not be changed
33 * @param target the previously modified surface33 * @param target the previously modified surface
34 * @return the modified surface or passed through target34 * @return the modified surface or passed through target
35 */35 */
@@ -289,6 +289,7 @@
289 289
290 DockSurface? surface = null;290 DockSurface? surface = null;
291 DockSurface? background_surface = null;291 DockSurface? background_surface = null;
292 DockSurface? foreground_surface = null;
292 293
293 /**294 /**
294 * Creates a new dock item.295 * Creates a new dock item.
@@ -304,6 +305,11 @@
304 Gtk.IconTheme.get_default ().changed.connect (icon_theme_changed);305 Gtk.IconTheme.get_default ().changed.connect (icon_theme_changed);
305 notify["Icon"].connect (reset_icon_buffer);306 notify["Icon"].connect (reset_icon_buffer);
306 notify["ForcePixbuf"].connect (reset_icon_buffer);307 notify["ForcePixbuf"].connect (reset_icon_buffer);
308
309 notify["Count"].connect (reset_foreground_buffer);
310 notify["CountVisible"].connect (reset_foreground_buffer);
311 notify["Progress"].connect (reset_foreground_buffer);
312 notify["ProgressVisible"].connect (reset_foreground_buffer);
307 }313 }
308 314
309 ~DockItem ()315 ~DockItem ()
@@ -312,6 +318,11 @@
312 Gtk.IconTheme.get_default ().changed.disconnect (icon_theme_changed);318 Gtk.IconTheme.get_default ().changed.disconnect (icon_theme_changed);
313 notify["Icon"].disconnect (reset_icon_buffer);319 notify["Icon"].disconnect (reset_icon_buffer);
314 notify["ForcePixbuf"].disconnect (reset_icon_buffer);320 notify["ForcePixbuf"].disconnect (reset_icon_buffer);
321
322 notify["Count"].disconnect (reset_foreground_buffer);
323 notify["CountVisible"].disconnect (reset_foreground_buffer);
324 notify["Progress"].disconnect (reset_foreground_buffer);
325 notify["ProgressVisible"].disconnect (reset_foreground_buffer);
315 }326 }
316 327
317 /**328 /**
@@ -337,6 +348,7 @@
337 {348 {
338 surface = null;349 surface = null;
339 background_surface = null;350 background_surface = null;
351 foreground_surface = null;
340 352
341 needs_redraw ();353 needs_redraw ();
342 }354 }
@@ -347,6 +359,12 @@
347 public void reset_buffers ()359 public void reset_buffers ()
348 {360 {
349 background_surface = null;361 background_surface = null;
362 foreground_surface = null;
363 }
364
365 void reset_foreground_buffer ()
366 {
367 foreground_surface = null;
350 }368 }
351 369
352 void icon_theme_changed ()370 void icon_theme_changed ()
@@ -359,7 +377,7 @@
359 });377 });
360 }378 }
361 379
362 DockSurface get_surface (int width, int height, DockSurface model)380 unowned DockSurface get_surface (int width, int height, DockSurface model)
363 {381 {
364 if (surface == null || width != surface.Width || height != surface.Height) {382 if (surface == null || width != surface.Width || height != surface.Height) {
365 surface = new DockSurface.with_dock_surface (width, height, model);383 surface = new DockSurface.with_dock_surface (width, height, model);
@@ -374,38 +392,63 @@
374 }392 }
375 393
376 /**394 /**
377 * Returns a copy of the dock surface for this item and triggers an395 * Returns the background surface for this item.
378 * internal redraw if the requested size isn't matching the cache.396 *
379 *397 * The draw_func may pass through the given previously computed surface
380 * @param width width of the requested surface398 * or change it as needed. This surface will be buffered internally.
381 * @param height height of the requested surface399 *
400 * Passing null as draw_func will destroy the internal background buffer.
401 *
402 * @param draw_func function which creates/changes the background surface
403 * @return the background surface of this item which may not be changed
404 */
405 public unowned DockSurface? get_background_surface (DrawItemFunc? draw_func = null)
406 requires (surface != null)
407 {
408 if (draw_func != null)
409 background_surface = draw_func (this, surface, background_surface);
410 else
411 background_surface = null;
412
413 return background_surface;
414 }
415
416 /**
417 * Returns the foreground surface for this item.
418 *
419 * The draw_func may pass through the given previously computed surface
420 * or change it as needed. This surface will be buffered internally.
421 *
422 * Passing null as draw_func will destroy the internal foreground buffer.
423 *
424 * @param draw_func function which creates/changes the foreground surface
425 * @return the background surface of this item which may not be changed
426 */
427 public unowned DockSurface? get_foreground_surface (DrawItemFunc? draw_func = null)
428 requires (surface != null)
429 {
430 if (draw_func != null)
431 foreground_surface = draw_func (this, surface, foreground_surface);
432 else
433 foreground_surface = null;
434
435 return foreground_surface;
436 }
437
438 /**
439 * Returns a copy of the dock surface for this item.
440 *
441 * It will trigger an internal redraw if the requested size
442 * isn't matching the cache.
443 *
444 * @param width width of the icon surface
445 * @param height height of the icon surface
382 * @param model existing surface to use as basis of new surface446 * @param model existing surface to use as basis of new surface
383 * @param draw_func function which manipulates the resulting surface
384 * @return the copied dock surface for this item447 * @return the copied dock surface for this item
385 */448 */
386 public DockSurface get_surface_copy (int width, int height, DockSurface model, DrawItemFunc? draw_func = null)449 public DockSurface get_surface_copy (int width, int height, DockSurface model)
387 {450 {
388 var icon_surface = get_surface (width, height, model);451 return get_surface (width, height, model).copy ();
389
390 if (draw_func == null) {
391 var surface_copy = new DockSurface.with_dock_surface (width, height, model);
392 unowned Cairo.Context cr = surface_copy.Context;
393
394 cr.set_source_surface (icon_surface.Internal, 0, 0);
395 cr.paint ();
396
397 return surface_copy;
398 }
399
400 background_surface = draw_func (this, icon_surface, background_surface);
401
402 var surface_copy = new DockSurface.with_dock_surface (background_surface.Width, background_surface.Height, model);
403 unowned Cairo.Context cr = surface_copy.Context;
404
405 cr.set_source_surface (background_surface.Internal, 0, 0);
406 cr.paint ();
407
408 return surface_copy;
409 }452 }
410453
411 /**454 /**

Subscribers

People subscribed via source and target branches

to status/vote changes: