11.7. Paned Window Widgets

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 (HPaned) or vertical (VPaned).

To create a new paned window, call one of:

Gtk::HPaned.new
Gtk::VPaned.new

After creating the paned window widget, you need to add child widgets to its two halves. To do this, use the methods:

Gtk::Paned#add1 ( child )
Gtk::Paned#add2 ( child )

Gtk::Paned#add1 adds the child widget to the left or top half of the paned window. Gtk::Paned#add2 adds the child widget to the right or bottom half of the paned window.

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. Also, we need to add the Gtk::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.

require 'gtk2'

def create_list
   
   # Create a new scrolled window, with the scrollbars only if needed
   scrolled_window = Gtk::ScrolledWindow.new( nil, nil )
   scrolled_window.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC )
   
   # This is a mini-monster of a widget. It will be tackled in the API
   # someday. For now, just copy and paste :)
   model = Gtk::ListStore.new( String )
   column = Gtk::TreeViewColumn.new("Messages", Gtk::CellRendererText.new, {:text => 0} )
   tree_view = Gtk::TreeView.new( model )
   scrolled_window.add_with_viewport( tree_view )

   messages = []
   # Add some messages to the window
   for i in 0..9
      msg = "Message " << (i + 1).to_s
      messages[i] = msg
   end
   
   messages.each do |m|
      iter = model.append
      iter.set_value( 0, m )
   end
   
   tree_view.append_column( column )
   
   return scrolled_window
end

def insert_text( buffer )

   # Add some test to our text widget - this is a callback that is invoked
   # when our window is realized.

   iter = buffer.get_iter_at_offset( 0 )
   buffer.insert( iter,
   "From:hugh@weareb.org\n" \
   "To: picard@enterprise.gov\n" \
   "Subject: The Collective\n" \
   "\n" \
   "Wish you were here. A planet we just\n" \
   "assimilated had the most beautiful flowers\n" \
   "that I have ever seen. We will be coming\n" \
   "for a visit. Tell Jordi I said Hi.\n" \
   "Yours Truly,\n" \
   "Hugh\n")

end

def create_text

   # Create a scrolled text area that displays a "message"
   view = Gtk::TextView.new
   buffer = view.buffer

   scrolled_window = Gtk::ScrolledWindow.new( nil, nil )
   scrolled_window.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC )
   scrolled_window.add( view )
   insert_text( buffer )

   return scrolled_window
end

Gtk.init
window = Gtk::Window.new( Gtk::Window::TOPLEVEL )
window.signal_connect( "destroy" ) { Gtk.main_quit }
window.set_border_width( 10 )
window.set_size_request( 450, 400 )
window.set_title( "Paned Windows" )

# Create a vpaned widget and add it to our window
vpaned = Gtk::VPaned.new
window.add( vpaned )

# Now create the contents of the two halves of the window
list = create_list
vpaned.add1( list )

text = create_text
vpaned.add2( text )

window.show_all
Gtk.main

Prev Next