Re-using widgets specified in a Builder UI with gnocl::builder buffer

WJG (14/03/10) Loading XML UI description files into gnocl applications presents the developer with a whole new range of commands not ordinarily expected. One of this is to reuse the UI specification for the creation of multiple instances of specific sets of widgets. The following screenshot makes this point clearer:

http://lh6.ggpht.com/_yaFgKvuZ36o/S5zXoFg1b1I/AAAAAAAAAdk/V7SitwYuRBA/s800/screenshot-sub-buffers.png

The main script window consists of a number of elements, the bulk are created by loading a builder XML file from a buffer, the control buttons enclosed in the red frame have been attached later. The main elements consist of a number of buttons enclosed in boxes, as the buffer is independent of the objects that it causes to be created, naturally it can be used to build other UI structures. The line below show's how this is achieved.The -container option must be the name of an existing container objects such as a toplevel, box or box, The -objects option requires a list of object, not the names registered with the gnocl interpreter but those specified in the the builder description file.

[gnocl::builder buffer $builderBuffer -container $testBox3 -objects [list button1 button3 button5 button7 ] ]

This is the script that created the above graphic. Needless to say, the XML file comprises the bulk of the script itself!

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "[email protected]"

package require Gnocl

#---------------
# Create a simple layout, a widget with a button.
#---------------
set builderBuffer {<?xml version="1.0"?>
<interface>
  <requires lib="gtk+" version="2.12"/>
  <object class="GtkWindow" id="window1">
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <child>
          <object class="GtkHBox" id="hbox1">
            <property name="visible">True</property>
            <property name="border_width">10</property>
            <child>
              <object class="GtkButton" id="button1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">red</property>
                <property name="response_id">0</property>
              </object>
            </child>
            <child>
              <object class="GtkButton" id="button2">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">green</property>
                <property name="response_id">0</property>
              </object>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button3">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">blue</property>
                <property name="response_id">0</property>
              </object>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
          </object>
        </child>
        <child>
          <object class="GtkVBox" id="vbox2">
            <property name="visible">True</property>
            <property name="border_width">10</property>
            <child>
              <object class="GtkButton" id="button4">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">cyan</property>
                <property name="response_id">0</property>
              </object>
            </child>
            <child>
              <object class="GtkButton" id="button5">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">magenta</property>
                <property name="response_id">0</property>
              </object>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button6">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">yellow</property>
                <property name="response_id">0</property>
              </object>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="button7">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="label" translatable="yes">white</property>
            <property name="response_id">0</property>
          </object>
          <packing>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
}

#---------------
# Load the buffer.
#---------------
set builderFileObjects [gnocl::builder buffer $builderBuffer]

#---------------
# Register the widgets using their glade names.
#---------------

foreach item $builderFileObjects {
    puts $item
    foreach {gnocl builder} $item {}
    set $builder $gnocl
}

$window1 configure -width 300 -height 200
$window1 center
$window1 show

# add some extra buttons to this one
set myBox [gnocl::box -background red]
set mb1 [gnocl::button -text "Show hbox1"]
$mb1 configure -onClicked {
set toplevel1 [gnocl::window  -title "Toplevel 1 - hbox1" -width 250 -height 150 -x 100 -y 100]
set builderFileObjects [gnocl::builder buffer $builderBuffer -container $toplevel1 -objects hbox1  ]
}

set mb2 [gnocl::button -text "Show vbox2"]
$mb2 configure -onClicked {
set testBox2 [gnocl::box -orientation vertical]
set toplevel2 [gnocl::window -child $testBox2 -title "Toplevel 2 -vbox2" -width 250 -height 150 -x 100 -y 300]
set builderFileObjects [gnocl::builder buffer $builderBuffer -container $testBox2 -objects vbox2 ]
}

set mb3 [gnocl::button -text "Mixed Buttons"]
$mb3 configure -onClicked {
    set testBox3 [gnocl::box -orientation vertical]
set toplevel3 [gnocl::window -child $testBox3 -title "Toplevel 3 -mixed buttons" -width 250 -height 150 -x 100 -y 500]
set builderFileObjects [gnocl::builder buffer $builderBuffer -container $testBox3 -objects [list button1 button3 button5 button7 ] ]

}

set myText  [gnocl::text]
$myText insert end "Buttons red, green and blue, are in hbox1.\n"
$myText insert end "Buttons cyan, magenta and yellow, are in vboxs.\n"
$myText insert end "Button white in a single button added to vbox1.\n"

set myBox1 [gnocl::box -orientation vertical -background red]
$myBox1 add $myText -fill {1 1} -expand 1 -padding 0

set myBox2 [gnocl::box]
$myBox2 add [list $mb1 $mb2 $mb3] -fill {0.5 1} -expand 1 -padding 5

$myBox1 add $myBox2

[$window1 cget -child] add $myBox1

puts [gnocl::screen geometry]

gnocl::mainLoop