Re: [gtk-list] Re: an additional argument flag



> > Therefore, either we duplicate all the "widget setup" code in each
> > _new() into the gtk-- constructors (which is what we currently do,
> > since it's quite tolerable for most widgets), or we get a new entry
> > point in the construction chain right after the call to
> > gtk_type_new().

Owen Taylor <owt1@cornell.edu> writes:
> Hmmm, some day I'm going to have to take a look at gtk-- and see
> what is going on there. I get the feeling that there is some
> horrible perversion of the GTK type system going on there. ;-)
> 
> Does gtk-- actually _change_ the type of the created widget. I don't
> see how this is necessary, or how it can successfully be integrated
> with normal GTK+ code.

For overriding virtual methods from C widgets, gtk-- "derives" from every
gtk widget and thus it has separate type and more importantly, its own
virtual function table. Then in the new type's class_init, gtk--
replaces that existing entries in the C virtual function table with
functions that call C++ virtual methods (these C++ virtual methods
of course then call the default implementation of what the widget
would have done anyway..). This way, you can after derivation override
everything gtk provides in its widgets.

> What I would expect is the gtk-- heirarchy would parallel the
> GTK heirarchy, and a gtk-- object would keep a pointer to
> the corresponding GTK object. 

This is what it does.

> But something more complicated
> is clearly being done. Is there a description of the design
> of gtk-- anywhere? (Somebody may have emailed me some more details
> earlier, but I can't find the relevant message, if so)

There is description of the calls going on when you emit a signal described
at start of src/gtk--sig.h from the gtk-- package. I'll cut/paste it here:

/*
  Some implementation documentation about how we deal with existing C widgets:
  * Each C widget has its signals represented in 4 parts:
        (we'll handle Gtk_Object::destroy as example)
     1) function object handling connections and emitting the signal
          Signal_proxy0<void,Gtk_Object> destroy;
     2) *_impl -virtual method for trapping the calls to existing C
        implementation of the signal
          virtual void destroy_impl();
     3) a static method as an replacement of gtk_real_object_destroy,
        which figures out from first arg about which C++ object we have
        and calls the *_impl method on that object
          static void destroy_callback(GtkObject *o);
     4) A structure (c_signals) keeping all old function pointers
     5) c_class static object keeping all per-class data/methods needed,
        for example the signals are kept there.

     * Calling Gtk_Object::destroy starts the following
       function calls:
       * Gtk_Object::destroy()    (called by user)
        * gtk_object_destroy(o)   (see  NOTE1 below)
        * Gtk_Object::destroy_callback(o) (see NOTE2 below)
        * Gtk_Object::destroy_impl()
        * gtk_real_object_destroy(o) (see NOTE3 below)

      And this way, by overriding the destroy_impl function does work
      as supposed.

  NOTE1: that isnt done correctly currently (13 Dec 97), now it calls
         gtk_signal_emit instead and works in most cases, not all.
  NOTE2: Gtk does call this, because we did set the value of the virtual
         function table pointing to Gtk_Object::destroy_callback
  NOTE3: We have stored old pointer from the virtual function table to
         an instance of C class and that points to gtk_real_object_destroy(o)
         and we can thus call it from Gtk_Object::destroy_impl
  */


> The problem is quite clear:
> 
>  Some widgets need to do initialization that _depends_ on 
>  the parameters that are passed in. However, no parameters
>  are passed to the _init() function. So this has to be
>  done in the new () function. (The list of such functions
>  is currently quite short though)
> 
>   - Tim doesn't like it, because he wants to do his 
>     gtk_widget_new (...) thingy.

Oh btw, gtk-- uses the gtk_widget_new(gtk_foobar_get_type()) and then
the cut/paste code got from existing widgets *_new() messes up with
the internal structure of the widgets depending on what kind of args
we got...

>   - Tero and Guillaume don't like it, because they want want
>     to do there black magic with widget types.
> 
>   - Normal people (;-) don't like it, because they can't
>     derive new widgets without rewriting the new() function.

Deriving from widgets is the only thing we need to do with gtk--. No
black magic involved. Deriving from widgets currently requires that
we rewrite all *_new() methods. On some widgets this cut/paste is kinda
large as there is static methods called from *_new() methods :)

Note that this cut/paste is still present in C++ too as everyone need
to cut/paste all constructors when they derive from a class. The
problem is solved in C++ usually by making a new method and making the
constructor call it. => thus cut/paste goes to minimum.

> But I'm not sure what people are proposing to do about it.
> 
>  ??? Tim's solution: mark all mandatory arguments of the widget
>      with a flag, then have a special "construct" signal that
>      does the argument-dependent initialization _after_
>      the the mandatory arguments have been set. ??? (This is
>      a bit ugly for people who don't want to do a query_args()
>      type dynamic thing, though such people should be able
>      to look a the source code and figure out there own way
>      of setting the mandatory arguments)
> 
>  ??? gtk-- solution: Give each widget that needs it, 
>      a special (non-virtual) _construct() function that
>      takes the necessary arguments ??? (This is not going to
>      solves Tim's problem.

Best for gtk-- would be to create for example the following:
  gtk_button_construct()
  gtk_button_construct_with_label(char*)

And those would not mess up with the type... and then the normal
gtk_button_new() and gtk_button_new_with_label(char*) would create the
object of specific type and then call the approciate construct()
functions.

(button isnt perfect example of this as the cut/paste code isnt that
much in there, but it would remove dependencies between gtk-- and gtk
widgets internals.)

-- 
-- Tero Pulkkinen -- terop@modeemi.cs.tut.fi --



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