858 lines
30 KiB
C
858 lines
30 KiB
C
/* PIKA - Photo and Image Kooker Application
|
|
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
|
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
|
*
|
|
* Original copyright, applying to most contents (license remains unchanged):
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* pikatooleditor.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 "libpikaconfig/pikaconfig.h"
|
|
#include "libpikawidgets/pikawidgets.h"
|
|
|
|
#include "widgets-types.h"
|
|
|
|
#include "core/pika.h"
|
|
#include "core/pikacontainer.h"
|
|
#include "core/pikacontext.h"
|
|
#include "core/pikatoolgroup.h"
|
|
#include "core/pikatreehandler.h"
|
|
|
|
#include "tools/pika-tools.h"
|
|
|
|
#include "pikacontainertreestore.h"
|
|
#include "pikacontainerview.h"
|
|
#include "pikadnd.h"
|
|
#include "pikaviewrenderer.h"
|
|
#include "pikatooleditor.h"
|
|
#include "pikahelp-ids.h"
|
|
#include "pikawidgets-utils.h"
|
|
|
|
#include "pika-intl.h"
|
|
|
|
|
|
struct _PikaToolEditorPrivate
|
|
{
|
|
PikaContainer *container;
|
|
PikaContext *context;
|
|
|
|
GtkWidget *scrolled;
|
|
|
|
GtkWidget *new_group_button;
|
|
GtkWidget *raise_button;
|
|
GtkWidget *lower_button;
|
|
GtkWidget *delete_button;
|
|
GtkWidget *reset_button;
|
|
|
|
PikaTreeHandler *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 pika_tool_editor_view_iface_init (PikaContainerViewInterface *iface);
|
|
|
|
static void pika_tool_editor_constructed (GObject *object);
|
|
|
|
static gboolean pika_tool_editor_select_items (PikaContainerView *view,
|
|
GList *items,
|
|
GList *paths);
|
|
static void pika_tool_editor_set_container (PikaContainerView *container_view,
|
|
PikaContainer *container);
|
|
static void pika_tool_editor_set_context (PikaContainerView *container_view,
|
|
PikaContext *context);
|
|
|
|
static gboolean pika_tool_editor_drop_possible (PikaContainerTreeView *tree_view,
|
|
PikaDndType src_type,
|
|
GList *src_viewables,
|
|
PikaViewable *dest_viewable,
|
|
GtkTreePath *drop_path,
|
|
GtkTreeViewDropPosition drop_pos,
|
|
GtkTreeViewDropPosition *return_drop_pos,
|
|
GdkDragAction *return_drag_action);
|
|
static void pika_tool_editor_drop_viewables (PikaContainerTreeView *tree_view,
|
|
GList *src_viewables,
|
|
PikaViewable *dest_viewable,
|
|
GtkTreeViewDropPosition drop_pos);
|
|
|
|
static void pika_tool_editor_tool_item_notify (PikaToolItem *tool_item,
|
|
GParamSpec *pspec,
|
|
PikaToolEditor *tool_editor);
|
|
|
|
static void pika_tool_editor_eye_data_func (GtkTreeViewColumn *tree_column,
|
|
GtkCellRenderer *cell,
|
|
GtkTreeModel *tree_model,
|
|
GtkTreeIter *iter,
|
|
gpointer data);
|
|
static void pika_tool_editor_eye_clicked (GtkCellRendererToggle *toggle,
|
|
gchar *path_str,
|
|
GdkModifierType state,
|
|
PikaToolEditor *tool_editor);
|
|
|
|
static void pika_tool_editor_new_group_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor);
|
|
static void pika_tool_editor_raise_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor);
|
|
static void pika_tool_editor_raise_extend_clicked (GtkButton *button,
|
|
GdkModifierType mask,
|
|
PikaToolEditor *tool_editor);
|
|
static void pika_tool_editor_lower_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor);
|
|
static void pika_tool_editor_lower_extend_clicked (GtkButton *button,
|
|
GdkModifierType mask,
|
|
PikaToolEditor *tool_editor);
|
|
static void pika_tool_editor_delete_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor);
|
|
static void pika_tool_editor_reset_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor);
|
|
|
|
static PikaToolItem * pika_tool_editor_get_selected_tool_item (PikaToolEditor *tool_editor);
|
|
static PikaContainer * pika_tool_editor_get_tool_item_container (PikaToolEditor *tool_editor,
|
|
PikaToolItem *tool_item);
|
|
|
|
static void pika_tool_editor_update_container (PikaToolEditor *tool_editor);
|
|
static void pika_tool_editor_update_sensitivity (PikaToolEditor *tool_editor);
|
|
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (PikaToolEditor, pika_tool_editor,
|
|
PIKA_TYPE_CONTAINER_TREE_VIEW,
|
|
G_ADD_PRIVATE (PikaToolEditor)
|
|
G_IMPLEMENT_INTERFACE (PIKA_TYPE_CONTAINER_VIEW,
|
|
pika_tool_editor_view_iface_init))
|
|
|
|
#define parent_class pika_tool_editor_parent_class
|
|
|
|
static PikaContainerViewInterface *parent_view_iface = NULL;
|
|
|
|
|
|
/* private functions */
|
|
|
|
static void
|
|
pika_tool_editor_class_init (PikaToolEditorClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
PikaContainerTreeViewClass *tree_view_class = PIKA_CONTAINER_TREE_VIEW_CLASS (klass);
|
|
|
|
object_class->constructed = pika_tool_editor_constructed;
|
|
|
|
tree_view_class->drop_possible = pika_tool_editor_drop_possible;
|
|
tree_view_class->drop_viewables = pika_tool_editor_drop_viewables;
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_view_iface_init (PikaContainerViewInterface *iface)
|
|
{
|
|
parent_view_iface = g_type_interface_peek_parent (iface);
|
|
|
|
if (! parent_view_iface)
|
|
parent_view_iface = g_type_default_interface_peek (PIKA_TYPE_CONTAINER_VIEW);
|
|
|
|
iface->select_items = pika_tool_editor_select_items;
|
|
iface->set_container = pika_tool_editor_set_container;
|
|
iface->set_context = pika_tool_editor_set_context;
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_init (PikaToolEditor *tool_editor)
|
|
{
|
|
tool_editor->priv = pika_tool_editor_get_instance_private (tool_editor);
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_constructed (GObject *object)
|
|
{
|
|
PikaToolEditor *tool_editor = PIKA_TOOL_EDITOR (object);
|
|
PikaContainerTreeView *tree_view = PIKA_CONTAINER_TREE_VIEW (object);
|
|
PikaContainerView *container_view = PIKA_CONTAINER_VIEW (object);
|
|
gint view_size;
|
|
gint border_width;
|
|
|
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
|
|
|
view_size = pika_container_view_get_view_size (container_view,
|
|
&border_width);
|
|
|
|
pika_editor_set_show_name (PIKA_EDITOR (tool_editor), FALSE);
|
|
|
|
gtk_tree_view_set_level_indentation (tree_view->view,
|
|
0.8 * (view_size + 2 * border_width));
|
|
|
|
pika_dnd_viewable_dest_add (GTK_WIDGET (tree_view->view),
|
|
PIKA_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 = pika_cell_renderer_toggle_new (PIKA_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,
|
|
pika_tool_editor_eye_data_func,
|
|
tree_view, NULL);
|
|
|
|
pika_container_tree_view_add_toggle_cell (tree_view, eye_cell);
|
|
|
|
g_signal_connect (eye_cell, "clicked",
|
|
G_CALLBACK (pika_tool_editor_eye_clicked),
|
|
tool_editor);
|
|
}
|
|
|
|
/* buttons */
|
|
tool_editor->priv->new_group_button =
|
|
pika_editor_add_button (PIKA_EDITOR (tool_editor), PIKA_ICON_FOLDER_NEW,
|
|
_("Create a new tool group"), NULL,
|
|
G_CALLBACK (pika_tool_editor_new_group_clicked),
|
|
NULL,
|
|
G_OBJECT (tool_editor));
|
|
|
|
tool_editor->priv->raise_button =
|
|
pika_editor_add_button (PIKA_EDITOR (tool_editor), PIKA_ICON_GO_UP,
|
|
_("Raise this item"),
|
|
_("Raise this item to the top"),
|
|
G_CALLBACK (pika_tool_editor_raise_clicked),
|
|
G_CALLBACK (pika_tool_editor_raise_extend_clicked),
|
|
G_OBJECT (tool_editor));
|
|
|
|
tool_editor->priv->lower_button =
|
|
pika_editor_add_button (PIKA_EDITOR (tool_editor), PIKA_ICON_GO_DOWN,
|
|
_("Lower this item"),
|
|
_("Lower this item to the bottom"),
|
|
G_CALLBACK (pika_tool_editor_lower_clicked),
|
|
G_CALLBACK (pika_tool_editor_lower_extend_clicked),
|
|
G_OBJECT (tool_editor));
|
|
|
|
tool_editor->priv->delete_button =
|
|
pika_editor_add_button (PIKA_EDITOR (tool_editor), PIKA_ICON_EDIT_DELETE,
|
|
_("Delete this tool group"), NULL,
|
|
G_CALLBACK (pika_tool_editor_delete_clicked),
|
|
NULL,
|
|
G_OBJECT (tool_editor));
|
|
|
|
tool_editor->priv->reset_button =
|
|
pika_editor_add_button (PIKA_EDITOR (tool_editor), PIKA_ICON_RESET,
|
|
_("Reset tool order and visibility"), NULL,
|
|
G_CALLBACK (pika_tool_editor_reset_clicked),
|
|
NULL,
|
|
G_OBJECT (tool_editor));
|
|
|
|
pika_tool_editor_update_sensitivity (tool_editor);
|
|
}
|
|
|
|
static gboolean
|
|
pika_tool_editor_select_items (PikaContainerView *container_view,
|
|
GList *viewables,
|
|
GList *paths)
|
|
{
|
|
PikaToolEditor *tool_editor = PIKA_TOOL_EDITOR (container_view);
|
|
gboolean result;
|
|
|
|
result = parent_view_iface->select_items (container_view,
|
|
viewables, paths);
|
|
|
|
pika_tool_editor_update_sensitivity (tool_editor);
|
|
|
|
return result;
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_set_container (PikaContainerView *container_view,
|
|
PikaContainer *container)
|
|
{
|
|
PikaToolEditor *tool_editor = PIKA_TOOL_EDITOR (container_view);
|
|
|
|
parent_view_iface->set_container (container_view, container);
|
|
|
|
pika_tool_editor_update_container (tool_editor);
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_set_context (PikaContainerView *container_view,
|
|
PikaContext *context)
|
|
{
|
|
PikaToolEditor *tool_editor = PIKA_TOOL_EDITOR (container_view);
|
|
|
|
parent_view_iface->set_context (container_view, context);
|
|
|
|
pika_tool_editor_update_container (tool_editor);
|
|
}
|
|
|
|
static gboolean
|
|
pika_tool_editor_drop_possible (PikaContainerTreeView *tree_view,
|
|
PikaDndType src_type,
|
|
GList *src_viewables,
|
|
PikaViewable *dest_viewable,
|
|
GtkTreePath *drop_path,
|
|
GtkTreeViewDropPosition drop_pos,
|
|
GtkTreeViewDropPosition *return_drop_pos,
|
|
GdkDragAction *return_drag_action)
|
|
{
|
|
if (PIKA_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 (pika_viewable_get_parent (dest_viewable) ||
|
|
(pika_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)
|
|
{
|
|
PikaViewable *src_viewable = iter->data;
|
|
|
|
if (pika_viewable_get_children (src_viewable))
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_drop_viewables (PikaContainerTreeView *tree_view,
|
|
GList *src_viewables,
|
|
PikaViewable *dest_viewable,
|
|
GtkTreeViewDropPosition drop_pos)
|
|
{
|
|
PikaContainerView *container_view = PIKA_CONTAINER_VIEW (tree_view);
|
|
|
|
PIKA_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_viewables (tree_view,
|
|
src_viewables,
|
|
dest_viewable,
|
|
drop_pos);
|
|
|
|
if (src_viewables)
|
|
pika_container_view_select_items (container_view, src_viewables);
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_new_group_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaContainerView *container_view = PIKA_CONTAINER_VIEW (tool_editor);
|
|
PikaContainer *container;
|
|
PikaToolItem *tool_item;
|
|
PikaToolGroup *group;
|
|
gint index = 0;
|
|
|
|
tool_item = pika_tool_editor_get_selected_tool_item (tool_editor);
|
|
|
|
if (tool_item)
|
|
{
|
|
if (pika_viewable_get_parent (PIKA_VIEWABLE (tool_item)) != NULL)
|
|
return;
|
|
|
|
container = pika_tool_editor_get_tool_item_container (tool_editor,
|
|
tool_item);
|
|
|
|
index = pika_container_get_child_index (container,
|
|
PIKA_OBJECT (tool_item));
|
|
}
|
|
else
|
|
{
|
|
container = tool_editor->priv->container;
|
|
}
|
|
|
|
if (container)
|
|
{
|
|
group = pika_tool_group_new ();
|
|
|
|
pika_container_insert (container, PIKA_OBJECT (group), index);
|
|
|
|
g_object_unref (group);
|
|
|
|
pika_container_view_select_item (container_view, PIKA_VIEWABLE (group));
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_raise_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaToolItem *tool_item;
|
|
|
|
tool_item = pika_tool_editor_get_selected_tool_item (tool_editor);
|
|
|
|
if (tool_item)
|
|
{
|
|
PikaContainer *container;
|
|
gint index;
|
|
|
|
container = pika_tool_editor_get_tool_item_container (tool_editor,
|
|
tool_item);
|
|
|
|
index = pika_container_get_child_index (container,
|
|
PIKA_OBJECT (tool_item));
|
|
|
|
if (index > 0)
|
|
{
|
|
pika_container_reorder (container,
|
|
PIKA_OBJECT (tool_item), index - 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_raise_extend_clicked (GtkButton *button,
|
|
GdkModifierType mask,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaToolItem *tool_item;
|
|
|
|
tool_item = pika_tool_editor_get_selected_tool_item (tool_editor);
|
|
|
|
if (tool_item && (mask & GDK_SHIFT_MASK))
|
|
{
|
|
PikaContainer *container;
|
|
gint index;
|
|
|
|
container = pika_tool_editor_get_tool_item_container (tool_editor,
|
|
tool_item);
|
|
|
|
index = pika_container_get_child_index (container,
|
|
PIKA_OBJECT (tool_item));
|
|
|
|
if (index > 0)
|
|
{
|
|
pika_container_reorder (container,
|
|
PIKA_OBJECT (tool_item), 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_lower_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaToolItem *tool_item;
|
|
|
|
tool_item = pika_tool_editor_get_selected_tool_item (tool_editor);
|
|
|
|
if (tool_item)
|
|
{
|
|
PikaContainer *container;
|
|
gint index;
|
|
|
|
container = pika_tool_editor_get_tool_item_container (tool_editor,
|
|
tool_item);
|
|
|
|
index = pika_container_get_child_index (container,
|
|
PIKA_OBJECT (tool_item));
|
|
|
|
if (index + 1 < pika_container_get_n_children (container))
|
|
{
|
|
pika_container_reorder (container,
|
|
PIKA_OBJECT (tool_item), index + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_lower_extend_clicked (GtkButton *button,
|
|
GdkModifierType mask,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaToolItem *tool_item;
|
|
|
|
tool_item = pika_tool_editor_get_selected_tool_item (tool_editor);
|
|
|
|
if (tool_item && (mask & GDK_SHIFT_MASK))
|
|
{
|
|
PikaContainer *container;
|
|
gint index;
|
|
|
|
container = pika_tool_editor_get_tool_item_container (tool_editor,
|
|
tool_item);
|
|
|
|
index = pika_container_get_n_children (container) - 1;
|
|
index = MAX (index, 0);
|
|
|
|
pika_container_reorder (container,
|
|
PIKA_OBJECT (tool_item), index);
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_delete_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaContainerView *container_view = PIKA_CONTAINER_VIEW (tool_editor);
|
|
PikaToolItem *tool_item;
|
|
|
|
tool_item = pika_tool_editor_get_selected_tool_item (tool_editor);
|
|
|
|
if (tool_item)
|
|
{
|
|
PikaContainer *src_container;
|
|
PikaContainer *dest_container;
|
|
gint index;
|
|
gint dest_index;
|
|
|
|
src_container = pika_viewable_get_children (PIKA_VIEWABLE (tool_item));
|
|
dest_container = pika_tool_editor_get_tool_item_container (tool_editor,
|
|
tool_item);
|
|
|
|
if (! src_container)
|
|
return;
|
|
|
|
index = pika_container_get_child_index (dest_container,
|
|
PIKA_OBJECT (tool_item));
|
|
dest_index = index;
|
|
|
|
g_object_ref (tool_item);
|
|
|
|
pika_container_freeze (src_container);
|
|
pika_container_freeze (dest_container);
|
|
|
|
pika_container_remove (dest_container, PIKA_OBJECT (tool_item));
|
|
|
|
while (! pika_container_is_empty (src_container))
|
|
{
|
|
PikaObject *object = pika_container_get_first_child (src_container);
|
|
|
|
g_object_ref (object);
|
|
|
|
pika_container_remove (src_container, object);
|
|
pika_container_insert (dest_container, object, dest_index++);
|
|
|
|
g_object_unref (object);
|
|
}
|
|
|
|
pika_container_thaw (dest_container);
|
|
pika_container_thaw (src_container);
|
|
|
|
pika_container_view_select_item (
|
|
container_view,
|
|
PIKA_VIEWABLE (pika_container_get_child_by_index (dest_container,
|
|
index)));
|
|
|
|
g_object_unref (tool_item);
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_reset_clicked (GtkButton *button,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
pika_tools_reset (tool_editor->priv->context->pika,
|
|
tool_editor->priv->container,
|
|
FALSE);
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_tool_item_notify (PikaToolItem *tool_item,
|
|
GParamSpec *pspec,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaContainerTreeView *tree_view = PIKA_CONTAINER_TREE_VIEW (tool_editor);
|
|
PikaContainerView *container_view = PIKA_CONTAINER_VIEW (tool_editor);
|
|
GtkTreeIter *iter;
|
|
|
|
iter = pika_container_view_lookup (container_view,
|
|
PIKA_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
|
|
pika_tool_editor_eye_data_func (GtkTreeViewColumn *tree_column,
|
|
GtkCellRenderer *cell,
|
|
GtkTreeModel *tree_model,
|
|
GtkTreeIter *iter,
|
|
gpointer data)
|
|
{
|
|
PikaViewRenderer *renderer;
|
|
PikaToolItem *tool_item;
|
|
|
|
gtk_tree_model_get (tree_model, iter,
|
|
PIKA_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
|
|
-1);
|
|
|
|
tool_item = PIKA_TOOL_ITEM (renderer->viewable);
|
|
|
|
g_object_set (cell,
|
|
"active", pika_tool_item_get_visible (tool_item),
|
|
"inconsistent", pika_tool_item_get_visible (tool_item) &&
|
|
! pika_tool_item_get_shown (tool_item),
|
|
NULL);
|
|
|
|
g_object_unref (renderer);
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_eye_clicked (GtkCellRendererToggle *toggle,
|
|
gchar *path_str,
|
|
GdkModifierType state,
|
|
PikaToolEditor *tool_editor)
|
|
{
|
|
PikaContainerTreeView *tree_view = PIKA_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))
|
|
{
|
|
PikaViewRenderer *renderer;
|
|
PikaToolItem *tool_item;
|
|
gboolean active;
|
|
|
|
gtk_tree_model_get (tree_view->model, &iter,
|
|
PIKA_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
|
|
-1);
|
|
|
|
tool_item = PIKA_TOOL_ITEM (renderer->viewable);
|
|
|
|
g_object_get (toggle,
|
|
"active", &active,
|
|
NULL);
|
|
|
|
pika_tool_item_set_visible (tool_item, ! active);
|
|
|
|
g_object_unref (renderer);
|
|
}
|
|
|
|
gtk_tree_path_free (path);
|
|
}
|
|
|
|
static PikaToolItem *
|
|
pika_tool_editor_get_selected_tool_item (PikaToolEditor *tool_editor)
|
|
{
|
|
PikaContainerTreeView *tree_view = PIKA_CONTAINER_TREE_VIEW (tool_editor);
|
|
|
|
if (tool_editor->priv->container)
|
|
{
|
|
PikaViewRenderer *renderer;
|
|
PikaToolItem *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,
|
|
PIKA_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
|
|
-1);
|
|
|
|
tool_item = PIKA_TOOL_ITEM (renderer->viewable);
|
|
|
|
g_object_unref (renderer);
|
|
|
|
return tool_item;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static PikaContainer *
|
|
pika_tool_editor_get_tool_item_container (PikaToolEditor *tool_editor,
|
|
PikaToolItem *tool_item)
|
|
{
|
|
PikaViewable *parent;
|
|
|
|
parent = pika_viewable_get_parent (PIKA_VIEWABLE (tool_item));
|
|
|
|
if (parent)
|
|
{
|
|
return pika_viewable_get_children (parent);
|
|
}
|
|
else
|
|
{
|
|
return tool_editor->priv->container;
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_update_container (PikaToolEditor *tool_editor)
|
|
{
|
|
PikaContainerView *container_view = PIKA_CONTAINER_VIEW (tool_editor);
|
|
PikaContainer *container;
|
|
PikaContext *context;
|
|
|
|
g_clear_pointer (&tool_editor->priv->tool_item_notify_handler,
|
|
pika_tree_handler_disconnect);
|
|
|
|
g_clear_pointer (&tool_editor->priv->initial_tool_state, g_free);
|
|
|
|
container = pika_container_view_get_container (container_view);
|
|
context = pika_container_view_get_context (container_view);
|
|
|
|
if (container && context)
|
|
{
|
|
GString *string;
|
|
PikaConfigWriter *writer;
|
|
|
|
tool_editor->priv->container = container;
|
|
tool_editor->priv->context = context;
|
|
|
|
tool_editor->priv->tool_item_notify_handler = pika_tree_handler_connect (
|
|
container, "notify",
|
|
G_CALLBACK (pika_tool_editor_tool_item_notify),
|
|
tool_editor);
|
|
|
|
/* save initial tool order */
|
|
string = g_string_new (NULL);
|
|
|
|
writer = pika_config_writer_new_from_string (string);
|
|
|
|
pika_tools_serialize (context->pika, container, writer);
|
|
|
|
pika_config_writer_finish (writer, NULL, NULL);
|
|
|
|
tool_editor->priv->initial_tool_state = g_string_free (string, FALSE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
pika_tool_editor_update_sensitivity (PikaToolEditor *tool_editor)
|
|
{
|
|
PikaToolItem *tool_item;
|
|
|
|
tool_item = pika_tool_editor_get_selected_tool_item (tool_editor);
|
|
|
|
if (tool_item)
|
|
{
|
|
PikaContainer *container;
|
|
gint index;
|
|
|
|
container = pika_tool_editor_get_tool_item_container (tool_editor,
|
|
tool_item);
|
|
|
|
index = pika_container_get_child_index (container,
|
|
PIKA_OBJECT (tool_item));
|
|
|
|
gtk_widget_set_sensitive (
|
|
tool_editor->priv->new_group_button,
|
|
pika_viewable_get_parent (PIKA_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 < pika_container_get_n_children (container) - 1);
|
|
|
|
gtk_widget_set_sensitive (
|
|
tool_editor->priv->delete_button,
|
|
pika_viewable_get_children (PIKA_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 *
|
|
pika_tool_editor_new (PikaContainer *container,
|
|
PikaContext *context,
|
|
gint view_size,
|
|
gint view_border_width)
|
|
{
|
|
PikaContainerView *container_view;
|
|
|
|
g_return_val_if_fail (PIKA_IS_CONTAINER (container), NULL);
|
|
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
|
|
|
|
container_view = g_object_new (PIKA_TYPE_TOOL_EDITOR,
|
|
"view-size", view_size,
|
|
"view-border-width", view_border_width,
|
|
NULL);
|
|
|
|
pika_container_view_set_context (container_view, context);
|
|
pika_container_view_set_container (container_view, container);
|
|
pika_container_view_set_reorderable (container_view, TRUE);
|
|
|
|
return GTK_WIDGET (container_view);
|
|
}
|
|
|
|
/**
|
|
* pika_tool_editor_revert_changes:
|
|
* @tool_editor:
|
|
*
|
|
* Reverts the tool order and visibility to the state at creation.
|
|
**/
|
|
void
|
|
pika_tool_editor_revert_changes (PikaToolEditor *tool_editor)
|
|
{
|
|
GScanner *scanner;
|
|
|
|
g_return_if_fail (PIKA_IS_TOOL_EDITOR (tool_editor));
|
|
|
|
scanner = pika_scanner_new_string (tool_editor->priv->initial_tool_state, -1,
|
|
NULL);
|
|
|
|
pika_tools_deserialize (tool_editor->priv->context->pika,
|
|
tool_editor->priv->container,
|
|
scanner);
|
|
|
|
pika_scanner_unref (scanner);
|
|
}
|