287. How to display bold and colored fonts in GtkTreeView using pango markup language?

Problem

You would like to display bold and colored fonts in a treeview as shown below:

This feature has long existed even in the Gnope version. However until now, it is still not documented yet in the official php-gtk2 manual.

How to display bold and colored fonts in GtkTreeView using pango markup language?


Solution

  • Use GtkCelllayout::set_cell_data_func() to add your user-defined cell-display function.
  • Display the cell content containing the pango markup by setting the property 'markup' (yes, it's not documented yet in the official php-gtk2 manual).

Sample Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
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   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
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   
87   
88   
89   
90   
91   
95   
96   
97   
98   
100   
101   
102   
103   
104   
105   
106   
107   
108   
109   
110   
111   
112   
113   
114   
116   
117   
118   
119   
120   
121   
122   
123   
124   
125   
126   
127   
128   
129   
130   
131   
132   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 200);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Display bold and colored fonts in GtkTreeView\n".
"           using Pango Markup Language");
$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);

// 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));

display_table($vbox, $data);

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

function display_table($vbox, $data) {

    // Set up a scroll window
    $scrolled_win = new GtkScrolledWindow();
    $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC,
        Gtk::POLICY_AUTOMATIC);
    $vbox->pack_start($scrolled_win);

    // Creates the list store
    if (defined("GObject::TYPE_STRING")) {
        $model = new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING,
            GObject::TYPE_LONG, GObject::TYPE_DOUBLE);
    } else {
        $model = new GtkListStore(Gtk::TYPE_STRING, Gtk::TYPE_STRING,
            Gtk::TYPE_LONG, Gtk::TYPE_DOUBLE);
    }
    $field_header = array('Row #', 'Description', 'Qty', 'Price');
    $field_justification = array(0.0, 0.0, 0.5, 1.0);

    // Creates the view to display the list store
    $view = new GtkTreeView($model);
    $scrolled_win->add($view);

    // Creates the columns
    for ($col=0; $col<count($field_header); ++$col) {
        $cell_renderer = new GtkCellRendererText();
        $cell_renderer->set_property("xalign", $field_justification[$col]);
        $column = new GtkTreeViewColumn($field_header[$col],
            $cell_renderer, 'text', $col);
        $column->set_alignment($field_justification[$col]);
        $column->set_sort_column_id($col);

        // set the header font and color
        $label = new GtkLabel($field_header[$col]);
        $label->modify_font(new PangoFontDescription("Arial Bold"));
        $label->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000FF"));
        $column->set_widget($label);
        $label->show();

        // setup self-defined function to display alternate row color
        $column->set_cell_data_func($cell_renderer, "format_col", $col); // note 1
        $view->append_column($column);
    }

    // pupulates the data
    for ($row=0; $row<count($data); ++$row) {
        $values = array();
        for ($col=0; $col<count($data[$row]); ++$col) {
            $values[] = $data[$row][$col];
        }
        $model->append($values);
    }

    $selection = $view->get_selection();
    $selection->connect('changed', 'on_selection');
}

// self-defined function to format the price column
function format_col($column, $cell, $model, $iter, $col_num) {
    $path = $model->get_path($iter); // get the current path
    $row_num = $path[0]; // get the row number
    $val = $model->get_value($iter, $col_num); // note 2

    switch($col_num) {
        case 1:
            $cell->set_property('markup', 
                "<span font_desc='Verdana 12'><b>$val</b></span>"); // note 3
            break;

        case 2:
            if ($val<10) {
                $cell->set_property('markup', 
                    "<span foreground='#FF0000'>$val</span>"); // note 4
            } else {
                $cell->set_property('markup', 
                    "<span foreground='#0000FF'>$val</span>"); // note 4
            }
            break;

        case 3:
            $cell->set_property('text', '$'.number_format($val,2)); // note 5
            break;
    }
    $row_color = ($row_num%2==1) ? '#dddddd' : '#ffffff';
    $cell->set_property('cell-background', $row_color); // note 6
}

// the function that is called when user selects a row
function on_selection($selection) {
    list($model, $iter) = $selection->get_selected();
    $desc = $model->get_value($iter, 1);
    $qty = $model->get_value($iter, 2);
    $price = $model->get_value($iter, 3);
    print "You have selected $desc: $qty ($price)\n";
}

?>

Output

As shown above.

 

Explanation

We make use of the code from the familiar treeview example: How to display a 2D array in GtkTreeView - Part 5 - get user selection?

What's new here:

  1. Setup the cell display funciton.
  2. Get the value of the current cell.
  3. For the description column (col 1), let's display it using Verdana size 12 in bold. (For linux users, please chnage to your respective font on your machine.)
  4. For the quantity column (col 2), let's display the quantity in red if it's less than 10, and in blue if it's more than or equals to 10.
  5. If you do not need any markup, just set the property 'text' instead of 'markup'.
  6. Display the rows in alternate row color.

Note

For more information on the pango markup language, please refer to: The Pango Markup Language - Quick Reference.

Related Links

Add comment


Security code
Refresh