Why ToolData Plugin Not Keeping the Input Data Values to the GUI Widgets SubDialog?
-
User Information:
Cinema 4D Version: R19/R21;
Platform: Windows ;
Language(s) : Python ;Hello Everyone!
This my first time making a tool data plugin. Now the problem is in R21 I drag the object into the link box and it don't stay and when I change the tool data or the settings dont stay , and i did this with other c4d gui widgets , eg: combobox, it just reset to the default value you set in the GeDialog.InitValues(). Now in R19 I drag the object into the link box and it stay but when I change the tool data or the settings dont stay.
You can see the short streamable videos below on what is happen inside C4D and take look at the code also. I hope there a easy fix for this problem and not a bug. lol
Inside R21: Video
Inside R19: VideoCode:
import c4d from c4d import plugins, gui, bitmaps, documents, storage, utils import os import sys PLUGIN_ID = 1054512 def GetDataFromLinkBox(ui_ins, uiLinkID): DATA = ui_ins.FindCustomGui(uiLinkID, c4d.CUSTOMGUI_LINKBOX).GetLink() objDATA = DATA objName = DATA.GetName() objGUID = DATA.GetGUID() return objDATA, objName, objGUID class DemoDialog(gui.SubDialog): UIDATA_PARAMETERS = {} LinkBC = c4d.BaseContainer() IDUI_CUSTOMGRP_LINK1 = 1003 def __init__(self, arg): # Checks if the argument passed is a dictionary if not isinstance(arg, dict): raise TypeError("arg is not a dict.") self.UIDATA_PARAMETERS = arg def CreateLayout(self): ui = self ui.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0, "") ui.AddStaticText(0, c4d.BFH_RIGHT, 0, 12, "Object:", c4d.BORDER_WITH_TITLE_BOLD) ui.AddCustomGui(ui.IDUI_CUSTOMGRP_LINK1, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_MASK, 240, 12, ui.LinkBC) ui.GroupEnd() return True def Command(self, id, msg): if id == self.IDUI_CUSTOMGRP_LINK1: obj, objName, objID = GetDataFromLinkBox(ui_ins=self, uiLinkID=self.IDUI_CUSTOMGRP_LINK1) self.UIDATA_PARAMETERS['grouplink'] = obj self.UIDATA_PARAMETERS['grouplinkGUID'] = objID print("Linked Object:{0} | ID:{1} | GUI-ID:{2}").format( objName, objID, id ) return True class ToolDemo(plugins.ToolData): def __init__(self): self.UI_DATA = { 'grouplink':None, 'grouplinkGUID':None } def GetState(self, doc): if doc.GetMode()==c4d.Mpaint: return 0 return c4d.CMD_ENABLED def InitDefaultSettings(self, doc, data): pass # expects None as return value def InitTool(self, doc, data, bt): return True def KeyboardInput(self, doc, data, bd, win, msg): return True def MouseInput(self, doc, data, bd, win, msg): return True def GetCursorInfo(self, doc, data, bd, x, y, bc): return True def AllocSubDialog(self, bc): return DemoDialog(getattr(self, "UI_DATA", self.UI_DATA)) if __name__ == "__main__": bmp = bitmaps.BaseBitmap() dir, file = os.path.split(__file__) fn = os.path.join(dir, "res", "tool_icon.tif") bmp.InitWith(fn) plugins.RegisterToolPlugin(id=PLUGIN_ID, str="MyPyToolDemo", info=0, icon=bmp, help="Tool", dat=ToolDemo())
And I am just wondering is c4d.plugins.SculptBrushToolData is better system than c4d.plugins.ToolData. Cause it look like description .res.. UI is for the tool plugin is more easy, like Node Data, Object Data Tags etc....
Any help would be very much appreciated.cheers, Ashton
-
hi,
you have to store a link to your gadget and add an
InitValues
function to your dialog like soin the create layout:
self.link = ui.AddCustomGui(ui.IDUI_CUSTOMGRP_LINK1, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_MASK, 240, 12, ui.LinkBC)
and add that function
def InitValues(self): self.link.SetLink(self.UIDATA_PARAMETERS['grouplink']) return True
Cheers,
Manuel -
@m_magalhaes Thank you! and it makes sense. Heres a update of the code and Demo Video. And hope it helps anyone who might need this or was wondering how a simple Tool Data GUI works.
You see I just add the AddComboBox, AddEditText for testing also.
Code in .pyp file:# // Imports for Cinema 4D // import c4d from c4d import plugins, gui, bitmaps, documents, storage, utils import os import sys PLUGIN_ID = 1054512 def GetDataFromLinkBox(ui_ins, uiLinkID): DATA = ui_ins.FindCustomGui(uiLinkID, c4d.CUSTOMGUI_LINKBOX).GetLink() objDATA = DATA objName = DATA.GetName() objGUID = DATA.GetGUID() return objDATA, objName, objGUID def SetDataFromLinkBox(ui_ins, uiLinkID, Data): LinkWidget = ui_ins.FindCustomGui(uiLinkID, c4d.CUSTOMGUI_LINKBOX) LinkWidget.SetLink(Data) return True class DemoDialog(gui.SubDialog): # Main Properties UIDATA_PARAMETERS = {} LinkBC = c4d.BaseContainer() IDUI_CUSTOMGRP_LINK1 = 1003 IDUI_GRG_OBJ_GUID = 1004 MODE_MENU = 1005 MODE_MENU_LIST = { "Mode 1":{'id':1, 'icon':"&i12298&"}, # (12298) # Model Icon Id (Eg:"&i12298&Model") "Mode 2":{'id':2, 'icon':"&i12139&"}, # (12139) # Points Icon Id "Mode 3":{'id':3, 'icon':"&i12187&"} # (12187) # Polygons Icon Id } def __init__(self, arg): # Checks if the argument passed is a dictionary if not isinstance(arg, dict): raise TypeError("arg is not a dict.") self.UIDATA_PARAMETERS = arg def CreateLayout(self): """ Window GUI elements layout that display to the User. """ ui = self ui.GroupBegin(0, c4d.BFH_MASK, 2, 2, "", c4d.BFV_GRIDGROUP_EQUALCOLS) ui.AddStaticText(0, c4d.BFH_RIGHT, 0, 12, "Object:", c4d.BORDER_WITH_TITLE_BOLD) ui.AddCustomGui(ui.IDUI_CUSTOMGRP_LINK1, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_MASK, 240, 12, ui.LinkBC) ui.AddStaticText(0, c4d.BFH_RIGHT, 0, 12, "Object GUID:", c4d.BORDER_WITH_TITLE_BOLD) ui.AddEditText(ui.IDUI_GRG_OBJ_GUID, c4d.BFH_MASK, 240, 12) ui.AddStaticText(0, c4d.BFH_RIGHT, 0, 12, "Modes:", c4d.BORDER_WITH_TITLE_BOLD) ui.AddComboBox(ui.MODE_MENU, c4d.BFH_SCALEFIT, 100, 15, False) for eachMode in sorted(ui.MODE_MENU_LIST): itemMode = ui.MODE_MENU_LIST.get(str(eachMode)) ui.AddChild(ui.MODE_MENU, itemMode['id'], itemMode['icon']+str(eachMode)) ui.GroupEnd() return True def InitValues(self): """ Called when the dialog is initialized by the GUI / GUI's startup values basically. """ SetDataFromLinkBox(ui_ins=self, uiLinkID=self.IDUI_CUSTOMGRP_LINK1, Data=self.UIDATA_PARAMETERS['grouplink']) self.SetString(self.IDUI_GRG_OBJ_GUID, self.UIDATA_PARAMETERS['grouplinkGUID']) self.SetLong(self.MODE_MENU, self.UIDATA_PARAMETERS['modeSelect']) return True def Command(self, id, msg): """ Excuting Commands for UI Widget Elements Functions. """ if id == self.IDUI_CUSTOMGRP_LINK1: obj, objName, objID = GetDataFromLinkBox(ui_ins=self, uiLinkID=self.IDUI_CUSTOMGRP_LINK1) self.UIDATA_PARAMETERS['grouplink'] = obj self.UIDATA_PARAMETERS['grouplinkGUID'] = objID self.SetString(self.IDUI_GRG_OBJ_GUID, str(objID)) print("Linked Object:{0} | ID:{1} | GUI-ID:{2}").format( objName, objID, id ) if id == self.MODE_MENU: for i in self.MODE_MENU_LIST: getModeID = self.MODE_MENU_LIST.get(str(i)) if self.GetLong(self.MODE_MENU) == getModeID["id"]: self.UIDATA_PARAMETERS['modeSelect']=getModeID["id"] return True class PyToolDemo(plugins.ToolData): def __init__(self): self.UI_DATA = { 'grouplink':None, 'grouplinkGUID':None, 'modeSelect':2 } def GetState(self, doc): if doc.GetMode()==c4d.Mpaint: return 0 return c4d.CMD_ENABLED def InitDefaultSettings(self, doc, data): pass def InitTool(self, doc, data, bt): return True def KeyboardInput(self, doc, data, bd, win, msg): return True def MouseInput(self, doc, data, bd, win, msg): return True def GetCursorInfo(self, doc, data, bd, x, y, bc): return True def AllocSubDialog(self, bc): return DemoDialog(getattr(self, "UI_DATA", self.UI_DATA)) if __name__ == "__main__": bmp = bitmaps.BaseBitmap() dir, file = os.path.split(__file__) fn = os.path.join(dir, "res", "tool_icon.tif") bmp.InitWith(fn) plugins.RegisterToolPlugin(id=PLUGIN_ID, str="MyPyToolDemo", info=0, icon=bmp, help="Your Data Staying ToolData UI", dat=PyToolDemo())
-
hi,
thanks a lot for sharing your code
Don't forget to change the state of this thread to solved. (if it is)
cheers,
Manuel