treeview-tutorial-xml/examples/simple-list/list.c

232 lines
5.9 KiB
C

#include <gtk/gtk.h>
enum
{
COL_TEXT = 0,
NUM_COLS
};
static GtkWidget *treeview;
static GtkWidget *delbutton;
/**************************************************************************
*
* onAddButtonPress
*
* Button has been clicked, or <enter> has been hit in entry
*
**************************************************************************/
static void
onAddButtonPress (GtkWidget *entry, gpointer data)
{
const gchar *txt;
g_assert(GTK_IS_ENTRY(entry));
txt = gtk_entry_get_text(GTK_ENTRY(entry));
/* ignore if entry is empty */
if (txt && *txt)
{
GtkTreeModel *model;
GtkTreeIter newrow;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
gtk_list_store_append(GTK_LIST_STORE(model), &newrow);
gtk_list_store_set(GTK_LIST_STORE(model), &newrow, COL_TEXT, txt, -1);
gtk_entry_set_text(GTK_ENTRY(entry), ""); /* clear entry */
}
}
/**************************************************************************
*
* onDelButtonPress
*
**************************************************************************/
static void
onDelButtonPress (GtkWidget *button, gpointer data)
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter selected_row;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
g_assert(gtk_tree_selection_get_mode(sel) == GTK_SELECTION_SINGLE);
if (gtk_tree_selection_get_selected(sel, &model, &selected_row))
{
gtk_list_store_remove(GTK_LIST_STORE(model), &selected_row);
}
else
{
/* If no row is selected, the button should
* not be clickable in the first place */
g_assert_not_reached();
}
}
/**************************************************************************
*
* onSelectionChanged
*
* Sets 'delete selected row' button active or inactive, depending
* on whether a row is selected or not. This function is called
* whenever the selection changes.
*
**************************************************************************/
static void
onSelectionChanged (GtkTreeSelection *sel, GtkListStore *liststore)
{
GtkTreeIter selected_row;
/* Check if a row is selected or not */
/* This will only work in SINGLE or BROWSE mode! */
if (gtk_tree_selection_get_selected(sel, NULL, &selected_row))
{
gtk_widget_set_sensitive(delbutton, TRUE);
}
else
{
gtk_widget_set_sensitive(delbutton, FALSE);
}
}
/**************************************************************************
*
* create_list_view
*
* sets up the tree view and returns a GtkTreeView widget
*
**************************************************************************/
static GtkWidget *
create_list_view (void)
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *col;
GtkTreeSelection *sel;
GtkListStore *liststore;
GtkWidget *view;
liststore = gtk_list_store_new(NUM_COLS, G_TYPE_STRING); /* NUM_COLS = 1 */
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
renderer = gtk_cell_renderer_text_new();
col = gtk_tree_view_column_new();
gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_TEXT);
gtk_tree_view_column_set_title(col, " Your items here ");
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
g_signal_connect(sel, "changed", G_CALLBACK(onSelectionChanged), liststore);
return view;
}
/**************************************************************************
*
* create_entry_hbox
*
* Returns GtkHBox widget with entry and button inside
*
**************************************************************************/
static GtkWidget *
create_entry_hbox (void)
{
GtkWidget *addbutton;
GtkWidget *entry;
GtkWidget *hbox;
hbox = gtk_hbox_new(FALSE, 2);
/* when 'return' is pressed, add text to list
* just as if the button had been pressed */
entry = gtk_entry_new();
g_signal_connect(entry, "activate", G_CALLBACK(onAddButtonPress), NULL);
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
addbutton = gtk_button_new_with_label(" Add text to list ");
/* using _swapped, so that the first argument to the callback
* is what we specify as 'data' argument here, ie. the entry,
* and data argument to callback is what is the object to
* connect to here, ie. the button */
g_signal_connect_swapped(addbutton, "clicked", G_CALLBACK(onAddButtonPress), entry);
gtk_box_pack_start(GTK_BOX(hbox), addbutton, FALSE, FALSE, 0);
delbutton = gtk_button_new_with_label(" Remove selected row ");
g_signal_connect(delbutton, "clicked", G_CALLBACK(onDelButtonPress), NULL);
gtk_box_pack_start(GTK_BOX(hbox), delbutton, FALSE, FALSE, 0);
/* at beginning no rows, so nothing to delete */
gtk_widget_set_sensitive(delbutton, FALSE);
return hbox;
}
/**************************************************************************
*
* main
*
**************************************************************************/
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *scrollwin;
GtkWidget *tophbox;
GtkWidget *vbox;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect(window, "delete_event", gtk_main_quit, NULL); /* dirty */
vbox = gtk_vbox_new(FALSE, 2);
tophbox = create_entry_hbox();
gtk_box_pack_start(GTK_BOX(vbox), tophbox, FALSE, FALSE, 0);
scrollwin = gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
treeview = create_list_view();
gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
gtk_box_pack_start(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show_all(window);
gtk_main();
return 0;
}