Commit 8c9c5a20 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

added utility function gimp_container_tree_view_find_click_cell(). Don't

2003-03-16  Michael Natterer  <mitch@gimp.org>

	* app/widgets/gimpcontainertreeview.[ch]: added utility function
	gimp_container_tree_view_find_click_cell(). Don't select the
	row if one of tree_view->toggle_cells was clicked. Removed
	"GList *toggle_columns" from the struct.

	* app/widgets/gimpdrawabletreeview.[ch]: added a
	GtkTreeSelectionFunc which ensures that nothing but the floating
	selection can be selected. Removed the "eye_column" from the
	struct.

	* app/widgets/gimpitemtreeview.[ch]: added virtual function
	rename_item() and a default implementation.

	* app/widgets/gimplayertreeview.[ch]: implement rename_item() and
	special case floating selections. Added
	gimp_layer_tree_view_mask_update() utility function to factor out
	duplicated code. Removed "chain_column" from the struct. Cleanup.
parent 205cdf13
2003-03-16 Michael Natterer <mitch@gimp.org>
* app/widgets/gimpcontainertreeview.[ch]: added utility function
gimp_container_tree_view_find_click_cell(). Don't select the
row if one of tree_view->toggle_cells was clicked. Removed
"GList *toggle_columns" from the struct.
* app/widgets/gimpdrawabletreeview.[ch]: added a
GtkTreeSelectionFunc which ensures that nothing but the floating
selection can be selected. Removed the "eye_column" from the
struct.
* app/widgets/gimpitemtreeview.[ch]: added virtual function
rename_item() and a default implementation.
* app/widgets/gimplayertreeview.[ch]: implement rename_item() and
special case floating selections. Added
gimp_layer_tree_view_mask_update() utility function to factor out
duplicated code. Removed "chain_column" from the struct. Cleanup.
2003-03-16 Michael Natterer <mitch@gimp.org>
Added GtkTreeView versions of layers/channels/vectors:
......@@ -645,6 +645,39 @@ gimp_container_tree_view_selection_changed (GtkTreeSelection *selection,
}
}
static GtkCellRenderer *
gimp_container_tree_view_find_click_cell (GList *cells,
GtkTreeViewColumn *column,
GdkRectangle *column_area,
gint tree_x,
gint tree_y)
{
GtkCellRenderer *renderer;
GList *list;
for (list = cells; list; list = g_list_next (list))
{
gint start_pos;
gint width;
renderer = (GtkCellRenderer *) list->data;
if (renderer->visible &&
gtk_tree_view_column_cell_get_position (column, renderer,
&start_pos, &width) &&
width > 0 &&
column_area->x + start_pos + renderer->xpad <= tree_x &&
column_area->x + start_pos + renderer->xpad + width - 1 >= tree_x)
{
g_print ("click on cell at %d (%d width)\n", start_pos, width);
return renderer;
}
}
return NULL;
}
static gboolean
gimp_container_tree_view_button_press (GtkWidget *widget,
GdkEventButton *bevent,
......@@ -671,7 +704,6 @@ gimp_container_tree_view_button_press (GtkWidget *widget,
gint tree_x;
gint tree_y;
GtkTreeIter iter;
GList *list;
gtk_tree_model_get_iter (tree_view->model, &iter, path);
......@@ -684,7 +716,6 @@ gimp_container_tree_view_button_press (GtkWidget *widget,
gtk_tree_view_widget_to_tree_coords (tree_view->view,
bevent->x, bevent->y,
&tree_x, &tree_y);
gtk_tree_view_get_background_area (tree_view->view, path,
column, &column_area);
......@@ -693,41 +724,16 @@ gimp_container_tree_view_button_press (GtkWidget *widget,
&iter,
FALSE, FALSE);
for (list = tree_view->toggle_columns; list; list = g_list_next (list))
{
if (list->data == (gpointer) column)
{
toggled_cell = NULL;
break;
}
}
if (column == tree_view->main_column)
{
for (list = tree_view->renderer_cells;
list;
list = g_list_next (list))
{
GtkCellRenderer *cell_renderer = list->data;
gint start_pos;
gint width;
if (cell_renderer->visible &&
gtk_tree_view_column_cell_get_position (column,
cell_renderer,
&start_pos,
&width) &&
width > 0 &&
column_area.x + start_pos + cell_renderer->xpad <= tree_x &&
column_area.x + start_pos + cell_renderer->xpad + width - 1 >= tree_x)
{
g_print ("click_cell at %d (%d width)\n", start_pos, width);
toggled_cell =
gimp_container_tree_view_find_click_cell (tree_view->toggle_cells,
column, &column_area,
tree_x, tree_y);
clicked_cell = cell_renderer;
break;
}
}
}
if (! toggled_cell)
clicked_cell =
gimp_container_tree_view_find_click_cell (tree_view->renderer_cells,
column, &column_area,
tree_x, tree_y);
switch (bevent->button)
{
......@@ -742,11 +748,11 @@ gimp_container_tree_view_button_press (GtkWidget *widget,
if (toggled_cell)
{
/* don't select path */
g_signal_emit_by_name (toggled_cell, "toggled",
path_str);
}
if (clicked_cell)
else if (clicked_cell)
{
gtk_tree_selection_select_path (tree_view->selection,
path);
......
......@@ -56,7 +56,6 @@ struct _GimpContainerTreeView
GtkCellRenderer *renderer_cell;
GtkCellRenderer *name_cell;
GList *toggle_columns;
GList *toggle_cells;
GList *renderer_cells;
......
......@@ -66,6 +66,12 @@ static gpointer gimp_drawable_tree_view_insert_item (GimpContainerView *view,
static void gimp_drawable_tree_view_set_image (GimpItemTreeView *view,
GimpImage *gimage);
static gboolean gimp_drawable_tree_view_select (GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
gpointer data);
static void gimp_drawable_tree_view_floating_selection_changed
(GimpImage *gimage,
GimpDrawableTreeView *view);
......@@ -168,34 +174,34 @@ gimp_drawable_tree_view_constructor (GType type,
GimpContainerTreeView *tree_view;
GimpDrawableTreeView *drawable_view;
GObject *object;
GtkTreeViewColumn *column;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
tree_view = GIMP_CONTAINER_TREE_VIEW (object);
drawable_view = GIMP_DRAWABLE_TREE_VIEW (object);
drawable_view->eye_column = gtk_tree_view_column_new ();
gtk_tree_view_insert_column (tree_view->view, drawable_view->eye_column, 0);
column = gtk_tree_view_column_new ();
gtk_tree_view_insert_column (tree_view->view, column, 0);
drawable_view->eye_cell = gimp_cell_renderer_toggle_new (GIMP_STOCK_VISIBLE);
gtk_tree_view_column_pack_start (drawable_view->eye_column,
drawable_view->eye_cell,
FALSE);
gtk_tree_view_column_set_attributes (drawable_view->eye_column,
drawable_view->eye_cell,
gtk_tree_view_column_pack_start (column, drawable_view->eye_cell, FALSE);
gtk_tree_view_column_set_attributes (column, drawable_view->eye_cell,
"active",
drawable_view->model_column_visible,
NULL);
tree_view->toggle_columns = g_list_prepend (tree_view->toggle_columns,
drawable_view->eye_column);
tree_view->toggle_cells = g_list_prepend (tree_view->toggle_cells,
drawable_view->eye_cell);
tree_view->toggle_cells = g_list_prepend (tree_view->toggle_cells,
drawable_view->eye_cell);
g_signal_connect (drawable_view->eye_cell, "toggled",
G_CALLBACK (gimp_drawable_tree_view_eye_toggled),
drawable_view);
gtk_tree_selection_set_select_function (tree_view->selection,
gimp_drawable_tree_view_select,
drawable_view, NULL);
return object;
}
......@@ -276,6 +282,52 @@ gimp_drawable_tree_view_set_image (GimpItemTreeView *item_view,
}
}
static gboolean
gimp_drawable_tree_view_select (GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
gpointer data)
{
GimpItemTreeView *item_view;
GtkTreeIter iter;
gboolean retval = TRUE;
item_view = GIMP_ITEM_TREE_VIEW (data);
if (gimp_image_floating_sel (item_view->gimage) &&
gtk_tree_model_get_iter (model, &iter, path))
{
GimpContainerTreeView *tree_view;
GimpPreviewRenderer *renderer;
tree_view = GIMP_CONTAINER_TREE_VIEW (item_view);
gtk_tree_model_get (model, &iter,
tree_view->model_column_renderer, &renderer,
-1);
if (((GimpLayer *) renderer->viewable ==
gimp_image_floating_sel (item_view->gimage)))
{
if (path_currently_selected)
retval = FALSE;
}
else
{
if (! path_currently_selected)
retval = FALSE;
}
g_print ("gimp_drawable_tree_view_select: floating sel present (%d)\n",
retval);
g_object_unref (renderer);
}
return retval;
}
static void
gimp_drawable_tree_view_floating_selection_changed (GimpImage *gimage,
GimpDrawableTreeView *view)
......
......@@ -42,7 +42,6 @@ struct _GimpDrawableTreeView
gint model_column_visible;
GtkTreeViewColumn *eye_column;
GtkCellRenderer *eye_cell;
GQuark visibility_changed_handler_id;
......
......@@ -33,14 +33,10 @@
#include "core/gimpchannel.h"
#include "core/gimpcontainer.h"
#include "core/gimpimage.h"
#include "core/gimpimage-undo.h"
#include "core/gimpimage-undo-push.h"
#include "core/gimplayer.h"
#include "core/gimpmarshal.h"
/* EEK */
#include "core/gimplayer-floating-sel.h"
#include "vectors/gimpvectors.h"
#include "gimpchanneltreeview.h"
......@@ -85,6 +81,10 @@ static void gimp_item_tree_view_context_item (GimpContainerView *view,
GimpViewable *item,
gpointer insert_data);
static void gimp_item_tree_view_real_rename_item (GimpItemTreeView *view,
GimpItem *item,
const gchar *new_name);
static void gimp_item_tree_view_new_clicked (GtkWidget *widget,
GimpItemTreeView *view);
static void gimp_item_tree_view_new_dropped (GtkWidget *widget,
......@@ -195,6 +195,7 @@ gimp_item_tree_view_class_init (GimpItemTreeViewClass *klass)
klass->add_item = NULL;
klass->remove_item = NULL;
klass->convert_item = NULL;
klass->rename_item = gimp_item_tree_view_real_rename_item;
klass->new_desc = NULL;
klass->duplicate_desc = NULL;
......@@ -490,8 +491,6 @@ gimp_item_tree_view_select_item (GimpContainerView *view,
tree_view = GIMP_ITEM_TREE_VIEW (view);
g_print ("item: %p\n", item);
GIMP_CONTAINER_VIEW_CLASS (parent_class)->select_item (view, item,
insert_data);
......@@ -575,6 +574,30 @@ gimp_item_tree_view_context_item (GimpContainerView *view,
}
/* GimpItemTreeView methods */
static void
gimp_item_tree_view_real_rename_item (GimpItemTreeView *view,
GimpItem *item,
const gchar *new_name)
{
if (strcmp (new_name, gimp_object_get_name (GIMP_OBJECT (item))))
{
GimpItemTreeViewClass *item_view_class;
item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view);
gimp_image_undo_push_item_rename (view->gimage,
item_view_class->rename_desc,
item);
gimp_object_set_name (GIMP_OBJECT (item), new_name);
gimp_image_flush (view->gimage);
}
}
/* "New" functions */
static void
......@@ -848,37 +871,8 @@ gimp_item_tree_view_name_edited (GtkCellRendererText *cell,
item = GIMP_ITEM (renderer->viewable);
if (strcmp (new_text, gimp_object_get_name (GIMP_OBJECT (item))))
{
GimpItemTreeViewClass *item_view_class;
item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view);
gimp_image_undo_group_start (view->gimage,
GIMP_UNDO_GROUP_ITEM_PROPERTIES,
item_view_class->rename_desc);
#ifdef __GNUC__
#warning need GimpItemTreeView::rename_item()
#endif
if (GIMP_IS_LAYER (item) &&
gimp_layer_is_floating_sel (GIMP_LAYER (item)))
{
/* If the layer is a floating selection, make it a layer */
floating_sel_to_layer (GIMP_LAYER (item));
}
gimp_image_undo_push_item_rename (view->gimage,
item_view_class->rename_desc,
item);
gimp_object_set_name (GIMP_OBJECT (item), new_text);
gimp_image_undo_group_end (view->gimage);
gimp_image_flush (view->gimage);
}
GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->rename_item (view, item,
new_text);
g_object_unref (renderer);
}
......
......@@ -101,6 +101,10 @@ struct _GimpItemTreeViewClass
GimpRemoveItemFunc remove_item;
GimpConvertItemFunc convert_item;
void (* rename_item) (GimpItemTreeView *view,
GimpItem *item,
const gchar *new_name);
/* various descriptive strings for tooltips and undo steps */
const gchar *new_desc;
const gchar *duplicate_desc;
......
......@@ -21,6 +21,8 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
......@@ -34,6 +36,8 @@
#include "core/gimplayermask.h"
#include "core/gimplayer-floating-sel.h"
#include "core/gimpimage.h"
#include "core/gimpimage-undo.h"
#include "core/gimpimage-undo-push.h"
#include "gimpcellrenderertoggle.h"
#include "gimpcellrendererviewable.h"
......@@ -64,6 +68,12 @@ static void gimp_layer_tree_view_select_item (GimpContainerView *view,
gpointer insert_data);
static void gimp_layer_tree_view_set_preview_size (GimpContainerView *view);
static void gimp_layer_tree_view_remove_item (GimpImage *gimage,
GimpItem *layer);
static void gimp_layer_tree_view_rename_item (GimpItemTreeView *view,
GimpItem *item,
const gchar *new_name);
static void gimp_layer_tree_view_anchor_clicked (GtkWidget *widget,
GimpLayerTreeView *view);
......@@ -89,6 +99,9 @@ static void gimp_layer_tree_view_chain_toggled (GtkCellRendererToggle *toggle
gchar *path,
GimpLayerTreeView *view);
static void gimp_layer_tree_view_mask_update (GimpLayerTreeView *view,
GtkTreeIter *iter,
GimpLayer *layer);
static void gimp_layer_tree_view_mask_changed (GimpLayer *layer,
GimpLayerTreeView *view);
static void gimp_layer_tree_view_renderer_update(GimpPreviewRenderer *renderer,
......@@ -96,7 +109,7 @@ static void gimp_layer_tree_view_renderer_update(GimpPreviewRenderer *renderer
static void gimp_layer_tree_view_update_borders (GimpLayerTreeView *view,
GtkTreeIter *iter);
static void gimp_layer_tree_view_mask_update (GimpLayerMask *mask,
static void gimp_layer_tree_view_mask_callback (GimpLayerMask *mask,
GimpLayerTreeView *view);
static void gimp_layer_tree_view_layer_clicked (GimpCellRendererViewable *cell,
const gchar *path,
......@@ -107,9 +120,6 @@ static void gimp_layer_tree_view_mask_clicked (GimpCellRendererViewable *cel
GdkModifierType state,
GimpLayerTreeView *view);
static void gimp_layer_tree_view_remove_layer (GimpImage *gimage,
GimpItem *layer);
static GimpDrawableTreeViewClass *parent_class = NULL;
......@@ -176,8 +186,9 @@ gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass)
item_view_class->set_active_item = (GimpSetItemFunc) gimp_image_set_active_layer;
item_view_class->reorder_item = (GimpReorderItemFunc) gimp_image_position_layer;
item_view_class->add_item = (GimpAddItemFunc) gimp_image_add_layer;
item_view_class->remove_item = gimp_layer_tree_view_remove_layer;
item_view_class->remove_item = gimp_layer_tree_view_remove_item;
item_view_class->convert_item = (GimpConvertItemFunc) gimp_layer_new_from_drawable;
item_view_class->rename_item = gimp_layer_tree_view_rename_item;
item_view_class->new_desc = _("New Layer");
item_view_class->duplicate_desc = _("Duplicate Layer");
......@@ -307,21 +318,19 @@ gimp_layer_tree_view_constructor (GType type,
GimpContainerTreeView *tree_view;
GimpLayerTreeView *layer_view;
GObject *object;
GtkTreeViewColumn *column;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
tree_view = GIMP_CONTAINER_TREE_VIEW (object);
layer_view = GIMP_LAYER_TREE_VIEW (object);
layer_view->chain_column = gtk_tree_view_column_new ();
gtk_tree_view_insert_column (tree_view->view, layer_view->chain_column, 1);
column = gtk_tree_view_column_new ();
gtk_tree_view_insert_column (tree_view->view, column, 1);
layer_view->chain_cell = gimp_cell_renderer_toggle_new (GIMP_STOCK_LINKED);
gtk_tree_view_column_pack_start (layer_view->chain_column,
layer_view->chain_cell,
FALSE);
gtk_tree_view_column_set_attributes (layer_view->chain_column,
layer_view->chain_cell,
gtk_tree_view_column_pack_start (column, layer_view->chain_cell, FALSE);
gtk_tree_view_column_set_attributes (column, layer_view->chain_cell,
"active",
layer_view->model_column_linked,
NULL);
......@@ -338,10 +347,8 @@ gimp_layer_tree_view_constructor (GType type,
layer_view->model_column_mask_visible,
NULL);
tree_view->toggle_columns = g_list_prepend (tree_view->toggle_columns,
layer_view->chain_column);
tree_view->toggle_cells = g_list_prepend (tree_view->toggle_cells,
layer_view->chain_cell);
tree_view->toggle_cells = g_list_prepend (tree_view->toggle_cells,
layer_view->chain_cell);
tree_view->renderer_cells = g_list_prepend (tree_view->renderer_cells,
layer_view->mask_cell);
......@@ -443,7 +450,6 @@ gimp_layer_tree_view_insert_item (GimpContainerView *view,
GimpContainerTreeView *tree_view;
GimpLayerTreeView *layer_view;
GimpLayer *layer;
GimpLayerMask *mask;
GtkTreeIter *iter;
tree_view = GIMP_CONTAINER_TREE_VIEW (view);
......@@ -453,45 +459,13 @@ gimp_layer_tree_view_insert_item (GimpContainerView *view,
index);
layer = GIMP_LAYER (viewable);
mask = gimp_layer_get_mask (layer);
gtk_list_store_set (GTK_LIST_STORE (tree_view->model), iter,
layer_view->model_column_linked,
gimp_layer_get_linked (layer),
-1);
if (mask)
{
GimpPreviewRenderer *renderer;
GClosure *closure;
renderer = gimp_preview_renderer_new (G_TYPE_FROM_INSTANCE (mask),
view->preview_size,
tree_view->preview_border_width,
FALSE);
gimp_preview_renderer_set_viewable (renderer, GIMP_VIEWABLE (mask));
g_signal_connect (renderer, "update",
G_CALLBACK (gimp_layer_tree_view_renderer_update),
layer_view);
closure =
g_cclosure_new (G_CALLBACK (gimp_layer_tree_view_mask_update),
layer_view, NULL);
g_object_watch_closure (G_OBJECT (renderer), closure);
g_signal_connect_closure (mask, "apply_changed", closure, FALSE);
g_signal_connect_closure (mask, "edit_changed", closure, FALSE);
g_signal_connect_closure (mask, "show_changed", closure, FALSE);
gtk_list_store_set (GTK_LIST_STORE (tree_view->model), iter,
layer_view->model_column_mask, renderer,
layer_view->model_column_mask_visible, TRUE,
-1);
gimp_layer_tree_view_mask_update (mask, layer_view);
gimp_preview_renderer_remove_idle (renderer);
g_object_unref (renderer);
}
gimp_layer_tree_view_mask_update (layer_view, iter, layer);
return iter;
}
......@@ -577,7 +551,55 @@ gimp_layer_tree_view_set_preview_size (GimpContainerView *view)
GIMP_CONTAINER_VIEW_CLASS (parent_class)->set_preview_size (view);
}
/* "Anchor" functions */
/* GimpItemTreeView methods */
static void
gimp_layer_tree_view_remove_item (GimpImage *gimage,
GimpItem *item)
{
if (gimp_layer_is_floating_sel (GIMP_LAYER (item)))
floating_sel_remove (GIMP_LAYER (item));
else
gimp_image_remove_layer (gimage, GIMP_LAYER (item));
}
static void
gimp_layer_tree_view_rename_item (GimpItemTreeView *view,
GimpItem *item,
const gchar *new_name)
{
if (strcmp (new_name, gimp_object_get_name (GIMP_OBJECT (item))))
{
GimpItemTreeViewClass *item_view_class;
GimpLayer *layer;
item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view);
layer = GIMP_LAYER (item);
gimp_image_undo_group_start (view->gimage,
GIMP_UNDO_GROUP_ITEM_PROPERTIES,
item_view_class->rename_desc);
/* If the layer is a floating selection, make it a layer */
if (gimp_layer_is_floating_sel (layer))
floating_sel_to_layer (layer);
gimp_image_undo_push_item_rename (view->gimage,
item_view_class->rename_desc,
item);
gimp_object_set_name (GIMP_OBJECT (item), new_name);
gimp_image_undo_group_end (view->gimage);
gimp_image_flush (view->gimage);
}
}
/* Anchor callback */
static void
gimp_layer_tree_view_anchor_clicked (GtkWidget *widget,
......@@ -714,9 +736,7 @@ gimp_layer_tree_view_layer_signal_handler (GimpLayer *layer,
GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_active_item (item_view->gimage);
if (active_layer == layer)
{
gimp_layer_tree_view_update_options (view, layer);
}
gimp_layer_tree_view_update_options (view, layer);
}
......@@ -762,6 +782,9 @@ gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
#undef BLOCK
#undef UNBLOCK
/* "Linked" callbacks */
static void
gimp_layer_tree_view_linked_changed (GimpLayer *layer,
GimpLayerTreeView *view)
......@@ -818,67 +841,77 @@ gimp_layer_tree_view_chain_toggled (GtkCellRendererToggle *toggle,
gtk_tree_path_free (path);
}
/* Layer Mask callbacks */
static void
gimp_layer_tree_view_mask_changed (GimpLayer *layer,
GimpLayerTreeView *layer_view)
gimp_layer_tree_view_mask_update (GimpLayerTreeView *layer_view,
GtkTreeIter *iter,
GimpLayer *layer)
{
GimpContainerView *view;
GimpContainerView *container_view;
GimpContainerTreeView *tree_view;
GtkTreeIter *iter;
GimpLayerMask *mask;
GimpPreviewRenderer *renderer = NULL;
gboolean mask_visible = FALSE;
view = GIMP_CONTAINER_VIEW (layer_view);
tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
container_view = GIMP_CONTAINER_VIEW (layer_view);
tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
iter = g_hash_table_lookup (view->hash_table, layer);
mask = gimp_layer_get_mask (layer);
if (iter)
if (mask)
{
GimpLayerMask *mask;
GimpPreviewRenderer *renderer = NULL;
gboolean mask_visible = FALSE;
GClosure *closure;
mask = gimp_layer_get_mask (layer);
mask_visible = TRUE;
if (mask)
{
GClosure *closure;
mask_visible = TRUE;
renderer = gimp_preview_renderer_new (G_TYPE_FROM_INSTANCE (mask),
view->preview_size,
tree_view->preview_border_width,
FALSE);
gimp_preview_renderer_set_viewable (renderer, GIMP_VIEWABLE (mask));
g_signal_connect (renderer, "update",
G_CALLBACK (gimp_layer_tree_view_renderer_update),