Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Modified Pop Up Menu

    Cinema 4D SDK
    r21 python
    4
    7
    1.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      bentraje
      last edited by

      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=0

      A few notable behaviors are that

      1. modified columnar layout
      2. it disappears once you click a command (pop-up)

      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.

      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

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @bentraje
        last edited by ferdinand

        Hi,

        @bentraje said in Modified Pop Up Menu:

        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.

        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

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 2
        • B
          bentraje
          last edited by

          @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"
          
          CairynC ferdinandF 2 Replies Last reply Reply Quote 0
          • CairynC
            Cairyn @bentraje
            last edited by

            @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 the self.Close() part.
            (You can remove two of the three returns from that method.)

            1 Reply Last reply Reply Quote 3
            • ferdinandF
              ferdinand @bentraje
              last edited by ferdinand

              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
              

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 3
              • B
                bentraje
                last edited by

                @Cairyn and @zipit

                Thanks for the clarification. Your solution works as expected.

                1 Reply Last reply Reply Quote 0
                • ManuelM
                  Manuel
                  last edited by

                  Hello,

                  Thanks for sharing your answer @zipit and @Cairyn

                  Cheers,
                  Manuel

                  MAXON SDK Specialist

                  MAXON Registered Developer

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post