generated from mstar/godot-template
185 lines
6.3 KiB
GDScript
185 lines
6.3 KiB
GDScript
@tool
|
|
extends VBoxContainer
|
|
const Utils = preload("../../scripts/Utils.gd")
|
|
const ConditionEditor = preload("../condition_editors/ConditionEditor.tscn")
|
|
const BoolConditionEditor = preload("../condition_editors/BoolConditionEditor.tscn")
|
|
const IntegerConditionEditor = preload("../condition_editors/IntegerConditionEditor.tscn")
|
|
const FloatConditionEditor = preload("../condition_editors/FloatConditionEditor.tscn")
|
|
const StringConditionEditor = preload("../condition_editors/StringConditionEditor.tscn")
|
|
|
|
@onready var header = $HeaderContainer/Header
|
|
@onready var title = $HeaderContainer/Header/Title
|
|
@onready var title_icon = $HeaderContainer/Header/Title/Icon
|
|
@onready var from = $HeaderContainer/Header/Title/From
|
|
@onready var to = $HeaderContainer/Header/Title/To
|
|
@onready var condition_count_icon = $HeaderContainer/Header/ConditionCount/Icon
|
|
@onready var condition_count_label = $HeaderContainer/Header/ConditionCount/Label
|
|
@onready var priority_icon = $HeaderContainer/Header/Priority/Icon
|
|
@onready var priority_spinbox = $HeaderContainer/Header/Priority/SpinBox
|
|
@onready var add = $HeaderContainer/Header/HBoxContainer/Add
|
|
@onready var add_popup_menu = $HeaderContainer/Header/HBoxContainer/Add/PopupMenu
|
|
@onready var content_container = $MarginContainer
|
|
@onready var condition_list = $MarginContainer/Conditions
|
|
|
|
var undo_redo
|
|
|
|
var transition:
|
|
set = set_transition
|
|
|
|
var _to_free
|
|
|
|
|
|
func _init():
|
|
_to_free = []
|
|
|
|
func _ready():
|
|
header.gui_input.connect(_on_header_gui_input)
|
|
priority_spinbox.value_changed.connect(_on_priority_spinbox_value_changed)
|
|
add.pressed.connect(_on_add_pressed)
|
|
add_popup_menu.index_pressed.connect(_on_add_popup_menu_index_pressed)
|
|
|
|
condition_count_icon.texture = get_theme_icon("MirrorX", "EditorIcons")
|
|
priority_icon.texture = get_theme_icon("AnimationTrackGroup", "EditorIcons")
|
|
|
|
func _exit_tree():
|
|
free_node_from_undo_redo() # Managed by EditorInspector
|
|
|
|
func _on_header_gui_input(event):
|
|
if event is InputEventMouseButton:
|
|
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
|
toggle_conditions()
|
|
|
|
func _on_priority_spinbox_value_changed(val: int) -> void:
|
|
set_priority(val)
|
|
|
|
func _on_add_pressed():
|
|
Utils.popup_on_target(add_popup_menu, add)
|
|
|
|
func _on_add_popup_menu_index_pressed(index):
|
|
## Handle condition name duplication (4.x changed how duplicates are
|
|
## automatically handled and gave a random index instead of a progressive one)
|
|
var default_new_condition_name = "Param"
|
|
var condition_dup_index = 0
|
|
var new_name = default_new_condition_name
|
|
for condition_editor in condition_list.get_children():
|
|
var condition_name = condition_editor.condition.name
|
|
if (condition_name == new_name):
|
|
condition_dup_index += 1
|
|
new_name = "%s%s" % [default_new_condition_name, condition_dup_index]
|
|
var condition
|
|
match index:
|
|
0: # Trigger
|
|
condition = Condition.new(new_name)
|
|
1: # Boolean
|
|
condition = BooleanCondition.new(new_name)
|
|
2: # Integer
|
|
condition = IntegerCondition.new(new_name)
|
|
3: # Float
|
|
condition = FloatCondition.new(new_name)
|
|
4: # String
|
|
condition = StringCondition.new(new_name)
|
|
_:
|
|
push_error("Unexpected index(%d) from PopupMenu" % index)
|
|
var editor = create_condition_editor(condition)
|
|
add_condition_editor_action(editor, condition)
|
|
|
|
func _on_ConditionEditorRemove_pressed(editor):
|
|
remove_condition_editor_action(editor)
|
|
|
|
func _on_transition_changed(new_transition):
|
|
if not new_transition:
|
|
return
|
|
|
|
for condition in transition.conditions.values():
|
|
var editor = create_condition_editor(condition)
|
|
add_condition_editor(editor, condition)
|
|
update_title()
|
|
update_condition_count()
|
|
update_priority_spinbox_value()
|
|
|
|
func _on_condition_editor_added(editor):
|
|
editor.undo_redo = undo_redo
|
|
if not editor.remove.pressed.is_connected(_on_ConditionEditorRemove_pressed):
|
|
editor.remove.pressed.connect(_on_ConditionEditorRemove_pressed.bind(editor))
|
|
transition.add_condition(editor.condition)
|
|
update_condition_count()
|
|
|
|
func add_condition_editor(editor, condition):
|
|
condition_list.add_child(editor)
|
|
editor.condition = condition # Must be assigned after enter tree, as assignment would trigger ui code
|
|
_on_condition_editor_added(editor)
|
|
|
|
func remove_condition_editor(editor):
|
|
transition.remove_condition(editor.condition.name)
|
|
condition_list.remove_child(editor)
|
|
_to_free.append(editor) # Freeing immediately after removal will break undo/redo
|
|
update_condition_count()
|
|
|
|
func update_title():
|
|
from.text = transition.from
|
|
to.text = transition.to
|
|
|
|
func update_condition_count():
|
|
var count = transition.conditions.size()
|
|
condition_count_label.text = str(count)
|
|
if count == 0:
|
|
hide_conditions()
|
|
else:
|
|
show_conditions()
|
|
|
|
func update_priority_spinbox_value():
|
|
priority_spinbox.value = transition.priority
|
|
priority_spinbox.apply()
|
|
|
|
func set_priority(value):
|
|
transition.priority = value
|
|
|
|
func show_conditions():
|
|
content_container.visible = true
|
|
|
|
func hide_conditions():
|
|
content_container.visible = false
|
|
|
|
func toggle_conditions():
|
|
content_container.visible = !content_container.visible
|
|
|
|
func create_condition_editor(condition):
|
|
var editor
|
|
if condition is BooleanCondition:
|
|
editor = BoolConditionEditor.instantiate()
|
|
elif condition is IntegerCondition:
|
|
editor = IntegerConditionEditor.instantiate()
|
|
elif condition is FloatCondition:
|
|
editor = FloatConditionEditor.instantiate()
|
|
elif condition is StringCondition:
|
|
editor = StringConditionEditor.instantiate()
|
|
else:
|
|
editor = ConditionEditor.instantiate()
|
|
return editor
|
|
|
|
func add_condition_editor_action(editor, condition):
|
|
undo_redo.create_action("Add Transition Condition")
|
|
undo_redo.add_do_method(self, "add_condition_editor", editor, condition)
|
|
undo_redo.add_undo_method(self, "remove_condition_editor", editor)
|
|
undo_redo.commit_action()
|
|
|
|
func remove_condition_editor_action(editor):
|
|
undo_redo.create_action("Remove Transition Condition")
|
|
undo_redo.add_do_method(self, "remove_condition_editor", editor)
|
|
undo_redo.add_undo_method(self, "add_condition_editor", editor, editor.condition)
|
|
undo_redo.commit_action()
|
|
|
|
func set_transition(t):
|
|
if transition != t:
|
|
transition = t
|
|
_on_transition_changed(t)
|
|
|
|
# Free nodes cached in UndoRedo stack
|
|
func free_node_from_undo_redo():
|
|
for node in _to_free:
|
|
if is_instance_valid(node):
|
|
var history_id = undo_redo.get_object_history_id(node)
|
|
undo_redo.get_history_undo_redo(history_id).clear_history(false) # TODO: Should be handled by plugin.gd (Temporary solution as only TransitionEditor support undo/redo)
|
|
node.queue_free()
|
|
|
|
_to_free.clear()
|