Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
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.
c4d.gui.ShowPopupDialog
You can see an illustration of what I am after here: https://www.dropbox.com/s/8dhs505yz34lap3/c4d140_modified_popup_menu.mp4?dl=0
A few notable behaviors are that
I initially thought the DLG_TYPE_ASYNC_POPUPEDIT or DLG_TYPE_ASYNC_POPUP_RESIZEABLE would do the trick but unfortunately, when you click a command, the dialog does not disappear.
DLG_TYPE_ASYNC_POPUPEDIT
DLG_TYPE_ASYNC_POPUP_RESIZEABLE
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
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.
CreateLayout()
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
@bentraje said in Modified Pop Up Menu:
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.
GeDialog.Close()
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"
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 the self.Close() part. (You can remove two of the three returns from that method.)
true
self.Close()
@Cairyn and @zipit
Thanks for the clarification. Your solution works as expected.
Hello,
Thanks for sharing your answer @zipit and @Cairyn
Cheers, Manuel