summaryrefslogtreecommitdiffstats
path: root/app/core/gimptoolgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/core/gimptoolgroup.c')
-rw-r--r--app/core/gimptoolgroup.c413
1 files changed, 413 insertions, 0 deletions
diff --git a/app/core/gimptoolgroup.c b/app/core/gimptoolgroup.c
new file mode 100644
index 0000000..aa8e3bc
--- /dev/null
+++ b/app/core/gimptoolgroup.c
@@ -0,0 +1,413 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimptoolgroup.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 <string.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "core-types.h"
+
+#include "gimplist.h"
+#include "gimpmarshal.h"
+#include "gimptoolgroup.h"
+#include "gimptoolinfo.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ ACTIVE_TOOL_CHANGED,
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_0,
+ PROP_ACTIVE_TOOL,
+ PROP_CHILDREN
+};
+
+
+struct _GimpToolGroupPrivate
+{
+ gchar *active_tool;
+ GimpContainer *children;
+};
+
+
+/* local function prototypes */
+
+
+static void gimp_tool_group_finalize (GObject *object);
+static void gimp_tool_group_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_tool_group_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static gint64 gimp_tool_group_get_memsize (GimpObject *object,
+ gint64 *gui_size);
+
+static gchar * gimp_tool_group_get_description (GimpViewable *viewable,
+ gchar **tooltip);
+static GimpContainer * gimp_tool_group_get_children (GimpViewable *viewable);
+static void gimp_tool_group_set_expanded (GimpViewable *viewable,
+ gboolean expand);
+static gboolean gimp_tool_group_get_expanded (GimpViewable *viewable);
+
+static void gimp_tool_group_child_add (GimpContainer *container,
+ GimpToolInfo *tool_info,
+ GimpToolGroup *tool_group);
+static void gimp_tool_group_child_remove (GimpContainer *container,
+ GimpToolInfo *tool_info,
+ GimpToolGroup *tool_group);
+
+static void gimp_tool_group_shown_changed (GimpToolItem *tool_item);
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (GimpToolGroup, gimp_tool_group, GIMP_TYPE_TOOL_ITEM)
+
+#define parent_class gimp_tool_group_parent_class
+
+static guint gimp_tool_group_signals[LAST_SIGNAL] = { 0 };
+
+
+/* private functions */
+
+static void
+gimp_tool_group_class_init (GimpToolGroupClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
+ GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
+ GimpToolItemClass *tool_item_class = GIMP_TOOL_ITEM_CLASS (klass);
+
+ gimp_tool_group_signals[ACTIVE_TOOL_CHANGED] =
+ g_signal_new ("active-tool-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpToolGroupClass, active_tool_changed),
+ NULL, NULL,
+ gimp_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ object_class->finalize = gimp_tool_group_finalize;
+ object_class->get_property = gimp_tool_group_get_property;
+ object_class->set_property = gimp_tool_group_set_property;
+
+ gimp_object_class->get_memsize = gimp_tool_group_get_memsize;
+
+ viewable_class->default_icon_name = "folder";
+ viewable_class->get_description = gimp_tool_group_get_description;
+ viewable_class->get_children = gimp_tool_group_get_children;
+ viewable_class->get_expanded = gimp_tool_group_get_expanded;
+ viewable_class->set_expanded = gimp_tool_group_set_expanded;
+
+ tool_item_class->shown_changed = gimp_tool_group_shown_changed;
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_ACTIVE_TOOL,
+ "active-tool", NULL, NULL,
+ NULL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_CHILDREN,
+ "children", NULL, NULL,
+ GIMP_TYPE_CONTAINER,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+}
+
+static void
+gimp_tool_group_init (GimpToolGroup *tool_group)
+{
+ tool_group->priv = gimp_tool_group_get_instance_private (tool_group);
+
+ tool_group->priv->children = g_object_new (
+ GIMP_TYPE_LIST,
+ "children-type", GIMP_TYPE_TOOL_INFO,
+ "append", TRUE,
+ NULL);
+
+ g_signal_connect (tool_group->priv->children, "add",
+ G_CALLBACK (gimp_tool_group_child_add),
+ tool_group);
+ g_signal_connect (tool_group->priv->children, "remove",
+ G_CALLBACK (gimp_tool_group_child_remove),
+ tool_group);
+}
+
+static void
+gimp_tool_group_finalize (GObject *object)
+{
+ GimpToolGroup *tool_group = GIMP_TOOL_GROUP (object);
+
+ g_clear_pointer (&tool_group->priv->active_tool, g_free);
+
+ g_clear_object (&tool_group->priv->children);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_tool_group_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpToolGroup *tool_group = GIMP_TOOL_GROUP (object);
+
+ switch (property_id)
+ {
+ case PROP_ACTIVE_TOOL:
+ g_value_set_string (value, tool_group->priv->active_tool);
+ break;
+
+ case PROP_CHILDREN:
+ g_value_set_object (value, tool_group->priv->children);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_tool_group_set_property_add_tool (GimpToolInfo *tool_info,
+ GimpToolGroup *tool_group)
+{
+ gimp_container_add (tool_group->priv->children, GIMP_OBJECT (tool_info));
+}
+
+static void
+gimp_tool_group_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpToolGroup *tool_group = GIMP_TOOL_GROUP (object);
+
+ switch (property_id)
+ {
+ case PROP_ACTIVE_TOOL:
+ g_free (tool_group->priv->active_tool);
+
+ tool_group->priv->active_tool = g_value_dup_string (value);
+ break;
+
+ case PROP_CHILDREN:
+ {
+ GimpContainer *container = g_value_get_object (value);
+
+ gimp_container_clear (tool_group->priv->children);
+
+ if (! container)
+ break;
+
+ gimp_container_foreach (container,
+ (GFunc) gimp_tool_group_set_property_add_tool,
+ tool_group);
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static gint64
+gimp_tool_group_get_memsize (GimpObject *object,
+ gint64 *gui_size)
+{
+ GimpToolGroup *tool_group = GIMP_TOOL_GROUP (object);
+ gint64 memsize = 0;
+
+ memsize += gimp_object_get_memsize (GIMP_OBJECT (tool_group->priv->children),
+ gui_size);
+
+ return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
+ gui_size);
+}
+
+static gchar *
+gimp_tool_group_get_description (GimpViewable *viewable,
+ gchar **tooltip)
+{
+ /* Translators: this is a noun */
+ return g_strdup (C_("tool-item", "Group"));
+}
+
+static GimpContainer *
+gimp_tool_group_get_children (GimpViewable *viewable)
+{
+ GimpToolGroup *tool_group = GIMP_TOOL_GROUP (viewable);
+
+ return tool_group->priv->children;
+}
+
+static void
+gimp_tool_group_set_expanded (GimpViewable *viewable,
+ gboolean expand)
+{
+ if (! expand)
+ gimp_viewable_expanded_changed (viewable);
+}
+
+static gboolean
+gimp_tool_group_get_expanded (GimpViewable *viewable)
+{
+ return TRUE;
+}
+
+static void
+gimp_tool_group_child_add (GimpContainer *container,
+ GimpToolInfo *tool_info,
+ GimpToolGroup *tool_group)
+{
+ g_return_if_fail (
+ gimp_viewable_get_parent (GIMP_VIEWABLE (tool_info)) == NULL);
+
+ gimp_viewable_set_parent (GIMP_VIEWABLE (tool_info),
+ GIMP_VIEWABLE (tool_group));
+
+ if (! tool_group->priv->active_tool)
+ gimp_tool_group_set_active_tool_info (tool_group, tool_info);
+}
+
+static void
+gimp_tool_group_child_remove (GimpContainer *container,
+ GimpToolInfo *tool_info,
+ GimpToolGroup *tool_group)
+{
+ gimp_viewable_set_parent (GIMP_VIEWABLE (tool_info), NULL);
+
+ if (! g_strcmp0 (tool_group->priv->active_tool,
+ gimp_object_get_name (GIMP_OBJECT (tool_info))))
+ {
+ GimpToolInfo *active_tool_info = NULL;
+
+ if (! gimp_container_is_empty (tool_group->priv->children))
+ {
+ active_tool_info = GIMP_TOOL_INFO (
+ gimp_container_get_first_child (tool_group->priv->children));
+ }
+
+ gimp_tool_group_set_active_tool_info (tool_group, active_tool_info);
+ }
+}
+
+static void
+gimp_tool_group_shown_changed (GimpToolItem *tool_item)
+{
+ GimpToolGroup *tool_group = GIMP_TOOL_GROUP (tool_item);
+ GList *iter;
+
+ if (GIMP_TOOL_ITEM_CLASS (parent_class)->shown_changed)
+ GIMP_TOOL_ITEM_CLASS (parent_class)->shown_changed (tool_item);
+
+ for (iter = GIMP_LIST (tool_group->priv->children)->queue->head;
+ iter;
+ iter = g_list_next (iter))
+ {
+ GimpToolItem *tool_item = iter->data;
+
+ if (gimp_tool_item_get_visible (tool_item))
+ gimp_tool_item_shown_changed (tool_item);
+ }
+}
+
+
+/* public functions */
+
+GimpToolGroup *
+gimp_tool_group_new (void)
+{
+ GimpToolGroup *tool_group;
+
+ tool_group = g_object_new (GIMP_TYPE_TOOL_GROUP, NULL);
+
+ gimp_object_set_static_name (GIMP_OBJECT (tool_group), "tool group");
+
+ return tool_group;
+}
+
+void
+gimp_tool_group_set_active_tool (GimpToolGroup *tool_group,
+ const gchar *tool_name)
+{
+ g_return_if_fail (GIMP_IS_TOOL_GROUP (tool_group));
+
+ if (g_strcmp0 (tool_group->priv->active_tool, tool_name))
+ {
+ g_return_if_fail (tool_name == NULL ||
+ gimp_container_get_child_by_name (
+ tool_group->priv->children, tool_name) != NULL);
+
+ g_free (tool_group->priv->active_tool);
+
+ tool_group->priv->active_tool = g_strdup (tool_name);;
+
+ g_signal_emit (tool_group,
+ gimp_tool_group_signals[ACTIVE_TOOL_CHANGED], 0);
+
+ g_object_notify (G_OBJECT (tool_group), "active-tool");
+ }
+}
+
+const gchar *
+gimp_tool_group_get_active_tool (GimpToolGroup *tool_group)
+{
+ g_return_val_if_fail (GIMP_IS_TOOL_GROUP (tool_group), NULL);
+
+ return tool_group->priv->active_tool;
+}
+
+void
+gimp_tool_group_set_active_tool_info (GimpToolGroup *tool_group,
+ GimpToolInfo *tool_info)
+{
+ g_return_if_fail (GIMP_IS_TOOL_GROUP (tool_group));
+ g_return_if_fail (tool_info == NULL || GIMP_IS_TOOL_INFO (tool_info));
+
+ gimp_tool_group_set_active_tool (
+ tool_group,
+ tool_info ? gimp_object_get_name (GIMP_OBJECT (tool_info)) : NULL);
+}
+
+GimpToolInfo *
+gimp_tool_group_get_active_tool_info (GimpToolGroup *tool_group)
+{
+ g_return_val_if_fail (GIMP_IS_TOOL_GROUP (tool_group), NULL);
+
+ return GIMP_TOOL_INFO (
+ gimp_container_get_child_by_name (tool_group->priv->children,
+ tool_group->priv->active_tool));
+}