Updated dialogic

This commit is contained in:
MaddoScientisto 2026-01-05 16:00:41 +01:00
commit cbb82512ee
483 changed files with 5743 additions and 2177 deletions

View file

@ -5,6 +5,9 @@ enum TreeButtons {ADD_FOLDER, ADD_VARIABLE, DUPLICATE_FOLDER, DELETE, CHANGE_TYP
@onready var editor: DialogicEditor = find_parent("VariablesEditor")
var validation_regex := RegEx.create_from_string(r"[^\w]")
var undo := UndoRedo.new()
#region INITIAL SETUP
@ -51,20 +54,21 @@ func load_info(dict:Dictionary, parent:TreeItem = null, is_new:=false) -> void:
load_info(dict[key], folder, is_new)
func add_variable_item(name:String, value:Variant, parent:TreeItem) -> TreeItem:
func add_variable_item(item_name:String, value:Variant, parent:TreeItem) -> TreeItem:
var item := create_item(parent)
item.set_meta("type", "VARIABLE")
item.set_text(0, name)
item.set_text(0, item_name)
item.set_editable(0, true)
item.set_metadata(0, name)
item.set_metadata(0, item_name)
item.set_icon(0, load(DialogicUtil.get_module_path('Variable').path_join("variable.svg")))
var folder_color: Color = parent.get_meta('color', Color.DARK_GOLDENROD)
item.set_custom_bg_color(0, folder_color.lerp(get_theme_color("background", "Editor"), 0.8))
var folder_color: Color = parent.get_meta('color', Color.TRANSPARENT)
folder_color.a *= 0.5
item.set_custom_bg_color(0, folder_color.lerp(get_theme_color("background", "Editor"), 0.5))
item.add_button(1, get_theme_icon("String", "EditorIcons"), TreeButtons.CHANGE_TYPE)
adjust_variable_type(item, DialogicUtil.get_variable_value_type(value), value)
set_variable_value(item, DialogicUtil.get_variable_value_type(value), value)
item.set_editable(2, true)
item.add_button(2, get_theme_icon("Remove", "EditorIcons"), TreeButtons.DELETE)
@ -72,27 +76,51 @@ func add_variable_item(name:String, value:Variant, parent:TreeItem) -> TreeItem:
return item
func add_folder_item(name:String, parent:TreeItem) -> TreeItem:
func add_folder_item(item_name:String, parent:TreeItem) -> TreeItem:
var item := create_item(parent)
item.set_icon(0, get_theme_icon("Folder", "EditorIcons"))
item.set_text(0, name)
item.set_meta("type", "FOLDER")
item.set_text(0, item_name)
item.set_metadata(0, item_name)
item.set_editable(0, item != get_root())
var folder_color: Color
var folder_color := Color.TRANSPARENT
if parent == null:
#folder_color = Color.TRANSPARENT#
folder_color = Color(0.33000001311302, 0.15179999172688, 0.15179999172688)
else:
folder_color = parent.get_meta('color')
folder_color.h = wrap(folder_color.h+0.15*(item.get_index()+1), 0, 1)
var parent_color: Color = parent.get_meta('color', Color(0.33000001311302, 0.15179999172688, 0.15179999172688))
folder_color = parent_color
var level := 1
var i := item
while i.get_parent():
i = i.get_parent()
level += 1
var parent_vars_count := 0
if parent:
parent_vars_count = parent.get_children().reduce(func(x, y): return x + 1 if y.get_meta("type") == "VARIABLE" else x, 0)
if level == 2:
folder_color.h = wrap(folder_color.h+0.15*(item.get_index()-parent_vars_count+1), 0, 1)
#folder_color = folder_color.lerp(get_theme_color("background", "Editor"), 0.1*level)
elif level == 3:
folder_color.h = wrap(folder_color.h-0.1*(item.get_index()-parent_vars_count+1), 0, 1)
elif level == 4:
folder_color.h = wrap(folder_color.h+0.1*(item.get_index()-parent_vars_count+1), 0, 1)
folder_color = folder_color.lerp(get_theme_color("background", "Editor"), 0.25)
item.set_custom_bg_color(0, folder_color)
item.set_custom_bg_color(1, folder_color)
item.set_custom_bg_color(2, folder_color)
item.set_meta('color', folder_color)
item.add_button(2, load(self.get_script().get_path().get_base_dir().get_base_dir() + "/add-variable.svg"), TreeButtons.ADD_VARIABLE)
item.add_button(2, load("res://addons/dialogic/Editor/Images/Pieces/add-folder.svg"), TreeButtons.ADD_FOLDER)
item.add_button(2, get_theme_icon("Duplicate", "EditorIcons"), TreeButtons.DUPLICATE_FOLDER, item == get_root())
item.add_button(2, get_theme_icon("Remove", "EditorIcons"), TreeButtons.DELETE, item == get_root())
item.set_meta("type", "FOLDER")
return item
@ -119,24 +147,27 @@ func get_variable_item_default(item:TreeItem) -> Variant:
return ""
func _on_button_clicked(item: TreeItem, column: int, id: int, mouse_button_index: int) -> void:
func _on_button_clicked(item: TreeItem, _column: int, id: int, _mouse_button_index: int) -> void:
match id:
TreeButtons.ADD_FOLDER:
var new_item := add_folder_item("Folder", item)
new_item.select(0)
new_item.set_meta("new", true)
TreeButtons.ADD_FOLDER, TreeButtons.ADD_VARIABLE:
var new_item_name := ""
if id == TreeButtons.ADD_FOLDER:
new_item_name = validate_name(item, "NewFolder")
item_add_undoable(item, new_item_name, "FOLDER", {})
else:
new_item_name = validate_name(item, "NewVar")
item_add_undoable(item, new_item_name, "VARIABLE", "")
await get_tree().process_frame
edit_selected()
TreeButtons.ADD_VARIABLE:
var new_item := add_variable_item("Var", "", item)
var new_item := get_path_item(get_item_path(item, new_item_name))
new_item.select(0)
new_item.set_meta("new", true)
await get_tree().process_frame
edit_selected()
TreeButtons.DELETE:
item.free()
item_remove_undoable(item)
TreeButtons.DUPLICATE_FOLDER:
load_info({item.get_text(0)+"(copy)":get_info(item)}, item.get_parent(), true)
var new_folder_name := validate_name(item.get_parent(), item.get_text(0))
item_add_undoable(item.get_parent(), new_folder_name, "FOLDER", get_info(item))
TreeButtons.CHANGE_TYPE:
%ChangeTypePopup.show()
%ChangeTypePopup.set_meta('item', item)
@ -146,10 +177,23 @@ func _on_button_clicked(item: TreeItem, column: int, id: int, mouse_button_index
%ChangeTypePopup/HBox.get_child(int(item.get_meta('value_type', DialogicUtil.VarTypes.STRING)-1)).set_pressed_no_signal(true)
func _on_type_pressed(pressed:bool, type:int) -> void:
func _on_type_pressed(_pressed:bool, type:int) -> void:
%ChangeTypePopup.hide()
var item: Variant = %ChangeTypePopup.get_meta('item')
adjust_variable_type(item, type, item.get_metadata(2))
# This is a MESS.
# Basically there are two ways a variable value can change:
# - by being set edited the tree
# - by the type being changed
# The problem is that to make the first undoable, we always store the value in the metadata as well.
# When we detect an edit (in _on_item_edited) we commit the do/undo actions which edit the value AGAIN.
# But here, where we change the type we now have to edit the type two times as well.
# There might be a better way but who cares...
var item: TreeItem = %ChangeTypePopup.get_meta('item')
var old_value: Variant = item.get_metadata(2)
set_variable_value(item, type, item.get_metadata(2))
var new_value: Variant = get_variable_item_default(item)
if typeof(new_value) != typeof(old_value) or new_value != old_value:
item.set_metadata(2, old_value)
item_change_value_undoable(item)
func _on_item_edited() -> void:
@ -160,19 +204,134 @@ func _on_item_edited() -> void:
0:
if item.get_text(0).is_empty():
item.set_text(0, item.get_metadata(0))
else:
validate_name(item)
if item.get_text(0) != item.get_metadata(0):
item.set_metadata(0, item.get_text(0))
report_name_changes(item)
item_rename_undoable(item)
2:
item.set_metadata(2, get_variable_item_default(item))
if get_variable_item_default(item) != item.get_metadata(2):
item_change_value_undoable(item)
"FOLDER":
report_name_changes(item)
if item.get_text(0) != item.get_metadata(0):
validate_name(item)
item_rename_undoable(item)
func adjust_variable_type(item:TreeItem, type:int, prev_value:Variant) -> void:
func item_add_undoable(parent_item:TreeItem, item_name:String, type:String, value:Variant) -> void:
undo.create_action("Add Item")
undo.add_do_method(
add_item.bind(
get_item_path(parent_item),
item_name,
type,
value)
)
undo.add_undo_method(remove_item.bind(get_item_path(parent_item, item_name)))
undo.commit_action()
func add_item(parent_path:String, text:String, type:String, value:Variant) -> void:
var parent_item := get_path_item(parent_path)
match type:
"VARIABLE":
add_variable_item(text, value, parent_item)
"FOLDER":
load_info({text:value}, parent_item, true)
func item_remove_undoable(item:TreeItem) -> void:
undo.create_action("Remove Item")
undo.add_do_method(remove_item.bind(get_item_path(item)))
undo.add_undo_method(
add_item.bind(
get_item_path(item.get_parent()),
item.get_text(0),
item.get_meta("type"),
get_variable_item_default(item) if item.get_meta("type") == "VARIABLE" else get_info(item))
)
undo.commit_action()
func remove_item(item_path:String) -> void:
get_path_item(item_path).free()
func item_rename_undoable(item:TreeItem) -> void:
var new_item_path := get_item_path(item)
var new_name := item.get_text(0)
var old_name: String = item.get_metadata(0)
item.set_text(0, item.get_metadata(0))
var old_item_path := get_item_path(item)
undo.create_action("Renamed Item")
undo.add_do_method(item_rename.bind(old_item_path, new_name, old_name))
undo.add_undo_method(item_rename.bind(new_item_path, old_name, new_name))
undo.commit_action()
func item_rename(item_path:String, new_name:String, old_name:String) -> void:
var item := get_path_item(item_path)
if item.get_text(0) == old_name:
item.set_text(0, new_name)
report_name_changes(item)
item.set_metadata(0, item.get_text(0))
func item_change_value_undoable(item:TreeItem) -> void:
var item_path := get_item_path(item)
var old_value: Variant = item.get_metadata(2)
var new_value: Variant = get_variable_item_default(item)
undo.create_action("Change Variable")
undo.add_do_method(item_change_value.bind(item_path, new_value))
undo.add_undo_method(item_change_value.bind(item_path, old_value))
undo.commit_action()
func item_change_value(item_path:String, value:Variant) -> void:
#print("SET VARIABLE VALUE ", value)
var item := get_path_item(item_path)
set_variable_value(item, DialogicUtil.get_variable_value_type(value), value)
item.set_metadata(2, value)
func validate_name(item:TreeItem, check_for_imaginary_child := "") -> String:
var item_name := item.get_text(0)
var item_parent := item.get_parent()
if check_for_imaginary_child:
item_name = check_for_imaginary_child
item_parent = item
if not item_name.is_valid_identifier():
item_name = validation_regex.sub(item_name, "_", true)
if not item_name.is_valid_identifier():
item_name = "_"+item_name
var sibling_names := []
for i in item_parent.get_children():
if i == item:
continue
sibling_names.append(i.get_text(0))
if item_name in sibling_names:
var number_regex := RegEx.create_from_string(r"(?<=\w)\d+$")
var res := number_regex.search(item_name)
var x := 2
if res:
var number := res.get_string()
x = int(number)
item_name = item_name.trim_suffix(number)
while item_name + str(x) in sibling_names:
x += 1
item_name = item_name + str(x)
if not check_for_imaginary_child:
item.set_text(0, item_name)
return item_name
func set_variable_value(item:TreeItem, type:int, prev_value:Variant) -> void:
set_variable_item_type(item, type)
match type:
DialogicUtil.VarTypes.STRING:
@ -195,13 +354,22 @@ func adjust_variable_type(item:TreeItem, type:int, prev_value:Variant) -> void:
item.set_checked(2, prev_value and true)
func _input(event):
func _input(event:InputEvent) -> void:
if get_window().has_focus() and is_visible_in_tree() and event is InputEventKey and event.is_pressed():
match event.as_text():
"Ctrl+Z":
undo.undo()
accept_event()
"Ctrl+Y", "Ctrl+Shift+Z":
undo.redo()
accept_event()
if !%ChangeTypePopup.visible:
return
if event is InputEventMouseButton and event.pressed:
if not %ChangeTypePopup.get_global_rect().has_point(get_global_mouse_position()):
%ChangeTypePopup.hide()
#endregion
@ -244,7 +412,7 @@ func get_info(item:TreeItem = null) -> Dictionary:
#region DRAG AND DROP
################################################################################
func _get_drag_data(position:Vector2) -> Variant:
func _get_drag_data(_position:Vector2) -> Variant:
drop_mode_flags = DROP_MODE_INBETWEEN
var preview := Label.new()
preview.text = " "+get_selected().get_text(0)
@ -254,17 +422,17 @@ func _get_drag_data(position:Vector2) -> Variant:
return get_selected()
func _can_drop_data(position:Vector2, data:Variant) -> bool:
func _can_drop_data(_position:Vector2, data:Variant) -> bool:
return data is TreeItem
func _drop_data(position:Vector2, item:Variant) -> void:
var to_item := get_item_at_position(position)
func _drop_data(drop_position:Vector2, item:Variant) -> void:
var to_item := get_item_at_position(drop_position)
if !to_item:
return
var drop_section := get_drop_section_at_position(position)
var drop_section := get_drop_section_at_position(drop_position)
var parent: TreeItem = null
if (drop_section == 1 and to_item.get_meta('type') == "FOLDER") or to_item == get_root():
parent = to_item
@ -311,7 +479,6 @@ func _drop_data(position:Vector2, item:Variant) -> void:
################################################################################
func report_name_changes(item:TreeItem) -> void:
match item.get_meta('type'):
"VARIABLE":
if item.get_meta("new", false):
@ -324,13 +491,39 @@ func report_name_changes(item:TreeItem) -> void:
report_name_changes(child)
func get_item_path(item:TreeItem) -> String:
var path := item.get_text(0)
while item.get_parent() != get_root():
func get_item_path(item:TreeItem, imaginary_child:String = "") -> String:
var path := ""
if item != get_root():
path = item.get_text(0)
while item != get_root() and item.get_parent() != get_root():
item = item.get_parent()
path = item.get_text(0)+"."+path
if imaginary_child:
if path:
path += "."+imaginary_child
else:
path = imaginary_child
return path
func get_path_item(path:String) -> TreeItem:
var paths := Array(path.split(".", false))
var item := get_root()
while paths:
var found := false
for i in item.get_children():
if i.get_text(0) == paths[0]:
item = i
paths.pop_front()
found = true
break
if not found:
break
if get_item_path(item) != path:
return null
return item
#endregion