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!
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
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:
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.
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.
@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.
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)
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)
@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().
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.
PLUGIN1_ID = 1234567
PLUGIN2_ID = 2345678
ACTIVATE_ID = 9999999
BUTTON_ID = 1000
active = False
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")
def Command(self, id, msg):
Editing document's BaseContainer
doc = c4d.documents.GetActiveDocument()
docBC = doc.GetDataInstance()
subBc = c4d.BaseContainer()
self.active = not self.active
subBc[PLUGIN2_ID] = self.active
print doc[PLUGIN1_ID][PLUGIN2_ID] #<--will not update without this
Sending a Message
node = c4d.plugins.FindPlugin(PLUGIN2_ID)
dlg = Plugin1_UI()
return dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2, \
pluginid=PLUGIN1_ID, defaultw=100, defaulth=100)
def Message(self, type, data):
if type == ACTIVATE_ID:
print "Message: %s"%type
#print type, data
def GetState(self, doc):
if not doc[PLUGIN1_ID] or not doc[PLUGIN1_ID][PLUGIN2_ID]:
help="Plugin 1 help text",
help="Plugin 2 help text",
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.
Thanks Manuel (and @zipit ) for your help.
Please let us know about why the Message isn't working.