[gtkmm] TreeView rendering



I modified a program that Mathew Walton posted last week that show changing the colors for individual cells.  I extended it to change colors of 'virtual' cells as well.  I'd like comments:

#include <sstream>
#include <gtkmm/treeview.h>
#include <gtkmm/treestore.h>
#include <gtkmm/window.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/main.h>
#include <gtkmm/scrolledwindow.h>

// copied right out of Stroustrup, C++ Programming Language, 3rd Edition, 8th printing, pg 686/
class RandInt
{
  unsigned long randx; 
 public:
  RandInt(long s = 0) { randx=s; }
  void seed(long s) { randx=s;}
  
  int abs(int x) {return x&0x7fffffff;}
  static double max() {return 2147483648.0;} 
  int draw() { return randx=randx*1103515245 + 12345; }
  
  double fdraw() { return abs(draw())/max(); }
  int operator()() { return abs(draw()); }
};
class Urand : public RandInt { // uniform distribution in the interval [0:n]
  int n;
 public:
  Urand(int nn) { n = nn; }
  int operator()() {int r = static_cast<int>(static_cast<double>(n)*fdraw()); return (r==n) ? n-1 : r;}
};
// end Stroustrup copy

// Modification of program pulled off the gtkmm mailing list <gtkmm-list gnome org>
// April 01, 2004 posted by Mathew Walton <matthew alledora co uk>

class DemoTree : public Gtk::TreeView
{
  private:
    struct Columns : public Gtk::TreeModelColumnRecord             
    {
      // One title colum
      Gtk::TreeModelColumn<Glib::ustring> column1;

      // Now we have vectors of columns containing raw data
      // and colors to put in the background of the treeview
      // in this respect the color columns are "hidden" columns.

      std::vector<Gtk::TreeModelColumn<int> > data;
      std::vector<Gtk::TreeModelColumn<Glib::ustring> > color;

      Columns() { 
	int cols = 0;  // track number of data/color columns.
	add(column1);

	// model will look like:
	// col1 data1 color1 data2 color2 data3 color3 data4 color4 data5 color5

	for (int j=0; j<2; ++j)
	  {
	    // Create 5 data columns and 5 color columns
	    for (int k = 0; k<5; ++k)
	      {
	       
		Gtk::TreeModelColumn<int> d;
		data.push_back(d);
		add(data[cols]);

		Gtk::TreeModelColumn<Glib::ustring> c;
		color.push_back(c);
		add(color[cols]);
		++cols;
	    }
	  }
      }
    };
    Columns columns;

    Gtk::CellRendererText* cell_renderer_text;
    Gtk::TreeViewColumn* color_column;
    Gtk::TreeRow row;

  public:
    Glib::RefPtr<Gtk::TreeStore> treestore;

    DemoTree()
    {
      treestore = Gtk::TreeStore::create( columns );
      set_model( treestore );

      append_column("DemoColumn", columns.column1);
      for (int i =  0; i < 2; ++i)
	{
	  Glib::ustring title("data 1");
	  if (i == 1) title = "data 2";

	  // Allocate our own column
	  Gtk::TreeView::Column* pColumn = Gtk::manage(new Gtk::TreeView::Column(title));

	  append_column(*pColumn);

	  // sets up 5 "virtual" columns, for each treeview column and pack them into the column
	  for (int j = 0; j < 5; ++j)
	    {
	      int idx = i*5 + j;
	      Gtk::CellRendererText* pRenderer = Gtk::manage( new Gtk::CellRendererText() );
	      pColumn->pack_start(*pRenderer,false);
	      pColumn->add_attribute(pRenderer->property_text(),columns.data[idx]);
	      pColumn->add_attribute(pRenderer->property_background(),columns.color[idx]);
	    }
	}
    }
  
  Glib::ustring calc_color( const int& val )
  {
    Glib::ustring color("red");
    if (val < 50)
      color = "blue";
    return color;
  }
  
  void AddRow( const Glib::ustring &name, const std::vector<int>& data)
  {		
    row = *(treestore->append());
    row[columns.column1] = name;

    int datasize = data.size();
    Glib::ustring color;

    for (int i = 0; i < datasize; ++i)
      {
	int raw_data = data[i];
	color = calc_color(raw_data);
	row[columns.data[i]] = raw_data;
	row[columns.color[i]] = color;
      }
    }
};

class DemoWindow : public Gtk::Window
{
  DemoTree dt;
  Gtk::ScrolledWindow scroll_window;
  Gtk::VBox vbox_main;
  Gtk::Button btn_Refresh;

  public:	
  DemoWindow() 
  {
    set_default_size( 400, 600 );

    scroll_window.add( dt );
    scroll_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
    vbox_main.pack_start( scroll_window );

    btn_Refresh.set_label("Refresh");
    btn_Refresh.signal_clicked().connect( SigC::slot(*this, &DemoWindow::btn_refresh_click) );
    vbox_main.pack_start( btn_Refresh, Gtk::PACK_SHRINK );


    btn_refresh_click();//fill 'er up :P

    add(vbox_main);
    show_all_children();
  }

  void btn_refresh_click()
  {
    static int seed = 987654;
    Urand value(100);
    value.seed(seed++);
    std::vector<int> v(10);
    dt.treestore->clear();
    for(int i = 0; i < 200; i++) 
      {
	for (int j = 0; j < 10; ++j)
	  {
	    v[j] = value();
	  }
	std::ostringstream ostr;
	ostr << "Testing " << i;
	dt.AddRow(ostr.str(), v);
      }
  }
  
};


int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  DemoWindow dw;
  Gtk::Main::run(dw);
}




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]