Gimp/app/widgets/gimptooleditor.c
Michael Natterer b416994ed0 app: make GimpContainerView behave like a normal widget
The old API to select stuff and its signals was doing unexpected
stuff and was very confusing. Change things to be "normal":

The selection API is now set_selected() and get_selected(), with no
internal data exposed, and set_selected() emitting the expected
signal.

The signals are now "selection-changed" and "item-activated".
"selection-changed" is always emitted in response to changing the
selection, be it via the API, or by changes in the model (the internal
callbacks in from e.g. GimpContext or GimpImage simply call set_selected()
and don't do any unxpected magic).
2025-08-01 10:02:37 +02:00

851 lines
30 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimptooleditor.c
* Copyright (C) 2001-2009 Michael Natterer <mitch@gimp.org>
* Stephen Griffiths <scgmk5@gmail.com>
*
* 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 "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
#include "core/gimp.h"
#include "core/gimpcontainer.h"
#include "core/gimpcontext.h"
#include "core/gimptoolgroup.h"
#include "core/gimptreehandler.h"
#include "tools/gimp-tools.h"
#include "gimpcontainertreestore.h"
#include "gimpcontainerview.h"
#include "gimpdnd.h"
#include "gimpviewrenderer.h"
#include "gimptooleditor.h"
#include "gimphelp-ids.h"
#include "gimpwidgets-utils.h"
#include "gimp-intl.h"
struct _GimpToolEditorPrivate
{
GimpContainer *container;
GimpContext *context;
GtkWidget *scrolled;
GtkWidget *new_group_button;
GtkWidget *raise_button;
GtkWidget *lower_button;
GtkWidget *delete_button;
GtkWidget *reset_button;
GimpTreeHandler *tool_item_notify_handler;
/* State of tools at creation of the editor, stored to support
* reverting changes
*/
gchar *initial_tool_state;
};
/* local function prototypes */
static void gimp_tool_editor_view_iface_init (GimpContainerViewInterface *iface);
static void gimp_tool_editor_constructed (GObject *object);
static void gimp_tool_editor_set_container (GimpContainerView *container_view,
GimpContainer *container);
static void gimp_tool_editor_set_context (GimpContainerView *container_view,
GimpContext *context);
static gboolean gimp_tool_editor_set_selected (GimpContainerView *view,
GList *items);
static gboolean gimp_tool_editor_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreePath *drop_path,
GtkTreeViewDropPosition drop_pos,
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action);
static void gimp_tool_editor_drop_viewables (GimpContainerTreeView *tree_view,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
static void gimp_tool_editor_tool_item_notify (GimpToolItem *tool_item,
GParamSpec *pspec,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_eye_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data);
static void gimp_tool_editor_eye_clicked (GtkCellRendererToggle *toggle,
gchar *path_str,
GdkModifierType state,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_new_group_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_raise_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_raise_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_lower_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_lower_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_delete_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_reset_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static GimpToolItem * gimp_tool_editor_get_selected_tool_item (GimpToolEditor *tool_editor);
static GimpContainer * gimp_tool_editor_get_tool_item_container (GimpToolEditor *tool_editor,
GimpToolItem *tool_item);
static void gimp_tool_editor_update_container (GimpToolEditor *tool_editor);
static void gimp_tool_editor_update_sensitivity (GimpToolEditor *tool_editor);
G_DEFINE_TYPE_WITH_CODE (GimpToolEditor, gimp_tool_editor,
GIMP_TYPE_CONTAINER_TREE_VIEW,
G_ADD_PRIVATE (GimpToolEditor)
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONTAINER_VIEW,
gimp_tool_editor_view_iface_init))
#define parent_class gimp_tool_editor_parent_class
static GimpContainerViewInterface *parent_view_iface = NULL;
/* private functions */
static void
gimp_tool_editor_class_init (GimpToolEditorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpContainerTreeViewClass *tree_view_class = GIMP_CONTAINER_TREE_VIEW_CLASS (klass);
object_class->constructed = gimp_tool_editor_constructed;
tree_view_class->drop_possible = gimp_tool_editor_drop_possible;
tree_view_class->drop_viewables = gimp_tool_editor_drop_viewables;
}
static void
gimp_tool_editor_view_iface_init (GimpContainerViewInterface *iface)
{
parent_view_iface = g_type_interface_peek_parent (iface);
if (! parent_view_iface)
parent_view_iface = g_type_default_interface_peek (GIMP_TYPE_CONTAINER_VIEW);
iface->set_container = gimp_tool_editor_set_container;
iface->set_context = gimp_tool_editor_set_context;
iface->set_selected = gimp_tool_editor_set_selected;
}
static void
gimp_tool_editor_init (GimpToolEditor *tool_editor)
{
tool_editor->priv = gimp_tool_editor_get_instance_private (tool_editor);
}
static void
gimp_tool_editor_constructed (GObject *object)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (object);
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (object);
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (object);
gint view_size;
gint border_width;
G_OBJECT_CLASS (parent_class)->constructed (object);
view_size = gimp_container_view_get_view_size (container_view,
&border_width);
gimp_editor_set_show_name (GIMP_EDITOR (tool_editor), FALSE);
gtk_tree_view_set_level_indentation (tree_view->view,
0.8 * (view_size + 2 * border_width));
gimp_dnd_viewable_dest_add (GTK_WIDGET (tree_view->view),
GIMP_TYPE_TOOL_ITEM,
NULL, NULL);
/* construct tree view */
{
GtkTreeViewColumn *column;
GtkCellRenderer *eye_cell;
GtkStyleContext *tree_style;
GtkBorder border;
gint icon_size;
tree_style = gtk_widget_get_style_context (GTK_WIDGET (tool_editor));
gtk_style_context_get_border (tree_style, 0, &border);
column = gtk_tree_view_column_new ();
gtk_tree_view_insert_column (tree_view->view, column, 0);
eye_cell = gimp_cell_renderer_toggle_new (GIMP_ICON_VISIBLE);
g_object_get (eye_cell, "icon-size", &icon_size, NULL);
icon_size = MIN (icon_size, MAX (view_size - (border.left + border.right),
view_size - (border.top + border.bottom)));
g_object_set (eye_cell, "icon-size", icon_size, NULL);
gtk_tree_view_column_pack_start (column, eye_cell, FALSE);
gtk_tree_view_column_set_cell_data_func (column, eye_cell,
gimp_tool_editor_eye_data_func,
tree_view, NULL);
gimp_container_tree_view_add_toggle_cell (tree_view, eye_cell);
g_signal_connect (eye_cell, "clicked",
G_CALLBACK (gimp_tool_editor_eye_clicked),
tool_editor);
}
/* buttons */
tool_editor->priv->new_group_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_FOLDER_NEW,
_("Create a new tool group"), NULL,
G_CALLBACK (gimp_tool_editor_new_group_clicked),
NULL,
G_OBJECT (tool_editor));
tool_editor->priv->raise_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_GO_UP,
_("Raise this item"),
_("Raise this item to the top"),
G_CALLBACK (gimp_tool_editor_raise_clicked),
G_CALLBACK (gimp_tool_editor_raise_extend_clicked),
G_OBJECT (tool_editor));
tool_editor->priv->lower_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_GO_DOWN,
_("Lower this item"),
_("Lower this item to the bottom"),
G_CALLBACK (gimp_tool_editor_lower_clicked),
G_CALLBACK (gimp_tool_editor_lower_extend_clicked),
G_OBJECT (tool_editor));
tool_editor->priv->delete_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_EDIT_DELETE,
_("Delete this tool group"), NULL,
G_CALLBACK (gimp_tool_editor_delete_clicked),
NULL,
G_OBJECT (tool_editor));
tool_editor->priv->reset_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_RESET,
_("Reset tool order and visibility"), NULL,
G_CALLBACK (gimp_tool_editor_reset_clicked),
NULL,
G_OBJECT (tool_editor));
gimp_tool_editor_update_sensitivity (tool_editor);
}
static void
gimp_tool_editor_set_container (GimpContainerView *container_view,
GimpContainer *container)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view);
parent_view_iface->set_container (container_view, container);
gimp_tool_editor_update_container (tool_editor);
}
static void
gimp_tool_editor_set_context (GimpContainerView *container_view,
GimpContext *context)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view);
parent_view_iface->set_context (container_view, context);
gimp_tool_editor_update_container (tool_editor);
}
static gboolean
gimp_tool_editor_set_selected (GimpContainerView *container_view,
GList *items)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view);
gboolean result;
result = parent_view_iface->set_selected (container_view, items);
gimp_tool_editor_update_sensitivity (tool_editor);
return result;
}
static gboolean
gimp_tool_editor_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreePath *drop_path,
GtkTreeViewDropPosition drop_pos,
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action)
{
if (GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (
tree_view,
src_type, src_viewables, dest_viewable, drop_path, drop_pos,
return_drop_pos, return_drag_action))
{
if (gimp_viewable_get_parent (dest_viewable) ||
(gimp_viewable_get_children (dest_viewable) &&
(drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER ||
drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)))
{
GList *iter;
for (iter = src_viewables; iter; iter = iter->next)
{
GimpViewable *src_viewable = iter->data;
if (gimp_viewable_get_children (src_viewable))
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
static void
gimp_tool_editor_drop_viewables (GimpContainerTreeView *tree_view,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tree_view);
GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_viewables (tree_view,
src_viewables,
dest_viewable,
drop_pos);
if (src_viewables)
gimp_container_view_set_selected (container_view, src_viewables);
}
static void
gimp_tool_editor_new_group_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GimpContainer *container;
GimpToolItem *tool_item;
GimpToolGroup *group;
gint index = 0;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
if (gimp_viewable_get_parent (GIMP_VIEWABLE (tool_item)) != NULL)
return;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
}
else
{
container = tool_editor->priv->container;
}
if (container)
{
group = gimp_tool_group_new ();
gimp_container_insert (container, GIMP_OBJECT (group), index);
g_object_unref (group);
gimp_container_view_set_1_selected (container_view,
GIMP_VIEWABLE (group));
}
}
static void
gimp_tool_editor_raise_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
if (index > 0)
{
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), index - 1);
}
}
}
static void
gimp_tool_editor_raise_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item && (mask & GDK_SHIFT_MASK))
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
if (index > 0)
{
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), 0);
}
}
}
static void
gimp_tool_editor_lower_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
if (index + 1 < gimp_container_get_n_children (container))
{
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), index + 1);
}
}
}
static void
gimp_tool_editor_lower_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item && (mask & GDK_SHIFT_MASK))
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_n_children (container) - 1;
index = MAX (index, 0);
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), index);
}
}
static void
gimp_tool_editor_delete_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *src_container;
GimpContainer *dest_container;
gint index;
gint dest_index;
src_container = gimp_viewable_get_children (GIMP_VIEWABLE (tool_item));
dest_container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
if (! src_container)
return;
index = gimp_container_get_child_index (dest_container,
GIMP_OBJECT (tool_item));
dest_index = index;
g_object_ref (tool_item);
gimp_container_freeze (src_container);
gimp_container_freeze (dest_container);
gimp_container_remove (dest_container, GIMP_OBJECT (tool_item));
while (! gimp_container_is_empty (src_container))
{
GimpObject *object = gimp_container_get_first_child (src_container);
g_object_ref (object);
gimp_container_remove (src_container, object);
gimp_container_insert (dest_container, object, dest_index++);
g_object_unref (object);
}
gimp_container_thaw (dest_container);
gimp_container_thaw (src_container);
gimp_container_view_set_1_selected
(container_view,
GIMP_VIEWABLE (gimp_container_get_child_by_index (dest_container,
index)));
g_object_unref (tool_item);
}
}
static void
gimp_tool_editor_reset_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
gimp_tools_reset (tool_editor->priv->context->gimp,
tool_editor->priv->container,
FALSE);
}
static void
gimp_tool_editor_tool_item_notify (GimpToolItem *tool_item,
GParamSpec *pspec,
GimpToolEditor *tool_editor)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (tool_editor);
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GtkTreeIter *iter;
iter = _gimp_container_view_lookup (container_view,
GIMP_VIEWABLE (tool_item));
if (iter)
{
GtkTreePath *path;
path = gtk_tree_model_get_path (tree_view->model, iter);
gtk_tree_model_row_changed (tree_view->model, path, iter);
gtk_tree_path_free (path);
}
}
static void
gimp_tool_editor_eye_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data)
{
GimpViewRenderer *renderer;
GimpToolItem *tool_item;
gtk_tree_model_get (tree_model, iter,
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
-1);
tool_item = GIMP_TOOL_ITEM (renderer->viewable);
g_object_set (cell,
"active", gimp_tool_item_get_visible (tool_item),
"inconsistent", gimp_tool_item_get_visible (tool_item) &&
! gimp_tool_item_get_shown (tool_item),
NULL);
g_object_unref (renderer);
}
static void
gimp_tool_editor_eye_clicked (GtkCellRendererToggle *toggle,
gchar *path_str,
GdkModifierType state,
GimpToolEditor *tool_editor)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (tool_editor);
GtkTreePath *path;
GtkTreeIter iter;
path = gtk_tree_path_new_from_string (path_str);
if (gtk_tree_model_get_iter (tree_view->model, &iter, path))
{
GimpViewRenderer *renderer;
GimpToolItem *tool_item;
gboolean active;
gtk_tree_model_get (tree_view->model, &iter,
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
-1);
tool_item = GIMP_TOOL_ITEM (renderer->viewable);
g_object_get (toggle,
"active", &active,
NULL);
gimp_tool_item_set_visible (tool_item, ! active);
g_object_unref (renderer);
}
gtk_tree_path_free (path);
}
static GimpToolItem *
gimp_tool_editor_get_selected_tool_item (GimpToolEditor *tool_editor)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (tool_editor);
if (tool_editor->priv->container)
{
GimpViewRenderer *renderer;
GimpToolItem *tool_item;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
selection = gtk_tree_view_get_selection (tree_view->view);
if (! gtk_tree_selection_get_selected (selection, &model, &iter))
return NULL;
gtk_tree_model_get (model, &iter,
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
-1);
tool_item = GIMP_TOOL_ITEM (renderer->viewable);
g_object_unref (renderer);
return tool_item;
}
return NULL;
}
static GimpContainer *
gimp_tool_editor_get_tool_item_container (GimpToolEditor *tool_editor,
GimpToolItem *tool_item)
{
GimpViewable *parent;
parent = gimp_viewable_get_parent (GIMP_VIEWABLE (tool_item));
if (parent)
{
return gimp_viewable_get_children (parent);
}
else
{
return tool_editor->priv->container;
}
}
static void
gimp_tool_editor_update_container (GimpToolEditor *tool_editor)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GimpContainer *container;
GimpContext *context;
g_clear_pointer (&tool_editor->priv->tool_item_notify_handler,
gimp_tree_handler_disconnect);
g_clear_pointer (&tool_editor->priv->initial_tool_state, g_free);
container = gimp_container_view_get_container (container_view);
context = gimp_container_view_get_context (container_view);
if (container && context)
{
GString *string;
GimpConfigWriter *writer;
tool_editor->priv->container = container;
tool_editor->priv->context = context;
tool_editor->priv->tool_item_notify_handler = gimp_tree_handler_connect (
container, "notify",
G_CALLBACK (gimp_tool_editor_tool_item_notify),
tool_editor);
/* save initial tool order */
string = g_string_new (NULL);
writer = gimp_config_writer_new_from_string (string);
gimp_tools_serialize (context->gimp, container, writer);
gimp_config_writer_finish (writer, NULL, NULL);
tool_editor->priv->initial_tool_state = g_string_free (string, FALSE);
}
}
static void
gimp_tool_editor_update_sensitivity (GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
gtk_widget_set_sensitive (
tool_editor->priv->new_group_button,
gimp_viewable_get_parent (GIMP_VIEWABLE (tool_item)) == NULL);
gtk_widget_set_sensitive (
tool_editor->priv->raise_button,
index > 0);
gtk_widget_set_sensitive (
tool_editor->priv->lower_button,
index < gimp_container_get_n_children (container) - 1);
gtk_widget_set_sensitive (
tool_editor->priv->delete_button,
gimp_viewable_get_children (GIMP_VIEWABLE (tool_item)) != NULL);
}
else
{
gtk_widget_set_sensitive (tool_editor->priv->new_group_button, TRUE);
gtk_widget_set_sensitive (tool_editor->priv->raise_button, FALSE);
gtk_widget_set_sensitive (tool_editor->priv->lower_button, FALSE);
gtk_widget_set_sensitive (tool_editor->priv->delete_button, FALSE);
}
}
/* public functions */
GtkWidget *
gimp_tool_editor_new (GimpContainer *container,
GimpContext *context,
gint view_size,
gint view_border_width)
{
GimpContainerView *container_view;
g_return_val_if_fail (GIMP_IS_CONTAINER (container), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
container_view = g_object_new (GIMP_TYPE_TOOL_EDITOR,
"view-size", view_size,
"view-border-width", view_border_width,
NULL);
gimp_container_view_set_context (container_view, context);
gimp_container_view_set_container (container_view, container);
gimp_container_view_set_reorderable (container_view, TRUE);
return GTK_WIDGET (container_view);
}
/**
* gimp_tool_editor_revert_changes:
* @tool_editor:
*
* Reverts the tool order and visibility to the state at creation.
**/
void
gimp_tool_editor_revert_changes (GimpToolEditor *tool_editor)
{
GScanner *scanner;
g_return_if_fail (GIMP_IS_TOOL_EDITOR (tool_editor));
scanner = gimp_scanner_new_string (tool_editor->priv->initial_tool_state, -1,
NULL);
gimp_tools_deserialize (tool_editor->priv->context->gimp,
tool_editor->priv->container,
scanner);
gimp_scanner_unref (scanner);
}