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

    Multiple SubDialogs

    Scheduled Pinned Locked Moved PYTHON Development
    24 Posts 0 Posters 14.8k Views
    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.
    • H Offline
      Helper
      last edited by

      On 06/04/2014 at 11:24, xxxxxxxx wrote:

      Thanks Niklas.
      I never thought about using Restore() in the main GeDialog class like that.

      -ScottA

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 07/04/2014 at 09:29, xxxxxxxx wrote:

        You're welcome, Scott.

        You can also find the code at the GitHub py-cinema4sdk repository under gui/restore-sub-dialog.pyp!
        Do also take a look at the respective readme file at gui/restore-sub-dialog.md.

        Best,
        -Niklas

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 07/04/2014 at 11:19, xxxxxxxx wrote:

          Thanks for the help guys, however I still have a few problems. Using Kiklas' method I got the SubDialogs to behave correctly when I re-open them while they are open and the window becomes active. I still get a Plugin not found while restoring a layout, I think this reason is due to having more than one sub dialog.

          here is the code:

          def Restore(self, PLUGIN_ID, secref) :
               if secref['subid'] == 1:
                    return self.sub_dialog1.Restore(PLUGIN_ID,secref)
               elif secref['subid'] == 2:
                    return self.sub_dialog2.Restore(PLUGIN_ID,secref)
               else:
                    return super(MainDialog, self).Restore(PLUGIN_ID,secref)
          

          How do I correctly look for both subdialogs.

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 07/04/2014 at 11:23, xxxxxxxx wrote:

            How do you open the subdialogs?

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 07/04/2014 at 11:26, xxxxxxxx wrote:

              if id == 10017: # Get Render Time
                   self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, defaulth=200, defaultw=300, subid = 2)
              

              Oh wait, I think I just figured it out, This has to have the plugin ID as well correct?

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                On 07/04/2014 at 11:41, xxxxxxxx wrote:

                No that did not work. Here is what my @properties look like

                @property
                def sub_dialog1(self) :
                     if not hasattr(self, '_sub_dialog1') :
                          self._sub_dialog1 = ColorDialog()
                     return self._sub_dialog1
                @property
                def sub_dialog2(self) :
                     if not hasattr(self, '_sub_dialog2') :
                          self._sub_dialog2 = RenderTimeDialog()
                     return self._sub_dialog2
                
                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  On 07/04/2014 at 11:58, xxxxxxxx wrote:

                  Here is the code from your exaple made to have 2 sub dialogs: Same problem.

                  import c4d
                    
                  PLUGIN_ID = 1000004 # Test ID
                    
                  class MainDialog(c4d.gui.GeDialog) :
                    
                      # Do not create the object on class-level, although it might
                      # be unimportant since you do not open multiple objects of your
                      # MainDialog, it is contradicting to have one instance of sub
                      # dialog for all instances of the main dialog.
                      # A property that creates the dialog on-demand is perfect for
                      # this purpose.
                    
                      @property
                      def sub_dialog(self) :
                          if not hasattr(self, '_sub_dialog') :
                              self._sub_dialog = SubDialog()
                          return self._sub_dialog
                      @property
                      def sub_dialog2(self) :
                          if not hasattr(self, '_sub_dialog2') :
                              self._sub_dialog2 = SubDialog2()
                          return self._sub_dialog2
                      # c4d.gui.GeDialog
                    
                      def CreateLayout(self) :
                          self.SetTitle('Main Dialog')
                          self.AddButton(1000, 0, name="Open Sub-Dialog")
                          return True
                    
                      def Command(self, param, bc) :
                          if param == 1000:
                              self.sub_dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1)
                              self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=2)
                          return True
                    
                      def Restore(self, pluginid, secref) :
                          # We override this method so we don't have to handle the sub-
                          # dialog from the CommandData plugin. THIS dialog is responsible
                          # for the sub-dialog, do not split such management throughout
                          # your program or it gets confusing.
                          if secref['subid'] == 1:
                              return self.sub_dialog.Restore(pluginid, secref)
                          elif secref['subid'] == 2:
                              return self.sub_dialog2.Restore(pluginid, secref)
                          else:
                              return super(MainDialog, self).Restore(pluginid, secref)
                    
                  class SubDialog(c4d.gui.GeDialog) :
                    
                      def CreateLayout(self) :
                          self.SetTitle('Sub-Dialog')
                          self.AddStaticText(1000, 0, name="This is the sub-dialog.")
                          return True
                  class SubDialog2(c4d.gui.GeDialog) :
                    
                      def CreateLayout(self) :
                          self.SetTitle('Sub-Dialog2')
                          self.AddStaticText(1000, 0, name="This is the sub-dialog2.")
                          return True
                    
                  class Command(c4d.plugins.CommandData) :
                    
                      def Register(self) :
                          return c4d.plugins.RegisterCommandPlugin(
                                  PLUGIN_ID, "Sub-Dialog Docking Test", 0, None, "", self)
                    
                      @property
                      def dialog(self) :
                          if not hasattr(self, '_dialog') :
                              self._dialog = MainDialog()
                          return self._dialog
                    
                      # c4d.plugins.CommandData
                    
                      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
                  • H Offline
                    Helper
                    last edited by

                    On 07/04/2014 at 13:45, xxxxxxxx wrote:

                    OK I got the example to work. 
                    however I cannot get my plugin to work. could it be that my main window uses a .res file?

                    import c4d
                      
                    PLUGIN_ID = 1000004 # Test ID
                      
                    class MainDialog(c4d.gui.GeDialog) :
                      
                        # Do not create the object on class-level, although it might
                        # be unimportant since you do not open multiple objects of your
                        # MainDialog, it is contradicting to have one instance of sub
                        # dialog for all instances of the main dialog.
                        # A property that creates the dialog on-demand is perfect for
                        # this purpose.
                      
                        @property
                        def sub_dialog(self) :
                            if not hasattr(self, '_sub_dialog') :
                                self._sub_dialog = SubDialog()
                            return self._sub_dialog
                        @property
                        def sub_dialog2(self) :
                            if not hasattr(self, '_sub_dialog2') :
                                self._sub_dialog2 = SubDialog2()
                            return self._sub_dialog2
                        # c4d.gui.GeDialog
                      
                        def CreateLayout(self) :
                            self.SetTitle('Main Dialog')
                            self.AddButton(1000, 0, name="Open Sub-Dialog")
                            return True
                      
                        def Command(self, param, bc) :
                            if param == 1000:
                                self.sub_dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1)
                                self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=2)
                            return True
                      
                        def Restore(self, pluginid, secref) :
                            # We override this method so we don't have to handle the sub-
                            # dialog from the CommandData plugin. THIS dialog is responsible
                            # for the sub-dialog, do not split such management throughout
                            # your program or it gets confusing.
                            if secref['subid'] == 1:
                                print "yes"
                                return self.sub_dialog.Restore(pluginid, secref)
                            if secref['subid'] == 2:
                                return self.sub_dialog2.Restore(pluginid, secref)
                            else:
                                return super(MainDialog, self).Restore(pluginid, secref)
                      
                    class SubDialog(c4d.gui.GeDialog) :
                      
                        def CreateLayout(self) :
                            self.SetTitle('Sub-Dialog')
                            self.AddStaticText(1000, 0, name="This is the sub-dialog.")
                            return True
                            
                    class SubDialog2(c4d.gui.GeDialog) :
                      
                        def CreateLayout(self) :
                            self.SetTitle('Sub-Dialog2')
                            self.AddStaticText(1000, 0, name="This is the sub-dialog2.")
                            return True
                      
                    class Command(c4d.plugins.CommandData) :
                      
                        def Register(self) :
                            return c4d.plugins.RegisterCommandPlugin(
                                    PLUGIN_ID, "Sub-Dialog Docking Test", 0, None, "", self)
                      
                        @property
                        def dialog(self) :
                            if not hasattr(self, '_dialog') :
                                self._dialog = MainDialog()
                            return self._dialog
                      
                        # c4d.plugins.CommandData
                      
                        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
                    • H Offline
                      Helper
                      last edited by

                      On 08/04/2014 at 14:11, xxxxxxxx wrote:

                      I think the problem with my plugin has something to do with the main command class, the "RestoreLayout" does not get called at all. I added some print functions to see and nothing. However the example prints just fine. Here is my main command code:

                      class RenderBuddy(c4d.plugins.CommandData) :
                        
                          @property
                          def RBdialog(self) :
                              if not hasattr(self, '_RBdialog') :
                                  self._RBdialog = BuddyDialog()
                              return self._RBdialog
                              
                          def Register(self) :
                              return c4d.plugins.RegisterCommandPlugin(PLUGIN_ID, "Render Buddy (Beta)",0, bmp, "", self)
                                      
                          def Execute(self, doc) :
                              return self.RBdialog.Open(c4d.DLG_TYPE_ASYNC,PLUGIN_ID)
                              
                          def RestorLayout(self, secref) :
                              print "RB_Main"
                              return self.RBdialog.Restore(PLUGIN_ID, secref)
                          
                      if __name__ == "__main__":
                          
                          path, fn = os.path.split(__file__)
                          bmp = bitmaps.BaseBitmap()  
                          bmp.InitWith(os.path.join(path, "res/icons/", "icon.tif"))
                           
                          RenderBuddy().Register()
                      

                      Everything seems to be right, but the RestoreLayout does not get called.

                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        Helper
                        last edited by

                        On 08/04/2014 at 14:14, xxxxxxxx wrote:

                        Figured it out! After typing it out above I realized RestoreLayout() was misspelled. Thank you guys for all the help!

                        *Edit there is a new problem the setup:

                            def Restore(self, pluginid, secref) :
                                if secref['subid'] == 1:
                                    print "Color"
                                    return self.RB_ColorDLG.Restore(pluginid,secref)
                                if secref['subid'] == 2:
                                    print "Temp"
                                    return self.RB_TempDLG.Restore(pluginid,secref)
                                else:
                                    print "Main"
                                    return super(BuddyDialog, self).Restore(pluginid,secref)
                        

                        This causes cinema to crash. I will restore the layout but if you launch the sub dialog again everything locks up. This happens with the Example as well. Confused

                        1 Reply Last reply Reply Quote 0
                        • H Offline
                          Helper
                          last edited by

                          On 08/04/2014 at 16:01, xxxxxxxx wrote:

                          Hi Shawn, I can reproduce the problems you have described. The Example I posted worked though,
                          but funnily broke after a few more times testing it. I'll have to talk to a developer on this, I am pretty
                          sure this is a bug. Especially this message is

                          Traceback (most recent call last) :
                            File "'restore-sub-dialog.pyp'", line 57, in CreateLayout
                          SystemError: error return without exception set

                          Best,
                          -Niklas

                          1 Reply Last reply Reply Quote 0
                          • H Offline
                            Helper
                            last edited by

                            On 08/04/2014 at 16:19, xxxxxxxx wrote:

                            Thank you Niklas.

                            -Shawn

                            1 Reply Last reply Reply Quote 0
                            • H Offline
                              Helper
                              last edited by

                              On 08/04/2014 at 19:28, xxxxxxxx wrote:

                              It seems to work just fine for me. No errors or problems at all.
                              Maybe you're trying to do something different than I'm doing?

                              Here is a complete example that works fine for me in R13.
                              Save it as a .pyp file and put it in your plugins folder.
                              The main dialog has buttons to open two other dialogs. And a button that will change the checkbox gizmo in dilaog1.
                              All three dialogs can be docked into the UI and saved in a custom layout.

                              #This is an example of a GeDialog plugin that opens three dialogs  
                              #It also allows all three dialogs to be docked and saved in a custom layout  
                                
                              import c4d, os  
                              from c4d import gui, plugins, bitmaps  
                                
                              PLUGIN_ID  = 1000004 #Testing ID  
                              SUBDLG_ID1  = 1000005 #Testing ID  
                              SUBDLG_ID2 = 1000006 #Testing ID  
                                
                              MAINDLG_BUTTON1_ID = 1000  
                              MAINDLG_BUTTON2_ID = 1001  
                              MAINDLG_BUTTON3_ID = 1002  
                              SUBDLG_TEXT_ID     = 1003  
                              SUBDLG_CHKBOX_ID   = 1004  
                              SUBDLG_RESET_ID    = 1005  
                                
                              ############################  
                              #The first sub dialog              
                              class SubDialog1(c4d.gui.GeDialog) :  
                                
                                def CreateLayout(self) :  
                                    self.SetTitle('Sub-Dialog1')      
                                      
                                    self.GroupBeginInMenuLine()    
                                    self.AddCheckbox(SUBDLG_RESET_ID, c4d.BFH_RIGHT, 100, 20, name="Reset")  
                                    self.GroupEnd()          
                                      
                                    self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0, "MyGroup")  
                                    self.GroupBorderSpace(5, 5, 5, 5)  
                                    self.GroupBorder(c4d.BORDER_BLACK)  
                                    self.AddStaticText(SUBDLG_TEXT_ID, c4d.BFH_LEFT, 200, 20, "This is the sub-dialog1")  
                                    self.AddCheckbox(SUBDLG_CHKBOX_ID, c4d.BFH_LEFT, 20, 20, "myChkbox")  
                                    self.GroupEnd()   
                                      
                                    return True          
                                      
                                def Command(self, id, msg) :  
                                    if id == SUBDLG_RESET_ID:  
                                        self.SetBool(SUBDLG_CHKBOX_ID, False)   
                                        self.SetBool(SUBDLG_RESET_ID, False)     
                                          
                                    return True         
                                      
                                      
                              ############################  
                              #The second sub dialog              
                              class SubDialog2(c4d.gui.GeDialog) :  
                                
                                def CreateLayout(self) :  
                                    self.SetTitle('Sub-Dialog2')      
                                      
                                    self.GroupBeginInMenuLine()    
                                    self.AddCheckbox(SUBDLG_RESET_ID, c4d.BFH_RIGHT, 100, 20, name="Reset")  
                                    self.GroupEnd()          
                                      
                                    self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0, "MyGroup")  
                                    self.GroupBorderSpace(5, 5, 5, 5)  
                                    self.GroupBorder(c4d.BORDER_BLACK)  
                                    self.AddStaticText(SUBDLG_TEXT_ID, c4d.BFH_LEFT, 200, 20, "This is the sub-dialog2")  
                                    self.AddCheckbox(SUBDLG_CHKBOX_ID, c4d.BFH_LEFT, 20, 20, "myChkbox")  
                                    self.GroupEnd()   
                                      
                                    return True          
                                      
                                def Command(self, id, msg) :  
                                    if id == SUBDLG_RESET_ID:  
                                        self.SetBool(SUBDLG_CHKBOX_ID, False)   
                                        self.SetBool(SUBDLG_RESET_ID, False)     
                                          
                                    return True          
                                      
                                
                                
                              ############################  
                              #The main dialog  
                              class MainDialog(c4d.gui.GeDialog) :   
                                
                                sub_dialog1 = SubDialog1()  
                                sub_dialog2 = SubDialog2()          
                                
                                def CreateLayout(self) :  
                                    self.SetTitle('Main Dialog')  
                                    self.AddButton(MAINDLG_BUTTON1_ID, 0, name="Open Sub-Dialog1")  
                                    self.AddButton(MAINDLG_BUTTON2_ID, 0, name="Open Sub-Dialog2")  
                                    self.AddButton(MAINDLG_BUTTON3_ID, 0, name="Change Sub-Dialog1")  
                                    return True  
                                
                                def Command(self, id, msg) :  
                                    if id == MAINDLG_BUTTON1_ID:  
                                        self.sub_dialog1.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=SUBDLG_ID1)  
                                          
                                    if id == MAINDLG_BUTTON2_ID:  
                                        self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=SUBDLG_ID2)              
                                          
                                    if id == MAINDLG_BUTTON3_ID:  
                                        self.sub_dialog1.SetBool(SUBDLG_CHKBOX_ID, True)              
                                          
                                    return True  
                                      
                                #Restore the subdialog and the main dialog in the layout  
                                def Restore(self, pluginid, secref) :  
                                    if secref['subid'] == SUBDLG_ID1:  
                                        return self.sub_dialog1.Restore(pluginid, secref)  
                                          
                                    if secref['subid'] == SUBDLG_ID2:  
                                        return self.sub_dialog2.Restore(pluginid, secref)              
                                          
                                    else:  
                                        return super(MainDialog, self).Restore(pluginid, secref)  
                                      
                              ############################  
                              #The Command Data section   
                              class MainDialog_CD(c4d.plugins.CommandData) :  
                                
                                @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__":  
                                
                                bmp = bitmaps.BaseBitmap()  
                                dir, file = os.path.split(__file__)  
                                fn = os.path.join(dir, "res", "icon.png")  
                                bmp.InitWith(fn)  
                                plugins.RegisterCommandPlugin(PLUGIN_ID, "Sub-Dialog Docking",0, bmp, "re-open", MainDialog_CD())
                              

                              -ScottA

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