Tool plugin gui
-
Hi,
I want to create a gui interface similar to the Measure tool for my tool, but the gui is blank when my tool is running.
I read py-sculpt_grab_brush_r16 in github, but I still can't solve my problemHere is my toolsscreenshot.h file
#ifndef TOOLSSCREENSHOT_H__ #define TOOLSSCREENSHOT_H__ enum { SSCREENSHOT_GROUPTWO_CUTBUTTON = 1051, }; #endif
Here is my toolsscreenshot.res file
CONTAINER toolsscreenshot { NAME toolsscreenshot; GROUP MDATA_MAINGROUP { SCALE_H; COLUMNS 1; BUTTON SSCREENSHOT_CUTBUTTON {} } }
Here is my toolsscreenshot.str file
STRINGTABLE toolsscreenshot { toolsscreenshot "S_ScreenShot"; SSCREENSHOT_CUTBUTTON "Cut"; }
and the toolsscreenshot.pyp file
class S_ScreenShot(plugins.ToolData): def Draw(self, doc, data, bd, bh, bt, flags): return c4d.TOOLDRAW_NONE def MouseInput(self, doc, data, bd, win, msg): return True if __name__ == "__main__": bmp = bitmaps.BaseBitmap() dir, file = os.path.split(__file__) fn = os.path.join(dir, "res", "S_PanZoom2D.tif") bmp.InitWith(fn) plugins.RegisterToolPlugin(id=PLUGIN_ID, str="S_ScreenShot", info=0, icon=bmp, help="", dat=S_ScreenShot())
Thanks for any help
-
Hello @chuanzhen,
Thank you for reaching out to us. In short, the answer is that you are looking at the wrong example and therefore do not load your GUI, resulting in nothing being displayed. You must overwrite ToolData.AllocSubDialog() to show your tool dialog.
There are two ways to implement tools in the Cinema 4D API: ToolData plugins which base their GUI on dialog resources, and DescriptionToolData plugins which base their GUI on description resources, i.e., work for example similar to an
ObjectData
plugin.In Python you can only implement directly
ToolData
plugins, i.e., plugins which are based on dialogs. There is however one caveat, as there isSculptBrushToolData
, which is a specialization ofDescriptionToolData
for sculpting brushes. AndSculptBrushToolData
has been wrapped for Python, sculpt_grab_brush_r16.pyp is an example for that.Python examples for
ToolData
plugins can be found in py-liquid_painter_r12.pyp and py-tooldata_ui_r15.pyp. Your classS_ScreenShot
is not implementingAllocSubDialog
and therefore cannot open that dialog. It must look something like this:class MyToolDialog(c4d.gui.SubDialog): """Realizes a dialog for a tool hook. """ def __init__(self, toolData: c4d.BaseContainer) -> None: """Not necessary, but IMHO advantageous to grab the tool data container. """ self._toolData = toolData def CreateLayout(self) -> bool: """Adds gadgets to the dialog. Either populate the dialog manually or load a dialog resource. """ return self.LoadDialogResource(*data) class S_ScreenShot(plugins.ToolData): """Realizes a tool hook. """ def AllocSubDialog(self, bc: c4d.BaseContainer) -> c4d.gui.SubDialog: """Called by Cinema 4D to allocate the tool dialog. """ return MyToolDialog(bc) ...
Cheers,
Ferdinand -
@ferdinand Thanks for your help!
My last version used dialog to implement gui, but due to some data transmission methods, I want to use res method to re-implement it, it seems that this is a limitation, I can only use dialog to achieve!
Use dialog:
-
Hello @chuanzhen,
I unfortunately do not fully understand what you want to say.
My last version used dialog to implement gui, but due to some data transmission methods, I want to use res method to re-implement
Both
ToolData
andDescriptionToolData
allow defining their GUI using resources, one uses dialog resources, the other description resources.it, it seems that this is a limitation, I can only use dialog to achieve!
I am not quite sure what you mean by limitation here. Not being able to implement a
DescriptionToolData
plugin in Python is a limitation, but that does not stop you from defining your tool plugin GUI in a resource.If you really want a description-based tool, you must move to C++ there you would also have (more) direct viewport image buffer access, which would further incentivize doing this.
Cheers,
Ferdinand -
@ferdinand yes,limition is python can not creat DescriptionToolData.
I'm not sure how to use resources to define the gui, in the above example also use function CreateLayout(), self.AddButton(), etc. to add elements.
There are related examples about defining their GUI uses dialog resources?
Thanks! -
Hello @chuanzhen,
in the above example also use function CreateLayout(), self.AddButton(),
I am not sure to which example you refer, but if it is my mock-up, you will see that it does not use any of the methods for adding gadgets manually. But you of course still have to implement the dialog and
CreateLayout
.def CreateLayout(self) -> bool: """Adds gadgets to the dialog. Either populate the dialog manually or load a dialog resource. """ return self.LoadDialogResource(*data)
The example is a bit optimistic, usually you still must do some stuff in the dialog, like for example adjusting the title or populating its menu, but in principle you just have to call
self.LoadDialogResource(*data)
to load a dialog resource into a dialog. Note that you can also invoke the method in succession to load in multiple dialog fragements.There is no dedicated Python documentation for this, but it all works in Python too, I have used it myself recently. I would recommend having a look at:
- The C++ Resource Files Manual to understand how resources work in general (and that there are two types of resources: one for descriptions and one for dialogs),
- the C++ Dialog Layout Manual to understand the fundamental design principle of a dialog (which you probably already do), and
- the C++ Dialog Resource Manual which describes the syntax of dialog resource files. Which is very similar to the syntax of description resources but not identical to it.
As far as I am aware of, we have no Python examples for using
GeDialog.LoadDialogResource
but there are plenty of C++ examples. The Asset API Examples Dialog is for example partially being loaded from a dialog resource (in line 80).Cheers,
Ferdinand -
@ferdinand Thanks!