Merge lp:~tintou/granite/avatar-hidpi into lp:~elementary-pantheon/granite/granite

Proposed by Corentin Noël
Status: Rejected
Rejected by: Danielle Foré
Proposed branch: lp:~tintou/granite/avatar-hidpi
Merge into: lp:~elementary-pantheon/granite/granite
Diff against target: 231 lines (+99/-66)
2 files modified
demo/GraniteDemo.vala (+2/-1)
lib/Widgets/Avatar.vala (+97/-65)
To merge this branch: bzr merge lp:~tintou/granite/avatar-hidpi
Reviewer Review Type Date Requested Status
Zisu Andrei (community) Needs Information
Danielle Foré ux Approve
Review via email: mp+313493@code.launchpad.net

Description of the change

Make it work with HiDPI

To post a comment you must log in.
lp:~tintou/granite/avatar-hidpi updated
1016. By Corentin Noël

[Avatar] working with HiDPI devices.

Revision history for this message
Danielle Foré (danrabbit) wrote :

As far as I can tell, this is working as expected and fixes the issue with this widget on HiDPI

review: Approve (ux)
Revision history for this message
Zisu Andrei (matzipan) wrote :

2 comments inline.

review: Needs Information

Unmerged revisions

1016. By Corentin Noël

[Avatar] working with HiDPI devices.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'demo/GraniteDemo.vala'
2--- demo/GraniteDemo.vala 2016-09-29 01:45:59 +0000
3+++ demo/GraniteDemo.vala 2016-12-17 20:23:09 +0000
4@@ -336,13 +336,14 @@
5 private Granite.Widgets.Avatar create_avatar () {
6 var username = GLib.Environment.get_user_name ();
7 var avatar = new Granite.Widgets.Avatar ();
8+ avatar.pixel_size = 24;
9 var iconfile = @"/var/lib/AccountsService/icons/$username";
10
11 avatar.valign = Gtk.Align.CENTER;
12
13 try {
14 var pixbuf = new Gdk.Pixbuf.from_file (iconfile);
15- avatar.pixbuf = pixbuf.scale_simple (24, 24, Gdk.InterpType.BILINEAR);
16+ avatar.pixbuf = pixbuf;
17 avatar.set_tooltip_text ("Avatar widget: User image found");
18 } catch (Error e) {
19 avatar.show_default (24);
20
21=== modified file 'lib/Widgets/Avatar.vala'
22--- lib/Widgets/Avatar.vala 2015-09-01 21:08:27 +0000
23+++ lib/Widgets/Avatar.vala 2016-12-17 20:23:09 +0000
24@@ -23,13 +23,12 @@
25 * The Avatar widget allowes to theme & crop images with css BORDER_RADIUS property in the .avatar class.
26 *
27 */
28-public class Granite.Widgets.Avatar : Gtk.EventBox {
29+public class Granite.Widgets.Avatar : Gtk.Image {
30 private const string DEFAULT_ICON = "avatar-default";
31 private const string DEFAULT_STYLE = "avatar";
32 private const int EXTRA_MARGIN = 4;
33- private bool draw_theme_background = true;
34
35- public Gdk.Pixbuf? pixbuf { get; set; }
36+ private Gdk.Pixbuf? internal_pixbuf;
37
38 /**
39 * Makes new Avatar widget
40@@ -44,96 +43,129 @@
41 * @param pixbuf image to be used
42 */
43 public Avatar.from_pixbuf (Gdk.Pixbuf pixbuf) {
44- Object (pixbuf: pixbuf);
45+ this.pixbuf = pixbuf;
46 }
47
48 /**
49 * Creates a new Avatar from the speficied filepath and icon size
50 *
51 * @param filepath image to be used
52- * @param size to scale the image
53+ * @param pixel_size to scale the image
54 */
55- public Avatar.from_file (string filepath, int icon_size) {
56- try {
57- pixbuf = new Gdk.Pixbuf.from_file_at_scale (filepath, icon_size, icon_size, true);
58- } catch (Error e) {
59- show_default (icon_size);
60- }
61+ public Avatar.from_file (string filepath, int pixel_size) {
62+ this.pixel_size = pixel_size;
63+ file = filepath;
64+ icon_name = null;
65+ render_pixbuf ();
66 }
67
68 /**
69 * Creates a new Avatar with the default icon from theme without applying the css style
70 *
71- * @param icon_size size of the icon to be loaded
72+ * @param pixel_size size of the icon to be loaded
73 */
74- public Avatar.with_default_icon (int icon_size) {
75- show_default (icon_size);
76+ public Avatar.with_default_icon (int pixel_size) {
77+ show_default (pixel_size);
78 }
79
80 construct {
81+ icon_size = Gtk.IconSize.BUTTON;
82+ pixel_size = 64;
83 valign = Gtk.Align.CENTER;
84 halign = Gtk.Align.CENTER;
85- visible_window = false;
86- get_style_context ().add_class (DEFAULT_STYLE);
87-
88- notify["pixbuf"].connect (refresh_size_request);
89- }
90-
91- ~Avatar () {
92- notify["pixbuf"].disconnect (refresh_size_request);
93- }
94-
95- private void refresh_size_request () {
96+ unowned Gtk.StyleContext style_context = get_style_context ();
97+ style_context.add_class (DEFAULT_STYLE);
98+ notify["scale-factor"].connect (render_pixbuf);
99+ notify["icon-size"].connect (render_pixbuf);
100+ }
101+
102+ private void render_pixbuf () {
103+ if (file != null) {
104+ try {
105+ var temp_pixbuf = new Gdk.Pixbuf.from_file_at_scale (file, pixel_size, pixel_size, true);
106+ internal_pixbuf = temp_pixbuf.scale_simple (pixel_size, pixel_size, Gdk.InterpType.BILINEAR);
107+ } catch (Error e) {
108+ show_default (pixel_size);
109+ }
110+ } else if (pixbuf != null) {
111+ internal_pixbuf = pixbuf.scale_simple (pixel_size, pixel_size, Gdk.InterpType.BILINEAR);
112+ }
113+
114+ queue_draw ();
115+ }
116+
117+ /**
118+ * Load the default avatar icon from theme into the widget without applying the css style
119+ *
120+ * @param pixel_size size of the icon to be loaded
121+ */
122+ public void show_default (int pixel_size) {
123+ this.pixel_size = pixel_size;
124+ this.file = null;
125+ this.icon_name = DEFAULT_ICON;
126+ base.pixbuf = null;
127+ internal_pixbuf = null;
128+ queue_draw ();
129+ }
130+
131+ /**
132+ * Get the current pixbuf, here for API retro-compatibility
133+ *
134+ * @return the pixbuf in use or //null//
135+ */
136+ [Version (deprecated = true, deprecated_since = "0.5", replacement = "Gtk.Image.get_pixbuf")]
137+ public new Gdk.Pixbuf? get_pixbuf () {
138+ return pixbuf;
139+ }
140+
141+ /**
142+ * Get the current internal pixbuf, here for API retro-compatibility
143+ *
144+ * @param pixbuf the pixbuf to show. Automatically resized.
145+ */
146+ public void set_pixbuf (Gdk.Pixbuf? pixbuf) {
147 if (pixbuf != null) {
148- set_size_request (pixbuf.width + EXTRA_MARGIN * 2, pixbuf.height + EXTRA_MARGIN * 2);
149- draw_theme_background = true;
150+ icon_name = null;
151+ file = null;
152+ this.pixbuf = pixbuf;
153+ render_pixbuf ();
154 } else {
155- set_size_request (0, 0);
156- }
157-
158- queue_draw ();
159- }
160-
161- /**
162- * Load the default avatar icon from theme into the widget without applying the css style
163- *
164- * @param icon_size size of the icon to be loaded
165- */
166- public void show_default (int icon_size) {
167- Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default ();
168- try {
169- pixbuf = icon_theme.load_icon (DEFAULT_ICON, icon_size, 0);
170- } catch (Error e) {
171- stderr.printf ("Error setting default avatar icon: %s ", e.message);
172- }
173-
174- draw_theme_background = false;
175+ show_default (pixel_size);
176+ }
177+ }
178+
179+ public override void get_preferred_width (out int minimum_width, out int natural_width) {
180+ minimum_width = pixel_size + EXTRA_MARGIN * 2;
181+ natural_width = minimum_width;
182+ }
183+
184+ public override void get_preferred_height (out int minimum_height, out int natural_height) {
185+ minimum_height = pixel_size + EXTRA_MARGIN * 2;
186+ natural_height = minimum_height;
187 }
188
189 public override bool draw (Cairo.Context cr) {
190- if (pixbuf == null) {
191- return base.draw (cr);
192+ unowned Gtk.StyleContext style_context = get_style_context ();
193+ if (internal_pixbuf == null) {
194+ style_context.save ();
195+ style_context.remove_class (DEFAULT_STYLE);
196+ var result = base.draw (cr);
197+ style_context.restore ();
198+ return result;
199 }
200
201- unowned Gtk.StyleContext style_context = get_style_context ();
202+ int scale = style_context.get_scale ();
203 var width = get_allocated_width () - EXTRA_MARGIN * 2;
204 var height = get_allocated_height () - EXTRA_MARGIN * 2;
205
206- if (draw_theme_background) {
207- var border_radius = style_context.get_property (Gtk.STYLE_PROPERTY_BORDER_RADIUS, Gtk.StateFlags.NORMAL).get_int ();
208- var crop_radius = int.min (width / 2, border_radius * width / 100);
209-
210- Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, EXTRA_MARGIN, EXTRA_MARGIN, width, height, crop_radius);
211- Gdk.cairo_set_source_pixbuf (cr, pixbuf, EXTRA_MARGIN, EXTRA_MARGIN);
212- cr.fill_preserve ();
213- style_context.render_background (cr, EXTRA_MARGIN, EXTRA_MARGIN, width, height);
214- style_context.render_frame (cr, EXTRA_MARGIN, EXTRA_MARGIN, width, height);
215-
216- } else {
217- Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, EXTRA_MARGIN, EXTRA_MARGIN, width, height, 0);
218- Gdk.cairo_set_source_pixbuf (cr, pixbuf, EXTRA_MARGIN, EXTRA_MARGIN);
219- cr.fill_preserve ();
220- }
221+ var border_radius = style_context.get_property (Gtk.STYLE_PROPERTY_BORDER_RADIUS, Gtk.StateFlags.NORMAL).get_int ();
222+ var crop_radius = int.min (width / 2, border_radius * width / 100);
223+
224+ Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, EXTRA_MARGIN, EXTRA_MARGIN, width, height, crop_radius);
225+ Gdk.cairo_set_source_pixbuf (cr, internal_pixbuf, EXTRA_MARGIN, EXTRA_MARGIN);
226+ cr.fill_preserve ();
227+ style_context.render_background (cr, EXTRA_MARGIN, EXTRA_MARGIN, width, height);
228+ style_context.render_frame (cr, EXTRA_MARGIN, EXTRA_MARGIN, width, height);
229
230 return Gdk.EVENT_STOP;
231 }

Subscribers

People subscribed via source and target branches