[gimp/gimp-2-10] app: add GimpAccelLabel



commit a54704bcdcde881e0ced3ddb1a0de6d9e20fb6a9
Author: Ell <ell_se yahoo com>
Date:   Mon Jun 1 18:38:57 2020 +0300

    app: add GimpAccelLabel
    
    Add a new GimpAccelLabel widget, which shows an accelerator label
    for a given GimpAction.  Unlike GtkAccelLabel, GimpAccelLabel
    doesn't show a user-provided label in addition to that.
    
    Note that the size request of GtkAccelLabel doesn't include the
    accelerator part, which is desirable in some contexts.
    GimpAccelLabel doesn't suffer from that.
    
    (cherry picked from commit 2259ad5fcc25a7429d45538d71e8c5b91b6e0328)

 app/widgets/Makefile.am      |   2 +
 app/widgets/gimpaccellabel.c | 283 +++++++++++++++++++++++++++++++++++++++++++
 app/widgets/gimpaccellabel.h |  58 +++++++++
 app/widgets/widgets-types.h  |   1 +
 4 files changed, 344 insertions(+)
---
diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am
index 0503d5e204..451e88c066 100644
--- a/app/widgets/Makefile.am
+++ b/app/widgets/Makefile.am
@@ -32,6 +32,8 @@ noinst_LIBRARIES = libappwidgets.a
 libappwidgets_a_sources = \
        widgets-enums.h                 \
        widgets-types.h                 \
+       gimpaccellabel.c                \
+       gimpaccellabel.h                \
        gimpaction.c                    \
        gimpaction.h                    \
        gimpaction-history.c            \
diff --git a/app/widgets/gimpaccellabel.c b/app/widgets/gimpaccellabel.c
new file mode 100644
index 0000000000..6f1c0c0f9a
--- /dev/null
+++ b/app/widgets/gimpaccellabel.c
@@ -0,0 +1,283 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpaccellabel.c
+ * Copyright (C) 2020 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+
+#include "widgets-types.h"
+
+#include "gimpaction.h"
+#include "gimpaccellabel.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_ACTION
+};
+
+
+struct _GimpAccelLabelPrivate
+{
+  GimpAction *action;
+};
+
+
+/*  local function prototypes  */
+
+static void   gimp_accel_label_dispose       (GObject             *object);
+static void   gimp_accel_label_set_property  (GObject             *object,
+                                              guint                property_id,
+                                              const GValue        *value,
+                                              GParamSpec          *pspec);
+static void   gimp_accel_label_get_property  (GObject             *object,
+                                              guint                property_id,
+                                              GValue              *value,
+                                              GParamSpec          *pspec);
+
+static void   gimp_accel_label_accel_changed (GtkAccelGroup       *accel_group,
+                                              guint                keyval,
+                                              GdkModifierType      modifier,
+                                              GClosure            *accel_closure,
+                                              GimpAccelLabel      *accel_label);
+
+static void   gimp_accel_label_update        (GimpAccelLabel      *accel_label);
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (GimpAccelLabel, gimp_accel_label, GTK_TYPE_LABEL)
+
+#define parent_class gimp_accel_label_parent_class
+
+
+/*  private functions  */
+
+static void
+gimp_accel_label_class_init (GimpAccelLabelClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose      = gimp_accel_label_dispose;
+  object_class->get_property = gimp_accel_label_get_property;
+  object_class->set_property = gimp_accel_label_set_property;
+
+  g_object_class_install_property (object_class, PROP_ACTION,
+                                   g_param_spec_object ("action",
+                                                        NULL, NULL,
+                                                        GIMP_TYPE_ACTION,
+                                                        GIMP_PARAM_READWRITE));
+}
+
+static void
+gimp_accel_label_init (GimpAccelLabel *accel_label)
+{
+  accel_label->priv = gimp_accel_label_get_instance_private (accel_label);
+}
+
+static void
+gimp_accel_label_dispose (GObject *object)
+{
+  GimpAccelLabel *accel_label = GIMP_ACCEL_LABEL (object);
+
+  gimp_accel_label_set_action (accel_label, NULL);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gimp_accel_label_set_property (GObject      *object,
+                               guint         property_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  GimpAccelLabel *accel_label = GIMP_ACCEL_LABEL (object);
+
+  switch (property_id)
+    {
+    case PROP_ACTION:
+      gimp_accel_label_set_action (accel_label, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_accel_label_get_property (GObject    *object,
+                               guint       property_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  GimpAccelLabel *accel_label = GIMP_ACCEL_LABEL (object);
+
+  switch (property_id)
+    {
+    case PROP_ACTION:
+      g_value_set_object (value, accel_label->priv->action);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_accel_label_accel_changed (GtkAccelGroup   *accel_group,
+                                guint            keyval,
+                                GdkModifierType  modifier,
+                                GClosure        *accel_closure,
+                                GimpAccelLabel  *accel_label)
+{
+  if (accel_closure ==
+      gimp_action_get_accel_closure (accel_label->priv->action))
+    {
+      gimp_accel_label_update (accel_label);
+    }
+}
+
+static gboolean
+gimp_accel_label_update_accel_find_func (GtkAccelKey *key,
+                                         GClosure    *closure,
+                                         gpointer     data)
+{
+  return (GClosure *) data == closure;
+}
+
+static void
+gimp_accel_label_update (GimpAccelLabel *accel_label)
+{
+  GClosure      *accel_closure;
+  GtkAccelGroup *accel_group;
+  GtkAccelKey   *accel_key;
+
+  gtk_label_set_label (GTK_LABEL (accel_label), NULL);
+
+  if (! accel_label->priv->action)
+    return;
+
+  accel_closure = gimp_action_get_accel_closure (accel_label->priv->action);
+
+  if (! accel_closure)
+    return;
+
+  accel_group = gtk_accel_group_from_accel_closure (accel_closure);
+
+  if (! accel_group)
+    return;
+
+  accel_key = gtk_accel_group_find (accel_group,
+                                    gimp_accel_label_update_accel_find_func,
+                                    accel_closure);
+
+  if (accel_key            &&
+      accel_key->accel_key &&
+      (accel_key->accel_flags & GTK_ACCEL_VISIBLE))
+    {
+      gchar *label;
+
+      label = gtk_accelerator_get_label (accel_key->accel_key,
+                                         accel_key->accel_mods);
+
+      gtk_label_set_label (GTK_LABEL (accel_label), label);
+
+      g_free (label);
+    }
+}
+
+
+/*  public functions  */
+
+GtkWidget *
+gimp_accel_label_new (GimpAction *action)
+{
+  g_return_val_if_fail (action == NULL || GIMP_IS_ACTION (action), NULL);
+
+  return g_object_new (GIMP_TYPE_ACCEL_LABEL,
+                       "action", action,
+                       NULL);
+}
+
+void
+gimp_accel_label_set_action (GimpAccelLabel *accel_label,
+                             GimpAction     *action)
+{
+  g_return_if_fail (GIMP_IS_ACCEL_LABEL (accel_label));
+  g_return_if_fail (action == NULL || GIMP_IS_ACTION (action));
+
+  if (action != accel_label->priv->action)
+    {
+      if (accel_label->priv->action)
+        {
+          GClosure *accel_closure;
+
+          accel_closure = gimp_action_get_accel_closure (
+            accel_label->priv->action);
+
+          if (accel_closure)
+            {
+              GtkAccelGroup *accel_group;
+
+              accel_group = gtk_accel_group_from_accel_closure (accel_closure);
+
+              g_signal_handlers_disconnect_by_func (
+                accel_group,
+                gimp_accel_label_accel_changed,
+                accel_label);
+            }
+        }
+
+      g_set_object (&accel_label->priv->action, action);
+
+      if (accel_label->priv->action)
+        {
+          GClosure *accel_closure;
+
+          accel_closure = gimp_action_get_accel_closure (
+            accel_label->priv->action);
+
+          if (accel_closure)
+            {
+              GtkAccelGroup *accel_group;
+
+              accel_group = gtk_accel_group_from_accel_closure (accel_closure);
+
+              g_signal_connect (accel_group, "accel-changed",
+                                G_CALLBACK (gimp_accel_label_accel_changed),
+                                accel_label);
+            }
+        }
+
+      gimp_accel_label_update (accel_label);
+    }
+}
+
+GimpAction *
+gimp_accel_label_get_action (GimpAccelLabel *accel_label)
+{
+  g_return_val_if_fail (GIMP_IS_ACCEL_LABEL (accel_label), NULL);
+
+  return accel_label->priv->action;
+}
diff --git a/app/widgets/gimpaccellabel.h b/app/widgets/gimpaccellabel.h
new file mode 100644
index 0000000000..543812128d
--- /dev/null
+++ b/app/widgets/gimpaccellabel.h
@@ -0,0 +1,58 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpaccellabel.h
+ * Copyright (C) 2020 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_ACCEL_LABEL_H__
+#define __GIMP_ACCEL_LABEL_H__
+
+
+#define GIMP_TYPE_ACCEL_LABEL            (gimp_accel_label_get_type ())
+#define GIMP_ACCEL_LABEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ACCEL_LABEL, 
GimpAccelLabel))
+#define GIMP_ACCEL_LABEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ACCEL_LABEL, 
GimpAccelLabelClass))
+#define GIMP_IS_ACCEL_LABEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_ACCEL_LABEL))
+#define GIMP_IS_ACCEL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_ACCEL_LABEL))
+#define GIMP_ACCEL_LABEL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_ACCEL_LABEL, 
GimpAccelLabelClass))
+
+
+typedef struct _GimpAccelLabelPrivate GimpAccelLabelPrivate;
+typedef struct _GimpAccelLabelClass   GimpAccelLabelClass;
+
+struct _GimpAccelLabel
+{
+  GtkLabel               parent_instance;
+
+  GimpAccelLabelPrivate *priv;
+};
+
+struct _GimpAccelLabelClass
+{
+  GtkLabelClass  parent_class;
+};
+
+
+GType        gimp_accel_label_get_type   (void) G_GNUC_CONST;
+
+GtkWidget  * gimp_accel_label_new        (GimpAction     *action);
+
+void         gimp_accel_label_set_action (GimpAccelLabel *accel_label,
+                                          GimpAction     *action);
+GimpAction * gimp_accel_label_get_action (GimpAccelLabel *accel_label);
+
+
+#endif /* __GIMP_ACCEL_LABEL_H__ */
diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h
index 63872a37e5..2687bc529d 100644
--- a/app/widgets/widgets-types.h
+++ b/app/widgets/widgets-types.h
@@ -166,6 +166,7 @@ typedef struct _GimpPdbDialog                GimpPdbDialog;
 
 /*  misc widgets  */
 
+typedef struct _GimpAccelLabel               GimpAccelLabel;
 typedef struct _GimpActionEditor             GimpActionEditor;
 typedef struct _GimpActionView               GimpActionView;
 typedef struct _GimpBlobEditor               GimpBlobEditor;


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