255. How to use GtkSheet - Part 8 - alternate row colors?

Problem

You have displayed a 2D array in a GtkSheet in How to use GtkSheet - Part 7 - tab to move to next row?.

Suppose you would like to display the grid with alternate row colors as shown below:

How to use GtkSheet - Part 8 - alternate row colors?


Solution

  • Make sure your version of PHP-GTK2 has the GtkExtra library, and the feature turned on in php.ini. (See notes below.)
  • By right, GtkSheet has a method called GtkSheet::range_set_background() that allows us to set the background of a range of cells easily. However, this method is not imported into php-gtk2 yet. (Pleas refer here for details.)
  • Assuming your GtkSheet is set up for browsing only (i.e. no editing), it is still easy for us to set up alternate row colors.
  • Instead of using GtkSheet::set_cell(), we use GtkSheet::attach(GtkSheet *sheet, GtkWidget *widget, int row, gint col, int xoptions, int yoptions, int xpadding, int ypadding) to set the values of each content. The attach() works exactly like GtkTable::attach(). This means that you can attach almost any standard GTK widget to a cell.
  • To display alternate row colors, we create a GtkLabel for each cell, stuff them into a GtkEventBox, and set the background color of the GtkEventBox.
  • By the way, this example actually took me two full days to get it right. The most "tricky" part is to remember that for some reason, PHP-GTK needs to have access to each GtkEventBox after you have set up the spreadsheet. Take a look at the code below. That's why you see a declaration of global $eventbox, and the need to use $eventbox[$row][$col]. Try playing around with this, and comment out the global. You will understand what I mean.

Important Note: This only works for PHP-GTK2 compliled with the additional library GtkExtra. For linux, you can download the files from http://gtkextra.sourceforge.net/ and do a recompile. For windows, you may use the builds by Elizabeth Smith or the official php-gtk2 beta release available at http://gtk.php.net/download.php. Both contain all the required gtkextra libraries and dll's. In the php.ini, don't forget to add php-gtk.extensions = php_gtk_extra2.dll to turn on GtkExtra.


Sample Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
50   
51   
54   
55   
56   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
72   
73   
74   
75   
76   
78   
79   
81   
82   
83   
84   
85   
90   
91   
94   
95   
96   
97   
98   
99   
100   
101   
102   
107   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(430, 250);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Using GtkSheet\n".
"Part 8 - Alternate row colors");
$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, 0, 0);
$alignment->add($title);
$vbox->pack_start($alignment, 0, 0);
$vbox->pack_start(new GtkLabel(), 0, 0);

// the 2D table
$data = array(
array('row0', 'item 42', 2, 3.1),
array('row1', 'item 36', 20, 6.21),
array('row2', 'item 21', 8, 9.36),
array('row3', 'item 10', 11, 12.4),
array('row4', 'item 7', 5, 15.5),
array('row5', 'item 4', 17, 18.6),
array('row6', 'item 3', 20, 21.73));

$max_col = count($data[0])-1;
$max_row = count($data)-1;

$field_header = array('Row #', 'Description', 'Qty', 'Price');
$justification = array('LEFT', 'LEFT', 'CENTER', 'RIGHT');

display_table($vbox, $data, $field_header, $justification);

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

function display_table($vbox, $data, $field_header, $justification) {

    $scrolled_win = new GtkScrolledWindow();
    $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC,
        Gtk::POLICY_AUTOMATIC);
    $vbox->pack_start($scrolled_win);

    $sheet = GtkSheet::new_browser(count($data), count($data[0]), 'Test 123');
    $sheet->set_autoresize(1);
    $scrolled_win->add($sheet);

    $sheet->connect('key-press-event', 'on_keypress');

    // set column header
    for ($col=0; $col<count($field_header); ++$col) {
        $sheet->column_button_add_label($col, $field_header[$col]);
        $justify = constant("Gtk::JUSTIFY_".$justification[$col]);
        $sheet->column_button_justify($col, $justify);
    }

    global $eventbox; // note 1
    for ($row=0; $row<count($data); ++$row) {
        $sheet->row_button_add_label($row, $row+1);
        for ($col=0; $col<count($data[$row]); ++$col) {
            $justify = constant("Gtk::JUSTIFY_".$justification[$col]);
            $eventbox[$row][$col] = new GtkEventBox(); // note 2
            $eventbox[$row][$col]->add(new GtkLabel($data[$row][$col])); // note 3
            $row_color = ($row%2==1) ? '#dddddd' : '#ffffff'; // note 4
            $eventbox[$row][$col]->modify_bg(Gtk::STATE_NORMAL, // note 5
                GdkColor::parse($row_color)); 
            $sheet->attach($eventbox[$row][$col], $row, $col, // note 6
                Gtk::FILL, Gtk::FILL, 0, 0); 
        }
    }
}

function on_keypress($sheet, $event) {
    global $max_col, $max_row;
    list($row, $col) = $sheet->get_active_cell();
    if ($event->keyval == Gdk::KEY_Tab) {
        if ($col<$max_col || $row==$max_row) return false;
        $sheet->set_active_cell($row+1, 0);
        return true;
    } else {
        return false;
    }
}

?>

Output

As shown above.
 

Explanation

The example above is based on How to use GtkSheet - Part 7 - tab to move to next row?

What's new here:

  1. Don't forget this! See notes above.
  2. Create the eventbox.
  3. Create the label.
  4. Set alternate row color.
  5. Set the background color of the cell through the eventbox.
  6. Attach the eventbox to the cell.

Note

As I've mentioned in the blog, there's some problem with this method.

Try pressing the Tab key. Did you see the underlying GtkItemEntry?

I'm not sure if this is a feature or a bug. Although I could find some ways to "gobble" up the Tab or arrow keys so that the GtkItemEntry doesn't appear, I know this should not be the right way of doing things.

Anybody knows how to "deactivate" the underlying GtkItemEntry?

Related Links

Add comment


Security code
Refresh