Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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
    • Login

    Drag and Drop onto Range Slider

    Cinema 4D SDK
    python r19
    3
    15
    2.3k
    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.
    • ferdinandF
      ferdinand
      last edited by ferdinand

      Hi,

      from the context of your question I assume you are in some kind of scripting sceneario (Python scripting tag, Python generator object, etc.). To react to drag and drop events you have to do the following:

      def message(mid, data):
          """ 
          """
          if mid == c4d.MSG_DRAGANDDROP:
              print "Drag and drop event", data
          elif mid == c4d.MSG_DESCRIPTION_CHECKDRAGANDDROP:
              print "Drag and drop check", data
      

      For more information on messages check MSG_C4DATOM and MSG_PLUGINS.

      Cheers
      zipit

      MAXON SDK Specialist
      developers.maxon.net

      1 Reply Last reply Reply Quote 0
      • G
        gsmetzer
        last edited by

        Thank You Zipit, Yes, I have a range slider on a Python Generator. I made a GIF of what I'm trying to achieve. ezgif-3-fdf319a9cd5c-1.gif

        After a user drops the object onto the range slider I want to be able to populate a link user data with the object that was dropped.

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

          Hm,

          you want to drag and drop a data type that is not accepted by a RangeCustomGui onto it and reroute that dragged data into a BaseLink gui somewhere else? I do not think that this is possible in Python. Why cannot you use a BaseLink in your user data and reroute these inputs?

          Cheers
          zipit

          MAXON SDK Specialist
          developers.maxon.net

          1 Reply Last reply Reply Quote 0
          • G
            gsmetzer
            last edited by

            Dragging into a BaseLink is just an example, I want to add the drag and drop freature simply for improved user experience.
            How do you know this isn't an acceptable operation? I get the drop box icon as I hover over the slider data. If this isn't possible I'll abandon this topic.

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

              Hm,

              I am slightly confused, either I or you do not really understand something here 😉 A RangeCustomGui obviously only accepts RangeData as drag and drop event data, since it is a GUI that has been purposely build for that type. You can set the DESC_ACCEPT description field for your description elements with which you can specify the type of BaseList2Ds you can drag and drop onto that element. But this only works for the two GUIs that are meant to display arbitrary BaseList2Ds (the BaseLink gui and the InExcludeCustomGui).

              I am still confused on what you are trying to do. At least for me it would be better to know what exactly you are trying to do rather than having "just an example".

              Cheers
              zipit

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 0
              • G
                gsmetzer
                last edited by

                I just want to get the object data from the object that is dropped on the slider. Thats about as simple as I can say it.

                It looks as though you can't pass any DRAG AND DROP message from the Range Slider.

                check = op[c4d.ID_USERDATA, 1].Message(c4d.MSG_DRAGANDDROP)
                

                Console: AttributeError: 'c4d.RangeData' object has no attribute 'Message'
                but works for a link object like you said earlier.

                Is there maybe a way to draw a GeUserArea with a drop area over the Range Slider?

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

                  Hi,

                  @gsmetzer said in Drag and Drop onto Range Slider:

                  I just want to get the object data from the object that is dropped on the slider. Thats about as simple as I can say it.

                  It looks as though you can't pass any DRAG AND DROP message from the Range Slider.

                  check = op[c4d.ID_USERDATA, 1].Message(c4d.MSG_DRAGANDDROP)
                  

                  Console: AttributeError: 'c4d.RangeData' object has no attribute 'Message'
                  but works for a link object like you said earlier.

                  Is there maybe a way to draw a GeUserArea with a drop area over the Range Slider?

                  c4d.C4DAtom.Message() is a method of the atomic type of c4d -c4d.C4DAtom. So you can only invoke it on types that are deriving from that type. Most types that are presented in GUI elements are not derived from C4dAtom (e.g. float, int, bool, str, c4d.Vector, c4d.SplineData, c4d.RangeData, etc.). This is the reason why you get the exception: RangeData is not derived from c4d.C4DAtom, while a BaseList2D (the type objects are collected under in the object link GUIs) is derived from it.

                  But there is also another misunderstanding. You do not have to invoke Message() yourself , but Cinema does it for you. And Message() is also invoked on the C4DAtom that is hosting the description that drag and drop event has occurred on, not on its data elements (for the reasons described above). You can then listen to that message in the implementation of your atoms Message() method - or message() function in case of a scripting object - as shown above. Here is a more complete example, for your case of a Python generator object:

                  import c4d
                  # Put this in a Python generator and drag and drop stuff onto that generator's description elements, 
                  # i.e. stuff in the attribute manager.
                  
                  def main():
                      return c4d.BaseObject(c4d.Ocube)
                  
                  def message(mid, data):
                      if mid == c4d.MSG_DRAGANDDROP:
                          print mid, data
                  

                  The drag and drop event also sends its drag and drop data, but it is a PyCObject, which is of no use to us, since it is only a pointer to the C(++) data structure of that drag and drop data. So to properly react to drag and drop events in Python, we only can deal with drag and drop events of data that matches the data type of the gadget/element it is dropped onto. Since we then can either just compare the (cached) previous value and the new current value or just deal with the current value.

                  I hope this helps.

                  edit: While GeUserArea also offers a Message() method, you cannot use it. Because GeUserAreas are for dialog resources and not description resources. Everything displayed in the attribute manager has a description resource (with ToolData being an exception). You also cannot place / draw stuff on top of each other in general in c4d.

                  Cheers
                  zipit

                  MAXON SDK Specialist
                  developers.maxon.net

                  1 Reply Last reply Reply Quote 0
                  • ManuelM
                    Manuel
                    last edited by

                    Hello,

                    as @zipit said, it's not possible in python as the object is a PyCObject.

                    What kind of workflow do you want to achieve with this ?

                    Cheers,
                    Manuel

                    MAXON SDK Specialist

                    MAXON Registered Developer

                    1 Reply Last reply Reply Quote 0
                    • G
                      gsmetzer
                      last edited by

                      Ok, I see, @zipit example finally got a message to work for me. (I'm still wrapping my head around the message system) Thank You Zipit.

                      I'm not ready to dive into C++ yet. I would love to be able to use a PyCObject but it looks as though that may be a ways off for me.

                      @m_magalhaes I am building an object list by dropping objects on the range slider and using the range slider's knot data to animate the object. The drag and drop would be a much cleaner way of building that list without using an InExclude or bunch of Link's.

                      Looks like I will just use Link for now. If you know of any sample PyCObject code I would love to have a look. Thank you for the help.

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

                        Hi,

                        Looks like I will just use Link for now. If you know of any sample PyCObject code I would love to have a look. Thank you for the help.

                        There are no such examples. PyCObject is a type of Python itself, it is meant to pass C(++) data through Python as a glue language. You can finde here more information on that class. But don't expect much from it, it is just an extension of the atomic Python type - PyObject and meant to pass the data opaquely, i.e. access form Python is not intended. You will have to use C++ to get access to all message data.

                        Cheers
                        zipit

                        MAXON SDK Specialist
                        developers.maxon.net

                        1 Reply Last reply Reply Quote 0
                        • ManuelM
                          Manuel
                          last edited by

                          hello,

                          As @zipit said there's nothing you can do with this object.
                          But I'm not even sure you can do what you want to achieve in C++

                          Just to understand, how do you want to link the animation with the rangedata ?

                          Cheers,
                          Manuel

                          MAXON SDK Specialist

                          MAXON Registered Developer

                          1 Reply Last reply Reply Quote 0
                          • G
                            gsmetzer
                            last edited by

                            @m_magalhaes My aim is to create a drag and drop interface so the user can drop an object between the knots of the range slider. The range slider would represent the timeline and each knot in the range slider an in-out edit point. Drag and drop is just a cleaner way to assign edit points to an object than iterating through a link list or inExclude list.

                            SetEditorMode(c4d.MODE_ON)
                            SetEditorMode(c4d.MODE_OFF)
                            
                            ferdinandF 1 Reply Last reply Reply Quote 0
                            • ferdinandF
                              ferdinand @gsmetzer
                              last edited by ferdinand

                              @gsmetzer

                              Hi,

                              drag and drop messages do contain the position of the mouse at the time of the event. However, to make use of that position in your intended use case, you would need to know the screen space bounding box of the description element on which that event did occur. This is not possible in Python, no matter if the drag event has been accepted by the element or not (I think this is not even possible in C++).

                              There are countless ways how you could approach this. But the most important thing is IMHO to ask yourself, if diluting the concepts of timeline and attribute manger is a good idea in the first place. What are the trade-offs and are you willing to pay a probably rather hefty price of development effort for such an unusual feature? The answer might be very well yes, but at least considering alternative concepts seems to be a good idea.

                              Cheers
                              zipit

                              MAXON SDK Specialist
                              developers.maxon.net

                              1 Reply Last reply Reply Quote 0
                              • ManuelM
                                Manuel
                                last edited by

                                hello,

                                I'll mark this thread as solved tomorrow if you have nothing to add.

                                Cheers,
                                Manuel

                                MAXON SDK Specialist

                                MAXON Registered Developer

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