SOLVED CommandData Plugin with Submenu

Hi,

below is a simple CommandData plugin with a submenu to invoke different actions.

This works fine if more than one of these plugins (with unique Plugin Ids ofc) are in one plugin folder.
But there is no menu if there is only one plugin present in the folder.

Is there a way to create such a menu with one plugin, while not registering each menu point as separate command?

best index

# encoding: utf-8

''' CommandData Plugin with Menu '''

import c4d 

PLUGIN_ID = 12345678  # Unique Plugin Id

MENUID_CMD0 = 1000
MENUID_CMD1 = 1001

class MenuHandler(c4d.plugins.CommandData):

	def Register(self):
		return c4d.plugins.RegisterCommandPlugin(
			id=PLUGIN_ID, str="Test", info=c4d.PLUGINFLAG_COMMAND_HOTKEY, icon=None, help=None, dat=MenuHandler())

	def GetSubContainer(self, doc, submenu):
		bc = c4d.BaseContainer()
		bc.SetString(1, "Test")
		bc.SetString(MENUID_CMD0, "Command 0")
		bc.SetString(MENUID_CMD1, "Command 1")
		submenu.InsData(0, bc)
		return True

	def ExecuteSubID(self, doc, id):
		if id == MENUID_CMD0:
			pass
		if id == MENUID_CMD1:
			pass
		return True

	def Execute(self, doc):
		return True

if __name__ == "__main__":
	MenuHandler().Register()

hi,

there's currently a bug with this function in python.
(as i forgot to report in this thread)

Cheers,
Manuel

hm, ok...

but is this bug the reason, that there need to be more than one plugin in a plugin folder to get submenus?
or in other words ... is it possible to create a submenu in the plugin menu with a single command data plugin?

index

hi,

To have a sub menu, you need to register more than one plugin.
If you add an extra folder (//User/PluginDirectory/Menu) and make cinema4D point to PluginDirectory. An extra level will be created in the menu named in that example Menu.

Interesting fact. If you register two command, and one have SubID Registered, than the SubID works as expected. (this is obviously a bug)

If you burry the following code inside a sub folder, the second command will not appear, it's named "---" so should act as a separator. (but there's nothing to separate)
And you will be able to execute subIDs from the first command.

I would not do that on a public plugins. This will not work if the user remove that extra folder.

import c4d


MAIN_CMD_PLUGIN_ID  = 1055692
MAIN_CMD_PLUGIN_ID2  = 1055693



class MYCOMMANDWITHDIALOG (c4d.plugins.CommandData):

	def Execute(self, doc):
		print ("execute")
		return True

	def GetSubContainer(self, doc, submenu):
		print ("getsubcontainer", doc, submenu)
		bc = c4d.BaseContainer()
		bc.SetString(1, "Create Primitives")
		bc.SetString(1000, "Create a cube")
		bc.SetString(1001, "Create a sphere")
		submenu.InsData(0, bc)
		return True
	
	def ExecuteSubID(self, doc, subid):
		print("execute subID", doc, subid)
		op = None
		if subid == 1000:
			 op = c4d.BaseObject(c4d.Ocube)
		elif subid == 1001:
			op = c4d.BaseObject(c4d.Osphere)
		
		
		if op is None:
			return False

		doc.InsertObject(op)

		return True

class Dummy (c4d.plugins.CommandData):

	def Execute(self, doc):
		return True



def main():

    c4d.plugins.RegisterCommandPlugin(id=MAIN_CMD_PLUGIN_ID,
                                str  ="Command with sub id",
                                info = 0,
                                help ="Command with sub command or dialog option",
                                dat = MYCOMMANDWITHDIALOG(),
                                icon=None)

    c4d.plugins.RegisterCommandPlugin(id=MAIN_CMD_PLUGIN_ID2,
                                str  ="---",
                                info = 0,
                                help ="DummyHiddenCommand",
                                dat = Dummy(),
                                icon=None)
if __name__ == '__main__':
	main()

Cheers,
Manuel