[Py4D] SubDialogs in ToolData plugins
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 30/01/2012 at 08:24, xxxxxxxx wrote:
User Information:
Cinema 4D Version:
Platform:
Language(s) :---------
When using a SubDialog to display a settings-dialog for a ToolData plugin, make sure to save the options somewhere while the user is changin them. As soon as the user selects another object/tag or alike, the options-dialog will disappear. This will cause any call's to GetReal, GetLong, etc. to freeze Cinema 4D. Actually, I had a long time to figure this out as it isn't any remark about this in the documentation.Here is an example that easen's the use of a SubDialog:
import c4d import copy class PreparedSubDialog(c4d.gui.SubDialog) : BASEDATA = dict() data = None def __init__(self, data = None) : if not data: self.data = copy.deepcopy(self.BASEDATA) elif isinstance(data, PreparedSubDialog) : self.data = data.data else: self.data = data def __getattr__(self, name) : item = self.data.get(name, None) if not item: raise AttributeError('No such dialog-element %r.' %name) id, type, value, min, max = item return value # ---- overwritten from ``c4d.gui.GeDialog`` ------------------------------- def InitValues(self) : for name, (id, type, default, min, max) in self.data.iteritems() : if type == 'str': self.SetString(id, default) elif type == 'm': self.SetMeter(id, default, min, max) elif type == 'p': self.SetPercent(id, default, min, max) elif type == 'b': self.SetBool(id, default) elif type == 'l': self.SetLong(id, default, min, max) elif type == 'r': self.SetReal(id, default, min, max) elif type == 'd': self.SetDegree(id, default, min, max) elif type == 't': self.SetTime(id, default, min, max) elif type == 'f': self.SetFilename(id, default) else: raise ValueError('Unknown element-type %r.' % type) return True def Command(self, id, msg) : # save the values for name, v in self.data.iteritems() : if v[0] == id: v[2] = self.__getattr__(name) break return True
A possible subclass could look like this:
class MySubDialog(PreparedSubDialog) : ID_MYREAL = 1001 ID_MYSTRING = 1002 ID_MYMETER = 1003 ID_MYBOOL = 1004 BASEDATA = dict( myreal = [ID_MYREAL, 'r', 0, 0, 1000], mystring = [ID_MYSTRING, 's', 'String here', None, None], mymeter = [ID_MYMETER, 'm', 100, -500, 500], mybool = [ID_MYBOOL, 'b', True, None, None] ) def CreateLayout(self) : self.AddStaticString(self.ID_MYSTRING, c4d.BFH_FIT) self.AddEditNumberArrows(self.ID_MYREAL, c4d.BFH_FIT) self.AddEditNumberArrows(self.ID_MYMETER, c4d.BFH_FIT) self.AddCheckbox(self.ID_MYBOOL, c4d.BFH_FIT)
And used like this:
class MyToolPlugin(c4d.plugins.ToolData) : dlg = None def MouseInput(self, doc, data, bd, win, msg) : myreal = self.dlg.myreal mystring = self.dlg.mystring mymeter = self.dlg.mymeter mybool = self.dlg.mybool # ... def AllocSubDialog(self, bc) : self.dlg = MySubDialog(self.dlg) return self.dlg
Any problems understanding the code? Ask.
Greetz, Niklas