gr4ph0s

C4D TreeView Example - Part 2 Children

Jan 6th, 2020
88
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #More information http://www.plugincafe.com/forum/forum_posts.asp?TID=14102&PID=56287#56287
  2. import c4d
  3. import weakref
  4.  
  5. # Be sure to use a unique ID obtained from http://www.plugincafe.com/.
  6. PLUGIN_ID = 1000010 # TEST ID ONLY
  7.  
  8. # TreeView Column IDs.
  9. ID_CHECKBOX = 1
  10. ID_NAME = 2
  11. ID_OTHER = 3
  12.  
  13. def TextureObjectIterator(lst):
  14.    
  15.     for parentTex in lst:
  16.         yield parentTex
  17.         for childTex in TextureObjectIterator(parentTex.GetChildren()):
  18.             yield childTex
  19.  
  20. class TextureObject(object):
  21.     """
  22.    Class which represent a texture, aka an Item in our list
  23.    """
  24.     texturePath = "TexPath"
  25.     otherData = "OtherData"
  26.     _selected = False
  27.     _open = True
  28.  
  29.     def __init__(self, texturePath):
  30.         self.texturePath = texturePath
  31.         self.otherData += texturePath
  32.         self.children = []
  33.         self._parent = None
  34.  
  35.     @property
  36.     def IsSelected(self):
  37.         return self._selected
  38.  
  39.     def Select(self):
  40.         self._selected = True
  41.  
  42.     def Deselect(self):
  43.         self._selected = False
  44.  
  45.     @property
  46.     def IsOpened(self):
  47.         return self._open
  48.  
  49.     def Open(self):
  50.         self._open = True
  51.    
  52.     def Close(self):
  53.         self._open = False
  54.  
  55.     def AddChild(self, obj):
  56.         obj._parent = weakref.ref(self)
  57.         self.children.append(obj)
  58.        
  59.     def GetChildren(self):
  60.         return self.children
  61.  
  62.     def GetParent(self):
  63.         if self._parent:
  64.             return self._parent()
  65.        
  66.         return None
  67.        
  68.     def __repr__(self):
  69.         return str(self)
  70.  
  71.     def __str__(self):
  72.         return self.texturePath
  73.  
  74.  
  75. class ListView(c4d.gui.TreeViewFunctions):
  76.  
  77.     def __init__(self):
  78.         self.listOfTexture = list() # Store all objects we need to display in this list
  79.  
  80.         # Add some defaults values
  81.         t1 = TextureObject("T1")
  82.         t2 = TextureObject("T2")
  83.         t3 = TextureObject("T3")
  84.         t4 = TextureObject("T4")
  85.  
  86.         self.listOfTexture.extend([t1, t2, t3, t4])
  87.  
  88.  
  89.     def IsResizeColAllowed(self, root, userdata, lColID):
  90.         return True
  91.  
  92.     def IsTristate(self, root, userdata):
  93.         return False
  94.  
  95.     def GetColumnWidth(self, root, userdata, obj, col, area):
  96.         return 80  # All have the same initial width
  97.  
  98.     def IsMoveColAllowed(self, root, userdata, lColID):
  99.         # The user is allowed to move all columns.
  100.         # TREEVIEW_MOVE_COLUMN must be set in the container of AddCustomGui.
  101.         return True
  102.  
  103.     def GetFirst(self, root, userdata):
  104.         """
  105.        Return the first element in the hierarchy, or None if there is no element.
  106.        """
  107.         rValue = None if not self.listOfTexture else self.listOfTexture[0]
  108.         return rValue
  109.  
  110.     def GetDown(self, root, userdata, obj):
  111.         """
  112.        Return a child of a node, since we only want a list, we return None everytime
  113.        """
  114.         children = obj.GetChildren()
  115.         if children:
  116.             return children[0]
  117.  
  118.         return None
  119.  
  120.     def GetNext(self, root, userdata, obj):
  121.         """
  122.        Returns the next Object to display after arg:'obj'
  123.        """
  124.         rValue = None
  125.  
  126.         # If does have a child it means it's a child.
  127.         objParent = obj.GetParent()
  128.         listToSearch = objParent.GetChildren() if objParent is not None else self.listOfTexture
  129.  
  130.         currentObjIndex = listToSearch.index(obj)
  131.         nextIndex = currentObjIndex + 1
  132.         if nextIndex < len(listToSearch):
  133.             rValue = listToSearch[nextIndex]
  134.  
  135.         return rValue
  136.  
  137.     def GetPred(self, root, userdata, obj):
  138.         """
  139.        Returns the previous Object to display before arg:'obj'
  140.        """
  141.         rValue = None
  142.  
  143.         # If does have a child it means it's a child.
  144.         objParent = obj.GetParent()
  145.         listToSearch = objParent.GetChildren() if objParent is not None else self.listOfTexture
  146.  
  147.         currentObjIndex = listToSearch.index(obj)
  148.         predIndex = currentObjIndex - 1
  149.         if 0 <= predIndex < len(listToSearch):
  150.             rValue = listToSearch[predIndex]
  151.  
  152.         return rValue
  153.  
  154.     def GetId(self, root, userdata, obj):
  155.         """
  156.        Return a unique ID for the element in the TreeView.
  157.        """
  158.         return hash(obj)
  159.  
  160.     def Select(self, root, userdata, obj, mode):
  161.         """
  162.        Called when the user selects an element.
  163.        """
  164.         if mode == c4d.SELECTION_NEW:
  165.             for tex in self.listOfTexture:
  166.                 tex.Deselect()
  167.             obj.Select()
  168.         elif mode == c4d.SELECTION_ADD:
  169.             obj.Select()
  170.         elif mode == c4d.SELECTION_SUB:
  171.             obj.Deselect()
  172.  
  173.     def IsSelected(self, root, userdata, obj):
  174.         """
  175.        Returns: True if *obj* is selected, False if not.
  176.        """
  177.         return obj.IsSelected
  178.  
  179.     def SetCheck(self, root, userdata, obj, column, checked, msg):
  180.         """
  181.        Called when the user clicks on a checkbox for an object in a
  182.        `c4d.LV_CHECKBOX` column.
  183.        """
  184.         if checked:
  185.             obj.Select()
  186.         else:
  187.             obj.Deselect()
  188.  
  189.     def IsChecked(self, root, userdata, obj, column):
  190.         """
  191.        Returns: (int): Status of the checkbox in the specified *column* for *obj*.
  192.        """
  193.         if obj.IsSelected:
  194.             return c4d.LV_CHECKBOX_CHECKED | c4d.LV_CHECKBOX_ENABLED
  195.         else:
  196.             return c4d.LV_CHECKBOX_ENABLED
  197.  
  198.     def IsOpened(self, root, userdata, obj):
  199.         """
  200.        Returns: (bool): Status If it's opened = True (folded) or closed = False.
  201.        """
  202.         # If there is some children
  203.         return obj.IsOpened
  204.  
  205.     def Open(self, root, userdata, obj, onoff):
  206.         """
  207.        Called when the user clicks on a folding state of an object to display/hide its children
  208.        """
  209.         if onoff:
  210.             obj.Open()
  211.  
  212.         else:
  213.             obj.Close()
  214.  
  215.     def GetName(self, root, userdata, obj):
  216.         """
  217.        Returns the name to display for arg:'obj', only called for column of type LV_TREE
  218.        """
  219.         return str(obj) # Or obj.texturePath
  220.  
  221.     def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor):
  222.         """
  223.        Draw into a Cell, only called for column of type LV_USER
  224.        """
  225.         if col == ID_OTHER:
  226.             name = obj.otherData
  227.             geUserArea = drawinfo["frame"]
  228.             w = geUserArea.DrawGetTextWidth(name)
  229.             h = geUserArea.DrawGetFontHeight()
  230.             xpos = drawinfo["xpos"]
  231.             ypos = drawinfo["ypos"] + drawinfo["height"]
  232.             drawinfo["frame"].DrawText(name, xpos, ypos - h * 1.1)
  233.  
  234.     def DoubleClick(self, root, userdata, obj, col, mouseinfo):
  235.         """
  236.        Called when the user double-clicks on an entry in the TreeView.
  237.  
  238.        Returns:
  239.          (bool): True if the double-click was handled, False if the
  240.            default action should kick in. The default action will invoke
  241.            the rename procedure for the object, causing `SetName()` to be
  242.            called.
  243.        """
  244.         c4d.gui.MessageDialog("You clicked on " + str(obj))
  245.         return True
  246.  
  247.     def DeletePressed(self, root, userdata):
  248.         "Called when a delete event is received."
  249.         for tex in reversed(list(TextureObjectIterator(self.listOfTexture))):
  250.             if tex.IsSelected:
  251.                 listToRemove = objParent.GetChildren() if objParent is not None else self.listOfTexture
  252.                 listToRemove.remove(tex)
  253.  
  254. class TestDialog(c4d.gui.GeDialog):
  255.     _treegui = None # Our CustomGui TreeView
  256.     _listView = ListView() # Our Instance of c4d.gui.TreeViewFunctions
  257.  
  258.     def CreateLayout(self):
  259.         # Create the TreeView GUI.
  260.         customgui = c4d.BaseContainer()
  261.         customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN)
  262.         customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True) # True if the tree view may have a header line.
  263.         customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, False) # True if no lines should be drawn.
  264.         customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, True) # True if the user can move the columns.
  265.         customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) # True if the column width can be changed by the user.
  266.         customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) # True if all lines have the same height.
  267.         customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) # Alternate background per line.
  268.         customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True) # True if cursor keys should be processed.
  269.         customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, False) # Suppresses the rename popup when the user presses enter.
  270.  
  271.         self._treegui = self.AddCustomGui( 1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 300, 300, customgui)
  272.         if not self._treegui:
  273.             print "[ERROR]: Could not create TreeView"
  274.             return False
  275.  
  276.         self.AddButton(1001, c4d.BFH_CENTER, name="Add")
  277.         self.AddButton(1002, c4d.BFH_CENTER, name="Add Child to selected")
  278.         return True
  279.  
  280.     def InitValues(self):
  281.         # Initialize the column layout for the TreeView.
  282.         layout = c4d.BaseContainer()
  283.         layout.SetLong(ID_CHECKBOX, c4d.LV_CHECKBOX)
  284.         layout.SetLong(ID_NAME, c4d.LV_TREE)
  285.         layout.SetLong(ID_OTHER, c4d.LV_USER)
  286.         self._treegui.SetLayout(3, layout)
  287.  
  288.         # Set the header titles.
  289.         self._treegui.SetHeaderText(ID_CHECKBOX, "Check")
  290.         self._treegui.SetHeaderText(ID_NAME, "Name")
  291.         self._treegui.SetHeaderText(ID_OTHER, "Other")
  292.         self._treegui.Refresh()
  293.  
  294.         # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW
  295.         self._treegui.SetRoot(self._treegui, self._listView, None)
  296.         return True
  297.  
  298.     def Command(self, id, msg):
  299.         # Click on button
  300.         if id == 1001:
  301.             # Add data to our DataStructure (ListView)
  302.             newID = len(self._listView.listOfTexture) + 1
  303.             tex = TextureObject("T{}".format(newID))
  304.             self._listView.listOfTexture.append(tex)
  305.  
  306.             # Refresh the TreeView
  307.             self._treegui.Refresh()
  308.            
  309.         elif id == 1002:
  310.             for parentTex in TextureObjectIterator(self._listView.listOfTexture):
  311.                 if not parentTex.IsSelected:
  312.                     continue
  313.  
  314.                 newID = len(parentTex.GetChildren()) + 1
  315.                 tex = TextureObject("T{0}.{1}".format(str(parentTex), newID))
  316.                 parentTex.AddChild(tex)
  317.                
  318.             # Refresh the TreeView
  319.             self._treegui.Refresh()
  320.  
  321.         return True
  322.  
  323.  
  324. def main():
  325.     global dialog
  326.     dialog = TestDialog()
  327.     dialog.Open(c4d.DLG_TYPE_ASYNC, defaulth=600, defaultw=600)
  328.  
  329.  
  330. if __name__ == "__main__":
  331.     main()
RAW Paste Data