Building Plugin Submenus

On 20/02/2017 at 14:47, xxxxxxxx wrote:

Hi there,
i m trying here to get some kind of modular plugin
meaning i have one plugin folder with multiple pyp files
which all add their items to the same menu.

here is the code for the first pyp:

_# FILE plugins/test/test1.pyp
import c4d
from c4d import bitmaps
import os.path
import sys

PLUGIN_ID     = 1234500+1
PLUGIN_NAME     = 'Test Menu 1'

class MenuHandler(c4d.plugins.CommandData) :
     def Register(self) :
          bmp = bitmaps.BaseBitmap()
          dir, f = os.path.split(__file__)
          fn = os.path.join(dir, "res", "icon.png")
          return c4d.plugins.RegisterCommandPlugin(
                    id = PLUGIN_ID,
                    str = PLUGIN_NAME,
                    info = c4d.PLUGINFLAG_COMMAND_HOTKEY,
                    icon = bmp,
                    help = PLUGIN_NAME,
                    dat = MenuHandler())

def GetSubContainer(self, doc, submenu) :
          '''Build submenu.'''
          bc = c4d.BaseContainer()
          bc.SetString(1, PLUGIN_NAME)
          bc.SetString(1001, 'My Item 1')
          bc.SetString(1002, 'My Item 2')
          bc.SetString(1003, 'My Item 3')
          submenu.InsData(0, bc)
          return True
     def ExecuteSubID(self, doc, id) :
          return True
     def Init(self, op) :
          return True
     def Execute(self, doc) :
          return True

if __name__ == '__main__':

now, if you add some more pyp files by
duplicating the file and changing the PLUGIN_ID / NAME ...

_# FILE plugins/test/test2.pyp
PLUGIN_ID     = 1234500+2
PLUGIN_NAME     = 'Test Menu 2'

you get a menu item "test" under plugins (the name is the plugin folders name)
having subitems (one item per pyp file)
with sub-sub items (My Item 1 to 3)

but... you dont get the drag-off handler for menu items that the standard menus have.
(i mean that you can drag off the menu, and have it in a small floating window)

i noted that when you return false in GetSubContainer()
then you get the drag-off handler, but then you dont get the sub-sub items.

is there a way to enable this handler somehow ?
preferably for both levels ?
at Test Menu 1/2/3 and also at each My Item 1/2/3 ?

i uploaded the example here :

otherwise its not understandable i guess.

On 20/02/2017 at 20:58, xxxxxxxx wrote:

Hi Zeorge,
You can my fcs tools box plugin, its a .pyp file , so you can look at it in sublime, it will show how to do it, hope it helps you.

Download It:
AP Ashton

On 21/02/2017 at 01:44, xxxxxxxx wrote:

thanks ashton!
you're using a different apporach on how to build the plugins menu
by injecting manually commands as i understand it?
(didnt check about the drag-off handler behaviour yet)

about the handler there is something to find in the SDK here:
c4d.gui.ShowPopupDialog() has a the following flags:
POPUP_ALLOWUNDOCK --> "Allow to undock popupmenu."
POPUP_ALLOWUNDOCK_REC --> "Allow to undock popupmenu for children."

is there something like that for the "normal" menu like in my example?

On 21/02/2017 at 05:47, xxxxxxxx wrote:


the popup menu is a completely different thing. Don't get confused.

As you already found in Ashton's example normal menu's get detachable by having commands in them. Reason, when being torn off, the menu turns into a command palette, which it can't when the menu items are no commands.

But you have a completely different and maybe simpler option:
Cinema 4D will automatically group all plugins registered from within a sub-folder of the plugins folder into a sub-menu of the Plugins menu. It doesn't matter if you have several plugins in multiple .pyp files or if you register multiple plugins from within one single .pyp file. So instead of using sub-command IDs, you could simply register a bunch of CommandData plugins, each with its own unique plugin ID. And voila, there's your Plugin's sub-menu, that can be torn off by the user to get a button palette.

Speaking of unique plugin IDs. Maybe I'm wrong, than simply ignore me, but I'm a bit sus**cious about the line:

PLUGIN_ID     = 1234500+2 

Sure looks like a test ID, which is fine as long as you do not release the plugin. But the "+2" really makes me worry, as it might mean, that you plan to register only one ID and then use successive ones for whatever purposes. Of course you may have been lucky and received a bunch of successive IDs when requesting unique plugin IDs from Plugin Cafe. But just in case you are not, I'd like to emphasize that it is absolutely vital to request unique plugin IDs from Plugin Cafe in order not to break other plugins or get your own plugin broken by others. As I said, you sure know about this, I wanted to make absolutely sure, just in case you are not. Hope you don't mind.