Creating a table view using c4d.gui.TreeViewCustom
-
On 24/03/2016 at 23:28, xxxxxxxx wrote:
I'm trying to create a table with each row representing information about an object. To understand how this could be done, I have created a simple plugin based on c4d_treeview.pyp (https://gist.github.com/NiklasRosenstein/632e39a9b4dda391fe54)
Unfortunately, DrawCell does not render text to the cell using this approach. Am I using drawinfo["frame"].DrawText() incorrectly or is my approach the wrong way to go about implementing a table view using tree view?
The code follows
import c4d PLUGIN_ID = 9912399 PLUGIN_NAME = "Python TreeView Example" PLUGIN_HELP = "Show a simple table." ID_NAME = 1 ID_PLACE = 2 ID_ANIMAL = 3 ID_THING = 4 class Node(object) : def __init__(self, name, place, animal, thing) : self.name = name self.place = place self.animal = animal self.thing = thing self.next = None def SetNext(self, next) : self.next = next def GetNext(self) : return self.next def GetDown(self) : return None def GetPred(self) : return None def GetName(self) : return self.name def GetPlace(self) : return self.place def GetAnimal(self) : return self.animal def GetThing(self) : return self.thing class Hierarchy(c4d.gui.TreeViewFunctions) : def __init__(self, dlg) : node1 = Node("name1", "place1", "animal1", "thing1") node2 = Node("name2", "place2", "animal2", "thing2") node3 = Node("name3", "place3", "animal3", "thing3") node4 = Node("name4", "place4", "animal4", "thing4") node1.SetNext(node2) node2.SetNext(node3) node3.SetNext(node4) self.root = node1 def GetFirst(self, root, userdata) : root = self.root return root def GetDown(self, root, userdata, obj) : return obj.GetDown() def GetNext(self, root, userdata, obj) : return obj.GetNext() def GetPred(self, root, userdata, obj) : return obj.GetPred() def GetName(self, root, userdata, obj) : return obj.GetName() def GetId(self, root, userdata, obj) : return obj.GetUniqueID() def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor) : if col == ID_NAME: name = obj.GetName() w = drawinfo["frame"].DrawGetTextWidth(name) h = drawinfo["frame"].DrawGetFontHeight() xpos = drawinfo["xpos"] ypos = drawinfo["ypos"] print "%d) name = %s" % (col, name) print "text width= %d, font height= %d" % (w, h) print "width= %d, height= %d" % (drawinfo["frame"].GetWidth(), drawinfo["frame"].GetHeight()) print "xpos= %d, ypos= %d" % (xpos, ypos) drawinfo["frame"].DrawText(name, xpos, ypos - h) elif col == ID_PLACE: pass elif col == ID_ANIMAL: pass elif col == ID_THING: pass else: print "unknown column id!" def GetColumnWidth(self, root, userdata, obj, col, area) : return 80 class TestDialog(c4d.gui.GeDialog) : _treegui = None def CreateLayout(self) : customgui = c4d.BaseContainer() customgui.SetBool(c4d.TREEVIEW_BORDER, True) customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True) customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, True) customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, False) customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, False) customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) self._treegui = self.AddCustomGui(1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 300, 300, customgui) return True def CoreMessage(self, id, msg) : if id == c4d.EVMSG_CHANGE: self._treegui.Refresh() return True def InitValues(self) : layout = c4d.BaseContainer() layout.SetLong(ID_NAME, c4d.LV_USER) layout.SetLong(ID_PLACE, c4d.LV_USER) layout.SetLong(ID_ANIMAL, c4d.LV_USER) layout.SetLong(ID_THING, c4d.LV_USER) self._treegui.SetLayout(4, layout) self._treegui.SetHeaderText(ID_NAME, "Name") self._treegui.SetHeaderText(ID_PLACE, "Place") self._treegui.SetHeaderText(ID_ANIMAL, "Animal") self._treegui.SetHeaderText(ID_THING, "Thing") self._treegui.Refresh() data_model = Hierarchy(self) self._treegui.SetRoot(None, data_model, None) return True class MenuCommand(c4d.plugins.CommandData) : dialog = None def Execute(self, doc) : if self.dialog is None: self.dialog = TestDialog() return self.dialog.Open( c4d.DLG_TYPE_ASYNC, PLUGIN_ID, defaulth=600, defaultw=600) def RestoreLayout(self, sec_ref) : if self.dialog is None: self.dialog = TestDialog() return self.dialog.Restore(PLUGIN_ID, secret=sec_ref) def main() : c4d.plugins.RegisterCommandPlugin( PLUGIN_ID, PLUGIN_NAME, 0, None, PLUGIN_HELP, MenuCommand()) if __name__ == "__main__": main()
-
On 25/03/2016 at 08:33, xxxxxxxx wrote:
I was able to solve the rendering issue
- One of the column items has to be of type LV_TREE
- For that item, TreeFunction.GetName() is used to render the text in the cell
- For other items (of type LV_USER), TreeFunction.DrawCell() is used to render the contents of the cell.
Changes:
layout.SetLong(ID_NAME, c4d.LV_USER)
layout.SetLong(ID_NAME, c4d.LV_TREE)def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor) :
~~ if col == ID_NAME:~~
~~ name = obj.GetName()~~
~~ w = drawinfo["frame"].DrawGetTextWidth(name)~~
~~ h = drawinfo["frame"].DrawGetFontHeight()~~
~~ xpos = drawinfo["xpos"]~~
~~ ypos = drawinfo["ypos"]~~
~~ print "%d) name = %s" % (col, name)~~
~~ print "text width= %d, font height= %d" % (w, h)~~
~~ print "width= %d, height= %d" % (drawinfo["frame"].GetWidth(), drawinfo["frame"].GetHeight())~~
~~ print "xpos= %d, ypos= %d" % (xpos, ypos)~~
~~ drawinfo["frame"].DrawText(name, xpos, ypos - h)~~
~~ elif col == ID_PLACE: pass~~
~~ elif col == ID_ANIMAL: pass~~
~~ elif col == ID_THING: pass~~
else:
print "unknown column id!"def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor) :
if col == ID_PLACE:
drawinfo["frame"].DrawText(obj.GetPlace(), drawinfo["xpos"], drawinfo["ypos"] + 2)
elif col == ID_ANIMAL:
drawinfo["frame"].DrawText(obj.GetAnimal(), drawinfo["xpos"], drawinfo["ypos"] + 2)
elif col == ID_THING:
drawinfo["frame"].DrawText(obj.GetThing(), drawinfo["xpos"], drawinfo["ypos"] + 2)
else:
print "unknown column id!"