Godot Tree to JSON

Viewed 191

Can someone tell me how to save a Tree with all of the TreeItems to a JSON? I specifically only care about the column 0 text of each TreeItem. The issue I am currently having is I can either get only 1 level of keys dict[keys] but can't get the nested dicts. I found a resource of how to save the ScenceTree to a JSON, but this does not work with Tree as has an odd child structure (get_children()) acts differently. Also you can't iterate over TreeItems and I don't see TreeItems in the Remote view of the editor. If I try to return to dict in pieces it seems to fail, and I can create a string to the correct dict path for example dict[level 0][level 1], but I don't know how to turn that string into a way to access the dictionary (for example str2var). And I don't know how to remember where I am in the dictionary.

The area in question is _on_NewEntity_confirmed() it will then call get_tree_leaves(branch):

extends Tree

var root = null
var entities = {"AAA":"BBB"}

onready var menu = $TreeRMBMenu
onready var newEntry = $NewEntity
onready var entryName = $NewEntity/LineEdit
onready var tree = self
onready var popup_ok = null

func _ready() -> void:
    ### Add BACK
    #buildTree(entities)
    
    
    ### Might not need to add
    #for child in self.get_children():
        #if child.get_class() == "PopupMenu" and child.name != "NewEntity":
        #print(tree_to_dictionary(child))
        #print(child.name)
        #print(child.get_class())
        #break
        
    # print(tree_to_dictionary(self.get_node()))
    #print(tree_to_dictionary(self))
    
    #return
    
    root = tree.create_item()
    
    tree.set_hide_root(false)
    root.set_text(0, "Categories")
    
    # add menu options
    menu.add_item("Create (Child)")
    menu.add_item("Edit (Self)")
    menu.add_item("Delete (Self + Children)")
    
    fix_new_entry_popup()

func fix_new_entry_popup():
    for child in newEntry.get_children():
        if child.get_class() == "HBoxContainer":
            for subchild in child.get_children():
                if subchild.get_class() == "Button":
                    subchild.name = subchild.get_text()
                    if subchild.name == "OK":
                        popup_ok = subchild
    
    entryName.set_focus_next(popup_ok.get_path())
    

func _on_EntityTree_item_rmb_edited() -> void:
    print("RMB Edited")


func _on_EntityTree_item_rmb_selected(_position: Vector2) -> void:
    print("RMB Selected")
    
    # disable delete and edit on root
    if tree.get_selected() == root:
        menu.set_item_disabled(1, true)
        menu.set_item_disabled(2, true)
    else:
        menu.set_item_disabled(1, false)
        menu.set_item_disabled(2, false)
        
    menu.popup(Rect2(get_global_mouse_position(), Vector2(10, 10)))
    menu.show()
    entryName.grab_focus()


func _on_TreeRMBMenu_index_pressed(index: int) -> void:
    print(menu.get_item_text(index))
    
    # create item
    if index == 0:
        newEntry.popup_centered()


func _on_NewEntity_about_to_show() -> void:
    entryName.text = ""
    


func _on_NewEntity_confirmed() -> void:
    var child = tree.create_item(tree.get_selected())
    child.set_text(0, entryName.text)
    
    var result = ""
    var path = ""
    var current_child = child
    while result != "Categories":
        result = current_child.get_parent().get_text(0)
        if result != "Categories":
            path = result + "/" + path
            current_child = current_child.get_parent()
        
    print(path)
    path = path.split("/")
    
    var my_string =  "entities"
    for entity in path:
        if entity == "":
            continue
        my_string = my_string + "[" + str(entity) + "]"
        #entities[entities] = {}
        #previous_path = previous_path + entity
    
    my_string = my_string + "[" + entryName.text + "]"
    print(my_string)
    
    print("NEXT")
    
    entities = {}
    entities = get_tree_leaves(root)
    print(entities)


func get_tree_leaves(branch):
    var old_branch = branch
    if tree.get_root() != null:
        #var child = tree.get_root().get_children()
        branch = branch.get_children()
        
        var branchDictionary = {}
        
        while branch != null:
            # put code here
            print(branch.get_text(0))
            
            return branch.get_text(0)
            
            if old_branch.get_text(0) != "Categories":
                branchDictionary[old_branch.get_text(0)][branch.get_text(0)]=get_tree_leaves(branch)
            #var leaves = branch.get_children()
            #get_tree_leaves(branch)
            
            branch = branch.get_next()
        
        return branchDictionary 


func _on_LineEdit_text_entered(_new_text: String) -> void:
    newEntry.emit_signal("confirmed")
    newEntry.hide()


func _on_LineEdit_draw() -> void:
    if entryName.text == "":
        entryName.grab_focus()


func tree_to_dictionary(node):
    node = node.duplicate()
    var branchDictionary = {
    node: {}
    }
    var childrenNodes = node.get_children()
    for childNode in childrenNodes:
        branchDictionary[node][childNode]=tree_to_dictionary(childNode)
    return branchDictionary


### KEEP THIS CODE AS IT POPULATES THE TREE
func buildTree(dict):
    root = self.create_item()
    self.set_hide_root(true)

    for i in dict.keys():
        var category = self.create_item(root)
        category.set_text(0,i)
        dictrecurse(dict[i], category)

func dictrecurse(o, dict):
    var check = {}
    if typeof(o) != typeof(check):
        var entry = self.create_item(dict)
        entry.set_text(0,o)
        pass
    else:
        for n in o.keys():
            var entry = self.create_item(dict)
            entry.set_text(0,n)
            dictrecurse(o[n], entry)
0 Answers
Related