Modified Pop Up Menu
-
Hi,
I'm trying to create a pop-up menu with a modified layout. Currently, the default layout of
c4d.gui.ShowPopupDialog
is vertical. I was looking forward to a columnar layout where its easier to see everything.You can see an illustration of what I am after here:
https://www.dropbox.com/s/8dhs505yz34lap3/c4d140_modified_popup_menu.mp4?dl=0A few notable behaviors are that
- modified columnar layout
- it disappears once you click a command (pop-up)
I initially thought the
DLG_TYPE_ASYNC_POPUPEDIT
orDLG_TYPE_ASYNC_POPUP_RESIZEABLE
would do the trick but unfortunately, when you click a command, the dialog does not disappear.You can see an illustration code below:
import c4d import os from c4d import gui, plugins, bitmaps, utils, documents PLUGIN_ID = 1011325 MAIN_TAB = 10001 MY_BUTTON = 11002 class MyDialog(gui.GeDialog): def get_all_objects(op): output = [] while op: output.append(op) get_all_objects(op.GetDown()) op = op.GetNext() return output def CreateLayout(self): self.GroupBegin(id=1013, flags=c4d.BFH_SCALEFIT, cols=5, rows=4) self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button1") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button2") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button3") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button4") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button5") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button6") self.GroupEnd() return True def Command(self, id, msg): if (id == MY_BUTTON): print "Button is clicked" return True return True class MyMenuPlugin(plugins.CommandData): dialog = None def Execute(self, doc): # create the dialog if self.dialog is None: self.dialog = MyDialog() return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC_POPUPEDIT, pluginid=PLUGIN_ID, defaultw=200, defaulth=150, xpos=-1, ypos=-1) def RestoreLayout(self, sec_ref): # manage the dialog if self.dialog is None: self.dialog = MyDialog() return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref) if __name__ == "__main__": okyn = plugins.RegisterCommandPlugin(PLUGIN_ID, "BT Popup",0, None, "Python Menu", MyMenuPlugin()) if (okyn): print "Utilities Pop Up"
Thank you for looking at my problem
-
Hi,
@bentraje said in Modified Pop Up Menu:
I initially thought the
DLG_TYPE_ASYNC_POPUPEDIT
orDLG_TYPE_ASYNC_POPUP_RESIZEABLE
would do the trick but unfortunately, when you click a command, the dialog does not disappear.To programmatically close a dialog you have to invoke
GeDialog.Close()
. So if you want to mimic a popup menu, you should do that after the button event handling.all_button_ids = [ID_BUTTON_1, ID_BUTTON_2, ...] def Command(self, id, msg): if id == ID_BUTTON_1: # your button logic ... if id in all_button_ids: self.Close()
Cheers
zipit -
@zipit said in Modified Pop Up Menu:
if id in all_button_ids:
Thanks for the response. I tried adding it. It didn't error out but it also didn't close.
You can see the current code here:
import c4d import os from c4d import gui, plugins, bitmaps, utils, documents PLUGIN_ID = 1011325 MAIN_TAB = 10001 MY_BUTTON = 11002 all_button_ids = [MY_BUTTON] class MyDialog(gui.GeDialog): def get_all_objects(op): output = [] while op: output.append(op) get_all_objects(op.GetDown()) op = op.GetNext() return output def CreateLayout(self): self.GroupBegin(id=1013, flags=c4d.BFH_SCALEFIT, cols=5, rows=4) self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button1") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button2") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button3") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button4") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Button5") self.AddButton(MY_BUTTON, c4d.BFV_MASK, initw=100, name="Changed") self.GroupEnd() return True def Command(self, id, msg): if (id == MY_BUTTON): print "Button is clicked" return True if id in all_button_ids: self.Close() return True return True class MyMenuPlugin(plugins.CommandData): dialog = None def Execute(self, doc): # create the dialog if self.dialog is None: self.dialog = MyDialog() return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC_POPUPEDIT, pluginid=PLUGIN_ID, defaultw=200, defaulth=150, xpos=-1, ypos=-1) def RestoreLayout(self, sec_ref): # manage the dialog if self.dialog is None: self.dialog = MyDialog() return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref) if __name__ == "__main__": okyn = plugins.RegisterCommandPlugin(PLUGIN_ID, "BT Popup",0, None, "Python Menu", MyMenuPlugin()) if (okyn): print "Utilities Pop Up"
-
@bentraje said in Modified Pop Up Menu:
Thanks for the response. I tried adding it. It didn't error out but it also didn't close
Unreached code. You return
true
when MY_BUTTON is clicked, and never get to theself.Close()
part.
(You can remove two of the three returns from that method.) -
Hi,
as @Cairyn said the problem is unreachable code. I also just saw now that you did assign the same ID to all your buttons in your
CreateLayout()
. Ressource and dialog element IDs should be unique. I would generally recommend to define your dialogs using a resource, but here is an example on how to do it in code.BUTTON_BASE_ID = 1000 BUTTON_NAMES = ["Button1", "Button2", "Button3", "Button4", "Button5"] BUTTON_DATA = {BUTTON_BASE_ID + i: name for i, name in enumerate(BUTTON_NAMES)} class MyDialog(gui.GeDialog): def CreateLayout(self): """ """ self.GroupBegin(id=1013, flags=c4d.BFH_SCALEFIT, cols=5, rows=4) for element_id, element_name in BUTTON_DATA.items(): self.AddButton(element_id, c4d.BFV_MASK, initw=100, name=element_name) self.GroupEnd() return True def Command(self, id, msg): """ """ if id == BUTTON_BASE_ID: print "First button has been clicked" elif id == BUTTON_BASE_ID + 1: print "Second button has been clicked" # ... if id in BUTTON_DATA.keys(): # or just if id in BUTTON_DATA self.Close() return True
-
@Cairyn and @zipit
Thanks for the clarification. Your solution works as expected.
-