[gimp] app: implement picking any image or layer in GimpPickableButton/Popup



commit 2ef565b58f08956fd6ea83976b2749d4e29b43b5
Author: Michael Natterer <mitch gimp org>
Date:   Fri Jun 6 22:47:24 2014 +0200

    app: implement picking any image or layer in GimpPickableButton/Popup

 app/widgets/gimppickablebutton.c |   15 +--
 app/widgets/gimppickablepopup.c  |  209 ++++++++++++++++++++++++++++++++------
 app/widgets/gimppickablepopup.h  |   10 +-
 3 files changed, 186 insertions(+), 48 deletions(-)
---
diff --git a/app/widgets/gimppickablebutton.c b/app/widgets/gimppickablebutton.c
index 841808e..7a11ea8 100644
--- a/app/widgets/gimppickablebutton.c
+++ b/app/widgets/gimppickablebutton.c
@@ -73,8 +73,6 @@ static void     gimp_pickable_button_get_property  (GObject            *object,
 
 static void     gimp_pickable_button_clicked       (GtkButton          *button);
 
-static void     gimp_pickable_button_popup_cancel  (GimpPickablePopup  *popup,
-                                                    GimpPickableButton *button);
 static void     gimp_pickable_button_popup_confirm (GimpPickablePopup  *popup,
                                                     GimpPickableButton *button);
 static void     gimp_pickable_button_drop_pickable (GtkWidget          *widget,
@@ -248,9 +246,6 @@ gimp_pickable_button_clicked (GtkButton *button)
                                    pickable_button->private->view_size,
                                    pickable_button->private->view_border_width);
 
-  g_signal_connect (popup, "cancel",
-                    G_CALLBACK (gimp_pickable_button_popup_cancel),
-                    button);
   g_signal_connect (popup, "confirm",
                     G_CALLBACK (gimp_pickable_button_popup_confirm),
                     button);
@@ -259,15 +254,13 @@ gimp_pickable_button_clicked (GtkButton *button)
 }
 
 static void
-gimp_pickable_button_popup_cancel (GimpPickablePopup  *popup,
-                                   GimpPickableButton *button)
-{
-}
-
-static void
 gimp_pickable_button_popup_confirm (GimpPickablePopup  *popup,
                                     GimpPickableButton *button)
 {
+  GimpPickable *pickable = gimp_pickable_popup_get_pickable (popup);
+
+  if (pickable)
+    gimp_pickable_button_set_pickable (button, pickable);
 }
 
 static void
diff --git a/app/widgets/gimppickablepopup.c b/app/widgets/gimppickablepopup.c
index b7d2795..36c7b2a 100644
--- a/app/widgets/gimppickablepopup.c
+++ b/app/widgets/gimppickablepopup.c
@@ -30,10 +30,12 @@
 
 #include "core/gimp.h"
 #include "core/gimpcontext.h"
+#include "core/gimpimage.h"
 #include "core/gimppickable.h"
 #include "core/gimpviewable.h"
 
 #include "gimpcontainertreeview.h"
+#include "gimpcontainerview.h"
 #include "gimppickablepopup.h"
 #include "gimpviewrenderer.h"
 
@@ -56,21 +58,35 @@ struct _GimpPickablePopupPrivate
 
   gint          view_size;
   gint          view_border_width;
-};
 
+  GtkWidget    *image_view;
+  GtkWidget    *layer_view;
+  GtkWidget    *layer_label;
+};
 
-static void   gimp_pickable_popup_constructed  (GObject      *object);
-static void   gimp_pickable_popup_finalize     (GObject      *object);
-static void   gimp_pickable_popup_set_property (GObject      *object,
-                                                guint         property_id,
-                                                const GValue *value,
-                                                GParamSpec   *pspec);
-static void   gimp_pickable_popup_get_property (GObject      *object,
-                                                guint         property_id,
-                                                GValue       *value,
-                                                GParamSpec   *pspec);
 
-static void   gimp_pickable_popup_confirm      (GimpPopup    *popup);
+static void   gimp_pickable_popup_constructed    (GObject           *object);
+static void   gimp_pickable_popup_finalize       (GObject           *object);
+static void   gimp_pickable_popup_set_property   (GObject           *object,
+                                                  guint              property_id,
+                                                  const GValue      *value,
+                                                  GParamSpec        *pspec);
+static void   gimp_pickable_popup_get_property   (GObject           *object,
+                                                  guint              property_id,
+                                                  GValue            *value,
+                                                  GParamSpec        *pspec);
+
+static void   gimp_pickable_popup_image_changed  (GimpContext       *context,
+                                                  GimpImage          *image,
+                                                  GimpPickablePopup  *popup);
+static void   gimp_pickable_popup_image_activate (GimpContainerView *view,
+                                                  GimpImage         *image,
+                                                  gpointer           unused,
+                                                  GimpPickablePopup *popup);
+static void   gimp_pickable_popup_layer_activate (GimpContainerView *view,
+                                                  GimpLayer         *layer,
+                                                  gpointer           unused,
+                                                  GimpPickablePopup *popup);
 
 
 G_DEFINE_TYPE (GimpPickablePopup, gimp_pickable_popup, GIMP_TYPE_POPUP)
@@ -81,16 +97,13 @@ G_DEFINE_TYPE (GimpPickablePopup, gimp_pickable_popup, GIMP_TYPE_POPUP)
 static void
 gimp_pickable_popup_class_init (GimpPickablePopupClass *klass)
 {
-  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
-  GimpPopupClass *popup_class  = GIMP_POPUP_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->constructed  = gimp_pickable_popup_constructed;
   object_class->finalize     = gimp_pickable_popup_finalize;
   object_class->get_property = gimp_pickable_popup_get_property;
   object_class->set_property = gimp_pickable_popup_set_property;
 
-  popup_class->confirm       = gimp_pickable_popup_confirm;
-
   g_object_class_install_property (object_class, PROP_CONTEXT,
                                    g_param_spec_object ("context",
                                                         NULL, NULL,
@@ -142,7 +155,10 @@ gimp_pickable_popup_constructed (GObject *object)
 {
   GimpPickablePopup *popup = GIMP_PICKABLE_POPUP (object);
   GtkWidget         *frame;
-  GtkWidget         *image_view;
+  GtkWidget         *hbox;
+  GtkWidget         *vbox;
+  GtkWidget         *label;
+  GimpImage         *image;
 
   G_OBJECT_CLASS (parent_class)->constructed (object);
 
@@ -153,18 +169,72 @@ gimp_pickable_popup_constructed (GObject *object)
   gtk_container_add (GTK_CONTAINER (popup), frame);
   gtk_widget_show (frame);
 
-  image_view = gimp_container_tree_view_new (popup->priv->context->gimp->images,
-                                             popup->priv->context,
-                                             popup->priv->view_size,
-                                             popup->priv->view_border_width);
-  gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (image_view),
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+  gtk_container_add (GTK_CONTAINER (frame), hbox);
+  gtk_widget_show (hbox);
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
+  gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+  gtk_widget_show (vbox);
+
+  label = gtk_label_new (_("Images"));
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  popup->priv->image_view =
+    gimp_container_tree_view_new (popup->priv->context->gimp->images,
+                                  popup->priv->context,
+                                  popup->priv->view_size,
+                                  popup->priv->view_border_width);
+  gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (popup->priv->image_view),
+                                       4 * (popup->priv->view_size +
+                                            2 * popup->priv->view_border_width),
+                                       4 * (popup->priv->view_size +
+                                            2 * popup->priv->view_border_width));
+  gtk_box_pack_start (GTK_BOX (vbox), popup->priv->image_view, TRUE, TRUE, 0);
+  gtk_widget_show (popup->priv->image_view);
+
+  g_signal_connect_object (popup->priv->image_view, "activate-item",
+                           G_CALLBACK (gimp_pickable_popup_image_activate),
+                           G_OBJECT (popup), 0);
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
+  gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+  gtk_widget_show (vbox);
+
+  popup->priv->layer_label = label = gtk_label_new (_("Layers"));
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  popup->priv->layer_view =
+    gimp_container_tree_view_new (NULL,
+                                  popup->priv->context,
+                                  popup->priv->view_size,
+                                  popup->priv->view_border_width);
+  gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (GIMP_CONTAINER_TREE_VIEW (popup->priv->layer_view)->view),
+                                    TRUE);
+  gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (popup->priv->layer_view),
                                        4 * (popup->priv->view_size +
                                             2 * popup->priv->view_border_width),
                                        4 * (popup->priv->view_size +
                                             2 * popup->priv->view_border_width));
-  gtk_container_set_border_width (GTK_CONTAINER (image_view), 6);
-  gtk_container_add (GTK_CONTAINER (frame), image_view);
-  gtk_widget_show (image_view);
+  gtk_box_pack_start (GTK_BOX (vbox), popup->priv->layer_view, TRUE, TRUE, 0);
+  gtk_widget_show (popup->priv->layer_view);
+
+  g_signal_connect_object (popup->priv->layer_view, "activate-item",
+                           G_CALLBACK (gimp_pickable_popup_layer_activate),
+                           G_OBJECT (popup), 0);
+
+  g_signal_connect_object (popup->priv->context, "image-changed",
+                           G_CALLBACK (gimp_pickable_popup_image_changed),
+                           G_OBJECT (popup), 0);
+
+  image = gimp_context_get_image (popup->priv->context);
+  gimp_pickable_popup_image_changed (popup->priv->context, image, popup);
 }
 
 static void
@@ -250,14 +320,6 @@ gimp_pickable_popup_get_property (GObject    *object,
     }
 }
 
-static void
-gimp_pickable_popup_confirm (GimpPopup *popup)
-{
-  /* GimpPickablePopup *c_popup = GIMP_PICKABLE_POPUP (popup); */
-
-  GIMP_POPUP_CLASS (parent_class)->confirm (popup);
-}
-
 GtkWidget *
 gimp_pickable_popup_new (GimpContext *context,
                          gint         view_size,
@@ -277,3 +339,84 @@ gimp_pickable_popup_new (GimpContext *context,
                        "view-border-width", view_border_width,
                        NULL);
 }
+
+GimpPickable *
+gimp_pickable_popup_get_pickable (GimpPickablePopup *popup)
+{
+  GtkWidget    *focus;
+  GimpPickable *pickable = NULL;
+
+  g_return_val_if_fail (GIMP_IS_PICKABLE_POPUP (popup), NULL);
+
+  focus = gtk_window_get_focus (GTK_WINDOW (popup));
+
+  if (focus && gtk_widget_is_ancestor (focus, popup->priv->image_view))
+    {
+      pickable = GIMP_PICKABLE (gimp_context_get_image (popup->priv->context));
+    }
+  else if (focus && gtk_widget_is_ancestor (focus, popup->priv->layer_view))
+    {
+      GList *selected;
+
+      if (gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (popup->priv->layer_view),
+                                            &selected))
+        {
+          pickable = selected->data;
+          g_list_free (selected);
+        }
+    }
+
+  return pickable;
+}
+
+
+/*  private functions  */
+
+static void
+gimp_pickable_popup_image_changed (GimpContext       *context,
+                                   GimpImage         *image,
+                                   GimpPickablePopup *popup)
+{
+  GimpContainer *container = NULL;
+
+  if (image)
+    {
+      gchar *desc;
+      gchar *text;
+
+      container = gimp_image_get_layers (image);
+
+      desc = gimp_viewable_get_description (GIMP_VIEWABLE (image), NULL);
+      text = g_strdup_printf (_("Layers of %s"), desc);
+      g_free (desc);
+
+      gtk_label_set_text (GTK_LABEL (popup->priv->layer_label), text);
+      g_free (text);
+    }
+  else
+    {
+      gtk_label_set_text (GTK_LABEL (popup->priv->layer_label),
+                          _("Layers"));
+    }
+
+  gimp_container_view_set_container (GIMP_CONTAINER_VIEW (popup->priv->layer_view),
+                                     container);
+}
+
+static void
+gimp_pickable_popup_image_activate (GimpContainerView *view,
+                                    GimpImage         *image,
+                                    gpointer           unused,
+                                    GimpPickablePopup *popup)
+{
+  g_signal_emit_by_name (popup, "confirm");
+}
+
+static void
+gimp_pickable_popup_layer_activate (GimpContainerView *view,
+                                    GimpLayer         *layer,
+                                    gpointer           unused,
+                                    GimpPickablePopup *popup)
+{
+  g_signal_emit_by_name (popup, "confirm");
+}
diff --git a/app/widgets/gimppickablepopup.h b/app/widgets/gimppickablepopup.h
index e2d34d4..bff96b2 100644
--- a/app/widgets/gimppickablepopup.h
+++ b/app/widgets/gimppickablepopup.h
@@ -49,11 +49,13 @@ struct _GimpPickablePopupClass
 };
 
 
-GType       gimp_pickable_popup_get_type (void) G_GNUC_CONST;
+GType          gimp_pickable_popup_get_type     (void) G_GNUC_CONST;
 
-GtkWidget * gimp_pickable_popup_new      (GimpContext *context,
-                                          gint         view_size,
-                                          gint         view_border_width);
+GtkWidget    * gimp_pickable_popup_new          (GimpContext       *context,
+                                                 gint               view_size,
+                                                 gint               view_border_width);
+
+GimpPickable * gimp_pickable_popup_get_pickable (GimpPickablePopup *popup);
 
 
 #endif  /*  __GIMP_PICKABLE_POPUP_H__  */


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