The List widget is designed to act as a vertical container for widgets that should be of the type ListItem. A List widget has its own window to receive events and its own background color which is usually white.
In order to keep from confusing you, a List (capitalized) refers to a Gtk::List widget, while a list (lowercase) refers to a Perl list (which may also be referred to, somewhat inaccurately, as arrays).
There is two fields inside the structure definition of the List widget that will be of great interest to us, they are selection and selection_mode .
The selection field of a List is a list of all items that are currently selected, or the empty list if the selection is empty. So to learn about the current selection we read the selection field, but do not modify it since the internal fields are maintained by the List functions.
The selection_mode of the List determines the selection facilities of a List and therefore the contents of the selection field. The selection_mode may be one of the following:
'single' - The selection is either empty or its list contains a single selected item.
'browse' - The selection is empty if the list contains no widgets or insensitive ones only, otherwise it contains a list with one list item.
'multiple' - The selection is empty if no list items are selected or list of all the selected items.
'extended' - Any number of elements may be selected. Click-drag selects a range of elements. The Ctrl key may be used to enlarge the selection, and Shift key to select between the focus and the child pointed to.
The default is 'multiple'.
The 'selection changed' signal will be invoked whenever the selection field of a List has changed. This happens when a child of the List got selected or deselected.
The 'select_child' signal is invoked when a child of the List is about to get selected. This happens mainly on calls to select_item(), select_child(), button presses and sometimes indirectly triggered on some else occasions where children get added to or removed from the List.
The 'unselect_child' signal is invoked when a child of the List is about to get deselected. This happens mainly on calls to unselect_item(), unselect_child(), button presses and sometimes indirectly triggered on occassions where children get added to or removed from the List.
To create a new List, use:
$list = new Gtk::List();
Items may be added to the List using:
$list->insert_items( @items, $position );
where
@items
is the list of items to add, and
$position
is the starting position of the items.
You can also append and prepend items to the List using:
$list->append_items( @items );
$list->prepend_items( @items );
To remove items from the list, use:
$list->remove_items( @items );
Where
@items
is a list of the items you want removed.
You can also remove a range of items using:
$list->clear_items( $start, $end );
Items can be selected using:
$list->select_item( $index );
$list->select_child( $child );
which will also invoke either the
'select_item'
or the
'select_child'
signal on the list item.
Unselecting works in a similar way:
$list->unselect_item( $index );
$list->unselect_child( $child );
If you want the index for a List child, use:
$index = $list->child_position( $child );
If a failure occurs, a value of
-1
is returned.
The selection mode can be set using:
$list->set_selection_mode( $mode );
Where
$mode
can be
'single',
'browse',
'multiple', or
'extended'.
Object
+--- Widget
+--- Container
+--- Bin
+--- Item
+--- ListItem
The ListItem widget is designed to act as a container holding up to one child, providing functions for selection/deselection just like the List widget requires them for its children.
A ListItem has its own window to receive events and has its own background color which is usually white.
As it is directly derived from an Item it can be treated as such. See the Item widget for more on this. Usually a ListItem just holds a label to identify, e.g., a filename within a List -- therefore the convenience function new_with_label() is provided. The same effect can be achieved by creating a Label on its own, setting its alignment to xalign=0 and yalign=0.5 with a subsequent container addition to the ListItem.
As one is not forced to add a GtkLabel to a GtkListItem, you could also add another widget (such as GtkVBox, GtkArrow, etc.) to the GtkListItem.
To create a ListItem, call one of the following functions:
$item = new Gtk::ListItem();
$item = new Gtk::ListItem( $label );
If you send a string as an argument, it creates the ListItem
with a Label as the sole child of the ListItem.
To select a ListItem:
$item->select();
which will also emit the
'select'
signal on the ListItem.
Following is an example program that will print out the changes of the selection of a List, and lets you "arrest" list items into a prison by selecting them with the rightmost mouse button.
#!/usr/bin/perl -w use Gtk ; use strict ; set_locale Gtk; init Gtk; my $false = 0; my $true = 1; my $separator; my $window; my $vbox; my $scrolled_window; my $frame; my $gtklist; my $button; my $list_item; my $buffer; # Create the window $window = new Gtk::Window( 'toplevel' ); $window->set_title( "List Example" ); $window->signal_connect( 'destroy', sub { Gtk-> exit ( 0 ); } ); # Inside the window we need a box to arrange the widgets vertically $vbox = new Gtk::VBox( $false, 5 ); $vbox->set_border_width( 5 ); $window->add( $vbox ); $vbox->show(); # This is the scrolled window to put the List widget inside $scrolled_window = new Gtk::ScrolledWindow( undef, undef ); $scrolled_window->set_usize( 250, 150 ); $vbox->add( $scrolled_window ); $scrolled_window->show(); # Create the List widget. Connect the sigh_print_selection() signal handler # function to the "selection_changed" signal of the List to print out the # selected items each time the selection has changed. $gtklist = new Gtk::List(); $scrolled_window->add_with_viewport( $gtklist ); $gtklist->show(); $gtklist->signal_connect( 'selection_changed', \&sigh_print_selection ); # We create a "Prison" to put a list item in ;) $frame = new Gtk::Frame( "Prison" ); $frame->set_usize( 200, 50 ); $frame->set_border_width( 5 ); $frame->set_shadow_type( 'out' ); $vbox->add( $frame ); $frame->show(); # Connect the sigh_button_event() signal handler to the List, which will # handle the "arresting" of list items. $gtklist->signal_connect( 'button_release_event', \&sigh_button_event, $frame ); # Create a separator $separator = new Gtk::HSeparator(); $vbox->add( $separator ); $separator->show(); # Finally create a button and connect its "clicked" signal to the # destruction of the window $button = new Gtk::Button( "Close" ); $vbox->add( $button ); $button->show(); $button->signal_connect( 'clicked', sub { $window->destroy(); } ); # Now we create 5 list items, each having its own label and add them to # the List using add(). for my $i ( 0..4 ) { my $label; my $string; $buffer = "ListItemContainer with Label #" . $i; $label = new Gtk::Label( $buffer ); $list_item = new Gtk::ListItem(); $list_item->add( $label ); $label->show(); $gtklist->add( $list_item ); $list_item->show(); $string = $label->get(); } # Here, we are creating another 5 labels, this time sending the label to # the new() function. for my $i ( 5..9 ) { $buffer = "List Item with Label $i"; $list_item = new Gtk::ListItem( $buffer ); $gtklist->add( $list_item ); $list_item->show(); } # Finally we want to see the window, don't we? ;) $window->show(); # Fire up the main event loop of gtk main Gtk; exit ( 0 ); ### Subroutines # This is the signal handler that got connected to button press/release # events of the List sub sigh_button_event { my ( $gtklist, $frame, $event ) = @_; # We only do something if the third (rightmost mouse button) # was released if ( ( defined( $event->{ 'type' } ) ) and ( defined( $event->{ 'button' } ) ) and ( $event->{ 'type' } eq 'button_release' ) and ( $event->{ 'button' } == 3 ) ) { my @dlist = $gtklist->selection; my $new_prisoner = $dlist[0]; my $list_item; # Look for already imprisoned list items, we will put them back # into the list. foreach $list_item ( $frame->children() ) { $list_item->reparent( $gtklist ); } # If we have a new prisoner, remove him from the List and put him # into the frame "Prison". We need to unselect the item first. if ( $new_prisoner ) { $gtklist->unselect_child( $new_prisoner ); $new_prisoner->reparent( $frame ); } } return $true; } # This is the signal handler that gets called if List emits the # "selection_changed" signal sub sigh_print_selection { my ( $gtklist ) = @_; # Fetch the currently selected list item which will be our next # prisoner my @dlist = $gtklist->selection; # If there are no selected items there is nothing more to do than # just telling the user so unless ( @dlist ) { print "Selection cleared\n"; } } # END EXAMPLE PROGRAM
List Example Screenshot