434. How to activate deactivate a bunch of GtkButtons using GtkAction and GtkActionGroup?

Problem

If you have followed the previous two articles (How to setup and process a GtkButton using GtkAction - Part 1? and How to setup and process a GtkButton using GtkAction - Part 2 - add stock image?) you might be wondering what's the use of GtkAction?

This example will clearly illustrate one of its uses.

Suppose you need to activate or deactivate a group of related buttons as shown below. Try "click on an even number". The entire column of odd numbers is grayed out. Although you can also acheive this by using set_sensitive(false) on all the odd-number buttons, using GtkActionGroup, it's a one-liner!

How to activate deactivate a bunch of GtkButtons using GtkAction and GtkActionGroup?


Solution


Sample Code

1   
2   
3   
4   
5   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
30   
31   
32   
33   
34   
35   
36   
37   
39   
40   
41   
42   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
63   
64   
66   
67   
68   
69   
70   
71   
72   
73   
74   
76   
77   
78   
79   
80   
81   
82   
83   
85   
87   
88   
89   
90   
91   
92   
93   
95   
96   
98   
99   
100   
101   
102   
103   
104   
105   
106   
107   
108   
109   
110   
111   
112   
113   
114   
115   
116   
117   
118   
119   
120   
121   
122   
123   
124   
125   
126   
131   
134   
135   
136   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 320);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Activate/deactivate a bunch of GtkButtons\n".
"  using GtkAction and GtkActionGroup");
$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);
$vbox->pack_start($title, 0, 0);
$vbox->pack_start(new GtkLabel(), 0, 0);

setup_menu($vbox);

setup_numbers($vbox);

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

function setup_numbers($vbox) {

    function setup_buttons($button_label, $vbox, $action_grp) {
        $button = new GtkButton($button_label);
        $button->set_size_request(60, -1);
        $vbox->pack_start($hbox = new GtkHBox(), 0);
        $hbox->pack_start($button, 0);

        $action = new GtkAction($button_label, '_'.$button_label, '', ''); // note 3
        $action->connect_proxy($button); // note 3
        $action->connect('activate', "on_click", $button_label);
        $action_grp->add_action($action); // note 4
        return $button;
    }

    function on_click($button, $label) {
        echo "button clicked: $label\n";
    }

    $vbox->pack_start($hbox = new GtkHBox());
    $hbox->pack_start($vbox1 = new GtkVBox());
    $hbox->pack_start($vbox2 = new GtkVBox());

    global $odd_nummbers_action_grp;
    $odd_nummbers_action_grp = new GtkActionGroup("OddActions"); // note 1

    global $buttons;
    $vbox1->pack_start($hbox1 = new GtkHBox, 0);
    $hbox1->pack_start($label = new GtkLabel('Odd'), 0);
    $label->modify_font(new PangoFontDescription("Arial Bold"));
    for ($i=1; $i<=10; $i+=2) {
        $buttons[$i] = setup_buttons($i, $vbox1, $odd_nummbers_action_grp);
    }

    global $even_nummbers_action_grp;
    $even_nummbers_action_grp = new GtkActionGroup("EvenActions"); // note 2
    $vbox2->pack_start($hbox2 = new GtkHBox, 0);
    $hbox2->pack_start($label = new GtkLabel('Even'), 0);
    $label->modify_font(new PangoFontDescription("Arial Bold"));
    for ($i=2; $i<=10; $i+=2) {
        $buttons[$i] = setup_buttons($i, $vbox2, $even_nummbers_action_grp);
    }

}

function setup_menu($vbox) {

    function setup_radio($radio_button_grp, $button_label, $button_value) {
        $radio = new GtkRadioButton($radio_button_grp, $button_label);
        $radio->connect('toggled', "on_toggle", $button_value);
        return $radio;
    }

    function on_toggle($radio, $value) {
        global $status_area;
        $label = $radio->child->get_label();
        $active = $radio->get_active();

        global $odd_nummbers_action_grp, $even_nummbers_action_grp;
        switch($value) {

            case 'odd_number': // note 5
                $odd_nummbers_action_grp->set_sensitive(true);
                $even_nummbers_action_grp->set_sensitive(false);
                break;

            case 'even_number': // note 5
                $odd_nummbers_action_grp->set_sensitive(false); // note 6
                $even_nummbers_action_grp->set_sensitive(true);
                break;

            case 'any_number': // note 5
                $odd_nummbers_action_grp->set_sensitive(true);
                $even_nummbers_action_grp->set_sensitive(true);
                break;
        }

    }

    // setup grouped radio buttons
    $radio1 = setup_radio(null, 'Click on any number from 1 to 10', 'any_number');
    $radio2 = setup_radio($radio1, 'Click on an odd number', 'odd_number');
    $radio3 = setup_radio($radio1, 'Click on an even number', 'even_number');

    // pack them inside vbox
    $vbox->pack_start($radio1, 0);
    $vbox->pack_start($radio2, 0);
    $vbox->pack_start($radio3, 0);
    $vbox->pack_start(new GtkLabel());
}

?>

Output

As shown above.
 

Explanation

We make use of the code from How to setup and process a GtkButton using GtkAction - Part 1? to set up GtkButtons with GtkActions.

We also make use of the code from How to display and process grouped radio buttons? to set up and process radio buttons.

What's new here:

  1. Create the odd-number action group.
  2. Create the even-number action group.
  3. Create a new action and binds the button to the action.
  4. Add the action to the action group.
  5. Turn the respective group on and off based on the user selection.
  6. Gray out all the odd numbers.

Related Links

Add comment


Security code
Refresh