From aba260146c099864e69379e31bd3decbf3681817 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 12 Feb 2013 14:04:37 +0100 Subject: [PATCH 63/68] entry: Use scaled icons on windows with a scale factor --- gtk/gtkentry.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++------ gtk/gtkentry.h | 7 +++ 2 files changed, 171 insertions(+), 20 deletions(-) diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 0d16d71..313804e 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -105,9 +105,11 @@ typedef struct gchar *stock_id; gchar *icon_name; GIcon *gicon; + GtkIconSet *icon_set; GtkTargetList *target_list; GdkDragAction actions; + gdouble render_scale; } EntryIconInfo; struct _GtkEntryPrivate @@ -207,6 +209,8 @@ enum { PROP_ICON_NAME_SECONDARY, PROP_GICON_PRIMARY, PROP_GICON_SECONDARY, + PROP_ICON_SET_PRIMARY, + PROP_ICON_SET_SECONDARY, PROP_STORAGE_TYPE_PRIMARY, PROP_STORAGE_TYPE_SECONDARY, PROP_ACTIVATABLE_PRIMARY, @@ -1009,7 +1013,21 @@ gtk_entry_class_init (GtkEntryClass *class) P_("GIcon for secondary icon"), G_TYPE_ICON, GTK_PARAM_READWRITE)); - + g_object_class_install_property (gobject_class, + PROP_ICON_SET_PRIMARY, + g_param_spec_boxed ("primary-icon-set", + P_("Primary icon set"), + P_("GtkIconSet for the primary icon"), + GTK_TYPE_ICON_SET, + GTK_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_ICON_SET_SECONDARY, + g_param_spec_boxed ("secondary-icon-set", + P_("Secondary icon set"), + P_("GtkIconSet for the secondary icon"), + GTK_TYPE_ICON_SET, + GTK_PARAM_READWRITE)); + /** * GtkEntry:primary-icon-storage-type: * @@ -1940,6 +1958,18 @@ gtk_entry_set_property (GObject *object, g_value_get_object (value)); break; + case PROP_ICON_SET_PRIMARY: + gtk_entry_set_icon_from_icon_set (entry, + GTK_ENTRY_ICON_PRIMARY, + g_value_get_boxed (value)); + break; + + case PROP_ICON_SET_SECONDARY: + gtk_entry_set_icon_from_icon_set (entry, + GTK_ENTRY_ICON_SECONDARY, + g_value_get_boxed (value)); + break; + case PROP_ACTIVATABLE_PRIMARY: gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_PRIMARY, @@ -2158,6 +2188,18 @@ gtk_entry_get_property (GObject *object, GTK_ENTRY_ICON_SECONDARY)); break; + case PROP_ICON_SET_PRIMARY: + g_value_set_boxed (value, + gtk_entry_get_icon_set (entry, + GTK_ENTRY_ICON_PRIMARY)); + break; + + case PROP_ICON_SET_SECONDARY: + g_value_set_boxed (value, + gtk_entry_get_icon_set (entry, + GTK_ENTRY_ICON_SECONDARY)); + break; + case PROP_STORAGE_TYPE_PRIMARY: g_value_set_enum (value, gtk_entry_get_icon_storage_type (entry, @@ -2334,7 +2376,9 @@ get_icon_width (GtkEntry *entry, gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &menu_icon_width, NULL); - return MAX (gdk_pixbuf_get_width (icon_info->pixbuf), menu_icon_width); + return MAX (gdk_pixbuf_get_width (icon_info->pixbuf) / + gtk_widget_get_scale_factor (GTK_WIDGET (entry)), + menu_icon_width); } static void @@ -3188,6 +3232,7 @@ draw_icon (GtkWidget *widget, EntryIconInfo *icon_info = priv->icons[icon_pos]; GdkPixbuf *pixbuf; gint x, y, width, height; + gdouble window_scale; cairo_t *cr; if (!icon_info) @@ -3198,8 +3243,9 @@ draw_icon (GtkWidget *widget, if (icon_info->pixbuf == NULL) return; - width = gdk_window_get_width (icon_info->window); - height = gdk_window_get_height (icon_info->window); + window_scale = gdk_window_get_scale_factor (widget->window); + width = gdk_window_get_width (icon_info->window) / window_scale; + height = gdk_window_get_height (icon_info->window) / window_scale; /* size_allocate hasn't been called yet. These are the default values. */ @@ -3209,20 +3255,20 @@ draw_icon (GtkWidget *widget, pixbuf = icon_info->pixbuf; g_object_ref (pixbuf); - if (gdk_pixbuf_get_height (pixbuf) > height) + if (gdk_pixbuf_get_height (pixbuf) > (height * window_scale)) { GdkPixbuf *temp_pixbuf; gint scale; - scale = height - 2 * priv->icon_margin; + scale = (height - 2 * priv->icon_margin) * window_scale; temp_pixbuf = gdk_pixbuf_scale_simple (pixbuf, scale, scale, GDK_INTERP_BILINEAR); g_object_unref (pixbuf); pixbuf = temp_pixbuf; } - x = (width - gdk_pixbuf_get_width (pixbuf)) / 2; - y = (height - gdk_pixbuf_get_height (pixbuf)) / 2; + x = (width - (gdk_pixbuf_get_width (pixbuf) / window_scale)) / 2; + y = (height - (gdk_pixbuf_get_height (pixbuf) / window_scale)) / 2; if (!gtk_widget_is_sensitive (widget) || icon_info->insensitive) @@ -6455,6 +6501,17 @@ gtk_entry_clear (GtkEntry *entry, icon_pos == GTK_ENTRY_ICON_PRIMARY ? "primary-icon-gicon" : "secondary-icon-gicon"); break; + case GTK_IMAGE_ICON_SET: + if (icon_info->icon_set) + { + gtk_icon_set_unref (icon_info->icon_set); + icon_info->icon_set = NULL; + } + + g_object_notify (G_OBJECT (entry), + icon_pos == GTK_ENTRY_ICON_PRIMARY ? "primary-icon-set" : "secondary-icon-set"); + break; + default: g_assert_not_reached (); break; @@ -6494,15 +6551,18 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry, case GTK_IMAGE_STOCK: state = gtk_widget_get_state (widget); gtk_widget_set_state (widget, GTK_STATE_NORMAL); - icon_info->pixbuf = gtk_widget_render_icon (widget, - icon_info->stock_id, - GTK_ICON_SIZE_MENU, - NULL); + icon_info->render_scale = gtk_widget_get_scale_factor (widget); + icon_info->pixbuf = gtk_widget_render_icon_scaled (widget, + icon_info->stock_id, + GTK_ICON_SIZE_MENU, + NULL, + &icon_info->render_scale); if (!icon_info->pixbuf) - icon_info->pixbuf = gtk_widget_render_icon (widget, - GTK_STOCK_MISSING_IMAGE, - GTK_ICON_SIZE_MENU, - NULL); + icon_info->pixbuf = gtk_widget_render_icon_scaled (widget, + GTK_STOCK_MISSING_IMAGE, + GTK_ICON_SIZE_MENU, + NULL, + &icon_info->render_scale); gtk_widget_set_state (widget, state); break; @@ -6514,8 +6574,9 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry, settings = gtk_settings_get_for_screen (screen); gtk_icon_size_lookup_for_settings (settings, - GTK_ICON_SIZE_MENU, - &width, &height); + GTK_ICON_SIZE_MENU, + // gdk_window_get_scale_factor (widget->window), + &width, &height); icon_info->pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_info->icon_name, @@ -6543,8 +6604,9 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry, settings = gtk_settings_get_for_screen (screen); gtk_icon_size_lookup_for_settings (settings, - GTK_ICON_SIZE_MENU, - &width, &height); + GTK_ICON_SIZE_MENU, + //gdk_window_get_scale_factor (widget->window), + &width, &height); info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon_info->gicon, @@ -6569,6 +6631,17 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry, } break; + case GTK_IMAGE_ICON_SET: + icon_info->render_scale = gtk_widget_get_scale_factor (widget); + icon_info->pixbuf = + gtk_icon_set_render_icon_scaled (icon_info->icon_set, + widget->style, + gtk_widget_get_direction (widget), + gtk_widget_get_state (widget), + GTK_ICON_SIZE_MENU, widget, + NULL, &icon_info->render_scale); + break; + default: g_assert_not_reached (); break; @@ -7847,6 +7920,58 @@ gtk_entry_set_icon_from_gicon (GtkEntry *entry, g_object_thaw_notify (G_OBJECT (entry)); } +void +gtk_entry_set_icon_from_icon_set (GtkEntry *entry, + GtkEntryIconPosition icon_pos, + GtkIconSet *icon_set) +{ + GtkEntryPrivate *priv; + EntryIconInfo *icon_info; + + g_return_if_fail (GTK_IS_ENTRY (entry)); + g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); + + priv = GTK_ENTRY_GET_PRIVATE (entry); + + if ((icon_info = priv->icons[icon_pos]) == NULL) + icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); + + g_object_freeze_notify (G_OBJECT (entry)); + + /* need to ref before clearing */ + if (icon_set) + gtk_icon_set_ref (icon_set); + + gtk_entry_clear (entry, icon_pos); + + if (icon_set) + { + icon_info->storage_type = GTK_IMAGE_ICON_SET; + icon_info->icon_set = icon_set; + + if (icon_pos == GTK_ENTRY_ICON_PRIMARY) + { + g_object_notify (G_OBJECT (entry), "primary-icon-set"); + g_object_notify (G_OBJECT (entry), "primary-icon-storage-type"); + } + else + { + g_object_notify (G_OBJECT (entry), "secondary-icon-set"); + g_object_notify (G_OBJECT (entry), "secondary-icon-storage-type"); + } + + if (gtk_widget_get_mapped (GTK_WIDGET (entry))) + gdk_window_show_unraised (icon_info->window); + } + + gtk_entry_ensure_pixbuf (entry, icon_pos); + + if (gtk_widget_get_visible (GTK_WIDGET (entry))) + gtk_widget_queue_resize (GTK_WIDGET (entry)); + + g_object_thaw_notify (G_OBJECT (entry)); +} + /** * gtk_entry_set_icon_activatable: * @entry: A #GtkEntry @@ -8050,6 +8175,25 @@ gtk_entry_get_icon_name (GtkEntry *entry, return icon_info->storage_type == GTK_IMAGE_ICON_NAME ? icon_info->icon_name : NULL; } +const GtkIconSet * +gtk_entry_get_icon_set (GtkEntry *entry, + GtkEntryIconPosition icon_pos) +{ + GtkEntryPrivate *priv; + EntryIconInfo *icon_info; + + g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); + g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); + + priv = GTK_ENTRY_GET_PRIVATE (entry); + icon_info = priv->icons[icon_pos]; + + if (!icon_info) + return NULL; + + return icon_info->storage_type == GTK_IMAGE_ICON_SET ? icon_info->icon_set : NULL; +} + /** * gtk_entry_set_icon_sensitive: * @entry: A #GtkEntry diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h index f771e17..0153f49 100644 --- a/gtk/gtkentry.h +++ b/gtk/gtkentry.h @@ -264,6 +264,9 @@ void gtk_entry_set_icon_from_icon_name (GtkEntry * void gtk_entry_set_icon_from_gicon (GtkEntry *entry, GtkEntryIconPosition icon_pos, GIcon *icon); +void gtk_entry_set_icon_from_icon_set (GtkEntry *entry, + GtkEntryIconPosition icon_pos, + GtkIconSet *icon_set); GtkImageType gtk_entry_get_icon_storage_type (GtkEntry *entry, GtkEntryIconPosition icon_pos); GdkPixbuf* gtk_entry_get_icon_pixbuf (GtkEntry *entry, @@ -274,6 +277,10 @@ const gchar* gtk_entry_get_icon_name (GtkEntry * GtkEntryIconPosition icon_pos); GIcon* gtk_entry_get_icon_gicon (GtkEntry *entry, GtkEntryIconPosition icon_pos); +const GtkIconSet * + gtk_entry_get_icon_set (GtkEntry *entry, + GtkEntryIconPosition icon_pos); + void gtk_entry_set_icon_activatable (GtkEntry *entry, GtkEntryIconPosition icon_pos, gboolean activatable); -- 1.7.10.2 (Apple Git-33)