Overview
- Generic GUI actions are implemented with the CommandData plugin class.
- A custom window is based on GeDialog which has to be stored within a CommandData plugin.
- The window layout can be defined in code or using a resource file.
- File and file names are handled with maxon::Url and ::Filename classes.
- The content of files can be read using file streams.
Adding new Commands
A command is an action that is presented in Cinema 4D's user interface. The command can be invoked by pressing the button in the interface or calling CallCommand() with the command ID.
A custom command is created by implementing a CommandData based class. CommandData::Execute() receives a pointer to the currently active BaseDocument.
See also Common Plugin Concepts and Command Utility Manual.
class ExampleCommand : public CommandData
{
public:
Bool Execute(BaseDocument*
doc, GeDialog* parentManager)
{
return true;
};
static ExampleCommand* Alloc() { return NewObjClear(ExampleCommand); }
};
#define INSTANCEOF(X, Y)
Definition: c4d_baselist.h:49
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:204
maxon::Bool Bool
Definition: ge_sys_math.h:46
const char * doc
Definition: pyerrors.h:226
A custom command plugin must be registered with RegisterCommandPlugin(). The function must be called in the context of PluginStart().
See also Plugin Messages.
Bool RegisterCommandPlugin(Int32 id, const maxon::String &str, Int32 info, BaseBitmap *icon, const maxon::String &help, CommandData *dat)
Creating new Dialogs
GeDialog is the base class for custom dialog windows. A custom window is created by implementing a GeDialog based class.
See GeDialog Manual.
class ExampleDialog : public GeDialog
{
public:
{
SetTitle("Example Dialog"_s);
return true;
}
};
A dialog window can be displayed modal/synchronously (blocking) or non-modal/asynchronously. Such an asynchronous dialog instance must be stored in memory. It is typically stored as a member of a CommandData plugin. The CommandData plugin can be used to open and close the dialog. CommandData::RestoreLayout() must be implemented to handle the dialog correctly in a layout.
class ExampleCommand : public CommandData
{
private:
ExampleDialog _dialog;
public:
Bool Execute(BaseDocument*
doc, GeDialog* parentManager)
{
if (_dialog.IsOpen() == false)
{
}
else
{
_dialog.Close();
}
return true;
};
Bool RestoreLayout(
void* secret)
{
return _dialog.RestoreLayout(g_exampleDialogID, 0, secret);
};
static ExampleCommand* Alloc() { return NewObjClear(ExampleCommand); }
};
ASYNC
Asynchronous thread.
Definition: ge_prepass.h:1
Dialog Layout
The layout is defined with groups that contain various GUI gadgets. It is possible to define the layout by implementing GeDialog::CreateLayout(). It is also possible to define the layout in a layout file.
See Layout and Resource Files Manual.
{
SetTitle("Example Dialog"_s);
GroupEnd();
return true;
}
{
SetInt32(g_numberID, 123);
return true;
}
@ BFH_SCALEFIT
Scale fit. BFH_SCALE|BFH_FIT.
Definition: gui.h:316
Interaction
A user can interact with the gadgets displayed in the dialog. The dialog can react when a value was changed or when a button was pressed. In such a case GeDialog::Command() will be called.
See Interaction and Gadget Values.
{
switch (id)
{
case (g_numberID):
{
if (GetInt32(g_numberID,
value))
{
const String valueStr = String::IntToString(
value);
}
break;
}
case (g_buttonID):
{
if (GetInt32(g_numberID,
value))
{
SetInt32(g_numberID,
value);
}
break;
}
}
return true;
}
PyObject * value
Definition: abstract.h:715
maxon::Int32 Int32
Definition: ge_sys_math.h:51
const char const char * msg
Definition: object.h:438
Handling Files
Files can simply be read using file streams. File names can be handled using the Cinema API Filename class or the maxon::Url class.
See Filename Manual, Url Manual and InputStream Manual.
String LoadTextFromFile(
const Filename&
file)
{
{
err.DiagOutput();
err.DbgStop();
return ""_s;
};
const maxon::InputStreamRef inputStream = url.OpenInputStream()
iferr_return;
}
NONE
Definition: asset_browser.h:1
Definition: basearray.h:415
ResultMem Resize(Int newCnt, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::DEFAULT)
Resizes the array to contain newCnt elements. If newCnt is smaller than GetCount() all extra elements...
Definition: basearray.h:1217
Definition: string.h:1287
Int64 Int
signed 32/64 bit int, size depends on the platform
Definition: apibase.h:187
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:69
PyWideStringList Py_ssize_t length
Definition: initconfig.h:448
maxon::Url MaxonConvert(const Filename &fn, MAXONCONVERTMODE convertMode)
#define iferr_scope_handler
Definition: resultbase.h:1414
#define iferr_throw(ERR)
Definition: resultbase.h:1596
#define iferr_return
Definition: resultbase.h:1531
const char const char const char * file
Definition: object.h:439
This function could be used in a dialog like this:
{
SetTitle("Example Dialog"_s);
GroupEnd();
return true;
}
{
switch (id)
{
case (g_buttonID):
{
Filename selectedFile;
return true;
const String loadedText = LoadTextFromFile(selectedFile);
SetString(g_textID, loadedText);
break;
}
}
return true;
}
LOAD
Load.
Definition: c4d_filterdata.h:1
ANYTHING
Any file.
Definition: ge_prepass.h:0
@ BFV_TOP
Aligned to the top. 1<<0.
Definition: gui.h:304
@ DR_MULTILINE_WORDWRAP
Word wrap multi-line field.
Definition: gui.h:327