ajout du plugin dialogical
This commit is contained in:
@@ -0,0 +1,545 @@
|
||||
@tool
|
||||
extends Tree
|
||||
|
||||
enum TreeButtons {ADD_FOLDER, ADD_VARIABLE, DUPLICATE_FOLDER, DELETE, CHANGE_TYPE}
|
||||
|
||||
@onready var editor: DialogicEditor = find_parent("VariablesEditor")
|
||||
|
||||
var validation_regex := RegEx.create_from_string(r"[^\w]")
|
||||
|
||||
var undo := UndoRedo.new()
|
||||
|
||||
#region INITIAL SETUP
|
||||
|
||||
func _ready() -> void:
|
||||
set_column_title(0, "Name")
|
||||
set_column_title(1, "")
|
||||
set_column_title(2, "Default Value")
|
||||
set_column_expand(1, false)
|
||||
set_column_expand_ratio(2, 2)
|
||||
set_column_title_alignment(0, 0)
|
||||
set_column_title_alignment(2, 0)
|
||||
|
||||
%ChangeTypePopup.self_modulate = get_theme_color("dark_color_3", "Editor")
|
||||
%ChangeTypePopup.theme.set_stylebox('pressed', 'Button', get_theme_stylebox("LaunchPadMovieMode", "EditorStyles"))
|
||||
%ChangeTypePopup.theme.set_stylebox('hover', 'Button', get_theme_stylebox("LaunchPadMovieMode", "EditorStyles"))
|
||||
for child in %ChangeTypePopup/HBox.get_children():
|
||||
child.toggled.connect(_on_type_pressed.bind(child.get_index()+1))
|
||||
child.icon = get_theme_icon(["String", "float", "int", "bool"][child.get_index()], "EditorIcons")
|
||||
|
||||
%RightClickMenu.set_item_icon(0, get_theme_icon("ActionCopy", "EditorIcons"))
|
||||
#endregion
|
||||
|
||||
|
||||
#region POPULATING THE TREE
|
||||
|
||||
func load_info(dict:Dictionary, parent:TreeItem = null, is_new:=false) -> void:
|
||||
if parent == null:
|
||||
clear()
|
||||
parent = add_folder_item("VAR", null)
|
||||
|
||||
var sorted_keys := dict.keys()
|
||||
sorted_keys.sort()
|
||||
for key in sorted_keys:
|
||||
if typeof(dict[key]) != TYPE_DICTIONARY:
|
||||
var item := add_variable_item(key, dict[key], parent)
|
||||
if is_new:
|
||||
item.set_meta("new", true)
|
||||
|
||||
for key in sorted_keys:
|
||||
if typeof(dict[key]) == TYPE_DICTIONARY:
|
||||
var folder := add_folder_item(key, parent)
|
||||
if is_new:
|
||||
folder.set_meta("new", true)
|
||||
load_info(dict[key], folder, is_new)
|
||||
|
||||
|
||||
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, item_name)
|
||||
item.set_editable(0, true)
|
||||
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.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)
|
||||
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)
|
||||
|
||||
item.set_meta('prev_path', get_item_path(item))
|
||||
return item
|
||||
|
||||
|
||||
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_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.TRANSPARENT
|
||||
if parent == null:
|
||||
#folder_color = Color.TRANSPARENT#
|
||||
folder_color = Color(0.33000001311302, 0.15179999172688, 0.15179999172688)
|
||||
else:
|
||||
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())
|
||||
|
||||
return item
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region EDITING THE TREE
|
||||
|
||||
func set_variable_item_type(item:TreeItem, type:int) -> void:
|
||||
item.set_meta('value_type', type)
|
||||
item.set_button(1, 0, get_theme_icon(["Variant", "String", "float", "int", "bool"][type], "EditorIcons"))
|
||||
|
||||
|
||||
func get_variable_item_default(item:TreeItem) -> Variant:
|
||||
match int(item.get_meta('value_type', DialogicUtil.VarTypes.STRING)):
|
||||
DialogicUtil.VarTypes.STRING:
|
||||
return item.get_text(2)
|
||||
DialogicUtil.VarTypes.FLOAT:
|
||||
return item.get_range(2)
|
||||
DialogicUtil.VarTypes.INT:
|
||||
return int(item.get_range(2))
|
||||
DialogicUtil.VarTypes.BOOL:
|
||||
return item.is_checked(2)
|
||||
return ""
|
||||
|
||||
|
||||
func _on_button_clicked(item: TreeItem, _column: int, id: int, _mouse_button_index: int) -> void:
|
||||
match id:
|
||||
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
|
||||
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_remove_undoable(item)
|
||||
TreeButtons.DUPLICATE_FOLDER:
|
||||
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)
|
||||
%ChangeTypePopup.position = get_local_mouse_position()+Vector2(-%ChangeTypePopup.size.x/2, 10)
|
||||
for child in %ChangeTypePopup/HBox.get_children():
|
||||
child.set_pressed_no_signal(false)
|
||||
%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:
|
||||
%ChangeTypePopup.hide()
|
||||
# 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:
|
||||
var item := get_edited()
|
||||
match item.get_meta('type'):
|
||||
"VARIABLE":
|
||||
match get_edited_column():
|
||||
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_rename_undoable(item)
|
||||
2:
|
||||
if get_variable_item_default(item) != item.get_metadata(2):
|
||||
item_change_value_undoable(item)
|
||||
"FOLDER":
|
||||
if item.get_text(0) != item.get_metadata(0):
|
||||
validate_name(item)
|
||||
item_rename_undoable(item)
|
||||
|
||||
|
||||
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:
|
||||
item.set_metadata(2, str(prev_value))
|
||||
item.set_cell_mode(2, TreeItem.CELL_MODE_STRING)
|
||||
item.set_text(2, str(prev_value))
|
||||
DialogicUtil.VarTypes.FLOAT:
|
||||
item.set_metadata(2, float(prev_value))
|
||||
item.set_cell_mode(2, TreeItem.CELL_MODE_RANGE)
|
||||
item.set_range_config(2, -9999, 9999, 0.001, false)
|
||||
item.set_range(2, float(prev_value))
|
||||
DialogicUtil.VarTypes.INT:
|
||||
item.set_metadata(2, int(prev_value))
|
||||
item.set_cell_mode(2, TreeItem.CELL_MODE_RANGE)
|
||||
item.set_range_config(2, -9999, 9999, 1, false)
|
||||
item.set_range(2, int(prev_value))
|
||||
DialogicUtil.VarTypes.BOOL:
|
||||
item.set_metadata(2, prev_value and true)
|
||||
item.set_cell_mode(2, TreeItem.CELL_MODE_CHECK)
|
||||
item.set_checked(2, prev_value and true)
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
func filter(filter_term:String, item:TreeItem = null) -> bool:
|
||||
if item == null:
|
||||
item = get_root()
|
||||
|
||||
var any := false
|
||||
for child in item.get_children():
|
||||
match child.get_meta('type'):
|
||||
"VARIABLE":
|
||||
child.visible = filter_term.is_empty() or filter_term.to_lower() in child.get_text(0).to_lower()
|
||||
|
||||
"FOLDER":
|
||||
child.visible = filter(filter_term, child)
|
||||
if child.visible:
|
||||
any = true
|
||||
return any
|
||||
|
||||
|
||||
## Parses the tree and returns a dictionary representing it.
|
||||
func get_info(item:TreeItem = null) -> Dictionary:
|
||||
if item == null:
|
||||
item = get_root()
|
||||
if item == null:
|
||||
return {}
|
||||
|
||||
var dict := {}
|
||||
|
||||
for child in item.get_children():
|
||||
match child.get_meta('type'):
|
||||
"VARIABLE":
|
||||
dict[child.get_text(0)] = child.get_metadata(2)
|
||||
"FOLDER":
|
||||
dict[child.get_text(0)] = get_info(child)
|
||||
|
||||
return dict
|
||||
|
||||
|
||||
#region DRAG AND DROP
|
||||
################################################################################
|
||||
|
||||
func _get_drag_data(_position:Vector2) -> Variant:
|
||||
drop_mode_flags = DROP_MODE_INBETWEEN
|
||||
var preview := Label.new()
|
||||
preview.text = " "+get_selected().get_text(0)
|
||||
preview.add_theme_stylebox_override('normal', get_theme_stylebox("Background", "EditorStyles"))
|
||||
set_drag_preview(preview)
|
||||
|
||||
return get_selected()
|
||||
|
||||
|
||||
func _can_drop_data(_position:Vector2, data:Variant) -> bool:
|
||||
return data is TreeItem
|
||||
|
||||
|
||||
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(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
|
||||
else:
|
||||
parent = to_item.get_parent()
|
||||
|
||||
## Test for inheritance-recursion
|
||||
var test_item := to_item
|
||||
while true:
|
||||
if test_item == item:
|
||||
return
|
||||
test_item = test_item.get_parent()
|
||||
if test_item == get_root():
|
||||
break
|
||||
|
||||
var new_item: TreeItem = null
|
||||
match item.get_meta('type'):
|
||||
"VARIABLE":
|
||||
new_item = add_variable_item(item.get_text(0), item.get_metadata(2), parent)
|
||||
new_item.set_meta('prev_path', get_item_path(item))
|
||||
if item.get_meta("new", false):
|
||||
new_item.set_meta("new", true)
|
||||
"FOLDER":
|
||||
new_item = add_folder_item(item.get_text(0), parent)
|
||||
load_info(get_info(item), new_item)
|
||||
if item.get_meta("new", false):
|
||||
new_item.set_meta("new", true)
|
||||
|
||||
# If this was dropped on a variable (or the root node)
|
||||
if to_item != parent:
|
||||
if drop_section == -1:
|
||||
new_item.move_before(to_item)
|
||||
else:
|
||||
new_item.move_after(to_item)
|
||||
|
||||
report_name_changes(new_item)
|
||||
|
||||
item.free()
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region NAME CHANGES
|
||||
################################################################################
|
||||
|
||||
func report_name_changes(item:TreeItem) -> void:
|
||||
match item.get_meta('type'):
|
||||
"VARIABLE":
|
||||
if item.get_meta("new", false):
|
||||
return
|
||||
var new_path := get_item_path(item)
|
||||
editor.variable_renamed(item.get_meta('prev_path'), new_path)
|
||||
item.set_meta('prev_path', new_path)
|
||||
"FOLDER":
|
||||
for child in item.get_children():
|
||||
report_name_changes(child)
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
func _on_gui_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_MASK_RIGHT and event.pressed:
|
||||
var item := get_item_at_position(get_local_mouse_position())
|
||||
if item and item != get_root():
|
||||
%RightClickMenu.popup_on_parent(Rect2(get_global_mouse_position(), Vector2()))
|
||||
%RightClickMenu.set_item_text(0, 'Copy "' + get_item_path(item) + '"')
|
||||
%RightClickMenu.set_meta("item", item)
|
||||
%RightClickMenu.size = Vector2()
|
||||
|
||||
|
||||
func _on_right_click_menu_id_pressed(id: int) -> void:
|
||||
if %RightClickMenu.get_meta("item", null) == null:
|
||||
return
|
||||
match id:
|
||||
0:
|
||||
DisplayServer.clipboard_set(get_item_path(%RightClickMenu.get_meta("item")))
|
||||
@@ -0,0 +1 @@
|
||||
uid://deduielq1r0r
|
||||
@@ -0,0 +1,62 @@
|
||||
@tool
|
||||
extends DialogicEditor
|
||||
|
||||
## Editor that allows
|
||||
|
||||
#region EDITOR STUFF
|
||||
|
||||
func _get_title() -> String:
|
||||
return "Variables"
|
||||
|
||||
|
||||
func _get_icon() -> Texture:
|
||||
return load(self.get_script().get_path().get_base_dir().get_base_dir() + "/variable.svg")
|
||||
|
||||
|
||||
func _register() -> void:
|
||||
editors_manager.register_simple_editor(self)
|
||||
alternative_text = "Create and edit dialogic variables and their default values"
|
||||
|
||||
|
||||
func _open(_argument:Variant = null) -> void:
|
||||
%ReferenceInfo.hide()
|
||||
%Tree.load_info(ProjectSettings.get_setting('dialogic/variables', {}))
|
||||
|
||||
|
||||
func _save() -> void:
|
||||
ProjectSettings.set_setting('dialogic/variables', %Tree.get_info())
|
||||
ProjectSettings.save()
|
||||
|
||||
|
||||
func _close() -> void:
|
||||
_save()
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
func _ready() -> void:
|
||||
%ReferenceInfo.get_node('Label').add_theme_color_override('font_color', get_theme_color("warning_color", "Editor"))
|
||||
%Search.right_icon = get_theme_icon("Search", "EditorIcons")
|
||||
|
||||
#region RENAMING
|
||||
|
||||
func variable_renamed(old_name:String, new_name:String):
|
||||
if old_name == new_name:
|
||||
return
|
||||
var count: int = editors_manager.reference_manager.get_change_count()
|
||||
editors_manager.reference_manager.add_variable_ref_change(old_name, new_name)
|
||||
var new_count: int = editors_manager.reference_manager.get_change_count()
|
||||
if count > new_count:
|
||||
%ReferenceInfo.hide()
|
||||
elif count < new_count:
|
||||
%ReferenceInfo.show()
|
||||
|
||||
func _on_reference_manager_pressed() -> void:
|
||||
editors_manager.reference_manager.open()
|
||||
%ReferenceInfo.hide()
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
func _on_search_text_changed(new_text: String) -> void:
|
||||
%Tree.filter(new_text)
|
||||
@@ -0,0 +1 @@
|
||||
uid://d1yoykg323a5p
|
||||
@@ -0,0 +1,197 @@
|
||||
[gd_scene load_steps=10 format=3 uid="uid://6tdle4y5o03o"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://d1yoykg323a5p" path="res://addons/dialogic/Modules/Variable/variables_editor/variables_editor.gd" id="2"]
|
||||
[ext_resource type="Script" uid="uid://deduielq1r0r" path="res://addons/dialogic/Modules/Variable/variables_editor/variable_tree.gd" id="2_1i17i"]
|
||||
|
||||
[sub_resource type="Image" id="Image_1bhct"]
|
||||
data = {
|
||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
||||
"format": "RGBA8",
|
||||
"height": 16,
|
||||
"mipmaps": false,
|
||||
"width": 16
|
||||
}
|
||||
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_sr7s6"]
|
||||
image = SubResource("Image_1bhct")
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7aodm"]
|
||||
content_margin_left = 2.0
|
||||
content_margin_top = 0.0
|
||||
content_margin_right = 2.0
|
||||
content_margin_bottom = 0.0
|
||||
bg_color = Color(0.44, 0.73, 0.98, 0.1)
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color(0.44, 0.73, 0.98, 1)
|
||||
corner_radius_top_left = 3
|
||||
corner_radius_top_right = 3
|
||||
corner_radius_bottom_right = 3
|
||||
corner_radius_bottom_left = 3
|
||||
corner_detail = 3
|
||||
anti_aliasing = false
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_vn21i"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ffuxp"]
|
||||
content_margin_bottom = 0.0
|
||||
bg_color = Color(0.44, 0.73, 0.98, 0.1)
|
||||
border_width_bottom = 2
|
||||
border_color = Color(0.44, 0.73, 0.98, 1)
|
||||
expand_margin_left = 4.0
|
||||
expand_margin_top = 2.0
|
||||
expand_margin_right = 4.0
|
||||
expand_margin_bottom = 4.0
|
||||
anti_aliasing = false
|
||||
|
||||
[sub_resource type="Theme" id="Theme_17j6i"]
|
||||
Button/styles/hover = SubResource("StyleBoxFlat_7aodm")
|
||||
Button/styles/normal = SubResource("StyleBoxEmpty_vn21i")
|
||||
Button/styles/pressed = SubResource("StyleBoxFlat_7aodm")
|
||||
pressed/styles/Button = SubResource("StyleBoxFlat_ffuxp")
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ncgqs"]
|
||||
bg_color = Color(1, 1, 1, 1)
|
||||
corner_radius_top_left = 3
|
||||
corner_radius_top_right = 3
|
||||
corner_radius_bottom_right = 3
|
||||
corner_radius_bottom_left = 3
|
||||
|
||||
[node name="VariablesEditor" type="HSplitContainer"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("2")
|
||||
|
||||
[node name="Editor" type="VBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="HBox" type="HBoxContainer" parent="Editor"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Title" type="Label" parent="Editor/HBox"]
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"DialogicSubTitle"
|
||||
text = "Variables"
|
||||
|
||||
[node name="Search" type="LineEdit" parent="Editor/HBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "Search"
|
||||
right_icon = SubResource("ImageTexture_sr7s6")
|
||||
|
||||
[node name="Tree" type="Tree" parent="Editor"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_type_variation = &"DialogicPanelB"
|
||||
theme_override_constants/button_margin = 4
|
||||
theme_override_constants/draw_guides = 1
|
||||
columns = 3
|
||||
column_titles_visible = true
|
||||
script = ExtResource("2_1i17i")
|
||||
|
||||
[node name="ChangeTypePopup" type="PanelContainer" parent="Editor/Tree"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
self_modulate = Color(0, 0, 0, 1)
|
||||
layout_mode = 0
|
||||
offset_left = 140.0
|
||||
offset_top = 160.0
|
||||
offset_right = 272.0
|
||||
offset_bottom = 190.0
|
||||
theme = SubResource("Theme_17j6i")
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_ncgqs")
|
||||
|
||||
[node name="HBox" type="HBoxContainer" parent="Editor/Tree/ChangeTypePopup"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="String" type="Button" parent="Editor/Tree/ChangeTypePopup/HBox"]
|
||||
custom_minimum_size = Vector2(30, 30)
|
||||
layout_mode = 2
|
||||
tooltip_text = "String (Any text)"
|
||||
toggle_mode = true
|
||||
icon = SubResource("ImageTexture_sr7s6")
|
||||
icon_alignment = 1
|
||||
|
||||
[node name="Float" type="Button" parent="Editor/Tree/ChangeTypePopup/HBox"]
|
||||
custom_minimum_size = Vector2(30, 30)
|
||||
layout_mode = 2
|
||||
tooltip_text = "Float (Number with Decimals)"
|
||||
toggle_mode = true
|
||||
icon = SubResource("ImageTexture_sr7s6")
|
||||
icon_alignment = 1
|
||||
|
||||
[node name="Int" type="Button" parent="Editor/Tree/ChangeTypePopup/HBox"]
|
||||
custom_minimum_size = Vector2(30, 30)
|
||||
layout_mode = 2
|
||||
tooltip_text = "Int (Integer)"
|
||||
toggle_mode = true
|
||||
icon = SubResource("ImageTexture_sr7s6")
|
||||
icon_alignment = 1
|
||||
|
||||
[node name="Bool" type="Button" parent="Editor/Tree/ChangeTypePopup/HBox"]
|
||||
custom_minimum_size = Vector2(30, 30)
|
||||
layout_mode = 2
|
||||
tooltip_text = "Bool (True/False flag)"
|
||||
toggle_mode = true
|
||||
icon = SubResource("ImageTexture_sr7s6")
|
||||
icon_alignment = 1
|
||||
|
||||
[node name="RightClickMenu" type="PopupMenu" parent="Editor/Tree"]
|
||||
unique_name_in_owner = true
|
||||
size = Vector2i(67, 35)
|
||||
item_count = 1
|
||||
item_0/text = "Copy"
|
||||
item_0/id = 0
|
||||
|
||||
[node name="ReferenceInfo" type="HBoxContainer" parent="Editor"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Editor/ReferenceInfo"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
text = "You've made some changes to existing variables! Use the reference manager to check if something broke."
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="ReferenceManager" type="Button" parent="Editor/ReferenceInfo"]
|
||||
layout_mode = 2
|
||||
text = "Reference Manager"
|
||||
|
||||
[node name="Info" type="VBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="HBox" type="HBoxContainer" parent="Info"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Title" type="Label" parent="Info/HBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_type_variation = &"DialogicSection"
|
||||
text = "How to use variables"
|
||||
|
||||
[node name="Documentation" type="LinkButton" parent="Info/HBox"]
|
||||
layout_mode = 2
|
||||
text = "Read the Docs"
|
||||
uri = "https://docs.dialogic.pro/variables.html"
|
||||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="Info"]
|
||||
layout_mode = 2
|
||||
text = "Variables are good way to keep track of all kinds of things during your game. Dialogic has an easy-to-use and beginner friendly variable system built in. However Dialogic allows to use outside variables (of Autoload Singletons) just as easily. You can also access the Dialogic variables from outside scripts."
|
||||
fit_content = true
|
||||
|
||||
[connection signal="text_changed" from="Editor/HBox/Search" to="." method="_on_search_text_changed"]
|
||||
[connection signal="button_clicked" from="Editor/Tree" to="Editor/Tree" method="_on_button_clicked"]
|
||||
[connection signal="gui_input" from="Editor/Tree" to="Editor/Tree" method="_on_gui_input"]
|
||||
[connection signal="item_edited" from="Editor/Tree" to="Editor/Tree" method="_on_item_edited"]
|
||||
[connection signal="id_pressed" from="Editor/Tree/RightClickMenu" to="Editor/Tree" method="_on_right_click_menu_id_pressed"]
|
||||
[connection signal="pressed" from="Editor/ReferenceInfo/ReferenceManager" to="." method="_on_reference_manager_pressed"]
|
||||
Reference in New Issue
Block a user