Merge lp:~unity-team/unity/unity.new-quicklist-rendering into lp:unity

Proposed by Mirco Müller
Status: Merged
Approved by: Gord Allott
Approved revision: no longer in the source branch.
Merged at revision: 357
Proposed branch: lp:~unity-team/unity/unity.new-quicklist-rendering
Merge into: lp:unity
Diff against target: 629 lines (+608/-0)
2 files modified
unity-private/launcher/quicklist-view.vala (+147/-0)
unity/quicklist-rendering.vala (+461/-0)
To merge this branch: bzr merge lp:~unity-team/unity/unity.new-quicklist-rendering
Reviewer Review Type Date Requested Status
Gord Allott (community) Approve
Review via email: mp+28870@code.launchpad.net

Description of the change

modified:
  unity-private/launcher/quicklist-view.vala
  unity/quicklist-rendering.vala

Added the new texture-parts rendering for the quicklist/tooltip background, to go along with the new (still to be pushed) CtkMenuExpandable and related chagnes. The old rendering calls are not deleted yet intentionally, because they are still used. Those will be removed once CtkMenuExpndable landed in clutk trunk. Working on that right now.

The new approach, to facilitate the reveal-animation in an efficient way, is to render the quicklist/tooltip background in three "layers" with split-up masks/parts: blurred with 3-5 masks applied, tint-dot-highlight with 3-5 masks applied, 3-5 texture-parts holding the drop-shadow and outline. The different masks/parts:

* top
* first optional dynamic part which can grow (using texture-repeating)
* anchor
* second optional dynamic part which can grow (using texture-repeating)
* bottom

If this is still unclear I can provide you with a schematic drawing visualizing this better.

For the convenience of the reviewer, I added temp. image-dumps in the constructor of QuicklistMenu for verification of rendering of the new calls:

/tmp/anchor-mask.png
/tmp/outline-shadow-dyn.png
/tmp/bottom-mask.png
/tmp/outline-shadow-top.png
/tmp/dyn-mask.png
/tmp/tint-dot-highlight.png
/tmp/outline-shadow-anchor.png
/tmp/top-mask.png
/tmp/outline-shadow-bottom.png

These will of course not be merged into trunk once this branch is approved.

To post a comment you must log in.
Revision history for this message
Gord Allott (gordallott) wrote :

Everything seems to be rendered okay here, checked the /tmp files and they look correct to me. if you want me to send you the files in my /tmp so you can check i would be glad to. launchpad really needs attachments on merge requests ;)

review: Approve
Revision history for this message
Mirco Müller (macslow) wrote :

> if you want me to send you the files in my /tmp so you can check i would be glad to.

Yes, if you still have them, that would be nice. Thanks!

> launchpad really needs attachments on merge requests ;)

+1

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'unity-private/launcher/quicklist-view.vala'
2--- unity-private/launcher/quicklist-view.vala 2010-06-28 18:12:21 +0000
3+++ unity-private/launcher/quicklist-view.vala 2010-06-30 11:55:50 +0000
4@@ -475,6 +475,153 @@
5 old_height = 0;
6 cached_x = 0.0f; // needed to fix LP: #525905
7 cached_y = 0.0f; // needed to fix LP: #526335
8+
9+ // test new cairo-based texture-part drawing calls
10+ int width = 150;
11+ int height = 25;
12+ float radius = 7.0f;
13+ float anchor_width = 15.0f;
14+ float anchor_height = 20.0f;
15+ float line_width = 1.0f;
16+ float[] rgba = {1.0f, 1.0f, 1.0f, 1.0f};
17+ float[] rgba_tint = {0.1f, 0.1f, 0.1f, 0.5f};
18+ float[] rgba_hl = {1.0f, 1.0f, 1.0f, 0.5f};
19+ float[] rgba_shadow = {0.0f, 0.0f, 0.0f, 1.0f};
20+ float[] rgba_line = {1.0f, 1.0f, 1.0f, 1.0f};
21+ uint shadow_size = 5;
22+
23+ {
24+ Cairo.Surface surf;
25+
26+ Unity.QuicklistRendering.Menu.outline_shadow_top (out surf,
27+ width,
28+ height,
29+ anchor_width,
30+ radius,
31+ shadow_size,
32+ rgba_shadow,
33+ line_width,
34+ rgba_line);
35+ surf.write_to_png ("/tmp/outline-shadow-top.png");
36+ }
37+
38+ {
39+ Cairo.Surface surf;
40+
41+ Unity.QuicklistRendering.Menu.outline_shadow_dyn (out surf,
42+ width,
43+ height,
44+ anchor_width,
45+ shadow_size,
46+ rgba_shadow,
47+ line_width,
48+ rgba_line);
49+ surf.write_to_png ("/tmp/outline-shadow-dyn.png");
50+ }
51+
52+ {
53+ Cairo.Surface surf;
54+
55+ Unity.QuicklistRendering.Menu.outline_shadow_anchor (out surf,
56+ width,
57+ height,
58+ anchor_width,
59+ anchor_height,
60+ shadow_size,
61+ rgba_shadow,
62+ line_width,
63+ rgba_line);
64+ surf.write_to_png ("/tmp/outline-shadow-anchor.png");
65+ }
66+
67+ {
68+ Cairo.Surface surf;
69+
70+ Unity.QuicklistRendering.Menu.outline_shadow_bottom (out surf,
71+ width,
72+ height,
73+ anchor_width,
74+ radius,
75+ shadow_size,
76+ rgba_shadow,
77+ line_width,
78+ rgba_line);
79+ surf.write_to_png ("/tmp/outline-shadow-bottom.png");
80+ }
81+
82+ {
83+ Cairo.Surface surf;
84+
85+ Unity.QuicklistRendering.Menu.tint_dot_hl (out surf,
86+ width + 20,
87+ 3 * height,
88+ 87.0f,
89+ 25.0f,
90+ 62.5f,
91+ rgba_tint,
92+ rgba_hl);
93+ surf.write_to_png ("/tmp/tint-dot-highlight.png");
94+ }
95+
96+ {
97+ Cairo.Surface surf;
98+
99+ Unity.QuicklistRendering.Menu.top_mask (out surf,
100+ width,
101+ height,
102+ radius,
103+ anchor_width,
104+ true,
105+ false,
106+ line_width,
107+ rgba);
108+ surf.write_to_png ("/tmp/top-mask.png");
109+ }
110+
111+ {
112+ Cairo.Surface surf;
113+
114+ Unity.QuicklistRendering.Menu.dyn_mask (out surf,
115+ width,
116+ height,
117+ anchor_width,
118+ true,
119+ false,
120+ line_width,
121+ rgba);
122+ surf.write_to_png ("/tmp/dyn-mask.png");
123+ }
124+
125+ {
126+ Cairo.Surface surf;
127+
128+ Unity.QuicklistRendering.Menu.anchor_mask (out surf,
129+ width,
130+ height,
131+ anchor_width,
132+ anchor_height,
133+ true,
134+ false,
135+ line_width,
136+ rgba);
137+ surf.write_to_png ("/tmp/anchor-mask.png");
138+ }
139+
140+ {
141+ Cairo.Surface surf;
142+
143+ Unity.QuicklistRendering.Menu.bottom_mask (out surf,
144+ width,
145+ height,
146+ radius,
147+ anchor_width,
148+ true,
149+ false,
150+ line_width,
151+ rgba);
152+ surf.write_to_png ("/tmp/bottom-mask.png");
153+ }
154+
155 }
156 }
157 }
158
159=== modified file 'unity/quicklist-rendering.vala'
160--- unity/quicklist-rendering.vala 2010-06-08 09:52:30 +0000
161+++ unity/quicklist-rendering.vala 2010-06-30 11:55:50 +0000
162@@ -283,6 +283,467 @@
163 }
164
165 private static void
166+ _setup (out Cairo.Surface surf,
167+ out Cairo.Context cr,
168+ bool outline,
169+ int width,
170+ int height,
171+ bool negative)
172+ {
173+ // create context
174+ if (outline)
175+ surf = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, height);
176+ else
177+ surf = new Cairo.ImageSurface (Cairo.Format.A8, width, height);
178+
179+ cr = new Cairo.Context (surf);
180+
181+ // clear context
182+ cr.scale (1.0f, 1.0f);
183+ if (outline)
184+ {
185+ cr.set_source_rgba (0.0f, 0.0f, 0.0f, 0.0f);
186+ cr.set_operator (Cairo.Operator.CLEAR);
187+ }
188+ else
189+ {
190+ cr.set_operator (Cairo.Operator.OVER);
191+ if (negative)
192+ cr.set_source_rgba (0.0f, 0.0f, 0.0f, 0.0f);
193+ else
194+ cr.set_source_rgba (1.0f, 1.0f, 1.0f, 1.0f);
195+ }
196+ cr.paint ();
197+ }
198+
199+ private static void
200+ _draw (Cairo.Context cr,
201+ bool outline,
202+ float line_width,
203+ float* rgba,
204+ bool negative,
205+ bool stroke)
206+ {
207+ // prepare drawing
208+ cr.set_operator (Cairo.Operator.SOURCE);
209+
210+ // actually draw the mask
211+ if (outline)
212+ {
213+ cr.set_line_width (line_width);
214+ cr.set_source_rgba (rgba[0], rgba[1], rgba[2], rgba[3]);
215+ }
216+ else
217+ {
218+ if (negative)
219+ cr.set_source_rgba (1.0f, 1.0f, 1.0f, 1.0f);
220+ else
221+ cr.set_source_rgba (0.0f, 0.0f, 0.0f, 0.0f);
222+ }
223+
224+ // stroke or fill?
225+ if (stroke)
226+ cr.stroke_preserve ();
227+ else
228+ cr.fill_preserve ();
229+ }
230+
231+ private static void
232+ _finalize (Cairo.Context cr,
233+ bool outline,
234+ float line_width,
235+ float* rgba,
236+ bool negative,
237+ bool stroke)
238+ {
239+ // prepare drawing
240+ cr.set_operator (Cairo.Operator.SOURCE);
241+
242+ // actually draw the mask
243+ if (outline)
244+ {
245+ cr.set_line_width (line_width);
246+ cr.set_source_rgba (rgba[0], rgba[1], rgba[2], rgba[3]);
247+ }
248+ else
249+ {
250+ if (negative)
251+ cr.set_source_rgba (1.0f, 1.0f, 1.0f, 1.0f);
252+ else
253+ cr.set_source_rgba (0.0f, 0.0f, 0.0f, 0.0f);
254+ }
255+
256+ // stroke or fill?
257+ if (stroke)
258+ cr.stroke ();
259+ else
260+ cr.fill ();
261+ }
262+
263+ private static void
264+ _top_mask_path (Cairo.Context cr,
265+ float anchor_width,
266+ int width,
267+ int height,
268+ float radius,
269+ bool outline)
270+ {
271+ // create path
272+ cr.move_to (anchor_width + 0.5f, 0.0f);
273+ cr.line_to (anchor_width + 0.5f, (double) height - radius - 0.5f);
274+ cr.arc_negative (anchor_width + radius + 0.5f,
275+ (double) height - radius - 0.5f,
276+ radius,
277+ 180.0f * GLib.Math.PI / 180.0f,
278+ 90.0f * GLib.Math.PI / 180.0f);
279+ cr.line_to ((double) width - radius - 0.5f, (double) height - 0.5f);
280+ cr.arc_negative ((double) width - radius - 0.5f,
281+ (double) height - radius - 0.5f,
282+ radius,
283+ 90.0f * GLib.Math.PI / 180.0f,
284+ 0.0f * GLib.Math.PI / 180.0f);
285+ cr.line_to ((double) width - 0.5f, 0.0f);
286+ if (!outline)
287+ cr.close_path ();
288+ }
289+
290+ private static void
291+ _dyn_mask_path (Cairo.Context cr,
292+ float anchor_width,
293+ int width,
294+ int height,
295+ bool outline)
296+ {
297+ // create path
298+ cr.move_to (anchor_width + 0.5f, 0.0f);
299+ cr.line_to (anchor_width + 0.5f, (double) height);
300+ if (outline)
301+ cr.move_to ((double) width - 0.5f, (double) height);
302+ else
303+ cr.line_to ((double) width - 0.5f, (double) height);
304+ cr.line_to ((double) width - 0.5f, 0.0f);
305+ if (!outline)
306+ cr.close_path ();
307+ }
308+
309+ private static void
310+ _anchor_mask_path (Cairo.Context cr,
311+ float anchor_width,
312+ float anchor_height,
313+ int width,
314+ int height,
315+ bool outline)
316+ {
317+ // create path
318+ cr.move_to (anchor_width + 0.5f, 0.0f);
319+ cr.line_to (anchor_width + 0.5f,
320+ ((double) height - anchor_height) / 2.0f);
321+ cr.line_to (0.5f,
322+ (((double) height - anchor_height) + anchor_height) / 2.0f);
323+ cr.line_to (anchor_width + 0.5f,
324+ (double) height - ((double) height - anchor_height) / 2.0f);
325+ cr.line_to (anchor_width + 0.5f, (double) height);
326+ if (outline)
327+ cr.move_to ((double) width - 0.5f, (double) height);
328+ else
329+ cr.line_to ((double) width - 0.5f, (double) height);
330+ cr.line_to ((double) width - 0.5f, 0.0f);
331+ }
332+
333+ private static void
334+ _bottom_mask_path (Cairo.Context cr,
335+ float anchor_width,
336+ int width,
337+ int height,
338+ float radius,
339+ bool outline)
340+ {
341+ // create path
342+ cr.move_to (anchor_width + 0.5f, (double) height);
343+ cr.line_to (anchor_width + 0.5f, radius + 0.5f);
344+ cr.arc (anchor_width + radius + 0.5f,
345+ radius + 0.5f,
346+ radius,
347+ 180.0f * GLib.Math.PI / 180.0f,
348+ 270.0f * GLib.Math.PI / 180.0f);
349+ cr.line_to ((double) width - radius - 0.5f, 0.5f);
350+ cr.arc ((double) width - radius - 0.5f,
351+ radius + 0.5f,
352+ radius,
353+ 270.0f * GLib.Math.PI / 180.0f,
354+ 0.0f * GLib.Math.PI / 180.0f);
355+ cr.line_to ((double) width - 0.5f, (double) height);
356+ if (!outline)
357+ cr.close_path ();
358+ }
359+
360+ private static void
361+ _mask (Cairo.Context cr)
362+ {
363+ cr.set_operator (Cairo.Operator.CLEAR);
364+ cr.fill_preserve ();
365+ }
366+
367+ private static void
368+ _outline (Cairo.Context cr,
369+ float line_width,
370+ float[] rgba_line)
371+ {
372+ cr.set_operator (Cairo.Operator.SOURCE);
373+ cr.set_source_rgba (rgba_line[0],
374+ rgba_line[1],
375+ rgba_line[2],
376+ rgba_line[3]);
377+ cr.set_line_width (line_width);
378+ cr.stroke ();
379+ }
380+
381+ public static void
382+ outline_shadow_top (out Cairo.Surface surf,
383+ int width,
384+ int height,
385+ float anchor_width,
386+ float corner_radius,
387+ uint shadow_radius,
388+ float[] rgba_shadow,
389+ float line_width,
390+ float[] rgba_line)
391+ {
392+ Cairo.Context cr;
393+
394+ _setup (out surf, out cr, true, width, height, false);
395+ _top_mask_path (cr, anchor_width, width, height, corner_radius, false);
396+ _draw (cr, true, line_width, rgba_shadow, false, false);
397+ Ctk.surface_blur (surf, shadow_radius);
398+ _mask (cr);
399+ _outline (cr, line_width, rgba_line);
400+ }
401+
402+ public static void
403+ outline_shadow_dyn (out Cairo.Surface surf,
404+ int width,
405+ int height,
406+ float anchor_width,
407+ uint shadow_radius,
408+ float[] rgba_shadow,
409+ float line_width,
410+ float[] rgba_line)
411+ {
412+ Cairo.Context cr;
413+
414+ _setup (out surf, out cr, true, width, height, false);
415+ _dyn_mask_path (cr, anchor_width, width, height, false);
416+ _draw (cr, true, line_width, rgba_shadow, false, false);
417+ Ctk.surface_blur (surf, shadow_radius);
418+ _mask (cr);
419+ cr.new_path ();
420+ _dyn_mask_path (cr, anchor_width, width, height, true);
421+ _outline (cr, line_width, rgba_line);
422+ }
423+
424+ public static void
425+ outline_shadow_anchor (out Cairo.Surface surf,
426+ int width,
427+ int height,
428+ float anchor_width,
429+ float anchor_height,
430+ uint shadow_radius,
431+ float[] rgba_shadow,
432+ float line_width,
433+ float[] rgba_line)
434+ {
435+ Cairo.Context cr;
436+
437+ _setup (out surf, out cr, true, width, height, false);
438+ _anchor_mask_path (cr, anchor_width, anchor_height, width, height, false);
439+ _draw (cr, true, line_width, rgba_shadow, false, false);
440+ Ctk.surface_blur (surf, shadow_radius);
441+ _mask (cr);
442+ cr.new_path ();
443+ _anchor_mask_path (cr, anchor_width, anchor_height, width, height, true);
444+ _outline (cr, line_width, rgba_line);
445+ }
446+
447+ public static void
448+ outline_shadow_bottom (out Cairo.Surface surf,
449+ int width,
450+ int height,
451+ float anchor_width,
452+ float corner_radius,
453+ uint shadow_radius,
454+ float[] rgba_shadow,
455+ float line_width,
456+ float[] rgba_line)
457+ {
458+ Cairo.Context cr;
459+
460+ _setup (out surf, out cr, true, width, height, false);
461+ _bottom_mask_path (cr, anchor_width, width, height, corner_radius, true);
462+ _draw (cr, true, line_width, rgba_shadow, false, false);
463+ Ctk.surface_blur (surf, shadow_radius);
464+ _mask (cr);
465+ _outline (cr, line_width, rgba_line);
466+ }
467+
468+ public static void
469+ tint_dot_hl (out Cairo.Surface surf,
470+ int width,
471+ int height,
472+ float hl_x,
473+ float hl_y,
474+ float hl_size,
475+ float[] rgba_tint,
476+ float[] rgba_hl)
477+ {
478+ Cairo.Context cr;
479+ Cairo.Surface dots_surf;
480+ Cairo.Context dots_cr;
481+ Cairo.Pattern dots_pattern;
482+ Cairo.Pattern hl_pattern;
483+
484+ // create normal context
485+ surf = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, height);
486+ cr = new Cairo.Context (surf);
487+
488+ // create context for dot-pattern
489+ dots_surf = new Cairo.ImageSurface (Cairo.Format.ARGB32, 4, 4);
490+ dots_cr = new Cairo.Context (dots_surf);
491+
492+ // clear normal context
493+ cr.scale (1.0f, 1.0f);
494+ cr.set_source_rgba (0.0f, 0.0f, 0.0f, 0.0f);
495+ cr.set_operator (Cairo.Operator.CLEAR);
496+ cr.paint ();
497+
498+ // prepare drawing for normal context
499+ cr.set_operator (Cairo.Operator.OVER);
500+
501+ // create path in normal context
502+ cr.rectangle (0.0f, 0.0f, (double) width, (double) height);
503+
504+ // fill path of normal context with tint
505+ cr.set_source_rgba (rgba_tint[0],
506+ rgba_tint[1],
507+ rgba_tint[2],
508+ rgba_tint[3]);
509+ cr.fill_preserve ();
510+
511+ // create pattern in dot-context
512+ dots_cr.set_operator (Cairo.Operator.CLEAR);
513+ dots_cr.paint ();
514+ dots_cr.scale (1.0f, 1.0f);
515+ dots_cr.set_operator (Cairo.Operator.OVER);
516+ dots_cr.set_source_rgba (rgba_hl[0],
517+ rgba_hl[1],
518+ rgba_hl[2],
519+ rgba_hl[3]);
520+ dots_cr.rectangle (0.0f, 0.0f, 1.0f, 1.0f);
521+ dots_cr.fill ();
522+ dots_cr.rectangle (2.0f, 2.0f, 1.0f, 1.0f);
523+ dots_cr.fill ();
524+ dots_pattern = new Cairo.Pattern.for_surface (dots_surf);
525+
526+ // fill path of normal context with dot-pattern
527+ cr.set_operator (Cairo.Operator.OVER);
528+ cr.set_source (dots_pattern);
529+ dots_pattern.set_extend (Cairo.Extend.REPEAT);
530+ cr.fill_preserve ();
531+
532+ // draw highlight
533+ cr.set_operator (Cairo.Operator.OVER);
534+ hl_pattern = new Cairo.Pattern.radial (hl_x,
535+ hl_y,
536+ 0.0f,
537+ hl_x,
538+ hl_y,
539+ hl_size);
540+ hl_pattern.add_color_stop_rgba (0.0f,
541+ rgba_hl[0],
542+ rgba_hl[1],
543+ rgba_hl[2],
544+ rgba_hl[3]);
545+ hl_pattern.add_color_stop_rgba (1.0f, 1.0f, 1.0f, 1.0f, 0.0f);
546+ cr.set_source (hl_pattern);
547+ cr.fill ();
548+ }
549+
550+ public static void
551+ top_mask (out Cairo.Surface surf,
552+ int width,
553+ int height,
554+ float radius,
555+ float anchor_width,
556+ bool negative,
557+ bool outline,
558+ float line_width,
559+ float[] rgba)
560+ {
561+ Cairo.Context cr;
562+
563+ _setup (out surf, out cr, outline, width, height, negative);
564+ _top_mask_path (cr, anchor_width, width, height, radius, outline);
565+ _finalize (cr, outline, line_width, rgba, negative, outline);
566+ }
567+
568+ public static void
569+ dyn_mask (out Cairo.Surface surf,
570+ int width,
571+ int height,
572+ float anchor_width,
573+ bool negative,
574+ bool outline,
575+ float line_width,
576+ float[] rgba)
577+ {
578+ Cairo.Context cr;
579+
580+ _setup (out surf, out cr, outline, width, height, negative);
581+ _dyn_mask_path (cr, anchor_width, width, height, outline);
582+ _finalize (cr, outline, line_width, rgba, negative, outline);
583+ }
584+
585+ public static void
586+ anchor_mask (out Cairo.Surface surf,
587+ int width,
588+ int height,
589+ float anchor_width,
590+ float anchor_height,
591+ bool negative,
592+ bool outline,
593+ float line_width,
594+ float[] rgba)
595+ {
596+ Cairo.Context cr;
597+
598+ _setup (out surf, out cr, outline, width, height, negative);
599+ _anchor_mask_path (cr,
600+ anchor_width,
601+ anchor_height,
602+ width,
603+ height,
604+ outline);
605+ _finalize (cr, outline, line_width, rgba, negative, outline);
606+ }
607+
608+ public static void
609+ bottom_mask (out Cairo.Surface surf,
610+ int width,
611+ int height,
612+ float radius,
613+ float anchor_width,
614+ bool negative,
615+ bool outline,
616+ float line_width,
617+ float[] rgba)
618+ {
619+ Cairo.Context cr;
620+
621+ _setup (out surf, out cr, outline, width, height, negative);
622+ _bottom_mask_path (cr, anchor_width, width, height, radius, outline);
623+ _finalize (cr, outline, line_width, rgba, negative, outline);
624+ }
625+
626+ private static void
627 _round_rect_anchor (Cairo.Context cr,
628 double aspect, // aspect-ratio
629 double x, // top-left corner