Files
evolution/e-util/test-tree-view-frame.c
Matthew Barnes 9ae72cb11c Add ETreeViewFrame.
ETreeViewFrame embeds a GtkTreeView in a scrolled window and adds an
inline-style toolbar beneath the scrolled window which can be hidden.

The inline-style toolbar supports "add" and "remove" actions, as well
as move actions if the tree view is reorderable and selection actions
if the tree view supports multiple selections.  The action set can be
extended through e_tree_view_frame_insert_toolbar_action().

This also adds a small demo program: test-tree-view-frame
2013-06-25 14:44:11 -04:00

376 lines
9.8 KiB
C

#include <gtk/gtk.h>
#include <libedataserver/libedataserver.h>
#include "e-tree-view-frame.h"
static GtkTreeView *tree_view;
static ETreeViewFrame *tree_view_frame;
static gboolean
delete_event_cb (GtkWidget *widget,
GdkEvent *event)
{
gtk_main_quit ();
return TRUE;
}
static void
action_add_cb (ETreeViewFrame *tree_view_frame,
GtkAction *action)
{
GtkTreeView *tree_view;
GtkTreeModel *tree_model;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreePath *path;
GtkTreeIter iter;
GList *list;
tree_view = e_tree_view_frame_get_tree_view (tree_view_frame);
tree_model = gtk_tree_view_get_model (tree_view);
gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
path = gtk_tree_model_get_path (tree_model, &iter);
column = gtk_tree_view_get_column (tree_view, 0);
list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
renderer = GTK_CELL_RENDERER (list->data);
g_list_free (list);
g_object_set (renderer, "editable", TRUE, NULL);
gtk_tree_view_set_cursor_on_cell (
tree_view, path, column, renderer, TRUE);
g_object_set (renderer, "editable", FALSE, NULL);
gtk_tree_path_free (path);
}
static void
action_remove_cb (ETreeViewFrame *tree_view_frame,
GtkAction *action)
{
GtkTreeView *tree_view;
GtkTreeModel *tree_model;
GtkTreeSelection *selection;
GtkListStore *list_store;
GList *list, *link;
tree_view = e_tree_view_frame_get_tree_view (tree_view_frame);
selection = gtk_tree_view_get_selection (tree_view);
list = gtk_tree_selection_get_selected_rows (selection, &tree_model);
/* Reverse the list so we don't invalidate paths. */
list = g_list_reverse (list);
list_store = GTK_LIST_STORE (tree_model);
for (link = list; link != NULL; link = g_list_next (link)) {
GtkTreePath *path = link->data;
GtkTreeIter iter;
if (gtk_tree_model_get_iter (tree_model, &iter, path))
gtk_list_store_remove (list_store, &iter);
}
g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
}
static void
update_toolbar_actions_cb (ETreeViewFrame *tree_view_frame)
{
GtkAction *action;
GtkTreeView *tree_view;
GtkTreeSelection *selection;
gint n_selected_rows;
tree_view = e_tree_view_frame_get_tree_view (tree_view_frame);
selection = gtk_tree_view_get_selection (tree_view);
n_selected_rows = gtk_tree_selection_count_selected_rows (selection);
action = e_tree_view_frame_lookup_toolbar_action (
tree_view_frame, E_TREE_VIEW_FRAME_ACTION_REMOVE);
gtk_action_set_sensitive (action, n_selected_rows > 0);
}
static void
cell_edited_cb (GtkCellRendererText *renderer,
const gchar *path_string,
const gchar *new_text,
GtkTreeView *tree_view)
{
GtkTreeModel *tree_model;
GtkTreePath *path;
GtkTreeIter iter;
path = gtk_tree_path_new_from_string (path_string);
tree_model = gtk_tree_view_get_model (tree_view);
gtk_tree_model_get_iter (tree_model, &iter, path);
gtk_list_store_set (
GTK_LIST_STORE (tree_model), &iter, 0, new_text, -1);
gtk_tree_path_free (path);
}
static void
editing_canceled_cb (GtkCellRenderer *renderer,
GtkTreeView *tree_view)
{
GtkTreeModel *tree_model;
GtkTreePath *path;
GtkTreeIter iter;
gtk_tree_view_get_cursor (tree_view, &path, NULL);
tree_model = gtk_tree_view_get_model (tree_view);
gtk_tree_model_get_iter (tree_model, &iter, path);
gtk_list_store_remove (GTK_LIST_STORE (tree_model), &iter);
gtk_tree_path_free (path);
}
static void
build_tree_view (void)
{
GtkListStore *list_store;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeIter iter;
guint ii;
/* Somebody's a child of the 80's */
const gchar *items[] = {
"Cherry",
"Strawberry",
"Peach",
"Pretzel",
"Apple",
"Pear",
"Banana"
};
tree_view = (GtkTreeView *) gtk_tree_view_new ();
gtk_tree_view_set_headers_visible (tree_view, FALSE);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (
"Bonus Item", renderer, "text", 0, NULL);
gtk_tree_view_append_column (tree_view, column);
g_signal_connect (
renderer, "edited",
G_CALLBACK (cell_edited_cb), tree_view);
g_signal_connect (
renderer, "editing-canceled",
G_CALLBACK (editing_canceled_cb), tree_view);
list_store = gtk_list_store_new (1, G_TYPE_STRING);
for (ii = 0; ii < G_N_ELEMENTS (items); ii++) {
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter, 0, items[ii], -1);
}
gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
g_object_unref (list_store);
}
static void
build_test_window (void)
{
GtkTreeSelection *selection;
GtkWidget *widget;
GtkWidget *container;
GtkWidget *grid;
const gchar *text;
selection = gtk_tree_view_get_selection (tree_view);
widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (widget), 500, 300);
gtk_window_set_title (GTK_WINDOW (widget), "ETreeViewFrame");
gtk_widget_show (widget);
g_signal_connect (
widget, "delete-event",
G_CALLBACK (delete_event_cb), NULL);
container = widget;
widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (widget), 12);
gtk_container_add (GTK_CONTAINER (container), widget);
gtk_widget_show (widget);
container = widget;
widget = e_tree_view_frame_new ();
e_tree_view_frame_set_tree_view (
E_TREE_VIEW_FRAME (widget), tree_view);
gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
gtk_widget_show (widget);
tree_view_frame = E_TREE_VIEW_FRAME (widget);
widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
container = widget;
text = "Inline toolbar is visible";
widget = gtk_check_button_new_with_label (text);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
g_object_bind_property (
tree_view_frame, "toolbar-visible",
widget, "active",
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE);
text = "Tree view is reorderable";
widget = gtk_check_button_new_with_label (text);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
g_object_bind_property (
tree_view, "reorderable",
widget, "active",
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE);
gtk_widget_set_margin_bottom (widget, 6);
widget = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
gtk_widget_set_margin_bottom (widget, 6);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
grid = widget;
widget = gtk_label_new ("Tree view selection mode:");
gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
gtk_widget_set_halign (GTK_WIDGET (widget), GTK_ALIGN_END);
gtk_grid_attach (GTK_GRID (grid), widget, 0, 0, 1, 1);
gtk_widget_show (widget);
widget = gtk_combo_box_text_new ();
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"none", "None");
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"single", "Single");
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"browse", "Browse");
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"multiple", "Multiple");
gtk_grid_attach (GTK_GRID (grid), widget, 1, 0, 1, 1);
gtk_widget_show (widget);
g_object_bind_property_full (
selection, "mode",
widget, "active-id",
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE,
e_binding_transform_enum_value_to_nick,
e_binding_transform_enum_nick_to_value,
NULL, (GDestroyNotify) NULL);
widget = gtk_label_new ("Horizontal scrollbar policy:");
gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
gtk_widget_set_halign (GTK_WIDGET (widget), GTK_ALIGN_END);
gtk_grid_attach (GTK_GRID (grid), widget, 0, 1, 1, 1);
gtk_widget_show (widget);
widget = gtk_combo_box_text_new ();
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"always", "Always");
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"automatic", "Automatic");
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"never", "Never");
gtk_grid_attach (GTK_GRID (grid), widget, 1, 1, 1, 1);
gtk_widget_show (widget);
g_object_bind_property_full (
tree_view_frame, "hscrollbar-policy",
widget, "active-id",
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE,
e_binding_transform_enum_value_to_nick,
e_binding_transform_enum_nick_to_value,
NULL, (GDestroyNotify) NULL);
widget = gtk_label_new ("Vertical scrollbar policy:");
gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
gtk_widget_set_halign (GTK_WIDGET (widget), GTK_ALIGN_END);
gtk_grid_attach (GTK_GRID (grid), widget, 0, 2, 1, 1);
gtk_widget_show (widget);
widget = gtk_combo_box_text_new ();
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"always", "Always");
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"automatic", "Automatic");
gtk_combo_box_text_append (
GTK_COMBO_BOX_TEXT (widget),
"never", "Never");
gtk_grid_attach (GTK_GRID (grid), widget, 1, 2, 1, 1);
gtk_widget_show (widget);
g_object_bind_property_full (
tree_view_frame, "vscrollbar-policy",
widget, "active-id",
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE,
e_binding_transform_enum_value_to_nick,
e_binding_transform_enum_nick_to_value,
NULL, (GDestroyNotify) NULL);
g_signal_connect (
tree_view_frame,
"toolbar-action-activate::"
E_TREE_VIEW_FRAME_ACTION_ADD,
G_CALLBACK (action_add_cb), NULL);
g_signal_connect (
tree_view_frame,
"toolbar-action-activate::"
E_TREE_VIEW_FRAME_ACTION_REMOVE,
G_CALLBACK (action_remove_cb), NULL);
g_signal_connect (
tree_view_frame, "update-toolbar-actions",
G_CALLBACK (update_toolbar_actions_cb), NULL);
e_tree_view_frame_update_toolbar_actions (tree_view_frame);
}
gint
main (gint argc,
gchar **argv)
{
gtk_init (&argc, &argv);
build_tree_view ();
build_test_window ();
gtk_main ();
return 0;
}