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 92 93 94 95 96 97 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| <?php $window = new GtkWindow(); $window->set_size_request(400, 320); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox()); $accel_group = new GtkAccelGroup(); $window->add_accel_group($accel_group);
$highlight_qty = 1; $highlight_price = 1;
// define menu definition
$menu_definition = array( '_File' => array('_Quit|Q'), '_Test' => array('Show All Rows|1', 'Show Rows where Qty > 10|2', 'Show Rows where Price < $10|3'), ); setup_menu($vbox, $menu_definition);
// display title
$title = new GtkLabel("Selectively highlight some cells in treeview"); $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("Press Ctrl-1 to for default view\nCtrl-2 to highlight qty > 10\nCtrl-3 to highlight price < \$10"), 0, 0); $vbox->pack_start(new GtkLabel(), 0, 0); // add a small gap
// Set up a scroll window
$scrolled_win = &new GtkScrolledWindow(); $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); $vbox->pack_start($scrolled_win);
// the 2D table
$data = array( array('row0', 'item 19', 2, 3.1, 1), array('row1', 'item 16', 20, 6.21, 1), array('row2', 'item 13', 8, 9.36, 1), array('row3', 'item 10', 11, 12.4, 1), array('row4', 'item 7', 5, 15.5, 1), array('row5', 'item 4', 17, 8.6, 1), array('row6', 'item 3', 20, 21.73, 1));
display_table ($scrolled_win, $data);
function display_table($scrolled_win, $data) { // Creates the list store
global $model, $view; if (defined("GObject::TYPE_STRING")) { $model = new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING, GObject::TYPE_LONG, GObject::TYPE_DOUBLE, GObject::TYPE_BOOLEAN); } else { $model = new GtkListStore(Gtk::TYPE_STRING, Gtk::TYPE_STRING, Gtk::TYPE_LONG, Gtk::TYPE_DOUBLE, Gtk::TYPE_BOOLEAN); } $field_header = array('Row #', 'Description', 'Qty', 'Price'); $field_justification = array(0.0, 0.0, 0.5, 1.0);
$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); $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); }
// setup selection
$selection = $view->get_selection(); // get the selection associated with the view
$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
if ($col_num==3) { $amt = $model->get_value($iter, 3); $cell->set_property('text', '$'.number_format($amt,2)); } global $highlight_qty, $highlight_price; $row_color = ($row_num%2==1) ? '#dddddd' : '#ffffff'; // note 1
if ($highlight_qty) { // note 2
$qty = $model->get_value($iter, 2); if ($qty>10 && $col_num==2) $row_color = '#FF3366'; }
if ($highlight_price) { // note 3
$amt = $model->get_value($iter, 3); if ($amt<10 && $col_num==3) $row_color = '#99FF99'; }
$cell->set_property('cell-background', $row_color); }
// the function that is called when user selects a row
function on_selection($selection) { list($model, $iter) = $selection->get_selected(); if ($iter==NULL) return; $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"; }
// setup menu
function setup_menu($vbox, $menus) { global $accel_group; $menubar = new GtkMenuBar(); $vbox->pack_start($menubar, 0, 0); foreach($menus as $toplevel => $sublevels) { $menubar->append($top_menu = new GtkMenuItem($toplevel)); $menu = new GtkMenu(); $top_menu->set_submenu($menu); foreach($sublevels as $submenu) {
|
October 02, 2008 9:36pm
This is exactly what we're trying to do inside our code, but we can't make it work. Any reason why when you set the TreeView in a class and then try to set the cell renderer property after the fact, you get the whole column, instead of a specific cell???
October 02, 2008 10:33pm
Hi,
My guess is that you have overlooked some "minor details" in your custom display function.
One of the "most tricky" part about the custom display function is that when you try to highlight a cell by setting some attributes on (e.g. change the foreground or background color), the effect remains there for subsequent cells. You need to manually set the attributes back to its original state for those cells that you do not want to highlight. If you do not set it back, you will see the whole column or whole row highlighted, just like what you're seeing.
I've actually written 3 sample codes to explain some of these techniques in detail:
Sample Code 512: How to change the font of some rows or columns in treeview?
Sample Code 513: How to change the foreground color of some rows or columns in treeview?
Sample Code 514: How to change the foreground and background color of some rows or columns in treeview?
Once you understand the above examples, you should be able to resolve your issue.
Regards,
/kksou
October 06, 2008 1:28am
Fantastic!!!! I talked to 3 other sites on this one, and nobody had a clue. You've almost saved my life.
Just one small thing. I can get this to work using the set_cell_data_func, but not inside a for loop for the treestore. Same idea; set the cell renderer background if I match a value, otherwise set it to 0. But this way I get the entire column colored.
Any idea why?
thanks.
October 06, 2008 1:46am
Hi,
Glad it works!
Could you please elaborate a bit what do you mean by "inside a for loop for the treestore"? How do you actually "set the cell renderer background" for the treestore? Is it possible for you to show me a few lines of code so that I have a better picture?
Regards,
/kksou
October 06, 2008 10:57pm
Tried several different ways. Current version loops through the data rows, retrieves the cell-renderer, checks to see what the value is for the specific column and looks up a matching color. If found, we use the same set-property', 'background-set' to change the cell display. If not, we 'background-set' to 0.
It seems like the flaw has to be in here:
$readColumn = $inView->get_column(11);
$rendArray = $readColumn->get_cell_renderers();
$cellRend = $rendArray[0];
But we can't find any way to read cell-renderer for a specific cell, instead of a column. And again, why does something pretty similar work for the callback?
thanks.
October 06, 2008 11:25pm
Hi,
Want to know why it didn't work? Because whatever you do elsewhere, it's the custom display function that gets the final say.
Think of it as the final make-up area just before the actors go on stage.
So just do any formating you want in the custom display function and you should be fine.
Regards,
/kksou
October 07, 2008 11:15am
Not sure I follow. If custom display function means the callback for set_cell_data_func, I get the same results, even if the callback isn't set...??
thanks.
October 07, 2008 9:16pm
Did you realize that one single cellrenderer is used for the entire GtkTreeViewColumn?
What this means that when you set the property on one cellrenderer, it will affect the entire column.
Which is why you have the custom display function to allow you to do any formatting before it is being displayed for a particular cell.
Think of it as a global setting vs local setting. When you set any property direct on the cellrender, it's a global setting. If you need to do any local setting, you do this in the custom display function.
Regards,
/kksou