Here is the code used to create the above images. It's commented fairly heavily so I hope you won't have any problems following it. Run it yourself and play with it.
1 #!/usr/bin/env gst 2 3 " example packbox.st" 4 5 Eval [ 6 PackageLoader fileInPackage: 'GTK'. 7 ] 8 9 Object subclass: PackageBox [ 10 | box1 box2 button label quitbox separator window | 11 12 " Helper function that makes a new hbox filled with button-labels. Arguments 13 for the variables we're interested are passed in to this function. We do 14 not show the box, but do show everything inside. " 15 makeBox: aHomogeneousBool spacing: aSpacingInt expand: anExpandBool fill: aFillBool padding: aPaddingInt [ 16 | box padstr | 17 18 " Create a new hbox with the appropriate homogeneous 19 and spacing settings " 20 box := GTK.GtkHBox new: aHomogeneousBool spacing: aSpacingInt. 21 22 " Create a series of buttons with the appropriate settings " 23 button := GTK.GtkButton newWithLabel: 'box.pack'. 24 box packStart: button expand: anExpandBool fill: aFillBool padding: aPaddingInt. 25 button show. 26 27 button := GTK.GtkButton newWithLabel: '(button,'. 28 box packStart: button expand: anExpandBool fill: aFillBool padding: aPaddingInt. 29 button show. 30 31 " Create a button with the label depending on the value of 32 expand. " 33 anExpandBool 34 ifTrue: [ button := GTK.GtkButton newWithLabel: 'true,' ] 35 ifFalse: [ button := GTK.GtkButton newWithLabel: 'false,' ]. 36 37 box packStart: button expand: anExpandBool fill: aFillBool padding: aPaddingInt. 38 button show. 39 40 " This is the same as the button creation for 'expand' 41 above, but uses the shorthand form. " 42 button := GTK.GtkButton newWithLabel: (aFillBool ifTrue: [ 'true,' ] ifFalse: [ 'false,' ]). 43 box packStart: button expand: anExpandBool fill: aFillBool padding: aPaddingInt. 44 button show. 45 46 padstr := aPaddingInt asString, ')'. 47 48 button := GTK.GtkButton newWithLabel: padstr. 49 box packStart: button expand: anExpandBool fill: aFillBool padding: aPaddingInt. 50 button show. 51 ^ box 52 ] 53 54 delete: aWidget event: aGdkEvent [ 55 GTK.Gtk mainQuit. 56 ^ false 57 ] 58 59 box1 [ 60 | label separator | 61 62 " create a new label. " 63 label := GTK.GtkLabel new: 'HBox(false, 0)'. 64 65 " Align the label to the left side. We'll discuss this method 66 and others in the section on Widget Attributes. " 67 label setAlignment: 0 yalign: 0. 68 69 " Pack the label into the vertical box (vbox box1). Remember that 70 widgets added to a vbox will be packed one on top of the other in 71 order. " 72 box1 packStart: label expand: false fill: false padding: 0. 73 74 " Show the label " 75 label show. 76 77 " Call our make box function - homogeneous = false, spacing = 0, 78 expand = false, fill = false, padding = 0 " 79 box2 := self makeBox: false spacing: 0 expand: false fill: false padding: 0. 80 box1 packStart: box2 expand: false fill: false padding: 0. 81 box2 show. 82 83 " Call our make box function - homogeneous = false, spacing = 0, 84 expand = true, fill = false, padding = 0 " 85 box2 := self makeBox: false spacing: 0 expand: true fill: false padding: 0. 86 box1 packStart: box2 expand: false fill: false padding: 0. 87 box2 show. 88 89 " Args are: homogeneous, spacing, expand, fill, padding " 90 box2 := self makeBox: false spacing: 0 expand: true fill: true padding: 0. 91 box1 packStart: box2 expand: false fill: false padding: 0. 92 box2 show. 93 94 " Creates a separator, we'll learn more about these later, 95 but they are quite simple. " 96 separator := GTK.GtkHSeparator new. 97 98 " Pack the separator into the vbox. Remember each of these 99 widgets is being packed into a vbox, so they'll be stacked 100 vertically. " 101 box1 packStart: separator expand:false fill: true padding: 5. 102 separator show. 103 104 " Create another new label, and show it. " 105 label := GTK.GtkLabel new: 'HBox(true, 0)'. 106 label setAlignment: 0 yalign: 0. 107 box1 packStart: label expand: false fill: false padding: 0. 108 label show. 109 110 " Args are: homogeneous, spacing, expand, fill, padding " 111 box2 := self makeBox: true spacing: 0 expand: true fill: false padding: 0. 112 box1 packStart: box2 expand: false fill: false padding: 0. 113 box2 show. 114 115 " Args are: homogeneous, spacing, expand, fill, padding " 116 box2 := self makeBox: true spacing: 0 expand: true fill: true padding: 0. 117 box1 packStart: box2 expand: false fill: false padding: 0. 118 box2 show. 119 120 " Another new separator. " 121 separator := GTK.GtkHSeparator new. 122 " The last 3 arguments to pack_start are: 123 expand, fill, padding. " 124 box1 packStart: separator expand: false fill: true padding: 5. 125 separator show 126 ] 127 128 box2 [ 129 " Create a new label, remember box1 is a vbox as created 130 near the beginning of show: " 131 label := GTK.GtkLabel new: 'HBox(false, 10)'. 132 label setAlignment: 0 yalign: 0. 133 box1 packStart: label expand: false fill: false padding: 0. 134 label show. 135 136 " Args are: homogeneous, spacing, expand, fill, padding " 137 box2 := self makeBox: false spacing: 10 expand: true fill: false padding: 0. 138 box1 packStart: box2 expand: false fill: false padding: 0. 139 box2 show. 140 141 " Args are: homogeneous, spacing, expand, fill, padding " 142 box2 := self makeBox: false spacing: 10 expand: true fill: true padding: 0. 143 box1 packStart: box2 expand: false fill: false padding: 0. 144 box2 show. 145 146 separator := GTK.GtkHSeparator new. 147 " The last 3 arguments to pack_start are: 148 expand, fill, padding. " 149 box1 packStart: separator expand: false fill: true padding: 5. 150 separator show. 151 152 label := GTK.GtkLabel new: 'HBox(false, 0)'. 153 label setAlignment: 0 yalign: 0. 154 box1 packStart: label expand: false fill: false padding: 0. 155 label show. 156 157 " Args are: homogeneous, spacing, expand, fill, padding " 158 box2 := self makeBox: false spacing: 0 expand: true fill: false padding: 10. 159 box1 packStart: box2 expand: false fill: false padding: 0. 160 box2 show. 161 162 " Args are: homogeneous, spacing, expand, fill, padding " 163 box2 := self makeBox: false spacing: 0 expand: true fill: true padding: 10. 164 box1 packStart: box2 expand: false fill: false padding: 0. 165 box2 show. 166 167 separator := GTK.GtkHSeparator new. 168 " The last 3 arguments to pack_start are: 169 expand, fill, padding. " 170 box1 packStart: separator expand: false fill: true padding: 5. 171 separator show. 172 ] 173 174 box3 [ 175 " This demonstrates the ability to use packEnd to 176 right justify widgets. First, we create a new box as before. " 177 box2 := self makeBox: false spacing: 0 expand: false fill: false padding: 0. 178 179 " Create the label that will be put at the end. " 180 label := GTK.GtkLabel new: 'end'. 181 " Pack it using packEnd, so it is put on the right 182 side of the hbox created in the makeBox: call. " 183 box2 packEnd: label expand: false fill: false padding: 0. 184 " Show the label. " 185 label show. 186 187 " Pack box2 into box1 " 188 box1 packStart: box2 expand: false fill: false padding: 0. 189 box2 show. 190 191 " A separator for the bottom. " 192 separator := GTK.GtkHSeparator new. 193 194 " This explicitly sets the separator to 400 pixels wide by 5 195 pixels high. This is so the hbox we created will also be 400 196 pixels wide, and the 'end' label will be separated from the 197 other labels in the hbox. Otherwise, all the widgets in the 198 hbox would be packed as close together as possible. " 199 separator setSizeRequest: 400 height: 5. 200 " pack the separator into the vbox (box1) created near the start 201 of show: " 202 box1 packStart: separator expand: false fill: true padding: 5. 203 separator show. 204 ] 205 206 show: aSymbol [ 207 " Create our window " 208 window := GTK.GtkWindow new:GTK.Gtk gtkWindowToplevel. 209 210 " You should always remember to connect the delete_event signal 211 to the main window. This is very important for proper intuitive 212 behavior " 213 window connectSignal: 'delete_event' to: self selector: #delete:event: userData: nil. 214 window setBorderWidth: 10. 215 216 " We create a vertical box (vbox) to pack the horizontal boxes into. 217 This allows us to stack the horizontal boxes filled with buttons one 218 on top of the other in this vbox. " 219 box1 := GTK.GtkVBox new: false spacing: 0. 220 221 " which example to show. These correspond to the pictures above. " 222 self perform: aSymbol. 223 224 " Create another new hbox.. remember we can use as many as we need! " 225 quitbox := GTK.GtkHBox new: false spacing: 0. 226 227 " Our quit button. " 228 button := GTK.GtkButton newWithLabel: 'Quit'. 229 230 " Setup the signal to terminate the program when the button is clicked " 231 button connectSignal: 'clicked' to: self selector: #delete:event:. 232 233 " Pack the button into the quitbox. 234 The last 3 arguments to pack_start are: 235 expand, fill, padding. " 236 quitbox packStart: button expand: true fill: false padding: 0. 237 " pack the quitbox into the vbox (box1) " 238 box1 packStart: quitbox expand: false fill: false padding: 0. 239 240 " Pack the vbox (box1) which now contains all our widgets, into the 241 main window. " 242 window add: box1. 243 244 " And show everything left " 245 button show. 246 quitbox show. 247 248 box1 show. 249 " Showing the window last so everything pops up at once. " 250 window show. 251 ] 252 ] 253 254 Eval [ 255 package := PackageBox new. 256 package show: Smalltalk arguments first asSymbol. 257 GTK.Gtk main 258 ]
A brief tour of the packbox.st code starts
with lines 15-52 which define a helper function
makeBox that creates a horizontal box and populates
it with buttons according to the specified parameters. A reference to the
horizontal box is returned.
Lines 9-251 define the PackBox class
initialization method show that creates a
window and a child vertical box that is populated with a different widget
arrangement depending on the argument passed to it. If a box1 is passed, lines
59-126 define the method box1 creates a window displaying
the five unique packing arrangements that are available when varying the homogeneous, expand and fill parameters. If a
box2 is passed, lines 128-172 define the method box2 creates a window displaying the various
combinations of fill with spacing and padding. Finally, if a 3 is passed,
lines 174-204 define the method box1 creates a window displaying the use of the
packStart method to left justify the buttons and
packEnd method to right justify a label. Lines
225-238 create a horizontal box containing a button that is packed into the
vertical box. The button "clicked" signal is connected to the Smalltalk
delete:event: function to terminate the program.
Lines 255-257 check the command line arguments and exit the
program using the ObjectMemory quit: 0 function if there isn't
exactly one argument. Line 257 invokes the GTK.Gtk main function to start the GTK event processing
loop.