mirror of https://github.com/GNOME/gimp.git
854 lines
30 KiB
C
854 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 gboolean gimp_tool_editor_select_item (GimpContainerView *view,
|
|
GimpViewable *viewable,
|
|
gpointer insert_data);
|
|
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_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->select_item = gimp_tool_editor_select_item;
|
|
iface->set_container = gimp_tool_editor_set_container;
|
|
iface->set_context = gimp_tool_editor_set_context;
|
|
}
|
|
|
|
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,
|
|
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),
|
|
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),
|
|
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,
|
|
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,
|
|
tool_editor);
|
|
|
|
gimp_tool_editor_update_sensitivity (tool_editor);
|
|
}
|
|
|
|
static gboolean
|
|
gimp_tool_editor_select_item (GimpContainerView *container_view,
|
|
GimpViewable *viewable,
|
|
gpointer insert_data)
|
|
{
|
|
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view);
|
|
gboolean result;
|
|
|
|
result = parent_view_iface->select_item (container_view,
|
|
viewable, insert_data);
|
|
|
|
gimp_tool_editor_update_sensitivity (tool_editor);
|
|
|
|
return result;
|
|
}
|
|
|
|
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_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_select_item (container_view, src_viewables->data);
|
|
}
|
|
|
|
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_select_item (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_select_item (
|
|
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);
|
|
}
|