hello,guys
I'm implement some functions like model manage system, similar with asset browser, but the data come from Remote DataBase,so this is some questions on my way。
my environment
python
c4d R26
code:
import c4d
ID_NAME = 1
PLUGIN_ID = 3000011 # TEST ID ONLY
class TreeNode(object):
data = None
_selected = False
def __init__(self, data):
self.data = data
@property
def Text(self):
return self.__text
@Text.setter
def Text(self, value: str):
self.__text = value
@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 str(self.data)
class TreeView(c4d.gui.TreeViewFunctions):
def __init__(self):
self.listOfItems = list() # Store all objects we need to display in this list
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 False
def GetFirst(self, root, userdata):
"""
Return the first element in the hierarchy, or None if there is no element.
"""
rValue = None if not self.listOfItems else self.listOfItems[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
"""
return None
def GetNext(self, root, userdata, obj):
"""
Returns the next Object to display after arg:'obj'
"""
rValue = None
currentObjIndex = self.listOfItems.index(obj)
nextIndex = currentObjIndex + 1
if nextIndex < len(self.listOfItems):
rValue = self.listOfItems[nextIndex]
return rValue
def GetPred(self, root, userdata, obj):
"""
Returns the previous Object to display before arg:'obj'
"""
rValue = None
currentObjIndex = self.listOfItems.index(obj)
predIndex = currentObjIndex - 1
if 0 <= predIndex < len(self.listOfItems):
rValue = self.listOfItems[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.listOfItems:
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:
for tex in self.listOfItems:
tex.Deselect()
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 GetName(self, root, userdata, obj):
"""
Returns the name to display for arg:'obj', only called for column of type LV_TREE
"""
return str(obj.Text)
def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor):
"""
Draw into a Cell, only called for column of type LV_USER
"""
value = obj.Text
geUserArea = drawinfo["frame"]
w = geUserArea.DrawGetTextWidth(value)
h = geUserArea.DrawGetFontHeight()
xpos = drawinfo["xpos"]
ypos = drawinfo["ypos"] + drawinfo["height"]
drawinfo["frame"].DrawText(value, xpos, 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.
"""
return True
def EmptyText(self, root: object, userdata: object) -> str:
return "empty"
class TestTreeDialog(c4d.gui.SubDialog):
_treegui = None # Our CustomGui TreeView
_listView = TreeView() # Our Instance of c4d.gui.TreeViewFunctions
ID_LISTVIEW = 10000
def CreateLayout(self):
if self.GroupBegin(0, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, cols=2):
# Create the TreeView GUI.
customgui = c4d.BaseContainer()
customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_OUT)
# True if the tree view may have a header line.
customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True)
# True if no lines should be drawn.
customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, False)
# True if the user can move the columns.
customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, True)
# True if the column width can be changed by the user.
customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True)
# True if all lines have the same height.
customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True)
# Alternate background per line.
customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True)
# True if cursor keys should be processed.
customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True)
# Suppresses the rename popup when the user presses enter.
customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, False)
customgui.SetBool(c4d.TREEVIEW_NO_MULTISELECT, True)
#customgui.SetBool(c4d.TREEVIEW_RESIZABLE, True)
self._treegui = self.AddCustomGui(
self.ID_LISTVIEW, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT, 50, 100, customgui)
if not self._treegui:
print("[ERROR]: Could not create TreeView")
return False
self.AddMultiLineEditText(0, c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT, 80,100)
self.GroupEnd()
return True
def InitValues(self):
#testcode
node1 = TreeNode("1")
node1.Text = "a1"
self._listView.listOfItems.append(node1)
node2 = TreeNode("1")
node2.Text = "a2"
self._listView.listOfItems.append(node2)
# Initialize the column layout for the TreeView.
layout = c4d.BaseContainer()
layout.SetLong(ID_NAME, c4d.LV_TREE)
self._treegui.SetLayout(1, layout)
# Set the header titles.
self._treegui.SetHeaderText(ID_NAME, "name")
#self._treegui.Refresh()
# Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW
self._treegui.SetRoot(self._treegui, self._listView, None)
self._treegui.Refresh()
return True
def Command(self, messageId, bc):
return True
class MenuToolData(c4d.plugins.ToolData):
dialog = None
def Message(self, doc, data, msgType, t_data):
return True
def AllocSubDialog(self, bc):
return TestTreeDialog()
def GetState(self, doc):
return c4d.CMD_ENABLED
def MouseInput(self, doc, data, bd, win, msg):
return True
def main() -> None:
# c4d.plugins.RegisterCommandPlugin(
# PLUGIN_ID, "treeTest1", 0, None, "treeTest1", MenuCommand())
c4d.plugins.RegisterToolPlugin(PLUGIN_ID, "treeTest2menu", 0, None,"treeTest2describe", MenuToolData())
if __name__ == '__main__':
main()
1.is there any way to add a separator in the model of the two control, so I'can drag to resize,
like asset browser.
2.how to hide this title? It's seem useless
3.can embed the Dialog like asset browser?
thanks a lot!