diff options
Diffstat (limited to 'app/core/gimptoolgroup.c')
-rw-r--r-- | app/core/gimptoolgroup.c | 413 |
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)); +} |