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! -
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
andMSG_GETCUSTOMICON
...none of the messages I'm sending with SpecialEventAdd()or GePluginMessage() are registering. -
Hi,
to disable the icons of a
CommandData
orToolData
plugin, you have simply to returnFalse
.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 ofFalse
to disable the icon.Cheers,
zipit -
@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 -
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 -
@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)
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 -
@m_magalhaes
Thanks Manuel (and @zipit ) for your help.
Please let us know about why the Message isn't working.