]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkentry.c
tests: Add simple test for image clipboard
[~andy/gtk] / gtk / gtkentry.c
index b95fd8b901af4b099969de27851ce7468b05793f..0e2d931b307e24540beaa294b88892c88e5c6fb2 100644 (file)
@@ -33,7 +33,6 @@
 #include <math.h>
 #include <string.h>
 
-#include "gtkalignment.h"
 #include "gtkbindings.h"
 #include "gtkcelleditable.h"
 #include "gtkclipboard.h"
@@ -231,6 +230,8 @@ struct _EntryIconInfo
   gchar        *icon_name;
   GIcon        *gicon;
 
+  GtkStateFlags last_state;
+
   GtkTargetList *target_list;
   GdkDragAction actions;
 };
@@ -3335,8 +3336,6 @@ draw_icon (GtkWidget            *widget,
   GdkPixbuf *pixbuf;
   gint x, y, width, height;
   GtkStyleContext *context;
-  GtkIconSource *icon_source;
-  GtkStateFlags state;
 
   if (!icon_info)
     return;
@@ -3349,6 +3348,8 @@ draw_icon (GtkWidget            *widget,
   width = gdk_window_get_width (icon_info->window);
   height = gdk_window_get_height (icon_info->window);
 
+  context = gtk_widget_get_style_context (widget);
+
   /* size_allocate hasn't been called yet. These are the default values.
    */
   if (width == 1 || height == 1)
@@ -3372,26 +3373,7 @@ draw_icon (GtkWidget            *widget,
   x = (width  - gdk_pixbuf_get_width (pixbuf)) / 2;
   y = (height - gdk_pixbuf_get_height (pixbuf)) / 2;
 
-  icon_source = gtk_icon_source_new ();
-  gtk_icon_source_set_pixbuf (icon_source, pixbuf);
-  gtk_icon_source_set_state_wildcarded (icon_source, TRUE);
-
-  state = 0;
-  if (!gtk_widget_is_sensitive (widget) || icon_info->insensitive)
-    state |= GTK_STATE_FLAG_INSENSITIVE;
-  else if (icon_info->prelight)
-    state |= GTK_STATE_FLAG_PRELIGHT;
-
-  context = gtk_widget_get_style_context (widget);
-  gtk_style_context_save (context);
-  gtk_style_context_set_state (context, state);
-  pixbuf = gtk_render_icon_pixbuf (context, icon_source, (GtkIconSize)-1);
-  gtk_style_context_restore (context);
-
-  gtk_icon_source_free (icon_source);
-
-  gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
-  cairo_paint (cr);
+  gtk_render_icon (context, cr, pixbuf, x, y);
 
   g_object_unref (pixbuf);
 }
@@ -6711,7 +6693,7 @@ create_normal_pixbuf (GtkStyleContext *context,
   gtk_style_context_save (context);
 
   /* Unset any state */
-  gtk_style_context_set_state (context, 0);
+  gtk_style_context_set_state (context, GTK_STATE_FLAG_NORMAL);
 
   icon_set = gtk_style_context_lookup_icon_set (context, stock_id);
   pixbuf = gtk_icon_set_render_icon_pixbuf (icon_set, context, icon_size);
@@ -6721,6 +6703,49 @@ create_normal_pixbuf (GtkStyleContext *context,
   return pixbuf;
 }
 
+static GdkPixbuf *
+ensure_stated_icon_from_info (GtkStyleContext *context,
+                              GtkIconInfo *info)
+{
+  GdkPixbuf *retval = NULL;
+  gboolean symbolic = FALSE;
+
+  if (info != NULL)
+    {
+      retval =
+        gtk_icon_info_load_symbolic_for_context (info,
+                                                 context,
+                                                 &symbolic,
+                                                 NULL);
+    }
+
+  if (retval == NULL)
+    {
+      retval =
+        create_normal_pixbuf (context,
+                              GTK_STOCK_MISSING_IMAGE,
+                              GTK_ICON_SIZE_MENU);
+    }
+  else if (!symbolic)
+    {
+      GdkPixbuf *temp_pixbuf;
+      GtkIconSource *icon_source;
+
+      icon_source = gtk_icon_source_new ();
+      gtk_icon_source_set_pixbuf (icon_source, retval);
+      gtk_icon_source_set_state_wildcarded (icon_source, TRUE);
+
+      temp_pixbuf = gtk_render_icon_pixbuf (context, icon_source, (GtkIconSize)-1);
+
+      gtk_icon_source_free (icon_source);
+
+      g_object_unref (retval);
+      retval = temp_pixbuf;
+    }
+
+  return retval;
+}
+
 static void
 gtk_entry_ensure_pixbuf (GtkEntry             *entry,
                          GtkEntryIconPosition  icon_pos)
@@ -6734,13 +6759,28 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
   GtkWidget *widget;
   GdkScreen *screen;
   gint width, height;
-
-  if (!icon_info || icon_info->pixbuf)
-    return;
+  GtkStateFlags state;
 
   widget = GTK_WIDGET (entry);
   context = gtk_widget_get_style_context (widget);
 
+  state = GTK_STATE_FLAG_NORMAL;
+
+  if (!gtk_widget_is_sensitive (widget) || icon_info->insensitive)
+    state |= GTK_STATE_FLAG_INSENSITIVE;
+  else if (icon_info->prelight)
+    state |= GTK_STATE_FLAG_PRELIGHT;
+
+  if ((icon_info == NULL) ||
+      ((icon_info->pixbuf != NULL) && icon_info->last_state == state))
+    return;
+
+  icon_info->last_state = state;
+
+  gtk_style_context_save (context);
+  gtk_style_context_set_state (context, state);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_IMAGE);
+
   switch (icon_info->storage_type)
     {
     case GTK_IMAGE_EMPTY:
@@ -6767,15 +6807,16 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
                                              GTK_ICON_SIZE_MENU,
                                              &width, &height);
 
-          icon_info->pixbuf = gtk_icon_theme_load_icon (icon_theme,
-                                                        icon_info->icon_name,
-                                                        MIN (width, height),
-                                                        0, NULL);
+          info = gtk_icon_theme_lookup_icon (icon_theme,
+                                             icon_info->icon_name,
+                                             MIN (width, height), 
+                                             0);
+
+          icon_info->pixbuf =
+            ensure_stated_icon_from_info (context, info);
 
-          if (icon_info->pixbuf == NULL)
-            icon_info->pixbuf = create_normal_pixbuf (context,
-                                                      GTK_STOCK_MISSING_IMAGE,
-                                                      GTK_ICON_SIZE_MENU);
+          if (info)
+            gtk_icon_info_free (info);
         }
       break;
 
@@ -6794,16 +6835,12 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
                                                  icon_info->gicon,
                                                  MIN (width, height), 
                                                  GTK_ICON_LOOKUP_USE_BUILTIN);
-          if (info)
-            {
-              icon_info->pixbuf = gtk_icon_info_load_icon (info, NULL);
-              gtk_icon_info_free (info);
-            }
 
-          if (icon_info->pixbuf == NULL)
-            icon_info->pixbuf = create_normal_pixbuf (context,
-                                                      GTK_STOCK_MISSING_IMAGE,
-                                                      GTK_ICON_SIZE_MENU);
+          icon_info->pixbuf =
+            ensure_stated_icon_from_info (context, info);
+
+          if (info)
+            gtk_icon_info_free (info);
         }
       break;
 
@@ -6811,7 +6848,9 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
       g_assert_not_reached ();
       break;
     }
-    
+
+  gtk_style_context_restore (context);
+
   if (icon_info->pixbuf != NULL && icon_info->window != NULL)
     gdk_window_show_unraised (icon_info->window);
 }
@@ -7232,7 +7271,7 @@ gtk_entry_get_overwrite_mode (GtkEntry *entry)
  *      storage in the widget and must not be freed, modified or
  *      stored.
  **/
-G_CONST_RETURN gchar*
+const gchar*
 gtk_entry_get_text (GtkEntry *entry)
 {
   g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
@@ -7497,7 +7536,7 @@ gtk_entry_set_inner_border (GtkEntry        *entry,
  *
  * Since: 2.10
  **/
-G_CONST_RETURN GtkBorder *
+const GtkBorder *
 gtk_entry_get_inner_border (GtkEntry *entry)
 {
   g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
@@ -9987,6 +10026,12 @@ gtk_entry_set_completion (GtkEntry           *entry,
           old->priv->completion_timeout = 0;
         }
 
+      if (old->priv->check_completion_idle)
+        {
+          g_source_destroy (old->priv->check_completion_idle);
+          old->priv->check_completion_idle = NULL;
+        }
+
       if (gtk_widget_get_mapped (old->priv->popup_window))
         _gtk_entry_completion_popdown (old);
 
@@ -10309,7 +10354,7 @@ gtk_entry_set_placeholder_text (GtkEntry    *entry,
  *
  * Since: 3.2
  **/
-G_CONST_RETURN gchar *
+const gchar *
 gtk_entry_get_placeholder_text (GtkEntry *entry)
 {
   GtkEntryPrivate *priv;