]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcolorswatch.c
GtkIconTheme: fix failed assertion when asynchrnously loading emblemed icons
[~andy/gtk] / gtk / gtkcolorswatch.c
index 3c8edd59dbf9d3f8fb5e0f86c4a21fb89948d99f..c6081d7907f1adadc9339f088297f497801fbf5b 100644 (file)
 #include "gtkmenu.h"
 #include "gtkmenuitem.h"
 #include "gtkmenushell.h"
+#include "gtkpressandholdprivate.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
-#include "a11y/gtkcolorswatchaccessible.h"
+#include "a11y/gtkcolorswatchaccessibleprivate.h"
 
 
 struct _GtkColorSwatchPrivate
@@ -44,6 +45,8 @@ struct _GtkColorSwatchPrivate
   guint    selectable       : 1;
 
   GdkWindow *event_window;
+
+  GtkPressAndHold *press_and_hold;
 };
 
 enum
@@ -117,7 +120,7 @@ swatch_draw (GtkWidget *widget,
         {
           cairo_save (cr);
 
-          _gtk_rounded_box_path (&background.clip_box, cr);
+          _gtk_rounded_box_path (&background.padding_box, cr);
           cairo_clip_preserve (cr);
 
           cairo_set_source_rgb (cr, 0.33, 0.33, 0.33);
@@ -156,9 +159,9 @@ swatch_draw (GtkWidget *widget,
         cairo_set_source_rgba (cr, 1., 1., 1., 0.4);
       else
         cairo_set_source_rgba (cr, 0., 0., 0., 0.4);
-      _gtk_rounded_box_shrink (&background.clip_box, 3, 3, 3, 3);
-      _gtk_rounded_box_path (&background.clip_box, cr);
-      cairo_stroke (cr);
+        _gtk_rounded_box_shrink (&background.padding_box, 3, 3, 3, 3);
+        _gtk_rounded_box_path (&background.padding_box, cr);
+        cairo_stroke (cr);
     }
 
   if (swatch->priv->icon)
@@ -225,7 +228,7 @@ swatch_draw (GtkWidget *widget,
           g_object_unref (pixbuf);
         }
 
-      gtk_icon_info_free (icon_info);
+      g_object_unref (icon_info);
     }
 
   cairo_restore (cr);
@@ -484,31 +487,89 @@ swatch_button_press (GtkWidget      *widget,
   return FALSE;
 }
 
+static gboolean
+swatch_primary_action (GtkColorSwatch *swatch)
+{
+  GtkWidget *widget = (GtkWidget *)swatch;
+  GtkStateFlags flags;
+
+  flags = gtk_widget_get_state_flags (widget);
+  if (!swatch->priv->has_color)
+    {
+      g_signal_emit (swatch, signals[ACTIVATE], 0);
+      return TRUE;
+    }
+  else if (swatch->priv->selectable &&
+           (flags & GTK_STATE_FLAG_SELECTED) == 0)
+    {
+      gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 static gboolean
 swatch_button_release (GtkWidget      *widget,
                        GdkEventButton *event)
 {
   GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
-  GtkStateFlags flags;
 
   if (event->button == GDK_BUTTON_PRIMARY &&
       swatch->priv->contains_pointer)
+    return swatch_primary_action (swatch);
+
+  return FALSE;
+}
+
+static void
+hold_action (GtkPressAndHold *pah,
+             gint             x,
+             gint             y,
+             GtkColorSwatch  *swatch)
+{
+  emit_customize (swatch);
+}
+
+static void
+tap_action (GtkPressAndHold *pah,
+            gint             x,
+            gint             y,
+            GtkColorSwatch  *swatch)
+{
+  swatch_primary_action (swatch);
+}
+
+static gboolean
+swatch_touch (GtkWidget     *widget,
+              GdkEventTouch *event)
+{
+  GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
+
+  if (!swatch->priv->press_and_hold)
     {
-      flags = gtk_widget_get_state_flags (widget);
-      if (!swatch->priv->has_color)
-        {
-          g_signal_emit (swatch, signals[ACTIVATE], 0);
-          return TRUE;
-        }
-      else if (swatch->priv->selectable &&
-               (flags & GTK_STATE_FLAG_SELECTED) == 0)
-        {
-          gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE);
-          return TRUE;
-        }
+      gint drag_threshold;
+
+      g_object_get (gtk_widget_get_settings (widget),
+                    "gtk-dnd-drag-threshold", &drag_threshold,
+                    NULL);
+
+      swatch->priv->press_and_hold = gtk_press_and_hold_new ();
+
+      g_object_set (swatch->priv->press_and_hold,
+                    "drag-threshold", drag_threshold,
+                    "hold-time", 1000,
+                    NULL);
+
+      g_signal_connect (swatch->priv->press_and_hold, "hold",
+                        G_CALLBACK (hold_action), swatch);
+      g_signal_connect (swatch->priv->press_and_hold, "tap",
+                        G_CALLBACK (tap_action), swatch);
     }
 
-  return FALSE;
+  gtk_press_and_hold_process_event (swatch->priv->press_and_hold, (GdkEvent *)event);
+
+  return TRUE;
 }
 
 static void
@@ -552,10 +613,11 @@ swatch_realize (GtkWidget *widget)
   attributes.height = allocation.height;
   attributes.wclass = GDK_INPUT_ONLY;
   attributes.event_mask = gtk_widget_get_events (widget);
-  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
-                           GDK_BUTTON_RELEASE_MASK |
-                           GDK_ENTER_NOTIFY_MASK |
-                           GDK_LEAVE_NOTIFY_MASK);
+  attributes.event_mask |= GDK_BUTTON_PRESS_MASK
+                           | GDK_BUTTON_RELEASE_MASK
+                           | GDK_ENTER_NOTIFY_MASK
+                           | GDK_LEAVE_NOTIFY_MASK
+                           | GDK_TOUCH_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y;
 
@@ -566,7 +628,7 @@ swatch_realize (GtkWidget *widget)
   swatch->priv->event_window = 
     gdk_window_new (window,
                     &attributes, attributes_mask);
-  gdk_window_set_user_data (swatch->priv->event_window, widget);
+  gtk_widget_register_window (widget, swatch->priv->event_window);
 }
 
 static void
@@ -576,7 +638,7 @@ swatch_unrealize (GtkWidget *widget)
 
   if (swatch->priv->event_window)
     {
-      gdk_window_set_user_data (swatch->priv->event_window, NULL);
+      gtk_widget_unregister_window (widget, swatch->priv->event_window);
       gdk_window_destroy (swatch->priv->event_window);
       swatch->priv->event_window = NULL;
     }
@@ -661,6 +723,7 @@ swatch_finalize (GObject *object)
   GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object);
 
   g_free (swatch->priv->icon);
+  g_clear_object (&swatch->priv->press_and_hold);
 
   G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
 }
@@ -692,6 +755,7 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
   widget_class->map = swatch_map;
   widget_class->unmap = swatch_unmap;
   widget_class->size_allocate = swatch_size_allocate;
+  widget_class->touch_event = swatch_touch;
 
   signals[ACTIVATE] =
     g_signal_new ("activate",