Drag Object in GeDialog.AddEditText
-
can I drag an obj into an AddEditText to then get string?
similar to the example I show through user data -
Hello @pyxelrigger,
Thank you for reaching out to us. Please share your code in the future, especially when you have a demo. In the days of AI it is not that time consuming anymore to pump out a basic setup, but it still costs me time to write the query to ask the AI to write me a GeDialog with an edit field in it and then fix the little mistakes the AI makes.
What you want to do is not directly possible. The edit field of a dialog does not support drag and drop events for scene elements. You are comparing it with the multiline edit of the console and with a string parameter in a description, which are both entirely different things.
What you can do, is implement the drag handling yourself. At least to some degree. You cannot mimic the drag-and-drop mouse cursor because the edit field over-rules you there. You can only set the drag cursor when you implement the gadget yourself. You could implement for example a text field with a
GeUserArea
which lets you both type and drag, and then also displays the correct drag cursor.Here is a quick and dirty version, which simply handles the drag event on a dialog level.
Cheers,
FerdinandResult
Code
"""Demonstrates how to handle drag events in a GeDialog. """ import c4d from c4d import gui class MyDialog(gui.GeDialog): """A simple dialog that displays a text edit field. """ ID_TEXTEDIT: int = 1000 def CreateLayout(self) -> bool: """Called by Cinema 4D to let the dialog populate its controls. """ self.SetTitle('My Dialog') self.AddEditText(MyDialog.ID_TEXTEDIT, c4d.BFH_SCALEFIT, 200, 26) return True def InitValues(self) -> bool: """Called by Cinema 4D to let the dialog initialize its controls. """ self.SetString(MyDialog.ID_TEXTEDIT, "Initial text") return True def Message(self, msg: c4d.BaseContainer, result: c4d.BaseContainer) -> bool: """Called by Cinema 4D to convey events to the dialog. We use it here to handle drag events. """ # This is an on-going drag event, i.e., the user is actively dragging something over the # dialog and the user is hitting the edit text field. if (msg.GetId() == c4d.BFM_DRAGRECEIVE and self.CheckDropArea(MyDialog.ID_TEXTEDIT, msg, True, True)): # Set the cursor: Does not work because we do not own the gadget implementation, the # edit text field overwrites our cursor. # self.SetDragDestination(c4d.MOUSE_POINT_HAND) # We unpack the drag data from the drag message. The drag data is a dictionary with two # keys: 'type' and 'object'. The 'type' key holds the type of the drag data (e.g., # files). The 'object' key holds the actual drag data (e.g., a list of files). dragData: dict = self.GetDragObject(msg) dragType: int = dragData.get('type', c4d.NOTOK) dragObject: any = dragData.get('object', None) if dragType == c4d.NOTOK or dragObject is None: return c4d.gui.GeDialog.Message(self, msg, result) text: str | None = None # An atom array (a C++ thing which does not exist in Python) is a list of scene elements. # Objects, tags, layers, shaders, materials, etc. are currently dragged over the dialog. if dragType == c4d.DRAGTYPE_ATOMARRAY: text = (", ".join([obj.GetName() for obj in dragObject]) if len(dragObject) > 1 else dragObject[0].GetName()) # Unknown file types, images, or scenes are currently dragged over the dialog. if dragType in (c4d.DRAGTYPE_FILES, c4d.DRAGTYPE_FILENAME_IMAGE, c4d.DRAGTYPE_FILENAME_OTHER, c4d.DRAGTYPE_FILENAME_SCENE): dragObject = list(dragObject) if not isinstance(dragObject, list) else dragObject text = (", ".join(dragObject) if len(dragObject) > 1 else dragObject[0]) # We set the text in the edit text field when we had a valid drag event. if text is not None: self.SetString(MyDialog.ID_TEXTEDIT, text) return c4d.gui.GeDialog.Message(self, msg, result) dialog: MyDialog = MyDialog() if __name__=='__main__': dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2, defaultw=400, default=400)
-
hmm is it not possible to add the same element that is in the user data?
I tried usingself.AddCustomGui(IDOBJ , pluginid=c4d.CUSTOMGUI_STRING, flags=c4d.BFH_SCALEFIT, minw=0, minh=0, customdata=c4d.BaseContainer())
but it didn't work
-
Hey @pyxelrigger,
sure you can use the string custom GUI. You could also use a base link or a filename field which be the more natural solutions for this. But you asked for
AddEditText
and that is what I answered.Cheers,
Ferdinand