diff --git a/addons/dialogic/Editor/Events/BranchEnd.gd b/addons/dialogic/Editor/Events/BranchEnd.gd index 81222e92e..21aa87cba 100644 --- a/addons/dialogic/Editor/Events/BranchEnd.gd +++ b/addons/dialogic/Editor/Events/BranchEnd.gd @@ -1,27 +1,30 @@ @tool extends Control - var resource var parent_node +var end_control :Control + ### the indent size -var indent_size = 45 +var indent_size = 15 var current_indent_level = 1 func _ready(): + $Icon.icon = get_theme_icon("GuiSpinboxUpdown", "EditorIcons") parent_node_changed() - $ConditionButtons/Elif.pressed.connect(add_elif) - $ConditionButtons/Else.pressed.connect(add_else) + $Spacer.custom_minimum_size.x = 300*DialogicUtil.get_editor_scale() + func visual_select(): - modulate = get_theme_color("accent_color", "Editor") + modulate = get_theme_color("warning_color", "Editor") func visual_deselect(): modulate = Color(1,1,1,1) + func highlight(): - modulate = get_theme_color("warning_color", "Editor") + modulate = parent_node.resource.event_color.lightened(0.5) func unhighlight(): @@ -36,27 +39,14 @@ func set_indent(indent: int): func parent_node_changed(): if parent_node: - if parent_node.resource is DialogicChoiceEvent: - $Label.text = "End of choice '"+parent_node.resource.Text+"'" - $ConditionButtons.hide() - elif parent_node.resource is DialogicConditionEvent: - if parent_node.resource.ConditionType != DialogicConditionEvent.ConditionTypes.ELSE: - $ConditionButtons.show() - $Label.text = "End of condition '"+parent_node.resource.Condition+"'" - else: - $ConditionButtons.hide() - $Label.text = "End of else" - - -func add_elif(): - var timeline = find_parent('TimelineEditor') - if timeline: - timeline.add_condition_pressed(get_index()+1, DialogicConditionEvent.ConditionTypes.ELIF) - timeline.indent_events() - -func add_else(): - var timeline = find_parent('TimelineEditor') - if timeline: - timeline.add_condition_pressed(get_index()+1, DialogicConditionEvent.ConditionTypes.ELSE) - timeline.indent_events() + if end_control and end_control.has_method('refresh'): + end_control.refresh() + +func add_end_control(control:Control): + add_child(control) + if "parent_resource" in control: + control.parent_resource = parent_node.resource + if control.has_method('refresh'): + control.refresh() + end_control = control diff --git a/addons/dialogic/Editor/Events/BranchEnd.tscn b/addons/dialogic/Editor/Events/BranchEnd.tscn index ef8d30072..93a44a2ca 100644 --- a/addons/dialogic/Editor/Events/BranchEnd.tscn +++ b/addons/dialogic/Editor/Events/BranchEnd.tscn @@ -1,75 +1,42 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 format=3 uid="uid://de13fdeebrkcb"] -[ext_resource path="res://addons/dialogic/Editor/Events/BranchEnd.gd" type="Script" id=1] +[ext_resource type="Script" path="res://addons/dialogic/Editor/Events/BranchEnd.gd" id="1"] -[sub_resource type="StyleBoxLine" id=1] -content_margin_left = 0.0 -content_margin_right = 0.0 -content_margin_top = 0.0 -content_margin_bottom = 0.0 -color = Color( 1, 1, 1, 1 ) -grow_begin = -5.0 -grow_end = -5.0 -thickness = 2 +[sub_resource type="Image" id="Image_cje5s"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 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, 93, 93, 131, 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, 93, 93, 131, 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, 93, 93, 131, 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, 252, 255, 93, 93, 252, 255, 93, 93, 252, 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, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 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, 93, 93, 55, 255, 97, 97, 58, 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, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 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, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 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, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 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_sojvl"] +image = SubResource("Image_cje5s") [node name="EndBranch" type="HBoxContainer"] anchor_right = 1.0 -margin_bottom = 40.0 -rect_min_size = Vector2( 0, 40 ) +offset_bottom = 48.0 mouse_filter = 0 -script = ExtResource( 1 ) +script = ExtResource("1") [node name="Indent" type="Control" parent="."] -margin_bottom = 40.0 - -[node name="Space" type="Control" parent="."] -margin_left = 4.0 -margin_right = 34.0 -margin_bottom = 40.0 -rect_min_size = Vector2( 30, 0 ) - -[node name="PanelContainer2" type="PanelContainer" parent="."] -margin_left = 38.0 -margin_top = 20.0 -margin_right = 212.0 -margin_bottom = 20.0 -size_flags_horizontal = 7 -size_flags_vertical = 4 -size_flags_stretch_ratio = 0.3 -custom_styles/panel = SubResource( 1 ) - -[node name="Label" type="Label" parent="."] -margin_left = 216.0 -margin_top = 13.0 -margin_right = 303.0 -margin_bottom = 27.0 -text = "End of Branch" - -[node name="ConditionButtons" type="HBoxContainer" parent="."] -margin_left = 307.0 -margin_right = 438.0 -margin_bottom = 40.0 - -[node name="Elif" type="Button" parent="ConditionButtons"] -margin_top = 10.0 -margin_right = 60.0 -margin_bottom = 30.0 -size_flags_vertical = 4 -text = "Add Elif" - -[node name="Else" type="Button" parent="ConditionButtons"] -margin_left = 64.0 -margin_top = 10.0 -margin_right = 131.0 -margin_bottom = 30.0 -size_flags_vertical = 4 -text = "Add Else" - -[node name="PanelContainer" type="PanelContainer" parent="."] -margin_left = 442.0 -margin_top = 20.0 -margin_right = 1024.0 -margin_bottom = 20.0 -size_flags_horizontal = 7 +offset_bottom = 48.0 + +[node name="Spacer" type="Control" parent="."] +custom_minimum_size = Vector2(300, 0) +offset_left = 4.0 +offset_right = 304.0 +offset_bottom = 48.0 + +[node name="Icon" type="Button" parent="."] +unique_name_in_owner = true +custom_minimum_size = Vector2(31, 0) +offset_left = 308.0 +offset_top = 12.0 +offset_right = 339.0 +offset_bottom = 36.0 size_flags_vertical = 4 -custom_styles/panel = SubResource( 1 ) +mouse_filter = 1 +icon = SubResource("ImageTexture_sojvl") +flat = true diff --git a/addons/dialogic/Editor/Events/EventNode/EventNode.gd b/addons/dialogic/Editor/Events/EventNode/EventNode.gd index 72c36b839..7ad857511 100644 --- a/addons/dialogic/Editor/Events/EventNode/EventNode.gd +++ b/addons/dialogic/Editor/Events/EventNode/EventNode.gd @@ -35,7 +35,7 @@ var collapsed = false var editor_reference ### the indent size -var indent_size = 45 +var indent_size = 15 var current_indent_level = 1 # Setting this to true will ignore the event while saving @@ -52,10 +52,12 @@ func visual_select(): func visual_deselect(): - if selected_style: - selected_style.hide() + selected_style.hide() +func is_selected() -> bool: + return selected_style.visible + # called by the timeline before adding it to the tree func load_data(data): resource = data @@ -147,6 +149,7 @@ func focus(): func toggle_collapse(toggled): collapsed = toggled + %CollapsedBody.visible = toggled var timeline_editor = find_parent('TimelineEditor') if (timeline_editor != null): # @todo select item and clear selection is marked as "private" in TimelineEditor.gd @@ -304,7 +307,7 @@ func _ready(): _set_event_icon(resource.get_icon()) %IconPanel.self_modulate = resource.event_color - %ExpandButton.button_pressed = resource.expand_by_default + _on_ExpandButton_toggled(resource.expand_by_default) set_focus_mode(1) # Allowing this node to grab focus @@ -320,8 +323,10 @@ func _ready(): func _on_ExpandButton_toggled(button_pressed): + %ExpandButton.button_pressed = button_pressed expanded = button_pressed body_container.visible = button_pressed + get_parent().get_parent().update() func _on_EventNode_gui_input(event): @@ -330,7 +335,7 @@ func _on_EventNode_gui_input(event): if event is InputEventMouseButton and event.is_pressed() and event.button_index == 1: grab_focus() # Grab focus to avoid copy pasting text or events if event.double_click: - expanded = !expanded + _on_ExpandButton_toggled(!expanded) # For opening the context menu if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed: diff --git a/addons/dialogic/Editor/Events/EventNode/EventNode.tscn b/addons/dialogic/Editor/Events/EventNode/EventNode.tscn index a519adba1..16af6201e 100644 --- a/addons/dialogic/Editor/Events/EventNode/EventNode.tscn +++ b/addons/dialogic/Editor/Events/EventNode/EventNode.tscn @@ -13,7 +13,7 @@ corner_radius_top_right = 5 corner_radius_bottom_right = 5 corner_radius_bottom_left = 5 -[sub_resource type="Image" id="Image_xrgmo"] +[sub_resource type="Image" id="Image_vgcnl"] data = { "data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 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, 93, 93, 131, 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, 93, 93, 131, 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, 93, 93, 131, 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, 252, 255, 93, 93, 252, 255, 93, 93, 252, 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, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 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, 93, 93, 55, 255, 97, 97, 58, 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, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 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, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 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, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 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", @@ -22,14 +22,14 @@ data = { "width": 16 } -[sub_resource type="ImageTexture" id="ImageTexture_axbsf"] -image = SubResource("Image_xrgmo") +[sub_resource type="ImageTexture" id="ImageTexture_mjdnk"] +image = SubResource("Image_vgcnl") -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_04k4j"] +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_qdmxb"] [sub_resource type="Theme" id="Theme_g6f7f"] PopupMenu/colors/font_color_hover = Color(0.44, 0.73, 0.98, 1) -PopupMenu/styles/hover = SubResource("StyleBoxEmpty_04k4j") +PopupMenu/styles/hover = SubResource("StyleBoxEmpty_qdmxb") PopupMenu/styles/panel = ExtResource("5_wntx6") [node name="EventNode" type="HBoxContainer"] @@ -114,7 +114,7 @@ and [End branch] events. [Choice] [...] [End branch]" -texture = SubResource("ImageTexture_axbsf") +texture = SubResource("ImageTexture_mjdnk") stretch_mode = 5 [node name="TitleLabel" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer/Header"] @@ -145,16 +145,30 @@ offset_left = 993.0 offset_right = 1017.0 offset_bottom = 24.0 toggle_mode = true -icon = SubResource("ImageTexture_axbsf") +icon = SubResource("ImageTexture_mjdnk") flat = true [node name="CollapseButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer/Header"] unique_name_in_owner = true visible = false toggle_mode = true -icon = SubResource("ImageTexture_axbsf") +icon = SubResource("ImageTexture_mjdnk") flat = true +[node name="CollapsedBody" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"] +unique_name_in_owner = true +visible = false +offset_top = 28.0 +offset_right = 1017.0 +offset_bottom = 54.0 + +[node name="Label" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer/CollapsedBody"] +offset_right = 1017.0 +offset_bottom = 26.0 +size_flags_horizontal = 3 +text = "Contains Events (currently hidden)" +horizontal_alignment = 1 + [node name="Body" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"] unique_name_in_owner = true offset_top = 28.0 @@ -164,10 +178,12 @@ size_flags_horizontal = 3 [node name="BodySpacing" type="Control" parent="PanelContainer/MarginContainer/VBoxContainer/Body"] unique_name_in_owner = true +custom_minimum_size = Vector2(10, 0) +offset_right = 10.0 [node name="BodyContent" type="HFlowContainer" parent="PanelContainer/MarginContainer/VBoxContainer/Body"] unique_name_in_owner = true -offset_left = 4.0 +offset_left = 14.0 offset_right = 1017.0 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -177,22 +193,22 @@ mouse_filter = 2 theme = SubResource("Theme_g6f7f") item_count = 6 item_0/text = "Documentation" -item_0/icon = SubResource("ImageTexture_axbsf") +item_0/icon = SubResource("ImageTexture_mjdnk") item_0/id = 0 item_1/text = "" item_1/id = -1 item_1/separator = true item_2/text = "Move up" -item_2/icon = SubResource("ImageTexture_axbsf") +item_2/icon = SubResource("ImageTexture_mjdnk") item_2/id = 2 item_3/text = "Move down" -item_3/icon = SubResource("ImageTexture_axbsf") +item_3/icon = SubResource("ImageTexture_mjdnk") item_3/id = 3 item_4/text = "" item_4/id = -1 item_4/separator = true item_5/text = "Delete" -item_5/icon = SubResource("ImageTexture_axbsf") +item_5/icon = SubResource("ImageTexture_mjdnk") item_5/id = 5 script = ExtResource("8") diff --git a/addons/dialogic/Editor/Events/Fields/Array.gd b/addons/dialogic/Editor/Events/Fields/Array.gd index 4c778478e..9fa09a414 100644 --- a/addons/dialogic/Editor/Events/Fields/Array.gd +++ b/addons/dialogic/Editor/Events/Fields/Array.gd @@ -12,7 +12,7 @@ func set_value(value:Array): child.queue_free() for item in value: - var x = load(ArrayValue).instanciate() + var x = load(ArrayValue).instantiate() %Values.add_child(x) x.set_value(item) x.value_changed.connect(recalculate_values) diff --git a/addons/dialogic/Editor/Events/Fields/Array.tscn b/addons/dialogic/Editor/Events/Fields/Array.tscn index 05f7f433a..8ef15fe96 100644 --- a/addons/dialogic/Editor/Events/Fields/Array.tscn +++ b/addons/dialogic/Editor/Events/Fields/Array.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://btmy7ageqpyq1"] -[ext_resource type="PackedScene" path="res://addons/dialogic/Editor/Events/Fields/ArrayValue.tscn" id="1"] +[ext_resource type="PackedScene" uid="uid://ch4j2lesn1sis" path="res://addons/dialogic/Editor/Events/Fields/ArrayValue.tscn" id="1"] [ext_resource type="Script" path="res://addons/dialogic/Editor/Events/Fields/Array.gd" id="2"] [node name="Array" type="VBoxContainer"] diff --git a/addons/dialogic/Editor/Events/Fields/MultilineText.tscn b/addons/dialogic/Editor/Events/Fields/MultilineText.tscn index 4bba361cc..cc728bf5c 100644 --- a/addons/dialogic/Editor/Events/Fields/MultilineText.tscn +++ b/addons/dialogic/Editor/Events/Fields/MultilineText.tscn @@ -1,56 +1,36 @@ -[gd_scene load_steps=4 format=3 uid="uid://dyp7m2nvab1aj"] +[gd_scene load_steps=3 format=3 uid="uid://dyp7m2nvab1aj"] [ext_resource type="Script" path="res://addons/dialogic/Editor/Events/Fields/MultilineText.gd" id="1"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bofjx"] content_margin_left = 16.0 content_margin_top = 14.0 -bg_color = Color(0.27451, 0.27451, 0.27451, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.648438, 0.648438, 0.648438, 1) -corner_radius_top_left = 8 +bg_color = Color(0.09, 0.09, 0.09, 0.588235) corner_radius_top_right = 8 corner_radius_bottom_right = 8 -corner_radius_bottom_left = 8 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lyutj"] -content_margin_left = 16.0 -content_margin_top = 14.0 -bg_color = Color(0.27451, 0.27451, 0.27451, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0, 0.470588, 0.823529, 1) -corner_radius_top_left = 8 -corner_radius_top_right = 8 -corner_radius_bottom_right = 8 -corner_radius_bottom_left = 8 [node name="MultilineText" type="HBoxContainer"] anchor_right = 1.0 anchor_bottom = 1.0 size_flags_horizontal = 3 +theme_override_constants/separation = 0 script = ExtResource("1") [node name="LeftText" type="Label" parent="."] +visible = false offset_top = 288.0 offset_right = 1.0 offset_bottom = 311.0 [node name="TextEdit" type="TextEdit" parent="."] -offset_left = 5.0 -offset_right = 22.0 +offset_right = 1024.0 offset_bottom = 600.0 -size_flags_horizontal = 2 +size_flags_horizontal = 3 size_flags_vertical = 3 theme_override_styles/normal = SubResource("StyleBoxFlat_bofjx") -theme_override_styles/focus = SubResource("StyleBoxFlat_lyutj") [node name="RightText" type="Label" parent="."] +visible = false offset_left = 1023.0 offset_top = 288.0 offset_right = 1024.0 diff --git a/addons/dialogic/Editor/TimelineEditor/TimelineArea.gd b/addons/dialogic/Editor/TimelineEditor/TimelineArea.gd index c7f43be90..9574d8d0b 100644 --- a/addons/dialogic/Editor/TimelineEditor/TimelineArea.gd +++ b/addons/dialogic/Editor/TimelineEditor/TimelineArea.gd @@ -73,3 +73,49 @@ func _on_gui_input(event): if (_last_event_button_drop_attempt != ''): _drop_data(Vector2.ZERO, { "source": "EventButton", "event_id": _last_event_button_drop_attempt} ) _is_drag_receiving = false + +func _draw(): + var _scale = DialogicUtil.get_editor_scale() + var line_width = 5 * _scale + var horizontal_line_length = 300*_scale + var color_multiplier = Color(1,1,1,0.5) + var selected_color_multiplier = Color(1,1,1,1) + for idx in range($TimeLine.get_child_count()): + var event = $TimeLine.get_child(idx) + + if not "resource" in event: + continue + + if not event.visible: + continue + + if !event.resource is DialogicEndBranchEvent: + var icon_panel_height = 32*_scale + var rect_position = event.get_node('%IconPanel').global_position+Vector2(0,1)*event.get_node('%IconPanel').size+Vector2(0,-4) + var color = event.resource.event_color + if event.is_selected(): + color *= selected_color_multiplier + else: + color *= color_multiplier + if idx < $TimeLine.get_child_count()-1 and event.current_indent_level < $TimeLine.get_child(idx+1).current_indent_level: + var end_node = event.end_node + var sub_idx = idx + if !end_node: + while sub_idx < $TimeLine.get_child_count()-1: + sub_idx += 1 + if $TimeLine.get_child(sub_idx).current_indent_level == event.current_indent_level: + end_node = $TimeLine.get_child(sub_idx-1) + break + + if end_node != null: + var rect_size = Vector2(line_width, end_node.global_position.y+end_node.size.y-rect_position.y) + if end_node.resource is DialogicEndBranchEvent and event.resource.can_contain_events: + rect_size = Vector2(line_width, end_node.global_position.y+end_node.size.y/2-rect_position.y) + draw_rect(Rect2(rect_position-global_position, rect_size), color) + draw_rect(Rect2(Vector2(event.get_node('%IconPanel').global_position.x+line_width, rect_position.y+rect_size.y-line_width)-global_position, Vector2(horizontal_line_length, line_width)), color) + + else: + draw_rect(Rect2(rect_position-global_position, Vector2(line_width, $TimeLine.get_child(-3).position.y+$TimeLine.get_child(-3).size.y)), color) + + elif event.expanded: + draw_rect(Rect2(rect_position-global_position, Vector2(line_width, event.size.y-event.get_node('%IconPanel').size.y-8*_scale)), color) diff --git a/addons/dialogic/Editor/TimelineEditor/TimelineEditor.gd b/addons/dialogic/Editor/TimelineEditor/TimelineEditor.gd index f78eaed7c..fab95e7a5 100644 --- a/addons/dialogic/Editor/TimelineEditor/TimelineEditor.gd +++ b/addons/dialogic/Editor/TimelineEditor/TimelineEditor.gd @@ -134,8 +134,8 @@ func _on_event_block_gui_input(event, item: Node): TimelineUndoRedo.add_do_method(self, "move_block_to_index", move_start_position, to_position) TimelineUndoRedo.add_undo_method(self, "move_block_to_index", to_position, move_start_position) - # in case a choice or condition was moved BELOW it's end node the end_node is moved as well!!! - if moving_piece.resource is DialogicChoiceEvent or moving_piece.resource is DialogicConditionEvent: + # in case a something like a choice or condition was moved BELOW it's end node the end_node is moved as well!!! + if moving_piece.resource.can_contain_events: if moving_piece.end_node.get_index() < to_position: TimelineUndoRedo.add_do_method(self, "move_block_to_index", moving_piece.end_node.get_index(), to_position) TimelineUndoRedo.add_undo_method(self, "move_block_to_index", to_position+1, moving_piece.end_node.get_index()) @@ -177,42 +177,19 @@ func _input(event): if (event is InputEventKey and event is InputEventWithModifiers and is_visible_in_tree()): # CTRL Z # UNDO - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_Z - and event.echo == false - ): + if is_event_pressed(event, KEY_Z, false, false, true): TimelineUndoRedo.undo() indent_events() get_viewport().set_input_as_handled() if (event is InputEventKey and event is InputEventWithModifiers and is_visible_in_tree()): # CTRL +SHIFT+ Z # REDO - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == true - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_Z - and event.echo == false - ) or (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_Y - and event.echo == false): + if is_event_pressed(event, KEY_Z, false, true, true) or is_event_pressed(event, KEY_Y, false, false, true): TimelineUndoRedo.redo() indent_events() get_viewport().set_input_as_handled() if (event is InputEventKey and event is InputEventWithModifiers and is_visible_in_tree()): # UP - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == false or event.command_pressed == false) - and event.keycode == KEY_UP - and event.echo == false - ): + if is_event_pressed(event, KEY_UP, false, false, false): # select previous if (len(selected_items) == 1): var prev = max(0, selected_items[0].get_index() - 1) @@ -224,13 +201,7 @@ func _input(event): # DOWN - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == false or event.command_pressed == false) - and event.keycode == KEY_DOWN - and event.echo == false - ): + if is_event_pressed(event, KEY_DOWN, false, false, false): # select next if (len(selected_items) == 1): var next = min(timeline.get_child_count() - 1, selected_items[0].get_index() + 1) @@ -241,13 +212,7 @@ func _input(event): get_viewport().set_input_as_handled() # DELETE - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == false or event.command_pressed == false) - and event.keycode == KEY_DELETE - and event.echo == false - ): + if is_event_pressed(event, KEY_DELETE, false, false, false): if (len(selected_items) != 0): var events_indexed = get_events_indexed(selected_items) TimelineUndoRedo.create_action("[D] Deleting "+str(len(selected_items))+" event(s).") @@ -257,67 +222,37 @@ func _input(event): get_viewport().set_input_as_handled() # CTRL T - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_T - and event.echo == false - ): + if is_event_pressed(event, KEY_T, false, false, true): var at_index = -1 if selected_items: at_index = selected_items[-1].get_index()+1 else: at_index = timeline.get_child_count() - TimelineUndoRedo.create_action("[D] Add Text event.") - TimelineUndoRedo.add_do_method(self, "create_event", "dialogic_001", {'no-data': true}, true, at_index, true) - TimelineUndoRedo.add_undo_method(self, "remove_events_at_index", at_index, 1) - TimelineUndoRedo.commit_action() +# TimelineUndoRedo.create_action("[D] Add Text event.") +# TimelineUndoRedo.add_do_method(self, "create_event", "dialogic_001", {'no-data': true}, true, at_index, true) +# TimelineUndoRedo.add_undo_method(self, "remove_events_at_index", at_index, 1) +# TimelineUndoRedo.commit_action() get_viewport().set_input_as_handled() # CTRL A - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_A - and event.echo == false - ): + if is_event_pressed(event, KEY_A, false, false, true): if (len(selected_items) != 0): select_all_items() get_viewport().set_input_as_handled() # CTRL SHIFT A - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == true - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_A - and event.echo == false - ): + if is_event_pressed(event, KEY_A, false, true, true): if (len(selected_items) != 0): deselect_all_items() get_viewport().set_input_as_handled() # CTRL C - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_C - and event.echo == false - ): + if is_event_pressed(event, KEY_V, false, false, true): copy_selected_events() get_viewport().set_input_as_handled() # CTRL V - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_V - and event.echo == false - ): + if is_event_pressed(event, KEY_V, false, false, true): var events_list = paste_check() var paste_position = -1 if selected_items: @@ -332,13 +267,7 @@ func _input(event): get_viewport().set_input_as_handled() # CTRL X - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_X - and event.echo == false - ): + if is_event_pressed(event, KEY_X, false, false, true): var events_indexed = get_events_indexed(selected_items) TimelineUndoRedo.create_action("[D] Cut "+str(len(selected_items))+" event(s).") TimelineUndoRedo.add_do_method(self, "cut_events_indexed", events_indexed) @@ -347,14 +276,7 @@ func _input(event): get_viewport().set_input_as_handled() # CTRL D - if (event.pressed - and event.alt_pressed == false - and event.shift_pressed == false - and (event.ctrl_pressed == true or event.command_pressed == true) - and event.keycode == KEY_D - and event.echo == false - ): - + if is_event_pressed(event, KEY_D, false, false, true): if len(selected_items) > 0: var events = get_events_indexed(selected_items).values() var at_index = selected_items[-1].get_index() @@ -367,13 +289,7 @@ func _input(event): func _unhandled_key_input(event): if (event is InputEventWithModifiers): # ALT UP - if (event.pressed - and event.alt_pressed == true - and event.shift_pressed == false - and (event.ctrl_pressed == false or event.command_pressed == false) - and event.keycode == KEY_UP - and event.echo == false - ): + if is_event_pressed(event, KEY_UP, true, false, false): # move selected up if (len(selected_items) == 1): move_block(selected_items[0], "up") @@ -381,19 +297,20 @@ func _unhandled_key_input(event): get_viewport().set_input_as_handled() # ALT DOWN - if (event.pressed - and event.alt_pressed == true - and event.shift_pressed == false - and (event.ctrl_pressed == false or event.command_pressed == false) - and event.keycode == KEY_DOWN - and event.echo == false - ): + if is_event_pressed(event, KEY_DOWN, true, false, false): # move selected down if (len(selected_items) == 1): move_block(selected_items[0], "down") indent_events() get_viewport().set_input_as_handled() +func is_event_pressed(event, keycode, alt:bool, shift:bool, ctrl_or_command:bool): + return (event.pressed and event.alt_pressed == alt + and event.shift_pressed == shift + and (event.ctrl_pressed or event.command_pressed ) == ctrl_or_command + and event.keycode == keycode + and event.echo == false) + ## ***************************************************************************** ## DELETING, COPY, PASTE ## ***************************************************************************** @@ -419,17 +336,15 @@ func add_events_indexed(indexed_events:Dictionary) -> void: indexes.sort() var events = [] - print('ADDING', indexed_events) for event_idx in indexes: deselect_all_items() var event_resource = DialogicUtil.get_event_by_string(indexed_events[event_idx]).new() event_resource.load_from_string_to_store(indexed_events[event_idx]) - print(event_resource) if event_resource is DialogicEndBranchEvent: events.append(create_end_branch_event(timeline.get_child_count(), timeline.get_child(indexed_events[event_idx].trim_prefix('<>').to_int()))) timeline.move_child(events[-1], event_idx) else: - events.append(add_event_to_timeline(event_resource)) + events.append(add_event_node(event_resource)) timeline.move_child(events[-1], event_idx) selected_items = events @@ -531,7 +446,7 @@ func add_events_at_index(event_list:Array, at_index:int) -> void: var resource = DialogicUtil.get_event_by_string(item).new() resource.load_from_string_to_store(item) if item: - new_items.append(add_event_to_timeline(resource)) + new_items.append(add_event_node(resource)) selected_items = new_items sort_selection() visual_update_selection() @@ -579,10 +494,8 @@ func select_item(item: Node, multi_possible:bool = true): selected_items = [item] else: selected_items = [item] - sort_selection() - visual_update_selection() @@ -637,10 +550,10 @@ func _on_event_options_action(action: String, item: Node): func delete_event(event): event.get_parent().remove_child(event) event.queue_free() + ## ***************************************************************************** ## CREATING NEW EVENTS USING THE BUTTONS ## ***************************************************************************** - # Event Creation signal for buttons func _add_event_button_pressed(event_script): var at_index = -1 @@ -648,48 +561,24 @@ func _add_event_button_pressed(event_script): at_index = selected_items[-1].get_index()+1 else: at_index = timeline.get_child_count() - if event_script.new() is DialogicChoiceEvent: - TimelineUndoRedo.create_action("[D] Add choice event.") - TimelineUndoRedo.add_do_method(self, "add_choice", at_index) + + if event_script.new().can_contain_events: + TimelineUndoRedo.create_action("[D] Add event.") + TimelineUndoRedo.add_do_method(self, "add_event_with_end_branch", event_script.new(), at_index, true, true) TimelineUndoRedo.add_undo_method(self, "remove_events_at_index", at_index, 2) TimelineUndoRedo.commit_action() - elif event_script.new() is DialogicConditionEvent: - add_condition_pressed(at_index, DialogicConditionEvent.ConditionTypes.IF) else: TimelineUndoRedo.create_action("[D] Add event.") - TimelineUndoRedo.add_do_method(self, "add_event_to_timeline", event_script.new(), at_index, true, true) + TimelineUndoRedo.add_do_method(self, "add_event_node", event_script.new(), at_index, true, true) TimelineUndoRedo.add_undo_method(self, "remove_events_at_index", at_index, 1) TimelineUndoRedo.commit_action() + scroll_to_piece(at_index) indent_events() - -func add_choice(at_index): - var choice = add_event_to_timeline(DialogicChoiceEvent.new(), at_index) - create_end_branch_event(at_index+1, choice) - -# this is a seperate function, because it's also called from the EndBranch buttons. -func add_condition_pressed(at_index, type): - TimelineUndoRedo.create_action("[D] Add condition event.") - TimelineUndoRedo.add_do_method(self, "add_condition", at_index, type) - TimelineUndoRedo.add_undo_method(self, "remove_events_at_index", at_index, 2) - TimelineUndoRedo.commit_action() - -func add_condition(at_index, type = DialogicConditionEvent.ConditionTypes.IF): - var resource = DialogicConditionEvent.new() - resource.ConditionType = type - var condition = add_event_to_timeline(resource, at_index) - create_end_branch_event(at_index+1, condition) - -func create_end_branch_event(at_index, parent_node): - var end_branch_event = load("res://addons/dialogic/Editor/Events/BranchEnd.tscn").instantiate() - end_branch_event.resource = DialogicEndBranchEvent.new() - end_branch_event.gui_input.connect(_on_event_block_gui_input.bind(end_branch_event)) - parent_node.end_node = end_branch_event - end_branch_event.parent_node = parent_node - timeline.add_child(end_branch_event) - timeline.move_child(end_branch_event, at_index) - return end_branch_event +func add_event_with_end_branch(resource, at_index:int=-1, auto_select:bool = false, indent:bool = false): + var event = add_event_node(resource, at_index, auto_select, indent) + create_end_branch_event(at_index+1, event) ## ***************************************************************************** @@ -699,7 +588,7 @@ func create_end_branch_event(at_index, parent_node): # Creates a ghost event for drag and drop func create_drag_and_drop_event(resource): var index = get_index_under_cursor() - var piece = add_event_to_timeline(resource) + var piece = add_event_node(resource) currently_draged_event_type = resource timeline.move_child(piece, index) moving_piece = piece @@ -732,7 +621,10 @@ func cancel_drop_event(): ## CREATING THE TIMELINE ## ***************************************************************************** # Adding an event to the timeline -func add_event_to_timeline(event_resource:Resource, at_index:int = -1, auto_select: bool = false, indent: bool = false): +func add_event_node(event_resource:Resource, at_index:int = -1, auto_select: bool = false, indent: bool = false): + if event_resource is DialogicEndBranchEvent: + return create_end_branch_event(at_index, timeline.get_child(0)) + var piece = load("res://addons/dialogic/Editor/Events/EventNode/EventNode.tscn").instantiate() var resource = event_resource piece.resource = event_resource @@ -767,13 +659,27 @@ func add_event_to_timeline(event_resource:Resource, at_index:int = -1, auto_sele return piece +func create_end_branch_event(at_index, parent_node): + var end_branch_event = load("res://addons/dialogic/Editor/Events/BranchEnd.tscn").instantiate() + end_branch_event.resource = DialogicEndBranchEvent.new() + end_branch_event.gui_input.connect(_on_event_block_gui_input.bind(end_branch_event)) + parent_node.end_node = end_branch_event + end_branch_event.parent_node = parent_node + end_branch_event.add_end_control(parent_node.resource.get_end_branch_control()) + timeline.add_child(end_branch_event) + timeline.move_child(end_branch_event, at_index) + return end_branch_event + +## ***************************************************************************** +## SAVING +## ***************************************************************************** func new_timeline() -> void: save_timeline() clear_timeline() show_save_dialog() -# Saving + func save_timeline() -> void: if ! visible: return @@ -809,9 +715,11 @@ func create_and_save_new_timeline(path): load_timeline(new_timeline) +## ***************************************************************************** +## LOADING +## ***************************************************************************** func load_timeline(object) -> void: - #print('[D] Load timeline: ', object) clear_timeline() %Toolbar.load_timeline(object.resource_path) current_timeline = object @@ -831,9 +739,9 @@ func something_changed(): func batch_events(array, size, batch_number): - return array.slice((batch_number - 1) * size, batch_number * size - 1) + return array.slice((batch_number - 1) * size, batch_number * size) -# a list of all choice and condition events (so they get connected to their end events) +# a list of all events like choice and condition events (so they get connected to their end events) var opener_events_stack = [] func load_batch(data): @@ -843,8 +751,8 @@ func load_batch(data): if i is DialogicEndBranchEvent: create_end_branch_event(timeline.get_child_count(), opener_events_stack.pop_back()) else: - var piece = add_event_to_timeline(i, timeline.get_child_count()) - if i is DialogicChoiceEvent or i is DialogicConditionEvent: + var piece = add_event_node(i, timeline.get_child_count()) + if i.can_contain_events: opener_events_stack.push_back(piece) emit_signal("batch_loaded") @@ -854,6 +762,10 @@ func _on_batch_loaded(): await get_tree().create_timer(0.01).timeout load_batch(batches) else: + if opener_events_stack: + for ev in opener_events_stack: + create_end_branch_event(timeline.get_child_count(), ev) + opener_events_stack = [] indent_events() building_timeline = false emit_signal("timeline_loaded") @@ -935,31 +847,23 @@ func scroll_to_piece(piece_index) -> void: # Event Indenting func indent_events() -> void: - # Now indenting var indent: int = 0 - var prev_indent : int = 0 - var delay: bool = false # true for some logic events, so indent only changes one event later var event_list: Array = timeline.get_children() - var question_index: int = 0 - var question_indent = {} + if event_list.size() < 2: return - # Resetting all the indents - for event in event_list: - var indent_node - - event.set_indent(0) - + var currently_hidden = false var hidden_until = null - # Adding new indents + + # will be applied to the indent after the current event + var delayed_indent: int = 0 + for event in event_list: - # since there are indicators now, not all elements - # in this list have an event_data property if (not "resource" in event): continue - if (not currently_hidden) and 'end_node' in event and event.end_node and event.collapsed: + if (not currently_hidden) and event.resource.can_contain_events and event.end_node and event.collapsed: currently_hidden = true hidden_until = event.end_node elif currently_hidden and event == hidden_until: @@ -969,43 +873,31 @@ func indent_events() -> void: event.hide() else: event.show() + + delayed_indent = 0 - ## DETECT QUESTIONS - if event.resource is DialogicTextEvent or event.resource is DialogicConditionEvent: - if (get_block_below(event) and 'resource' in get_block_below(event) and get_block_below(event).resource is DialogicChoiceEvent) or event.resource is DialogicConditionEvent: - indent += 1 - delay = true - question_index += 1 - question_indent[question_index] = indent + if event.resource.can_contain_events: + delayed_indent = 1 + + if event.resource.needs_parent_event: + if get_block_above(event) and 'resource' in get_block_above(event): + if get_block_above(event).resource is DialogicEndBranchEvent: + if event.resource.is_expected_parent_event(get_block_above(get_block_above(event).parent_node).resource): + indent += 1 + elif event.resource.is_expected_parent_event(get_block_above(event).resource): + indent += 1 + + if event.resource is DialogicEndBranchEvent: + delayed_indent -= 1 + if event.parent_node.resource.needs_parent_event: + delayed_indent -= 1 - elif event.resource is DialogicChoiceEvent: - if question_index > 0: - indent = question_indent[question_index] + 1 - delay = true - if (get_block_above(event) and 'resource' in get_block_above(event)) and (get_block_above(event).resource is DialogicEndBranchEvent or get_block_above(event).resource is DialogicTextEvent): - event.remove_warning('This event is not connected to any Question!') - else: - event.set_warning('This event is not connected to any Question!') - - elif event.resource is DialogicEndBranchEvent: - if question_indent.has(question_index): - if get_block_below(event) and 'resource' in get_block_below(event) and get_block_below(event).resource is DialogicChoiceEvent: - indent = question_indent[question_index] - delay = true - else: - indent = question_indent[question_index] -1 - delay = true - question_index -= 1 - if indent < 0: - indent = 0 -# if indent >= 0: - if delay: - event.set_indent(prev_indent) - else: - event.set_indent(indent) - delay = false - prev_indent = indent + event.set_indent(indent) + else: + event.set_indent(0) + indent += delayed_indent + timeline_area.update() diff --git a/addons/dialogic/Editor/TimelineEditor/TimelineEditor.tscn b/addons/dialogic/Editor/TimelineEditor/TimelineEditor.tscn index d49433fec..40607513a 100644 --- a/addons/dialogic/Editor/TimelineEditor/TimelineEditor.tscn +++ b/addons/dialogic/Editor/TimelineEditor/TimelineEditor.tscn @@ -5,7 +5,7 @@ [ext_resource type="Script" path="res://addons/dialogic/Editor/TimelineEditor/TimelineArea.gd" id="22"] [ext_resource type="Theme" path="res://addons/dialogic/Editor/Theme/MainTheme.tres" id="28"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_prwb3"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_oy4h5"] bg_color = Color(0, 0, 0, 1) [node name="TimelineEditor" type="MarginContainer"] @@ -30,7 +30,7 @@ offset_right = 822.0 offset_bottom = 595.0 size_flags_horizontal = 3 size_flags_vertical = 3 -theme_override_styles/bg = SubResource("StyleBoxFlat_prwb3") +theme_override_styles/bg = SubResource("StyleBoxFlat_oy4h5") script = ExtResource("22") [node name="TimeLine" type="VBoxContainer" parent="View/TimelineArea"] @@ -48,13 +48,13 @@ offset_right = 1014.0 offset_bottom = 595.0 [node name="EventContainer" type="VBoxContainer" parent="View/ScrollContainer"] -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 775.0 size_flags_horizontal = 3 size_flags_vertical = 3 [node name="HBoxContainer6" type="HBoxContainer" parent="View/ScrollContainer/EventContainer"] -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 26.0 [node name="TLabel" parent="View/ScrollContainer/EventContainer/HBoxContainer6" instance=ExtResource("21")] @@ -68,19 +68,19 @@ mode = 0 [node name="HSeparator2" type="HSeparator" parent="View/ScrollContainer/EventContainer/HBoxContainer6"] offset_left = 43.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 26.0 size_flags_horizontal = 3 [node name="FlexContainer0" type="HFlowContainer" parent="View/ScrollContainer/EventContainer"] offset_top = 30.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 131.0 size_flags_horizontal = 3 [node name="HBoxContainer5" type="HBoxContainer" parent="View/ScrollContainer/EventContainer"] offset_top = 135.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 161.0 [node name="TLabel2" parent="View/ScrollContainer/EventContainer/HBoxContainer5" instance=ExtResource("21")] @@ -94,19 +94,19 @@ mode = 0 [node name="HSeparator2" type="HSeparator" parent="View/ScrollContainer/EventContainer/HBoxContainer5"] offset_left = 44.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 26.0 size_flags_horizontal = 3 [node name="FlexContainer1" type="HFlowContainer" parent="View/ScrollContainer/EventContainer"] offset_top = 165.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 231.0 size_flags_horizontal = 3 [node name="HBoxContainer3" type="HBoxContainer" parent="View/ScrollContainer/EventContainer"] offset_top = 235.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 261.0 [node name="TLabel3" parent="View/ScrollContainer/EventContainer/HBoxContainer3" instance=ExtResource("21")] @@ -120,20 +120,20 @@ mode = 0 [node name="HSeparator2" type="HSeparator" parent="View/ScrollContainer/EventContainer/HBoxContainer3"] offset_left = 71.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 26.0 size_flags_horizontal = 3 [node name="FlexContainer2" type="HFlowContainer" parent="View/ScrollContainer/EventContainer"] offset_top = 265.0 -offset_right = 172.0 -offset_bottom = 401.0 +offset_right = 176.0 +offset_bottom = 366.0 size_flags_horizontal = 3 [node name="HBoxContainer4" type="HBoxContainer" parent="View/ScrollContainer/EventContainer"] -offset_top = 405.0 -offset_right = 172.0 -offset_bottom = 431.0 +offset_top = 370.0 +offset_right = 176.0 +offset_bottom = 396.0 [node name="TLabel4" parent="View/ScrollContainer/EventContainer/HBoxContainer4" instance=ExtResource("21")] anchor_right = 0.0 @@ -146,20 +146,20 @@ mode = 0 [node name="HSeparator2" type="HSeparator" parent="View/ScrollContainer/EventContainer/HBoxContainer4"] offset_left = 96.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 26.0 size_flags_horizontal = 3 [node name="FlexContainer3" type="HFlowContainer" parent="View/ScrollContainer/EventContainer"] -offset_top = 435.0 -offset_right = 172.0 -offset_bottom = 571.0 +offset_top = 400.0 +offset_right = 176.0 +offset_bottom = 536.0 size_flags_horizontal = 3 [node name="HBoxContainer" type="HBoxContainer" parent="View/ScrollContainer/EventContainer"] -offset_top = 575.0 -offset_right = 172.0 -offset_bottom = 601.0 +offset_top = 540.0 +offset_right = 176.0 +offset_bottom = 566.0 [node name="TLabel5" parent="View/ScrollContainer/EventContainer/HBoxContainer" instance=ExtResource("21")] anchor_right = 0.0 @@ -172,20 +172,20 @@ mode = 0 [node name="HSeparator2" type="HSeparator" parent="View/ScrollContainer/EventContainer/HBoxContainer"] offset_left = 52.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 26.0 size_flags_horizontal = 3 [node name="FlexContainer4" type="HFlowContainer" parent="View/ScrollContainer/EventContainer"] -offset_top = 605.0 -offset_right = 172.0 -offset_bottom = 706.0 +offset_top = 570.0 +offset_right = 176.0 +offset_bottom = 671.0 size_flags_horizontal = 3 [node name="OtherContainer" type="HBoxContainer" parent="View/ScrollContainer/EventContainer"] -offset_top = 710.0 -offset_right = 172.0 -offset_bottom = 736.0 +offset_top = 675.0 +offset_right = 176.0 +offset_bottom = 701.0 [node name="TLabel6" parent="View/ScrollContainer/EventContainer/OtherContainer" instance=ExtResource("21")] anchor_right = 0.0 @@ -198,17 +198,17 @@ mode = 0 [node name="HSeparator2" type="HSeparator" parent="View/ScrollContainer/EventContainer/OtherContainer"] offset_left = 50.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 26.0 size_flags_horizontal = 3 [node name="FlexContainer5" type="HFlowContainer" parent="View/ScrollContainer/EventContainer"] -offset_top = 740.0 -offset_right = 172.0 +offset_top = 705.0 +offset_right = 176.0 offset_bottom = 771.0 size_flags_horizontal = 3 [node name="Spacer" type="Control" parent="View/ScrollContainer/EventContainer"] offset_top = 775.0 -offset_right = 172.0 +offset_right = 176.0 offset_bottom = 775.0 diff --git a/addons/dialogic/Events/Choice/Choice_End.gd b/addons/dialogic/Events/Choice/Choice_End.gd new file mode 100644 index 000000000..413d85e5b --- /dev/null +++ b/addons/dialogic/Events/Choice/Choice_End.gd @@ -0,0 +1,11 @@ +@tool +extends HBoxContainer + +var parent_resource = null + +func refresh(): + if parent_resource is DialogicChoiceEvent: + show() + $Label.text = "End of choice ("+parent_resource.Text+")" + else: + hide() diff --git a/addons/dialogic/Events/Choice/Choice_End.tscn b/addons/dialogic/Events/Choice/Choice_End.tscn new file mode 100644 index 000000000..dcedf15e5 --- /dev/null +++ b/addons/dialogic/Events/Choice/Choice_End.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=3 uid="uid://dtgsqv4xw0355"] + +[ext_resource type="Script" path="res://addons/dialogic/Events/Choice/Choice_End.gd" id="1_7qd85"] + +[node name="Choice_End" type="HBoxContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource("1_7qd85") + +[node name="Label" type="Label" parent="."] +offset_top = 288.0 +offset_right = 1.0 +offset_bottom = 311.0 diff --git a/addons/dialogic/Events/Choice/Subsystem_Choices.gd b/addons/dialogic/Events/Choice/Subsystem_Choices.gd index 8456a0c6e..35afd1e84 100644 --- a/addons/dialogic/Events/Choice/Subsystem_Choices.gd +++ b/addons/dialogic/Events/Choice/Subsystem_Choices.gd @@ -108,7 +108,7 @@ func get_current_choice_indexes() -> Array: if ignore == 0: choices.append(evt_idx) ignore += 1 - if dialogic.current_timeline_events[evt_idx] is DialogicConditionEvent: + elif dialogic.current_timeline_events[evt_idx].can_contain_events: ignore += 1 else: if ignore == 0: diff --git a/addons/dialogic/Events/Choice/event.gd b/addons/dialogic/Events/Choice/event.gd index 349d6ed0d..db801b9ad 100644 --- a/addons/dialogic/Events/Choice/event.gd +++ b/addons/dialogic/Events/Choice/event.gd @@ -32,8 +32,17 @@ func _init() -> void: set_default_color('Color3') event_category = Category.LOGIC event_sorting_index = 0 + can_contain_events = true + needs_parent_event = true expand_by_default = false +# if needs_parent_event is true, this needs to return true if the event is that event +func is_expected_parent_event(event:DialogicEvent): + return event is DialogicTextEvent + +# return a control node that should show on the END BRANCH node +func get_end_branch_control() -> Control: + return load(get_script().resource_path.get_base_dir().plus_file('Choice_End.tscn')).instantiate() ################################################################################ ## SAVING/LOADING diff --git a/addons/dialogic/Events/Condition/Condition_End.gd b/addons/dialogic/Events/Condition/Condition_End.gd new file mode 100644 index 000000000..4c04421bc --- /dev/null +++ b/addons/dialogic/Events/Condition/Condition_End.gd @@ -0,0 +1,31 @@ +@tool +extends HBoxContainer + +var parent_resource = null + +func _ready(): + $AddElif.button_up.connect(add_elif) + $AddElse.button_up.connect(add_else) + +func refresh(): + if parent_resource is DialogicConditionEvent: + show() + $Label.text = "End of IF ("+parent_resource.Condition+")" + else: + hide() + +func add_elif(): + var timeline = find_parent('TimelineEditor') + if timeline: + var resource = DialogicConditionEvent.new() + resource.ConditionType = DialogicConditionEvent.ConditionTypes.ELIF + timeline.add_event_with_end_branch(resource, get_parent().get_index()+1) + timeline.indent_events() + +func add_else(): + var timeline = find_parent('TimelineEditor') + if timeline: + var resource = DialogicConditionEvent.new() + resource.ConditionType = DialogicConditionEvent.ConditionTypes.ELSE + timeline.add_event_with_end_branch(resource, get_parent().get_index()+1) + timeline.indent_events() diff --git a/addons/dialogic/Events/Condition/Condition_End.tscn b/addons/dialogic/Events/Condition/Condition_End.tscn new file mode 100644 index 000000000..f4c20df6e --- /dev/null +++ b/addons/dialogic/Events/Condition/Condition_End.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=2 format=3 uid="uid://dbc22utb2gp6b"] + +[ext_resource type="Script" path="res://addons/dialogic/Events/Condition/Condition_End.gd" id="1_sh52m"] + +[node name="Condition_End" type="HBoxContainer"] +offset_right = 90.0 +offset_bottom = 23.0 +script = ExtResource("1_sh52m") + +[node name="Label" type="Label" parent="."] +offset_top = 2.0 +offset_right = 141.0 +offset_bottom = 28.0 +text = "End of condition X" + +[node name="AddElif" type="Button" parent="."] +offset_left = 145.0 +offset_right = 212.0 +offset_bottom = 31.0 +text = "Add Elif" + +[node name="AddElse" type="Button" parent="."] +offset_left = 216.0 +offset_right = 290.0 +offset_bottom = 31.0 +text = "Add Else" diff --git a/addons/dialogic/Events/Condition/event.gd b/addons/dialogic/Events/Condition/event.gd index 65b5f78db..943daf554 100644 --- a/addons/dialogic/Events/Condition/event.gd +++ b/addons/dialogic/Events/Condition/event.gd @@ -17,24 +17,27 @@ func _execute() -> void: if not result: var idx = dialogic.current_event_idx var ignore = 1 - # this will go through the next events, until there is a event that is not a choice and on the same level as this one while true: idx += 1 if not dialogic.current_timeline.get_event(idx): break - if dialogic.current_timeline.get_event(idx) is DialogicChoiceEvent: + if ignore == 0 and dialogic.current_timeline.get_event(idx) is DialogicConditionEvent: + break + if dialogic.current_timeline.get_event(idx).can_contain_events: ignore += 1 elif dialogic.current_timeline.get_event(idx) is DialogicEndBranchEvent: ignore -= 1 elif ignore == 0: break - # excuse this, checking like above creates a FUCKING CYCLIC DEPENDENCY.... - elif 'ConditionType' in dialogic.current_timeline.get_event(idx): - ignore += 1 - + dialogic.current_event_idx = idx-1 finish() +# only called if the previous event was an end-branch event +# return true if this event should be executed if the previous event was an end-branch event +func should_execute_this_branch() -> bool: + return ConditionType == ConditionTypes.IF + ################################################################################ ## INITIALIZE @@ -46,9 +49,14 @@ func _init() -> void: set_default_color('Color3') event_category = Category.LOGIC event_sorting_index = 0 + can_contain_events = true continue_at_end = true +# return a control node that should show on the END BRANCH node +func get_end_branch_control() -> Control: + return load(get_script().resource_path.get_base_dir().plus_file('Condition_End.tscn')).instantiate() + ################################################################################ ## SAVING/LOADING ################################################################################ @@ -94,5 +102,5 @@ func is_valid_event_string(string:String): ################################################################################ func build_event_editor(): - add_header_edit('ConditionType', ValueType.FixedOptionSelector, '', '', {'selector_options':{"if":ConditionTypes.IF, "elif":ConditionTypes.ELIF, "else":ConditionTypes.ELSE}, 'disabled':true}) + add_header_edit('ConditionType', ValueType.FixedOptionSelector, '', '', {'selector_options':{"IF":ConditionTypes.IF, "ELIF":ConditionTypes.ELIF, "ELSE":ConditionTypes.ELSE}, 'disabled':true}) add_header_edit('Condition', ValueType.SinglelineText, '', '', {}, 'ConditionType != %s'%ConditionTypes.ELSE) diff --git a/addons/dialogic/Events/End Branch/event.gd b/addons/dialogic/Events/End Branch/event.gd index 438bf8c5a..50c9ad637 100644 --- a/addons/dialogic/Events/End Branch/event.gd +++ b/addons/dialogic/Events/End Branch/event.gd @@ -3,7 +3,6 @@ extends DialogicEvent class_name DialogicEndBranchEvent var this_is_an_end_event -var parent_event = null func _execute() -> void: dialogic.current_event_idx = find_next_index()-1 @@ -11,37 +10,28 @@ func _execute() -> void: func find_next_index(): var idx = dialogic.current_event_idx - - # In case the next event is not a choice or ELIF/ELSE event, just go to the next one - # excuse this, checking like normally creates a FUCKING CYCLIC DEPENDENCY.... - if not (dialogic.current_timeline.get_event(idx+1) and 'ConditionType' in dialogic.current_timeline.get_event(idx+1) and dialogic.current_timeline.get_event(idx+1).ConditionType != 0): - if not dialogic.current_timeline.get_event(idx+1) is DialogicChoiceEvent: - return idx+1 - - +# +# # if the next event is a boringly normal event, just go there +# if dialogic.current_timeline.get_event(idx+1) and !dialogic.current_timeline.get_event(idx+1).can_contain_events: +# return idx+1 +# +# # if the next event +# if dialogic.current_timeline.get_event(idx+1) and dialogic.current_timeline.get_event(idx+1).should_execute_this_branch(): +# return idx+1 +# var ignore = 1 - # this will go through the next events, until - # there is a event that's ONE INDENT LESS and NOT A CHOICE and NOT an ELIF or ELSE event while true: idx += 1 var event = dialogic.current_timeline.get_event(idx) if not event: - idx -= 1 - break - if event is DialogicChoiceEvent: + return idx + if event is DialogicEndBranchEvent: + if ignore > 1: ignore -= 1 + elif event.can_contain_events and not event.should_execute_this_branch(): ignore += 1 - # if we get to a condition that is of type elif or else - elif 'ConditionType' in event and event.ConditionType != 0: - pass - elif ignore == 1: - break - # excuse this, checking like above creates a FUCKING CYCLIC DEPENDENCY.... - if 'ConditionType' in dialogic.current_timeline.get_event(idx): - ignore += 1 - # excuse this, checking like above creates a FUCKING CYCLIC DEPENDENCY.... - elif 'this_is_an_end_event' in dialogic.current_timeline.get_event(idx): - ignore -= 1 - + elif ignore <= 1: + return idx + return idx ################################################################################ diff --git a/addons/dialogic/Events/Text/event.gd b/addons/dialogic/Events/Text/event.gd index a322d10b6..4b5666a9c 100644 --- a/addons/dialogic/Events/Text/event.gd +++ b/addons/dialogic/Events/Text/event.gd @@ -78,14 +78,14 @@ func _init() -> void: func get_as_string_to_store() -> String: if Character: if Portrait and not Portrait.is_empty(): - return Character.name+" ("+Portrait+"): "+Text.replace("\n", "
") - return Character.name+": "+Text.replace("\n", "
") - return Text.replace("\n", "
") + return Character.name+" ("+Portrait+"): "+Text.replace("\n", "\\\n") + return Character.name+": "+Text.replace("\n", "\\\n") + return Text.replace("\n", "\\\n") ## THIS HAS TO READ ALL THE DATA FROM THE SAVED STRING (see above) func load_from_string_to_store(string:String): var reg = RegEx.new() - reg.compile("((?[^:()\\n\\s]*)?(?=(\\([^()]*\\))?:)(\\((?[^()]*)\\))?)?:?(?[^\\n]+)") + reg.compile("((?[^:()\\n]*)?(?=(\\([^()]*\\))?:)(\\((?[^()]*)\\))?)?:?(?(.|(?<=\\\\)\\n)+)") var result = reg.search(string) if result and !result.get_string('name').is_empty(): var character = DialogicUtil.guess_resource('.dch', result.get_string('name').strip_edges()) @@ -96,12 +96,14 @@ func load_from_string_to_store(string:String): #print("When importing timeline, we couldn't identify what character you meant with ", result.get_string('name'), ".") if !result.get_string('portrait').is_empty(): Portrait = result.get_string('portrait').strip_edges() - Text = result.get_string('text').replace("
", "\n").trim_prefix(" ") + Text = result.get_string('text').replace("\\\n", "\n").strip_edges() func is_valid_event_string(string): return true +func is_string_full_event(string:String) -> bool: + return !string.ends_with('\\') func can_be_translated(): return true diff --git a/addons/dialogic/Resources/TimelineResourceLoader.gd b/addons/dialogic/Resources/TimelineResourceLoader.gd index 66760f7b1..726e56d20 100644 --- a/addons/dialogic/Resources/TimelineResourceLoader.gd +++ b/addons/dialogic/Resources/TimelineResourceLoader.gd @@ -45,34 +45,53 @@ func _load(path: String, original_path: String, use_sub_threads: bool, cache_mod # this is needed to add a end branch event even to empty conditions/choices var prev_was_opener = false - for line in file.get_as_text().split("\n", false): - var stripped_line = line.strip_edges(true, false) - - if stripped_line.is_empty(): - continue + var lines = file.get_as_text().split('\n', true) + var idx = -1 + + while idx < len(lines)-1: + idx += 1 + var line = lines[idx] + var line_stripped = line.strip_edges(true, false) + var indent = line.substr(0,len(line)-len(line_stripped)) - var indent = line.substr(0,len(line)-len(stripped_line)) if len(indent) < len(prev_indent): for i in range(len(prev_indent)-len(indent)): events.append(DialogicEndBranchEvent.new()) + elif prev_was_opener and len(indent) == len(prev_indent): events.append(DialogicEndBranchEvent.new()) - + + if line_stripped.is_empty(): + continue + prev_indent = indent + var event_content = line_stripped + var event = DialogicUtil.get_event_by_string(event_content).new() - line = stripped_line - var event = DialogicUtil.get_event_by_string(line).new() - event._load_from_string(line) - events.append(event) + # add the following lines until the event says it's full there is an empty line or the indent changes + while !event.is_string_full_event(event_content): + idx += 1 + if idx == len(lines): + break + var following_line = lines[idx] + var following_line_stripped = following_line.strip_edges(true, false) + var following_line_indent = following_line.substr(0,len(following_line)-len(following_line_stripped)) + if following_line_stripped.is_empty(): + break + if following_line_indent != indent: + idx -= 1 + break + event_content += "\n"+following_line_stripped - prev_was_opener = (event is DialogicChoiceEvent or event is DialogicConditionEvent) + event._load_from_string(event_content) + events.append(event) + prev_was_opener = event.can_contain_events if !prev_indent.is_empty(): for i in range(len(prev_indent)): events.append(DialogicEndBranchEvent.new()) - res._events = events return res diff --git a/addons/dialogic/Resources/TimelineResourceSaver.gd b/addons/dialogic/Resources/TimelineResourceSaver.gd index 209afaa2b..6cf5123ee 100644 --- a/addons/dialogic/Resources/TimelineResourceSaver.gd +++ b/addons/dialogic/Resources/TimelineResourceSaver.gd @@ -37,11 +37,8 @@ func _save(path: String, resource: Resource, flags: int) -> int: var event = resource._events[idx] if event is DialogicEndBranchEvent: - if idx < len(resource._events)-1 and resource._events[idx+1] is DialogicChoiceEvent: - indent -= 1 - else: - result += "\t".repeat(indent)+"\n" - indent -= 1 + #result += "\t".repeat(indent)+"\n" + indent -= 1 continue if event != null: result += "\t".repeat(indent)+event._store_as_string() + "\n" @@ -50,10 +47,11 @@ func _save(path: String, resource: Resource, flags: int) -> int: trans_updates[event.translation_id] = event.get_original_translation_text() else: trans_updates[event.add_translation_id()] = event.get_original_translation_text() - if event is DialogicChoiceEvent or event is DialogicConditionEvent: + if event.can_contain_events: indent += 1 if indent < 0: indent = 0 result += "\t".repeat(indent)+"\n" + file.store_string(result) file.close() print('[Dialogic] Saved timeline "' , path, '"') diff --git a/addons/dialogic/Resources/event.gd b/addons/dialogic/Resources/event.gd index 5a1b313e9..cbca5f8a3 100644 --- a/addons/dialogic/Resources/event.gd +++ b/addons/dialogic/Resources/event.gd @@ -11,7 +11,6 @@ var dialogic_color_name:String = '' ## If the resource name is different from the event name, resource_name is returned instead. var event_name:String = "Event" - # To sort the buttons shown in the editor var event_sorting_index : int = 0 @@ -31,6 +30,12 @@ enum Location { var event_category:int = Category.OTHER +var help_page_path : String = "" + +var display_name : bool = true +var disable_editor_button : bool = false +var expand_by_default : bool = true + # This is necessary to distinguish different ways value types might need to be represented # It's used to communicate between the event resource and the event node, how a value @@ -43,9 +48,8 @@ enum ValueType { Bool, - # + # "Resources" ComplexPicker, - Script, File, StringArray, @@ -61,24 +65,15 @@ enum ValueType { } var editor_list = [] -# Hopefully we can replace this with a cleaner system -# maybe even generate them based on some markup? who knows, it is free to dream -var header : Array -var body : Array - -var help_page_path : String = "" - -var expand_by_default : bool = true var needs_indentation : bool = false -var display_name : bool = true -var disable_editor_button : bool = false -var translation_id = null +## +# This means it will always spawn with a END BRANCH event +var can_contain_events : bool = false +var end_branch_event : DialogicEndBranchEvent = null +var needs_parent_event : bool = false -# ----------------------------------------- -# Emilio: -# Stuff I yet don't understand made by Dex: -# ----------------------------------------- +var translation_id = null # This file is part of EventSystem, distributed under MIT license # and modified to work with Dialogic. @@ -153,6 +148,25 @@ func set_default_color(value): func get_required_subsystems() -> Array: return [] +# to be overridden by sub-classes +# if needs_parent_event is true, this needs to return true if the event is that event +func is_expected_parent_event(event:DialogicEvent): + return false + +# to be overridden by sub-classes +# only called if can_contain_events is true. +# return a control node that should show on the END BRANCH node +func get_end_branch_control() -> Control: + return null + + +# to be overridden by sub-classes +# only called if can_contain_events is true and the previous event was an end-branch event +# return true if this event should be executed if the previous event was an end-branch event +# basically only important for the Condition event but who knows. Some day someone might need this. +func should_execute_this_branch(): + return false + ################################################################################ ## TRANSLATIONS ################################################################################ @@ -198,6 +212,7 @@ func _test_event_string(string:String) -> bool: return is_valid_event_string(string.get_slice('#id:', 0)) return is_valid_event_string(string.strip_edges()) + ################################################################################ ## PARSE AND STRINGIFY ################################################################################ @@ -250,6 +265,14 @@ func is_valid_event_string(string:String): return true return false +# has to return true if this string seems to be a full event of this kind +# (only tested if is_valid_event_string() returned true) +# if a shortcode it used it will default to true if the string ends with ']' +func is_string_full_event(string:String) -> bool: + if get_shortcode() != 'default_shortcode': return string.ends_with(']') + return true + + # used to get all the shortcode parameters in a string as a dictionary func parse_shortcode_parameters(shortcode : String) -> Dictionary: var regex = RegEx.new()