Chapter 35. List Widget

Table of Contents
35.1. List Widget
35.2. List Item Widget
35.3. List Example

Inheritance Hierarchy

Object
   +--- Widget
         +--- Container
               +--- List
         

35.1. List Widget

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:

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'.

35.2. List Item Widget

Inheritance Hierarchy

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.

Deselecting works in a similar fashion:

$item->deselect();

35.3. List Example

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.

List Example Source

      
#!/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