On Thu, 31 Aug 2006 09:41:35 -0500, Gareth Foster  
<[EMAIL PROTECTED]> 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/
_______________________________________________
gtkmm-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Reply via email to