Hello @yesbird,
That is indeed one of the pitfalls of our GUI system, the custom GUI resource symbols, they are not very well documented. I will update the GUI documentation with the upcoming cycle, but currently writing GUI resources often means greping the {Cinema 4D RXX}\resource
directory, particularly the *.res
files to be found in there. E.g., you could grep for LONG.*CUSTOMGUI.*CYCLE
, i.e., all things that are LONG
, have a CUSTOMGUI
and are a CYCLE
, it will for example spit out this from the viewport resources and show you how we define the GUI:
LONG BASEDRAW_DATA_PICTURE_USEALPHA
{
ANIM OFF;
CUSTOMGUI QUICKTABRADIO;
CYCLE
{
BASEDRAW_ALPHA_NONE;
BASEDRAW_ALPHA_NORMAL;
BASEDRAW_ALPHA_INVERTED;
}
}
The crucial bit of information is here that "fundamentally different looks and feels" are expressed by changing the CUSTOMGUI
of a parameter type, here LONG
.
The greping workflow is laborious, requires the knowledge of how these things are structured, and relies on the assumption that all custom GUIs are always in use in the Cinema 4D description resources (which does not hold true). Currently some of the more specialized LONG
GUIs do not seem to be in use (in descriptions) anymore for example; at least I did not find them all. Another technique which I also sometimes use it the user data editor, as it is fantastic way to find out which custom GUIs and flags are supported by a data type and its GUIs.

As shown here, a long cycle can have four GUIs: The default, button style, tabs, and radio. Sometimes parameter type GUIs also have custom flags which can be set in the resource, but these are then more fine-tuning options. The radio GUI does that for example and allows you to define the layout of the radio gadgets, among other things. These GUI flags are currently largely undocumented except from what you find in the C++ docs. As a rule of thumb: One can usually infer them from the user data editor details tab:

The actual resource properties definition for the radio tab GUI:
static CustomProperty longtabsprops[] =
{
{ CUSTOMTYPE::FLAG, LONGTABS_OPENCLOSED, "OPEN" },
{ CUSTOMTYPE::LONG, LONGTABS_ROWS, "COLUMNS" },
{ CUSTOMTYPE::LONG, LONGTABS_COLUMNS, "ROWS" },
{ CUSTOMTYPE::FLAG, LONGTABS_BUTTONS, "BUTTONS" },
{ CUSTOMTYPE::END, 0, nullptr }
};
I.e., the following code block would be valid markup for a radio button GUI that uses a two-column layout. As a warning, not all flags make sense for public usage. OPEN
and BUTTONS
do not seem to be too useful for public users in this case (at least to me their purpose is unclear).
LONG ID_CYCLE_RADIO
{
CUSTOMGUI RADIOBUTTONS;
OPEN;
BUTTONS;
COLUMNS 2;
CYCLE { ID_ITEM_0; ID_ITEM_1; ID_ITEM_2; }
}
Find below how to define the four LONG
cycle GUIs in a resource.
Cheers,
Ferdinand
Result:

Resource:
*.res
// The description defintion of the tag Tmmover.
CONTAINER Tmmover
{
NAME Tmmover;
INCLUDE Texpression;
// I resued here a tag plugin resource
GROUP ID_TAGPROPERTIES
{
// ...
// Plain cycle long with no special GUI.
LONG ID_CYCLE { CYCLE { ID_ITEM_0; ID_ITEM_1; ID_ITEM_2; } }
// The three custom GUIs which can be used with LONG cycle elements as of 2023. They were
// probably all present in R19, as most of the GUI stuff is quite old, but I did not check.
// Reusing cycle value symbols as I do here is technically fine but not usually something one
// does in pratice.
LONG ID_CYCLE_BUTTON { CUSTOMGUI CYCLEBUTTON; CYCLE { ID_ITEM_0; ID_ITEM_1; ID_ITEM_2; } }
LONG ID_CYCLE_TAB { CUSTOMGUI QUICKTABRADIO; CYCLE { ID_ITEM_0; ID_ITEM_1; ID_ITEM_2; } }
LONG ID_CYCLE_RADIO { CUSTOMGUI RADIOBUTTONS; CYCLE { ID_ITEM_0; ID_ITEM_1; ID_ITEM_2; } }
}
}
*.h
#ifndef _TMMOVER_H_
#define _TMMOVER_H_
enum
{
// ...
ID_CYCLE = 2000,
ID_CYCLE_BUTTON,
ID_CYCLE_TAB,
ID_CYCLE_RADIO,
ID_ITEM_0 = 0,
ID_ITEM_1 = 1,
ID_ITEM_2 = 2,
}
#endif // _TMMOVER_H_
*str
STRINGTABLE Tmmover
{
Tmmover "mMover";
// ...
ID_CYCLE "Cycle";
ID_CYCLE_BUTTON "Cycle Button";
ID_CYCLE_TAB "Cycle Tabs";
ID_CYCLE_RADIO "Cycle Radio";
ID_ITEM_0 "Item 0";
ID_ITEM_1 "Item 1";
ID_ITEM_2 "Item 2";
}