All the code (hopefully, let me know if it's not
> working/I left something out) can be found:
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
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.