Refreshing customgui tree view in a dialog



  • On 04/10/2017 at 07:50, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R17 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hello.

    I have a GeDialog with a Treeview custom gui in a group. 
    I want to recreate the tree with different nodes after a specific node is selected. 
    What I do is that i set a different root, but since I do it in the Select method of TreeViewFunctions, I get memory corruption crash (since I delete the previous).
    Where is the correct place to set a different root node in the treeview ? 
    I didn't find any callback for that purpose in TreeViewFunctions.

    Should I do it by sending a message in the dialog ?

    Thank you for your time !



  • On 06/10/2017 at 12:47, xxxxxxxx wrote:

    Hi Peterakos, thanks for writing us.

    With reference to your question, from my research, you should not encounter any issue in defining a new root in the TreeViewFunctions::Select() method. Are you maybe deleting the old root before setting the new one?

    I've actually changed the "Layer Shader Browser" example found in the cinema4dsdk modifying the accepted items from a LayerShaderLayer to a standard BaseObject. The behavior is simple but yet adhering to what you've described: every time an item is selected in the TreeViewCustomGui, assuming that this isn't the first, the newly selected object become the new root whilst the previous "root" is removed from the scene and disposed.

    This actually happen in the TreeViewFunctions::Select() method as shown below:

      
    void Select(void* root, void* userdata, void* obj, Int32 mode)  
    {  
      BaseObject* bo = static_cast<BaseObject*>(obj);  
      
      // retrieve the GeDialog instance  
      MyTreeBrowser* tb = ((MyTreeBrowser* )userdata);  
        
      // retrieve the TreeViewCustomGui instance  
      TreeViewCustomGui* tree = (TreeViewCustomGui* )tb->FindCustomGui(DLG_MYTREEBROWSER_TREE, CUSTOMGUI_TREEVIEW);  
        
      if (!tree)  
          return;  
        
      // retrieve the first object which is also set as root  
      BaseObject* currentRoot = (BaseObject* )this->GetFirst(root, userdata);  
        
      // set the new root  
      tree->SetRoot(bo, this, userdata);  
        
      // eventually remove the "previous" root  
      if (currentRoot && currentRoot != bo)  
      {  
          currentRoot->Remove();  
          BaseObject::Free(currentRoot);  
          EventAdd();  
      }  
      // do something else  
      // ...        
    }  
    

    That said I actually used no fancy callbacks or messages rather than simply relying on the methods pointed above.

    Let me know if it helps, otherwise well let's dig down again.

    Best, Riccardo



  • On 08/10/2017 at 14:38, xxxxxxxx wrote:

    Hello.

    Originally posted by xxxxxxxx

    Are you maybe deleting the old root before setting the new one?

    That's exactly what I do !
    I'll fix my code to delete it after setting the new root.

    Thank you very much for your help !


Log in to reply