[gimp] libgimpwidgets: new GimpLabelEntry widget and associated prop API…



commit 93575520593c64c49e5e03cf0b55bd3a691215ad
Author: Jehan <jehan girinstud io>
Date:   Wed Feb 16 21:30:33 2022 +0100

    libgimpwidgets: new GimpLabelEntry widget and associated prop API…
    
    … gimp_prop_label_entry_new().

 libgimpwidgets/Makefile.gi        |   2 +
 libgimpwidgets/gimplabelentry.c   | 296 ++++++++++++++++++++++++++++++++++++++
 libgimpwidgets/gimplabelentry.h   |  64 +++++++++
 libgimpwidgets/gimppropwidgets.c  |  57 ++++++++
 libgimpwidgets/gimppropwidgets.h  |   3 +
 libgimpwidgets/gimpwidgets.h      |   1 +
 libgimpwidgets/gimpwidgetstypes.h |   1 +
 libgimpwidgets/meson.build        |   2 +
 8 files changed, 426 insertions(+)
---
diff --git a/libgimpwidgets/Makefile.gi b/libgimpwidgets/Makefile.gi
index e5f65f44dd..685f015482 100644
--- a/libgimpwidgets/Makefile.gi
+++ b/libgimpwidgets/Makefile.gi
@@ -35,6 +35,7 @@ libgimpwidgets_introspectable_headers =       \
        ../libgimpwidgets/gimpintcombobox.h                     \
        ../libgimpwidgets/gimpintstore.h                        \
        ../libgimpwidgets/gimplabeled.h                         \
+       ../libgimpwidgets/gimplabelentry.h                      \
        ../libgimpwidgets/gimplabelintwidget.h                  \
        ../libgimpwidgets/gimplabelspin.h                       \
        ../libgimpwidgets/gimpmemsizeentry.h                    \
@@ -100,6 +101,7 @@ libgimpwidgets_introspectable =     \
        ../libgimpwidgets/gimpintcombobox.c                     \
        ../libgimpwidgets/gimpintstore.c                        \
        ../libgimpwidgets/gimplabeled.c                         \
+       ../libgimpwidgets/gimplabelentry.c                      \
        ../libgimpwidgets/gimplabelintwidget.c                  \
        ../libgimpwidgets/gimplabelspin.c                       \
        ../libgimpwidgets/gimpmemsizeentry.c                    \
diff --git a/libgimpwidgets/gimplabelentry.c b/libgimpwidgets/gimplabelentry.c
new file mode 100644
index 0000000000..6b60f3d936
--- /dev/null
+++ b/libgimpwidgets/gimplabelentry.c
@@ -0,0 +1,296 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimplabelentry.c
+ * Copyright (C) 2022 Jehan
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpmath/gimpmath.h"
+#include "libgimpbase/gimpbase.h"
+
+#include "gimpwidgets.h"
+
+
+/**
+ * SECTION: gimplabelentry
+ * @title: GimpLabelEntry
+ * @short_description: Widget containing an entry and a label.
+ *
+ * This widget is a subclass of #GimpLabeled with a #GtkEntry.
+ **/
+
+enum
+{
+  VALUE_CHANGED,
+  LAST_SIGNAL
+};
+
+enum
+{
+  PROP_0,
+  PROP_VALUE,
+};
+
+typedef struct _GimpLabelEntryPrivate
+{
+  GtkWidget *entry;
+} GimpLabelEntryPrivate;
+
+static void        gimp_label_entry_constructed       (GObject       *object);
+static void        gimp_label_entry_set_property      (GObject       *object,
+                                                       guint          property_id,
+                                                       const GValue  *value,
+                                                       GParamSpec    *pspec);
+static void        gimp_label_entry_get_property      (GObject       *object,
+                                                       guint          property_id,
+                                                       GValue        *value,
+                                                       GParamSpec    *pspec);
+
+static GtkWidget * gimp_label_entry_populate          (GimpLabeled   *entry,
+                                                       gint          *x,
+                                                       gint          *y,
+                                                       gint          *width,
+                                                       gint          *height);
+
+G_DEFINE_TYPE_WITH_PRIVATE (GimpLabelEntry, gimp_label_entry, GIMP_TYPE_LABELED)
+
+#define parent_class gimp_label_entry_parent_class
+
+static guint gimp_label_entry_signals[LAST_SIGNAL] = { 0 };
+
+static void
+gimp_label_entry_class_init (GimpLabelEntryClass *klass)
+{
+  GObjectClass     *object_class  = G_OBJECT_CLASS (klass);
+  GimpLabeledClass *labeled_class = GIMP_LABELED_CLASS (klass);
+
+  gimp_label_entry_signals[VALUE_CHANGED] =
+    g_signal_new ("value-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpLabelEntryClass, value_changed),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  object_class->constructed  = gimp_label_entry_constructed;
+  object_class->set_property = gimp_label_entry_set_property;
+  object_class->get_property = gimp_label_entry_get_property;
+
+  labeled_class->populate    = gimp_label_entry_populate;
+
+  /**
+   * GimpLabelEntry:value:
+   *
+   * The currently set value.
+   *
+   * Since: 3.0
+   **/
+  g_object_class_install_property (object_class, PROP_VALUE,
+                                   g_param_spec_string ("value",
+                                                        "Entry text",
+                                                        "The text in the entry",
+                                                        NULL,
+                                                        GIMP_PARAM_READWRITE));
+}
+
+static void
+gimp_label_entry_init (GimpLabelEntry *entry)
+{
+  GimpLabelEntryPrivate *priv = gimp_label_entry_get_instance_private (entry);
+
+  priv->entry = gtk_entry_new ();
+}
+
+static void
+gimp_label_entry_constructed (GObject *object)
+{
+  GimpLabelEntry        *entry  = GIMP_LABEL_ENTRY (object);
+  GimpLabelEntryPrivate *priv   = gimp_label_entry_get_instance_private (entry);
+  GtkEntryBuffer        *buffer = gtk_entry_get_buffer (GTK_ENTRY (priv->entry));
+
+  G_OBJECT_CLASS (parent_class)->constructed (object);
+
+  /* This is important to make this object into a property widget. It
+   * will allow config object to bind the "value" property of this
+   * widget, and therefore be updated automatically.
+   */
+  g_object_bind_property (G_OBJECT (buffer), "text",
+                          G_OBJECT (entry),  "value",
+                          G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+}
+
+static void
+gimp_label_entry_set_property (GObject      *object,
+                              guint         property_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  GimpLabelEntry        *entry = GIMP_LABEL_ENTRY (object);
+  GimpLabelEntryPrivate *priv  = gimp_label_entry_get_instance_private (entry);
+
+  switch (property_id)
+    {
+    case PROP_VALUE:
+        {
+          GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY (priv->entry));
+
+          /* Avoid looping forever since we have bound this widget's
+           * "value" property with the entry button "value" property.
+           */
+          if (g_strcmp0 (gtk_entry_buffer_get_text (buffer),
+                         g_value_get_string (value)) != 0)
+            gtk_entry_buffer_set_text (buffer, g_value_get_string (value), -1);
+
+          g_signal_emit (object, gimp_label_entry_signals[VALUE_CHANGED], 0);
+        }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_label_entry_get_property (GObject    *object,
+                               guint       property_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  GimpLabelEntry        *entry = GIMP_LABEL_ENTRY (object);
+  GimpLabelEntryPrivate *priv  = gimp_label_entry_get_instance_private (entry);
+
+  switch (property_id)
+    {
+    case PROP_VALUE:
+        {
+          GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY (priv->entry));
+
+          g_value_set_string (value, gtk_entry_buffer_get_text (buffer));
+        }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static GtkWidget *
+gimp_label_entry_populate (GimpLabeled *labeled,
+                           gint        *x,
+                           gint        *y,
+                           gint        *width,
+                           gint        *height)
+{
+  GimpLabelEntry        *entry = GIMP_LABEL_ENTRY (labeled);
+  GimpLabelEntryPrivate *priv = gimp_label_entry_get_instance_private (entry);
+
+  gtk_grid_attach (GTK_GRID (entry), priv->entry, 1, 0, 1, 1);
+  /* Make sure the label and entry won't be glued next to each other's. */
+  gtk_grid_set_column_spacing (GTK_GRID (entry),
+                               4 * gtk_widget_get_scale_factor (GTK_WIDGET (entry)));
+  gtk_widget_show (priv->entry);
+
+  return priv->entry;
+}
+
+
+/* Public Functions */
+
+
+/**
+ * gimp_label_entry_new:
+ * @label:  The text for the #GtkLabel.
+ *
+ *
+ * Returns: (transfer full): The new #GimpLabelEntry widget.
+ **/
+GtkWidget *
+gimp_label_entry_new (const gchar *label)
+{
+  GtkWidget *labeled;
+
+  labeled = g_object_new (GIMP_TYPE_LABEL_ENTRY,
+                          "label",  label,
+                          NULL);
+
+  return labeled;
+}
+
+/**
+ * gimp_label_entry_set_value:
+ * @entry: The #GtkLabelEntry.
+ * @value: A new value.
+ *
+ * This function sets the value in the #GtkEntry inside @entry.
+ **/
+void
+gimp_label_entry_set_value (GimpLabelEntry *entry,
+                            const gchar    *value)
+{
+  g_return_if_fail (GIMP_IS_LABEL_ENTRY (entry));
+
+  g_object_set (entry,
+                "value", value,
+                NULL);
+}
+
+/**
+ * gimp_label_entry_get_value:
+ * @entry: The #GtkLabelEntry.
+ *
+ * This function returns the value shown by @entry.
+ *
+ * Returns: (transfer none): The value currently set.
+ **/
+const gchar *
+gimp_label_entry_get_value (GimpLabelEntry *entry)
+{
+  GimpLabelEntryPrivate *priv = gimp_label_entry_get_instance_private (entry);
+  GtkEntryBuffer        *buffer;
+
+  g_return_val_if_fail (GIMP_IS_LABEL_ENTRY (entry), NULL);
+
+  buffer = gtk_entry_get_buffer (GTK_ENTRY (priv->entry));
+
+  return gtk_entry_buffer_get_text (buffer);
+}
+
+/**
+ * gimp_label_entry_get_entry:
+ * @entry: The #GimpLabelEntry
+ *
+ * This function returns the #GtkEntry packed in @entry.
+ *
+ * Returns: (transfer none): The #GtkEntry contained in @entry.
+ **/
+GtkWidget *
+gimp_label_entry_get_entry (GimpLabelEntry *entry)
+{
+  GimpLabelEntryPrivate *priv = gimp_label_entry_get_instance_private (entry);
+
+  g_return_val_if_fail (GIMP_IS_LABEL_ENTRY (entry), NULL);
+
+  return priv->entry;
+}
diff --git a/libgimpwidgets/gimplabelentry.h b/libgimpwidgets/gimplabelentry.h
new file mode 100644
index 0000000000..fa69df18b3
--- /dev/null
+++ b/libgimpwidgets/gimplabelentry.h
@@ -0,0 +1,64 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimplabelentry.h
+ * Copyright (C) 2022 Jehan
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__GIMP_WIDGETS_H_INSIDE__) && !defined (GIMP_WIDGETS_COMPILATION)
+#error "Only <libgimpwidgets/gimpwidgets.h> can be included directly."
+#endif
+
+#ifndef __GIMP_LABEL_ENTRY_H__
+#define __GIMP_LABEL_ENTRY_H__
+
+#include <libgimpwidgets/gimplabeled.h>
+
+G_BEGIN_DECLS
+
+#define GIMP_TYPE_LABEL_ENTRY (gimp_label_entry_get_type ())
+G_DECLARE_DERIVABLE_TYPE (GimpLabelEntry, gimp_label_entry, GIMP, LABEL_ENTRY, GimpLabeled)
+
+struct _GimpLabelEntryClass
+{
+  GimpLabeledClass   parent_class;
+
+  /*  Signals */
+  void (* value_changed)   (GimpLabelEntry *entry);
+
+  /* Padding for future expansion */
+  void (* _gimp_reserved1) (void);
+  void (* _gimp_reserved2) (void);
+  void (* _gimp_reserved3) (void);
+  void (* _gimp_reserved4) (void);
+  void (* _gimp_reserved5) (void);
+  void (* _gimp_reserved6) (void);
+  void (* _gimp_reserved7) (void);
+  void (* _gimp_reserved8) (void);
+};
+
+GtkWidget   * gimp_label_entry_new        (const gchar   *label);
+
+void          gimp_label_entry_set_value  (GimpLabelEntry *entry,
+                                           const gchar    *value);
+const gchar * gimp_label_entry_get_value  (GimpLabelEntry *entry);
+
+GtkWidget   * gimp_label_entry_get_entry  (GimpLabelEntry *entry);
+
+G_END_DECLS
+
+#endif /* __GIMP_LABEL_ENTRY_H__ */
diff --git a/libgimpwidgets/gimppropwidgets.c b/libgimpwidgets/gimppropwidgets.c
index 34db39d2a6..c624cd48e2 100644
--- a/libgimpwidgets/gimppropwidgets.c
+++ b/libgimpwidgets/gimppropwidgets.c
@@ -2100,6 +2100,63 @@ gimp_prop_entry_notify (GObject    *config,
   g_free (value);
 }
 
+/*****************/
+/*  label entry  */
+/*****************/
+
+/**
+ * gimp_prop_label_entry_new:
+ * @config:        Object to which property is attached.
+ * @property_name: Name of string property.
+ * @max_len:       Maximum allowed length of string (set to negative for
+ *                 no maximum).
+ *
+ * Creates a #GimpLabelEntry to set and display the value of the
+ * specified string property.
+ *
+ * Returns: (transfer full): A new #GtkEntry widget.
+ *
+ * Since: 3.0
+ */
+GtkWidget *
+gimp_prop_label_entry_new (GObject     *config,
+                           const gchar *property_name,
+                           gint         max_len)
+{
+  GParamSpec  *param_spec;
+  GtkWidget   *label_entry;
+  GtkWidget   *entry;
+  const gchar *label;
+
+  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
+  g_return_val_if_fail (property_name != NULL, NULL);
+
+  param_spec = check_param_spec (config, property_name,
+                                 G_TYPE_PARAM_STRING, G_STRFUNC);
+  if (! param_spec)
+    return NULL;
+
+  label = g_param_spec_get_nick (param_spec);
+  label_entry = gimp_label_entry_new (label);
+  entry = gimp_label_entry_get_entry (GIMP_LABEL_ENTRY (label_entry));
+
+  if (max_len > 0)
+    gtk_entry_set_max_length (GTK_ENTRY (entry), max_len);
+
+  gtk_editable_set_editable (GTK_EDITABLE (entry),
+                             param_spec->flags & G_PARAM_WRITABLE);
+
+  set_param_spec (G_OBJECT (label_entry), label_entry, param_spec);
+
+  g_object_bind_property (config,      property_name,
+                          label_entry, "value",
+                          G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+  gtk_widget_show (label_entry);
+
+  return label_entry;
+}
+
 
 /*****************/
 /*  text buffer  */
diff --git a/libgimpwidgets/gimppropwidgets.h b/libgimpwidgets/gimppropwidgets.h
index 120df1ab2c..8bfdf99e24 100644
--- a/libgimpwidgets/gimppropwidgets.h
+++ b/libgimpwidgets/gimppropwidgets.h
@@ -147,6 +147,9 @@ GtkWidget     * gimp_prop_label_new               (GObject       *config,
 GtkWidget     * gimp_prop_entry_new               (GObject       *config,
                                                    const gchar   *property_name,
                                                    gint           max_len);
+GtkWidget     * gimp_prop_label_entry_new         (GObject       *config,
+                                                   const gchar   *property_name,
+                                                   gint           max_len);
 GtkTextBuffer * gimp_prop_text_buffer_new         (GObject       *config,
                                                    const gchar   *property_name,
                                                    gint           max_len);
diff --git a/libgimpwidgets/gimpwidgets.h b/libgimpwidgets/gimpwidgets.h
index 84bc0b2473..b7dc789081 100644
--- a/libgimpwidgets/gimpwidgets.h
+++ b/libgimpwidgets/gimpwidgets.h
@@ -62,6 +62,7 @@
 #include <libgimpwidgets/gimpintcombobox.h>
 #include <libgimpwidgets/gimpintstore.h>
 #include <libgimpwidgets/gimplabeled.h>
+#include <libgimpwidgets/gimplabelentry.h>
 #include <libgimpwidgets/gimplabelintwidget.h>
 #include <libgimpwidgets/gimplabelspin.h>
 #include <libgimpwidgets/gimpmemsizeentry.h>
diff --git a/libgimpwidgets/gimpwidgetstypes.h b/libgimpwidgets/gimpwidgetstypes.h
index 3177bf39e9..940698e757 100644
--- a/libgimpwidgets/gimpwidgetstypes.h
+++ b/libgimpwidgets/gimpwidgetstypes.h
@@ -63,6 +63,7 @@ typedef struct _GimpHintBox                   GimpHintBox;
 typedef struct _GimpIntComboBox               GimpIntComboBox;
 typedef struct _GimpIntStore                  GimpIntStore;
 typedef struct _GimpLabeled                   GimpLabeled;
+typedef struct _GimpLabelEntry                GimpLabelEntry;
 typedef struct _GimpLabelSpin                 GimpLabelSpin;
 typedef struct _GimpMemsizeEntry              GimpMemsizeEntry;
 typedef struct _GimpNumberPairEntry           GimpNumberPairEntry;
diff --git a/libgimpwidgets/meson.build b/libgimpwidgets/meson.build
index 7004d8cb3e..9521a69cf9 100644
--- a/libgimpwidgets/meson.build
+++ b/libgimpwidgets/meson.build
@@ -57,6 +57,7 @@ libgimpwidgets_sources_introspectable = files(
   'gimplabeled.c',
   'gimplabelintwidget.c',
   'gimplabelspin.c',
+  'gimplabelentry.c',
   'gimpmemsizeentry.c',
   'gimpnumberpairentry.c',
   'gimpoffsetarea.c',
@@ -133,6 +134,7 @@ libgimpwidgets_headers_introspectable = files(
   'gimplabeled.h',
   'gimplabelintwidget.h',
   'gimplabelspin.h',
+  'gimplabelentry.h',
   'gimpintstore.h',
   'gimpmemsizeentry.h',
   'gimpnumberpairentry.h',


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