1From aba260146c099864e69379e31bd3decbf3681817 Mon Sep 17 00:00:00 2001
2From: Carlos Garnacho <carlosg@gnome.org>
3Date: Tue, 12 Feb 2013 14:04:37 +0100
4Subject: [PATCH 63/68] entry: Use scaled icons on windows with a scale factor
5
6---
7 gtk/gtkentry.c |  184 ++++++++++++++++++++++++++++++++++++++++++++++++++------
8 gtk/gtkentry.h |    7 +++
9 2 files changed, 171 insertions(+), 20 deletions(-)
10
11diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
12index 0d16d71..313804e 100644
13--- a/gtk/gtkentry.c
14+++ b/gtk/gtkentry.c
15@@ -105,9 +105,11 @@ typedef struct
16   gchar        *stock_id;
17   gchar        *icon_name;
18   GIcon        *gicon;
19+  GtkIconSet   *icon_set;
20
21   GtkTargetList *target_list;
22   GdkDragAction actions;
23+  gdouble render_scale;
24 } EntryIconInfo;
25
26 struct _GtkEntryPrivate
27@@ -207,6 +209,8 @@ enum {
28   PROP_ICON_NAME_SECONDARY,
29   PROP_GICON_PRIMARY,
30   PROP_GICON_SECONDARY,
31+  PROP_ICON_SET_PRIMARY,
32+  PROP_ICON_SET_SECONDARY,
33   PROP_STORAGE_TYPE_PRIMARY,
34   PROP_STORAGE_TYPE_SECONDARY,
35   PROP_ACTIVATABLE_PRIMARY,
36@@ -1009,7 +1013,21 @@ gtk_entry_class_init (GtkEntryClass *class)
37                                                         P_("GIcon for secondary icon"),
38                                                         G_TYPE_ICON,
39                                                         GTK_PARAM_READWRITE));
40-
41+  g_object_class_install_property (gobject_class,
42+                                   PROP_ICON_SET_PRIMARY,
43+                                   g_param_spec_boxed ("primary-icon-set",
44+                                                       P_("Primary icon set"),
45+                                                       P_("GtkIconSet for the primary icon"),
46+                                                       GTK_TYPE_ICON_SET,
47+                                                       GTK_PARAM_READWRITE));
48+  g_object_class_install_property (gobject_class,
49+                                   PROP_ICON_SET_SECONDARY,
50+                                   g_param_spec_boxed ("secondary-icon-set",
51+                                                       P_("Secondary icon set"),
52+                                                       P_("GtkIconSet for the secondary icon"),
53+                                                       GTK_TYPE_ICON_SET,
54+                                                       GTK_PARAM_READWRITE));
55+
56   /**
57    * GtkEntry:primary-icon-storage-type:
58    *
59@@ -1940,6 +1958,18 @@ gtk_entry_set_property (GObject         *object,
60                                      g_value_get_object (value));
61       break;
62
63+    case PROP_ICON_SET_PRIMARY:
64+      gtk_entry_set_icon_from_icon_set (entry,
65+                                        GTK_ENTRY_ICON_PRIMARY,
66+                                        g_value_get_boxed (value));
67+      break;
68+
69+    case PROP_ICON_SET_SECONDARY:
70+      gtk_entry_set_icon_from_icon_set (entry,
71+                                        GTK_ENTRY_ICON_SECONDARY,
72+                                        g_value_get_boxed (value));
73+      break;
74+
75     case PROP_ACTIVATABLE_PRIMARY:
76       gtk_entry_set_icon_activatable (entry,
77                                       GTK_ENTRY_ICON_PRIMARY,
78@@ -2158,6 +2188,18 @@ gtk_entry_get_property (GObject         *object,
79                                                     GTK_ENTRY_ICON_SECONDARY));
80       break;
81
82+    case PROP_ICON_SET_PRIMARY:
83+      g_value_set_boxed (value,
84+                         gtk_entry_get_icon_set (entry,
85+                                                 GTK_ENTRY_ICON_PRIMARY));
86+      break;
87+
88+    case PROP_ICON_SET_SECONDARY:
89+      g_value_set_boxed (value,
90+                         gtk_entry_get_icon_set (entry,
91+                                                 GTK_ENTRY_ICON_SECONDARY));
92+      break;
93+
94     case PROP_STORAGE_TYPE_PRIMARY:
95       g_value_set_enum (value,
96                         gtk_entry_get_icon_storage_type (entry,
97@@ -2334,7 +2376,9 @@ get_icon_width (GtkEntry             *entry,
98   gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
99                                      &menu_icon_width, NULL);
100
101-  return MAX (gdk_pixbuf_get_width (icon_info->pixbuf), menu_icon_width);
102+  return MAX (gdk_pixbuf_get_width (icon_info->pixbuf) /
103+              gtk_widget_get_scale_factor (GTK_WIDGET (entry)),
104+              menu_icon_width);
105 }
106
107 static void
108@@ -3188,6 +3232,7 @@ draw_icon (GtkWidget            *widget,
109   EntryIconInfo *icon_info = priv->icons[icon_pos];
110   GdkPixbuf *pixbuf;
111   gint x, y, width, height;
112+  gdouble window_scale;
113   cairo_t *cr;
114
115   if (!icon_info)
116@@ -3198,8 +3243,9 @@ draw_icon (GtkWidget            *widget,
117   if (icon_info->pixbuf == NULL)
118     return;
119
120-  width = gdk_window_get_width (icon_info->window);
121-  height = gdk_window_get_height (icon_info->window);
122+  window_scale = gdk_window_get_scale_factor (widget->window);
123+  width = gdk_window_get_width (icon_info->window) / window_scale;
124+  height = gdk_window_get_height (icon_info->window) / window_scale;
125
126   /* size_allocate hasn't been called yet. These are the default values.
127    */
128@@ -3209,20 +3255,20 @@ draw_icon (GtkWidget            *widget,
129   pixbuf = icon_info->pixbuf;
130   g_object_ref (pixbuf);
131
132-  if (gdk_pixbuf_get_height (pixbuf) > height)
133+  if (gdk_pixbuf_get_height (pixbuf) > (height * window_scale))
134     {
135       GdkPixbuf *temp_pixbuf;
136       gint scale;
137
138-      scale = height - 2 * priv->icon_margin;
139+      scale = (height - 2 * priv->icon_margin) * window_scale;
140       temp_pixbuf = gdk_pixbuf_scale_simple (pixbuf, scale, scale,
141                                              GDK_INTERP_BILINEAR);
142       g_object_unref (pixbuf);
143       pixbuf = temp_pixbuf;
144     }
145
146-  x = (width  - gdk_pixbuf_get_width (pixbuf)) / 2;
147-  y = (height - gdk_pixbuf_get_height (pixbuf)) / 2;
148+  x = (width  - (gdk_pixbuf_get_width (pixbuf) / window_scale)) / 2;
149+  y = (height - (gdk_pixbuf_get_height (pixbuf) / window_scale)) / 2;
150
151   if (!gtk_widget_is_sensitive (widget) ||
152       icon_info->insensitive)
153@@ -6455,6 +6501,17 @@ gtk_entry_clear (GtkEntry             *entry,
154                        icon_pos == GTK_ENTRY_ICON_PRIMARY ? "primary-icon-gicon" : "secondary-icon-gicon");
155       break;
156
157+    case GTK_IMAGE_ICON_SET:
158+      if (icon_info->icon_set)
159+        {
160+          gtk_icon_set_unref (icon_info->icon_set);
161+          icon_info->icon_set = NULL;
162+        }
163+
164+      g_object_notify (G_OBJECT (entry),
165+                       icon_pos == GTK_ENTRY_ICON_PRIMARY ? "primary-icon-set" : "secondary-icon-set");
166+      break;
167+
168     default:
169       g_assert_not_reached ();
170       break;
171@@ -6494,15 +6551,18 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
172     case GTK_IMAGE_STOCK:
173       state = gtk_widget_get_state (widget);
174       gtk_widget_set_state (widget, GTK_STATE_NORMAL);
175-      icon_info->pixbuf = gtk_widget_render_icon (widget,
176-                                                  icon_info->stock_id,
177-                                                  GTK_ICON_SIZE_MENU,
178-                                                  NULL);
179+      icon_info->render_scale = gtk_widget_get_scale_factor (widget);
180+      icon_info->pixbuf = gtk_widget_render_icon_scaled (widget,
181+                                                         icon_info->stock_id,
182+                                                         GTK_ICON_SIZE_MENU,
183+                                                         NULL,
184+                                                         &icon_info->render_scale);
185       if (!icon_info->pixbuf)
186-        icon_info->pixbuf = gtk_widget_render_icon (widget,
187-                                                    GTK_STOCK_MISSING_IMAGE,
188-                                                    GTK_ICON_SIZE_MENU,
189-                                                    NULL);
190+        icon_info->pixbuf = gtk_widget_render_icon_scaled (widget,
191+                                                           GTK_STOCK_MISSING_IMAGE,
192+                                                           GTK_ICON_SIZE_MENU,
193+                                                           NULL,
194+                                                           &icon_info->render_scale);
195       gtk_widget_set_state (widget, state);
196       break;
197
198@@ -6514,8 +6574,9 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
199           settings = gtk_settings_get_for_screen (screen);
200
201           gtk_icon_size_lookup_for_settings (settings,
202-                                             GTK_ICON_SIZE_MENU,
203-                                             &width, &height);
204+                                       GTK_ICON_SIZE_MENU,
205+                                //                                       gdk_window_get_scale_factor (widget->window),
206+                                       &width, &height);
207
208           icon_info->pixbuf = gtk_icon_theme_load_icon (icon_theme,
209                                                         icon_info->icon_name,
210@@ -6543,8 +6604,9 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
211           settings = gtk_settings_get_for_screen (screen);
212
213           gtk_icon_size_lookup_for_settings (settings,
214-                                             GTK_ICON_SIZE_MENU,
215-                                             &width, &height);
216+                                       GTK_ICON_SIZE_MENU,
217+                                             //gdk_window_get_scale_factor (widget->window),
218+                                       &width, &height);
219
220           info = gtk_icon_theme_lookup_by_gicon (icon_theme,
221                                                  icon_info->gicon,
222@@ -6569,6 +6631,17 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
223         }
224       break;
225
226+    case GTK_IMAGE_ICON_SET:
227+      icon_info->render_scale = gtk_widget_get_scale_factor (widget);
228+      icon_info->pixbuf =
229+        gtk_icon_set_render_icon_scaled (icon_info->icon_set,
230+                                         widget->style,
231+                                         gtk_widget_get_direction (widget),
232+                                         gtk_widget_get_state (widget),
233+                                         GTK_ICON_SIZE_MENU, widget,
234+                                         NULL, &icon_info->render_scale);
235+      break;
236+
237     default:
238       g_assert_not_reached ();
239       break;
240@@ -7847,6 +7920,58 @@ gtk_entry_set_icon_from_gicon (GtkEntry             *entry,
241   g_object_thaw_notify (G_OBJECT (entry));
242 }
243
244+void
245+gtk_entry_set_icon_from_icon_set (GtkEntry             *entry,
246+                                  GtkEntryIconPosition  icon_pos,
247+                                  GtkIconSet           *icon_set)
248+{
249+  GtkEntryPrivate *priv;
250+  EntryIconInfo *icon_info;
251+
252+  g_return_if_fail (GTK_IS_ENTRY (entry));
253+  g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
254+
255+  priv = GTK_ENTRY_GET_PRIVATE (entry);
256+
257+  if ((icon_info = priv->icons[icon_pos]) == NULL)
258+    icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
259+
260+  g_object_freeze_notify (G_OBJECT (entry));
261+
262+  /* need to ref before clearing */
263+  if (icon_set)
264+    gtk_icon_set_ref (icon_set);
265+
266+  gtk_entry_clear (entry, icon_pos);
267+
268+  if (icon_set)
269+    {
270+      icon_info->storage_type = GTK_IMAGE_ICON_SET;
271+      icon_info->icon_set = icon_set;
272+
273+      if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
274+        {
275+          g_object_notify (G_OBJECT (entry), "primary-icon-set");
276+          g_object_notify (G_OBJECT (entry), "primary-icon-storage-type");
277+        }
278+      else
279+        {
280+          g_object_notify (G_OBJECT (entry), "secondary-icon-set");
281+          g_object_notify (G_OBJECT (entry), "secondary-icon-storage-type");
282+        }
283+
284+      if (gtk_widget_get_mapped (GTK_WIDGET (entry)))
285+          gdk_window_show_unraised (icon_info->window);
286+    }
287+
288+  gtk_entry_ensure_pixbuf (entry, icon_pos);
289+
290+  if (gtk_widget_get_visible (GTK_WIDGET (entry)))
291+    gtk_widget_queue_resize (GTK_WIDGET (entry));
292+
293+  g_object_thaw_notify (G_OBJECT (entry));
294+}
295+
296 /**
297  * gtk_entry_set_icon_activatable:
298  * @entry: A #GtkEntry
299@@ -8050,6 +8175,25 @@ gtk_entry_get_icon_name (GtkEntry             *entry,
300   return icon_info->storage_type == GTK_IMAGE_ICON_NAME ? icon_info->icon_name : NULL;
301 }
302
303+const GtkIconSet *
304+gtk_entry_get_icon_set (GtkEntry             *entry,
305+                        GtkEntryIconPosition  icon_pos)
306+{
307+  GtkEntryPrivate *priv;
308+  EntryIconInfo *icon_info;
309+
310+  g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
311+  g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL);
312+
313+  priv = GTK_ENTRY_GET_PRIVATE (entry);
314+  icon_info = priv->icons[icon_pos];
315+
316+  if (!icon_info)
317+    return NULL;
318+
319+  return icon_info->storage_type == GTK_IMAGE_ICON_SET ? icon_info->icon_set : NULL;
320+}
321+
322 /**
323  * gtk_entry_set_icon_sensitive:
324  * @entry: A #GtkEntry
325diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h
326index f771e17..0153f49 100644
327--- a/gtk/gtkentry.h
328+++ b/gtk/gtkentry.h
329@@ -264,6 +264,9 @@ void           gtk_entry_set_icon_from_icon_name         (GtkEntry             *
330 void           gtk_entry_set_icon_from_gicon             (GtkEntry             *entry,
331							  GtkEntryIconPosition  icon_pos,
332							  GIcon                *icon);
333+void           gtk_entry_set_icon_from_icon_set          (GtkEntry             *entry,
334+							  GtkEntryIconPosition  icon_pos,
335+							  GtkIconSet           *icon_set);
336 GtkImageType gtk_entry_get_icon_storage_type             (GtkEntry             *entry,
337							  GtkEntryIconPosition  icon_pos);
338 GdkPixbuf*   gtk_entry_get_icon_pixbuf                   (GtkEntry             *entry,
339@@ -274,6 +277,10 @@ const gchar* gtk_entry_get_icon_name                     (GtkEntry             *
340							  GtkEntryIconPosition  icon_pos);
341 GIcon*       gtk_entry_get_icon_gicon                    (GtkEntry             *entry,
342							  GtkEntryIconPosition  icon_pos);
343+const GtkIconSet *
344+             gtk_entry_get_icon_set                      (GtkEntry             *entry,
345+                                                          GtkEntryIconPosition  icon_pos);
346+
347 void         gtk_entry_set_icon_activatable              (GtkEntry             *entry,
348							  GtkEntryIconPosition  icon_pos,
349							  gboolean              activatable);
350--
3511.7.10.2 (Apple Git-33)
352