Open Search
    DynamicDescription Manual

    About

    A DynamicDescription object stores the description of user data parameters that can be added to an element by the user. It allows to access existing parameters and also to add new parameters.

    Warning
    Standard parameters can be dynamically created and edited by implementing NodeData::GetDDescription(). See NodeData::GetDDescription() Manual.
    Note
    User data parameters are accessed using a special DescID, see DescID Manual.
    For description parameter IDs see Description Settings Manual.
    // This example adds a group and a child string user data parameter to the active object.
    BaseObject* const op = doc->GetActiveObject();
    if (op == nullptr)
    return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    DynamicDescription* const ddesc = op->GetDynamicDescriptionWritable();
    if (ddesc == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
    DescID groupID;
    {
    // make group
    bc.SetString(DESC_NAME, "Group"_s);
    bc.SetInt32(DESC_COLUMNS, 1);
    bc.SetInt32(DESC_DEFAULT, 1);
    bc.SetInt32(DESC_SCALEH, 1);
    groupID = ddesc->Alloc(bc);
    }
    {
    // make string parameter
    bc.SetString(DESC_NAME, "Text 1"_s);
    bc.SetInt32(DESC_SCALEH, 1);
    // set group as parent
    GeData data = GeData(CUSTOMDATATYPE_DESCID, DEFAULTVALUE);
    DescID* dataDescId = data.GetCustomDataTypeWritable<DescID>();
    if (dataDescId)
    *dataDescId = groupID;
    bc.SetData(DESC_PARENTGROUP, data);
    ddesc->Alloc(bc);
    }
    #define MAXON_SCOPE
    Definition: apibase.h:2891
    @ DESC_DEFAULT
    Int32/Float/Vector Default numeric value.
    Definition: lib_description.h:119
    @ DESC_SCALEH
    Bool Scale element horizontally.
    Definition: lib_description.h:134
    @ DESC_NAME
    String Name for standalone use.
    Definition: lib_description.h:90
    @ DESC_PARENTGROUP
    Int32/Parent ID.
    Definition: lib_description.h:116
    @ DESC_COLUMNS
    Int32 Number of columns for layout groups (DTYPE_GROUP).
    Definition: lib_description.h:126
    @ DTYPE_STRING
    String.
    Definition: lib_description.h:71
    @ DTYPE_GROUP
    Group.
    Definition: lib_description.h:55
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:69
    #define CUSTOMDATATYPE_DESCID
    DescID custom data type ID.
    Definition: lib_description.h:270
    @ DEFAULTVALUE
    Dummy value for the default value GeData constructor.
    Definition: c4d_gedata.h:64
    BaseContainer GetCustomDataTypeDefault(Int32 type)
    const char * doc
    Definition: pyerrors.h:226
    PyObject * op
    Definition: object.h:520

    Access

    The DynamicDescription object can be obtained from every C4DAtom:

    • C4DAtom::GetDynamicDescription(): Returns the user data parameter description of the entity.

    The description of a specific user data parameter can be directly accessed:

    • DynamicDescription::Find(): Returns the description of the user data parameter with the given ID.
    // This example prints the name of the user data parameter with the ID 1.
    const DynamicDescription* const ddesc = object->GetDynamicDescription();
    if (ddesc == nullptr)
    return maxon::UnknownError(MAXON_SOURCE_LOCATION);
    const DescLevel userData = DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER, 0);
    const DescID ID = CreateDescID(userData, DescLevel(1));
    const BaseContainer* const bc = ddesc->Find(ID);
    if (bc != nullptr)
    ApplicationOutput("Name: " + bc->GetString(DESC_NAME));
    void * userData
    Definition: fileobject.h:20
    @ DTYPE_SUBCONTAINER
    Sub-container.
    Definition: lib_description.h:57
    #define ApplicationOutput(formatString,...)
    Definition: debugdiagnostics.h:204
    #define ID_USERDATA
    User data ID.
    Definition: lib_description.h:24
    #define CreateDescID(...)
    Definition: lib_description.h:593

    It is also possible to iterate through all user data parameter descriptions:

    • DynamicDescription::BrowseInit(): Returns the handle used to browse the parameter descriptions.
    • DynamicDescription::BrowseGetNext(): Retrieves the next parameter description.
    • DynamicDescription::BrowseFree(): Frees the given browse handles.
    // This example prints the name of all user data parameters of the given object.
    // get user data
    DynamicDescription* const ddesc = object->GetDynamicDescriptionWritable();
    if (ddesc == nullptr)
    return maxon::UnknownError(MAXON_SOURCE_LOCATION);
    // browse user data
    void* handle = ddesc->BrowseInit();
    if (handle == nullptr)
    return maxon::UnknownError(MAXON_SOURCE_LOCATION);
    DescID ID;
    const BaseContainer* bc = nullptr;
    // loop through all user data parameter descriptions
    while (ddesc->BrowseGetNext(handle, &ID, &bc))
    {
    // print name
    if (bc != nullptr)
    ApplicationOutput("Name: " + bc->GetString(DESC_NAME));
    }
    ddesc->BrowseFree(handle);

    Edit User Data

    User data parameter descriptions can be added or removed:

    • DynamicDescription::Alloc(): Allocates a new user data parameter and returns its ID.
    • DynamicDescription::Set(): Inserts a new user data parameter with the given ID.
    • DynamicDescription::Remove(): Removes the user data parameter with the given ID.
    • DynamicDescription::FillDefaultContainer(): Fills the given BaseContainer with the default settings of the given data type.
    // This example creates a new user data parameter
    // get user data
    DynamicDescription* const ddesc = object->GetDynamicDescriptionWritable();
    if (ddesc == nullptr)
    return maxon::UnknownError(MAXON_SOURCE_LOCATION);
    // configure type as vector
    BaseContainer bc(DTYPE_VECTOR);
    ddesc->FillDefaultContainer(bc, DTYPE_VECTOR, "Position");
    // create new userdata parameter
    ddesc->Alloc(bc);
    @ DTYPE_VECTOR
    Vector
    Definition: lib_description.h:69
    Note
    An empty DescID as the ::DESC_PARENTGROUP of a user data group will create a new tab in the Attribute Manager.

    Interaction

    User data parameters can include buttons. When such a button is pressed a message is sent to NodeData::Message(), see NodeData::Message() Manual.

    // This example catches the event triggered when a user data button was pressed.
    // The event is caught in the host NodeData::Message() function.
    {
    DescriptionCommand* const dc = static_cast<DescriptionCommand*>(data);
    if (dc == nullptr)
    return false;
    // check if the DescID has two levels (expected for user data)
    if (dc->_descId.GetDepth() == 2)
    {
    // check if it is a user data button
    if (dc->_descId[0].id == ID_USERDATA)
    {
    const maxon::String stringID = maxon::String::IntToString(dc->_descId[1].id);
    MessageDialog("User Data Button clicked: "_s + stringID);
    }
    }
    break;
    }
    Definition: string.h:1287
    #define MSG_DESCRIPTION_COMMAND
    Sent by for example BUTTON description element. The corresponding data is DescriptionCommand.
    Definition: c4d_baselist.h:408
    void MessageDialog(const maxon::String &str)

    Miscellaneous

    Further functions of the DynamicDescription class are:

    • DynamicDescription::CopyTo(): Copies the dynamic description to the given object.
    • DynamicDescription::GetDirty(): Returns a dirty count of the parameter descriptions (not the parameter values).
    // This example prints the dirty count of the user data description.
    const UInt32 dirty = ddesc->GetDirty();
    ApplicationOutput("Dirty State: " + String::UIntToString(dirty));
    maxon::UInt32 UInt32
    Definition: ge_sys_math.h:52

    User Data Editor

    The user data manager can be opened with these functions:

    // This example opens the dialog to add user data descriptions to the given object.
    BaseObject* const object = doc->GetActiveObject();
    if (object == nullptr)
    return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    AddDescription(object);
    void AddDescription(C4DAtom *bl)

    Further Reading