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);
groupID = ddesc->Alloc(bc);
}
{
// make string parameter
bc.SetString(DESC_NAME, "Text 1"_s);
// set group as parent
DescID* dataDescId = data.GetCustomDataTypeWritable<DescID>();
if (dataDescId)
*dataDescId = groupID;
ddesc->Alloc(bc);
}
BaseContainer GetCustomDataTypeDefault(Int32 type)
@ DEFAULTVALUE
Dummy value for the default value GeData constructor.
Definition: c4d_gedata.h:65
Definition: c4d_basecontainer.h:48
Bool SetData(Int32 id, const GeData &n)
Definition: c4d_basecontainer.h:274
void SetString(Int32 id, const maxon::String &s)
Definition: c4d_basecontainer.h:643
void SetInt32(Int32 id, Int32 l)
Definition: c4d_basecontainer.h:579
Definition: c4d_baseobject.h:248
Definition: lib_description.h:355
Definition: lib_description.h:828
DescID Alloc(const BaseContainer &datadescription)
Definition: c4d_gedata.h:83
DATATYPE * GetCustomDataTypeWritable()
Definition: c4d_gedata.h:547
#define MAXON_SCOPE
Definition: apibase.h:2898
@ DESC_DEFAULT
Int32/Float/Vector Default numeric value.
Definition: lib_description.h:120
@ DESC_SCALEH
Bool Scale element horizontally.
Definition: lib_description.h:135
@ DESC_NAME
String Name for standalone use.
Definition: lib_description.h:91
@ DESC_PARENTGROUP
Int32/Parent ID.
Definition: lib_description.h:117
@ DESC_COLUMNS
Int32 Number of columns for layout groups (DTYPE_GROUP).
Definition: lib_description.h:127
@ DTYPE_STRING
String.
Definition: lib_description.h:72
@ DTYPE_GROUP
Group.
Definition: lib_description.h:56
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
#define CUSTOMDATATYPE_DESCID
DescID custom data type ID.
Definition: lib_description.h:272
const char * doc
Definition: pyerrors.h:226
PyObject * op
Definition: object.h:520

Access

The DynamicDescription object can be obtained from every C4DAtom:

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

// 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 BaseContainer* const bc = ddesc->Find(ID);
if (bc != nullptr)
String GetString(Int32 id, const maxon::String &preset=maxon::String()) const
Definition: c4d_basecontainer.h:424
const BaseContainer * Find(const DescID &descid) const
void * userData
Definition: fileobject.h:20
@ DTYPE_SUBCONTAINER
Sub-container.
Definition: lib_description.h:58
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:210
#define ID_USERDATA
User data ID.
Definition: lib_description.h:25
#define CreateDescID(...)
Definition: lib_description.h:595
Represents a level within a DescID.
Definition: lib_description.h:298

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

// 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)
}
ddesc->BrowseFree(handle);
void BrowseFree(void *&handle)
Bool BrowseGetNext(void *handle, DescID *id, const BaseContainer **data)

Edit User Data

User data parameter descriptions can be added or removed:

// 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
ddesc->FillDefaultContainer(bc, DTYPE_VECTOR, "Position");
// create new userdata parameter
ddesc->Alloc(bc);
Bool FillDefaultContainer(BaseContainer &res, Int32 type, const String &name)
@ DTYPE_VECTOR
Vector
Definition: lib_description.h:70
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;
}
void MessageDialog(const maxon::String &str)
Int32 GetDepth() const
Definition: string.h:1235
#define MSG_DESCRIPTION_COMMAND
Sent by for example BUTTON description element. The corresponding data is DescriptionCommand.
Definition: c4d_baselist.h:395
DescID _descId
Description ID of the parameter that triggered the command.
Definition: lib_description.h:940
Message struct for MSG_DESCRIPTION_COMMAND.
Definition: lib_description.h:948

Miscellaneous

Further functions of the DynamicDescription class are:

// This example prints the dirty count of the user data description.
const UInt32 dirty = ddesc->GetDirty();
ApplicationOutput("Dirty State: " + String::UIntToString(dirty));
UInt32 GetDirty() const
static String UIntToString(UInt32 v)
Definition: c4d_string.h:511
maxon::UInt32 UInt32
Definition: ge_sys_math.h:61

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