drag parameter to user data field like in console

On 28/03/2017 at 02:26, xxxxxxxx wrote:

I'm trying to do something cheeky here, wondering if its possible.
I want to make a python tag which performs an action on an object's parameters, but the user can define which parameter it is performed on by just dragging the parameter into a user data field;
exactly like how we can drag a parameter or object into our python scripts or console.
I thought I could do this with a string field but it doesn't let me, link field doesn't either.

What makes the console input field so special, is there any way this could be done?
cheers!

On 29/03/2017 at 05:23, xxxxxxxx wrote:

Hi,

The Console input is an edit text that processes the drag and drop events for parameters. Same for the Script Manager except it's a multi-line edit text.

You can create a String user data that uses the Multi-Line String Interface in Python mode (Check PYTHON in Details tab). The Multi-Line String GUI accepts dragged parameters.
In code, DESC_CUSTOMGUI would be set to CUSTOMGUI_STRINGMULTI and DR_MULTILINE_PYTHON to 1.

Then in the Python tag you can evaluate a dynamically built expression string generated with the String user data that contains the parameter ID.
Here's some code:

import c4d
  
def main() :
    obj = op.GetObject()
  
    data = obj[c4d.ID_USERDATA,1]
    
    # Evaluates the parameter ID string
    # Returns a list of integers for the description levels
    paramID = eval(data)
    print paramID
    
    # Builds the expression obj[ID]
    expr = "obj" + data
    paramValue = eval(expr)
    print paramValue

On 30/03/2017 at 11:39, xxxxxxxx wrote:

Hey thank you that works great! 
I can now get the value of the dragged in parameter.
But, if you wanted to set the evaluated parameter, how would you proceed?

On 31/03/2017 at 07:25, xxxxxxxx wrote:

Originally posted by xxxxxxxx

But, if you wanted to  set  the evaluated parameter, how would you proceed?

You can set the evaluated parameter with  obj ->SetParameter( id, data, flags ).
SetParameter() needs a complete DescID (with the DescLevel dtype filled) to effectively set a parameter.
To get a full DescID, the best solution is to use Description.CheckDescID() (function added in R18).

Here's some code:

import c4d
  
def main() :
    obj = op.GetObject()
  
    data = obj[c4d.ID_USERDATA,1]
    param = eval(data)
  
    desc = obj.GetDescription(c4d.DESCFLAGS_DESC_0)
    if desc is None:
        return
    
    partialID = c4d.DescID()
    for level in param:
        partialID.PushId(c4d.DescLevel(level))
    
    completeID = desc.CheckDescID(partialID, [obj])
    if completeID is None:
        return
    
    obj.SetParameter(completeID, 100, c4d.DESCFLAGS_SET_0)

On 31/03/2017 at 11:19, xxxxxxxx wrote:

This really exciting, it works perfectly.
I don't quite grasp whats happening with all this ID stuff, I need to read up on it!
Thanks again!