@i_mazlov Thanks for your help, it works well.

Posts made by chuanzhen
-
RE: Change Icon Color parameter
-
RE: Change Icon Color parameter
@JH23 Thanks for your help,this is indeed a solution.
For existing objects in Object Manager, using this code is effective, but creating a new object and setting it up yields a different result, which is confusing.@chuanzhen said in Change Icon Color parameter:
import c4d doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: for i in range(2): obj = c4d.BaseObject(c4d.Ojoint) obj[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = 2 obj[c4d.ID_BASEOBJECT_USECOLOR] = 2 obj[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector() obj.SetName(str(i)) doc.InsertObject(obj) c4d.EventAdd() if __name__ == '__main__': main()
-
Change Icon Color parameter
hi,
I use script to create bone and insert it to document, set it Icon Color=Display Color,Why does the Icon Color parameter of the object turn to Custom when I click on it.import c4d doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: for i in range(2): obj = c4d.BaseObject(c4d.Ojoint) obj[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = 2 obj[c4d.ID_BASEOBJECT_USECOLOR] = 2 obj[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector() obj.SetName(str(i)) doc.InsertObject(obj) c4d.EventAdd() if __name__ == '__main__': main()
Thanks for any help!
-
RE: How to convert the length of a line on the screen to the length of an object.
@ferdinand Thanks for your help.
For the unwanted effect of perspective distortion, I tried projecting a fixed size line onto an object to determine the length of the projected line in the world, and then proceeded to draw it.
code:
import c4d doc: c4d.documents.BaseDocument # The document containing this field object. op: c4d.BaseTag # The Python tag containing this code. flags: int # The execution flags of `main()`. See c4d.EXECUTIONFLAGS for details. priority: int # The execution priority of this tag. See c4d.EXECUTIONPRIORITY for details. tp: c4d.modules.thinkingparticles.TP_MasterSystem # The TP system of the document. def GetLineAndPlaneIntersection(plane_pos, plane_normal, line_start, line_dir): zero_find = line_dir.Dot(plane_normal) if zero_find == 0: return False, None else: d = (plane_pos - line_start).Dot(plane_normal) / zero_find return True, line_start + d * line_dir def main() -> None: pass def draw(bd: c4d.BaseDraw) -> bool: if op[c4d.EXPRESSION_ENABLE]: c_mg = bd.GetMg() c_mi = bd.GetMi() plane_normal = c_mg.v3 plane_100_point = c_mg * c4d.Vector(0,0,100) plane_obj_point = op.GetMain().GetMg().off intersect,intersect_100_plane_point = GetLineAndPlaneIntersection(plane_100_point, plane_normal, plane_obj_point, c_mg.off - plane_obj_point) line_end = intersect_100_plane_point + (c_mg * c4d.Vector(5,0,0) - c_mg.off) # fixed size intersect,intersect_obj_plane_point = GetLineAndPlaneIntersection(plane_obj_point, plane_normal, c_mg.off, line_end - c_mg.off) length = (intersect_obj_plane_point - plane_obj_point).GetLength() mg = op.GetMain().GetMg() pos = bd.WS(plane_obj_point) bd.SetMatrix_Screen() bd.SetPen(c4d.GetViewColor(c4d.VIEWCOLOR_XAXIS)) x = bd.WS(mg * c4d.Vector(length,0,0)) bd.DrawLine2D(pos,x) bd.SetPen(c4d.GetViewColor(c4d.VIEWCOLOR_YAXIS)) y = bd.WS(mg * c4d.Vector(0,length,0)) bd.DrawLine2D(pos,y) bd.SetPen(c4d.GetViewColor(c4d.VIEWCOLOR_ZAXIS)) z = bd.WS(mg * c4d.Vector(0,0,length)) bd.DrawLine2D(pos,z) return True
-
How to convert the length of a line on the screen to the length of an object.
hi,
I tried to have an object display its coordinate axis at a fixed screen space length, but it didn't work properly. Where did I make a mistake with my code?This is a c4d file that displays its coordinate axis using tags.-->
video:
code:
import c4d doc: c4d.documents.BaseDocument # The document containing this field object. op: c4d.BaseTag # The Python tag containing this code. flags: int # The execution flags of `main()`. See c4d.EXECUTIONFLAGS for details. priority: int # The execution priority of this tag. See c4d.EXECUTIONPRIORITY for details. tp: c4d.modules.thinkingparticles.TP_MasterSystem # The TP system of the document. def main() -> None: """Called by Cinema 4D to execute the tag. """ # Get the object the tag is attached to and its global position. pass def draw(bd: c4d.BaseDraw) -> bool: # Called to display some visual element in the viewport. Similar to TagData.Draw. # Write your code here if op[c4d.EXPRESSION_ENABLE]: size = 40 # 40 pixel length line bd.SetMatrix_Screen() start = c4d.Vector(200) end = start + c4d.Vector(size,0,0) bd.SetPen(c4d.Vector(1.0)) bd.DrawLine2D(start, end) mg = op.GetMain().GetMg() pos = bd.WS(mg.off) length = size/bd.WP_W(pos,True) bd.SetPen(c4d.Vector(1.0,0,0)) x = bd.WS(mg * c4d.Vector(length,0,0)) bd.DrawLine2D(pos,x) bd.SetPen(c4d.Vector(0,1.0,0)) y = bd.WS(mg * c4d.Vector(0,length,0)) bd.DrawLine2D(pos,y) bd.SetPen(c4d.Vector(0,0,1.0)) z = bd.WS(mg * c4d.Vector(0,0,length)) bd.DrawLine2D(pos,z) return True
Thanks for any help!
-
RE: Show or Hide Object in Viewport
@gheyret Thanks for your help!
i use "c4d.CallCommand(12147) # Redraw" to replace c4d.EventAdd() or c4d.Redraw(), it also work!change code:
if id == 1001: for obj in doc.GetObjects(): obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_CLEAR) c4d.CallCommand(12147) # Redraw return True
-
Show or Hide Object in Viewport
Hi,
I encountered some issues when importing documents and performing hide and display object.this is an example c4d file to import --> import.c4d
this is an example script code:
import c4d class MyDialog (c4d.gui.GeDialog): def CreateLayout(self) -> bool: self.GroupBorderSpace(5, 5, 5, 5) self.GroupSpace(5, 5) self.AddButton(1000, c4d.BFH_SCALEFIT, name = "import") self.AddButton(1001, c4d.BFH_SCALEFIT, name = "show") self.AddButton(1002, c4d.BFH_SCALEFIT, name = "hide") return True def Command(self, id, msg): if id == 1000: file_path = c4d.storage.LoadDialog() c4d.documents.MergeDocument(doc,file_path,c4d.SCENEFILTER_OBJECTS|c4d.SCENEFILTER_MATERIALS) for obj in doc.GetObjects(): obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_SET) c4d.EventAdd() return True if id == 1001: for obj in doc.GetObjects(): obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_CLEAR) c4d.EventAdd() c4d.DrawViews(c4d.DRAWFLAGS_FORCEFULLREDRAW) return True if id == 1002: for obj in doc.GetObjects(): obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_SET) c4d.EventAdd() return True return True if __name__ == "__main__": dlg = MyDialog() dlg.Open(c4d.DLG_TYPE_ASYNC, 0, -1, -1, 200, 200)
ui:
Step 1: Use "import" to merge a document into the current document, and then hide the imported object
Step 2: Use "show" to restore the display of the object, but it will not refresh the display. Only by using the "Redraw" command can the display be refreshed
Why c4d.EventAdd() and c4d.DrawView() doesn't work, did I miss something?
It seems to only occur in the document imported for the first time, and when the "show" or "hide" command is used again, it works normally.
Thanks for any help! -
How to drag rows in Treeview
Hi,
I have read many posts about the dragging behavior of treeview, all of which are examples of dragging from the outside into treeview. What I want is to drag the rows of treeview to rearrange them, just like an object manager dragging objects.
This post also mentioned some explanations about the drag and drop process, but I am still confused about how to start.I found an example of code in this post. Can we implement the drag behavior of treeview rows on this basis
import c4d import weakref # Be sure to use a unique ID obtained from [URL-REMOVED] PLUGIN_ID = 1000010 # TEST ID ONLY # TreeView Column IDs. ID_CHECKBOX = 1 ID_NAME = 2 ID_OTHER = 3 def TextureObjectIterator(lst): for parentTex in lst: yield parentTex for childTex in TextureObjectIterator(parentTex.GetChildren()): yield childTex class TextureObject(object): """ Class which represent a texture, aka an Item in our list """ texturePath = "TexPath" otherData = "OtherData" _selected = False _open = True def __init__(self, texturePath): self.texturePath = texturePath self.otherData += texturePath self.children = [] self._parent = None @property def IsSelected(self): return self._selected def Select(self): self._selected = True def Deselect(self): self._selected = False @property def IsOpened(self): return self._open def Open(self): self._open = True def Close(self): self._open = False def AddChild(self, obj): obj._parent = weakref.ref(self) self.children.append(obj) def GetChildren(self): return self.children def GetParent(self): if self._parent: return self._parent() return None def __repr__(self): return str(self) def __str__(self): return self.texturePath class ListView(c4d.gui.TreeViewFunctions): def __init__(self): self.listOfTexture = list() # Store all objects we need to display in this list # Add some defaults values t1 = TextureObject("T1") t2 = TextureObject("T2") t3 = TextureObject("T3") t4 = TextureObject("T4") self.listOfTexture.extend([t1, t2, t3, t4]) def IsResizeColAllowed(self, root, userdata, lColID): return True def IsTristate(self, root, userdata): return False def GetColumnWidth(self, root, userdata, obj, col, area): return 80 # All have the same initial width def IsMoveColAllowed(self, root, userdata, lColID): # The user is allowed to move all columns. # TREEVIEW_MOVE_COLUMN must be set in the container of AddCustomGui. return True def GetFirst(self, root, userdata): """ Return the first element in the hierarchy, or None if there is no element. """ rValue = None if not self.listOfTexture else self.listOfTexture[0] return rValue def GetDown(self, root, userdata, obj): """ Return a child of a node, since we only want a list, we return None everytime """ children = obj.GetChildren() if children: return children[0] return None def GetNext(self, root, userdata, obj): """ Returns the next Object to display after arg:'obj' """ rValue = None # If does have a child it means it's a child. objParent = obj.GetParent() listToSearch = objParent.GetChildren() if objParent is not None else self.listOfTexture currentObjIndex = listToSearch.index(obj) nextIndex = currentObjIndex + 1 if nextIndex < len(listToSearch): rValue = listToSearch[nextIndex] return rValue def GetPred(self, root, userdata, obj): """ Returns the previous Object to display before arg:'obj' """ rValue = None # If does have a child it means it's a child. objParent = obj.GetParent() listToSearch = objParent.GetChildren() if objParent is not None else self.listOfTexture currentObjIndex = listToSearch.index(obj) predIndex = currentObjIndex - 1 if 0 <= predIndex < len(listToSearch): rValue = listToSearch[predIndex] return rValue def GetId(self, root, userdata, obj): """ Return a unique ID for the element in the TreeView. """ return hash(obj) def Select(self, root, userdata, obj, mode): """ Called when the user selects an element. """ if mode == c4d.SELECTION_NEW: for tex in self.listOfTexture: tex.Deselect() obj.Select() elif mode == c4d.SELECTION_ADD: obj.Select() elif mode == c4d.SELECTION_SUB: obj.Deselect() def IsSelected(self, root, userdata, obj): """ Returns: True if *obj* is selected, False if not. """ return obj.IsSelected def SetCheck(self, root, userdata, obj, column, checked, msg): """ Called when the user clicks on a checkbox for an object in a `c4d.LV_CHECKBOX` column. """ if checked: obj.Select() else: obj.Deselect() def IsChecked(self, root, userdata, obj, column): """ Returns: (int): Status of the checkbox in the specified *column* for *obj*. """ if obj.IsSelected: return c4d.LV_CHECKBOX_CHECKED | c4d.LV_CHECKBOX_ENABLED else: return c4d.LV_CHECKBOX_ENABLED def IsOpened(self, root, userdata, obj): """ Returns: (bool): Status If it's opened = True (folded) or closed = False. """ # If there is some children return obj.IsOpened def Open(self, root, userdata, obj, onoff): """ Called when the user clicks on a folding state of an object to display/hide its children """ if onoff: obj.Open() else: obj.Close() def GetName(self, root, userdata, obj): """ Returns the name to display for arg:'obj', only called for column of type LV_TREE """ return str(obj) # Or obj.texturePath def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor): """ Draw into a Cell, only called for column of type LV_USER """ if col == ID_OTHER: name = obj.otherData geUserArea = drawinfo["frame"] w = geUserArea.DrawGetTextWidth(name) h = geUserArea.DrawGetFontHeight() xpos = drawinfo["xpos"] ypos = drawinfo["ypos"] + drawinfo["height"] drawinfo["frame"].DrawText(name, xpos, int(ypos - h * 1.1)) def DoubleClick(self, root, userdata, obj, col, mouseinfo): """ Called when the user double-clicks on an entry in the TreeView. Returns: (bool): True if the double-click was handled, False if the default action should kick in. The default action will invoke the rename procedure for the object, causing `SetName()` to be called. """ c4d.gui.MessageDialog("You clicked on " + str(obj)) return True def DeletePressed(self, root, userdata): "Called when a delete event is received." for tex in reversed(list(TextureObjectIterator(self.listOfTexture))): if tex.IsSelected: listToRemove = objParent.GetChildren() if objParent is not None else self.listOfTexture listToRemove.remove(tex) def DragStart(self, root: object, userdata: object, obj: object) -> int: print("drag") c4d.gui.SetMousePointer(c4d.MOUSE_INSERTMOVE) return c4d.TREEVIEW_DRAGSTART_ALLOW | c4d.TREEVIEW_DRAGSTART_SELECT def SetDragObject(self, root: object, userdata: object, obj: object) -> None: pass class TestDialog(c4d.gui.GeDialog): _treegui = None # Our CustomGui TreeView _listView = ListView() # Our Instance of c4d.gui.TreeViewFunctions def CreateLayout(self): # Create the TreeView GUI. customgui = c4d.BaseContainer() customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN) customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True) # True if the tree view may have a header line. customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, False) # True if no lines should be drawn. customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, True) # True if the user can move the columns. customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) # True if the column width can be changed by the user. customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) # True if all lines have the same height. customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) # Alternate background per line. customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True) # True if cursor keys should be processed. customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, False) # Suppresses the rename popup when the user presses enter. customgui.SetBool(c4d.TREEVIEW_NO_MULTISELECT, True) self._treegui = self.AddCustomGui(1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 300, 300, customgui) if not self._treegui: print("[ERROR]: Could not create TreeView") return False self.AddButton(1001, c4d.BFH_CENTER, name="Add") self.AddButton(1002, c4d.BFH_CENTER, name="Add Child to selected") return True def InitValues(self): # Initialize the column layout for the TreeView. layout = c4d.BaseContainer() layout.SetLong(ID_CHECKBOX, c4d.LV_CHECKBOX) layout.SetLong(ID_NAME, c4d.LV_TREE) layout.SetLong(ID_OTHER, c4d.LV_USER) self._treegui.SetLayout(3, layout) # Set the header titles. self._treegui.SetHeaderText(ID_CHECKBOX, "Check") self._treegui.SetHeaderText(ID_NAME, "Name") self._treegui.SetHeaderText(ID_OTHER, "Other") self._treegui.Refresh() # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW self._treegui.SetRoot(self._treegui, self._listView, None) return True def Command(self, id, msg): # Click on button if id == 1001: # Add data to our DataStructure (ListView) newID = len(self._listView.listOfTexture) + 1 tex = TextureObject("T{}".format(newID)) self._listView.listOfTexture.append(tex) # Refresh the TreeView self._treegui.Refresh() elif id == 1002: for parentTex in TextureObjectIterator(self._listView.listOfTexture): if not parentTex.IsSelected: continue newID = len(parentTex.GetChildren()) + 1 tex = TextureObject("T{0}.{1}".format(str(parentTex), newID)) parentTex.AddChild(tex) # Refresh the TreeView self._treegui.Refresh() return True def main(): global dialog dialog = TestDialog() dialog.Open(c4d.DLG_TYPE_ASYNC, defaulth=600, defaultw=600) if __name__ == "__main__": main()
Thanks for your help
-
RE: Switching of Multi Object Working Axis for Move Tools
@ferdinand Thanks for reply. Perhaps not expressed clearly. For changing the axis of an object, it is not a problem. What I want to ask is whether the manual operation step of selecting the axis before the Move tool works can be implemented using a script.
-
Switching of Multi Object Working Axis for Move Tools
Hi,
For Move tools(or rotation tool or scale toll), when multiple objects are selected, the axis of the tool can be switched by clicking on it. Can this be achieved through a Python script to switch to the axis of a certain object instead of manually selecting itThanks for any help!
-
RE: TreeView rows selected?
@m_adam Thanks,it works well
this is code:
import c4d import random from c4d import gui # Welcome to the world of Python NAME = 0 LINKTO = 1 LINK = 2 TYPE = 3 class TreeView_Item(object): def __init__(self,): self.type = 'psr' self.selected = False self.obj_name = str(random.randint(1,100)) self.linkto_name = "" @property def IsSelected(self): return self.selected def Select(self): self.selected = True def Deselect(self): self.selected = False def __repr__(self): return str(self) def __str__(self): return self.obj_name class TreeView(c4d.gui.TreeViewFunctions): def __init__(self,items_list=None): self.items_list = items_list if items_list else [] def GetLineHeight(self,root, userdata, obj, col, area): return area.DrawGetFontHeight() def IsResizeColAllowed(self, root, userdata, lColID): return True def IsTristate(self, root, userdata): return False def GetColumnWidth(self, root, userdata, obj, col, area): """Measures the width of cells. Although this function is called #GetColumnWidth and has a #col, it is not only executed by column but by cell. So, when there is a column with items requiring the width 5, 10, and 15, then there is no need for evaluating all items. Each item can return its ideal width and Cinema 4D will then pick the largest value. Args: root (any): The root node of the tree view. userdata (any): The user data of the tree view. obj (any): The item for the current cell. col (int): The index of the column #obj is contained in. area (GeUserArea): An already initialized GeUserArea to measure the width of strings. Returns: TYPE: Description """ # The default width of a column is 80 units. width = 80 # Replace the width with the text width. area is a prepopulated # user area which has already setup all the font stuff, we can # measure right away. if col == NAME: return area.DrawGetTextWidth(obj.obj_name) + 5 if col == LINKTO: return area.DrawGetTextWidth("-->") + 5 if col == LINK: return area.DrawGetTextWidth(obj.linkto_name) + 5 if col == TYPE: return area.DrawGetTextWidth(obj.type) + 5 return width def GetFirst(self, root, userdata): """ Return the first element in the hierarchy, or None if there is no element. """ rValue = None if not len(self.items_list) else self.items_list[0] return rValue def GetNext(self, root, userdata, obj): """ Returns the next Object to display after arg:'obj' """ rValue = None currentObjIndex = self.items_list.index(obj) nextIndex = currentObjIndex + 1 if nextIndex < len(self.items_list): rValue = self.items_list[nextIndex] return rValue def GetPred(self, root, userdata, obj): """ Returns the previous Object to display before arg:'obj' """ rValue = None currentObjIndex = self.items_list.index(obj) predIndex = currentObjIndex - 1 if 0 <= predIndex < len(self.items_list): rValue = self.items_list[predIndex] return rValue def GetId(self, root, userdata, obj): """ Return a unique ID for the element in the TreeView. """ return hash(obj) def Select(self, root, userdata, obj, mode): print(obj.obj_name) if mode == c4d.SELECTION_NEW: for item in self.items_list: item.Deselect() obj.Select() elif mode == c4d.SELECTION_ADD: obj.Select() elif mode == c4d.SELECTION_SUB: obj.Deselect() def IsSelected(self, root, userdata, obj): return obj.IsSelected def DeletePressed(self, root, userdata): "Called when a delete event is received." for item in reversed(self.items_list): if item.IsSelected: self.items_list.remove(item) def GetName(self, root, userdata, obj): """ Returns the name to display for arg:'obj', only called for column of type LV_TREE """ return str(obj) # Or obj.texturePath def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor): """ Draw into a Cell, only called for column of type LV_USER """ if col == NAME: text = obj.obj_name elif col == LINKTO: text = '-->' elif col == LINK: text = obj.linkto_name elif col == TYPE: text = obj.type else: text = '' canvas = drawinfo["frame"] xpos = drawinfo["xpos"] ypos = drawinfo["ypos"] txtColorDict = canvas.GetColorRGB(c4d.COLOR_TEXT_SELECTED) if obj.IsSelected else canvas.GetColorRGB( c4d.COLOR_TEXT) txtColorVector = c4d.Vector(txtColorDict["r"] / 255.0, txtColorDict["g"] / 255.0, txtColorDict["b"] / 255.0) canvas.DrawSetTextCol(txtColorVector, bgColor) canvas.DrawText(text, xpos, ypos) def DoubleClick(self, root, userdata, obj, col, mouseinfo): return True class test_dialog(gui.GeDialog): def __init__(self): self._treegui = None self.treeview = TreeView() def CreateLayout(self): # Other than edit fields, buttons do not have a builtin bubble help. customgui = c4d.BaseContainer() customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN) customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True) # True if the tree view may have a header line. customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, False) # True if no lines should be drawn. customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, False) # True if the user can move the columns. customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) # True if the column width can be changed by the user. customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) # True if all lines have the same height. customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) # Alternate background per line. customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True) # True if cursor keys should be processed. customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, True) # Suppresses the rename popup when the user presses enter. customgui.SetBool(c4d.TREEVIEW_NO_MULTISELECT, False) self._treegui = self.AddCustomGui(1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 300, 300, customgui) if not self._treegui: print("[ERROR]: Could not create TreeView") return False self.AddButton(1001, c4d.BFH_CENTER, name="Add") return True def InitValues(self) -> bool: layout = c4d.BaseContainer() layout.SetInt32(NAME, c4d.LV_USER) layout.SetInt32(LINKTO, c4d.LV_USER) layout.SetInt32(LINK, c4d.LV_USER) layout.SetInt32(TYPE, c4d.LV_USER) self.layout = layout self._treegui.SetLayout(4, layout) # Set the header titles. self._treegui.SetHeaderText(NAME, "Name") self._treegui.SetHeaderText(LINKTO, "") self._treegui.SetHeaderText(LINK, "Link") self._treegui.SetHeaderText(TYPE, "Type") # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW self._treegui.SetRoot(self._treegui, self.treeview, None) self._treegui.Refresh() return True def Command(self, id, msg): if id == 1001: item = TreeView_Item() self.treeview.items_list.append(item) self._treegui.Refresh() return True return True # Execute main() if __name__=='__main__': dlg = test_dialog() dlg.Open(c4d.DLG_TYPE_ASYNC,0 -1,-1,400,400)
-
RE: Cannot post?
It was blocked from publication due to some keywords in the code
-
TreeView rows selected?
hi,
why are all rows highlighted(Although the selection of the function was correct, the text display color of the entire tree view has been changed) when selecting a row in the TreeView using the c4d.LV_USER parameter in each column (as shown in the left figure), and why is only that row highlighted when selecting a row in the first column using the c4d.LV_TREE parameter (as shown in the right figure)?how it can be done so that when all columns use c4d.LV_USER, the selected row can be activated as shown in the right figure
Thanks for any help!
code:
import c4d import random from c4d import gui # Welcome to the world of Python NAME = 0 LINKTO = 1 LINK = 2 TYPE = 3 class TreeView_Item(object): def __init__(self,): self.type = 'psr' self.selected = False self.obj_name = str(random.randint(1,100)) self.linkto_name = "" @property def IsSelected(self): return self.selected def Select(self): self.selected = True def Deselect(self): self.selected = False def __repr__(self): return str(self) def __str__(self): return self.obj_name class TreeView(c4d.gui.TreeViewFunctions): def __init__(self,items_list=None): self.items_list = items_list if items_list else [] def GetLineHeight(self,root, userdata, obj, col, area): return area.DrawGetFontHeight() def IsResizeColAllowed(self, root, userdata, lColID): return True def IsTristate(self, root, userdata): return False def GetColumnWidth(self, root, userdata, obj, col, area): """Measures the width of cells. Although this function is called #GetColumnWidth and has a #col, it is not only executed by column but by cell. So, when there is a column with items requiring the width 5, 10, and 15, then there is no need for evaluating all items. Each item can return its ideal width and Cinema 4D will then pick the largest value. Args: root (any): The root node of the tree view. userdata (any): The user data of the tree view. obj (any): The item for the current cell. col (int): The index of the column #obj is contained in. area (GeUserArea): An already initialized GeUserArea to measure the width of strings. Returns: TYPE: Description """ # The default width of a column is 80 units. width = 80 # Replace the width with the text width. area is a prepopulated # user area which has already setup all the font stuff, we can # measure right away. if col == NAME: return area.DrawGetTextWidth(obj.obj_name) + 5 if col == LINKTO: return area.DrawGetTextWidth("-->") + 5 if col == LINK: return area.DrawGetTextWidth(obj.linkto_name) + 5 if col == TYPE: return area.DrawGetTextWidth(obj.type) + 5 return width def GetFirst(self, root, userdata): """ Return the first element in the hierarchy, or None if there is no element. """ rValue = None if not len(self.items_list) else self.items_list[0] return rValue def GetNext(self, root, userdata, obj): """ Returns the next Object to display after arg:'obj' """ rValue = None currentObjIndex = self.items_list.index(obj) nextIndex = currentObjIndex + 1 if nextIndex < len(self.items_list): rValue = self.items_list[nextIndex] return rValue def GetPred(self, root, userdata, obj): """ Returns the previous Object to display before arg:'obj' """ rValue = None currentObjIndex = self.items_list.index(obj) predIndex = currentObjIndex - 1 if 0 <= predIndex < len(self.items_list): rValue = self.items_list[predIndex] return rValue def GetId(self, root, userdata, obj): """ Return a unique ID for the element in the TreeView. """ return hash(obj) def Select(self, root, userdata, obj, mode): print(obj.obj_name) if mode == c4d.SELECTION_NEW: for item in self.items_list: item.Deselect() obj.Select() elif mode == c4d.SELECTION_ADD: obj.Select() elif mode == c4d.SELECTION_SUB: obj.Deselect() def IsSelected(self, root, userdata, obj): return obj.IsSelected def DeletePressed(self, root, userdata): "Called when a delete event is received." for item in reversed(self.items_list): if item.IsSelected: self.items_list.remove(item) def GetName(self, root, userdata, obj): """ Returns the name to display for arg:'obj', only called for column of type LV_TREE """ return str(obj) # Or obj.texturePath def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor): """ Draw into a Cell, only called for column of type LV_USER """ if col == NAME: text = obj.obj_name elif col == LINKTO: text = '-->' elif col == LINK: text = obj.linkto_name elif col == TYPE: text = obj.type else: text = '' canvas = drawinfo["frame"] xpos = drawinfo["xpos"] ypos = drawinfo["ypos"] canvas.DrawText(text, xpos, ypos) def DoubleClick(self, root, userdata, obj, col, mouseinfo): return True class test_dialog(gui.GeDialog): def __init__(self): self._treegui = None self.treeview = TreeView() def CreateLayout(self): # Other than edit fields, buttons do not have a builtin bubble help. customgui = c4d.BaseContainer() customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN) customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True) # True if the tree view may have a header line. customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, False) # True if no lines should be drawn. customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, False) # True if the user can move the columns. customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) # True if the column width can be changed by the user. customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) # True if all lines have the same height. customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) # Alternate background per line. customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True) # True if cursor keys should be processed. customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, True) # Suppresses the rename popup when the user presses enter. customgui.SetBool(c4d.TREEVIEW_NO_MULTISELECT, False) self._treegui = self.AddCustomGui(1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 300, 300, customgui) if not self._treegui: print("[ERROR]: Could not create TreeView") return False self.AddButton(1001, c4d.BFH_CENTER, name="Add") return True def InitValues(self) -> bool: layout = c4d.BaseContainer() layout.SetInt32(NAME, c4d.LV_USER) layout.SetInt32(LINKTO, c4d.LV_USER) layout.SetInt32(LINK, c4d.LV_USER) layout.SetInt32(TYPE, c4d.LV_USER) self.layout = layout self._treegui.SetLayout(4, layout) # Set the header titles. self._treegui.SetHeaderText(NAME, "Name") self._treegui.SetHeaderText(LINKTO, "") self._treegui.SetHeaderText(LINK, "Link") self._treegui.SetHeaderText(TYPE, "Type") # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW self._treegui.SetRoot(self._treegui, self.treeview, None) self._treegui.Refresh() return True def Command(self, id, msg): if id == 1001: item = TreeView_Item() self.treeview.items_list.append(item) self._treegui.Refresh() return True return True # Execute main() if __name__=='__main__': dlg = test_dialog() dlg.Open(c4d.DLG_TYPE_ASYNC,0 -1,-1,400,400)
-
RE: How to add a tree view to a Description Resource?
@ferdinand Thank you for your detailed answer.
-
How to add a tree view to a Description Resource?
I saw that the Character Component tag of c4d seems to achieve this effect. Can I use Python to create a plugin and make the tree view a parameter of the plugin. I tried to find the answer in the C++doc Resource Files Manual, but couldn't find it.
Thanks for any help!
-
RE: SetJointResetState() Parameter interpretation error in py doc?
@m_adam c4d.Vector().GetMin() and .GetMax() in py doc also need to fix the explanation errors,them return float value