241. How to change tab order - Example 4?

Problem

Note: This is a series of examples to show you how to change tab orders in PHP-GTK2.

Ready for something more challenging? Suppose now you have 12 buttons arranged in a circle. You would like to change the tab order to start from the top right button and traverse round the circle, just like that in a monopoly, as shown below:

How to change tab order - Example 4?


Solution

Here are the rules to use GtkContainer::set_focus_chain() again:.

  1. The method takes only one argument - an array of GtkWidgets.
  2. All the widgets in the array must be direct descedents of the container.
  3. It's not necessary to define the tab orders of all levels.

Because of Rule #2 above, there are much rework to be done. Based on the way we want the tab order to be, we have repacked the 12 buttons into the following hboxes and vboxes:

  • hbox_top_row to hold buttons 1 to 4.
  • hbox_bottom_row to hold three vboxes.
  • vbox_column1 holds buttons 5, 6 and 7.
  • vbox_column2 holds only one button: buttons 8.
  • vbox_column3 holds only one button: buttons 9.
  • vbox_column4 holds buttons 10, 11 and 12.

Once you have the hboxes and vboxes in place, you then apply GtkContainer::set_focus_chain():

  • To change the tab order to hbox_top_row so that it goes from left to right.
  • To change the tab order to vbox_column4 so that it goes from bottom to top.

That's it! The rest of the tab order are defaults. So using Rule #3, we do not need to define any of them!


Sample Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
17   
19   
20   
21   
22   
23   
24   
25   
26   
27   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
54   
55   
56   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
75   
76   
77   
78   
79   
80   
81   
82   
83   
84   
85   
86   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(480, 240);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Set tab order - Example 4");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$title->set_size_request(-1, 40);
$title->set_justify(Gtk::JUSTIFY_CENTER);
$alignment = new GtkAlignment(0.5, 0.5, 0, 0);
$alignment->add($title);
$vbox->pack_start($alignment, 0);
$alignment = new GtkAlignment(0.5, 0.5, 0, 0);
$alignment->add($label = new GtkLabel(
"The tab orders are as indicated on the button.\n".
"It starts from the top right button and traverse ".
"round the circle like the monopoly"));
$label->set_justify(Gtk::JUSTIFY_CENTER);
$vbox->pack_start($alignment);
$vbox->pack_start(new GtkLabel(), 0);

$button_hbox = array();

$vbox->pack_start($hbox_top_row = new GtkHBox(), 0);
setup_buttons($hbox_top_row, array(4,3,2,1));

$vbox->pack_start($hbox_bottom_row = new GtkHBox(), 0);

$hbox_bottom_row->pack_start($vbox_column1 = new GtkVBox(), 0);
setup_buttons($vbox_column1, array(5,6,7));

$hbox_bottom_row->pack_start($vbox_column2 = new GtkVBox(), 0);
setup_buttons($vbox_column2, array('', '', 8));

$hbox_bottom_row->pack_start($vbox_column3 = new GtkVBox(), 0);
setup_buttons($vbox_column3, array('', '', 9));

$hbox_bottom_row->pack_start($vbox_column4 = new GtkVBox(), 0);
setup_buttons($vbox_column4, array(12, 11, 10));


// set the tab order
$hbox_top_row->set_focus_chain(array($button_hbox[1], // note 1
    $button_hbox[2], $button_hbox[3], $button_hbox[4])); 

$vbox_column4->set_focus_chain(array($button_hbox[10], // note 2
    $button_hbox[11], $button_hbox[12])); 

$window->show_all();
Gtk::main();

function setup_buttons($container, $button_indexes) {
    global $button_hbox;
    foreach($button_indexes as $index) {
        $hbox = new GtkHBox(); // note 3
        $hbox->set_size_request(110, 33);
        if ($index!='') {
            $button = new GtkButton("tab order $index");
            $button->set_size_request(110, 33);
            $hbox->pack_start($button, 0);
            $button->connect('clicked', 'on_click', $index);
        }
        $container->pack_start($hbox, 0);
        $button_hbox[$index] = $hbox; // note 4
    }
}

function on_click($button, $index) {
    echo "You clicked me: button[$index]!\n";
}

?>

Output

As shown above.

 

Explanation

  1. Set the tab order of hbox_top_row to go from right to left. Note the use of $button_box instead of $button, because the direct descendent is $button_box and not $button. Try changing it to $button. You will find that it won't work.
  2. Set the tab order of vbox_column4 to go from bottom to top. Note the use of $button_box instead of $button, because the direct descendent is $button_box and not $button.
  3. In case you're wondering, I pack the button inside another layer of hbox to make it easy to create the "four holes" at the centre of the monopoly.
  4. Pay particular attention to this. We need the pointer to the hbox when setting the tab order.

Related Links

Add comment


Security code
Refresh