theodox / mGui

Python module for cleaner maya GUI layout syntax
MIT License
123 stars 23 forks source link

Adding a method for preserving callbacks of wrapped controls. #71

Closed bob-white closed 7 years ago

bob-white commented 7 years ago

I ran into a few issues using gui.derive and Control.wrap where I'd lose any callbacks defined on the wrapped widget.

For example:

from mGui import gui
file_menu = gui.derive('mainFileMenu')
print(file_menu.postMenuCommand)

Would print an empty MayaEvent and overwrite the postMenuCommand defined in the mel startup script for the file menu.

With this change, instead we get whatever callback has already been assigned to the control.

theodox commented 7 years ago

This is an interesting one... What happens if the existing control is has a mel callback? The tricky bit is that we have to make a change to the widget itself -- we have to rewrite its callback to support multicast, and potentially swap it to python. We can recognize a string and turn it into a call to mel.eval() but ... what if it's a pyhon string? How could we tell?

bob-white commented 7 years ago

It was mel callbacks that lead me to solution I cam up with.

So my initial thought was something along these lines: Though this still needs extra checks for python callables, or Event instances.

callback_string = ctrl.postMenuCommand
try:
    compiled_callback = compile(callback_string)
except SyntaxError:
    def _callback(callback_string=callback_string, *args, **kwargs):
        mel.eval(callback_string)
else:
    def _callback(compiled_callback=compiled_callback, *args, **kwargs):
        exec(compiled_callback)

I ran into issues with this however, can't remember what they were though as it was a few weeks ago.

The reason I went with the current solution, was the idea that if something already existed on the control, it was probably there for a reason and mucking around with it might be dangerous.

theodox commented 7 years ago

How about this - instead of adding this to the base class, we do it as separate static function (maybe in mgui.helpers that can do all the other work too -- like populating the child lists and so on? That's not a trivial task, but it could be useful, and we can keep all the complexity in the one func that is specifically for that.

bob-white commented 7 years ago

So more of a gui.derive on steroids? That makes sense, and yeah after thinking about it a bit, this is kind of a specialized case, so probably not worth polluting the entire class tree with it.

bob-white commented 7 years ago

I'm going to close this out for now.