I would do that, except the process for creating a plugin is not trivial and in no way intuitive anymore. There's no resEdit to generate all the necessary resource information and UI elements, so now I have to do that manually. That means to provide a meaningful and functional example, I need to now go through the several hoops of creating a plugin just for this test, despite giving reasonably clear indications of what is being done function and plugin-wise. And despite going through the process of getting a new plugin ID, and creating a new folder, .pyp file, res, strings_us, renaming my classes, using the correct, new, throwaway plugin ID, my plugin wont even initialize. Even though it's the same code as my actual plugin, just with renamed classes and file, and stripped down, the plugin would not initialize. So here's the code that had to hijack an existing toolData plugin SDK example to demonstrate the issue.
"""
Copyright: MAXON Computer GmbH
Author: XXX, Maxime Adam
Description:
- Tool, Creates a liquid Painter Tool.
- Consists of Metaball and Sphere.
Class/method highlighted:
- c4d.plugins.ToolData
- ToolData.GetState()
- ToolData.MouseInput()
- ToolData.Draw()
- ToolData.GetCursorInfo()
- ToolData.AllocSubDialog()
"""
import c4d
import os
# Be sure to use a unique ID obtained from www.plugincafe.com
PLUGIN_ID = 1025247
# Values must match with the header file, usd by c4d.plugins.GeLoadString
IDS_PRIMITIVETOOL = 50000
class SettingsDialog(c4d.gui.SubDialog):
"""Creates a Dialog to show the ToolData options.
This dialog will be displayed in the Attribute Manager so this means the ToolDemoDialog
will be instantiate each time the tool is activate and destruct when the AM change its mode.
"""
def __init__(self, sharedDict):
super(SettingsDialog, self).__init__()
def CreateLayout(self):
self.SetTitle("BB-Distribute Points")
self.GroupBegin(id=100010, flags=c4d.BFH_SCALEFIT, cols=1, rows=5, title="BB-Distribute Points")
self.GroupBegin(id=200010, flags=c4d.BFH_SCALEFIT, cols=2, rows=1)
#bc=c4d.BaseContainer()
self.AddCheckbox(id=8888, flags = c4d.BFH_LEFT, initw=10, inith= 10, name="")
self.linkGadget = self.AddCustomGui(9898, c4d.CUSTOMGUI_LINKBOX, "Custom", c4d.BFH_SCALEFIT, minw=100, minh=10)
self.GroupEnd()
self.GroupEnd()
return True
def Command(self, commandID, msg):
"""This Method is called automatically when the user clicks on a gadget and/or changes its value this function will be called.
It is also called when a string menu item is selected.
Args:
commandID (int): The ID of the gadget that triggered the event.
msg (c4d.BaseContainer): The original message container
Returns:
bool: False if there was an error, otherwise True.
"""
if commandID == 9898:
print(self.linkGadget.GetLink())
class LiquidTool(c4d.plugins.ToolData):
"""Inherit from ToolData to create your own tool"""
def __init__(self):
self.data = {'sphere_size':15}
def AllocSubDialog(self, bc):
"""Called by Cinema 4D To allocate the Tool Dialog Option.
Args:
bc (c4d.BaseContainer): Currently not used.
Returns:
The allocated sub dialog.
"""
return SettingsDialog(getattr(self, "data", {'sphere_size': 15}))
if __name__ == "__main__":
# Retrieves the icon path
directory, _ = os.path.split(__file__)
fn = os.path.join(directory, "res", "liquid.tif")
# Creates a BaseBitmap
bmp = c4d.bitmaps.BaseBitmap()
if bmp is None:
raise MemoryError("Failed to create a BaseBitmap.")
# Init the BaseBitmap with the icon
if bmp.InitWith(fn)[0] != c4d.IMAGERESULT_OK:
raise MemoryError("Failed to initialize the BaseBitmap.")
# Registers the tool plugin
c4d.plugins.RegisterToolPlugin(id=PLUGIN_ID,
str="Py-Liquid PainterBB",
info=0, icon=bmp,
help="This string is shown in the statusbar",
dat=LiquidTool())
This is a copy of an SDK example of a toolData plugin, it does the same thing I am doing in my plugin which is using and was as I described in my first post def AllocSubDialog(self, bc)
in the toolData pluginto call a c4d.gui.SubDialog
class that is calling CreateLayout(self)
which inside there is using self.linkGadget = self.AddCustomGui(9898, c4d.CUSTOMGUI_LINKBOX, "Custom", c4d.BFH_SCALEFIT, minw=100, minh=10)
. I also added the Command bit from your example, and it will print the object, but the object does not get retained.
Open Cinema. Select Py-Liquid PainterBB. Drag any object into the link field of the AM and it should disappear immediately.