Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Drag Object in GeDialog.AddEditText

    Cinema 4D SDK
    windows 2024 python
    2
    4
    445
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • pyxelriggerP
      pyxelrigger
      last edited by

      can I drag an obj into an AddEditText to then get string?
      similar to the example I show through user data

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @pyxelrigger
        last edited by ferdinand

        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,
        Ferdinand

        Result

        4d4b7b45-1969-4018-94b7-5f72f1c60cce-image.png

        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)
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • pyxelriggerP
          pyxelrigger
          last edited by

          hmm is it not possible to add the same element that is in the user data?
          I tried using

          self.AddCustomGui(IDOBJ , pluginid=c4d.CUSTOMGUI_STRING, flags=c4d.BFH_SCALEFIT, minw=0, minh=0, customdata=c4d.BaseContainer())
          

          but it didn't work

          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @pyxelrigger
            last edited by

            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

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • First post
              Last post