5.3. Packing Demonstartion Program

require 'gtk2'

def delete_event( widget )
   Gtk.main_quit
   return false
end

# Make a new hbox filled with button labels. Arguments
# for the variables we're intrested are passed into this
# method. We do not show the box, but do show everything
# inside.
def make_box( homogeneous, spacing, expand, fill, padding )
   # Create a new hbox with the appropriate homogeneous
   # and spacing settings
   box = Gtk::HBox.new( homogeneous, spacing )

   # Create a series of buttons with the appropriate
   # settings.
   button = Gtk::Button.new( "#pack_start" )
   box.pack_start( button, expand, fill, padding )
   button.show

   button = Gtk::Button.new( "( box," )
   box.pack_start( button, expand, fill, padding )
   button.show

   button = Gtk::Button.new( "button," )
   box.pack_start( button, expand, fill, padding )
   button.show

   # Create a button with the label depending on the value
   # of expand
   button = Gtk::Button.new( expand.to_s )
   box.pack_start( button, expand, fill, padding )
   button.show

   # This is the same as the button created for "expand"
   # above.
   button = Gtk::Button.new( fill.to_s )
   box.pack_start( button, expand, fill, padding )
   button.show

   button = Gtk::Button.new( padding.to_s + " )")
   box.pack_start( button, expand, fill, padding )
   button.show
   
   return box
end

# Our init, don't forget this!
Gtk.init

if ARGV.length != 1
   puts "usage: packbox.rb num, where num is 1, 2, or 3."
   exit
end

which = ARGV[0].to_i

# Create our new window
window = Gtk::Window.new( Gtk::Window::TOPLEVEL )

# You should always remember to connect the delete_event
# signal to the main window. This is very important for
# proper intuitive behavior
window.signal_connect( 'delete_event') { |w,e| delete_event( e ) }

# Add the invisible border around the inside of the window
window.set_border_width( 10 )

# We create a vertical box to pack the horizontal boxes into.
# This allows us to stack the horizontal boxes filled with
# buttons one on top of the other in this box
box1 = Gtk::VBox.new( false, 0 )

# which example to show, These correspond to the pictures in 5.2
case which
   when 1
      # Create a new label
      label = Gtk::Label.new( "Gtk::HBox.new( false, 0 )" )

      # Align the label to the left side. We'll dicuss this method
      # and others in the section Widget Attributes
      label.set_alignment( 0, 0 )

      # Pack the label into the vertical box (vbox box1). Remember
      # that widgets added to a vbox will be packed one on top
      # of the other in order
      box1.pack_start( label, false, false, 0 )

      # Show the label
      label.show

      # Call our make_box method - homogeneous = false, spacing = 0,
      # expand = false, fill = false, padding = 0
      box2 = make_box( false, 0, false, false, 0 )
      box1.pack_start( box2, false, false, 0 )
      box2.show

      # Call our make_box method - homogeneous = false, spacing = 0,
      # expand = true, fill = false, padding = 0
      box2 = make_box( false, 0, true, false, 0 )
      box1.pack_start( box2, false, false, 0 )
      box2.show

      # Args are: homogeneous, spacing, expand, fill, padding
      box2 = make_box( false, 0, true, true, 0 )
      box1.pack_start( box2, false, false, 0 )
      box2.show

      # Creates a separator, we'll learn more about these later,
      # but they are quite simple
      separator = Gtk::HSeparator.new

      # Pack the separator into the vbox. Remember each of these
      # widgets is being packed into a vbox, so they'll be stacked
      # vertically
      box1.pack_start( separator, false, true, 5 )
      separator.show

      # Create another new label, and show it
      label = Gtk::Label.new( "Gtk::HBox.new( true, 0 )" )
      label.set_alignment( 0, 0 )
      box1.pack_start( label, false, false, 0 )
      label.show
      
      # Args are: homogeneous, spacing, expand, fill, padding
      box2 = make_box( true, 0, true, false, 0)
      box1.pack_start( box2, false, false, 0 )
      box2.show
      
      # Args are: homogeneous, spacing, expand, fill, padding
      box2 = make_box( true, 0, true, true, 0)
      box1.pack_start( box2, false, false, 0 )
      box2.show

      # Another new separator
      separator = Gtk::HSeparator.new
      box1.pack_start( separator, false, true, 5 )
      separator.show
      
   when 2
      # Create a new label, remember box1 is a vbox as created
      # near the beginning of our program
      label = Gtk::Label.new( "Gtk::HBox.new( false, 10 )" )
      label.set_alignment( 0, 0 )
      box1.pack_start( label, false, false, 0 )
      label.show

      # Args are: homogeneous, spacing, expand, fill, padding
      box2 = make_box( false, 10, true, false, 0 )
      box1.pack_start( box2, false, false, 0 )
      box2.show

      # Args are: homogeneous, spacing, expand, fill, padding
      box2 = make_box( false, 10, true, true, 0 )
      box1.pack_start( box2, false, false, 0 )
      box2.show

      separator = Gtk::HSeparator.new

      # The last three arguments to Gtk::Box#pack_start are:
      # expand, fill, padding
      box1.pack_start( separator, false, true, 5 )
      separator.show

      label = Gtk::Label.new( "Gtk::HBox.new( true, 0 )" )
      label.set_alignment( 0, 0 )
      box1.pack_start( label, false, false, 0 )
      label.show
      
      # Args are: homogeneous, spacing, expand, fill, padding
      box2 = make_box( false, 0, true, false, 10 )
      box1.pack_start( box2, false, false, 0 )
      box2.show
      
      # Args are: homogeneous, spacing, expand, fill, padding
      box2 = make_box( false, 0, true, true, 10 )
      box1.pack_start( box2, false, false, 0 )
      box2.show

      # Another new separator
      separator = Gtk::HSeparator.new
      box1.pack_start( separator, false, true, 5 )
      separator.show

   when 3
      # This just demonstrates the ability to use Gtk::Box#pack_end to
      # right justify widgets. First, we create a new box as before
      box2 = make_box( false, 0, false, false, 0 )
      
      # Create the label that will be put at the end
      label = Gtk::Label.new( "end" )
      
      # Pack it using Gtk::Box#pack_end, so it is put on the right
      # side of the hbox created in the make_box call
      box2.pack_end( label, false, false, 0 )
      
      # Show the label
      label.show
      
      # Pack box2 into box1 (the vbox remember ? :)
      box1.pack_start( box2, false, false, 0 )
      box2.show

      # A separator for the bottom
      separator = Gtk::HSeparator.new

      # This explicitly sets the separator to 400 pixels wide by 5 pixels
      # high. This is so the hbox we created will also be 400 pixels wide,
      # and the "end" label will be separated from the other labels in the
      # hbox. Otherwise, all the widgets in the hbox would be packed as
      # close together as possible.
      separator.set_size_request( 400, 5 )

      # Pack the separator into the vbox created near the beginning
      box1.pack_start( separator, false, true, 5 )
      separator.show

   else
      puts "usage: packbox.rb num, where num is 1, 2, or 3."
      exit
end

# Create yet another new hbox.. remember we can use as many as we need
quitbox = Gtk::HBox.new( false, 0 )

# Our quit button
button = Gtk::Button.new( "Quit" )

# Setup the signal to terminate the program when the button is clicked
button.signal_connect( "clicked" ) { |w| delete_event(w) }

# Pack the button into the quitbox
# the last three arguments to Gtk::Box#pack_start are:
# expand, fill, padding
quitbox.pack_start( button, true, false, 0 )

# Pack the quitbox into the vbox
box1.pack_start( quitbox, false, false, 0 )

# Pack the vbox which now contains all of our widgets, into
# the main window
window.add( box1 )

# Show everything left
button.show
quitbox.show
box1.show

# Showing the window last so that everything pops up at once
window.show

# And of course, our main method
Gtk.main

Prev Next