PROP_SEARCH_COLUMN,
PROP_FIXED_HEIGHT_MODE,
PROP_HOVER_SELECTION,
- PROP_HOVER_EXPAND
+ PROP_HOVER_EXPAND,
+ PROP_SHOW_EXPANDERS,
+ PROP_LEVEL_INDENTATION
};
static void gtk_tree_view_class_init (GtkTreeViewClass *klass);
FALSE,
GTK_PARAM_READWRITE));
+ g_object_class_install_property (o_class,
+ PROP_SHOW_EXPANDERS,
+ g_param_spec_boolean ("show-expanders",
+ P_("Show Expanders"),
+ P_("View has expanders"),
+ TRUE,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (o_class,
+ PROP_LEVEL_INDENTATION,
+ g_param_spec_int ("level-indentation",
+ P_("Level Indentation"),
+ P_("Extra indentation for each level"),
+ 0,
+ G_MAXINT,
+ 0,
+ GTK_PARAM_READWRITE));
+
/* Style properties */
#define _TREE_VIEW_EXPANDER_SIZE 12
#define _TREE_VIEW_VERTICAL_SEPARATOR 2
tree_view->priv->hover_selection = FALSE;
tree_view->priv->hover_expand = FALSE;
+
+ tree_view->priv->level_indentation = 0;
}
\f
case PROP_HOVER_EXPAND:
tree_view->priv->hover_expand = g_value_get_boolean (value);
break;
+ case PROP_SHOW_EXPANDERS:
+ if (g_value_get_boolean (value))
+ GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_SHOW_EXPANDERS);
+ else
+ GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_SHOW_EXPANDERS);
+ break;
+ case PROP_LEVEL_INDENTATION:
+ tree_view->priv->level_indentation = g_value_get_int (value);
+ break;
default:
break;
}
case PROP_HOVER_EXPAND:
g_value_set_boolean (value, tree_view->priv->hover_expand);
break;
+ case PROP_SHOW_EXPANDERS:
+ g_value_set_boolean (value, GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_SHOW_EXPANDERS));
+ break;
+ case PROP_LEVEL_INDENTATION:
+ g_value_set_int (value, tree_view->priv->level_indentation);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
/* are we in an arrow? */
if (tree_view->priv->prelight_node &&
- GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT))
+ GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT) &&
+ TREE_VIEW_DRAW_EXPANDERS (tree_view))
{
if (event->button == 1)
{
cell_area.height -= vertical_separator;
cell_area.x += horizontal_separator/2;
cell_area.y += vertical_separator/2;
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS(tree_view))
+ if (gtk_tree_view_is_expander_column (tree_view, column))
{
- cell_area.x += depth * tree_view->priv->expander_size;
- cell_area.width -= depth * tree_view->priv->expander_size;
+ cell_area.x += (depth - 1) * tree_view->priv->level_indentation;
+ cell_area.width -= (depth - 1) * tree_view->priv->level_indentation;
+
+ if (TREE_VIEW_DRAW_EXPANDERS(tree_view))
+ {
+ cell_area.x += depth * tree_view->priv->expander_size;
+ cell_area.width -= depth * tree_view->priv->expander_size;
+ }
}
break;
}
/* We are still on the same node,
but we might need to take care of the arrow */
- if (tree && node)
+ if (tree && node && TREE_VIEW_DRAW_EXPANDERS (tree_view))
{
gboolean over_arrow;
gboolean flag_set;
GTK_RBNODE_UNSET_FLAG (tree_view->priv->prelight_node,
GTK_RBNODE_IS_PRELIT);
- if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT))
+ if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT)
+ && TREE_VIEW_DRAW_EXPANDERS (tree_view))
{
GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_ARROW_PRELIT);
/* Prelight the new node and arrow */
- if (coords_are_over_arrow (tree_view, tree, node, x, y))
+ if (TREE_VIEW_DRAW_EXPANDERS (tree_view)
+ && coords_are_over_arrow (tree_view, tree, node, x, y))
{
GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_ARROW_PRELIT);
background_area.width,
background_area.height);
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS(tree_view))
+ if (gtk_tree_view_is_expander_column (tree_view, column))
{
- if (!rtl)
- cell_area.x += depth * tree_view->priv->expander_size;
- cell_area.width -= depth * tree_view->priv->expander_size;
+ cell_area.x += (depth - 1) * tree_view->priv->level_indentation;
+ cell_area.width -= (depth - 1) * tree_view->priv->level_indentation;
+
+ if (TREE_VIEW_DRAW_EXPANDERS(tree_view))
+ {
+ if (!rtl)
+ cell_area.x += depth * tree_view->priv->expander_size;
+ cell_area.width -= depth * tree_view->priv->expander_size;
+ }
/* If we have an expander column, the highlight underline
* starts with that column, so that it indicates which
&cell_area,
&event->area,
flags);
- if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
+ if (TREE_VIEW_DRAW_EXPANDERS(tree_view)
+ && (node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
{
if (!got_pointer)
{
else
height = 2 + 2 * focus_pad;
- if (gtk_tree_view_is_expander_column (tree_view, column) && TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ if (gtk_tree_view_is_expander_column (tree_view, column))
{
- tmp_width = tmp_width + horizontal_separator + depth * (tree_view->priv->expander_size);
+ tmp_width = tmp_width + horizontal_separator + (depth - 1) * tree_view->priv->level_indentation;
+
+ if (TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ tmp_width += depth * tree_view->priv->expander_size;
}
else
tmp_width = tmp_width + horizontal_separator;
&width, NULL);
}
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ if (gtk_tree_view_is_expander_column (tree_view, column))
{
- if (depth * tree_view->priv->expander_size + horizontal_separator + width > column->requested_width)
+ int tmp = 0;
+
+ tmp = horizontal_separator + width + (depth - 1) * tree_view->priv->level_indentation;
+ if (TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ tmp += depth * tree_view->priv->expander_size;
+
+ if (tmp > column->requested_width)
{
_gtk_tree_view_column_cell_set_dirty (column, TRUE);
retval = TRUE;
rect->height = MAX (CELL_HEIGHT (node, vertical_separator), tree_view->priv->expander_size - vertical_separator);
if (column &&
- gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ gtk_tree_view_is_expander_column (tree_view, column))
{
gint depth = gtk_tree_path_get_depth (path) - 1;
- rect->x += depth * tree_view->priv->expander_size;
- rect->width -= depth * tree_view->priv->expander_size;
+ if (depth > 0)
+ {
+ rect->x += (depth - 1) * tree_view->priv->level_indentation;
+ rect->width -= (depth - 1) * tree_view->priv->level_indentation;
+ }
+
+ if (TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ {
+ rect->x += depth * tree_view->priv->expander_size;
+ rect->width -= depth * tree_view->priv->expander_size;
+ }
+
rect->width = MAX (rect->width, 0);
}
}
cell_area.y += vertical_separator / 2;
cell_area.height -= vertical_separator;
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS(tree_view))
+ if (gtk_tree_view_is_expander_column (tree_view, column))
{
- cell_area.x += depth * tree_view->priv->expander_size;
- cell_area.width -= depth * tree_view->priv->expander_size;
+ cell_area.x += (depth - 1) * tree_view->priv->level_indentation;
+ cell_area.width -= (depth - 1) * tree_view->priv->level_indentation;
+
+ if (TREE_VIEW_DRAW_EXPANDERS(tree_view))
+ {
+ cell_area.x += depth * tree_view->priv->expander_size;
+ cell_area.width -= depth * tree_view->priv->expander_size;
+ }
}
if (gtk_tree_view_column_cell_is_visible (column))
tree_view->priv->focus_column,
&cell_area);
- if (gtk_tree_view_is_expander_column (tree_view, tree_view->priv->focus_column) && TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ if (gtk_tree_view_is_expander_column (tree_view, tree_view->priv->focus_column))
{
- cell_area.x += tree_view->priv->expander_size;
- cell_area.width -= tree_view->priv->expander_size;
+ gint depth = gtk_tree_path_get_depth (cursor_path);
+
+ cell_area.x += (depth - 1) * tree_view->priv->level_indentation;
+ cell_area.width -= (depth - 1) * tree_view->priv->level_indentation;
+
+ if (TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ {
+ cell_area.x += depth * tree_view->priv->expander_size;
+ cell_area.width -= depth * tree_view->priv->expander_size;
+ }
}
if (_gtk_tree_view_column_cell_event (tree_view->priv->focus_column,
--- /dev/null
+#include <gtk/gtk.h>
+
+
+static GtkTreeModel *
+create_model (void)
+{
+ GtkTreeStore *store;
+ GtkTreeIter iter;
+ GtkTreeIter parent;
+
+ store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+ gtk_tree_store_insert_with_values (store, &parent, NULL, 0,
+ 0, "Applications", -1);
+
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "File Manager", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "Gossip", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "System Settings", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "The GIMP", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "Terminal", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "Word Processor", -1);
+
+
+ gtk_tree_store_insert_with_values (store, &parent, NULL, 1,
+ 0, "Documents", -1);
+
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "blaat.txt", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "sliff.txt", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "test.txt", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "blaat.txt", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "brrrr.txt", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "hohoho.txt", -1);
+
+
+ gtk_tree_store_insert_with_values (store, &parent, NULL, 2,
+ 0, "Images", -1);
+
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "image1.png", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "image2.png", -1);
+ gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+ 0, "image3.jpg", -1);
+
+ return GTK_TREE_MODEL (store);
+}
+
+static void
+set_color_func (GtkTreeViewColumn *column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ if (gtk_tree_model_iter_has_child (model, iter))
+ g_object_set (cell, "cell-background", "Grey", NULL);
+ else
+ g_object_set (cell, "cell-background", NULL, NULL);
+}
+
+static void
+tree_view_row_activated (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column)
+{
+ if (gtk_tree_path_get_depth (path) > 1)
+ return;
+
+ if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (tree_view), path))
+ gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
+ else
+ gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+}
+
+static gboolean
+tree_view_select_func (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean path_currently_selected,
+ gpointer data)
+{
+ if (gtk_tree_path_get_depth (path) > 1)
+ return TRUE;
+
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window, *sw, *tv;
+ GtkTreeModel *model;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ gtk_init (&argc, &argv);
+
+ model = create_model ();
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (window, "delete_event",
+ G_CALLBACK (gtk_main_quit), NULL);
+ gtk_window_set_default_size (GTK_WINDOW (window), 320, 480);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (window), sw);
+
+ tv = gtk_tree_view_new_with_model (model);
+ gtk_container_add (GTK_CONTAINER (sw), tv);
+
+ g_signal_connect (tv, "row-activated",
+ G_CALLBACK (tree_view_row_activated), tv);
+ g_object_set (tv,
+ "show-expanders", FALSE,
+ "level-indentation", 10,
+ NULL);
+
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv), FALSE);
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (tv));
+
+ gtk_tree_selection_set_select_function (gtk_tree_view_get_selection (GTK_TREE_VIEW (tv)),
+ tree_view_select_func,
+ NULL,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("(none)",
+ renderer,
+ "text", 0,
+ NULL);
+ gtk_tree_view_column_set_cell_data_func (column,
+ renderer,
+ set_color_func,
+ NULL,
+ NULL);
+ gtk_tree_view_insert_column (GTK_TREE_VIEW (tv), column, 0);
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}