How to simulate a drag behavior with UA?
-
Hi community,
I want to imitate the function of dragging models from Asset Manager to the scene, but with my own userarea, can I do this in python?
More specific:
- I want to drag a model path the UA represents to viewport (I learned from the forum that filename is not working and needs to be forged through the Assets API).
- when holding on the mouse, draw a bounding box and its axis, assume we have the size data.
- we can place the axis with the model as "Place" tool does.
- Insert the model at the mouse position.
Any guidance would be greatly appreciated.
Cheers~
DunHou -
Hey @Dunhou,
Thank you for reaching out to us. So, let me clarify this, because I first misunderstood this:
You want to drag from your dialog/user area some data into the viewport and then have drag behaviour that is similar to dragging object assets from the Asset Browser into the viewport?
I want to drag a model path the UA represents to viewport (I learned from the forum that filename is not working and needs to be forged through the Assets API).
Drawing into the scene just with a
GeDialog
is not possible, as you do not have a drawing context. In C++ there is the Drawport API and internally we have of course even more options, but in Python that is not possible. What you could try, is implement a tool, and enable that tool when the user is dragging and then disable, reinstate the old tool, once the drag is over. But I fear that this tool would not be processed until your drag event is over. Another path could be aSceneHookData
(not yet available in Python) or its Python approximation, a hidden object you inject into a scene for drawing purposes. When you do everything in one Python project/module, you should not have any issues with exchanging complex data (just on a pure Python level). But to make it more robust, it would be better to pack up drawing instructions in container and send them withc4d.MSG_BASECONTAINER
from your dialog to the hidden object.when holding on the mouse, draw a bounding box and its axis, assume we have the size data.
Drawing a bound box is trivial, the issue is getting the drawing context in Python.
we can place the axis with the model as "Place" tool does.
I am not 100% sure how this is meant, but the place tool includes rigid body dynamics and is absolutely non-trivial to implement. We cannot provide support on how to do reimplement that, at least not unless there are really specific questions.
Insert the model at the mouse position.
Could be done with
c4d.utils.ViewportSelect
.
Okay, when I read here a bit between the lines, I would point out a few things. You seem to want to implement some asset browser like entity which offers a place tool like functionality. If you go exactly into the direction you are going, this could end up being very difficult in Python or outright impossible. Here is how I would go about this:
- Implement your Asset Manager.
- Implement your own placing tool.
I won't talk about (1) that is up to you. The problem with (2) is that when you want to use here drag and drop, you have to understand that there are always two sides to a drag and drop event, the side which sends it, and the side which accepts it. So, when you would use
HandleMouseDrag()
in your user area to start a drag event of typeDRAGTYPE_ATOMARRAY
(to send a list ofBaseObject
for example), the receiving GUI element would have to support that. And when I drag an object from the OM into the viewport, all I get is a HUD element for that object. So, the Viewport does not seem to support recieving objects being dragged into it (which makes sense, as the OM is the place for that) (compare Maxime's example).So, dragging things into the viewport is not supported, unless the viewport does support what you are dragging there. An alternative could be to wrap up your dragged object in a document and store that to disk, because viewports do support file drag and drop operations (and then load that file). But that all does not resolve the drawing and placing thing, because the viewport would then just insert whatever you sent/dragged there, without any options of adjustment. This cannot be overcome as a third party developer.
An alternative could be to move away from drag and drop towards a click and place. I.e., the user double clicks on one of your assets, and you then simply would activate a custom
ToolData
of yours, which has been seeded with the asset to place. It could then implement drawing a bounding box and some move tool like dragging handles. Additionally, you could make it so that the tool would first start in a 'blank' state, and the mouse cursor set viac4d.gui.SetMousePointer()
to for exampleMOUSE_COPY
, so that the user can pick an inital insertion point (viaViewportSelect
).This at the end is a very broad topic, but drag and drop operations do not strike me as the best route for third parties.
Cheers,
Ferdinand -
Hey @ferdinand,
Thanks for your clarification.This is exactly what I am worried about, which is more or less undesirable in Python. I will try using custom tools or calling built-in placement tools after loading assets.
Cheers~
DunHou -
Hey,
a little update, as we talked in our morning meeting about this. Maxime pointed out that the Asset Browser itself also does not really implement drag and drop. All it it does when the users starts to drag, according to Maxime, is inject the asset object into the document, make sure there is no object selected and then enables the place tool (and probably sets the mouse cursor). The 'trick' is here that the place tool will then pick the first object in the OM when there is no object selection once the user clicked once.
Maxime showed me some code where this happens, and I am not as confident as he is that this is exactly replicable in the public (Python) API, because there are some calls to the side of this which cannot be replicated in Python and I also do not see any code which would set the mouse cursor. So, there is probably a little bit more to it. But it's definitely worth a shot, given how easy it would be to implement.
Cheers,
Ferdinand -
@ferdinand said in How to simulate a drag behavior with UA?:
All it it does when the users starts to drag, according to Maxime, is inject the asset object into the document, make sure there is no object selected and then enable the place tool (and probably set the mouse cursor)
This is my solution in my mind, definitely take a try after work.