Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    How to Communicate between SubDialog and main GeDialog

    Cinema 4D SDK
    s22 python sdk
    2
    5
    686
    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.
    • ?
      A Former User
      last edited by A Former User

      Hello,
      I am trying to send messages from a SubDialog to a parent GeDialog. I am using a variation of this example implementation from NiklasR.

      import c4d
      
      PLUGIN_ID = 1000004 # Test ID
      ACTION_ID = 123456
      
      class MainDialog(c4d.gui.GeDialog):
          @property
          def sub_dialog(self):
              if not hasattr(self, '_sub_dialog'):
                  self._sub_dialog = SubDialog()
              return self._sub_dialog
      
          def CreateLayout(self):
              self.SetTitle('Main Dialog')
              self.AddButton(1000, 0, name="Open Sub-Dialog")
              return True
      
          def Message(self, msg, result):
              if msg.GetId() == ACTION_ID:
                  print msg
              return c4d.gui.GeDialog.Message(self, msg, result)
      
          def Command(self, param, bc):
              print bc
              if param == 1000:
                  self.sub_dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1)
              return True
      
          def Restore(self, pluginid, secref):
              if secref['subid'] == 1:
                  return self.sub_dialog.Restore(pluginid, secref)
              else:
                  return super(MainDialog, self).Restore(pluginid, secref)
      
      class SubDialog(c4d.gui.GeDialog):
          def CreateLayout(self):
              self.SetTitle('Sub-Dialog')
              self.AddButton(1000, 0, name="Send Message")
              return True
      
          def Command(self, id, msg):
              if id == 1001:
                  bc = c4d.BaseContainer()
                  bc.SetId(c4d.BFM_ACTION)
                  bc.SetInt32(c4d.BFM_ACTION_ID, ACTION_ID)
                  self.SendParentMessage(bc)
              return True
      
      class Command(c4d.plugins.CommandData):
      
          def Register(self):
              return c4d.plugins.RegisterCommandPlugin(
                      PLUGIN_ID, "Sub-Dialog Message", 0, None, "", self)
      
          @property
          def dialog(self):
              if not hasattr(self, '_dialog'):
                  self._dialog = MainDialog()
              return self._dialog
      
          def Execute(self, doc):
              return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID)
      
          def RestoreLayout(self, secref):
              return self.dialog.Restore(PLUGIN_ID, secref)
      
      if __name__ == '__main__':
          Command().Register()
      
      
      

      I've tried using SendParentMessage but, for whatever reason, my parent dialog isn't receiving the message.

      In my parent GeDialog I've tried using the Command and Message methods, but neither receives the message from the SubDialog.

      Can anyone help? Thank you!

      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hi @blastframe the main issue I guess is because of your SubDialog inherit from GeDial and not SubDialog.
        Here a quick example

        import c4d
        
        GADGET_ID_SUBDIALOG = 10000
        MSG_ID_SUBDIALOG_LAYOUT_CREATED = 1000001
        
        
        class SubDialogExample(c4d.gui.SubDialog):
        
            def CreateLayout(self):
                """
                This Method is called automatically when Cinema 4D Create the Layout (display) of the SubDialog.
                """
        
                # Creates a Static Text
                self.AddStaticText(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, "First Sub Dialog", c4d.BORDER_THIN_IN)
                msgContainer = c4d.BaseContainer(MSG_ID_SUBDIALOG_LAYOUT_CREATED)
                self.SendParentMessage(msgContainer)
        
                return True
        
        
        class ExampleDialog(c4d.gui.GeDialog):
        
            # The SubDialog need to be stored somewhere, we will need this instance to be attached to the current Layout
            subDialog = SubDialogExample()
        
            def CreateLayout(self):
                """
                This Method is called automatically when Cinema 4D Create the Layout (display) of the Dialog.
                """
        
                # Adds a Gadget that will host a SubDialog
                self.AddSubDialog(GADGET_ID_SUBDIALOG, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 100, 100)
        
                # Attaches the stored SubDialog to the Gadget previously created
                self.AttachSubDialog(self.subDialog, GADGET_ID_SUBDIALOG)
        
                return True
        
            
            def Message(self, msg, result):
                """
                This Method is called automatically when the GeDialog receives a Message.
                :param msg: The message container.
                :param result: A container to place results in.
                """
        
                # Messages is sent from the GeUserArea in line 65
                if msg.GetId() == MSG_ID_SUBDIALOG_LAYOUT_CREATED:
                    print("The GeUserArea, has been draw.")
                    return True
        
                return super(ExampleDialog, self).Message(msg, result)
        
        
        def main():
            # Creates a new instance of the GeDialog
            dlg = ExampleDialog()
        
            # Opens the GeDialog, since it's open it as Modal, it block Cinema 4D
            dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=300, defaulth=50)
        
        
        if __name__ == "__main__":
            main()
        

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        ? 1 Reply Last reply Reply Quote 0
        • ?
          A Former User @m_adam
          last edited by A Former User

          @m_adam Hi Maxime, thank you for the reply.

          I wasn't able to get it to work. I would like the Subdialog to be its own window, not attached to the Main Dialog. Is this possible? In the documentation for SendParentMessage it says the method is available for GeDialog but is it only for usage with GeUserArea? I don't think I understand the purpose of the Subdialog when used as a gadget. I see in the documentation for Subdialog that it inherits from GeDialog so shouldn't it be able to open as such? Thank you.

          import c4d
          
          PLUGIN_ID = 1000004 # Test ID
          ACTION_ID = 123456
          GADGET_ID_SUBDIALOG = 10000
          
          class SubDialog(c4d.gui.SubDialog):
              def CreateLayout(self):
                  self.SetTitle('Sub-Dialog')
                  self.AddButton(1001, 0, name="Send Message")
                  return True
          
              def Command(self, id, msg):
                  if id == 1001:
                      bc = c4d.BaseContainer()
                      bc.SetId(c4d.BFM_ACTION)
                      bc.SetInt32(c4d.BFM_ACTION_ID, ACTION_ID)
                      self.SendParentMessage(bc)
                  return True
          
          class MainDialog(c4d.gui.GeDialog):
              subDialog = SubDialog()
          
              def CreateLayout(self):
                  self.SetTitle('Main Dialog')
                  self.AddButton(1000, 0, name="Open Sub-Dialog")
                  # Adds a Gadget that will host a SubDialog
                  #self.AddSubDialog(GADGET_ID_SUBDIALOG, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 100, 100)
          
                  # Attaches the stored SubDialog to the Gadget previously created
                  #self.AttachSubDialog(self.subDialog, GADGET_ID_SUBDIALOG)
                  return True
          
              def Message(self, msg, result):
                  if msg.GetId() == ACTION_ID:
                      print "YES"
                      return True
                  return c4d.gui.GeDialog.Message(self, msg, result)
          
              def Command(self, param, bc):
                  print bc
                  if param == 1000:
                      self.subDialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1)
                  return True
          
              def Restore(self, pluginid, secref):
                  if secref['subid'] == 1:
                      return self.subDialog.Restore(pluginid, secref)
                  else:
                      return super(MainDialog, self).Restore(pluginid, secref)
          
          class Command(c4d.plugins.CommandData):
          
              def Register(self):
                  return c4d.plugins.RegisterCommandPlugin(
                          PLUGIN_ID, "Sub-Dialog Message", 0, None, "", self)
          
              @property
              def dialog(self):
                  if not hasattr(self, '_dialog'):
                      self._dialog = MainDialog()
                  return self._dialog
          
              def Execute(self, doc):
                  return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID)
          
              def RestoreLayout(self, secref):
                  return self.dialog.Restore(PLUGIN_ID, secref)
          
          if __name__ == '__main__':
              Command().Register()
          
          1 Reply Last reply Reply Quote 0
          • M
            m_adam
            last edited by m_adam

            Did you try my example which exactly demonstrate the use of a SubDialog?
            SubDialog is about having a dialog embedded into another one.

            If you want to make communicate two independent GeDialog you have to use CoreMessage because there is no hierarchy between them they are both independent windows.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            ? 1 Reply Last reply Reply Quote 0
            • ?
              A Former User @m_adam
              last edited by A Former User

              @m_adam Hi Maxime, I did try your example and I saw it working as a gadget but, you're right, I want to communicate between two GeDialogs. I followed your advice on using CoreMessage and found success with SpecialEventAdd. Thank you!

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