[gtk/wip/matthiasc/context-menu: 7/7] color chooser: Use a popover menu



commit 2c75a1182b7ef3eba4063714bd12412b85a74ff9
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jun 12 03:02:15 2019 +0000

    color chooser: Use a popover menu
    
    Make the color chooser use a popover menu
    and actions.

 gtk/gtkcolorchooserwidget.c |  99 +++++++++++++++++++++-----------------
 gtk/gtkcolorswatch.c        | 113 +++++++++++++++++++++++++-------------------
 2 files changed, 121 insertions(+), 91 deletions(-)
---
diff --git a/gtk/gtkcolorchooserwidget.c b/gtk/gtkcolorchooserwidget.c
index b2cfdac794..4172eb296b 100644
--- a/gtk/gtkcolorchooserwidget.c
+++ b/gtk/gtkcolorchooserwidget.c
@@ -90,6 +90,8 @@ struct _GtkColorChooserWidgetPrivate
   gboolean has_default_palette;
 
   GSettings *settings;
+
+  GActionMap *context_actions;
 };
 
 enum
@@ -134,31 +136,6 @@ select_swatch (GtkColorChooserWidget *cc,
     g_object_notify (G_OBJECT (cc), "rgba");
 }
 
-static void
-swatch_activate (GtkColorSwatch        *swatch,
-                 GtkColorChooserWidget *cc)
-{
-  GdkRGBA color;
-
-  gtk_color_swatch_get_rgba (swatch, &color);
-  _gtk_color_chooser_color_activated (GTK_COLOR_CHOOSER (cc), &color);
-}
-
-static void
-swatch_customize (GtkColorSwatch        *swatch,
-                  GtkColorChooserWidget *cc)
-{
-  GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
-  GdkRGBA color;
-
-  gtk_color_swatch_get_rgba (swatch, &color);
-  gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (priv->editor), &color);
-
-  gtk_widget_hide (priv->palette);
-  gtk_widget_show (priv->editor);
-  g_object_notify (G_OBJECT (cc), "show-editor");
-}
-
 static void
 swatch_selected (GtkColorSwatch        *swatch,
                  GtkStateFlags          previous,
@@ -176,31 +153,14 @@ static void
 connect_swatch_signals (GtkWidget *p,
                         gpointer   data)
 {
-  g_signal_connect (p, "activate", G_CALLBACK (swatch_activate), data);
-  g_signal_connect (p, "customize", G_CALLBACK (swatch_customize), data);
   g_signal_connect (p, "state-flags-changed", G_CALLBACK (swatch_selected), data);
 }
 
-static void
-button_activate (GtkColorSwatch        *swatch,
-                 GtkColorChooserWidget *cc)
-{
-  GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
-  /* somewhat random, makes the hairline nicely visible */
-  GdkRGBA color = { 0.75, 0.25, 0.25, 1.0 };
-
-  gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (priv->editor), &color);
-
-  gtk_widget_hide (priv->palette);
-  gtk_widget_show (priv->editor);
-  g_object_notify (G_OBJECT (cc), "show-editor");
-}
-
 static void
 connect_button_signals (GtkWidget *p,
                         gpointer   data)
 {
-  g_signal_connect (p, "activate", G_CALLBACK (button_activate), data);
+//  g_signal_connect (p, "activate", G_CALLBACK (button_activate), data);
 }
 
 static void
@@ -532,6 +492,57 @@ add_default_palette (GtkColorChooserWidget *cc)
   priv->has_default_palette = TRUE;
 }
 
+static void
+customize_color (GSimpleAction *action,
+                 GVariant      *parameter,
+                 gpointer       user_data)
+{
+  GtkColorChooserWidget *cc = user_data;
+  GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
+  GdkRGBA color;
+
+  g_variant_get (parameter, "(dddd)", &color.red, &color.green, &color.blue, &color.alpha);
+
+  gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (priv->editor), &color);
+
+  gtk_widget_hide (priv->palette);
+  gtk_widget_show (priv->editor);
+  g_object_notify (G_OBJECT (cc), "show-editor");
+}
+
+static void
+select_color (GSimpleAction *action,
+              GVariant      *parameter,
+              gpointer       user_data)
+{
+  GtkColorChooserWidget *cc = user_data;
+  GdkRGBA color;
+
+  g_variant_get (parameter, "(dddd)", &color.red, &color.green, &color.blue, &color.alpha);
+
+  _gtk_color_chooser_color_activated (GTK_COLOR_CHOOSER (cc), &color);
+}
+
+static void
+gtk_color_chooser_widget_add_context_actions (GtkColorChooserWidget *cc)
+{
+  GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
+
+  GActionEntry entries[] = {
+    { "select", select_color, "(dddd)", NULL, NULL },
+    { "customize", customize_color, "(dddd)", NULL, NULL },
+  };
+
+  GSimpleActionGroup *actions = g_simple_action_group_new ();
+
+  priv->context_actions = G_ACTION_MAP (actions);
+
+  g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), cc);
+
+  gtk_widget_insert_action_group (GTK_WIDGET (cc), "color", G_ACTION_GROUP (actions));
+}
+
+
 static void
 gtk_color_chooser_widget_init (GtkColorChooserWidget *cc)
 {
@@ -623,6 +634,8 @@ gtk_color_chooser_widget_init (GtkColorChooserWidget *cc)
   priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
   gtk_size_group_add_widget (priv->size_group, priv->palette);
   gtk_size_group_add_widget (priv->size_group, box);
+
+  gtk_color_chooser_widget_add_context_actions (cc);
 }
 
 /* GObject implementation {{{1 */
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index a5d3f52499..6932fa2413 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -33,7 +33,7 @@
 #include "gtkintl.h"
 #include "gtkmain.h"
 #include "gtkmodelbutton.h"
-#include "gtkpopover.h"
+#include "gtkpopovermenu.h"
 #include "gtkprivate.h"
 #include "gtksnapshot.h"
 #include "gtkstylecontextprivate.h"
@@ -76,16 +76,6 @@ enum
   PROP_HAS_MENU
 };
 
-enum
-{
-  ACTIVATE,
-  CUSTOMIZE,
-  LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-
 G_DEFINE_TYPE_WITH_PRIVATE (GtkColorSwatch, gtk_color_swatch, GTK_TYPE_WIDGET)
 
 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
@@ -231,6 +221,32 @@ swatch_drag_data_received (GtkWidget        *widget,
   gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (widget), &color);
 }
 
+static void
+activate_color (GtkColorSwatch *swatch)
+{
+  GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
+  gtk_widget_activate_action (GTK_WIDGET (swatch),
+                              "color.select",
+                              g_variant_new ("(dddd)",
+                                             priv->color.red,
+                                             priv->color.green,
+                                             priv->color.blue,
+                                             priv->color.alpha));
+}
+
+static void
+customize_color (GtkColorSwatch *swatch)
+{
+  GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
+  gtk_widget_activate_action (GTK_WIDGET (swatch),
+                              "color.customize",
+                              g_variant_new ("(dddd)",
+                                             priv->color.red,
+                                             priv->color.green,
+                                             priv->color.blue,
+                                             priv->color.alpha));
+}
+
 static gboolean
 key_controller_key_pressed (GtkEventControllerKey *controller,
                             guint                  keyval,
@@ -252,40 +268,51 @@ key_controller_key_pressed (GtkEventControllerKey *controller,
           (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_SELECTED) == 0)
         gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE);
       else
-        g_signal_emit (swatch, signals[ACTIVATE], 0);
+        customize_color (swatch);
+
       return TRUE;
     }
 
   return FALSE;
 }
 
-static void
-emit_customize (GtkColorSwatch *swatch)
+static GMenuModel *
+gtk_color_swatch_get_menu_model (GtkColorSwatch *swatch)
 {
-  g_signal_emit (swatch, signals[CUSTOMIZE], 0);
+  GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
+  GMenu *menu, *section;
+  GMenuItem *item;
+
+  menu = g_menu_new ();
+
+  section = g_menu_new ();
+  item = g_menu_item_new (_("Customize"), NULL);
+  g_menu_item_set_action_and_target_value (item, "color.customize",
+                                           g_variant_new ("(dddd)",
+                                                          priv->color.red,
+                                                          priv->color.green,
+                                                          priv->color.blue,
+                                                          priv->color.alpha));
+
+  g_menu_append_item (section, item);
+  g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
+  g_object_unref (item);
+  g_object_unref (section);
+
+  return G_MENU_MODEL (menu);
 }
 
 static void
 do_popup (GtkColorSwatch *swatch)
 {
   GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
+  GMenuModel *model;
 
-  if (priv->popover == NULL)
-    {
-      GtkWidget *box;
-      GtkWidget *item;
-
-      priv->popover = gtk_popover_new (GTK_WIDGET (swatch));
-      box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-      gtk_container_add (GTK_CONTAINER (priv->popover), box);
-      g_object_set (box, "margin", 10, NULL);
-      item = g_object_new (GTK_TYPE_MODEL_BUTTON,
-                           "text", _("C_ustomize"),
-                           NULL);
-      g_signal_connect_swapped (item, "clicked",
-                                G_CALLBACK (emit_customize), swatch);
-      gtk_container_add (GTK_CONTAINER (box), item);
-    }
+  g_clear_pointer (&priv->popover, gtk_widget_unparent);
+
+  model = gtk_color_swatch_get_menu_model (swatch);
+  priv->popover = gtk_popover_menu_new_from_model (GTK_WIDGET (swatch), model);
+  g_object_unref (model);
 
   gtk_popover_popup (GTK_POPOVER (priv->popover));
 }
@@ -300,7 +327,7 @@ swatch_primary_action (GtkColorSwatch *swatch)
   flags = gtk_widget_get_state_flags (widget);
   if (!priv->has_color)
     {
-      g_signal_emit (swatch, signals[ACTIVATE], 0);
+      customize_color (swatch);
       return TRUE;
     }
   else if (priv->selectable &&
@@ -340,7 +367,7 @@ tap_action (GtkGestureClick *gesture,
       if (n_press == 1)
         swatch_primary_action (swatch);
       else if (n_press > 1)
-        g_signal_emit (swatch, signals[ACTIVATE], 0);
+        activate_color (swatch);
     }
   else if (button == GDK_BUTTON_SECONDARY)
     {
@@ -505,7 +532,7 @@ swatch_dispose (GObject *object)
   GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object);
   GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
 
-  g_clear_pointer (&priv->popover, gtk_widget_destroy);
+  g_clear_pointer (&priv->popover, gtk_widget_unparent);
 
   G_OBJECT_CLASS (gtk_color_swatch_parent_class)->dispose (object);
 }
@@ -530,20 +557,6 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
   widget_class->size_allocate = swatch_size_allocate;
   widget_class->state_flags_changed = swatch_state_flags_changed;
 
-  signals[ACTIVATE] =
-    g_signal_new (I_("activate"),
-                  GTK_TYPE_COLOR_SWATCH,
-                  G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GtkColorSwatchClass, activate),
-                  NULL, NULL, NULL, G_TYPE_NONE, 0);
-
-  signals[CUSTOMIZE] =
-    g_signal_new (I_("customize"),
-                  GTK_TYPE_COLOR_SWATCH,
-                  G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GtkColorSwatchClass, customize),
-                  NULL, NULL, NULL, G_TYPE_NONE, 0);
-
   g_object_class_install_property (object_class, PROP_RGBA,
       g_param_spec_boxed ("rgba", P_("RGBA Color"), P_("Color as RGBA"),
                           GDK_TYPE_RGBA, GTK_PARAM_READWRITE));
@@ -569,6 +582,10 @@ gtk_color_swatch_init (GtkColorSwatch *swatch)
   priv->use_alpha = TRUE;
   priv->selectable = TRUE;
   priv->has_menu = TRUE;
+  priv->color.red = 0.75;
+  priv->color.green = 0.25;
+  priv->color.blue = 0.25;
+  priv->color.alpha = 1.0;
 
   gtk_widget_set_can_focus (GTK_WIDGET (swatch), TRUE);
   gtk_widget_set_overflow (GTK_WIDGET (swatch), GTK_OVERFLOW_HIDDEN);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]