How to pass python code to c4d's editor window?
-
On 16/10/2017 at 04:03, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R19
Platform: Mac OSX ;
Language(s) : C++ ;---------
Hello all,I've written a particle-modifier plugin that calls a python script (much like the ordinary Python Generator, but now it works on Particles).
I would like to add the functionality of the "Open in Python Editor"-button, but I don't know how to implement it. I have found a function that would do the same in coffee here (https://developers.maxon.net/docs/cpp/2023_2/c4d__coffee_8h.html#a2274594417d5a88df99157f68c5b199a)
but my question is: How to pass my python-code to c4d's editor window and back?Kind regards,
Hermen
-
On 17/10/2017 at 08:50, xxxxxxxx wrote:
Hi,
CodeEditor_Open() is the function to use with Python as well but the documentation lacks information on how to implement the CodeEditorCallback.
The scripts hosted by plugins are edited inside the Script Expression editor. And plugins have to implement the callback so that they can interact with this editor.In the MSG_DESCRIPTION_COMMAND message for the "Open Python Editor" button, call CodeEditor_Open() passing the BaseList2D* node and the callback.
Inside the callback, several messages have to be handled:- CODEEDITOR_GETSTRING: Return the code string to set inside the Script Expression editor.
- CODEEDITOR_SETSTRING: Update the code string from the Script Expression editor.
- CODEEDITOR_GETID: Return the description ID for the parameter storing the code string. Used for undo handling.
- CODEEDITOR_COMPILE: Compile the code string. PythonLibrary::CheckSyntax() (see c4d_libs/lib_py.h) is used for Python code.
- CODEEDITOR_EXECUTE: Execute the code string (usually triggering an update of the active document).
Here is how a CodeEditorCallback can be implemented:
static GeData PythonExpressionCallback(BaseList2D* node, const BaseContainer& msg) { GeData res; BaseContainer* data = node->GetDataInstance(); if (data == nullptr) return res; switch (msg.GetId()) { case CODEEDITOR_GETSTRING: { BaseContainer bc; bc.SetString(CODEEDITOR_SETSTRING, data->GetString(PARAMETER_PYTHONSCRIPT)); bc.SetInt32(CODEEDITOR_SETMODE, SCRIPTMODE_PYTHON); res = bc; break; } case CODEEDITOR_SETSTRING: { GePythonGIL gil; data->SetString(PARAMETER_PYTHONSCRIPT, msg.GetString(CODEEDITOR_SETSTRING)); res = true; break; } case CODEEDITOR_COMPILE: { GePythonGIL pygil; PythonLibrary pylib; BaseContainer bc; String err_string; Int32 err_line = 0, err_row = 0; if (pylib.CheckSyntax(data->GetString(PARAMETER_PYTHONSCRIPT), &err_row, &err_line, &err_string)) { bc.SetInt32(CODEEDITOR_GETERROR_RES, true); bc.SetInt32(CODEEDITOR_GETERROR_LINE, -1); bc.SetInt32(CODEEDITOR_GETERROR_POS, -1); } else { bc.SetInt32(CODEEDITOR_GETERROR_RES, false); bc.SetString(CODEEDITOR_GETERROR_STRING, "SyntaxError: "+err_string); bc.SetInt32(CODEEDITOR_GETERROR_LINE, err_line); bc.SetInt32(CODEEDITOR_GETERROR_POS, err_row); } res = bc; break; } case CODEEDITOR_EXECUTE: { BaseContainer bc; EventAdd(); bc.SetInt32(CODEEDITOR_GETERROR_RES, true); bc.SetString(CODEEDITOR_GETERROR_STRING, ""); bc.SetInt32(CODEEDITOR_GETERROR_LINE, -1); bc.SetInt32(CODEEDITOR_GETERROR_POS, -1); res = bc; break; } case CODEEDITOR_GETID: { return GeData(CUSTOMDATATYPE_DESCID, DescID(DescLevel(PARAMETER_PYTHONSCRIPT))); } } return res; }
-
On 19/10/2017 at 13:08, xxxxxxxx wrote:
Thanks Yannick, that's awesome!
I'll try it over the weekend...
Regards,
Hermen