Solved Disable a Command Plugin

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!

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

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.

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

@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.

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

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

@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().

This post is deleted!

@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.

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

@m_magalhaes

Thanks Manuel (and @zipit ) for your help.

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