add ability to add new variables to variable viewer

This commit is contained in:
Lera Elvoé 2024-01-19 12:37:21 +03:00
parent ec7acbdce8
commit 01ca8f20d7
No known key found for this signature in database
5 changed files with 144 additions and 17 deletions

View file

@ -170,6 +170,7 @@ func add_empty_deck() -> void:
inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested) inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested)
inst.dirty_state_changed.connect(_on_deck_renderer_dirty_state_changed.bind(inst)) inst.dirty_state_changed.connect(_on_deck_renderer_dirty_state_changed.bind(inst))
tab_container.set_current_tab(tab) tab_container.set_current_tab(tab)
bottom_dock.variable_viewer.enable_new_button()
## Closes the current tab in [member tab_container] ## Closes the current tab in [member tab_container]
func close_current_tab() -> void: func close_current_tab() -> void:
@ -185,8 +186,10 @@ func close_tab(tab: int) -> void:
if tab_container.get_tab_metadata(c_tab, "id") == group: if tab_container.get_tab_metadata(c_tab, "id") == group:
tab_container.close_tab(c_tab) tab_container.close_tab(c_tab)
await get_tree().process_frame await get_tree().process_frame
tab_container.close_tab(tab) tab_container.close_tab(tab)
if tab_container.get_tab_count() == 0:
bottom_dock.variable_viewer.disable_new_button()
## Opens [member file_dialog] with the mode [member FileDialog.FILE_MODE_SAVE_FILE] ## Opens [member file_dialog] with the mode [member FileDialog.FILE_MODE_SAVE_FILE]
## as well as getting a weakref to the active [Deck] ## as well as getting a weakref to the active [Deck]
@ -254,6 +257,7 @@ func open_deck_at_path(path: String) -> void:
recent_path = path.get_base_dir() recent_path = path.get_base_dir()
RendererPersistence.set_value(PERSISTENCE_NAMESPACE, "config", "recent_path", recent_path) RendererPersistence.set_value(PERSISTENCE_NAMESPACE, "config", "recent_path", recent_path)
tab_container.set_current_tab(tab) tab_container.set_current_tab(tab)
bottom_dock.variable_viewer.enable_new_button()
## Returns the current deck in the [member tab_container]. ## Returns the current deck in the [member tab_container].

View file

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6z" fill="#e0e0e0"/></svg>

After

Width:  |  Height:  |  Size: 149 B

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://drxi5ks3mqbnk"
path="res://.godot/imported/add_icon.svg-1a070ac229fd6d9079fc5a70a6dc355a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://graph_node_renderer/textures/add_icon.svg"
dest_files=["res://.godot/imported/add_icon.svg-1a070ac229fd6d9079fc5a70a6dc355a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -6,8 +6,10 @@ class_name VariableViewer
const REMOVE_ICON = preload("res://graph_node_renderer/textures/remove-icon.svg") const REMOVE_ICON = preload("res://graph_node_renderer/textures/remove-icon.svg")
@onready var new_variable_button: Button = %NewVariableButton
@onready var variable_tree: Tree = %VariableTree @onready var variable_tree: Tree = %VariableTree
@onready var types_popup: PopupMenu = %TypesPopup @onready var types_popup: PopupMenu = %TypesPopup
var root: TreeItem var root: TreeItem
var _old_name: String var _old_name: String
@ -67,9 +69,9 @@ func _ready() -> void:
_: _:
new_value = item.get_meta(&"value") new_value = item.get_meta(&"value")
item.set_meta(&"value", new_value) #item.set_meta(&"value", new_value)
if item.get_meta(&"container", -1) is int: if !item.has_meta(&"container"):
top_field_edited.emit(_old_name, new_name, new_value) top_field_edited.emit(_old_name, new_name, new_value)
else: else:
var container = item.get_meta(&"container") var container = item.get_meta(&"container")
@ -83,14 +85,23 @@ func _ready() -> void:
var key := new_name var key := new_name
(container as Dictionary).erase(_old_name) (container as Dictionary).erase(_old_name)
(container as Dictionary)[key] = new_value (container as Dictionary)[key] = new_value
set_item_value(item, new_value)
) )
variable_tree.nothing_selected.connect(variable_tree.deselect_all)
variable_tree.button_clicked.connect(_on_variable_tree_button_clicked) variable_tree.button_clicked.connect(_on_variable_tree_button_clicked)
for i in DeckType.Types.size() - 1: for i in DeckType.Types.size() - 1:
types_popup.add_radio_check_item(DeckType.type_str(i)) types_popup.add_radio_check_item(DeckType.type_str(i))
types_popup.id_pressed.connect(_on_types_popup_id_pressed) types_popup.id_pressed.connect(_on_types_popup_id_pressed)
new_variable_button.pressed.connect(_on_new_variable_button_pressed)
disable_new_button()
func rebuild_variable_tree(data: Dictionary = {}) -> void: func rebuild_variable_tree(data: Dictionary = {}) -> void:
@ -102,8 +113,8 @@ func rebuild_variable_tree(data: Dictionary = {}) -> void:
add_item(i, data[i]) add_item(i, data[i])
func add_item(item_name: String, item_value: Variant, parent: TreeItem = root, container: Variant = -1, indexed: bool = false) -> TreeItem: func add_item(item_name: String, item_value: Variant, parent: TreeItem = root, container: Variant = null, indexed: bool = false) -> TreeItem:
# the container parameter is -1 instead of null because Object#get_metadata() logs an error # the container parameter is -1 instead of null because Object#get_meta() logs an error
# if the default parameter is null # if the default parameter is null
var item := variable_tree.create_item(parent) var item := variable_tree.create_item(parent)
item.set_text(0, item_name) item.set_text(0, item_name)
@ -122,7 +133,7 @@ func add_item(item_name: String, item_value: Variant, parent: TreeItem = root, c
if item_value is Array: if item_value is Array:
for i in (item_value as Array).size(): for i in (item_value as Array).size():
add_item(str(i), item_value[i], item, item_value, true) add_item(str(i), item_value[i], item, item_value, true)
item.collapsed = true #item.collapsed = true
item.add_button(2, REMOVE_ICON) item.add_button(2, REMOVE_ICON)
return item return item
@ -131,7 +142,6 @@ func add_item(item_name: String, item_value: Variant, parent: TreeItem = root, c
func set_item_value(item: TreeItem, value: Variant) -> void: func set_item_value(item: TreeItem, value: Variant) -> void:
item.set_meta(&"value", value) item.set_meta(&"value", value)
var type: DeckType.Types = DeckType.INVERSE_GODOT_TYPES_MAP[typeof(value)] var type: DeckType.Types = DeckType.INVERSE_GODOT_TYPES_MAP[typeof(value)]
match type: match type:
DeckType.Types.NUMERIC: DeckType.Types.NUMERIC:
item.set_cell_mode(1, TreeItem.CELL_MODE_RANGE) item.set_cell_mode(1, TreeItem.CELL_MODE_RANGE)
@ -143,6 +153,34 @@ func set_item_value(item: TreeItem, value: Variant) -> void:
_: _:
item.set_text(1, str(value)) item.set_text(1, str(value))
if item.has_meta(&"container"):
var container = item.get_meta(&"container")
if container is Array:
var index := item.get_index()
container[index] = value
else:
var key := item.get_text(0)
container[key] = value
if item.get_parent() != root:
refresh_item_value(item.get_parent())
func refresh_item_value(item: TreeItem) -> void:
var value = item.get_meta(&"value")
var type: DeckType.Types = DeckType.INVERSE_GODOT_TYPES_MAP[typeof(value)]
match type:
DeckType.Types.NUMERIC:
item.set_cell_mode(1, TreeItem.CELL_MODE_RANGE)
item.set_range_config(1, -9999, 9999, 0.0001)
item.set_range(1, value)
DeckType.Types.BOOL:
item.set_cell_mode(1, TreeItem.CELL_MODE_CHECK)
item.set_checked(1, value)
_:
item.set_cell_mode(1, TreeItem.CELL_MODE_STRING)
item.set_text(1, str(value))
func _on_variable_tree_button_clicked(item: TreeItem, column: int, id: int, mouse_button_index: int) -> void: func _on_variable_tree_button_clicked(item: TreeItem, column: int, id: int, mouse_button_index: int) -> void:
if mouse_button_index != MOUSE_BUTTON_LEFT: if mouse_button_index != MOUSE_BUTTON_LEFT:
@ -150,17 +188,16 @@ func _on_variable_tree_button_clicked(item: TreeItem, column: int, id: int, mous
# we only have a delete button for now, so assume it is what's clicked # we only have a delete button for now, so assume it is what's clicked
if item.get_meta(&"container", -1) is int: if !item.has_meta(&"container"):
var key := item.get_text(0) var key := item.get_text(0)
top_field_removed.emit(key) top_field_removed.emit(key)
item.free() item.free()
else: else:
var container = item.get_meta(&"container") var container = item.get_meta(&"container")
var parent := item.get_parent()
# array # array
if item.get_meta(&"indexed", false): if item.get_meta(&"indexed", false):
var index := item.get_index() var index := item.get_index()
var parent := item.get_parent()
(container as Array).remove_at(index) (container as Array).remove_at(index)
item.free() item.free()
@ -172,6 +209,8 @@ func _on_variable_tree_button_clicked(item: TreeItem, column: int, id: int, mous
else: else:
(container as Dictionary).erase(item.get_text(0)) (container as Dictionary).erase(item.get_text(0))
item.free() item.free()
refresh_item_value(parent)
func _on_types_popup_id_pressed(id: int) -> void: func _on_types_popup_id_pressed(id: int) -> void:
@ -188,16 +227,54 @@ func _on_types_popup_id_pressed(id: int) -> void:
# simple types that can generally be converted between each other # simple types that can generally be converted between each other
var target_type: Variant.Type = DeckType.GODOT_TYPES_MAP[id] var target_type: Variant.Type = DeckType.GODOT_TYPES_MAP[id]
new_value = type_convert(current_item.get_meta(&"value"), target_type) new_value = type_convert(current_item.get_meta(&"value"), target_type)
set_item_value(current_item, new_value)
DeckType.Types.ARRAY: DeckType.Types.ARRAY:
new_value = [] new_value = []
set_item_value(current_item, new_value) for i in current_item.get_children():
i.free()
DeckType.Types.DICTIONARY: DeckType.Types.DICTIONARY:
new_value = {} new_value = {}
set_item_value(current_item, new_value) for i in current_item.get_children():
i.free()
set_item_value(current_item, new_value)
current_item.set_text(2, DeckType.type_str(id)) current_item.set_text(2, DeckType.type_str(id))
if current_item.get_meta(&"container", -1) is int: if !current_item.has_meta(&"container"):
var field_name := current_item.get_text(0) var field_name := current_item.get_text(0)
top_field_edited.emit(field_name, field_name, new_value) top_field_edited.emit(field_name, field_name, new_value)
func _on_new_variable_button_pressed() -> void:
var selected := variable_tree.get_selected()
# TODO: UX impr. - if selected is part of a container, add to that container instead
# (but if selected is a container, prioritize adding to that)
if selected == null || !(selected.get_meta(&"value") is Array || selected.get_meta(&"value") is Dictionary):
# top field
var var_name := "new_variable%s" % variable_tree.get_root().get_child_count()
var new_item := add_item(var_name, "")
top_field_edited.emit(var_name, var_name, "")
new_item.select(0)
else:
var container = selected.get_meta(&"value")
if container is Dictionary:
var var_name := "new_key%s" % (container as Dictionary).size()
var new_item := add_item(var_name, "", selected, container)
new_item.select(0)
container[var_name] = ""
else:
var index := (container as Array).size()
(container as Array).append("")
var new_item := add_item(str(index), "", selected, container, true)
new_item.select(0)
refresh_item_value(selected)
func enable_new_button() -> void:
new_variable_button.disabled = false
new_variable_button.tooltip_text = ""
func disable_new_button() -> void:
new_variable_button.disabled = true
new_variable_button.tooltip_text = "There is no deck open, so you can not create a new variable.\nOpen a deck first."

View file

@ -1,11 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://ovf5nt5pt0oj"] [gd_scene load_steps=3 format=3 uid="uid://ovf5nt5pt0oj"]
[ext_resource type="Script" path="res://graph_node_renderer/variable_viewer.gd" id="1_b5gmj"] [ext_resource type="Script" path="res://graph_node_renderer/variable_viewer.gd" id="1_b5gmj"]
[ext_resource type="Texture2D" uid="uid://drxi5ks3mqbnk" path="res://graph_node_renderer/textures/add_icon.svg" id="2_15lro"]
[node name="VariableViewer" type="VBoxContainer"] [node name="VariableViewer" type="VBoxContainer"]
anchors_preset = -1 anchors_preset = -1
anchor_right = 0.182292 anchor_right = 0.467014
anchor_bottom = 0.123457 anchor_bottom = 0.359568
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_b5gmj") script = ExtResource("1_b5gmj")
@ -27,3 +28,10 @@ hide_root = true
[node name="TypesPopup" type="PopupMenu" parent="."] [node name="TypesPopup" type="PopupMenu" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
[node name="NewVariableButton" type="Button" parent="."]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
text = "New"
icon = ExtResource("2_15lro")