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

    1. One of the column items has to be of type LV_TREE
    2. For that item, TreeFunction.GetName() is used to render the text in the cell
    3. 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!"


Log in to reply