One small optimization I made was to look up the parent directly rather than going through the double value which represents the graphic handle. The function get_parent () returns a graphics_handle which get_object can use directly. Otherwise, get_object() has to call lookup() first on the double value passed to it in order to get a graphics_handle object and can then call the internal do_get_object() function.

There still might be some weirdness with respect to the HitTest property and Figure objects. As I understand this documentation, Figures ignore the HitTest property when it comes to executing callback functions.

But this is not what Octave does. If I use your test code from comment #5

then everything works as expected. Now if I add

then clicks on the figure itself, outside the axes object, cause "figure" to be displayed. But clicking on the patch object no longer causes "figure" to be printed.

If I check the HitTest property for figures the documentation is

It appears that "HitTest" still means something for Figures, the ability to become the CurrentObject or not, but it should have no influence on whether callbacks are run.

>> for absolute Matlab compatibility, not all objects accept the "all" value. ...

Yes it is much easier to have "pickableparts" a base_property so that you can access it through graphics_object::get_properties (), and anyway root and figure objects should not have this property at all so I chose the "unused property/value" route.

>> One thing I noticed is that even though the Patch object is on top of the Line object, it is always the Line object callback that is triggered ...

Confirmed, I have no clue

>> ... For example, when PickableParts is set to "none" on the axes object, I still think you should be able to interact with graphic objects within the axes.

No, it is clearly stated here [1] (see the second note) that if an axes has its "pickableparts"->"none", its children are not clickable.

>> When HitTest is "off", is the mouse click passed to the ancestor of the object which received the click (this is what the Matlab documentation says, but I'm not sure exactly what it means), or does the object which is behind the object which received the click get it instead? The latter is what is implemented, but I don't think that is right.

Yes, I have probably incorrectly interpreted the fact that when clicking on non visible parts of an object that has "pickableparts"->"visible", the click can be captured by objects below it([2]). But if an click is not captured by an object because its "hittest" is "off", then it is its ancestor that should inherit the click event. I'll look into this when I get some time.

@Pantxo: I pushed your patch here (). I re-worded the documentation in genpropdoc.m slightly to try and make clearer the distinction between "pickableparts" and "hittest", although it's already not very clear with Matlab.

I had a few questions. First, for absolute Matlab compatibility, not all objects accept the "all" value. That is why I had the base property contain the only two universal values "visible" and "none" and I overrode the property on the individual objects which do support "all". If it makes for an easier implementation then we can just keep things the way they are with the base property having all three values.

Second, I did some testing with the following script tst_pick.m

One thing I noticed is that even though the Patch object is on top of the Line object, it is always the Line object callback that is triggered. Of course, this happened before PickableParts was implemented so it is unrelated to your change; it's still wrong though.

It might be useful to get confirmation from someone with access to Matlab, but I think "PickableParts" only acts on a per object level and doesn't necessarily affect children. For example, when PickableParts is set to "none" on the axes object, I still think you should be able to interact with graphic objects within the axes.

Finally, I'm not sure our implementation of HitTest is correct. When HitTest is "off", is the mouse click passed to the ancestor of the object which received the click (this is what the Matlab documentation says, but I'm not sure exactly what it means), or does the object which is behind the object which received the click get it instead? The latter is what is implemented, but I don't think that is right.