Re: TreeView Design
- From: Samvel <ksamdev gmail com>
 
- To: "Gareth Foster" <earthwormgaz googlemail com>
 
- Cc: gtkmm-list gnome org, paul linuxaudiosystems com
 
- Subject: Re: TreeView Design
 
- Date: Thu, 31 Aug 2006 10:43:26 -0500
 
On Thu, 31 Aug 2006 09:41:35 -0500, Gareth Foster  
<earthwormgaz googlemail com> wrote:
struct Derived: public Base { ... };
Yes, sorry.
it->member = <any pointer to a class/struct that derived from Base>;
But what about setting the data therein, using GTKmm, things like this
are possible:
Gtk::TreeModel::Row row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = 1;
I am trying to get my head around the magic that makes this possible.
Hope that makes more sense.
Gaz
Oh, now I see. You want similar behaviour as in GTKmm: the magic of  
putting something into a row when columns are specified somewhere else. I  
was thinking about the same yesterday /I am a newbie in GTKmm/ but here is  
what I have found /it is beautiful implementation and use of  
C++ templates/ :)
	row[m_Columns.m_col_id] = 1
is equivalent to:
	row.operator[]( mColumnst.m_col_id).operator=( 1);
[1] gtkmm/treeiter.h /TreeRow<A>::operator[](...) implementation/
template <class ColumnType> inline
TreeValueProxy<ColumnType> TreeRow::operator[](const  
TreeModelColumn<ColumnType>& column) const
{
  return TreeValueProxy<ColumnType>(*this, column);
}
this should be clear: operator=(...) is a member of Template:  
TreeValueProxy.
[2] gtkmm/treeiter.h /TreeValueProxy<A>::operator =(...) implementation/
template <class ColumnType> inline
TreeValueProxy<ColumnType>& TreeValueProxy<ColumnType>::operator=(const  
ColumnType& data)
{
  row_.set_value(column_, data);
  return *this;
}
data is your '1'
So, set_value for a given row is called and returned reference to a given  
object to make nested '=' operators possible. Not a surprise.
[3] gtkmm/treeiter.h /TreeValueProxy declaration/
template <class ColumnType>
class TreeValueProxy
{
public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  inline TreeValueProxy(const TreeRow& row, const  
TreeModelColumn<ColumnType>& column);
#endif
  inline TreeValueProxy<ColumnType>& operator=(const ColumnType& data);
  inline operator ColumnType() const;
private:
  const TreeRow&                      row_;
  const TreeModelColumn<ColumnType>&  column_;
  // no copy assignment
  TreeValueProxy<ColumnType>& operator=(const TreeValueProxy<ColumnType>&);
};
row_    is a reference to our recently added row
column_ is a reference to our TreeModelColumn where you specified type of  
a given column :)
Do you remember writing something like?:
class ModelColumns: public Gtk::TreeModelColumnRecord {
  public:
    ModelColumns();
    virtual ~ModelColumns() {}
    Gtk::TreeModelColumn<std::string>		      cFileName;
    Gtk::TreeModelColumn<std::string>		      cDescription;
    Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > oThumbnail;
    // Next column will be hidden unless it is not added to a list of
    // visible ones with TreeView::append_column(...)
    Gtk::TreeModelColumn<std::string>		      cHiddenData;
};
/In your case it is a little bit different/
[4] gtkmm/treeiter.h /TreeRow::set_value implementation/
template <class ColumnType>
void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const  
ColumnType& data) const
{
  typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
  ValueType value;
  value.init(column.type());
  value.set(data);
  this->set_value_impl(column.index(), value);
}
Now you see that column /TreeModelColumn<A>/ is not used at all except  
grabbing a type of a given column. That's it. Very simple and very  
beautiful. Here you create some object of given type, assign value to it  
and that's it: you've got a cell in a given row/col.
So, if you want the same kind of flexibility in your code do something  
similar just don't mess with Templates.
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
[
Date Prev][
Date Next]   [
Thread Prev][
Thread Next]   
[
Thread Index]
[
Date Index]
[
Author Index]