Dynamically adding parameters in tag plugin - description is not refreshing
-
Hi, in my object plugin it worked fine but in my tag plugin the description cannot be updated after clicking a button which in this example should add a new button.
so when I click the button it adds a new id to the member variable self.id_list, and then I iter through this list in my GetDDescription() method
It just shows the added Button if I click on the Object which holds the tag and select again the tag.
Do I have to send a message? I read the GitHubExample but it is a example with an ObjectPlugin.import c4d from c4d import bitmaps, gui, plugins # Just a test ID PLUGIN_ID = 1110101 PY_ADD_TRACK = 10000 #The Plugin Class class Audioworkstation(plugins.TagData): def __init__(self): self.id_list = [] def Init(self, node): return True def GetDDescription(self, op, description, flags): if not description.LoadDescription(op.GetType()): return False singleID = description.GetSingleDescID() # id_counter = 1 for desc_id in reversed(self.id_list): measure_object_hide = c4d.DescID(c4d.DescLevel(desc_id + 2, c4d.DTYPE_BUTTON, op.GetType())) if not singleID or measure_object_hide.IsPartOf(singleID)[0]: bc_measure_object_hide = c4d.GetCustomDataTypeDefault(c4d.DTYPE_BUTTON) bc_measure_object_hide[c4d.DESC_NAME] = "DELETE" bc_measure_object_hide[c4d.DESC_CUSTOMGUI] = c4d.CUSTOMGUI_BUTTON # id_counter += 1 if not description.SetParameter(measure_object_hide, bc_measure_object_hide, c4d.DescID(c4d.DescLevel( c4d.ID_TAGPROPERTIES))): return False return True, flags | c4d.DESCFLAGS_DESC_LOADED def Execute(self, tag, doc, op, bt, priority, flags): return c4d.EXECUTIONRESULT_OK def Message(self, node, type, data): if type == c4d.MSG_DESCRIPTION_COMMAND: if data["id"][0].id == PY_ADD_TRACK: last_id = None if self.id_list: last_id = self.id_list[-1] new_id = last_id + 100 self.id_list.append(new_id) else: new_id = 10100 self.id_list.append(new_id) node.Message(c4d.MSG_CHANGE) return True # main if __name__ == "__main__": bmp = bitmaps.BaseBitmap() dir, file = os.path.split(__file__) fn = os.path.join(dir, "res", "icon.tif") bmp.InitWith(fn) c4d.plugins.RegisterTagPlugin(id=PLUGIN_ID, str="C4D-Audioworkstation", info=c4d.TAG_EXPRESSION | c4d.TAG_VISIBLE, description="audioworkstation", g=Audioworkstation, icon=bmp)
edit by @ferdinand:
@ThomasB said:
I have also problems to scale the button so that it fits the attribute manager:
so this doesn't work in the GetDDescription Example above:
bc_measure_object_hide[c4d.DESC_SCALEH] = True bc_measure_object_hide[c4d.DESC_FITH] = True
-
Hello @ThomasB,
Thank you for reaching to us. While you provided your code and a clear and brief problem description - thank you for that - your example was lacking the resources. Please provide your resources (the
res
folder) or ideally a full plugin in future cases, especially when like here the description/resource is the subject of the posting.Please also follow our rules of "consolidate your postings" and "one subject per topic". I have consolidated the posting here for you but must ask you to open another topic for your second question. For details please refer to our Support Procedures.
Find my full code at the end of the posting.
About your Issue
TLDR: You must flag yourself dirty.
Your code does everything correctly apart from some smaller issues and it took myself quite some time to figure out what is going wrong here. Due to that I rewrote your code to rule out that I overlooked something in your code and to streamline things. I ended up with this for the core methods:
def __init__(self): """ """ self.buttonIds: list[int] = [2000] def GetDDescription(self, op, description, flags): """ """ if not description.LoadDescription(Audioworkstation.PLUGIN_ID): return False target: c4d.DescID | None = description.GetSingleDescID() buttonIds: list[c4d.DescID] = [ c4d.DescID(c4d.DescLevel(did, c4d.DTYPE_BUTTON, Audioworkstation.PLUGIN_ID)) for did in self.buttonIds ] for eid in buttonIds: # The eid isPartOf target is an echo of what you did in your code which does not make too # much sense. I copied it here as it also does not hurt. if target and not eid.IsPartOf(target)[0]: continue buttonDesc: c4d.BaseContainer = c4d.GetCustomDataTypeDefault(c4d.DTYPE_BUTTON) buttonDesc[c4d.DESC_NAME] = str(eid) buttonDesc[c4d.DESC_CUSTOMGUI] = c4d.CUSTOMGUI_BUTTON if not description.SetParameter(eid, buttonDesc, c4d.DescID(c4d.ID_TAGPROPERTIES)): return False return True, flags | c4d.DESCFLAGS_DESC_LOADED def Message(self, node, mtype, mdata): """ """ if (mtype == c4d.MSG_DESCRIPTION_COMMAND and isinstance(mdata, dict)): descId: c4d.DescID = mxutils.CheckType(mdata.get("id", None)) if descId.GetDepth() < 1 or descId[0].id != Audioworkstation.ID_AUDIOWORKSTATION_ADD: return True self.buttonIds.append(self.buttonIds[-1] + 100) return True return True
I first could not wrap my head around why this is not working, as we have examples like
dynamic_parameters_object_r18.py
and this is still working fine. But then I realized that all these examples use elements like sliders or integer fields to add or remove elements, not buttons. And these elements are handled differently when it comes to user interaction. And sure enough, when I added aLONG
field to the description and its handling to the code, it works. I treat theLONG
fieldID_AUDIOWORKSTATION_ITEMS
like a button, i.e., I ignore if its goes up or down, or what its values is. The purpose is here to switch fromMSG_DESCRIPTION_COMMAND
toMSG_DESCRIPTION_POSTSETPARAMETER
. -
@ferdinand
Thanks a lot Ferdinand for your time and effort. It is always admirable how carefully and thoroughly you answer many questions.
At first it was often difficult to understand and follow your code examples...now it is a little easier.
Thanks for that.I found out that the following method also does the job:
c4d.SendCoreMessage(c4d.COREMSG_CINEMA, c4d.BaseContainer(c4d.COREMSG_CINEMA_FORCE_AM_UPDATE), 0)
Sorry for the second question about why this
buttonDesc[c4d.DESC_FITH] = True buttonDesc[c4d.DESC_SCALEH] = True
in the GetDDescription method are not working. I thought this is a follow-up question.
I will open another topic for that.