[Gtk-sharp-list] How to Give a TreeView Row a Different Color?

Adam Tauno Williams awilliam at whitemice.org
Sun May 9 15:29:07 EDT 2010


On Sun, 2010-05-09 at 14:20 -0400, Andy York wrote:
> Jacek,
> In Gtk it is not common to alter the row color as it is controlled by
> the currently installed theme. I have had minor success with altering
> the appearance of widgets without changing the theme but it has been a
> frustrating task to say the least.

Actually it is pretty straight forward.  But you apply the change via
*cell* not *row*.  For example I have a method like -

    internal static void Effect(
      Gtk.TreeModel _model, 
      Gtk.TreeIter _iter,
      Gtk.CellRendererText _cell,
      Whitemice.ZOGI.Task _task)
    {
      /* Apply the "green bar effect" to make reading easier for older
users */
      if((_model.GetPath(_iter).Indices[0] % 2) == 1)
        _cell.BackgroundGdk = GUI.ColorForKey("oddRowBackground");
        else _cell.BackgroundGdk =
GUI.ColorForKey("evenRowBackground");;
      /* Make overdue tasks red and upcoming tasks blue */
      if ((DateTime.Today > _task.End)  && (_task.IsActive))
        _cell.ForegroundGdk = GUI.ColorForKey("overdueForeground");
        else if (_task.Start > DateTime.Today)
          _cell.ForegroundGdk = GUI.ColorForKey("upcomingForeground");
          else _cell.ForegroundGdk =
GUI.ColorForKey("defaultForeground");
    } /* End Effect */

- which gets called by all of the render methods, such as -

    internal static void RenderTitle(
      Gtk.TreeViewColumn _column, 
      Gtk.CellRenderer _cell, 
      Gtk.TreeModel _model, 
      Gtk.TreeIter _iter)
    {
      Task task = IterTask(_model, _iter);    
      if(task == null)
        return;
      task = (Task)_model.GetValue(_iter, 0);
      (_cell as Gtk.CellRendererText).Text = task.Name;
      Effect(_model, _iter, (_cell as Gtk.CellRendererText), task);
    } /* End RenderTitle */

This does mean you have to have render methods for every column; but,
honestly, you end up having to have lots of methods to do anything
useful with the horror that is TreeView anyway.

So you add columns to the TreeView like -

      column = new Gtk.TreeViewColumn ();
      column.Title = "Project";
      column.Reorderable = true;
      column.Resizable = true;
      column.Clickable = true;      
      cell = new Gtk.CellRendererText ();
      column.PackStart(cell, true);
      column.SetCellDataFunc(cell, 
        new Gtk.TreeCellDataFunc(RenderProject));
      _view.AppendColumn(column);

 - then RenderProject calls Effect.

Verbose, and kinda ugly, but it works 100% of the time; and you avoid
the silly madness that is the whole theme-thing.

I'm certain there is a faster and more elegant way to do the same thing
via Hyena - by there is no documentation. :(
-- 
Adam Tauno Williams <awilliam at whitemice.org> LPIC-1, Novell CLA
<http://www.whitemiceconsulting.com>
OpenGroupware, Cyrus IMAPd, Postfix, OpenLDAP, Samba



More information about the Gtk-sharp-list mailing list