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

    Forcing One instance of Script Dialog

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 576 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

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 03/08/2012 at 09:22, xxxxxxxx wrote:

      When the users creates a script that opens a dialog window and docks it into the layout. It can spawn multiple copies of itself when the users executes that script from the UI. Ouch!

      Is there something in the SDK that will check to see if the dialog the script creates is open. And not create multiple copies of it?
      I see window open functions for plugins. But I don't see anything that deals with dialogs created with scripts.

      I have created my own work around for this. Which works ok. But not 100% safe.
      I would rather use a built in SDK method that is bullet proof instead of using my hack.

      -ScottA

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

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 03/08/2012 at 09:57, xxxxxxxx wrote:

        Simple: Async Dialogs should not be opened from the Script Manager. ^^

        _nik

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

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 03/08/2012 at 10:44, xxxxxxxx wrote:

          Party Pooper. Tongue
          Seriously though.
          If there's a supported way to do this with the SDK I'd like to know.

          Otherwise.....I will be forced share my workaround hack.
          And assert my position as supreme ruler. 😈
          Don't make me do it Maxon. I'll do it........ I'll do it. 🙂

          -ScottA

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

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 04/08/2012 at 02:16, xxxxxxxx wrote:

            Pff.. 😛
            Ye seriously, there is no "official" way to solve this. In a CommandData plugin for example, C4D keeps an instance of your plugin aside that you use to recognize whether the dialog is already created or not.

            You could save your dialog instance in a module, but that really is not a good way to handle it. I just post it here for completeness, but really: Don't use this!

            import c4d   
            # ...   
            dlg = getattr(c4d, 'my_dialog', None)   
            if not dlg:   
                dlg = Dialog()   
                setattr(c4d, 'my_dialog', None)   
            dlg.Open()
            

            What workaround were you talking about? 🙂

            -Nik

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

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 04/08/2012 at 08:34, xxxxxxxx wrote:

              The work around I came up with works on a different principle.
              Since we can't create a container in a script dialog and use it's data to test if the dialog is open or closed. What I needed was something that was already globally available that the script could use as a sort of "state switch".

              There's a ton of settable color attributes available for the UI. And I found something really obscure in there called IRR color. Which changes the border color of the IRR.
              I thought... Who in the heck would want to change that thing?
              So I use it for something more useful...Like a switch that tells my dialog plugin when it can and can't launch. Forcing only one copy of the dialog to be open at a time.

              #This is a trick to force only one script manager dialog instance to open  
              #The script toggles the IRR window color and uses it like a switch to tell the script whether it is allowed to launch or not  
              #The close button and/or the "X" in the menu sets the IRR color back to it's original white color when the dialog is closed  
                
              import c4d  
              from c4d import gui  
                
              class YourDialog(gui.GeDialog) :  
                
                BUTTON_ID = 1001   
                color = c4d.GetViewColor(c4d.VIEWCOLOR_IRR)   
                
                def CreateLayout(self) :   
                    c4d.SetViewColor(c4d.VIEWCOLOR_IRR,c4d.Vector(0,0,0))    #Change the IRR color to black      
                    c4d.EventAdd()  
                      
                    self.AddButton(self.BUTTON_ID, c4d.BFH_SCALE|c4d.BFV_SCALE, 100, 25, "Close Dialog")  
                    return True  
                
                def Command(self, id, msg) :  
                    if id==self.BUTTON_ID:   
                        c4d.SetViewColor(c4d.VIEWCOLOR_IRR,self.color)    #Set the color back to the original white value  
                        c4d.EventAdd()  
                        self.Close()  
                    return True  
                      
                
                      
                def DestroyWindow(self) :  #Use this method to toggle the IRR back to it's original white color   
                    c4d.SetViewColor(c4d.VIEWCOLOR_IRR,self.color)    #Set the color back to the original value  
                    c4d.EventAdd()      
                      
                 
                
              if __name__=='__main__':  
                dlg = YourDialog()   
                bgcolor = dlg.color  
                
                #If the IRR color is white(default) then go ahead and open this dialog window  
                if bgcolor.x == 1: dlg.Open(dlgtype= c4d.DLG_TYPE_ASYNC, xpos=600, ypos=500, defaultw=200, defaulth=200)
              

              It works great!
              But the down side is that the user could still change the IRR color(why anyone would do that I have no idea..But users often do crazy things) and cause problems.
              And I think I would also need to use another UI attribute If I wanted to apply it to two keep two dialogs.

              It would be handy if we had a bunch of empty global booleans in our preferences so we could use them for special cases like this.
              But then we'd all be doing things that we aren't supposed to do. 😂

              -ScottA

              *Edit- I also use a variation of this same code using a null and a user data boolean entry to force only one instance of a dialog to be open. Which is more safe. But requires more initial set up.

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

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 04/08/2012 at 09:29, xxxxxxxx wrote:

                What the heck.
                I guess I should just post that code version too:

                #This is a trick to force only one script manager dialog instance to open  
                #The script toggles a User Data boolean and uses it like a switch to tell the script whether it is allowed to launch or not  
                #The close button and/or the "X" in the menu sets the switch back to it's original off state when the dialog is closed  
                  
                import c4d  
                from c4d import gui  
                  
                class YourDialog(gui.GeDialog) :  
                  
                  BUTTON_ID = 1001   
                  
                  def CreateLayout(self) :   
                      obj[c4d.ID_USERDATA, 1]=1    #Toggle the UserData boolean to enabled  
                      c4d.EventAdd()  
                        
                      self.AddButton(self.BUTTON_ID, c4d.BFH_SCALE|c4d.BFV_SCALE, 100, 25, "Close Dialog")  
                      return True  
                  
                  def Command(self, id, msg) :  
                      if id==self.BUTTON_ID:   
                          c4d.EventAdd()  
                          self.Close()  
                      return True  
                  
                  def DestroyWindow(self) :        #Use this method to toggle the switch back to it's original off state  
                      obj[c4d.ID_USERDATA, 1]=0  
                      c4d.EventAdd()   
                  
                if __name__=='__main__':  
                  dlg = YourDialog()  
                  obj = doc.SearchObject("Null")  #The object holding a boolean that tells the dialog whether it can be opened  
                  
                  #If the switch is off (default) then go ahead and open this dialog window   
                  if obj[c4d.ID_USERDATA, 1]==0: dlg.Open(dlgtype= c4d.DLG_TYPE_ASYNC, xpos=600, ypos=500, defaultw=200, defaulth=200)
                

                Works good.
                But you need to set up your own object and UserData instead of using the built in preferences attributes like my first example.

                -ScottA

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