Adding icon to submenu
-
Hi again!
I'm generating a dynamic menu and was playing around with icons. Since you have to register seperate icon ids this is probably too complicated. I had an interesting thing happen though I wanted to ask about.
I don't think it is documented, but I saw on old forum post where someone was saying you could add an icon to a submenu by naming the entry[name]&i[iconID]&
. When looping through menus, giving one of the entries an icon like that the subsequent entries also get that icon, even though they are named the same way the first ones were.
Entry seven was given the iconsubmenu.SetString(entryID, name + "&i" + str(iconID) + "&")
,
all the others are named with identical code:submenu.SetString(entryID, name)
.Anyone got any insight into what's happening here or how to use this technique correctly?
-
Hi @Boony2000, just to inform you this is a known bug normally fixed in R20.
I know you tagged your post as R20. But from my test, this bug is fixed in R20 SP1 (the one currently available to everyone), so may I ask you if your code was really executed in R20? If yes could you provide us with more information (like the current context, if it's called from a GeDialog or ShowPopupDialog.)
Nevertheless, as a workaround, you can register an icon without any opacity and use this one for entries without icons.
Documentation will be improved in this regards.
Cheers,
Maxime. -
Hi Maxime!
I just updated to R20.030 and the issue is still there.
The screenshot is from the main editor window. I pretty much do what is described in the doc toenhanceMainMenu()
.
Within that I insert my commandDataPluginmenu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_" + str(res.ID_MENUTEST))
and in
GetSubContainer()
I iterate through a list and callsubmenu.SetString(entryID, name)
or
submenu.SetString(entryID, name + "&i" + str(iconID) + "&")
-
Hi from my test here is it's working nicely either reacting to C4DPL_BUILDMENU or by overriding GetSubContainer in a CommandData plugin.
Could you please share with us some code that doesn't work and in which context exactly?
Thanks a lot.
Cheers,
Maxime. -
Hi Maxime!
I reduced the code down to a plugin that just adds the menu and uses an existing icon and the error still persists:
import c4d TMP_PLUGIN_ID = 1000001 def enhanceMainMenu(): mainMenu = c4d.gui.GetMenuResource("M_EDITOR") pluginsMenu = c4d.gui.SearchPluginMenuResource() menu = c4d.BaseContainer() menu.InsData(c4d.MENURESOURCE_SUBTITLE, "Test Menu") menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_" + str(TMP_PLUGIN_ID)) mainMenu.InsDataAfter(c4d.MENURESOURCE_STRING, menu, pluginsMenu) def PluginMessage(id, data): print "Pluginmessage" if id==c4d.C4DPL_BUILDMENU: enhanceMainMenu() c4d.gui.UpdateMenus() class MenuTest(c4d.plugins.CommandData): def GetSubContainer(self, doc, submenu) : menuItems = [["name1"], ["name2", "hasIcon"], ["name3"]] for i, data in enumerate(menuItems) : if len(data) > 1: submenu.SetString(i+1000, data[0] + "&i" + str(c4d.IDM_KEY_NEXT) + "&") else: submenu.SetString(i+1000, data[0]) return True if __name__ == "__main__": c4d.plugins.RegisterCommandPlugin( TMP_PLUGIN_ID, "MENU TEST", c4d.PLUGINFLAG_HIDEPLUGINMENU, None, None, MenuTest())
-
Hi @Boony2000 thanks a lot for the code sample I can indeed confirm the issue. I will forward this bug to our development team.
Here a workaround by registering an empty icon.
import c4d TMP_PLUGIN_ID = 1000001 def enhanceMainMenu(): mainMenu = c4d.gui.GetMenuResource("M_EDITOR") pluginsMenu = c4d.gui.SearchPluginMenuResource() menu = c4d.BaseContainer() menu.InsData(c4d.MENURESOURCE_SUBTITLE, "Test Menu") menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_" + str(TMP_PLUGIN_ID)) mainMenu.InsDataAfter(c4d.MENURESOURCE_STRING, menu, pluginsMenu) def PluginMessage(id, data): print "Pluginmessage" if id==c4d.C4DPL_BUILDMENU: enhanceMainMenu() class MenuTest(c4d.plugins.CommandData): def CreateEmptyBmp(self): # Create a BaseBitmap bmp = c4d.bitmaps.BaseBitmap() # Init this Bitmap with 1 pixel and as 1bit if bmp.Init(1, 1, 1, c4d.INITBITMAPFLAGS_NONE) != c4d.IMAGERESULT_OK: return None # add alpha channel alphaChannel = bmp.AddChannel(True, False) # Set alpha bmp.SetAlphaPixel(alphaChannel, 1, 1, 0) return bmp def GetSubContainer(self, doc, submenu) : # if we don't have already registered an "empty" icon do it # This work because, the CommandData is not register with an icon, otherwise use another unique ID if c4d.gui.GetIcon(TMP_PLUGIN_ID) is None: bmp = self.CreateEmptyBmp() if not bmp: return True c4d.gui.RegisterIcon(TMP_PLUGIN_ID, bmp) menuItems = [["name1"], ["name2", "hasIcon"], ["name3"]] for i, data in enumerate(menuItems) : if len(data) > 1: submenu.SetString(i+1000, data[0] + "&i" + str(c4d.IDM_KEY_NEXT) + "&") else: submenu.SetString(i+1000, data[0] + "&i" + str(TMP_PLUGIN_ID) + "&") return True if __name__ == "__main__": c4d.plugins.RegisterCommandPlugin( TMP_PLUGIN_ID, "MENU TEST", c4d.PLUGINFLAG_HIDEPLUGINMENU, None, None, MenuTest())
-
Thanks, Maxime!
I will use that in the meantime.
Edit: Why can't I flag your posts as the correct answer? I can only flag my own.