Re: custom TreeModel



--- Jonathon Jongsma <jonathon jongsma gmail com>
wrote:

> On 5/19/06, Tamer Mowafy kalimakhus yahoo com wrote:
> > Second you may consider declaring your template
> > parameters like this:
> >
> > template < class T, template < class U, class =
> > allocator <U> > class TContainer>
> >
> > this makes your class instantiated with both the
> > container and the type it is storing. I just guess
> > that this may come handy later on.
> > In this case the member variable should look like
> > this:
> > TContainer<T>&  m_container;
> 
> I'd consider this.  Do you have a particular use
> case in mind?
Well, I can't be sure as I didn't studied all the
possible use-cases. I mean it depends on the
operations that can be performed on data through the
TreeView widget. It also depends on how you will
communicate with the user. Will it be enough to
communicate using iterators only or it would be
convenient at some time to use references of the
stored type. In fact it depends on how you think of
your class. Is it an adapter (a bridge between the
user's data and the TreeView), or it can also serve as
a data store. In the last case you will need to
provide functions that append, and insert new
instances into the container such functions will need
to know the type of the inserted object.
> > Another approach that should make your
implementation
> > more generic, is to use iterators to initialize
the
> > class rather than a whole container. This would
allow
> > the class to accept a wider range of containers
(even
> > arrays and pointers). Though this can be
problematic,
> > (After thinking this won't work for the purpose at
> > hand).
 
> If you initialize it with iterators, doesn't that
imply copying the
> values to a new container?  That doesn't seem quite
what we want.
Yes, this is why I added the last sentence.
> > Last point is the question, should the user
inherit
> > from your class or not? Well, it is there and it
has
> > virtual functions and some will do so even if you
> > provided some other alternative. Still for the
sake of
> > better view/model separation it should be better
that
> > they don't. You will still need to acquire
columns'
> > values from the user as well as communicating back
the
> > mutations performed on these values through the
UI.
> > One way to do that is to use some helper class
let's
> > say ValuesProvider. The user can inherit from it
and
> > supply a pointer/reference to your class that can
call
> > the helpers functions to get values for each row
of
> > data (or each column individually) as this is
needed.
> > It can pass an iterator over the container. If you
> > have a reference to the container rather than a
copy
> > such iterators will be valid ones. By the way this
> > approach is used in the java API of eclipse namely
in
> > the jface package. 
> I'm having a hard time picturing exactly what sort
> of interface you're
> talking about here.  Do you have any pseudo-code
> that you could use to explain a bit more clearly?
class GenericTreeModelDataProvider
{
     virtual void get_column_value( const iterator&
rowIter,
                                                      
 size_t colNum,
                                                      
 Glib::ValueBase& value) = 0;
    // other virtual functions
}
In your class
protected:
	GenericTreeModelDataProvider*     m_pDataProvider;
public:
            void 
set_data_provider(GenericTreeModelDataProvider *
pProvider)
	{   m_pDataProvider = pProvider; }
Then in (for instance) get_value_vfunc(const
TreeModel::iterator& iter, int column,
Glib::ValueBase& value) const.
Convert TreeModel::iterator -?³ to
TContainer::iterator 
Call:		m_pDataProvider->get_column_value(¡K);
In the user code it will be simple to do something
like
switch( colNum)
{
case 0:
	((*rowIter)->m_some_member) -?³ // put that in a
suitable Glib::Value<T>
Case 1:
	((*rowIter)->m_some_other_member) -?³ // put that in
a suitable Glib::Value<T>
}
The user's code will look just like what is done in
the CVS sample in the get_value_vfunc implementation.
> > Some other approach is to use signals that the
user
> > can connect to and supply column values through
his
> > slots.
> 
> For some reason, this seems more complicated to me. 
> I'm not sure I like it.
Well, it doesn't have to be a signal. In fact it
better be just a callback, you can do something like
this:
typedef   sigc::slot<void, const
TContainer::iterator&, int, Glib:;ValueBase&>  
GetColumnValueCallback;
void
set_get_column_value_callback(GetColumnValueCallback&
user_func);
you keep the slot in some member variable and call it
whenever needed.
This has the advantage that the user doesn't need to
implement a whole class for the purpose of
communicating column values to your class. A sigc++
slot can wrap a stand alone function or a class member
function (the class should inherit from
sigc::trackable but all Gtkmm widgets do inherit from
it).
> > I hope these notes are not totally out of point.
> 
> Not at all.  Thanks for your comments.
> 
> Jonner
>


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



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