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

    Disable a Command Plugin

    Cinema 4D SDK
    python
    3
    11
    1.1k
    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

      Hi,
      Is there a way to disable one command plugin from another plugin?

      I see that there's a method called CommandData.GetState() but I'm unsure how or when it is called. I found this post on CGTalk which demonstrates the GetState() override, but it does not explain how/when it gets called. Thank you!

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

        I found an example of GetState() in the py-liquid_painter_r12.pyp demo. How can I change the CommandData instance's attributes? For example, how would I set self.isActive in the data instance?

            def GetState(self, doc):
                if not self.isActive:
                    return False
        
                return c4d.CMD_ENABLED
        

        I tried overriding the plugin's Message method, but I'm only able to trace MSG_COMMANDINFORMATION and MSG_GETCUSTOMICON...none of the messages I'm sending with SpecialEventAdd()or GePluginMessage() are registering.

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

          Hi,

          to disable the icons of a CommandData or ToolData plugin, you have simply to return False.

          The attribute from the liquid painter example is just a custom attribute and has nothing to do with that functionality. You should not have to do anything else. And if I remember correctly, in the method, you could also return c4d.NOTOK or -1 instead of False to disable the icon.

          Cheers,
          zipit

          MAXON SDK Specialist
          developers.maxon.net

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

            @zipit Hi, thank you for the reply. Your answer does not address my question though: I wish to control the disabling of the CommandData plugin from another plugin. Perhaps this isn't the way to go about it, but my idea was to use a property such as isActive in the data instance. How do I access the data instance for the CommandData plugin from another plugin? The code example I shared is a modified version of the liquid painter example demonstrating how I'd implement it on the CommandData side.

            Thank you.

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

              Hi,

              ah sorry, I still need my coffee 😉 You would have to send your message via C4DAtom.Message on the the plugin nodes. So something like this should do the trick.

              node = c4d.plugins.FindPlugin(PLUGIN_ID)
              node.Message(ID_DO_STUFF)
              

              Cheers,
              zipit

              MAXON SDK Specialist
              developers.maxon.net

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

                hi,

                You can also use the document's basecontainer to store a Bool, and check it into GetState if your command/tools can be different from one document to another.
                GetState is called very often, you don't really need to synchronise the actions.

                as @zipit said, you have to return false if the command should be disabled.

                You can do a lot of things to check if it should be enable or disable, it's up to you.
                Sometimes it can be done in the GetState, like check if the selected object is a PolygonObject. Sometimes it's a state somewhere that can be changed by another plugin.

                (i'm not sure if it's clear)

                Cheers,
                Manuel

                MAXON SDK Specialist

                MAXON Registered Developer

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

                  @zipit Thank you. How do I listen for this message from the CommandData's data instance? As mentioned in the initial post, I'm not able to catch any of the messages when overriding Message. I can get them by calling PluginMessage, but I'm interested in getting the messages from the Plugin data instance.

                  @m_magalhaes It is clear, thank you. I sort of have it working checking the Document's BaseContainer in the GetState method.

                  Strangely, it won't work unless I print to the Console. ?? It will deactivate once but not reactivate unless I use the print function. If I add the command to a menu with MenuAddCommand, it will work when I open and close the Menu, but if I add the Command to a Palette, it won't work without print().

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

                    This post is deleted!
                    1 Reply Last reply Reply Quote 0
                    • ?
                      A Former User
                      last edited by

                      @m_magalhaes @zipit

                      I have created code that demonstrates both issues: not receiving the Message and not working without print. Please give it a try; dock both Plugin 1 & 2 in the UI, launch Plugin 1, and click the 'Toggle Plugin 2 Enable' button.

                      import c4d
                      
                      PLUGIN1_ID = 1234567
                      PLUGIN2_ID = 2345678
                      ACTIVATE_ID = 9999999
                      BUTTON_ID = 1000
                      
                      class Plugin1_UI(c4d.gui.GeDialog):
                          active = False
                      
                          def CreateLayout(self):
                              self.SetTitle("Plugin 1")
                              self.GroupBorderSpace(10,10,10,10)
                              self.AddButton(BUTTON_ID, c4d.BFH_CENTER | c4d.BFH_SCALE | c4d.BFV_CENTER | c4d.BFV_SCALE, initw=0, inith=0, name="Toggle Plugin 2 Enable")
                              return True
                      
                          def Command(self, id, msg):
                              if id==BUTTON_ID:
                                  """
                                  Editing document's BaseContainer
                                  """
                                  doc = c4d.documents.GetActiveDocument()
                                  docBC = doc.GetDataInstance()
                                  subBc = c4d.BaseContainer()
                                  self.active = not self.active
                                  subBc[PLUGIN2_ID] = self.active
                                  docBC.SetContainer(PLUGIN1_ID, subBc)
                                  doc.SetData(docBC)
                                  print doc[PLUGIN1_ID][PLUGIN2_ID] #<--will not update without this
                      
                                  """
                                  Sending a Message
                                  """
                                  node = c4d.plugins.FindPlugin(PLUGIN2_ID)
                                  node.Message(ACTIVATE_ID)
                      
                              return True
                      
                      class Plugin1_CommandData(c4d.plugins.CommandData):
                          def Execute(self,doc):
                              global dlg
                              dlg = Plugin1_UI()
                              return dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2, \
                                      pluginid=PLUGIN1_ID, defaultw=100, defaulth=100)
                      
                      class Plugin2_CommandData(c4d.plugins.CommandData):
                          def Message(self, type, data):
                              if type == ACTIVATE_ID:
                                  print "Message: %s"%type
                              #print type, data
                              return True
                      
                          def GetState(self, doc):
                              if not doc[PLUGIN1_ID] or not doc[PLUGIN1_ID][PLUGIN2_ID]:
                                  return False
                      
                              return c4d.CMD_ENABLED
                      
                          def Execute(self,doc):
                              return True
                      
                      c4d.plugins.RegisterCommandPlugin(id=PLUGIN1_ID,
                                                  str="Plugin 1",
                                                  info=0,
                                                  help="Plugin 1 help text",
                                                  dat=Plugin1_CommandData(),
                                                  icon=None)
                      
                      c4d.plugins.RegisterCommandPlugin(id=PLUGIN2_ID,
                                                  str="Plugin 2",
                                                  info=0,
                                                  help="Plugin 2 help text",
                                                  dat=Plugin2_CommandData(),
                                                  icon=None)
                      
                      

                      Annotation 2020-09-02 111616.jpg

                      I'm interested in whichever way I can get to work properly: messaging the plugin or storing the state in the document's BaseContainer. Neither is working for me right now. Thank you both.

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

                        hi,

                        The print trigger a refresh of the UI. Adding a EventAdd() will do the same.

                        About the message not being catched, that could make sense, the FindPlugin returning a BasePlugin. But i need to check if it's not a but 🙂

                        Cheers,
                        Manuel

                        MAXON SDK Specialist

                        MAXON Registered Developer

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

                          @m_magalhaes

                          Thanks Manuel (and @zipit ) for your help.

                          Please let us know about why the Message isn't working.

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