GeDialog Manual

内容表

关于

GeDialog is the base class for interface elements of Cinema 4D . An asynchronous (non-modal) dialog acts as a panel that can be added to the application layout or as a free floating window. In contrast a synchronous (modal) dialog blocks the application's main thread until it is closed. A custom dialog is added by creating a subclass of GeDialog . GeDialog is also the base class of iCustomGui which is used to create custom GUI elements for NodeData 参数。

Allocation

A GeDialog based window is typically owned by a CommandData plugin. This CommandData stores and opens the dialog instance.

// This CommandData example opens and restores a GeDialog based window. // g_geDialogID is the plugin ID of the CommandData plugin.
class OpenExampleDialog : public CommandData { INSTANCEOF (OpenExampleDialog, CommandData )
private : ExampleDialog _dialog; public : // "Execute" function opens the dialog window Bool Execute ( BaseDocument * doc, GeDialog * parentManager) { // open the dialog window if it is not already open if (_dialog.IsOpen() == false ) _dialog.Open( DLG_TYPE::ASYNC , g_geDialogID, -1, -1, 400, 400); else _dialog.Close(); return true ; };

// "RestoreLayout" is called to restore the dialog after a layout change Bool RestoreLayout ( void * secret) { return _dialog.RestoreLayout(g_geDialogID, 0, secret); }; static OpenExampleDialog* Alloc() { return NewObjClear(OpenExampleDialog); } };

The GeDialog is opened with GeDialog::Open() . The different types of dialogs are:

The GeDialog window can be closed with GeDialog::Close() . This will call GeDialog::AskClose() (see below).

GeDialog Based Classes

A custom window is created by implementing a subclass of GeDialog . This subclass can implement different virtual functions to define the layout and behaviour of the dialog.

Dialog setup:

// create the layout Bool CreateLayout() { SetTitle( "Example Dialog" _s); AddEditNumber(1000, BFH_SCALEFIT , 0, 10);

// sets the timer to 1000 milliseconds this->SetTimer(1000); return true ; }

// Initialize internal data and set the values Bool InitValues() { SetFloat(1000, 123.456); return true ; }

Messages and Interaction:

// This "Command" function checks if the gadget with the ID 1000 was changed. Bool Command( Int32 id , const BaseContainer & msg) { if ( id == 1000) { ApplicationOutput ( "Gadget 1000 was changed." ); } return GeDialog::Command ( id , msg); }

// This "Message" function checks if any interaction in the GeDialog starts or ends. Int32 Message( const BaseContainer & msg, BaseContainer & result) { // messages are identified // by the BaseContainer ID switch (msg. GetId ()) { case BFM_INTERACTSTART : { ApplicationOutput ( "Interaction start" ); break ; } case BFM_INTERACTEND : { ApplicationOutput ( "Interaction end" ); break ; } } return SUPER::Message(msg, result); }

Timed Actions:

// This "Timer" function is called depending on the value set with SetTimer() void Timer( const BaseContainer & msg) { ApplicationOutput ( "Tick.." ); }

Read-Only Properties

It is possible to check these GeDialog properties:

It is also possible to read the pixel ratio of the current screen:

// This example adds a BitmapButton to the layout of the GeDialog. // Depending on the pixel ratio a low-res or high-res bitmap file is loaded // and applied to the BitmapButton.

void * const customGUI = AddCustomGui(1000, CUSTOMGUI_BITMAPBUTTON , "" _s, BFH_SCALEFIT , 300, 300, settings); BitmapButtonCustomGui * const bitmapButtonGUI = static_cast< BitmapButtonCustomGui * > (customGUI); if (bitmapButtonGUI) { // allocate bitmap AutoAlloc<BaseBitmap> bitmap; if (bitmap) { String filename = "" ;

// get pixel ratio const Float pixelRatio = GetPixelRatio();

// check if Retina or not if (pixelRatio == 1.0) filename = "lowRes.png" ; else filename = "highRes.png" ;

// load bitmap (GetFullFilename() is just a custom utility function) const String fullFileName = GetFullFilename(filename); if (bitmap-> Init (fullFileName) == IMAGERESULT::OK ) { // store ratio bitmap-> SetData ( BASEBITMAP_DATA_GUIPIXELRATIO , pixelRatio);

// apply to BitmapButton bitmapButtonGUI-> SetImage (bitmap, true , false ); } } }

Layout

Create Layout

The layout of a GeDialog - the arrangement of groups and gadgets - is defined in the implementation of GeDialog::CreateLayout() . This layout can be defined by creating the groups and gadgets individually or by loading a dialog resource file.

General functions to handle GeDialog gadgets are:

// This example loads a dialog layout from a resource file and edits it. Bool CreateLayout() { // call default CreateLayout() if (! GeDialog::CreateLayout ()) return false ;

// load dialog from resource file if (!LoadDialogResource(DLG_CUSTOM_DIALOG, nullptr , 0)) return false ;

// set a different title this->SetTitle( "New Title" _s);

// disable a GUI element this->Enable(IDC_CUSTOM_CHECKBOX, false ); return true ; }

菜单

GeDialog based windows contain a menu bar. This menu bar can contain various sub-menus and also any kind of gadget in a special sub-group.

Menus are created with:

Sub-menus are added with these functions:

Menu items are added with these functions:

// This example creates two sub-menus. MenuFlushAll();

// submenu "Cinema Commands" MenuSubBegin( "Cinema 4D Commands" _s);

// add Cinema 4D commands const Int32 saveAsCommandID = 12218; // "Save as" Command const Int32 saveCommandID = 12098; // "Save" Command MenuAddCommand(saveAsCommandID); MenuAddCommand(saveCommandID); MenuSubEnd();

// submenu "Dialog Commands" MenuSubBegin( "Dialog Commands" _s);

// add dialog commands MenuAddString(ID_COMMAND_A, "Action A" _s); MenuAddSeparator(); MenuAddString(ID_COMMAND_B, "Action B" _s); MenuSubEnd(); MenuFinished();

// set state MenuInitString(ID_COMMAND_B, true , true ); // set as checked

It is possible to add arbitrary gadgets to a special sub-group of the menu bar:

// This example adds a group to the menu bar. // This menu group contains a button. GroupBeginInMenuLine(); GroupBegin(1000, BFH_RIGHT , 2, 1, "" _s, 0); AddButton(ID_MENU_BUTTON, BFH_SCALEFIT , 0, 10, "Button" _s); GroupEnd(); GroupEnd();

Groups

The arrangement of elements of the dialog layout is defined with groups. Such groups can define rows and columns and can contain further sub-groups.

Groups are created with these functions:

// This example creates a group with two columns. // The subgroup within the left column contains a tab group with two tabs.

// parent group with the whole width of the GeDialog GroupBegin(100, BFH_SCALEFIT , 2, 0, "" _s, 0, 0, 300);

// left subgroup GroupBegin(200, BFH_SCALEFIT | BFV_SCALEFIT , 1, 0, "" _s, 0, 0, 0);

// tab parent group within the left subgroup TabGroupBegin(210, BFH_SCALEFIT | BFV_SCALEFIT );

// first tab group GroupBegin(220, BFH_SCALEFIT | BFV_SCALEFIT , 1, 0, "Tab 1" _s, 0, 400, 300); AddStaticText(221, BFH_SCALEFIT | BFH_LEFT , 0, 10, "Tab 1" _s, BORDER_NONE ); GroupEnd();

// second tab group GroupBegin(230, BFH_SCALEFIT | BFV_SCALEFIT , 1, 0, "Tab 2" _s, 0, 400, 300); AddStaticText(231, BFH_SCALEFIT | BFH_LEFT , 0, 10, "Tab 2" _s, BORDER_NONE ); GroupEnd(); GroupEnd(); GroupEnd();

// right subgroup GroupBegin(300, BFH_SCALEFIT | BFV_SCALEFIT , 1, 0, "" _s, 0, 0, 0); AddStaticText(301, BFH_SCALEFIT | BFH_LEFT , 0, 10, "Right subgroup" _s, BORDER_NONE ); GroupEnd(); GroupEnd();

The border style and spacing of groups can be defined with these functions:

// This example creates a group with space settings and a border. GroupBegin(600, BFH_SCALEFIT , 2, 1, "Group" _s, BFV_BORDERGROUP_CHECKBOX , 0, 100); GroupSpace(100, 0); // space between group elements GroupBorder( BORDER_GROUP_IN ); // group border GroupBorderSpace(10, 10, 10, 10); // space around the group AddButton(601, BFH_SCALEFIT | BFV_SCALEFIT , 0, 0, "Button A" _s); AddButton(602, BFH_SCALEFIT | BFV_SCALEFIT , 0, 0, "Button B" _s); GroupEnd();

If the group flag BFV_GRIDGROUP_ALLOW_WEIGHTS is set the user can change the width/height of group's columns/rows. The size of columns/rows is stored as "weights" which can be stored.

另请参阅 BFM_WEIGHTS_CHANGED in GUI and Interaction Messages Manual .

// This example creates a group with two columns. // The width of these columns can be changed by the user. GroupBegin(WEIGHT_GROUP, BFH_SCALEFIT | BFV_SCALEFIT , 3, 1, "" _s, BFV_GRIDGROUP_ALLOW_WEIGHTS ); GroupBegin(GROUP_LEFT, BFH_SCALEFIT | BFV_SCALEFIT , 1, 1, "" _s, 0); AddStaticText(100, 0, 0, 10, "Left Column" _s, 0); GroupEnd(); AddSeparatorV(1); GroupBegin(GROUP_RIGHT, BFH_SCALEFIT | BFV_SCALEFIT , 1, 1, "" _s, 0); AddStaticText(200, 0, 0, 10, "Right Column" _s, 0); GroupEnd(); GroupEnd(); GroupWeightsLoad(WEIGHT_GROUP, _weights);

The content of a group can be flushed and replaced with new gadgets:

// This example flushes a layout group and fills it with new gadgets.

// flush group LayoutFlushGroup(100);

// add new gadget AddStaticText(101, BFH_SCALEFIT | BFH_LEFT , 0, 10, "New Element" _s, BORDER_NONE );

// update group LayoutChanged(100);

// This example flushes the group with the ID 1000 and adds new elements to it.

// begin layout change and store data UpdateDialogHelper updateDialog = BeginLayoutChange(1000, true );

// add new elements to flushed group AddStaticText(1100, BFH_SCALEFIT , 0, 10, "Add" _s, BORDER_NONE ); AddStaticText(1101, BFH_SCALEFIT , 0, 10, "new" _s, BORDER_NONE ); AddStaticText(1102, BFH_SCALEFIT , 0, 10, "elements" _s, BORDER_NONE );

// update group updateDialog. CommitChanges ();

A scroll group allows to scroll the content of a group using the mouse-wheel:

注意
A scroll group must always contain another sub-group that stores the actual gadgets.

另请参阅 BFM_SETSTATUSBAR in Specific GUI Elements .

// This example creates a scroll group and fills it with multiple gadgets. ScrollGroupBegin(500, BFH_SCALEFIT , SCROLLGROUP_VERT | SCROLLGROUP_BORDERIN , 0, 100);

// layout group within the scroll group GroupBegin(501, BFV_TOP | BFH_SCALEFIT , 1, 0, "" _s, 0);

// add gadgets for ( Int32 i = 0; i < 100; ++i) AddCheckbox(502 + i, BFH_SCALEFIT | BFH_LEFT , 0, 10, "element" _s); GroupEnd(); GroupEnd();

// This example gets the visible area of a scroll group and changes it. Int32 x1 = NOTOK ; Int32 y1 = NOTOK ; Int32 x2 = NOTOK ; Int32 y2 = NOTOK ;

// access the visible area of the scroll group if (GetVisibleArea(scrollGroupID, &x1, &y1, &x2, &y2)) { const Int32 height = y2 - y1; SetVisibleArea(scrollGroupID, x1, 0, x2, height); }

Gadget IDs

A gadget that is part of a GeDialog layout can be identified in two ways:

// This example creates two text edit fields. // One edit field is edited using the C4DGadget pointer, // the other using just the ID.

// add text edit field and store the C4DGadget pointer C4DGadget * const textA = AddEditText(ID_TEXT_A, BFH_SCALEFIT , 0, 10, 0); if (textA) SetString(textA, "This is some text." _s);

// add text edit field AddEditText(ID_TEXT_B, BFH_SCALEFIT , 0, 10, 0); SetString(ID_TEXT_B, "This is some other text." _s);

Default Gadgets

Default GUI gadgets can be added to a GeDialog with these member functions:

Number related gadgets:

Text related gadgets:

Color related gadgets:

Buttons:

Seperators:

Further gadgets are:

// This example just adds some generic gadgets to the layout. AddCheckbox(1000, BFH_SCALEFIT , 0, 10, "Checkbox" _s); AddButton(2000, BFH_SCALEFIT , 0, 10, "Button" _s); AddSeparatorH(0, BFH_SCALEFIT ); AddEditText(3000, BFH_SCALEFIT , 0, 10, 0);

// This example adds a list view to the GeDialog layout. private : SimpleListView _listview; public : Bool CreateLayout() { SetTitle( "Listview Dialog" _s);

// add list view element to layout AddListView(1000, BFH_SCALEFIT | BFV_SCALEFIT , 0, 0); _listview. AttachListView ( this , 1000); return true ; } Bool InitValues() { // configure listview columns BaseContainer layout; layout. SetInt32 (CHECKBOX, LV_COLUMN_CHECKBOX ); layout. SetInt32 ( NAME , LV_COLUMN_TEXT ); _listview. SetLayout (2, layout);

// don't allow multi selection _listview. SetProperty ( SLV_MULTIPLESELECTION , false );

// fill with content Int32 line = 0; BaseContainer data; data. SetBool (CHECKBOX, true ); data. SetString ( NAME , "Element A" _s); _listview. SetItem (line, data); ++line; // increment ID data. SetBool (CHECKBOX, false ); data. SetString ( NAME , "Element B" _s); _listview. SetItem (line, data);

// update _listview. DataChanged (); return true ; }

A multi-line text edit field can be created and configured with these functions:

另请参阅 Specific GUI Elements .

// This example creates a multi line edit field with Python syntax highlighting. const Int32 style = DR_MULTILINE_STATUSBAR | DR_MULTILINE_HIGHLIGHTLINE | DR_MULTILINE_WORDWRAP | DR_MULTILINE_MONOSPACED | DR_MULTILINE_PYTHON | DR_MULTILINE_SYNTAXCOLOR ; AddMultiLineEditText(4000, BFH_SCALEFIT , 0, 200, style);

// set some python code SetString(4000, "import c4d\n\nprint(\"hello world\")\n" _s);

// set the cursor position at the beginning of the last line SetMultiLinePos(4000, 4, 0);

Several gadgets can contain multiple child-elements, typically for selection purposes:

// This example creates a combo box and a combo button. AddComboBox(5000, BFH_LEFT , 100, 10, false ); AddChild(5000, 0, "Child 0" _s); AddChild(5000, 1, "Child 1" _s); AddChild(5000, 2, "Child 2" _s); AddComboButton(6000, BFH_LEFT , 100, 10, 0); BaseContainer children; children. SetString (0, "Child 0" _s); children. SetString (1, "Child 1" _s); AddChildren(6000, children);

// This example creates a combo box and defines the used icons.

// loading the icon data IconData data1, data2; GetIcon ( Ocube , &data1); GetIcon ( Osphere , &data2);

// creating the combo box // the address of the icon data is written into the String AddComboBox(5001, BFH_LEFT , 100, 10, false ); const String iconData1Address = String::HexToString (( UInt ) & data1); AddChild(5001, 0, "Cube &" + iconData1Address + "&" ); const String iconData2Address = String::HexToString (( UInt ) & data2); AddChild(5001, 1, "Sphere &" + iconData2Address + "&" );

Further interaction with gadgets is typically done by sending messages to the gadget:

另请参阅 GUI and Interaction Messages Manual .

// This example creates a "Progress Bar" custom GUI element. const Int32 flags = BFH_LEFT | BFV_FIT ; const BaseContainer settings; AddCustomGui(10000, CUSTOMGUI_PROGRESSBAR , String (), flags, SizePix (100), SizePix (12), settings);

// This example sends a message to the progress bar custom GUI element. BaseContainer m( BFM_SETSTATUSBAR ); m.SetBool( BFM_STATUSBAR_PROGRESSON , true ); m.SetFloat( BFM_STATUSBAR_PROGRESS , _someValue); m.SetData( BFM_STATUSBAR_TINT_COLOR , 向量 (0.0, 0.0, 1.0)); SendMessage(10000, m);

图像

There is no default gadget to display an image ( BaseBitmap ) in a GeDialog . Two possible solutions are:

// This example creates a BitmapButtonCustomGui to present an image. const Int32 flags = BFH_CENTER ; const Int32 width = SizePix (300); const Int32 height = SizePix (50); BaseContainer settings; 设置。 SetBool ( BITMAPBUTTON_BUTTON , false ); void * const customGUI = AddCustomGui(5050, CUSTOMGUI_BITMAPBUTTON , "" _s, flags, width, height, settings); BitmapButtonCustomGui * const bitmapButtonGUI = static_cast< BitmapButtonCustomGui * > (customGUI); if (bitmapButtonGUI) { bitmapButtonGUI-> SetImage (buttonBitmap, true , false ); }

Custom GUI Elements

Further gadgets are implemented as custom GUI elements. Such custom GUI elements have to be created using their type ID.

Custom GUI Elements .

注意
A custom GUI is typically configured using a BaseContainer given to GeDialog::AddCustomGui() . Only the parameters accessible with the custom GUI class itself can be changed afterwards.
Custom GUI element instances are based on BaseCustomGui . Using this base class it is possible to further edit the instance.
Some "custom GUIs" are no real custom GUI elements but are hardcoded in the DescriptionCustomGui and cannot be used in a GeDialog (e.g. CUSTOMGUI_VECTOR ).
// This example creates and configures a "Hyperlink" custom GUI element. BaseContainer hlSettings; hlSettings. SetBool ( HYPERLINK_IS_LINK , true ); const Int32 customGuiID = CUSTOMGUI_HYPER_LINK_STATIC ; void * const customGui = AddCustomGui(11000, customGuiID, String (), BFH_SCALEFIT , 100, 50, hlSettings); HyperLinkCustomGui * const linkGustomGui = static_cast< HyperLinkCustomGui * > (customGui); if (linkGustomGui != nullptr ) { const String linkTitle { "MAXON" }; const String url { "https://www.maxon.net" }; linkGustomGui-> SetLinkString (&url, &linkTitle); }

// This example accesses a custom GUI element that is part of the GeDialog. // The value presented in the GUI element is first set using the specific GUI element class. // Alternatively one can also set the value using the BaseCustomGui base class.

// search for custom gui gadget void * const customGUI = FindCustomGui(ID_GRADIENT, CUSTOMGUI_GRADIENT );

// cast into specific class GradientCustomGui * const gradientGUI = static_cast< GradientCustomGui * > (customGUI); if (gradientGUI) { // set data AutoAlloc<Gradient> gradientData; if (gradientData) { // set gradient data using the GradientCustomGui class function

// add a knot GradientKnot firstKnot; firstKnot. pos = 0.25; firstKnot. col = 向量 (1.0, 0, 0); // red gradientData-> InsertKnot (firstKnot); gradientGUI-> SetGradient (gradientData);

// set gradient data using the BaseCustomGui class function

// add a knot GradientKnot secondKnot; secondKnot. pos = 0.75; secondKnot. col = 向量 (0, 0, 1.0); // blue gradientData-> InsertKnot (secondKnot);

// store as GeData GeData geData; geData. SetCustomDataType ( CUSTOMDATATYPE_GRADIENT , gradientData);

// store as TriState TriState<GeData> triStateData; triStateData. 添加 (geData);

// set data of the GUI element gradientGUI-> SetData (triStateData); } }

GeUserAreas

GeUserArea is the base class for all dialog gadgets. A subclass of GeUserArea defines a new custom gadget. Such a custom gadget can be added to the GeDialog .

另请参阅 GeUserArea Manual .

// This example adds a user area (that is owned by the GeDialog) to the layout. C4DGadget * userarea = this->AddUserArea(12000, BFH_LEFT , 300, 100); if (userarea) this->AttachUserArea(_userArea, userarea);

Sub-Dialogs

It is possible to add a sub-dialog to a given GeDialog based window. Such a sub-dialog is based on SubDialog which in return is also based on GeDialog .

// This example adds a SubDialog based sub-dialog to the layout. AddSubDialog(14000, BFH_SCALEFIT | BFV_SCALEFIT ); AttachSubDialog(&_subDialog, 14000);

For convenience it is possible to add a default group of gadgets to the dialog. This group can contain the standard buttons "OK" or"Cancel". See DLG .

// This example adds the generic "OK" and "Cancel" buttons to the layout. AddDlgGroup( DLG_OK | DLG_CANCEL );

// The "Command" function is called when a button is pressed. Bool Command( Int32 id , const BaseContainer & msg) { switch ( id ) { // the "OK" button of a AddDlgGroup() group, IDC_CANCEL is the other case IDC_OK : { ApplicationOutput ( "OK was pressed" ); break ; } } return true ; }

Pixel Size

For most gadgets it is possible to define the size of the gadget. To define this size one must use these functions to bake the pixel size:

// This example creates a button with a height of 50 pixels. AddButton(15000, BFH_SCALEFIT , 0, SizePix (50), "" _s);

Layout Flags

The position and behaviour of groups and gadgets is defined with these flags:

Horizontal alignment:

Vertical alignment:

// This example creates a group with three subgroups. // The left and right subgroup have a fixed width. // The center subgroup is scaled horizontally.

// the parent group with three columns GroupBegin(20000, BFH_SCALEFIT , 3, 1, String (), BFV_GRIDGROUP_ALLOW_WEIGHTS );

// left group GroupBegin(21000, BFH_LEFT | BFV_SCALEFIT , 1, 1, String (), 0, 100); AddButton(21100, BFH_SCALEFIT | BFH_SCALEFIT , 0, 0, "" _s); GroupEnd();

// center group GroupBegin(22000, BFH_SCALEFIT | BFV_SCALEFIT , 1, 1, String (), 0); AddButton(22100, BFH_SCALEFIT | BFH_SCALEFIT , 0, 0, "" _s); GroupEnd();

// right group GroupBegin(23000, BFH_RIGHT | BFV_SCALEFIT , 1, 1, String (), 0, 100); AddButton(23100, BFH_SCALEFIT | BFH_SCALEFIT , 0, 0, "" _s); GroupEnd(); GroupEnd();

Gadget Values

GUI elements are used to display values and to allow user interaction to change these values. For default GUI elements there are three kinds of functions to edit these values:

Editing Boolean values:

Editing integer values:

Editing float values:

Editing Vector values:

Editing Time values:

编辑 String values:

编辑 Filename values: These functions just wrap around GeDialog::GetString() and GeDialog::SetString() .

Editing Color values:

// This example adds different GUI elements to the layout and sets their values.

// add a text field and define the text AddEditText(1000, BFH_SCALEFIT , 0, 10, 0); SetString(1000, "Hello World" _s);

// add a number field and set the value using a TriState object AddEditNumber(2000, BFH_SCALEFIT , 0, 10); TriState<Int32> numberData; numberData. 添加 (100); numberData. 添加 (200); SetInt32(2000, numberData);

交互

Messages

A GeDialog receives messages from both its gadget and from the Cinema 4D GUI. They are sent to GeDialog::Message() .

GUI and Interaction Messages Manual .

// This example catches the event when the "F1" key is pressed in GeDialog::Message().

case BFM_INPUT : { // check if this event was triggered by some keyboard interaction if (msg. GetInt32 ( BFM_INPUT_DEVICE ) == BFM_INPUT_KEYBOARD ) { // check if the "F1" triggered the event if (msg. GetInt32 ( BFM_INPUT_CHANNEL ) == KEY_F1 ) { ApplicationOutput ( "Pressed \"F1\" key." _s); return true ; } } break ; }

Interaction with Gadgets

When a gadget is changed it sends a message to the parent GeDialog . This message can be caught in GeDialog::Command() .

GUI and Interaction Messages Manual .

// This example adds a button to the layout. AddButton(ID_BUTTON_ACTION, BFH_SCALEFIT , 0, 20, "Button" _s);

// The "Command" function is called when the button is pressed. Bool Command( Int32 id , const BaseContainer & msg) { if ( id == ID_BUTTON_ACTION) { ApplicationOutput ( "Button pressed" ); }

When a gadget is changed one might need to know the state of the mouse or keyboard when this happened.

// This example is executed in a GeDialog::Command() function. // When the text gadget with the ID 1000 is changed its value is read. // If the "Enter" key was pressed, the value is printed to the console.

if ( id == 1000) { String value;

// get String value if (GetString(1000, value)) { // get state of the "Enter" key. BaseContainer state; GetInputState ( BFM_INPUT_KEYBOARD , KEY_ENTER , state);

// check if "Enter" key is pressed if (state. GetInt32 ( BFM_INPUT_VALUE )) { ApplicationOutput ( "Value: " + value); } } }

// This example catches an interaction message in GeDialog::Message(). If the // left mouse button is pressed more mouse events are processed via GeDialog::GetInputState(). // After the left mouse button is released all queued events are freed. Int32 Message( const BaseContainer & msg, BaseContainer & result) { // messages are identified by the BaseContainer ID switch (msg. GetId ()) { // interaction event case BFM_INPUT : { // check if mouse event if (msg. GetInt32 ( BFM_INPUT_DEVICE ) == BFM_INPUT_MOUSE ) { // check if left mouse button if (msg. GetInt32 ( BFM_INPUT_CHANNEL ) == BFM_INPUT_MOUSELEFT ) { // save initial start position Int32 xPos = msg. GetInt32 ( BFM_INPUT_X ); Int32 yPos = msg. GetInt32 ( BFM_INPUT_Y ); BaseContainer res;

// loop and process queued events while ( GetInputState ( BFM_INPUT_MOUSE , BFM_INPUT_MOUSELEFT , res)) { // check if left mouse button is still pressed if (!res. GetInt32 ( BFM_INPUT_VALUE )) break ;

// get coordinates const Int32 currentX = res. GetInt32 ( BFM_INPUT_X ); const Int32 currentY = res. GetInt32 ( BFM_INPUT_Y );

// compare coordinates const Bool xPosChanged = currentX != xPos; const Bool yPosChanged = currentY != yPos; if (xPosChanged || yPosChanged) { ApplicationOutput ( "Mouse dragged and moved" ); xPos = currentX; yPos = currentY; } }

// delete all other events that might have occurred in the meantime KillEvents(); return true ; } } break ; } } return SUPER::Message(msg, result); }

Drag and Drop

The user can drag and drop various elements onto a GeDialog GeDialog is informed about this event through messages sent to GeDialog::Message() . These functions are used to react to these messages:

另请参阅 Drag and Drop .

// This example catches a Drag&Drop message. // If the dragged element is a C4DAtom the name of the element is displayed in a text field. Int32 Message( const BaseContainer & msg, BaseContainer & result) { // messages are identified by the BaseContainer ID switch (msg. GetId ()) { case BFM_DRAGRECEIVE : { // Check if the drag is over a certain gadget if (CheckDropArea(ID_TEXT_NAME, msg, true , true )) { void * object = nullptr ; Int32 type;

// get the dragged element if (!GetDragObject(msg, &type, & object )) return false ;

// if the drag is finished set the text gadget const Bool typeIsAtom = type == DRAGTYPE_ATOMARRAY ; const Int32 isFinished = msg. GetInt32 ( BFM_DRAG_FINISHED ); if (typeIsAtom && isFinished) { const AtomArray * const atomArray = static_cast< AtomArray * > (object);

// check if the AtomArray can be accessed and if it contains any objects if (atomArray && atomArray-> GetCount () > 0) { C4DAtom * const atom = atomArray-> GetIndex (0);

// check if the given C4DAtom is a BaseList2D element if (atom && atom-> IsInstanceOf ( Tbaselist2d )) { BaseList2D * const baselist = static_cast< BaseList2D * > (atom); SetString(ID_TEXT_NAME, baselist-> GetName ()); } } return true ; } else { return SetDragDestination( MOUSE_POINT_HAND ); } } return SetDragDestination( MOUSE_FORBIDDEN ); } } return SUPER::Message(msg, result); }

Core Messages

A GeDialog can also receive core messages. These messages are sent to inform the dialog about global events e.g. when something in the active document changed. The messages are sent to GeDialog::CoreMessage() .

另请参阅 GUI and Interaction Messages Manual and Core Messages Manual .

// This example catches the core message EVMSG_CHANGE and re-initializes the dialog's values. // This is typically done to update GUI elements that correspond to certain scene elements. Bool CoreMessage( Int32 id , const BaseContainer & msg) { switch ( id ) { case EVMSG_CHANGE : { // check if this core message is new if (!CheckCoreMessage(msg)) break ; this->InitValues(); break ; } } return GeDialog::CoreMessage ( id , msg); } Bool InitValues() { // set default value SetString(1000, "---" _s);

// access active document and object BaseDocument * const doc = GetActiveDocument (); if (doc == nullptr ) return true ; BaseObject * const object = doc-> GetActiveObject (); if ( object == nullptr ) return true ;

// set string value SetString(1000, object-> GetName ()); return true ; }

GeDialog Parent

A GeDialog can be the base of a sub-dialog or a custom GUI element. In this case it must send messages to a parent dialog. The typical use case is a custom GUI element (based on CustomGuiData , iCustomGui ) that has to inform the parent dialog that a stored value has changed.

// This example sends a message from a GeDialog (iCustomGui) // to the parent GeDialog to inform about change of stored value.

// construct the message BaseContainer message( BFM_ACTION ); message.SetInt32( BFM_ACTION_ID , GetId()); message.SetData( BFM_ACTION_VALUE , _value);

// send the message SendParentMessage(message);

Utility

坐标

These utility functions allow to access the dimensions of a gadget or to transfer given coordinates into various spaces:

// This example catches the event when the button with the ID 4000 is pressed. // The dimensions of the button are accessed and transferred into screen space // so a pop up menu can be displayed beside it.

if ( id == 4000) { // get button dimensions Int32 x, y, w, h = 0; GetItemDim( id , &x, &y, &w, &h);

// construct position of the pop up menu x += w; Local2Screen(&x, &y);

// define pop up menu BaseContainer bc; bc. InsData (5159, "CMD" ); // cube bc. InsData (0, String ()); bc. InsData (5160, "CMD" ); // sphere

// show pop up menu ShowPopupMenu ( Get (), x, y, bc); }

Colors

Color related functions are:

// This example edits the color of the text gadget with the ID 1000. // The text color is set to red. SetDefaultColor(1000, COLOR_TEXT_EDIT , 向量 (1.0, 0.0, 0.0));

延伸阅读

BFM_SETSTATUSBAR
@ BFM_SETSTATUSBAR
To set a statusbar (e.g. inside a SCROLLGROUP (dialog element)):
定义: gui.h:813
String::HexToString
static String HexToString(UInt32 v, Bool prefix0x=true)
定义: c4d_string.h:478
BFM_INPUT_KEYBOARD
@ BFM_INPUT_KEYBOARD
Keyboard.
定义: gui.h:688
BFH_LEFT
@ BFH_LEFT
Aligned to the left. 1<<3.
定义: gui.h:306
BFM_ACTION
@ BFM_ACTION
One of the child elements made any action:
定义: gui.h:721
IMAGERESULT::OK
@ OK
Image loaded/created.
ShowPopupMenu
Int32 ShowPopupMenu(CDialog *cd, Int32 screenx, Int32 screeny, const BaseContainer &bc, Int32 flags=POPUP_RIGHT|POPUP_EXECUTECOMMANDS, Int32 *res_mainid=nullptr)
BaseList2D
定义: c4d_baselist.h:2144
UpdateDialogHelper::CommitChanges
void CommitChanges()
GetActiveDocument
BaseDocument * GetActiveDocument(void)
GradientKnot::pos
Float pos
Position.
定义: customgui_gradient.h:138
TriState
定义: c4d_gui.h:918
GeData::SetCustomDataType
void SetCustomDataType(Int32 datatype, const CustomDataType &v)
定义: c4d_gedata.h:664
DRAGTYPE_ATOMARRAY
@ DRAGTYPE_ATOMARRAY
AtomArray.
定义: gui.h:759
COLOR_TEXT_EDIT
@ COLOR_TEXT_EDIT
定义: c4d_colors.h:108
BFM_DRAGRECEIVE
@ BFM_DRAGRECEIVE
Drag receive. (See DragAndDrop.)
定义: gui.h:747
BFM_INPUT_VALUE
@ BFM_INPUT_VALUE
Int32 Value of the input channel (true/false or a Int32 value, e.g. for scroll wheel data).
定义: gui.h:701
BFM_STATUSBAR_TINT_COLOR
@ BFM_STATUSBAR_TINT_COLOR
Int32 Color ID for the status bar, or as RGB value (Vector).
定义: gui.h:821
SimpleListView::SetProperty
Bool SetProperty(Int32 id, Int32 val)
GetInputState
Bool GetInputState(Int32 askdevice, Int32 askchannel, BaseContainer &res)
BaseObject
定义: c4d_baseobject.h:224
BFM_INPUT_DEVICE
@ BFM_INPUT_DEVICE
Int32 Device:
定义: gui.h:686
BaseContainer::SetInt32
void SetInt32(Int32 id, Int32 l)
定义: c4d_basecontainer.h:505
BFM_INTERACTEND
@ BFM_INTERACTEND
Sent when user interaction ends.
定义: gui.h:917
BFH_CENTER
@ BFH_CENTER
Centered horizontally.
定义: gui.h:305
BaseContainer::SetString
void SetString(Int32 id, const maxon::String &s)
定义: c4d_basecontainer.h:569
GradientKnot
Represents a knot in a gradient.
定义: customgui_gradient.h:134
Float
maxon::Float Float
定义: ge_sys_math.h:64
BFH_RIGHT
@ BFH_RIGHT
Aligned to the right. 1<<4.
定义: gui.h:307
BitmapButtonCustomGui
定义: customgui_bitmapbutton.h:117
DR_MULTILINE_HIGHLIGHTLINE
@ DR_MULTILINE_HIGHLIGHTLINE
Highlight lines.
定义: gui.h:316
KEY_F1
@ KEY_F1
定义: gui.h:83
BFV_BORDERGROUP_CHECKBOX
@ BFV_BORDERGROUP_CHECKBOX
Checkbox in title of a border group.
定义: gui.h:193
AtomArray::GetCount
Int32 GetCount() const
定义: c4d_baselist.h:1619
BFM_ACTION_ID
@ BFM_ACTION_ID
Int32 ID of the dialog element that triggered the action.
定义: gui.h:722
IconData
Represents a single icon in a large bitmap array.
定义: operatingsystem.h:736
DR_MULTILINE_PYTHON
@ DR_MULTILINE_PYTHON
Python line return handling.
定义: gui.h:320
DR_MULTILINE_SYNTAXCOLOR
@ DR_MULTILINE_SYNTAXCOLOR
Python syntax highlighting.
定义: gui.h:314
SizePix
Int32 SizePix(Int32 pixels)
定义: c4d_gui.h:3034
Ocube
#define Ocube
Cube.
定义: ge_prepass.h:1040
DLG_TYPE::ASYNC
@ ASYNC
Non-modal (asynchronous) dialog.
BASEBITMAP_DATA_GUIPIXELRATIO
#define BASEBITMAP_DATA_GUIPIXELRATIO
Float.
定义: c4d_basebitmap.h:97
TriState::Add
void Add(TYPE val)
定义: c4d_gui.h:964
CommandData::Execute
virtual Bool Execute(BaseDocument *doc, GeDialog *parentManager)
GeDialog
定义: c4d_gui.h:1071
BaseContainer::SetBool
void SetBool(Int32 id, Bool b)
定义: c4d_basecontainer.h:498
DR_MULTILINE_WORDWRAP
@ DR_MULTILINE_WORDWRAP
Word wrap multi-line field.
定义: gui.h:321
BFM_ACTION_VALUE
@ BFM_ACTION_VALUE
GeData Action value.
定义: gui.h:723
BaseBitmap::Init
static IMAGERESULT Init(BaseBitmap *&res, const Filename &name, Int32 frame=-1, Bool *ismovie=nullptr, BitmapLoaderPlugin **loaderplugin=nullptr, const maxon::Delegate< void(Float progress)> &progressCallback=nullptr)
DLG_CANCEL
@ DLG_CANCEL
Cancel button.
定义: ge_prepass.h:3651
NAME
NAME
String Get/Set. The layer name.
定义: ge_prepass.h:8
MOUSE_POINT_HAND
static const Int32 MOUSE_POINT_HAND
Point hand cursor.
定义: ge_prepass.h:2495
GradientKnot::col
Vector col
Color.
定义: customgui_gradient.h:136
BFV_GRIDGROUP_ALLOW_WEIGHTS
@ BFV_GRIDGROUP_ALLOW_WEIGHTS
Allow the user to move the weights.
定义: gui.h:197
SCROLLGROUP_VERT
@ SCROLLGROUP_VERT
Allow the group to scroll vertically.
定义: gui.h:420
BFM_STATUSBAR_PROGRESS
@ BFM_STATUSBAR_PROGRESS
Float Between 0.0 and 1.0.
定义: gui.h:817
BaseContainer::GetId
Int32 GetId() const
定义: c4d_basecontainer.h:131
CommandData::RestoreLayout
virtual Bool RestoreLayout(void *secret)
MOUSE_FORBIDDEN
static const Int32 MOUSE_FORBIDDEN
Forbidden cursor.
定义: ge_prepass.h:2484
Osphere
#define Osphere
Sphere.
定义: ge_prepass.h:1041
String
定义: c4d_string.h:38
SimpleListView
A class for simple list views. See ListView.cpp SDK example.
定义: c4d_listview.h:147
UpdateDialogHelper
Helper class for GeDialog::BeginLayoutChange()
定义: c4d_gui.h:1033
BFV_SCALEFIT
@ BFV_SCALEFIT
Scale fit. BFV_SCALE|BFV_FIT.
定义: gui.h:302
BFV_FIT
@ BFV_FIT
Fit. BFV_BOTTOM|BFV_TOP.
定义: gui.h:300
BFM_INPUT
@ BFM_INPUT
A dialog/user area receives this message if any mouse or keyboard input is received....
定义: gui.h:683
BFM_DRAG_FINISHED
@ BFM_DRAG_FINISHED
Bool Drag finished.
定义: gui.h:770
maxon::Classes::Get
const Class< R > & Get(const Id &cls)
定义: objectbase.h:1903
BFM_INPUT_CHANNEL
@ BFM_INPUT_CHANNEL
Int32 Contains the key or mouse button. See also KEY.
定义: gui.h:691
KEY_ENTER
@ KEY_ENTER
定义: gui.h:68
NOTOK
#define NOTOK
定义: ge_sys_math.h:265
Tbaselist2d
#define Tbaselist2d
2D list.
定义: ge_prepass.h:938
CommandData
定义: c4d_commanddata.h:61
GeData
定义: c4d_gedata.h:82
LV_COLUMN_CHECKBOX
@ LV_COLUMN_CHECKBOX
Checkbox.
定义: ge_prepass.h:5131
C4DAtom
定义: c4d_baselist.h:1331
Gradient::InsertKnot
Int32 InsertKnot(const GradientKnot &knot)
INSTANCEOF
#define INSTANCEOF(X, Y)
定义: c4d_baselist.h:38
BFM_STATUSBAR_PROGRESSON
@ BFM_STATUSBAR_PROGRESSON
Bool Statusbar active.
定义: gui.h:815
Int32
maxon::Int32 Int32
定义: ge_sys_math.h:58
GeDialog::CoreMessage
virtual Bool CoreMessage(Int32 id, const BaseContainer &msg)
GeDialog::Command
virtual Bool Command(Int32 id, const BaseContainer &msg)
ApplicationOutput
#define ApplicationOutput(formatString,...)
定义: debugdiagnostics.h:207
BaseBitmap::SetData
Bool SetData(Int32 id, const GeData &data)
SimpleListView::SetItem
Bool SetItem(Int32 id, const BaseContainer &data)
SCROLLGROUP_BORDERIN
@ SCROLLGROUP_BORDERIN
Display a small border around the scroll group.
定义: gui.h:424
GradientCustomGui::SetGradient
Bool SetGradient(Gradient *grad)
DLG_OK
@ DLG_OK
OK button.
定义: ge_prepass.h:3650
CUSTOMGUI_GRADIENT
#define CUSTOMGUI_GRADIENT
Gradient custom GUI ID.
定义: customgui_gradient.h:26
CUSTOMGUI_PROGRESSBAR
#define CUSTOMGUI_PROGRESSBAR
Progress bar.
定义: lib_description.h:220
BitmapButtonCustomGui::SetImage
Bool SetImage(BaseBitmap *bmp, Bool copybmp, Bool secondstate=false)
EVMSG_CHANGE
#define EVMSG_CHANGE
Sent by EventAdd().
定义: ge_prepass.h:2530
BORDER_NONE
@ BORDER_NONE
No border.
定义: gui.h:250
HYPERLINK_IS_LINK
#define HYPERLINK_IS_LINK
Bool true for hyperlinks, static text otherwise.
定义: customgui_hyperlink.h:34
BFM_INPUT_Y
@ BFM_INPUT_Y
Float Y value.
定义: gui.h:704
向量
maxon::Vec3< maxon::Float64, 1 > Vector
定义: ge_math.h:145
BFM_INPUT_MOUSE
@ BFM_INPUT_MOUSE
Mouse.
定义: gui.h:687
BORDER_GROUP_IN
@ BORDER_GROUP_IN
Group border inside.
定义: gui.h:255
BFM_INPUT_MOUSELEFT
@ BFM_INPUT_MOUSELEFT
Left mouse button.
定义: gui.h:692
AutoAlloc
定义: ge_autoptr.h:36
IDC_OK
#define IDC_OK
定义: c4d_gui.h:15
BaseContainer::InsData
GeData * InsData(Int32 id, const GeData &n)
定义: c4d_basecontainer.h:238
SimpleListView::SetLayout
Bool SetLayout(Int32 columns, const BaseContainer &data)
GradientCustomGui
定义: customgui_gradient.h:362
BITMAPBUTTON_BUTTON
#define BITMAPBUTTON_BUTTON
定义: customgui_bitmapbutton.h:35
CUSTOMDATATYPE_GRADIENT
#define CUSTOMDATATYPE_GRADIENT
Gradient custom data ID.
定义: customgui_gradient.h:29
BFM_INTERACTSTART
@ BFM_INTERACTSTART
定义: gui.h:898
Bool
maxon::Bool Bool
定义: ge_sys_math.h:53
BFH_SCALEFIT
@ BFH_SCALEFIT
Scale fit. BFH_SCALE|BFH_FIT.
定义: gui.h:310
BaseDocument::GetActiveObject
BaseObject * GetActiveObject(void)
UInt
maxon::UInt UInt
定义: ge_sys_math.h:63
BaseCustomGui::SetData
Bool SetData(const TriState< GeData > &tristate)
定义: customgui_base.h:107
C4DAtom::IsInstanceOf
Bool IsInstanceOf(Int32 id) const
定义: c4d_baselist.h:1373
BaseList2D::GetName
String GetName() const
定义: c4d_baselist.h:2318
CUSTOMGUI_BITMAPBUTTON
#define CUSTOMGUI_BITMAPBUTTON
Bitmap button custom GUI ID.
定义: customgui_bitmapbutton.h:25
AtomArray
定义: c4d_baselist.h:1587
BFM_INPUT_X
@ BFM_INPUT_X
Float X value.
定义: gui.h:703
LV_COLUMN_TEXT
@ LV_COLUMN_TEXT
Text.
定义: ge_prepass.h:5128
BaseContainer::GetInt32
Int32 GetInt32(Int32 id, Int32 preset=0) const
定义: c4d_basecontainer.h:303
GetIcon
Bool GetIcon(Int32 lIconID, IconData *pData)
GeDialog::CreateLayout
virtual Bool CreateLayout(void)
DR_MULTILINE_MONOSPACED
@ DR_MULTILINE_MONOSPACED
Monospaced font.
定义: gui.h:313
SLV_MULTIPLESELECTION
#define SLV_MULTIPLESELECTION
Multiple selection allowed.
定义: c4d_listview.h:141
BaseDocument
定义: c4d_basedocument.h:490
GeListView::AttachListView
Bool AttachListView(GeDialog *cd, Int32 id)
BaseContainer
定义: c4d_basecontainer.h:46
DR_MULTILINE_STATUSBAR
@ DR_MULTILINE_STATUSBAR
Display a statusbar with the cursor position.
定义: gui.h:315
C4DGadget
Represents a gadget in a dialog.
定义: c4d_gui.h:99
BFV_TOP
@ BFV_TOP
Aligned to the top. 1<<0.
定义: gui.h:298
AtomArray::GetIndex
C4DAtom * GetIndex(Int32 idx) const
定义: c4d_baselist.h:1634
GeListView::DataChanged
void DataChanged(void)
Forces a recalculation. Called when the list view data has been changed.

Copyright  © 2014-2025 乐数软件    

工业和信息化部: 粤ICP备14079481号-1