only for RuBoard - do not distribute or recompile |
The GtkTable widget is like a grid, or perhaps what you would get if you crossed a horizontal packing box with a vertical packing box (see Figure 4.1). A tic-tac-toe game would work well as a three-by-three GtkTable. In addition, you can tell the table to span child widgets across more than one position in the table, either vertically or horizontally.
The GtkTable demo program shows the table widget in action (albeit in a slightly ugly implementation). It also shows a new paradigm for a program-in-action ”that of destroying and re-creating a widget in response to events. Remember that if this were an application, you would have to find some way to preserve the data in order to restore it after the widgets were re-created. The compiled and running version of Listing 4.1 is shown in Figure 4.1
#include <gtk/gtk.h> GtkWidget *frm_table; GtkWidget *tbl; /* Each command button widget, below, will be specified by the location of * its top left corner. For example, the first one is row 1, column 1. * The second is row 2, column 1, and so on. */ GtkWidget *cmd_1_1; GtkWidget *cmd_2_1; GtkWidget *cmd_4_1; GtkWidget *cmd_1_2; GtkWidget *cmd_1_3; GtkWidget *cmd_3_2; GtkWidget *cmd_2_3; GtkWidget *cmd_3_3; GtkWidget *chk_1; void destroy_main(); void make_table_buttons(); void attach_widgets(); void cmd_1_1_clicked(); void cmd_2_1_clicked(); void cmd_4_1_clicked(); void cmd_1_2_clicked(); void cmd_1_3_clicked(); void cmd_3_2_clicked(); void cmd_2_3_clicked(); void cmd_3_3_clicked(); gint main(gint argc, gchar *argv[]) { gtk_init(&argc, &argv); frm_table = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(frm_table), "Table Demo"); gtk_signal_connect(GTK_OBJECT(frm_table), "destroy", GTK_SIGNAL_FUNC(destroy_main), NULL); make_table_buttons(); / * Initial setup of command buttons uses defaults. * * The only reason you use gtk_table_attach_defaults() here * instead of attach_widgets() is to demonstrate the * gtk_table_attach_defaults() function. * / gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_1_1, 0, 1, 0, 1); gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_2_1, 0, 1, 1, 3); gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_4_1, 0, 4, 3, 4); gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_1_2, 1, 2, 0, 2); gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_1_3, 2, 3, 0, 1); gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_3_2, 1, 2, 2, 3); gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_3_3, 2, 3, 2, 3); gtk_table_attach_defaults(GTK_TABLE(tbl), cmd_2_3, 2, 4, 1, 2); chk_1 = gtk_check_button_new_with_label("Check Btn"); gtk_table_attach_defaults(GTK_TABLE(tbl), chk_1, 3, 4, 0, 1); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); gtk_main (); return 0; } void destroy_main() { gtk_main_quit(); } void attach_widgets(gint _OPTIONS, gint _PACKING) { gtk_table_attach(GTK_TABLE(tbl), cmd_1_1, 0, 1, 0, 1, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), cmd_2_1, 0, 1, 1, 3, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), cmd_4_1, 0, 4, 3, 4, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), cmd_1_2, 1, 2, 0, 2, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), cmd_1_3, 2, 3, 0, 1, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), cmd_3_2, 1, 2, 2, 3, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), cmd_3_3, 2, 3, 2, 3, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), cmd_2_3, 2, 4, 1, 2, _OPTIONS, _OPTIONS, _PACKING, _PACKING); gtk_table_attach(GTK_TABLE(tbl), chk_1, 3, 4, 0, 1, _OPTIONS, _OPTIONS, _PACKING, _PACKING); } void make_table_buttons() { tbl = gtk_table_new(4, 4, TRUE); /* The parameters for the previous call are rows, columns, and homogenous. */ cmd_1_1 = gtk_button_new_with_label("Set Padding 9"); gtk_signal_connect(GTK_OBJECT(cmd_1_1), "clicked", GTK_SIGNAL_FUNC(cmd_1_1_clicked), NULL); cmd_2_1 = gtk_button_new_with_label("Set\nOptions\nTo\nFILL"); gtk_signal_connect(GTK_OBJECT(cmd_2_1), "clicked", GTK_SIGNAL_FUNC(cmd_2_1_clicked), NULL); cmd_4_1 = gtk_button_new_with_label("Set Options To SHRINK"); gtk_signal_connect(GTK_OBJECT(cmd_4_1), "clicked", GTK_SIGNAL_FUNC(cmd_4_1_clicked), NULL); cmd_1_2 = gtk_button_new_with_label("Set\nOptions\nTo\nEXPAND"); gtk_signal_connect(GTK_OBJECT(cmd_1_2), "clicked", GTK_SIGNAL_FUNC(cmd_1_2_clicked), NULL); cmd_1_3 = gtk_button_new_with_label("Set\nOptions\nTo\nFILL\nand\nSHRINK"); gtk_signal_connect(GTK_OBJECT(cmd_1_3), "clicked", GTK_SIGNAL_FUNC(cmd_1_3_clicked), NULL); cmd_3_2 = gtk_button_new_with_label("Set\nOptions\nTo\nSHRINK\nand\nEXPAND"); gtk_signal_connect(GTK_OBJECT(cmd_3_2), "clicked", GTK_SIGNAL_FUNC(cmd_3_2_clicked), NULL); cmd_3_3 = gtk_button_new_with_label("Set\nOptions\nTo\nFILL\nand\nEXPAND"); gtk_signal_connect(GTK_OBJECT(cmd_3_3), "clicked", GTK_SIGNAL_FUNC(cmd_3_3_clicked), NULL); cmd_2_3 = gtk_button_new_with_label("Set Options To\nFILL and EXPAND and SHRINK"); gtk_signal_connect(GTK_OBJECT(cmd_2_3), "clicked", GTK_SIGNAL_FUNC(cmd_2_3_clicked), NULL); chk_1 = gtk_check_button_new_with_label("Check Btn"); } void cmd_1_1_clicked() { / * This is something new that hasn't been covered yet. The table of * command buttons that the user presses will actually be destroyed * and then re-created, as will all the following * command button callbacks. This is because there is no *_set_* * command for the table widget. * * Even if there was, you could still do it this way if you wanted * to. Granted, this gets a little tedious, but if you change the * user interface, you know all the places to make changes in order * to maintain your layout. * / gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(0, 9); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); } /* Clearly, the following could be better engineered as * a single function that reacted differently based on * the incoming parameters. However, it is * presented this way in order to show the different * values and their uses in an easy-to-compare format. * / void cmd_2_1_clicked() { gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(GTK_FILL, 0); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); } void cmd_4_1_clicked() { gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(GTK_SHRINK, 0); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); } void cmd_1_2_clicked() { gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(GTK_EXPAND, 0); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); } void cmd_1_3_clicked() { gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(GTK_FILL GTK_SHRINK, 0); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); } void cmd_3_2_clicked() { gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(GTK_SHRINK GTK_EXPAND, 0); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); } void cmd_3_3_clicked() { gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(GTK_FILL GTK_EXPAND, 0); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); } void cmd_2_3_clicked() { gtk_widget_destroy(tbl); make_table_buttons(); attach_widgets(GTK_SHRINK GTK_FILL GTK_EXPAND, 0); gtk_container_add(GTK_CONTAINER(frm_table), tbl); gtk_widget_show_all (frm_table); }
only for RuBoard - do not distribute or recompile |