[Glade-devel] Property Binding Support: Present and Future

Alexandre Mazari scaroo at gmail.com
Thu Sep 1 04:32:58 EDT 2011


Hi  Denis,

Thanks you very much for this amazing work.

I was wondering if the current code allows the binding of a 'model'
instance property to a widget's one. By model I mean non-graphical
non-glade-handled GObject. Is there some way to expose some arbitrary
GObject in the GtkBuilder context so we can bind its properties ?

Regarding transformation, would'nt providing default transformations
(int <-> string, percentage <-> double in 0...1, etc.. ) make you life
easier by not supporting user provided functs while covering 90%
percent of use cases ?

Happy Coding,
Alexandre

On Thu, Sep 1, 2011 at 9:58 AM, Denis Washington <denisw at online.de> wrote:
> Hello,
>
> As you may know, I took part in Google Summer of Code this year (thanks
> to Juan for mentoring me!) and worked on "GObject property binding
> support for GtkBuilder and Glade":
>
> https://live.gnome.org/DenisWashington_GtkBuilder
>
> While talking on IRC with Tristan yesterday, I realized that while I
> sent out weekly reports to gnome-soc-list and blogged about my work
> twice, I never actually wrote anything about the code's status or
> technical details on this mailing list. I would like to apologize for my
> failure to do so and will try to make up for it by telling you
> *everything* in this message: what I have done, how I have done it, what
> works now, where the remaining problems are, and how these issues could
> be overcome (this is where I really need your feedback!).
>
> For those who don't know, the objective of my work is to extend Glade
> with support for creating bindings between widget properties in a
> project. What this means is that you can define a property's value as
> being directly dependent on the value of another property - whenever the
> "source" property's value is set, the value of the "target" property is
> automatically updated, either to the same value or a user-defined
> transformation thereof (more on this later). GLib supports this through
> its GBinding API [1]. The goal is to expose this functionality in Glade
> so that the user can create, modify and delete property bindings in
> Glade and save them as part of a UI file.
>
> This feature requires changes to both GTK+ and Glade, so I created
> git.gnome.org branches for both of them, named "gtkbuilder-gbinding" and
> "gbinding", respectively [2][3]. The GTK+ branch adds support for a new
> bit of GtkBuilder syntax - the <binding> element - which makes it
> possible for GtkBuilder objects to read property bindings from UI files.
> It is used like this:
>
>   <object name="button">
>     ...
>     <binding to="sensitive" from="active" source="checkbutton"/>
>   </object>
>
> which means: "Let the 'sensitive' property of 'button' always have the
> same value as the 'active' property of 'checkbutton'." Thanks to the
> existence of GBinding, the code changes required for this are pretty
> small. No new API is introduced; all bindings are automatically created
> at the time they are read in by gtk_builder_add_from*(). (But this might
> change slightly; see the problem discussion later in this epic mail
> message).
>
> The "gbinding" Glade branch is where the bulk of my work happened. It
> adds a new "binding-source" property to GladeProperty for representing
> property bindings in the data model and supports serialization and
> deserialization of this information to <binding> elements. (See
> glade_property_binding_read() and glade_property_binding_write() in
> glade-property.c, respectively.) Furthermore, it augments Glade's
> undo/redo framework with a glade_command_bind_property() command for
> creating and deleting property bindings. On the UI side, this command is
> exposed through a "Bind to source..." context menu item in the property
> inspector. (For screenshots of how the UI currently looks, see my blog
> posts [4][5].)
>
> The UI and data model has been adapted to reflect the defined property
> bindings:
>
> - glade_command_set_property() was modified to recursively set the value
> of all properties bound to the originally set property. This means that
> the effect of a property binding is immediately visible in the Glade
> workspace.
>
> - In the property inspector, the edit widgets for bound properties are
> insensitive (setting the value of a bound property doesn't make much
> sense). Also, the tooltip of a bound property shows which other property
> it is bound to.
> (See glade-editor-property.c)
>
> Also, I made some precautions to avoid invalid property bindings:
>
> - The "Bind to source..." dialog for choosing the source of a property
> binding only allows you to select properties that have the same, or a
> compatible, type, and are enabled (if they are optional) and sensitive
> (if there are one of multiple alternative properties, e.g. "text",
> "stock" and "embedded widget" in GtkButton). All other properties are
> greyed out and moved to the end of the list.
> (See glade_editor_property_show_bind_dialog() and its helper functions
> in glade-editor-property.c)
>
> - If the source or target of a property binding disappears because the
> widget it belongs to is deleted, the binding is automatically removed
> too. This is properly integrated into the undo/redo system, so undoing
> the widget removal also brings the property binding back.
> (See glade_command_delete_binding_refs() in glade-command.c)
>
> One remaining issue with the current code is that it does not react to
> property binding sources becoming disabled or insensitive. This is
> currently not possible in a sane way as changes to a property's
> enabled/sensitivity state are not tracked with the undo/redo framework
> at the moment. (I had code to do this in the branch before, but it
> worked with manual signal handling hackery and was removed later on
> Tristan's request.) The obvious solution would be to change this by
> introducing glade_command_set_property_enabled() and
> glade_command_set_property_sensitive() and porting all of Glade to that.
> If there is general agreement to do so, I would be willing to do that
> work. In any case, this has to be fixed in some way before the branch is
> ready to be merged into master.
>
> Other than that, I don't know of any other major showstoppers, but an
> extensive code review by Juan and Tristan might very well reveal some. ;)
>
> The big question, however, it how to support transformation functions
> for property bindings. This GBinding feature allows you to define a
> function that processes the value of a binding's source property before
> it is applied to the target, which allows you to create bindings between
> properties of different types and generally make property bindings much
> more useful and interesting. Adding this into the GTK+ and Glade
> branches is not a big problem in principle, and in fact I did just that
> during Summer of Code. However, I had to later remove the code again,
> the reason being on the GTK+/GLib side.
>
> The problem is when and how to resolve the transformation function names
> that would be stored in the GtkBuilder file to the actual function
> implementations. In my code, I moved all property binding creation to
> two new API functions, gtk_builder_create_bindings() and
> gtk_builder_create_bindings_full(), which take the same arguments as
> gtk_builder_connect_signals*() and locate transformation functions the
> same way (GModule or a custom callback, called GtkBuilderBindingFunc).
>
> Unfortunately, this setup means more work for language binding authors:
> because transformation functions are specified as an argument to
> g_object_bind_property_full() rather than by connecting a signal, a
> language-specific GtkBuilderConnectFunc for
> gtk_builder_connect_signals*() cannot be reused and each language
> binding would be required to provide a GtkBuilderBindingFunc to replace
> the use of GModule with something appropriate for the language. Also,
> the introduction of another function to be called for every loaded
> GtkBuilder function is really not ideal.
>
> Talking with Juan and Tristan, we concluded that a proper solution
> probably requires changes to GBinding itself. More specifically, if
> GBinding implemented the transformation function as being the handler of
> a "transform" signal instead of an anonymous callback, one could reuse
> gtk_builder_connect_signals*() to locate transformation functions and
> move property binding creation there. For backwards compatibility and
> convenience, the g_object_bind_property() API could still stay as it is
> now. There would be some issues to sort out - for instance, how to
> behave if multiple signal handlers are connected to the "transform"
> signal - but it might be doable without breaking anything. This still
> needs to be talked about with both the GLib and GTK+ team, though.
>
> For reference, you can still find my code with transformation function
> support in the "gtkbuilder-gbinding" GTK+ and "gbinding-transform" Glade
> branch.
>
> Well, this is all there is to say about the code now. (This mail is
> already way too long as it is. ;) I hope you now have a better insight
> wrt what I have done during GSoC and what is still to do.
>
> As I wrote in the beginning, I need your feedback! If you have any
> questions, remarks, or suggestions regarding the issues I outlined -
> especially regarding the transformation function situation - I would be
> excited to hear them! Thanks. :)
>
> Regards,
> Denis
>
> [1] http://developer.gnome.org/gobject/unstable/GBinding.html
> [2] http://git.gnome.org/browse/gtk+/log/?h=gtkbuilder-gbinding
> [3] http://git.gnome.org/browse/glade/log/?h=gbinding
> [4]
> http://denwash.wordpress.com/2011/06/10/glade-and-property-binding-finally-something-to-see/
> [5]
> http://denwash.wordpress.com/2011/07/20/glade-and-property-binding-create-your-own-bindings-now/
> _______________________________________________
> Glade-devel maillist  -  Glade-devel at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/glade-devel
>



-- 
"If you open your mind too much, you brain will fall out"
Tim Minchin


More information about the Glade-devel mailing list