Chapter 48. Paned Window Widgets

Inheritance Hierarchy

Object
   +--- Widget
         +--- Container
               +--- Paned
         

The paned window widgets are useful when you want to divide an area into two parts, with the relative size of the two parts controlled by the user. A groove is drawn between the two portions with a handle that the user can drag to change the ratio. The division can either be horizontal (the HPaned widget) or vertical (the VPaned widget).

To create a new paned window, call one of:

$paned = new Gtk::HPaned();

$paned = new Gtk::VPaned();

After creating the paned window widget, you need to add child widgets to its two halves. To do this, use one of the the following sets of functions:

$paned->pack1( $child, $resize, $shrink );
$paned->add1( $child );

$paned->pack2( $child, $resize, $shrink );
$paned->add2( $child );

add1() and pack1() adds the child widget to the left or top half of the paned window. add2() and pack2() adds the child widget to the right or bottom half of the paned window.

The $resize argument specifies whether the child should expand when the paned widget is resized, and the $shrink argument specifies whether the child can be made smaller than its requested size.

The add1() function is equivelent to calling

$paned->pack1( $child, $false, $true );

And the add2() function is equivelent to calling

$paned->pack2( $child, $false, $false );

A paned widget can be changed visually using the following two functions.

$paned->set_handle_size( $size );

$paned->set_gutter_size( $size );

The first of these sets the size of the handle and the second sets the size of the gutter that is between the two parts of the paned window.

48.1. Paned Window Example

As an example, we will create part of the user interface of an imaginary email program. A window is divided into two portions vertically, with the top portion being a list of email messages and the bottom portion the text of the email message. Most of the program is pretty straightforward. A couple of points to note: text can't be added to a Text widget until it is realized. This could be done by calling realize(), but as a demonstration of an alternate technique, we connect a handler to the 'realize' signal to add the text. Also, we need to add the 'shrink' option to some of the items in the table containing the text window and its scrollbars, so that when the bottom portion is made smaller, the correct portions shrink instead of being pushed off the bottom of the window.

Paned Window Example Source

      
#!/usr/bin/perl -w

use 
Gtk
;
use 
strict
;

set_locale Gtk;
init Gtk;


my
 $false = 0;

my
 $true = 1;


my
 $window;

my
 $paned;

my
 $list;

my
 $text;


# Create the window
$window = new Gtk::Window( "toplevel" );
$window->set_title( "Paned Windows" );
$window->signal_connect( "destroy", 
sub
 { Gtk->
exit
( 0 ); } );
$window->border_width( 10 );
$window->set_usize( 450, 400 );

# create a vpaned widget and add it to our toplevel window
$paned = new Gtk::VPaned();
$window->add( $paned );
$paned->set_handle_size( 10 );
$paned->set_gutter_size( 15 );
$paned->show();

# Now create the contents of the two halves of the window
$list = create_list();
$paned->add1( $list );
$list->show();

# Create the text area.
$text = create_text();
$paned->add2( $text );
$text->show();
$window->show();

main Gtk;

exit
( 0 );



### Subroutines


# Create a list of messages and return it


sub
 
create_list

{
   
my
 $scrolled_window;
   
my
 $list;
   
my
 $list_item;

   
my
 @buffer;

   # Create a new scrolled window, with scrollbars only if needed
   $scrolled_window = new Gtk::ScrolledWindow( "
", "
" );
   $scrolled_window->set_policy( 'automatic', 'automatic' );

   # Create a new list and put it in the scrolled window
   $list = new Gtk::List();
   $scrolled_window->add_with_viewport( $list );
   $list->show();

   # Add some messages to the window
   
for
 
my
 $i ( 0..9 )
   {
      $buffer[ $i ] = "Message \#" . $i;
      $list_item = new Gtk::ListItem( $buffer[ $i ] );
      $list->add( $list_item );
      $list_item->show();
   }

   
return
 ( $scrolled_window );
}


# Add some text to our text widget - this is a callback that is invoked
# when our window is realized. We could also force our window to be
# realized with gtk_widget_realize, but it would have to be part of
# a hierarchy first


sub
 
realize_text

{
   
my
 ( $text ) = @_;

   $text->freeze();
   $text->insert( "
", $text->style->black, $text->style->white,
		  "From: pathfinder\@nasa.gov\n" .
		  "To: mom\@nasa.gov\n" .
		  "Subject: Made it!\n" .
		  "\n" .
		  "We just got in this morning. The weather has been\n" .
		  "great - clear but cold, and there are lots of fun\n" .
		  "sights.\n" .
		  "Sojourner says hi. See you soon.\n" .
		  " -Path\n" );

   $text->thaw();
}


# Create a scrolled text area that displays a "message"


sub
 
create_text

{
   
my
 $table;
   
my
 $text;
   
my
 $hscrollbar;
   
my
 $vscrollbar;

   # Create a table to hold the text widget and scrollbars
   $table = new Gtk::Table( 2, 2, $false );

   # Put a text widget in the upper left hand corner. Note the use of
   # 'shrink' in the y direction
   $text = new Gtk::Text( "
", "
" );
   $table->attach( $text, 0, 1, 0, 1,
		   [ 'fill', 'expand' ],
		   [ 'fill', 'expand', 'shrink' ],
		   0, 0 );
   $text->show();

   # Put a HScrollbar in the lower left hand corner
   $hscrollbar = new Gtk::HScrollbar( $text->hadj );
   $table->attach( $hscrollbar, 0, 1, 1, 2,
		   [ 'expand', 'fill' ],
		   'fill', 0, 0 );
   $hscrollbar->show();

   # And a VScrollbar in the upper right
   $vscrollbar = new Gtk::VScrollbar( $text->vadj );
   $table->attach( $vscrollbar, 1, 2, 0, 1, 'fill',
		   [ 'expand', 'fill', 'shrink' ], 0, 0 );
   $vscrollbar->show();

   # Add a handler to put a message in the text widget when it is realized
   $text->signal_connect( "realize", \&realize_text );

   
return
 ( $table );
}


# END EXAMPLE PROGRAM
      
   

Paned Example Screenshot