086. How to create a round button - Part 2?

Problem

You have created a round button in Part 1.

Now you would like to add in button click state and rollover effect as shown below:

How to create a round button - Part 2?


Solution

  • First display the round buttons using the technique as explained in Part 1.
  • Use the signal enter-notify-event to detect when a mouse hovers over the button.
  • Use the signal leave-notify-event to detect when a mouse leaves the button.

Sample Code

Note: The following image files are required by the sample code below. Please save a copy of the image files and put them in the same directory where you store the sample code.

 button_rew1.png
 button_rew2.png
 button_play1.png
 button_play2.png
 button_ff1.png
 button_ff2.png

1   
2   
3   
5   
6   
7   
8   
9   
11   
13   
18   
19   
20   
21   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
61   
62   
63   
64   
68   
69   
70   
71   
72   
73   
74   
75   
76   
77   
78   
79   
80   
82   
83   
84   
85   
86   
87   
88   
89   
90   
91   
93   
94   
95   
96   
97   
100   
101   
102   
103   
104   
111   
112   
113   
114   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 200);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$vbox = new GtkVBox();
$window->add($vbox);

// create a hbox to hold the buttons
$vbox->pack_start($hbox = new GtkHBox());

$buttons2 = new RoundButtons($hbox, array(
    array('button_rew1.png', 'button_rew2.png'),
    array('button_play1.png', 'button_play2.png'),
    array('button_ff1.png', 'button_ff2.png')));

class RoundButtons {

    function RoundButtons($container, $buttons) {
        $button_id = 0;
        $this->button_count = count($buttons);
        foreach($buttons as $button_img) {
            $this->create_round_button($container, $button_id,
                $button_img[0], $button_img[1]);
            $this->button_state[$button_id] = 0;
            ++$button_id;
        }
    }

    function create_round_button($container, $button_id, $image0, $image1) {
        $pixbuf[0]=GdkPixbuf::new_from_file($image0);
        list($this->pixmap[$button_id][0],
            $this->mask[$button_id][0]) =
                $pixbuf[0]-> render_pixmap_and_mask(255);

        $pixbuf[1]=GdkPixbuf::new_from_file($image1);
        list($this->pixmap[$button_id][1],
            $this->mask[$button_id][1]) =
                $pixbuf[1]-> render_pixmap_and_mask(255);

        $eventbox = new GtkEventBox();
        $this->eventbox[$button_id] = $eventbox;
        $eventbox->set_size_request(100, -1);
        $container->pack_start($eventbox, 0, 0);

        $style = $eventbox->get_style();
        $style=$style->copy();
        $style->bg_pixmap[Gtk::STATE_NORMAL]=$this->pixmap[$button_id][0];
        $eventbox->set_style($style);

        $eventbox->shape_combine_mask($this->mask[$button_id][0], 0, 0);


        $eventbox->connect('button-press-event',
            array(&$this, 'on_button_press'), $button_id);
        $eventbox->connect('enter-notify-event',
            array(&$this, 'on_enter_leave'), $button_id, 1); // note 1
        $eventbox->connect('leave-notify-event',
            array(&$this, 'on_enter_leave'), $button_id, 0); // note 1
    }

    function on_button_press($widget, $event, $button_id) {
        echo "button_pressed: button $button_id!\n";
        for ($i=0; $i<$this->button_count; ++$i) {
            $state = ($i==$button_id) ? 1 : 0;
            $style = $this->eventbox[$i]->get_style();
            $style=$style->copy();
            $style->bg_pixmap[Gtk::STATE_NORMAL]=$this->pixmap[$i][$state];
            $this->eventbox[$i]->set_style($style);
            $this->button_state[$i] = $state;
        }
        return true;
    }

    function on_enter_leave($widget, $event, $button_id, $state) {
        if ($state==0 && $this->button_state[$button_id]) return; // note 2
        $style = $this->eventbox[$button_id]->get_style();
        $style=$style->copy();
        $style->bg_pixmap[Gtk::STATE_NORMAL]=
            $this->pixmap[$button_id][$state]; // note 1
        $this->eventbox[$button_id]->set_style($style);
        return true;
    }
}

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

?>

Output

As shown above.
 

Explanation

  1. We detect whether the mouse is over the button, and set the image accordingly.
  2. We use the array $button_state[$button_id] to keep track of the state of the button. If it's pressed, hovering and leaving the button should not change the image.

Related Links

Add comment


Security code
Refresh