TreeView Menu



  • Hello,
    Is there a TreeView example to create a similar tree view menu like as the Cinema 4D help dialog?

    tree_view.png
    Thanks.



  • Hi @mfersaoui as a first introduction you can read using customgui listview then if you have more specific questions about treeview I would suggest to either search on plugincafe or directly ask the questions.

    Cheers,
    Maxime.



  • Hi @m_adam ,

    Thank you so much, I have two questions:

    The first is What the right way to rewriting the following code and obtain same result:

    class ListView(c4d.gui.TreeViewFunctions):
    
        def __init__(self):
            self.listOfTexture = list() # Store all objects we need to display in this list
    
    def CreateLayout(self):
    
        self.GroupBegin(0, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 2, 0)
        self.GroupBorderSpace(5, 5, 5, 5)
    
        self.GroupBegin(0, flags=c4d.BFH_LEFT | c4d.BFV_SCALEFIT, cols=1, rows=1, initw=400, inith=0)
    
        # Create the TreeView GUI.
        customgui = c4d.BaseContainer()
        customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN)
        customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, False) # 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, False) # 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, 0, 0, customgui)
        if not self._treegui:
            print "[ERROR]: Could not create TreeView"
            return False
    
        self.GroupEnd()
    
        self.GroupBegin(0, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, cols=1, rows=1)
        html_file = "file.html"
        htmlViewer = self.AddCustomGui(1000001, c4d.CUSTOMGUI_HTMLVIEWER, "Viewer", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0)
        htmlViewer.SetUrl(html_file, c4d.URL_ENCODING_UTF16)
        self.GroupEnd()
    
        return True
        
    def InitValues(self):
        # Initialize the column layout for the TreeView.
        layout = c4d.BaseContainer()
        layout.SetLong(ID_NAME, c4d.LV_TREE)
        self._treegui.SetLayout(1, layout)
    
        mdata = {
            "Menu 01": {
                "Item 01": ["sub-item 01", "sub-item 02", "sub-item 03"],
                "Item 02": ["sub-item 01", "sub-item 02"],
                "Item 03": [],
                },
            "Menu 02": [],
            "Menu 03": ["sub-item 01", "sub-item 02"],
            "Menu 04": ["sub-item 01"]
        }
        res = []
        for m in m_data:
            m1 = TextureObject(m)
            res.append(m1)
            m1_items = m_data[m]
            if len(m1_items):
                for m1_name in m1_items:
                    m1_item = TextureObject(m1_name)
                    m1.AddChild(m1_item)
                    if isinstance(m1_items, dict):
                        m2_items = m1_items[m1_name]
                        if len(m2_items):
                            for m2_name in m2_items:
                                m2_item = TextureObject(m2_name)
                                m1_item.AddChild(m2_item)
    
        self._listView.listOfTexture.extend(res)
    
        # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW
        self._treegui.SetRoot(self._treegui, self._listView, None)
    
        return True
    

    Result:
    tree_view_menu.jpg

    The second question is How to interact with the htmlViewer area at the right of dialog from the my TreeView menu (Changing the htmlViewer file when clicking on a menu items).

    def Select(self, root, userdata, obj, mode):
        """
        Called when the user selects an element.
        """
        if mode == c4d.SELECTION_NEW:
            html_file = "file.html"
            #TestDialog()
            for tex in TextureObjectIterator(self.listOfTexture):
                tex.Deselect()
            obj.Select()
    

    Thanks



  • @mfersaoui said in TreeView Menu:

    GroupBegin

    For my second question I found this function to interact with the htmlViewer area.

    c4d.SpecialEventAdd(ACTION_ID)
    


  • Hi @mfersaoui sorry for the delay, I overlooked your reply.

    Regarding your initial question, I would say it was just a simple example without children in mind.
    But if you are interested you can find in Insert object in Treeview an example that uses children or even in No multiple selection in Treeview not working? where each entry can also be a root.

    In the end, how you structure your internal data is up to you I can't really judge what's the best for you. 😉

    For your second point correct, or you can simply store a reference to your GeDialog in your treeview and use this reference to do the synchronization.

    Hope this helps and if you have a question, please let me know.
    Cheers,
    Maxie.


Log in to reply