17.11 LAYOUT MANAGEMENT IN GNOMEGTK


17.11 LAYOUT MANAGEMENT IN GNOME/GTK+

GNOME/GTK+ uses the following layout managers for controlling the layout:

      GtkHbox      GtkVBox      GtkTable 

GtkHBox and GtkVBox work much the same way as QHBox and QVBox layout managers in Qt. And GtkTable is similar to QGridLayout of Qt.

17.11.1 Box Layout

A GtkHBox arranges all of its children in a single row, and all the children are allocated the same height. The following program illustrates this by packing buttons into a GtkHBox. As shown in line (A) of the program, the layout manager is constructed by a call to gtk_hbox_new whose prototype is

      GtkWidget* gtk_hbox_new(gboolean homogeneous, gint spacing) 

The second parameter is the number of pixels of empty space around each child widget. If the first parameter, homogeneous, is set to TRUE, each child widget will occupy an equal amount of space horizontally. This means that the amount of horizontal space alloted to a button with a short label will the same as to a button with a long label. The size of each child widget in its allocated space in the layout and how that size changes as the top-level window is resized is specified at the time a component is inserted into the layout, as shown by line (B) of the program. The prototype of the function gtk_box_pack_start() invoked in line (B) is

      void gtk_box_pack_start( GtkBox* box,                                                    GtkWidget* child,                                                    gboolean expand,                                                    gboolean fill,                                                    guint padding); 

For the case of arranging buttons in the following program, if the expand parameter is set to TRUE, a button would be made just large enough to fit the label for the button (the label length has to exceed a threshold for this to be true). If the fill parameter is set to TRUE, the button will occupy as much space as possible (taking into account the value assigned to padding) within the horizontal space alloted to the button.

 
//GHBoxTest.c #include <gnome.h> gint eventDestroy(GtkWidget* widget, GdkEvent* event, gpointer data); int main(int argc, char* argv[]) { GtkWidget* window; GtkWidget* hbox; GtkWidget* button; gnome_init("HorizBoxTest", "1.0", argc, argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(eventDestroy), NULL); gtk_container_set_border_width(GTK_CONTAINER(window), 25); hbox = gtk_hbox_new(TRUE, 10); //(A) button = gtk_button_new_with_label("Hi"); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0); //(B) button = gtk_button_new_with_label("Hello"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0); button = gtk_button_new_with_label("Hi There"); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); button = gtk_button_new_with_label("Hello There"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(window), hbox); gtk_widget_show_all(window); gtk_main(); exit(0); } gint eventDestroy(GtkWidget* widget, GdkEvent* event, gpointer data){ gtk_main_quit(); return 0; }

The _start in the function name gtk_box_pack_start means that the child widgets will be inserted left to right in a horizontal layout. For inserting the child widgets right to left, one can use the function gtk_box_pack_end. The window created by the above program is shown in Figure 17.20.

click to expand
Figure 17.20

The discussion above applies equally to GtkVBox, except that now the child widgets will be arranged vertically. This layout manager is constructed with a call to gtk_vbox_new whose prototype is similar to that shown earlier for gtk_hbox_new.

17.11.2 Table Layout

Our next example shows how the GtkTable layout manager can be used for creating a grid-like arrangement of child widgets. The layout manager itself is constructed with a call whose prototype is

      GtkWidget* gtk_table_new(guint rows,                               guint columns,                               gboolean homogeneous); 

where the parameters rows and columns have obvious meanings. The meaning of homogeneous is the same as before; that is, the cell sizes will all be the equal regardless of the actual sizes of the child widgets if this parameter is set to TRUE.

As the following program shows in line (A), an easy way to enter a child widget into a cell is by invoking gtk_table_attach_defaults; this function is of prototype

      void gtk_table_attach_defaults( GtkTable* table,                                      GtkWidget* widget,                                      guint left_attach,                                      guint right_attach,                                      guint top_attach,                                      guint bottom_attach); 

where left_attach, right_attach, top_attach, and bottom_attach refer to the grid lines partitioning the table into cells. The leftmost edge of the table corresponds to the vertical grid line 0, the edge between the first column and the second column to the vertical grid line 1, and so on. So for the top left cell, the value of left_attach will always be 0 and that of right_attach 1. For the next cell in the top row, the left_attach will be 1 and the right_attach will be 2, and so on. Similarly for the values of top_attach and bottom_attach.

It is important to realize that a single widget can cover multiple cells in the table. In the program below, we show at (B) that the last button is constructed with the calls

      button = gtk_button_new_with_label("Hello There");      gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 3, 1, 2); 

which by giving a value of 0 to left_attach and 3 to right_attach would cause this button to occupy three cells horizontally in the second row of the table.

The reason for "defaults" in the function name gtk_table_attach_defaults shown above is that it is a defaults-assuming abbreviated version of a function whose prototype is

     void gtk_table_attach( GtkTable* table,                            GtkWidget* widget,                            guint left_attach,                            guint right_attach,                            guint top_attach,                            guint bottom_attach,                            GtkAttachOptions xoptions,                            GtkAttachOptions yoptions,                            guint xpadding,                            guint ypadding); 

where the parameters xoptions and yoptions are used to specify the expansion properties of the child widget when the table is resized horizontally or vertically. GtkAttachOptions is an enum defined by

 typedef enum {      GTK_EXPAND = 1 < < 0,      GTK_SHRINK = 1 < < 1,      GTK_FILL = 1 << 2, } GtkAttachOptions; 

When xoptions is set to 0, the child widget will not be resized horizontally as the size of the table is changed; the child widget will appear at its minimum horizontal size. Additionally, if the size of the cell (or cells for multicell widgets) is larger than the minimum horizontal size of the widget, the widget will be centered. The same for yoptions set to 0 for vertical adjustments. When xoptions and/or yoptions is set to GTK_FILL, the child widget will expand, horizontally and/or vertically, to fill the available space. When set to GTK_SHRINK, the child widget will shrink to fit inside the cell (or cells) if the cell is smaller than the minimum size of the widget. And when set to GTK_EXPAND, the child widget will expand proportionately to the change in the size of the table. The parameters xpadding and ypadding stand for the margins to be used around the child widgets. The default for both xoptions and yoptions is GTK_EXPAND | GTK_FILL, and the default for both xpadding and ypadding is 0.

 
//TableLayoutTest.c #include <gnome.h> gint eventDestroy(GtkWidget* widget, GdkEvent* event, gpointer data); int main(int argc, char* argv[]) { GtkWidget* window; GtkWidget* table; GtkWidget* button; gnome_init("TableLayoutTest", "1.0", argc, argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect( GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(eventDestroy), NULL); gtk_container_set_border_width(GTK_CONTAINER(window), 25); table = gtk_table_new(2, 3, TRUE); //rows, cols, homogeneous button = gtk_button_new_with_label("Hi"); gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 0, 1); //(A) button = gtk_button_new_with_label("Hello"); gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 0, 1); button = gtk_button_new_with_label("Hi There"); gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, 0, 1); button = gtk_button_new_with_label("Hello There"); //(B) gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 3, 1, 2); gtk_container_add(GTK_CONTAINER(window), table); gtk_widget_show_all(window); gtk_main(); exit(0); } gint eventDestroy(GtkWidget* widget, GdkEvent* event, gpointer data){ gtk_main_quit(); return 0; }

The window produced by the above program is shown in Figure 17.21.

click to expand
Figure 17.21




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net