NOTE: The GtkList widget has been superseded by the GtkCList widget. It is detailed here just for completeness.
The GtkList widget is designed to act as a vertical container for widgets that should be of the type GtkListItem.
A GtkList widget has its own window to receive events and its own background color which is usually white. As it is directly derived from a GtkContainer it can be treated as such by using the GTK_CONTAINER(List) macro, see the GtkContainer widget for more on this. One should already be familiar with the usage of a GList and its related functions g_list_*() to be able to use the GtkList widget to it full extent.
There is one field inside the structure definition of the GtkList widget that will be of greater interest to us, this is:
struct _GtkList
{
...
GList *selection;
guint selection_mode;
...
};
The selection field of a GtkList points to a linked list of all items that are currently selected, or NULL if the selection is empty. So to learn about the current selection we read the GTK_LIST()->selection field, but do not modify it since the internal fields are maintained by the gtk_list_*() functions.
The selection_mode of the GtkList determines the selection facilities of a GtkList and therefore the contents of the GTK_LIST()->selection field. The selection_mode may be one of the following:
The default is GTK_SELECTION_MULTIPLE.
void selection_changed( GtkList *list );
This signal will be invoked whenever the selection field of a GtkList has changed. This happens when a child of the GtkList got selected or deselected.
void select_child( GtkList *list,
GtkWidget *child);
This signal is invoked when a child of the GtkList is about to get selected. This happens mainly on calls to gtk_list_select_item(), gtk_list_select_child(), button presses and sometimes indirectly triggered on some else occasions where children get added to or removed from the GtkList.
void unselect_child( GtkList *list,
GtkWidget *child );
This signal is invoked when a child of the GtkList is about to get deselected. This happens mainly on calls to gtk_list_unselect_item(), gtk_list_unselect_child(), button presses and sometimes indirectly triggered on some else occasions where children get added to or removed from the GtkList.
guint gtk_list_get_type( void );
Returns the `GtkList' type identifier.
GtkWidget *gtk_list_new( void );
Create a new GtkList object. The new widget is returned as a pointer to a GtkWidget object. NULL is returned on failure.
void gtk_list_insert_items( GtkList *list,
GList *items,
gint position );
Insert list items into the list, starting at position
.
items
is a doubly linked list where each nodes data pointer is
expected to point to a newly created GtkListItem. The GList nodes of
items
are taken over by the list.
void gtk_list_append_items( GtkList *list,
GList *items);
Insert list items just like gtk_list_insert_items() at the end of the
list. The GList nodes of items
are taken over by the list.
void gtk_list_prepend_items( GtkList *list,
GList *items);
Insert list items just like gtk_list_insert_items() at the very
beginning of the list. The GList nodes of items
are taken over by
the list.
void gtk_list_remove_items( GtkList *list,
GList *items);
Remove list items from the list. items
is a doubly linked list
where each nodes data pointer is expected to point to a direct child
of list. It is the callers responsibility to make a call to
g_list_free(items) afterwards. Also the caller has to destroy the list
items himself.
void gtk_list_clear_items( GtkList *list,
gint start,
gint end );
Remove and destroy list items from the list. A widget is affected if
its current position within the list is in the range specified by
start
and end
.
void gtk_list_select_item( GtkList *list,
gint item );
Invoke the select_child signal for a list item specified through its current position within the list.
void gtk_list_unselect_item( GtkList *list,
gint item);
Invoke the unselect_child signal for a list item specified through its current position within the list.
void gtk_list_select_child( GtkList *list,
GtkWidget *child);
Invoke the select_child signal for the specified child.
void gtk_list_unselect_child( GtkList *list,
GtkWidget *child);
Invoke the unselect_child signal for the specified child.
gint gtk_list_child_position( GtkList *list,
GtkWidget *child);
Return the position of child
within the list. "-1" is returned on
failure.
void gtk_list_set_selection_mode( GtkList *list,
GtkSelectionMode mode );
Set the selection mode MODE which can be of GTK_SELECTION_SINGLE, GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE or GTK_SELECTION_EXTENDED.
GtkList *GTK_LIST( gpointer obj );
Cast a generic pointer to `GtkList *'. *Note Standard Macros::, for more info.
GtkListClass *GTK_LIST_CLASS( gpointer class);
Cast a generic pointer to `GtkListClass*'. *Note Standard Macros::, for more info.
gint GTK_IS_LIST( gpointer obj);
Determine if a generic pointer refers to a `GtkList' object. *Note Standard Macros::, for more info.
Following is an example program that will print out the changes of the selection of a GtkList, and lets you "arrest" list items into a prison by selecting them with the rightmost mouse button.
/* example-start list list.c */
/* Include the gtk+ header files
* Include stdio.h, we need that for the printf() function
*/
#include <gtk/gtk.h>
#include <stdio.h>
/* This is our data identification string to store
* data in list items
*/
const gchar *list_item_data_key="list_item_data";
/* prototypes for signal handler that we are going to connect
* to the GtkList widget
*/
static void sigh_print_selection( GtkWidget *gtklist,
gpointer func_data);
static void sigh_button_event( GtkWidget *gtklist,
GdkEventButton *event,
GtkWidget *frame );
/* Main function to set up the user interface */
gint main (int argc,
gchar *argv[])
{
GtkWidget *separator;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *scrolled_window;
GtkWidget *frame;
GtkWidget *gtklist;
GtkWidget *button;
GtkWidget *list_item;
GList *dlist;
guint i;
gchar buffer[64];
/* Initialize gtk+ (and subsequently gdk) */
gtk_init(&argc, &argv);
/* Create a window to put all the widgets in
* connect gtk_main_quit() to the "destroy" event of
* the window to handle window manager close-window-events
*/
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "GtkList Example");
gtk_signal_connect(GTK_OBJECT(window),
"destroy",
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);
/* Inside the window we need a box to arrange the widgets
* vertically */
vbox=gtk_vbox_new(FALSE, 5);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
/* This is the scrolled window to put the GtkList widget inside */
scrolled_window=gtk_scrolled_window_new(NULL, NULL);
gtk_widget_set_usize(scrolled_window, 250, 150);
gtk_container_add(GTK_CONTAINER(vbox), scrolled_window);
gtk_widget_show(scrolled_window);
/* Create the GtkList widget.
* Connect the sigh_print_selection() signal handler
* function to the "selection_changed" signal of the GtkList
* to print out the selected items each time the selection
* has changed */
gtklist=gtk_list_new();
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
gtklist);
gtk_widget_show(gtklist);
gtk_signal_connect(GTK_OBJECT(gtklist),
"selection_changed",
GTK_SIGNAL_FUNC(sigh_print_selection),
NULL);
/* We create a "Prison" to put a list item in ;) */
frame=gtk_frame_new("Prison");
gtk_widget_set_usize(frame, 200, 50);
gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
gtk_container_add(GTK_CONTAINER(vbox), frame);
gtk_widget_show(frame);
/* Connect the sigh_button_event() signal handler to the GtkList
* which will handle the "arresting" of list items
*/
gtk_signal_connect(GTK_OBJECT(gtklist),
"button_release_event",
GTK_SIGNAL_FUNC(sigh_button_event),
frame);
/* Create a separator */
separator=gtk_hseparator_new();
gtk_container_add(GTK_CONTAINER(vbox), separator);
gtk_widget_show(separator);
/* Finally create a button and connect its "clicked" signal
* to the destruction of the window */
button=gtk_button_new_with_label("Close");
gtk_container_add(GTK_CONTAINER(vbox), button);
gtk_widget_show(button);
gtk_signal_connect_object(GTK_OBJECT(button),
"clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(window));
/* Now we create 5 list items, each having its own
* label and add them to the GtkList using gtk_container_add()
* Also we query the text string from the label and
* associate it with the list_item_data_key for each list item
*/
for (i=0; i<5; i++) {
GtkWidget *label;
gchar *string;
sprintf(buffer, "ListItemContainer with Label #%d", i);
label=gtk_label_new(buffer);
list_item=gtk_list_item_new();
gtk_container_add(GTK_CONTAINER(list_item), label);
gtk_widget_show(label);
gtk_container_add(GTK_CONTAINER(gtklist), list_item);
gtk_widget_show(list_item);
gtk_label_get(GTK_LABEL(label), &string);
gtk_object_set_data(GTK_OBJECT(list_item),
list_item_data_key,
string);
}
/* Here, we are creating another 5 labels, this time
* we use gtk_list_item_new_with_label() for the creation
* we can't query the text string from the label because
* we don't have the labels pointer and therefore
* we just associate the list_item_data_key of each
* list item with the same text string.
* For adding of the list items we put them all into a doubly
* linked list (GList), and then add them by a single call to
* gtk_list_append_items().
* Because we use g_list_prepend() to put the items into the
* doubly linked list, their order will be descending (instead
* of ascending when using g_list_append())
*/
dlist=NULL;
for (; i<10; i++) {
sprintf(buffer, "List Item with Label %d", i);
list_item=gtk_list_item_new_with_label(buffer);
dlist=g_list_prepend(dlist, list_item);
gtk_widget_show(list_item);
gtk_object_set_data(GTK_OBJECT(list_item),
list_item_data_key,
"ListItem with integrated Label");
}
gtk_list_append_items(GTK_LIST(gtklist), dlist);
/* Finally we want to see the window, don't we? ;) */
gtk_widget_show(window);
/* Fire up the main event loop of gtk */
gtk_main();
/* We get here after gtk_main_quit() has been called which
* happens if the main window gets destroyed
*/
return(0);
}
/* This is the signal handler that got connected to button
* press/release events of the GtkList
*/
void sigh_button_event( GtkWidget *gtklist,
GdkEventButton *event,
GtkWidget *frame )
{
/* We only do something if the third (rightmost mouse button
* was released
*/
if (event->type==GDK_BUTTON_RELEASE &&
event->button==3) {
GList *dlist, *free_list;
GtkWidget *new_prisoner;
/* Fetch the currently selected list item which
* will be our next prisoner ;)
*/
dlist=GTK_LIST(gtklist)->selection;
if (dlist)
new_prisoner=GTK_WIDGET(dlist->data);
else
new_prisoner=NULL;
/* Look for already imprisoned list items, we
* will put them back into the list.
* Remember to free the doubly linked list that
* gtk_container_children() returns
*/
dlist=gtk_container_children(GTK_CONTAINER(frame));
free_list=dlist;
while (dlist) {
GtkWidget *list_item;
list_item=dlist->data;
gtk_widget_reparent(list_item, gtklist);
dlist=dlist->next;
}
g_list_free(free_list);
/* If we have a new prisoner, remove him from the
* GtkList and put him into the frame "Prison".
* We need to unselect the item first.
*/
if (new_prisoner) {
GList static_dlist;
static_dlist.data=new_prisoner;
static_dlist.next=NULL;
static_dlist.prev=NULL;
gtk_list_unselect_child(GTK_LIST(gtklist),
new_prisoner);
gtk_widget_reparent(new_prisoner, frame);
}
}
}
/* This is the signal handler that gets called if GtkList
* emits the "selection_changed" signal
*/
void sigh_print_selection( GtkWidget *gtklist,
gpointer func_data)
{
GList *dlist;
/* Fetch the doubly linked list of selected items
* of the GtkList, remember to treat this as read-only!
*/
dlist=GTK_LIST(gtklist)->selection;
/* If there are no selected items there is nothing more
* to do than just telling the user so
*/
if (!dlist) {
g_print("Selection cleared\n");
return;
}
/* Ok, we got a selection and so we print it
*/
g_print("The selection is a ");
/* Get the list item from the doubly linked list
* and then query the data associated with list_item_data_key.
* We then just print it */
while (dlist) {
GtkObject *list_item;
gchar *item_data_string;
list_item=GTK_OBJECT(dlist->data);
item_data_string=gtk_object_get_data(list_item,
list_item_data_key);
g_print("%s ", item_data_string);
dlist=dlist->next;
}
g_print("\n");
}
/* example-end */
The GtkListItem widget is designed to act as a container holding up to one child, providing functions for selection/deselection just like the GtkList widget requires them for its children.
A GtkListItem has its own window to receive events and has its own background color which is usually white.
As it is directly derived from a GtkItem it can be treated as such by using the GTK_ITEM(ListItem) macro, see the GtkItem widget for more on this. Usually a GtkListItem just holds a label to identify e.g. a filename within a GtkList -- therefore the convenience function gtk_list_item_new_with_label() is provided. The same effect can be achieved by creating a GtkLabel on its own, setting its alignment to xalign=0 and yalign=0.5 with a subsequent container addition to the GtkListItem.
As one is not forced to add a GtkLabel to a GtkListItem, you could also add a GtkVBox or a GtkArrow etc. to the GtkListItem.
A GtkListItem does not create new signals on its own, but inherits the signals of a GtkItem. *Note GtkItem::, for more info.
guint gtk_list_item_get_type( void );
Returns the `GtkListItem' type identifier.
GtkWidget *gtk_list_item_new( void );
Create a new GtkListItem object. The new widget is returned as a pointer to a GtkWidget object. NULL is returned on failure.
GtkWidget *gtk_list_item_new_with_label( gchar *label );
Create a new GtkListItem object, having a single GtkLabel as the sole child. The new widget is returned as a pointer to a GtkWidget object. NULL is returned on failure.
void gtk_list_item_select( GtkListItem *list_item );
This function is basically a wrapper around a call to gtk_item_select (GTK_ITEM (list_item)) which will emit the select signal. *Note GtkItem::, for more info.
void gtk_list_item_deselect( GtkListItem *list_item );
This function is basically a wrapper around a call to gtk_item_deselect (GTK_ITEM (list_item)) which will emit the deselect signal. *Note GtkItem::, for more info.
GtkListItem *GTK_LIST_ITEM( gpointer obj );
Cast a generic pointer to `GtkListItem*'. *Note Standard Macros::, for more info.
GtkListItemClass *GTK_LIST_ITEM_CLASS( gpointer class );
Cast a generic pointer to GtkListItemClass*. *Note Standard Macros::, for more info.
gint GTK_IS_LIST_ITEM( gpointer obj );
Determine if a generic pointer refers to a `GtkListItem' object. *Note Standard Macros::, for more info.
Please see the GtkList example on this, which covers the usage of a GtkListItem as well.