Re: Subclassing a Gtk2::TreeStore
Thanks Torsten and Scott. I've looked at it some more and I suspect I have two separate problems in addition to my initial lack of understanding :( Torsten Schoenfeld wrote: I haven't tested it in a complete application, but this seems to work: package MyTreeStore; use Glib qw(TRUE FALSE); use Gtk2; use Glib::Object::Subclass 'Gtk2::TreeStore', ; sub drag_data_received { my ($self, $dest_path, $selection_data) = @_; return $self-SUPER::drag_data_received ($dest_path, $selection_data); } 1; package main; my $store = MyTreeStore-new (qw/Glib::String/); $store-drag_data_received (undef, undef); Note how drag_data_received is overridden simply how you'd override any other method in normal Perl code, and how the parent's drag_data_received is invoked. That code compiles and starts to run for me too. Unfortunately, it's too simple in two ways. Firstly, my tree has more than one column and as soon as I change the call to MyTreeStore-new to have more than one column, I get the error again e.g.: my $tree_store = MyTreeStore-new(qw/Glib::String Glib::Int/); type MyTreeStore does not support property 'Glib::String' At least I now know that the error is caused by multiple args. Any idea on how to make the constructor work for trees with multiple columns? I'll keep experimenting. Secondly, and potentially more serious, is related to Scott's comments: muppet wrote: To be a little more explicit, this works because where you need it to be overridden is in your own code, where perl's method lookup can work normally. I don't think my code is where I need it to be overridden. I don't have any plans to call drag_data_received. It's called automatically by gtk+ as part of the treeview drag'n'drop mechanism. What I do want to do is influence what it does. From what you say, I suspect I can't to this. So before I waste more of everybody's time chasing something that's not possible, I'd better explain the big picture and you can hopefully suggest a better way to achieve my goal. My application is a tree editor. All the branches are the same height and nodes are typed according to their height (family, species etc). Only rearrangements that keep nodes at the same height should be permitted - you can't turn a species into a family, for example. The treeview drag'n'drop does pretty much everything I need. In my current code, I just call enable_model_drag_source and enable_model_drag_dest and gtk+ does the rest. But that allows a node to be dropped anywhere, so I need to find a hook somewhere that allows me to either prevent the node being dropped or force the drop destination to be the nearest node of the correct type. I favoured the latter option, given the well-known pixel sensitivity of the interface, and that's why I'm trying to override drag_data_received. But any other solutions are more than welcome. Trying to override drag_data_received as a signal won't work, because it's not a signal. Yes, that's why I was very surprised to see the suggestion in the section 'OVERRIDING BASE METHODS' on the page http://gtk2-perl.sourceforge.net/doc/pod/Glib/Object/Subclass.html. I think it could use rewording but I'm not sure exactly what it's trying to say. Is the section wrongly titled? Should it be something like 'OVERRIDING SIGNAL IMPLEMENTATIONS IN BASE CLASSES'? Cheers, Dave ___ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Re: Subclassing a Gtk2::TreeStore
Torsten Schoenfeld wrote: I see. Unfortunately, it doesn't seem to be possible to override just one interface method of some class (like row-drop-possible). You have to implement the whole interface, and that means implementing a completely custom tree model. But I think you can achieve what you want by using Gtk2::Widget's d'n'd stuff. For example: snip code Excellent! That works perfectly. Thanks again, Dave ___ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Re: Subclassing a Gtk2::TreeStore
On Mon, 2007-10-29 at 14:50 +0100, Torsten Schoenfeld wrote: I don't think my code is where I need it to be overridden. I don't have any plans to call drag_data_received. It's called automatically by gtk+ as part of the treeview drag'n'drop mechanism. What I do want to do is influence what it does. From what you say, I suspect I can't to this. I see. Unfortunately, it doesn't seem to be possible to override just one interface method of some class (like row-drop-possible). You have to implement the whole interface, and that means implementing a completely custom tree model. in C, I would just subclass GtkListStore with: G_DEFINE_TYPE_WITH_CODE (MyListStore, my_list_store, GTK_TYPE_LIST_STORE, G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE, gtk_tree_drag_source_init)); and in gtk_tree_drag_source_init() I'd override the virtual functions of the interface. in Perl I would expect that the following code would be the equivalent: use Glib::Object::Subclass 'Gtk2::ListStore', interfaces = [ 'Gtk2::TreeDragSource' ]; and the implementations: sub ROW_DRAGGABLE { my ($drag_source, $path) = @_; return is_my_row_draggable(); } sub DRAG_DATA_GET { my ($drag_source, $path, $selection_data) = @_; # fill $selection_data with the contents of the $path return TRUE; } which, as far as I can see from the code, is the case (usual disclaimer applies: I haven't tested it with real Perl code). internally, the TreeView widget will call gtk_tree_drag_source_row_draggable() which will call into the Perl bindings, which in turn will call the ROW_DRAGGABLE sub. this is, by the way, what I meant by override the override the Gtk2::TreeDragDest interface method above, in order to control whether the destination row is a valid drop point in the original mail. I'd say that, if this doesn't work, it should be considered a bug of the Perl bindings, as the code works perfectly fine from C (I used it inside the GtkFileChooser default implementation for GTK+ 2.12). ciao, Emmanuele. -- Emmanuele Bassi, W: http://www.emmanuelebassi.net B: http://log.emmanuelebassi.net ___ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Re: Subclassing a Gtk2::TreeStore
Emmanuele Bassi wrote: in C, I would just subclass GtkListStore with: snip code which, as far as I can see from the code, is the case (usual disclaimer applies: I haven't tested it with real Perl code). internally, the TreeView widget will call gtk_tree_drag_source_row_draggable() which will call into the Perl bindings, which in turn will call the ROW_DRAGGABLE sub. this is, by the way, what I meant by override the override the Gtk2::TreeDragDest interface method above, in order to control whether the destination row is a valid drop point in the original mail. I think I tried something like this, as I mentioned in http://mail.gnome.org/archives/gtk-perl-list/2007-October/msg00059.html but I got: GLib-GObject-WARNING **: cannot add interface type `GtkTreeDragDest' to type `MyTreeStore', since type `MyTreeStore' already conforms to interface I'd say that, if this doesn't work, it should be considered a bug of the Perl bindings, as the code works perfectly fine from C (I used it inside the GtkFileChooser default implementation for GTK+ 2.12). I don't know enough to know whether it's a bug or not. Torsten gave me another solution that worked but I can imagine there are other circumstances where being able to override a method would be useful. Cheers, Dave ___ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Re: Subclassing a Gtk2::TreeStore
On Fri, 2007-10-26 at 17:22 +0100, Dave Howorth wrote: My [non-working] code looks like this: I haven't tested it in a complete application, but this seems to work: package MyTreeStore; use Glib qw(TRUE FALSE); use Gtk2; use Glib::Object::Subclass 'Gtk2::TreeStore', ; sub drag_data_received { my ($self, $dest_path, $selection_data) = @_; return $self-SUPER::drag_data_received ($dest_path, $selection_data); } 1; package main; my $store = MyTreeStore-new (qw/Glib::String/); $store-drag_data_received (undef, undef); Note how drag_data_received is overridden simply how you'd override any other method in normal Perl code, and how the parent's drag_data_received is invoked. -- Bye, -Torsten ___ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Re: Subclassing a Gtk2::TreeStore
On Oct 26, 2007, at 6:37 AM, Torsten Schoenfeld wrote: On Fri, 2007-10-26 at 17:22 +0100, Dave Howorth wrote: My [non-working] code looks like this: Note how drag_data_received is overridden simply how you'd override any other method in normal Perl code, and how the parent's drag_data_received is invoked. To be a little more explicit, this works because where you need it to be overridden is in your own code, where perl's method lookup can work normally. Trying to override drag_data_received as a signal won't work, because it's not a signal. I think the root of the problem you were seeing, Dave, is that drag_data_received comes from a GInterface, and as such is not actually a virtual method that may be overridden by a class deriving from the class implementing the interface. You can't add the interface in your own class, because the base class already implements it. So, Torsten's solution effectively creates a wrapper function -- your perl code first calls a wrapper instead of the real thing, and then chains up to the real thing. -- elysse: You dance better than some. me: Some what? elysse: Some asparagus. ___ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list