more on plugins..

All the code (hopefully, let me know if it's not

    > working/I left something out) can be found:
    > http://www.cns.nyu.edu/~abes/matplotlib/

Hi Abraham,

It looks promising - nice job!

In my post yesterday I thought it would be nice to do all the toolbar
buttons this way (eg all the defaults on the nav toolbar). Now I am
on the fence. Not only because they already work, but because some of
them are tightly coupled. Eg, home, back and forward all operate on
the same view limits stack, and thus make sense together as an entity.
So a totally modular design may not make sense for all the buttons.

However, it may nonetheless be worth investigating whether the whole
toolbar could/should be built with this kind of mechanism, in part
because it would be cool/useful and in part because it would help
expose the issues we need to handle like coordination between various
buttons, sharing data, etc. Also, if we want to implement something
like the mechanism which supports signals (good idea by the way!) we
will need to make some changes to the existing buttons so the user
can, for example, disconnect them (eg call something like do_toggle on
the pan/zoom button). I wonder if the best approach here is simply to
use an observer pattern and have all buttons disconnect their signals
when another button is clicked.

Are you interested in exploring this Abraham? Or would you rather
simply see extensions to the existing toolbar and leave the current
implementation mostly untouched. I think the cleanest and most
powerful design would be a single framework in which all the buttons
could be handled in a single configurable way, but this may be too
much to bite off. What do other people think?

If we do try to fit everything in one roof, we would need some way to
call code implemented by the respective backend toolbars. Currently,
the only truly backend dependent toolbar action is savefig, in which
the various backends launch the file save dialog. But this could be
handled by using a magic name for the module which the backend could
detect and call when clicked, eg, self.savefig in that special case.

One minor implementation note: I thought it made more sense to put all
your code that was in plugins.py in __init__.py so everything was
loaded by default at init time. We could couple this with an rc param

plugins.on : True # or False

so the user could disable plugins. Then the last line of the rc file
would be

if rcParams['plugins.on']: load_plugins()

On a related note: I think now might be a good time to introduce a
verbose setting in rc. The more magic that happens under the hood
(loading various rc files, loading plugins) the more it would be nice
to get some feedback, particularly when debugging. Something like
silent | minimal | moderate | screaming. Make minimal the default,
and at the minimal level report things like loading rc file from such
and such, loading plugin module from such and such a dir. At the
moderate level we would report font loads and other such events, and
screaming report .... well you know.

Thanks!
JDH

Thanks.

I have moved most of the toolbar code over to a plugin file, and it seems to work (except for a couple of quirks which I'm working out, and once I do I'll send the code).

The signal/slot method seems to work well for the zoom and pan buttons. Each one is connected to the other's 'disable' function, which does an mpl_disconnect(...). Most of the work was copying the original code in the toolbar into separate classes, and getting them work properly (there were a couple places where I had to change things around)

As for the home, back, and forward button, I tried the observer pattern, as you suggested, and it seems to work well. I added a property to the widgets called 'visible', which if set to false, doesn't actually get added to the toolbar, but does still get loaded into memory, and capable of participating in signal handling.

I then made a class called 'view_controller', which keeps a Stack of the current views (I did need to modify the toolbar to access and set the views ('get_current_view', and 'set_view'). Whenever a control wants to save the view, it can emit the signal 'new_view', with the current view as the parameter. Likewise, the view-related buttons are connected to the view_controller such that they can set the current view (via 'toolbar.set_view').

I should have the code ready either later tonight, or sometime tomorrow.

As for putting the plugin code back in __init__.py, I seem to remember when I originally did this I came across dependency problems when dealing the the toolbar. 'backends.py' currently imports the plugins, so it is transparent to the user once again.

A verbose mode on the rc file sounds like an incredibly good idea.

Abe

John Hunter wrote:

···

"Abraham" == Abraham Schneider <abes@...137...> writes:
           
   > All the code (hopefully, let me know if it's not
   > working/I left something out) can be found:
   > http://www.cns.nyu.edu/~abes/matplotlib/

Hi Abraham,

It looks promising - nice job!

In my post yesterday I thought it would be nice to do all the toolbar
buttons this way (eg all the defaults on the nav toolbar). Now I am
on the fence. Not only because they already work, but because some of
them are tightly coupled. Eg, home, back and forward all operate on
the same view limits stack, and thus make sense together as an entity.
So a totally modular design may not make sense for all the buttons.

However, it may nonetheless be worth investigating whether the whole
toolbar could/should be built with this kind of mechanism, in part
because it would be cool/useful and in part because it would help
expose the issues we need to handle like coordination between various
buttons, sharing data, etc. Also, if we want to implement something
like the mechanism which supports signals (good idea by the way!) we
will need to make some changes to the existing buttons so the user
can, for example, disconnect them (eg call something like do_toggle on
the pan/zoom button). I wonder if the best approach here is simply to
use an observer pattern and have all buttons disconnect their signals
when another button is clicked.

Are you interested in exploring this Abraham? Or would you rather
simply see extensions to the existing toolbar and leave the current
implementation mostly untouched. I think the cleanest and most
powerful design would be a single framework in which all the buttons
could be handled in a single configurable way, but this may be too
much to bite off. What do other people think?

If we do try to fit everything in one roof, we would need some way to
call code implemented by the respective backend toolbars. Currently,
the only truly backend dependent toolbar action is savefig, in which
the various backends launch the file save dialog. But this could be
handled by using a magic name for the module which the backend could
detect and call when clicked, eg, self.savefig in that special case.

One minor implementation note: I thought it made more sense to put all
your code that was in plugins.py in __init__.py so everything was
loaded by default at init time. We could couple this with an rc param

plugins.on : True # or False

so the user could disable plugins. Then the last line of the rc file
would be

if rcParams['plugins.on']: load_plugins()

On a related note: I think now might be a good time to introduce a
verbose setting in rc. The more magic that happens under the hood
(loading various rc files, loading plugins) the more it would be nice
to get some feedback, particularly when debugging. Something like
silent | minimal | moderate | screaming. Make minimal the default,
and at the minimal level report things like loading rc file from such
and such, loading plugin module from such and such a dir. At the
moderate level we would report font loads and other such events, and
screaming report .... well you know.

Thanks!
JDH

-------------------------------------------------------
SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel