About
A Description object stores information on how C4DAtom parameters are to be displayed in the GUI (Attribute Manager). It contains information on:
- the parameter type and valid parameter values.
- optional information on the (custom) GUI that is used to display the parameter in the Attribute Manager.
The information is stored using description setting IDs, see Description Settings Manual.
- Note
- A Description is displayed in a GeDialog using the DescriptionCustomGui custom GUI element.
-
User data parameters are stored in a DynamicDescription object, see DynamicDescription Manual.
Access
To add dynamic parameters to a NodeData based plugin one can implement NodeData::GetDDescription(). This function receives a given Description object that should be filled with the description of the visible parameters.
See NodeData::GetDDescription() Manual.
{
const Bool invalidNode =
node ==
nullptr;
const Bool invalidDescription = description ==
nullptr;
if (invalidNode || invalidDescription)
return false;
if (description->LoadDescription(
node->GetType()) ==
false)
return false;
return SUPER::GetDDescription(
node, description,
flags);
}
PyCompilerFlags * flags
Definition: ast.h:14
LOADED
Set if elements have been added to the description, either by loading or manual addition.
Definition: ge_prepass.h:2
DESCFLAGS_DESC
Definition: ge_prepass.h:3358
maxon::Bool Bool
Definition: ge_sys_math.h:46
Correspondingly it is possible to get the parameter description from a C4DAtom:
- C4DAtom::GetDescription(): Gets the currently used parameter description of the entity.
See C4DAtom Parameter Properties.
AutoAlloc<Description> description;
if (description == nullptr)
void* handle = description->BrowseInit();
const BaseContainer* bc = nullptr;
DescID id, gid;
while (description->GetNext(handle, &bc, id, gid))
{
}
description->BrowseFree(handle);
NONE
Definition: asset_browser.h:1
@ DESC_NAME
String Name for standalone use.
Definition: lib_description.h:90
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:69
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:204
Allocation/Deallocation
A Description object can be created with the usual tools:
- Description::Alloc(): Creates a new Description object.
- Description::Free(): Deletes the given Description object.
This is needed to access the parameter description of a given object:
BaseObject*
const activeObject =
doc->GetActiveObject();
if (activeObject == nullptr)
AutoAlloc<Description> description;
if (description == nullptr)
{
}
const char * doc
Definition: pyerrors.h:226
Load Description
The description of an plugin's static parameters is defined in the plugin's *.res file. This *.res file is typically registered using the "Register" function of the plugin (see Common Plugin Concepts). Such a registered description can then be loaded:
- Description::LoadDescription(): Loads a registered Description. It is also possible to load the Descriptions of data types and custom GUIs. See Resource Files Manual.
A custom data type can also define its own description. This sub-description (or sub-channels) can be loaded with:
- Description::GetSubDescriptionWithData(): Loads the dynamic sub-description of the given custom data type.
AutoAlloc<AtomArray> elements;
if (elements == nullptr)
elements->Append(sweepObj);
AutoAlloc<Description>
desc;
if (resDataType == nullptr)
const Bool gotSubDescription =
desc->GetSubDescriptionWithData(
completeID, elements, resDataType, BaseContainer(), nullptr);
if (!gotSubDescription)
void* handle =
desc->BrowseInit();
const BaseContainer* bc = nullptr;
DescID loopID, gid;
while (
desc->GetNext(handle, &bc, loopID, gid))
desc->BrowseFree(handle);
#define CUSTOMDATATYPE_SPLINE
Spline data type ID.
Definition: customgui_splinecontrol.h:29
#define ConstDescID(...)
Definition: lib_description.h:592
RESOURCEDATATYPEPLUGIN * FindResourceDataTypePlugin(Int32 type)
@ SWEEPOBJECT_SPLINESCALE
Definition: osweep.h:20
PyStructSequence_Desc * desc
Definition: structseq.h:26
Parameter Descriptions
Edit
In certain situations NodeData::GetDDescription() is not called to get the description of all parameters but of only one specific parameter.
- Description::GetSingleDescID(): Returns the single DescID in single mode.
Existing parameter descriptions are stored in BaseContainers that can be accessed with:
- Description::GetParameter(): Returns the read-only BaseContainer describing the given parameter.
- Description::GetParameterI(): Returns an editable BaseContainer describing the given parameter.
- Note
- The parameter IDs are described in Description Settings Manual.
const DescID* const singleid = description->GetSingleDescID();
if (singleid == nullptr || cid.IsPartOf(*singleid, nullptr))
{
BaseContainer* settings = nullptr;
settings = description->GetParameterI(cid, nullptr);
if (settings)
}
@ DESC_SHORT_NAME
String Short name, for attributes dialog.
Definition: lib_description.h:91
@ DTYPE_BUTTON
Button.
Definition: lib_description.h:60
Also a new parameter description can be added:
- Description::SetParameter(): Inserts a parameter description.
const DescID* const singleid = description->GetSingleDescID();
if (singleid == nullptr || cid.IsPartOf(*singleid, nullptr))
{
settings.SetString(
DESC_NAME,
"A new parameter"_s);
return;
}
@ DTYPE_REAL
Float
Definition: lib_description.h:67
BaseContainer GetCustomDataTypeDefault(Int32 type)
@ ID_OBJECTPROPERTIES
Definition: obase.h:56
Iterate
There are two ways to iterate over all elements stored in a Description object. The first way is to loop over all stored parameters in a list:
- Description::BrowseInit(): Starts browsing the parameters and returns the browse handle.
- Description::GetNext(): Retrieves the next parameter description in the list.
- Description::BrowseFree(): Frees the browse handle.
AutoAlloc<Description> tempDesc;
if (tempDesc && tempDesc->LoadDescription("Mpreview"))
{
void* handle = tempDesc->BrowseInit();
const BaseContainer* settings = nullptr;
DescID id, gid;
while (tempDesc->GetNext(handle, &settings, id, gid))
{
description->SetParameter(id, *settings, gid);
}
tempDesc->BrowseFree(handle);
}
The other way to iterate over all elements is to navigate down the tree hierarchy defined by parameter groups:
- Description::GetFirst(): Returns a handle to the first description entry.
- Description::GetNext(): Returns the next description entry handle.
- Description::GetDown(): Returns the child description entry handle.
- Description::GetDescEntry(): Retrieves the data for a description entry handle.
BaseObject*
const object =
doc->GetActiveObject();
if (object == nullptr)
AutoAlloc<Description> description;
if (description == nullptr)
AutoAlloc<AtomArray> ar;
if (ar == nullptr)
DescEntry* entry = description->GetFirst(ar);
while (entry != nullptr)
{
const BaseContainer* bc = nullptr;
DescID descid;
description->GetDescEntry(entry, &bc, descid);
if (bc != nullptr)
DescEntry* const subEntries = description->GetDown(entry);
HandleSubEntries(subEntries);
entry = description->GetNext(entry);
}
Miscellaneous
This convenience function allows to fill the BaseContainer for a pop-up menu based on the content of the Description:
- Description::CreatePopupMenu(): Builds a popup menu for choosing a parameter.
BaseContainer descriptionPopUp;
if (!description->CreatePopupMenu(descriptionPopUp))
#define MOUSEPOS
Mouse position constant for ShowPopupMenu().
Definition: c4d_gui.h:3328
Int32 ShowPopupMenu(CDialog *cd, Int32 screenx, Int32 screeny, const BaseContainer &bc, Int32 flags=POPUP_RIGHT|POPUP_EXECUTECOMMANDS|POPUP_ALLOW_FILTERING, Int32 *res_mainid=nullptr)
This function allows to complete a given DescID:
- Description::CheckDescID(): Returns true if the given ID exists in the Description.
const DescID incompleteID =
ConstDescID(DescLevel(1110, 0, 0));
DescID completeID;
AutoAlloc<AtomArray> arr;
if (arr == nullptr)
if (description->CheckDescID(incompleteID, arr, &completeID))
{
}
Further Reading