pyblish / pyblish-qml

Pyblish QML frontend for Maya 2013+, Houdini 11+, Nuke 8+ and more
GNU Lesser General Public License v3.0
115 stars 44 forks source link

Instance Actions #149

Open tokejepsen opened 8 years ago

tokejepsen commented 8 years ago

Goal

To have actions, the developer creates, triggered by the interface through right-click menu. This is similar to plugins actions.

Motivation

The primary motivation for this, is preparing for an importer framework; http://forums.pyblish.com/t/importer-asset-manager/163. That being said, the application for actions on on instances could built ontop of the work for data handlers, given that toggling an instance would just be another action.

Implementation

This would follow the same structure as actions for plugins.

class ToggleInstanceTrue(pyblish.api.Action):
    label = "Open in Explorer"
    icon = "folder-open"

    def process(self, instance):
        print "toggling {0} to True".format(instance)
mottosso commented 8 years ago

Great summary.

Could you also give an example of how to assign an Action to an instance?

tokejepsen commented 8 years ago

Could you also give an example of how to assign an Action to an instance?

I would prefer it to be similar to how plugins work, so something similar to:

instance.actions.append(ToggleInstanceTrue)

In the case of toggling an instance which is predefined in the pyblish-qml interface, we could trigger a predefined action on an instance. Question would just be how to overwrite this action on the instance.

This is kinda turning the current discussion about data handlers upside-down, as we aren't talking about signals send from pyblish-qml anymore.

mottosso commented 8 years ago

Perhaps it could be simply:

instance.data["actions"] = [Action1, Action2]

Where the QML GUI queries the existance of actions when right-clicking, and draws the menu with the content if it exists?

tokejepsen commented 8 years ago

Where the QML GUI queries the existance of actions when right-clicking, and draws the menu with the content if it exists?

Then you have to remember two ways of assigning actions😀

mottosso commented 8 years ago

I can see it both ways. It's either you learn about another data member, or a new attribute on the object. I don't think it can really be the same as for plug-ins..

class MyPlugin(...):
  actions = [Action1, Action2]

As you assign them to the class, not the object after it has been instantiated.

Though having them as data, does mean that there is information in there not particularly relevant outside of a GUI..

{
  "age": 20,
  "color": "blue",
  "actions": ["FixBrokenStuff", "Separator", "ImportSafely"]
}

So, I'm not sure which is better. What other pros/cons can you think of?

tokejepsen commented 8 years ago

What other pros/cons can you think of?

None:( It seems mostly a preference, where I still believe having it the same for both instance and plugin will jell well with developers.

One of the main "problems" will be how to handle the new and old value coming from the GUI, where functionality it would be great to have a similar dependency injection;

class ToggleInstanceTrue(pyblish.api.Action):
    label = "Open in Explorer"
    icon = "folder-open"

    def process(self, instance, new_value, old_value):
        print "toggling {0} from {1} to {2}".format(instance, new_value, old_value)
mottosso commented 8 years ago

It sounds like you're confusing an event handler, with Actions.

Actions are for interactive functionality from within the GUI, whereas an event is some arbitrary response to something happening internally.

That action couldn't possibly have any effect on the visual representation in the GUI of the instance it is attached to, and what would it do with the new and old values in the first place?

The action can on the other hand be given the same arguments as they are currently given when attached to a plug-in, which incidentally is also happening via DI.

tokejepsen commented 8 years ago

Actions are for interactive functionality from within the GUI, whereas an event is some arbitrary response to something happening internally.

You are right. When I sent out on having something happening, apart from GUI changes, when the user toggles an instance or plugin, actions was probably a better description of what I wanted rather than data handlers. Can see the road for data handlers and instance actions better now, where the test I was using for data handlers (toggling) is actually better suited for instance actions.

The question is now, that data handlers are increasingly looking like event driven processing, wouldn't it be better to go full on down that route instead of investing time in a half way solution? I would currently focus my attention on instance actions instead, as event driven processing are a bit outside my scope right now.

mottosso commented 8 years ago

The question is now, that data handlers are increasingly looking like event driven processing, wouldn't it be better to go full on down that route instead of investing time in a half way solution? I would currently focus my attention on instance actions instead, as event driven processing are a bit outside my scope right now.

Half-way solution?! This is great progress! And it sounds like we've accomplished the goal you were looking for, where toggling an instance in the GUI would have an effect on the actual instance, or even scene, in the host. As far as I'm concerned, we're at the brink of that now with your pull-request (linked above).

The reason I keep including references to the event-driven processing issue, is such that we can refer to this if that ever happens, but I wouldn't consider them equal. At all.

The event-driven processing will require first of all embedding connections into plug-ins themselves, and somehow afterwards "resolve" these connections into actual physical connections (and then decide what to do about those that did not manage to connect).

What you have built in your PR is closer to a callback mechanism. A callback is basically an event too, but the event-driven processing isn't meant for outside handling of events, but rather decide which plug-in to process next based on what other plug-ins have emitted. A much different (and complex) topic.

In summary, callbacks and events can co-exist. I would not discard the work you've done with events (callbacks), I think the concept fits very well into the Pyblish framework, and Actions in Instances sounds to me like an entirely orthogonal feature and implementation or equal usefulness.

tokejepsen commented 8 years ago

Didn't we have a discussion about possibly having ContextAction and InstanceAction? Can't seem to find it anymore.

mottosso commented 8 years ago

Yeah, on the forums somewhere. Would you like to make an issue for that? Under pyblish-base preferably.

tokejepsen commented 8 years ago

Why under pyblish-base? Is it because it'll be affecting this module?

mottosso commented 8 years ago

It's something that will have to start being implemented in base.