Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
On 17/11/2013 at 18:53, xxxxxxxx wrote:
I seem to remember being told this wasn't possible in Python, but now I'm wanting to double check this.
When doing User Data, if you put something in a new group, that group can be foldable/collapsable.
Is there any way to do this in a GeDialog in Python?
To see what I mean create a cube, look in the Coords tab. The Freeze Transformation can be collapses. I'm looking to be able to do that in my GeDialog plugin.
On 18/11/2013 at 04:05, xxxxxxxx wrote:
Hi Bret,
unfortunately the groupflag which makes the group foldable is broken. It is however possible by using a button/userarea widget and the GeDialog.HideElement() function.
Here's a quick example:
> > import c4d > import weakref > > class FoldUa(c4d.gui.GeUserArea) : > > def __init__(self, dlg, wid, parent_id, state_1=None, state_2=None) : > super(FoldUa, self).__init__() > self.dlg = weakref.ref(dlg) > self.wid = wid > self.parent_id = parent_id > self.hidden = False > > if not state_1: state_1 = c4d.RESOURCEIMAGE_PLUS > if not state_2: state_2 = c4d.RESOURCEIMAGE_SUBGROUP > self.state_1 = state_1 > self.state_2 = state_2 > print self.state_1, self.state_2 > > def Toggle(self, notify=True) : > self.hidden = not self.hidden > self.SetState(self.hidden, notify) > > def SetState(self, hidden, notify=True) : > self.hidden = bool(hidden) > self.dlg().HideElement(self.wid, self.hidden) > if notify: > self.LayoutChanged() > self.dlg().LayoutChanged(self.parent_id) > > def GetStateIcon(self) : > if self.hidden: > icon = self.state_1 > else: > icon = self.state_2 > > if isinstance(icon, int) : > icon = c4d.gui.GetIcon(icon) > elif isinstance(icon, dict) : > pass > elif isinstance(icon, c4d.bitmaps.BaseBitmap) : > w, h = icon.GetSize() > icon = {'x': 0, 'y': 0, 'w': w, 'h': h, 'bmp': icon} > elif not icon: > pass > else: > raise TypeError('Expected int, dict or BaseBitmap for state field.') > > return icon > > def DrawMsg(self, x1, y1, x2, y2, msg) : > self.DrawSetPen(c4d.COLOR_BG) > self.DrawRectangle(x1, y1, x2 - 1, y2 - 1) > > icon = self.GetStateIcon() > if not icon: return > self.DrawBitmap(icon['bmp'], 0, 0, icon['w'], icon['h'], > icon['x'], icon['y'], icon['w'], icon['h'], > c4d.BMP_ALLOWALPHA) > > def InputEvent(self, msg) : > device = msg.GetLong(c4d.BFM_INPUT_DEVICE) > channel = msg.GetLong(c4d.BFM_INPUT_CHANNEL) > if device == c4d.BFM_INPUT_MOUSE and channel == c4d.BFM_INPUT_MOUSELEFT: > self.Toggle() > return True > > def GetMinSize(self) : > icon = self.GetStateIcon() > if icon: > return (icon['w'], icon['h']) > else: > return (0, 0) > > class Dialog(c4d.gui.GeDialog) : > > GRP_FOLDABLE = 1000 > EDT_SOMEFIELD = 1001 > > def __init__(self) : > super(Dialog, self).__init__() > self.__foldindex = 10000 > self.__folduas = {} > > def GroupBeginFoldable(self, id, flags, *args, **kwargs) : > self.GroupBegin(self.__foldindex, flags, 0, 1) > ua = FoldUa(self, id, self.__foldindex) > self.__foldindex += 1 > > self.AddUserArea(self.__foldindex, 0) > self.AttachUserArea(ua, self.__foldindex) > self.__folduas[self.__foldindex] = ua > self.__foldindex += 1 > > return self.GroupBegin(id, flags, *args, **kwargs) > > def GroupEndFoldable(self) : > self.GroupEnd() > self.GroupEnd() > > # c4d.gui.GeDialog > > def CreateLayout(self) : > if self.GroupBeginFoldable(self.GRP_FOLDABLE, c4d.BFH_SCALEFIT, 0, 1) : > self.AddStaticText(0, 0, name="Field") > self.AddEditSlider(self.EDT_SOMEFIELD, c4d.BFH_SCALEFIT) > self.GroupEndFoldable() > > self.AddDlgGroup(c4d.DLG_CANCEL) > return True > > def Command(self, wid, msg) : > if wid == c4d.DLG_CANCEL: > self.Close() > return True > > dlg = Dialog() > dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE)
Best, -Niklas
On 18/11/2013 at 07:30, xxxxxxxx wrote:
Is there a way though to make it so it will display the group name still?
On 18/11/2013 at 11:17, xxxxxxxx wrote:
Requires a bit more hacky approach using a 2-level group call.
import c4d import weakref class FoldUa(c4d.gui.GeUserArea) : minsize = (10, 10) def __init__(self, dlg, wid, parent_id, state_1=None, state_2=None) : super(FoldUa, self).__init__() self.dlg = weakref.ref(dlg) self.wid = wid self.parent_id = parent_id self.hidden = False if not state_1: state_1 = c4d.RESOURCEIMAGE_PLUS if not state_2: state_2 = c4d.RESOURCEIMAGE_SUBGROUP self.state_1 = state_1 self.state_2 = state_2 def Toggle(self, notify=True) : self.hidden = not self.hidden self.SetState(self.hidden, notify) def SetState(self, hidden, notify=True) : self.hidden = bool(hidden) self.dlg().HideElement(self.wid, self.hidden) if notify: self.LayoutChanged() self.dlg().LayoutChanged(self.parent_id) def GetStateIcon(self) : if self.hidden: icon = self.state_1 else: icon = self.state_2 if isinstance(icon, int) : icon = c4d.gui.GetIcon(icon) elif isinstance(icon, dict) : pass elif isinstance(icon, c4d.bitmaps.BaseBitmap) : w, h = icon.GetSize() icon = {'x': 0, 'y': 0, 'w': w, 'h': h, 'bmp': icon} elif not icon: pass else: raise TypeError('Expected int, dict or BaseBitmap for state field.') return icon def DrawMsg(self, x1, y1, x2, y2, msg) : self.DrawSetPen(c4d.COLOR_BGFOCUS) self.DrawRectangle(x1, y1, x2 - 1, y2 - 1) icon = self.GetStateIcon() if not icon: return x = (self.GetWidth() - icon['w']) / 2 y = (self.GetHeight() - icon['h']) / 2 self.DrawBitmap(icon['bmp'], x, x, icon['w'], icon['h'], icon['x'], icon['y'], icon['w'], icon['h'], c4d.BMP_ALLOWALPHA) def InputEvent(self, msg) : device = msg.GetLong(c4d.BFM_INPUT_DEVICE) channel = msg.GetLong(c4d.BFM_INPUT_CHANNEL) if device == c4d.BFM_INPUT_MOUSE and channel == c4d.BFM_INPUT_MOUSELEFT: self.Toggle() return True def GetMinSize(self) : icon = self.GetStateIcon() if icon: return tuple(map(max, zip(self.minsize, (icon['w'], icon['h'])))) else: return tuple(self.minsize) class Dialog(c4d.gui.GeDialog) : GRP_FOLDABLE = 1000 EDT_SOMEFIELD = 1001 def __init__(self) : super(Dialog, self).__init__() self.__foldindex = 10000 self.__folduas = {} def GroupBeginFoldable(self, id, flags, rows=0, cols=0, title="", groupflags=0, initw=0, inith=0) : id_ua = self.__foldindex id_group = self.__foldindex + 1 self.__foldindex += 2 self.GroupBegin(id, flags, 2, 0, title, groupflags, initw, inith) self.__continue_data = (id, flags, rows, cols, title, groupflags, initw, inith, id_ua, id_group) return True def GroupContinueFoldable(self) : if not self.__continue_data: raise RuntimeError('No foldable group opened.') (id, flags, rows, cols, title, groupflags, initw, inith, id_ua, id_group) = self.__continue_data self.__continue_data = None # Column 1: User Area ua = FoldUa(self, wid=id_group, parent_id=id) self.__folduas[id_ua] = ua self.AddUserArea(id_ua, 0) self.AttachUserArea(ua, id_ua) # Column 2: The inner group. self.GroupBegin(id_group, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, rows, cols, title, groupflags, initw, inith) return True def GroupEndFoldable(self) : self.GroupEnd() self.GroupEnd() # c4d.gui.GeDialog def CreateLayout(self) : if self.GroupBeginFoldable(self.GRP_FOLDABLE, c4d.BFH_SCALEFIT, 0, 1, title="Foldable Group") : self.GroupBorder(c4d.BORDER_GROUP_TOP | c4d.BORDER_WITH_TITLE) self.GroupContinueFoldable() self.AddStaticText(0, 0, name="Field") self.AddEditSlider(self.EDT_SOMEFIELD, c4d.BFH_SCALEFIT) self.GroupEndFoldable() self.AddDlgGroup(c4d.DLG_CANCEL) return True def Command(self, wid, msg) : if wid == c4d.DLG_CANCEL: self.Close() return True dlg = Dialog() dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE)
On 19/11/2013 at 02:20, xxxxxxxx wrote:
I think one thing worth mentioning in that context is also, that GeDialog.LoadDialogRessource does not overwrite the dialogs ressources, but appends the IDs content to the dialog.