First work on dialogic, resized guild, and started implementing portraits.
This commit is contained in:
86
addons/dialogic/Editor/Common/BrowserItem.gd
Normal file
86
addons/dialogic/Editor/Common/BrowserItem.gd
Normal file
@@ -0,0 +1,86 @@
|
||||
@tool
|
||||
extends Container
|
||||
|
||||
signal clicked
|
||||
signal middle_clicked
|
||||
signal double_clicked
|
||||
signal focused
|
||||
|
||||
var base_size := 1
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if get_parent() is SubViewport:
|
||||
return
|
||||
|
||||
%Name.add_theme_font_override("font", get_theme_font("bold", "EditorFonts"))
|
||||
custom_minimum_size = base_size * Vector2(200, 150) * DialogicUtil.get_editor_scale()
|
||||
%CurrentIcon.texture = get_theme_icon("Favorites", "EditorIcons")
|
||||
if %Image.texture == null:
|
||||
%Image.texture = get_theme_icon("ImportFail", "EditorIcons")
|
||||
%Image.stretch_mode = TextureRect.STRETCH_KEEP_CENTERED
|
||||
|
||||
|
||||
func load_info(info:Dictionary) -> void:
|
||||
%Name.text = info.name
|
||||
if not info.has("preview_image"):
|
||||
pass
|
||||
elif info.preview_image[0] == 'custom':
|
||||
await ready
|
||||
%Image.texture = get_theme_icon("CreateNewSceneFrom", "EditorIcons")
|
||||
%Image.stretch_mode = TextureRect.STRETCH_KEEP_CENTERED
|
||||
%Panel.self_modulate = get_theme_color("property_color_z", "Editor")
|
||||
elif info.preview_image[0].ends_with('scn'):
|
||||
DialogicUtil.get_dialogic_plugin().get_editor_interface().get_resource_previewer().queue_resource_preview(info.preview_image[0], self, 'set_scene_preview', null)
|
||||
elif ResourceLoader.exists(info.preview_image[0]):
|
||||
%Image.texture = load(info.preview_image[0])
|
||||
elif info.preview_image[0].is_valid_html_color():
|
||||
%Image.texture = null
|
||||
%Panel.self_modulate = Color(info.preview_image[0])
|
||||
|
||||
if ResourceLoader.exists(info.get('icon', '')):
|
||||
%Icon.get_parent().show()
|
||||
%Icon.texture = load(info.get('icon'))
|
||||
else:
|
||||
%Icon.get_parent().hide()
|
||||
|
||||
tooltip_text = info.description
|
||||
|
||||
|
||||
func set_scene_preview(path:String, preview:Texture2D, thumbnail:Texture2D, userdata:Variant) -> void:
|
||||
if preview:
|
||||
%Image.texture = preview
|
||||
else:
|
||||
%Image.texture = get_theme_icon("PackedScene", "EditorIcons")
|
||||
|
||||
|
||||
|
||||
func set_current(current:bool):
|
||||
%CurrentIcon.visible = current
|
||||
|
||||
|
||||
func _on_mouse_entered() -> void:
|
||||
%HoverBG.show()
|
||||
|
||||
|
||||
func _on_mouse_exited() -> void:
|
||||
%HoverBG.hide()
|
||||
|
||||
|
||||
func _on_gui_input(event):
|
||||
if event.is_action_pressed('ui_accept') or event.is_action_pressed("ui_select") or (
|
||||
event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT):
|
||||
clicked.emit()
|
||||
if not event is InputEventMouseButton or event.double_click:
|
||||
double_clicked.emit()
|
||||
elif event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_MIDDLE:
|
||||
middle_clicked.emit()
|
||||
|
||||
|
||||
func _on_focus_entered() -> void:
|
||||
$FocusFG.show()
|
||||
focused.emit()
|
||||
|
||||
|
||||
func _on_focus_exited() -> void:
|
||||
$FocusFG.hide()
|
||||
1
addons/dialogic/Editor/Common/BrowserItem.gd.uid
Normal file
1
addons/dialogic/Editor/Common/BrowserItem.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cxfu3mv2lrriv
|
||||
154
addons/dialogic/Editor/Common/BrowserItem.tscn
Normal file
154
addons/dialogic/Editor/Common/BrowserItem.tscn
Normal file
@@ -0,0 +1,154 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://ddlxjde1cx035"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/BrowserItem.gd" id="1_s3kf0"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pfw08"]
|
||||
bg_color = Color(1, 1, 1, 0.32549)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
expand_margin_left = 4.0
|
||||
expand_margin_top = 4.0
|
||||
expand_margin_right = 4.0
|
||||
expand_margin_bottom = 4.0
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ab24c"]
|
||||
bg_color = Color(1, 1, 1, 1)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qnehp"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
shadow_color = Color(0.847059, 0.847059, 0.847059, 0.384314)
|
||||
shadow_size = 5
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nxx8t"]
|
||||
bg_color = Color(0.435294, 0.435294, 0.435294, 0.211765)
|
||||
draw_center = false
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
expand_margin_left = 4.0
|
||||
expand_margin_top = 4.0
|
||||
expand_margin_right = 4.0
|
||||
expand_margin_bottom = 4.0
|
||||
|
||||
[node name="BrowserItem" type="MarginContainer"]
|
||||
custom_minimum_size = Vector2(200, 150)
|
||||
offset_left = 1.0
|
||||
offset_top = 1.0
|
||||
offset_right = 128.0
|
||||
offset_bottom = 102.0
|
||||
size_flags_horizontal = 0
|
||||
focus_mode = 2
|
||||
theme_override_constants/margin_left = 4
|
||||
theme_override_constants/margin_top = 4
|
||||
theme_override_constants/margin_right = 4
|
||||
theme_override_constants/margin_bottom = 4
|
||||
script = ExtResource("1_s3kf0")
|
||||
|
||||
[node name="HoverBG" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_pfw08")
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
theme_override_constants/separation = 0
|
||||
alignment = 1
|
||||
|
||||
[node name="Panel" type="PanelContainer" parent="VBox"]
|
||||
unique_name_in_owner = true
|
||||
self_modulate = Color(0.0705882, 0.0705882, 0.0705882, 1)
|
||||
clip_children = 2
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
mouse_filter = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_ab24c")
|
||||
|
||||
[node name="Image" type="TextureRect" parent="VBox/Panel"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
mouse_filter = 2
|
||||
expand_mode = 1
|
||||
stretch_mode = 6
|
||||
|
||||
[node name="CurrentIcon" type="TextureRect" parent="VBox/Panel/Image"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -22.0
|
||||
offset_top = 5.0
|
||||
offset_right = -6.0
|
||||
offset_bottom = 21.0
|
||||
grow_horizontal = 0
|
||||
tooltip_text = "Currently in use"
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="Panel" type="Panel" parent="VBox/Panel/Image"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -37.0
|
||||
offset_top = -36.0
|
||||
offset_right = -7.0
|
||||
offset_bottom = -6.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_qnehp")
|
||||
|
||||
[node name="Icon" type="TextureRect" parent="VBox/Panel/Image/Panel"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 4.0
|
||||
offset_top = 4.0
|
||||
offset_right = -4.0
|
||||
offset_bottom = -4.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="Name" type="Label" parent="VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Dialogic Theme"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FocusFG" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_nxx8t")
|
||||
|
||||
[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
|
||||
[connection signal="focus_exited" from="." to="." method="_on_focus_exited"]
|
||||
[connection signal="gui_input" from="." to="." method="_on_gui_input"]
|
||||
[connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"]
|
||||
47
addons/dialogic/Editor/Common/DCSS.gd
Normal file
47
addons/dialogic/Editor/Common/DCSS.gd
Normal file
@@ -0,0 +1,47 @@
|
||||
@tool
|
||||
class_name DCSS
|
||||
|
||||
static func inline(style: Dictionary) -> StyleBoxFlat:
|
||||
var scale: float = DialogicUtil.get_editor_scale()
|
||||
var s := StyleBoxFlat.new()
|
||||
for property in style.keys():
|
||||
match property:
|
||||
'border-left':
|
||||
s.set('border_width_left', style[property] * scale)
|
||||
'border-radius':
|
||||
var radius: float = style[property] * scale
|
||||
s.set('corner_radius_top_left', radius)
|
||||
s.set('corner_radius_top_right', radius)
|
||||
s.set('corner_radius_bottom_left', radius)
|
||||
s.set('corner_radius_bottom_right', radius)
|
||||
'background':
|
||||
if typeof(style[property]) == TYPE_STRING and style[property] == "none":
|
||||
s.set('draw_center', false)
|
||||
else:
|
||||
s.set('bg_color', style[property])
|
||||
'border':
|
||||
var width: float = style[property] * scale
|
||||
s.set('border_width_left', width)
|
||||
s.set('border_width_right', width)
|
||||
s.set('border_width_top', width)
|
||||
s.set('border_width_bottom', width)
|
||||
'border-color':
|
||||
s.set('border_color', style[property])
|
||||
'padding':
|
||||
var value_v: float = 0.0
|
||||
var value_h: float = 0.0
|
||||
if style[property] is int:
|
||||
value_v = style[property] * scale
|
||||
value_h = value_v
|
||||
else:
|
||||
value_v = style[property][0] * scale
|
||||
value_h = style[property][1] * scale
|
||||
s.set('content_margin_top', value_v)
|
||||
s.set('content_margin_bottom', value_v)
|
||||
s.set('content_margin_left', value_h)
|
||||
s.set('content_margin_right', value_h)
|
||||
'padding-right':
|
||||
s.set('content_margin_right', style[property] * scale)
|
||||
'padding-left':
|
||||
s.set('content_margin_left', style[property] * scale)
|
||||
return s
|
||||
1
addons/dialogic/Editor/Common/DCSS.gd.uid
Normal file
1
addons/dialogic/Editor/Common/DCSS.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b5ngxiswvr5pm
|
||||
@@ -0,0 +1,119 @@
|
||||
@tool
|
||||
extends PanelContainer
|
||||
|
||||
|
||||
enum Modes {EDIT, ADD}
|
||||
|
||||
var mode := Modes.EDIT
|
||||
var item: TreeItem = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
hide()
|
||||
%Character.resource_icon = load("res://addons/dialogic/Editor/Images/Resources/character.svg")
|
||||
%Character.get_suggestions_func = get_character_suggestions
|
||||
|
||||
%WholeWords.icon = get_theme_icon("FontItem", "EditorIcons")
|
||||
%MatchCase.icon = get_theme_icon("MatchCase", "EditorIcons")
|
||||
|
||||
func _on_add_pressed() -> void:
|
||||
if visible:
|
||||
if mode == Modes.ADD:
|
||||
hide()
|
||||
return
|
||||
elif mode == Modes.EDIT:
|
||||
save()
|
||||
|
||||
%AddButton.text = "Add"
|
||||
mode = Modes.ADD
|
||||
show()
|
||||
%Type.selected = 0
|
||||
_on_type_item_selected(0)
|
||||
%Where.selected = 2
|
||||
_on_where_item_selected(2)
|
||||
%Old.text = ""
|
||||
%New.text = ""
|
||||
|
||||
|
||||
func open_existing(_item:TreeItem, info:Dictionary):
|
||||
mode = Modes.EDIT
|
||||
item = _item
|
||||
show()
|
||||
%AddButton.text = "Update"
|
||||
%Type.selected = info.type
|
||||
_on_type_item_selected(info.type)
|
||||
if !info.character_names.is_empty():
|
||||
%Where.selected = 1
|
||||
%Character.set_value(info.character_names[0])
|
||||
else:
|
||||
%Where.selected = 0
|
||||
_on_where_item_selected(%Where.selected)
|
||||
|
||||
%Old.text = info.what
|
||||
%New.text = info.forwhat
|
||||
|
||||
func _on_type_item_selected(index:int) -> void:
|
||||
match index:
|
||||
0:
|
||||
%Where.select(0)
|
||||
%Where.set_item_disabled(0, false)
|
||||
%Where.set_item_disabled(1, false)
|
||||
%Where.set_item_disabled(2, true)
|
||||
1:
|
||||
%Where.select(0)
|
||||
%Where.set_item_disabled(0, false)
|
||||
%Where.set_item_disabled(1, false)
|
||||
%Where.set_item_disabled(2, true)
|
||||
2:
|
||||
%Where.select(1)
|
||||
%Where.set_item_disabled(0, true)
|
||||
%Where.set_item_disabled(1, false)
|
||||
%Where.set_item_disabled(2, true)
|
||||
3,4:
|
||||
%Where.select(0)
|
||||
%Where.set_item_disabled(0, false)
|
||||
%Where.set_item_disabled(1, true)
|
||||
%Where.set_item_disabled(2, true)
|
||||
%PureTextFlags.visible = index == 0
|
||||
_on_where_item_selected(%Where.selected)
|
||||
|
||||
|
||||
func _on_where_item_selected(index:int) -> void:
|
||||
%Character.visible = index == 1
|
||||
|
||||
|
||||
func get_character_suggestions(search_text:String) -> Dictionary:
|
||||
var suggestions := {}
|
||||
|
||||
#override the previous _character_directory with the meta, specifically for searching otherwise new nodes wont work
|
||||
var _character_directory := DialogicResourceUtil.get_character_directory()
|
||||
|
||||
var icon := load("res://addons/dialogic/Editor/Images/Resources/character.svg")
|
||||
suggestions['(No one)'] = {'value':null, 'editor_icon':["GuiRadioUnchecked", "EditorIcons"]}
|
||||
|
||||
for resource in _character_directory.keys():
|
||||
suggestions[resource] = {
|
||||
'value' : resource,
|
||||
'tooltip' : _character_directory[resource],
|
||||
'icon' : icon.duplicate()}
|
||||
return suggestions
|
||||
|
||||
|
||||
func save() -> void:
|
||||
if %Old.text.is_empty() or %New.text.is_empty():
|
||||
return
|
||||
if %Where.selected == 1 and %Character.current_value == null:
|
||||
return
|
||||
|
||||
var previous := {}
|
||||
if mode == Modes.EDIT:
|
||||
previous = item.get_metadata(0)
|
||||
item.get_parent()
|
||||
item.free()
|
||||
|
||||
var ref_manager := find_parent('ReferenceManager')
|
||||
var character_names := []
|
||||
if %Character.current_value != null:
|
||||
character_names = [%Character.current_value]
|
||||
ref_manager.add_ref_change(%Old.text, %New.text, %Type.selected, %Where.selected, character_names, %WholeWords.button_pressed, %MatchCase.button_pressed, previous)
|
||||
hide()
|
||||
@@ -0,0 +1 @@
|
||||
uid://yv2r6lvx1ccn
|
||||
8
addons/dialogic/Editor/Common/TitleBgStylebox.tres
Normal file
8
addons/dialogic/Editor/Common/TitleBgStylebox.tres
Normal file
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="StyleBoxFlat" format=3 uid="uid://dmsjhgv22dns8"]
|
||||
|
||||
[resource]
|
||||
content_margin_left = 5.0
|
||||
content_margin_top = 5.0
|
||||
content_margin_right = 5.0
|
||||
content_margin_bottom = 5.0
|
||||
bg_color = Color(0.545098, 0.545098, 0.545098, 0.211765)
|
||||
363
addons/dialogic/Editor/Common/broken_reference_manager.gd
Normal file
363
addons/dialogic/Editor/Common/broken_reference_manager.gd
Normal file
@@ -0,0 +1,363 @@
|
||||
@tool
|
||||
extends VSplitContainer
|
||||
|
||||
## This manager shows a list of changed references and allows searching for them and replacing them.
|
||||
|
||||
var reference_changes: Array[Dictionary] = []:
|
||||
set(changes):
|
||||
reference_changes = changes
|
||||
update_indicator()
|
||||
|
||||
var search_regexes: Array[Array]
|
||||
var finder_thread: Thread
|
||||
var progress_mutex: Mutex
|
||||
var progress_percent: float = 0.0
|
||||
var progress_message: String = ""
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if owner.get_parent() is SubViewport:
|
||||
return
|
||||
|
||||
%TabA.text = "Broken References"
|
||||
%TabA.icon = get_theme_icon("Unlinked", "EditorIcons")
|
||||
|
||||
owner.get_parent().visibility_changed.connect(func(): if is_visible_in_tree(): open())
|
||||
|
||||
%ReplacementSection.hide()
|
||||
|
||||
%CheckButton.icon = get_theme_icon("Search", "EditorIcons")
|
||||
%Replace.icon = get_theme_icon("ArrowRight", "EditorIcons")
|
||||
|
||||
%State.add_theme_color_override("font_color", get_theme_color("warning_color", "Editor"))
|
||||
visibility_changed.connect(func(): if !visible: close())
|
||||
await get_parent().ready
|
||||
|
||||
var tab_button: Control = %TabA
|
||||
var dot := Sprite2D.new()
|
||||
dot.texture = get_theme_icon("GuiGraphNodePort", "EditorIcons")
|
||||
dot.scale = Vector2(0.8, 0.8)
|
||||
dot.z_index = 10
|
||||
dot.position = Vector2(tab_button.size.x, tab_button.size.y*0.25)
|
||||
dot.modulate = get_theme_color("warning_color", "Editor").lightened(0.5)
|
||||
|
||||
tab_button.add_child(dot)
|
||||
update_indicator()
|
||||
|
||||
|
||||
func open() -> void:
|
||||
%ReplacementEditPanel.hide()
|
||||
%ReplacementSection.hide()
|
||||
%ChangeTree.clear()
|
||||
%ChangeTree.create_item()
|
||||
%ChangeTree.set_column_expand(0, false)
|
||||
%ChangeTree.set_column_expand(2, false)
|
||||
%ChangeTree.set_column_custom_minimum_width(2, 50)
|
||||
var categories := {null:%ChangeTree.get_root()}
|
||||
for i in reference_changes:
|
||||
var parent: TreeItem = null
|
||||
if !i.get('category', null) in categories:
|
||||
parent = %ChangeTree.create_item()
|
||||
parent.set_text(1, i.category)
|
||||
parent.set_custom_color(1, get_theme_color("disabled_font_color", "Editor"))
|
||||
categories[i.category] = parent
|
||||
else:
|
||||
parent = categories[i.get('category')]
|
||||
|
||||
var item: TreeItem = %ChangeTree.create_item(parent)
|
||||
item.set_text(1, i.what+" -> "+i.forwhat)
|
||||
item.add_button(1, get_theme_icon("Edit", "EditorIcons"), 1, false, 'Edit')
|
||||
item.add_button(1, get_theme_icon("Remove", "EditorIcons"), 0, false, 'Remove Change from List')
|
||||
item.set_cell_mode(0, TreeItem.CELL_MODE_CHECK)
|
||||
item.set_checked(0, true)
|
||||
item.set_editable(0, true)
|
||||
item.set_metadata(0, i)
|
||||
%CheckButton.disabled = reference_changes.is_empty()
|
||||
|
||||
|
||||
func _on_change_tree_button_clicked(item:TreeItem, column:int, id:int, mouse_button_index:int) -> void:
|
||||
if id == 0:
|
||||
reference_changes.erase(item.get_metadata(0))
|
||||
if item.get_parent().get_child_count() == 1:
|
||||
item.get_parent().free()
|
||||
else:
|
||||
item.free()
|
||||
update_indicator()
|
||||
%CheckButton.disabled = reference_changes.is_empty()
|
||||
|
||||
if id == 1:
|
||||
%ReplacementEditPanel.open_existing(item, item.get_metadata(0))
|
||||
|
||||
%ReplacementSection.hide()
|
||||
|
||||
|
||||
func _on_change_tree_item_edited() -> void:
|
||||
if !%ChangeTree.get_selected():
|
||||
return
|
||||
%CheckButton.disabled = false
|
||||
|
||||
|
||||
func _on_check_button_pressed() -> void:
|
||||
var to_be_checked: Array[Dictionary]= []
|
||||
var item: TreeItem = %ChangeTree.get_root()
|
||||
while item.get_next_visible():
|
||||
item = item.get_next_visible()
|
||||
|
||||
if item.get_child_count():
|
||||
continue
|
||||
|
||||
if item.is_checked(0):
|
||||
to_be_checked.append(item.get_metadata(0))
|
||||
to_be_checked[-1]['item'] = item
|
||||
to_be_checked[-1]['count'] = 0
|
||||
|
||||
open_finder(to_be_checked)
|
||||
%CheckButton.disabled = true
|
||||
|
||||
|
||||
func open_finder(replacements:Array[Dictionary]) -> void:
|
||||
%ReplacementSection.show()
|
||||
%Progress.show()
|
||||
%ReferenceTree.hide()
|
||||
|
||||
search_regexes = []
|
||||
for i in replacements:
|
||||
if i.has('character_names') and !i.character_names.is_empty():
|
||||
i['character_regex'] = RegEx.create_from_string("(?m)^(join|update|leave)?\\s*("+str(i.character_names).replace('"', '').replace(', ', '|').trim_suffix(']').trim_prefix('[').replace('/', '\\/')+")(?(1).*|.*:)")
|
||||
|
||||
for regex_string in i.regex:
|
||||
var regex := RegEx.create_from_string(regex_string)
|
||||
search_regexes.append([regex, i])
|
||||
|
||||
finder_thread = Thread.new()
|
||||
progress_mutex = Mutex.new()
|
||||
finder_thread.start(search_timelines.bind(search_regexes))
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if finder_thread and finder_thread.is_started():
|
||||
if finder_thread.is_alive():
|
||||
progress_mutex.lock()
|
||||
%State.text = progress_message
|
||||
%Progress.value = progress_percent
|
||||
progress_mutex.unlock()
|
||||
else:
|
||||
var finds: Variant = finder_thread.wait_to_finish()
|
||||
display_search_results(finds)
|
||||
|
||||
|
||||
|
||||
func display_search_results(finds:Array[Dictionary]) -> void:
|
||||
%Progress.hide()
|
||||
%ReferenceTree.show()
|
||||
for regex_info in search_regexes:
|
||||
regex_info[1]['item'].set_text(2, str(regex_info[1]['count']))
|
||||
|
||||
update_count_coloring()
|
||||
%State.text = str(len(finds))+ " occurrences found"
|
||||
|
||||
%ReferenceTree.clear()
|
||||
%ReferenceTree.set_column_expand(0, false)
|
||||
%ReferenceTree.create_item()
|
||||
|
||||
var timelines := {}
|
||||
var height := 0
|
||||
for i in finds:
|
||||
var parent: TreeItem = null
|
||||
if !i.timeline in timelines:
|
||||
parent = %ReferenceTree.create_item()
|
||||
parent.set_text(1, i.timeline)
|
||||
parent.set_custom_color(1, get_theme_color("disabled_font_color", "Editor"))
|
||||
timelines[i.timeline] = parent
|
||||
height += %ReferenceTree.get_item_area_rect(parent).size.y+10
|
||||
else:
|
||||
parent = timelines[i.timeline]
|
||||
|
||||
var item: TreeItem = %ReferenceTree.create_item(parent)
|
||||
item.set_text(1, 'Line '+str(i.line_number)+': '+i.line)
|
||||
item.set_tooltip_text(1, i.info.what+' -> '+i.info.forwhat)
|
||||
item.set_cell_mode(0, TreeItem.CELL_MODE_CHECK)
|
||||
item.set_checked(0, true)
|
||||
item.set_editable(0, true)
|
||||
item.set_metadata(0, i)
|
||||
height += %ReferenceTree.get_item_area_rect(item).size.y+10
|
||||
var change_item: TreeItem = i.info.item
|
||||
change_item.set_meta('found_items', change_item.get_meta('found_items', [])+[item])
|
||||
|
||||
%ReferenceTree.custom_minimum_size.y = min(height, 200)
|
||||
|
||||
%ReferenceTree.visible = !finds.is_empty()
|
||||
%Replace.disabled = finds.is_empty()
|
||||
if finds.is_empty():
|
||||
%State.text = "Nothing found"
|
||||
else:
|
||||
%Replace.grab_focus()
|
||||
|
||||
|
||||
func search_timelines(regexes:Array[Array]) -> Array[Dictionary]:
|
||||
var finds: Array[Dictionary] = []
|
||||
|
||||
var timeline_paths := DialogicResourceUtil.list_resources_of_type('.dtl')
|
||||
|
||||
var progress := 0
|
||||
var progress_max: float = len(timeline_paths)*len(regexes)
|
||||
|
||||
for timeline_path:String in timeline_paths:
|
||||
|
||||
var timeline_file := FileAccess.open(timeline_path, FileAccess.READ)
|
||||
var timeline_text: String = timeline_file.get_as_text()
|
||||
var timeline_event: PackedStringArray = timeline_text.split('\n')
|
||||
timeline_file.close()
|
||||
|
||||
for regex_info in regexes:
|
||||
progress += 1
|
||||
progress_mutex.lock()
|
||||
progress_percent = 1/progress_max*progress
|
||||
progress_message = "Searching '"+timeline_path+"' for "+regex_info[1].what+' -> '+regex_info[1].forwhat
|
||||
progress_mutex.unlock()
|
||||
for i in regex_info[0].search_all(timeline_text):
|
||||
if regex_info[1].has('character_regex'):
|
||||
if regex_info[1].character_regex.search(get_line(timeline_text, i.get_start()+1)) == null:
|
||||
continue
|
||||
|
||||
var line_number := timeline_text.count('\n', 0, i.get_start()+1)+1
|
||||
var line := timeline_text.get_slice('\n', line_number-1)
|
||||
finds.append({
|
||||
'match':i,
|
||||
'timeline':timeline_path,
|
||||
'info': regex_info[1],
|
||||
'line_number': line_number,
|
||||
'line': line,
|
||||
'line_start': timeline_text.rfind('\n', i.get_start())
|
||||
})
|
||||
regex_info[1]['count'] += 1
|
||||
return finds
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
# Shutting of
|
||||
if finder_thread and finder_thread.is_alive():
|
||||
finder_thread.wait_to_finish()
|
||||
|
||||
|
||||
func get_line(string:String, at_index:int) -> String:
|
||||
return string.substr(max(string.rfind('\n', at_index), 0), string.find('\n', at_index)-string.rfind('\n', at_index))
|
||||
|
||||
|
||||
func update_count_coloring() -> void:
|
||||
var item: TreeItem = %ChangeTree.get_root()
|
||||
while item.get_next_visible():
|
||||
item = item.get_next_visible()
|
||||
|
||||
if item.get_child_count():
|
||||
continue
|
||||
if int(item.get_text(2)) > 0:
|
||||
item.set_custom_bg_color(1, get_theme_color("warning_color", "Editor").darkened(0.8))
|
||||
item.set_custom_color(1, get_theme_color("warning_color", "Editor"))
|
||||
item.set_custom_color(2, get_theme_color("warning_color", "Editor"))
|
||||
else:
|
||||
item.set_custom_color(2, get_theme_color("success_color", "Editor"))
|
||||
item.set_custom_color(1, get_theme_color("readonly_font_color", "Editor"))
|
||||
if item.get_button_count(1):
|
||||
item.erase_button(1, 1)
|
||||
item.add_button(1, get_theme_icon("Eraser", "EditorIcons"), -1, true, "This reference was not found anywhere and will be removed from this list.")
|
||||
|
||||
|
||||
func _on_replace_pressed() -> void:
|
||||
var to_be_replaced: Array[Dictionary]= []
|
||||
var item: TreeItem = %ReferenceTree.get_root()
|
||||
var affected_timelines: Array[String]= []
|
||||
|
||||
while item.get_next_visible():
|
||||
item = item.get_next_visible()
|
||||
|
||||
if item.get_child_count():
|
||||
continue
|
||||
|
||||
if item.is_checked(0):
|
||||
to_be_replaced.append(item.get_metadata(0))
|
||||
to_be_replaced[-1]['f_item'] = item
|
||||
if !item.get_metadata(0).timeline in affected_timelines:
|
||||
affected_timelines.append(item.get_metadata(0).timeline)
|
||||
replace(affected_timelines, to_be_replaced)
|
||||
|
||||
|
||||
func replace(timelines:Array[String], replacement_info:Array[Dictionary]) -> void:
|
||||
var reopen_timeline := ""
|
||||
var timeline_editor: DialogicEditor = find_parent('EditorView').editors_manager.editors['Timeline'].node
|
||||
if timeline_editor.current_resource != null and timeline_editor.current_resource.resource_path in timelines:
|
||||
reopen_timeline = timeline_editor.current_resource.resource_path
|
||||
find_parent('EditorView').editors_manager.clear_editor(timeline_editor)
|
||||
|
||||
replacement_info.sort_custom(func(a,b): return a.match.get_start() < b.match.get_start())
|
||||
|
||||
for timeline_path in timelines:
|
||||
%State.text = "Loading '"+timeline_path+"'"
|
||||
|
||||
var timeline_file := FileAccess.open(timeline_path, FileAccess.READ_WRITE)
|
||||
var timeline_text: String = timeline_file.get_as_text()
|
||||
var timeline_events := timeline_text.split('\n')
|
||||
timeline_file.close()
|
||||
|
||||
var idx := 1
|
||||
var offset_correction := 0
|
||||
for replacement in replacement_info:
|
||||
if replacement.timeline != timeline_path:
|
||||
continue
|
||||
|
||||
%State.text = "Replacing in '"+timeline_path + "' ("+str(idx)+"/"+str(len(replacement_info))+")"
|
||||
var group := 'replace'
|
||||
if not 'replace' in replacement.match.names:
|
||||
group = ''
|
||||
|
||||
|
||||
timeline_text = timeline_text.substr(0, replacement.match.get_start(group) + offset_correction) + \
|
||||
replacement.info.regex_replacement + \
|
||||
timeline_text.substr(replacement.match.get_end(group) + offset_correction)
|
||||
offset_correction += len(replacement.info.regex_replacement)-len(replacement.match.get_string(group))
|
||||
|
||||
replacement.info.count -= 1
|
||||
replacement.info.item.set_text(2, str(replacement.info.count))
|
||||
replacement.f_item.set_custom_bg_color(1, get_theme_color("success_color", "Editor").darkened(0.8))
|
||||
|
||||
timeline_file = FileAccess.open(timeline_path, FileAccess.WRITE)
|
||||
timeline_file.store_string(timeline_text.strip_edges(false, true))
|
||||
timeline_file.close()
|
||||
|
||||
if ResourceLoader.has_cached(timeline_path):
|
||||
var tml := load(timeline_path)
|
||||
tml.from_text(timeline_text)
|
||||
|
||||
if !reopen_timeline.is_empty():
|
||||
find_parent('EditorView').editors_manager.edit_resource(load(reopen_timeline), false, true)
|
||||
|
||||
update_count_coloring()
|
||||
|
||||
%Replace.disabled = true
|
||||
%CheckButton.disabled = false
|
||||
%State.text = "Done Replacing"
|
||||
|
||||
|
||||
func update_indicator() -> void:
|
||||
%TabA.get_child(0).visible = !reference_changes.is_empty()
|
||||
|
||||
|
||||
func close() -> void:
|
||||
var item: TreeItem = %ChangeTree.get_root()
|
||||
if item:
|
||||
while item.get_next_visible():
|
||||
item = item.get_next_visible()
|
||||
|
||||
if item.get_child_count():
|
||||
continue
|
||||
if item.get_text(2) != "" and int(item.get_text(2)) == 0:
|
||||
reference_changes.erase(item.get_metadata(0))
|
||||
for i in reference_changes:
|
||||
i.item = null
|
||||
DialogicUtil.set_editor_setting('reference_changes', reference_changes)
|
||||
update_indicator()
|
||||
find_parent("ReferenceManager").update_indicator()
|
||||
|
||||
|
||||
func _on_add_button_pressed() -> void:
|
||||
%ReplacementEditPanel._on_add_pressed()
|
||||
@@ -0,0 +1 @@
|
||||
uid://bhml2gwyjbpj7
|
||||
12
addons/dialogic/Editor/Common/hint_tooltip_icon.gd
Normal file
12
addons/dialogic/Editor/Common/hint_tooltip_icon.gd
Normal file
@@ -0,0 +1,12 @@
|
||||
@tool
|
||||
extends TextureRect
|
||||
|
||||
@export_multiline var hint_text := ""
|
||||
|
||||
func _ready() -> void:
|
||||
if owner and owner.get_parent() is SubViewport:
|
||||
texture = null
|
||||
return
|
||||
texture = get_theme_icon("NodeInfo", "EditorIcons")
|
||||
modulate = get_theme_color("contrast_color_1", "Editor")
|
||||
tooltip_text = hint_text
|
||||
1
addons/dialogic/Editor/Common/hint_tooltip_icon.gd.uid
Normal file
1
addons/dialogic/Editor/Common/hint_tooltip_icon.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://pv58uk852jre
|
||||
21
addons/dialogic/Editor/Common/hint_tooltip_icon.tscn
Normal file
21
addons/dialogic/Editor/Common/hint_tooltip_icon.tscn
Normal file
@@ -0,0 +1,21 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://dbpkta2tjsqim"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/hint_tooltip_icon.gd" id="1_x8t45"]
|
||||
|
||||
[sub_resource type="Image" id="Image_eiyxd"]
|
||||
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_lseut"]
|
||||
image = SubResource("Image_eiyxd")
|
||||
|
||||
[node name="HintTooltip" type="TextureRect"]
|
||||
modulate = Color(0, 0, 0, 1)
|
||||
texture = SubResource("ImageTexture_lseut")
|
||||
stretch_mode = 3
|
||||
script = ExtResource("1_x8t45")
|
||||
38
addons/dialogic/Editor/Common/reference_manager.gd
Normal file
38
addons/dialogic/Editor/Common/reference_manager.gd
Normal file
@@ -0,0 +1,38 @@
|
||||
@tool
|
||||
extends PanelContainer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if get_parent() is SubViewport:
|
||||
return
|
||||
|
||||
add_theme_stylebox_override("panel", get_theme_stylebox("Background", "EditorStyles"))
|
||||
$Tabs/Close.icon = get_theme_icon("Close", "EditorIcons")
|
||||
|
||||
for tab in $Tabs/Tabs.get_children():
|
||||
tab.add_theme_color_override("font_selected_color", get_theme_color("accent_color", "Editor"))
|
||||
tab.add_theme_font_override("font", get_theme_font("main", "EditorFonts"))
|
||||
tab.toggled.connect(tab_changed.bind(tab.get_index()+1))
|
||||
|
||||
|
||||
func tab_changed(enabled:bool, index:int) -> void:
|
||||
for child in $Tabs.get_children():
|
||||
if child.get_index() == 0 or child.get_index() == index or child is Button:
|
||||
child.show()
|
||||
if child.get_index() == index:
|
||||
child.open()
|
||||
else:
|
||||
if child.visible:
|
||||
child.close()
|
||||
child.hide()
|
||||
for child in $Tabs/Tabs.get_children():
|
||||
child.set_pressed_no_signal(index-1 == child.get_index())
|
||||
|
||||
|
||||
func open() -> void:
|
||||
show()
|
||||
$Tabs/BrokenReferences.update_indicator()
|
||||
|
||||
|
||||
func _on_close_pressed() -> void:
|
||||
get_parent()._on_close_requested()
|
||||
1
addons/dialogic/Editor/Common/reference_manager.gd.uid
Normal file
1
addons/dialogic/Editor/Common/reference_manager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://clihsosyt8utt
|
||||
324
addons/dialogic/Editor/Common/reference_manager.tscn
Normal file
324
addons/dialogic/Editor/Common/reference_manager.tscn
Normal file
@@ -0,0 +1,324 @@
|
||||
[gd_scene load_steps=13 format=3 uid="uid://c7lmt5cp7bxcm"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/reference_manager.gd" id="1_3t531"]
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/broken_reference_manager.gd" id="1_agmg4"]
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/ReferenceManager_AddReplacementPanel.gd" id="2_tt4jd"]
|
||||
[ext_resource type="PackedScene" uid="uid://dpwhshre1n4t6" path="res://addons/dialogic/Editor/Events/Fields/field_options_dynamic.tscn" id="3_yomsc"]
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/unique_identifiers_manager.gd" id="5_wnvbq"]
|
||||
|
||||
[sub_resource type="ButtonGroup" id="ButtonGroup_l6uiy"]
|
||||
|
||||
[sub_resource type="Image" id="Image_36731"]
|
||||
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, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 224, 224, 224, 255, 224, 224, 224, 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, 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_a0gfq"]
|
||||
image = SubResource("Image_36731")
|
||||
|
||||
[sub_resource type="Image" id="Image_0rvkq"]
|
||||
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_mr0fw"]
|
||||
image = SubResource("Image_0rvkq")
|
||||
|
||||
[sub_resource type="Image" id="Image_5fmdt"]
|
||||
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_lce2m"]
|
||||
image = SubResource("Image_5fmdt")
|
||||
|
||||
[node name="Manager" type="PanelContainer"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_3t531")
|
||||
|
||||
[node name="Tabs" type="VBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Tabs" type="HBoxContainer" parent="Tabs"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="TabA" type="Button" parent="Tabs/Tabs"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
button_pressed = true
|
||||
text = "Broken References"
|
||||
flat = true
|
||||
|
||||
[node name="TabB" type="Button" parent="Tabs/Tabs"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
button_group = SubResource("ButtonGroup_l6uiy")
|
||||
text = "Unique Identifiers"
|
||||
flat = true
|
||||
|
||||
[node name="BrokenReferences" type="VSplitContainer" parent="Tabs"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource("1_agmg4")
|
||||
|
||||
[node name="ChangesList" type="PanelContainer" parent="Tabs/BrokenReferences"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_type_variation = &"DialogicPanelA"
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="Tabs/BrokenReferences/ChangesList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="Tabs/BrokenReferences/ChangesList/VBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SectionTitle" type="Label" parent="Tabs/BrokenReferences/ChangesList/VBox/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "Recent renames"
|
||||
|
||||
[node name="AddButton" type="Button" parent="Tabs/BrokenReferences/ChangesList/VBox/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 2
|
||||
tooltip_text = "Add custom rename"
|
||||
icon = SubResource("ImageTexture_a0gfq")
|
||||
|
||||
[node name="ReplacementEditPanel" type="PanelContainer" parent="Tabs/BrokenReferences/ChangesList/VBox"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
script = ExtResource("2_tt4jd")
|
||||
|
||||
[node name="VBox" type="HFlowContainer" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer3" type="HBoxContainer" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Type" type="OptionButton" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer3"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "This decides the regexes for searching. Pure text allows you to enter your own regex into into \"Old\". "
|
||||
item_count = 5
|
||||
selected = 0
|
||||
popup/item_0/text = "Pure Text"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "Variable"
|
||||
popup/item_1/id = 1
|
||||
popup/item_2/text = "Portrait"
|
||||
popup/item_2/id = 2
|
||||
popup/item_3/text = "Character (Ref)"
|
||||
popup/item_3/id = 3
|
||||
popup/item_4/text = "Timeline (Ref)"
|
||||
popup/item_4/id = 4
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Old" type="LineEdit" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "Old"
|
||||
|
||||
[node name="Label2" type="Label" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "->"
|
||||
|
||||
[node name="New" type="LineEdit" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "New"
|
||||
|
||||
[node name="PureTextFlags" type="HBoxContainer" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
alignment = 2
|
||||
|
||||
[node name="MatchCase" type="Button" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/PureTextFlags"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "Match Case"
|
||||
toggle_mode = true
|
||||
icon = SubResource("ImageTexture_mr0fw")
|
||||
|
||||
[node name="WholeWords" type="Button" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/PureTextFlags"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "Whole World"
|
||||
toggle_mode = true
|
||||
icon = SubResource("ImageTexture_mr0fw")
|
||||
|
||||
[node name="HBoxContainer4" type="HBoxContainer" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Where" type="OptionButton" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer4"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
item_count = 3
|
||||
selected = 0
|
||||
fit_to_longest_item = false
|
||||
popup/item_0/text = "Everywhere"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "Only for Character"
|
||||
popup/item_1/id = 1
|
||||
popup/item_2/text = "Texts only"
|
||||
popup/item_2/id = 2
|
||||
|
||||
[node name="Character" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer4" instance=ExtResource("3_yomsc")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="AddButton" type="Button" parent="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Add/Save"
|
||||
|
||||
[node name="ChangeTree" type="Tree" parent="Tabs/BrokenReferences/ChangesList/VBox"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 50)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/draw_relationship_lines = 1
|
||||
columns = 3
|
||||
hide_root = true
|
||||
|
||||
[node name="CheckButton" type="Button" parent="Tabs/BrokenReferences/ChangesList/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
tooltip_text = "Search timelines for occurences of these renames"
|
||||
text = "Check Selected"
|
||||
icon = SubResource("ImageTexture_lce2m")
|
||||
|
||||
[node name="ReplacementSection" type="PanelContainer" parent="Tabs/BrokenReferences"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"DialogicPanelA"
|
||||
|
||||
[node name="FindList" type="VBoxContainer" parent="Tabs/BrokenReferences/ReplacementSection"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="HBox" type="HBoxContainer" parent="Tabs/BrokenReferences/ReplacementSection/FindList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SectionTitle2" type="Label" parent="Tabs/BrokenReferences/ReplacementSection/FindList/HBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "Found references"
|
||||
|
||||
[node name="State" type="Label" parent="Tabs/BrokenReferences/ReplacementSection/FindList/HBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 8
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
text = "State"
|
||||
|
||||
[node name="ReferenceTree" type="Tree" parent="Tabs/BrokenReferences/ReplacementSection/FindList"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/draw_relationship_lines = 1
|
||||
columns = 2
|
||||
hide_root = true
|
||||
|
||||
[node name="Progress" type="ProgressBar" parent="Tabs/BrokenReferences/ReplacementSection/FindList"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
max_value = 1.0
|
||||
|
||||
[node name="Replace" type="Button" parent="Tabs/BrokenReferences/ReplacementSection/FindList"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
tooltip_text = "Replace all selected findings (Careful, no undo!)"
|
||||
text = "Replace Selected"
|
||||
icon = SubResource("ImageTexture_lce2m")
|
||||
|
||||
[node name="UniqueIdentifiers" type="PanelContainer" parent="Tabs"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_type_variation = &"DialogicPanelA"
|
||||
script = ExtResource("5_wnvbq")
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="Tabs/UniqueIdentifiers"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Tools" type="HBoxContainer" parent="Tabs/UniqueIdentifiers/VBox"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="Search" type="LineEdit" parent="Tabs/UniqueIdentifiers/VBox/Tools"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(400, 0)
|
||||
layout_mode = 2
|
||||
placeholder_text = "Search"
|
||||
|
||||
[node name="IdentifierTable" type="Tree" parent="Tabs/UniqueIdentifiers/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
columns = 2
|
||||
column_titles_visible = true
|
||||
hide_root = true
|
||||
|
||||
[node name="RenameNotification" type="Label" parent="Tabs/UniqueIdentifiers/VBox"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
text = "You've renamed some identifier(s)! Use the \"Broken References\" tab to check if you have used this identifier (and fix it if so)."
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="Close" type="Button" parent="Tabs"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
text = "Close"
|
||||
|
||||
[node name="HelpButton" type="LinkButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 0
|
||||
text = "Documentation"
|
||||
uri = "https://docs.dialogic.pro/reference-manager.html"
|
||||
|
||||
[connection signal="pressed" from="Tabs/BrokenReferences/ChangesList/VBox/HBoxContainer/AddButton" to="Tabs/BrokenReferences" method="_on_add_button_pressed"]
|
||||
[connection signal="item_selected" from="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer3/Type" to="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel" method="_on_type_item_selected"]
|
||||
[connection signal="item_selected" from="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/HBoxContainer4/Where" to="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel" method="_on_where_item_selected"]
|
||||
[connection signal="pressed" from="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel/VBox/AddButton" to="Tabs/BrokenReferences/ChangesList/VBox/ReplacementEditPanel" method="save"]
|
||||
[connection signal="button_clicked" from="Tabs/BrokenReferences/ChangesList/VBox/ChangeTree" to="Tabs/BrokenReferences" method="_on_change_tree_button_clicked"]
|
||||
[connection signal="item_edited" from="Tabs/BrokenReferences/ChangesList/VBox/ChangeTree" to="Tabs/BrokenReferences" method="_on_change_tree_item_edited"]
|
||||
[connection signal="pressed" from="Tabs/BrokenReferences/ChangesList/VBox/CheckButton" to="Tabs/BrokenReferences" method="_on_check_button_pressed"]
|
||||
[connection signal="pressed" from="Tabs/BrokenReferences/ReplacementSection/FindList/Replace" to="Tabs/BrokenReferences" method="_on_replace_pressed"]
|
||||
[connection signal="text_changed" from="Tabs/UniqueIdentifiers/VBox/Tools/Search" to="Tabs/UniqueIdentifiers" method="_on_search_text_changed"]
|
||||
[connection signal="button_clicked" from="Tabs/UniqueIdentifiers/VBox/IdentifierTable" to="Tabs/UniqueIdentifiers" method="_on_identifier_table_button_clicked"]
|
||||
[connection signal="item_edited" from="Tabs/UniqueIdentifiers/VBox/IdentifierTable" to="Tabs/UniqueIdentifiers" method="_on_identifier_table_item_edited"]
|
||||
[connection signal="pressed" from="Tabs/Close" to="." method="_on_close_pressed"]
|
||||
191
addons/dialogic/Editor/Common/reference_manager_window.gd
Normal file
191
addons/dialogic/Editor/Common/reference_manager_window.gd
Normal file
@@ -0,0 +1,191 @@
|
||||
@tool
|
||||
extends Window
|
||||
|
||||
## This window manages communication with the replacement manager it contains.
|
||||
## Other scripts can call the add_ref_change() method to register changes directly
|
||||
## or use the helpers add_variable_ref_change() and add_portrait_ref_change()
|
||||
|
||||
@onready var editors_manager := get_node("../EditorsManager")
|
||||
@onready var broken_manager := get_node("Manager/Tabs/BrokenReferences")
|
||||
enum Where {EVERYWHERE, BY_CHARACTER, TEXTS_ONLY}
|
||||
enum Types {TEXT, VARIABLE, PORTRAIT, CHARACTER_NAME, TIMELINE_NAME}
|
||||
|
||||
var icon_button: Button = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if owner.get_parent() is SubViewport:
|
||||
return
|
||||
|
||||
$Manager.theme = owner.get_theme()
|
||||
|
||||
icon_button = editors_manager.add_icon_button(get_theme_icon("Unlinked", "EditorIcons"), 'Reference Manager')
|
||||
icon_button.pressed.connect(open)
|
||||
|
||||
var dot := Sprite2D.new()
|
||||
dot.texture = get_theme_icon("GuiGraphNodePort", "EditorIcons")
|
||||
dot.scale = Vector2(0.8, 0.8)
|
||||
dot.z_index = 10
|
||||
dot.position = Vector2(icon_button.size.x*0.8, icon_button.size.x*0.2)
|
||||
dot.modulate = get_theme_color("warning_color", "Editor").lightened(0.5)
|
||||
|
||||
icon_button.add_child(dot)
|
||||
|
||||
var old_changes: Array = DialogicUtil.get_editor_setting('reference_changes', [])
|
||||
if !old_changes.is_empty():
|
||||
broken_manager.reference_changes = old_changes
|
||||
|
||||
update_indicator()
|
||||
|
||||
hide()
|
||||
|
||||
get_parent().plugin_reference.get_editor_interface().get_file_system_dock().files_moved.connect(_on_file_moved)
|
||||
get_parent().plugin_reference.get_editor_interface().get_file_system_dock().file_removed.connect(_on_file_removed)
|
||||
get_parent().get_node('ResourceRenameWarning').confirmed.connect(open)
|
||||
|
||||
|
||||
func add_ref_change(old_name:String, new_name:String, type:Types, where:=Where.TEXTS_ONLY, character_names:=[],
|
||||
whole_words:=false, case_sensitive:=false, previous:Dictionary = {}) -> void:
|
||||
var regexes := []
|
||||
var category_name := ""
|
||||
match type:
|
||||
Types.TEXT:
|
||||
category_name = "Texts"
|
||||
if '<replace>' in old_name:
|
||||
regexes = [old_name]
|
||||
else:
|
||||
regexes = [
|
||||
r'(?<replace>%s)' % old_name.replace('/', '\\/')
|
||||
]
|
||||
if !case_sensitive:
|
||||
regexes[0] = '(?i)'+regexes[0]
|
||||
if whole_words:
|
||||
regexes = ['\\b'+regexes[0]+'\\b']
|
||||
|
||||
Types.VARIABLE:
|
||||
regexes = [
|
||||
r'{(?<replace>\s*%s\s*)}' % old_name.replace("/", "\\/"),
|
||||
r'var\s*=\s*"(?<replace>\s*%s\s*)"' % old_name.replace("/", "\\/")
|
||||
]
|
||||
category_name = "Variables"
|
||||
|
||||
Types.PORTRAIT:
|
||||
regexes = [
|
||||
r'(?m)^[^:(\n]*\((?<replace>%s)\)' % old_name.replace('/', '\\/'),
|
||||
r'\[\s*portrait\s*=(?<replace>\s*%s\s*)\]' % old_name.replace('/', '\\/')
|
||||
]
|
||||
category_name = "Portraits by "+character_names[0]
|
||||
|
||||
Types.CHARACTER_NAME:
|
||||
# for reference: ((join|leave|update) )?(?<replace>NAME)(?!\B)(?(1)|(?!([^:\n]|\\:)*(\n|$)))
|
||||
regexes = [
|
||||
r'((join|leave|update) )?(?<replace>%s)(?!\B)(?(1)|(?!([^:\n]|\\:)*(\n|$)))' % old_name
|
||||
]
|
||||
category_name = "Renamed Character Files"
|
||||
|
||||
Types.TIMELINE_NAME:
|
||||
regexes = [
|
||||
r'timeline ?= ?" ?(?<replace>%s) ?"' % old_name
|
||||
]
|
||||
category_name = "Renamed Timeline Files"
|
||||
|
||||
if where != Where.BY_CHARACTER:
|
||||
character_names = []
|
||||
|
||||
# previous is only given when an existing item is edited
|
||||
# in that case the old one is removed first
|
||||
var idx := len(broken_manager.reference_changes)
|
||||
if previous in broken_manager.reference_changes:
|
||||
idx = broken_manager.reference_changes.find(previous)
|
||||
broken_manager.reference_changes.erase(previous)
|
||||
|
||||
if _check_for_ref_change_cycle(old_name, new_name, category_name):
|
||||
update_indicator()
|
||||
return
|
||||
|
||||
broken_manager.reference_changes.insert(idx,
|
||||
{'what':old_name,
|
||||
'forwhat':new_name,
|
||||
'regex': regexes,
|
||||
'regex_replacement':new_name,
|
||||
'category':category_name,
|
||||
'character_names':character_names,
|
||||
'texts_only':where == Where.TEXTS_ONLY,
|
||||
'type':type
|
||||
})
|
||||
|
||||
update_indicator()
|
||||
|
||||
if visible:
|
||||
$Manager.open()
|
||||
broken_manager.open()
|
||||
|
||||
|
||||
## Checks for reference cycles or chains.
|
||||
## E.g. if you first rename a portrait from "happy" to "happy1" and then to "Happy/happy1"
|
||||
## This will make sure only a change "happy" -> "Happy/happy1" is remembered
|
||||
## This is very important for correct replacement
|
||||
func _check_for_ref_change_cycle(old_name:String, new_name:String, category:String) -> bool:
|
||||
for ref in broken_manager.reference_changes:
|
||||
if ref['forwhat'] == old_name and ref['category'] == category:
|
||||
if new_name == ref['what']:
|
||||
broken_manager.reference_changes.erase(ref)
|
||||
else:
|
||||
broken_manager.reference_changes[broken_manager.reference_changes.find(ref)]['forwhat'] = new_name
|
||||
broken_manager.reference_changes[broken_manager.reference_changes.find(ref)]['regex_replacement'] = new_name
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
## Helper for adding variable ref changes
|
||||
func add_variable_ref_change(old_name:String, new_name:String) -> void:
|
||||
add_ref_change(old_name, new_name, Types.VARIABLE, Where.EVERYWHERE)
|
||||
|
||||
|
||||
## Helper for adding portrait ref changes
|
||||
func add_portrait_ref_change(old_name:String, new_name:String, character_names:PackedStringArray) -> void:
|
||||
add_ref_change(old_name, new_name, Types.PORTRAIT, Where.BY_CHARACTER, character_names)
|
||||
|
||||
|
||||
## Helper for adding character name ref changes
|
||||
func add_character_name_ref_change(old_name:String, new_name:String) -> void:
|
||||
add_ref_change(old_name, new_name, Types.CHARACTER_NAME, Where.EVERYWHERE)
|
||||
|
||||
|
||||
## Helper for adding timeline name ref changes
|
||||
func add_timeline_name_ref_change(old_name:String, new_name:String) -> void:
|
||||
add_ref_change(old_name, new_name, Types.TIMELINE_NAME, Where.EVERYWHERE)
|
||||
|
||||
|
||||
func open() -> void:
|
||||
DialogicResourceUtil.update_directory('dch')
|
||||
DialogicResourceUtil.update_directory('dtl')
|
||||
popup_centered_ratio(0.5)
|
||||
move_to_foreground()
|
||||
grab_focus()
|
||||
|
||||
|
||||
func _on_close_requested() -> void:
|
||||
hide()
|
||||
broken_manager.close()
|
||||
|
||||
|
||||
func update_indicator() -> void:
|
||||
icon_button.get_child(0).visible = !broken_manager.reference_changes.is_empty()
|
||||
|
||||
|
||||
## FILE MANAGEMENT:
|
||||
func _on_file_moved(old_file:String, new_file:String) -> void:
|
||||
if old_file.ends_with('.dch') and new_file.ends_with('.dch'):
|
||||
DialogicResourceUtil.change_resource_path(old_file, new_file)
|
||||
if old_file.get_file() != new_file.get_file():
|
||||
get_parent().get_node('ResourceRenameWarning').popup_centered()
|
||||
elif old_file.ends_with('.dtl') and new_file.ends_with('.dtl'):
|
||||
DialogicResourceUtil.change_resource_path(old_file, new_file)
|
||||
if old_file.get_file() != new_file.get_file():
|
||||
get_parent().get_node('ResourceRenameWarning').popup_centered()
|
||||
|
||||
|
||||
func _on_file_removed(file:String) -> void:
|
||||
if file.get_extension() in ['dch', 'dtl']:
|
||||
DialogicResourceUtil.remove_resource(file)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bqab632sxner5
|
||||
211
addons/dialogic/Editor/Common/side_bar.tscn
Normal file
211
addons/dialogic/Editor/Common/side_bar.tscn
Normal file
@@ -0,0 +1,211 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://cwe3r2tbh2og1"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/sidebar.gd" id="1_jnq65"]
|
||||
[ext_resource type="Texture2D" uid="uid://bff65e82555qr" path="res://addons/dialogic/Editor/Images/Pieces/close-icon.svg" id="2_54pks"]
|
||||
[ext_resource type="Texture2D" uid="uid://dx3o2ild56i76" path="res://addons/dialogic/Editor/Images/Pieces/closed-icon.svg" id="2_ilyps"]
|
||||
|
||||
[sub_resource type="Theme" id="Theme_pn0f4"]
|
||||
VBoxContainer/constants/separation = 4
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_gxwm6"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_n8rql"]
|
||||
|
||||
[node name="SideBar" type="VSplitContainer"]
|
||||
custom_minimum_size = Vector2(100, 130)
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme = SubResource("Theme_pn0f4")
|
||||
split_offset = 100
|
||||
script = ExtResource("1_jnq65")
|
||||
|
||||
[node name="VBoxHidden" type="VBoxContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="OpenButton" type="Button" parent="VBoxHidden"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 3
|
||||
tooltip_text = "Show Sidebar"
|
||||
theme_override_constants/icon_max_width = 20
|
||||
icon = ExtResource("2_ilyps")
|
||||
flat = true
|
||||
icon_alignment = 1
|
||||
|
||||
[node name="VBoxPrimary" type="VBoxContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="VBoxPrimary"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="MainVSplit" type="VSplitContainer" parent="VBoxPrimary/Margin"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="VBoxPrimary/Margin/MainVSplit"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Logo" type="TextureRect" parent="VBoxPrimary/Margin/MainVSplit/VBox"]
|
||||
unique_name_in_owner = true
|
||||
modulate = Color(1, 1, 1, 0.623529)
|
||||
texture_filter = 6
|
||||
custom_minimum_size = Vector2(0, 25)
|
||||
layout_mode = 2
|
||||
expand_mode = 3
|
||||
stretch_mode = 4
|
||||
|
||||
[node name="HBox" type="HBoxContainer" parent="VBoxPrimary/Margin/MainVSplit/VBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CurrentResource" type="LineEdit" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "No resource"
|
||||
alignment = 1
|
||||
editable = false
|
||||
|
||||
[node name="CloseButton" type="Button" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "Hide Sidebar"
|
||||
text = " "
|
||||
icon = ExtResource("2_54pks")
|
||||
flat = true
|
||||
icon_alignment = 1
|
||||
expand_icon = true
|
||||
|
||||
[node name="HBoxSearchSort" type="HBoxContainer" parent="VBoxPrimary/Margin/MainVSplit/VBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Search" type="LineEdit" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
tooltip_text = "Filter Resources"
|
||||
placeholder_text = "Filter Resources"
|
||||
caret_blink = true
|
||||
caret_blink_interval = 0.5
|
||||
|
||||
[node name="Options" type="Button" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="OptionsPopup" type="Popup" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options"]
|
||||
unique_name_in_owner = true
|
||||
transparent_bg = true
|
||||
position = Vector2i(890, 65)
|
||||
size = Vector2i(165, 101)
|
||||
visible = true
|
||||
transparent = true
|
||||
|
||||
[node name="OptionsPanel" type="PanelContainer" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options/OptionsPopup"]
|
||||
unique_name_in_owner = true
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options/OptionsPopup/OptionsPanel"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="GroupingOptions" type="OptionButton" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options/OptionsPopup/OptionsPanel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "Grouping
|
||||
- None: No Grouping, sorted alphabetically
|
||||
- Type: Group by type (Characters/Timeilnes)
|
||||
- Folder: Group based on the parent folder name.
|
||||
- Path: Group based on folders."
|
||||
text_overrun_behavior = 1
|
||||
clip_text = true
|
||||
selected = 0
|
||||
item_count = 4
|
||||
popup/item_0/text = "No Grouping"
|
||||
popup/item_1/text = "Type Grouping"
|
||||
popup/item_1/id = 1
|
||||
popup/item_2/text = "Folder Grouping"
|
||||
popup/item_2/id = 2
|
||||
popup/item_3/text = "Path Grouping"
|
||||
popup/item_3/id = 3
|
||||
|
||||
[node name="FolderColors" type="CheckBox" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options/OptionsPopup/OptionsPanel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Use Folder Colors"
|
||||
|
||||
[node name="TrimFolderPaths" type="CheckBox" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options/OptionsPopup/OptionsPanel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Trim Folder Paths"
|
||||
|
||||
[node name="ResourceTree" type="Tree" parent="VBoxPrimary/Margin/MainVSplit/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
allow_rmb_select = true
|
||||
hide_root = true
|
||||
scroll_horizontal_enabled = false
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxPrimary/Margin/MainVSplit/VBox"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 1
|
||||
text = "Sort Order"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SortOption" type="OptionButton" parent="VBoxPrimary/Margin/MainVSplit/VBox/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
item_count = 1
|
||||
popup/item_0/text = "Alphabetical (All)"
|
||||
|
||||
[node name="ContentListSection" type="VBoxContainer" parent="VBoxPrimary/Margin/MainVSplit"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 15)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ContentList" type="ItemList" parent="VBoxPrimary/Margin/MainVSplit/ContentListSection"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
tooltip_text = "Label events in your timeline will appear here, allowing you to jump to them."
|
||||
theme_override_styles/selected = SubResource("StyleBoxEmpty_gxwm6")
|
||||
theme_override_styles/selected_focus = SubResource("StyleBoxEmpty_n8rql")
|
||||
allow_reselect = true
|
||||
same_column_width = true
|
||||
|
||||
[node name="CurrentVersion" type="Button" parent="VBoxPrimary"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Some Version"
|
||||
flat = true
|
||||
clip_text = true
|
||||
|
||||
[node name="RightClickMenu" type="PopupMenu" parent="."]
|
||||
unique_name_in_owner = true
|
||||
size = Vector2i(164, 100)
|
||||
|
||||
[connection signal="dragged" from="VBoxPrimary/Margin/MainVSplit" to="." method="_on_main_v_split_dragged"]
|
||||
[connection signal="gui_input" from="VBoxPrimary/Margin/MainVSplit/VBox/Logo" to="." method="_on_logo_gui_input"]
|
||||
[connection signal="text_changed" from="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Search" to="." method="_on_search_text_changed"]
|
||||
[connection signal="text_submitted" from="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Search" to="." method="_on_search_text_submitted"]
|
||||
[connection signal="pressed" from="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options" to="." method="_on_options_pressed"]
|
||||
[connection signal="toggled" from="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options/OptionsPopup/OptionsPanel/VBox/FolderColors" to="." method="_on_folder_colors_toggled"]
|
||||
[connection signal="toggled" from="VBoxPrimary/Margin/MainVSplit/VBox/HBoxSearchSort/Options/OptionsPopup/OptionsPanel/VBox/TrimFolderPaths" to="." method="_on_trim_folder_paths_toggled"]
|
||||
[connection signal="id_pressed" from="RightClickMenu" to="." method="_on_right_click_menu_id_pressed"]
|
||||
529
addons/dialogic/Editor/Common/sidebar.gd
Normal file
529
addons/dialogic/Editor/Common/sidebar.gd
Normal file
@@ -0,0 +1,529 @@
|
||||
@tool
|
||||
class_name DialogicSidebar extends Control
|
||||
|
||||
## Script that handles the editor sidebar.
|
||||
|
||||
signal content_item_activated(item_name)
|
||||
signal show_sidebar(show: bool)
|
||||
|
||||
# References
|
||||
@onready var editors_manager = get_parent().get_parent()
|
||||
@onready var resource_tree: Tree = %ResourceTree
|
||||
|
||||
var current_resource_list: Array = []
|
||||
|
||||
enum GroupMode {
|
||||
NONE,
|
||||
TYPE,
|
||||
FOLDER,
|
||||
PATH,
|
||||
}
|
||||
var group_mode: GroupMode = GroupMode.TYPE
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if owner != null and owner.get_parent() is SubViewport:
|
||||
return
|
||||
if editors_manager is SubViewportContainer:
|
||||
return
|
||||
|
||||
## CONNECTIONS
|
||||
editors_manager.resource_opened.connect(_on_editors_resource_opened)
|
||||
editors_manager.editor_changed.connect(_on_editors_editor_changed)
|
||||
|
||||
resource_tree.item_activated.connect(_on_resources_tree_item_activated)
|
||||
resource_tree.item_mouse_selected.connect(_on_resources_tree_item_clicked)
|
||||
resource_tree.item_collapsed.connect(_on_resources_tree_item_collapsed)
|
||||
|
||||
%ContentList.item_selected.connect(
|
||||
func(idx: int): content_item_activated.emit(%ContentList.get_item_text(idx))
|
||||
)
|
||||
|
||||
%OpenButton.pressed.connect(_show_sidebar)
|
||||
%CloseButton.pressed.connect(_hide_sidebar)
|
||||
|
||||
var editor_scale := DialogicUtil.get_editor_scale()
|
||||
|
||||
## ICONS
|
||||
%Logo.texture = load("res://addons/dialogic/Editor/Images/dialogic-logo.svg")
|
||||
%Logo.custom_minimum_size.y = 30 * editor_scale
|
||||
%Search.right_icon = get_theme_icon("Search", "EditorIcons")
|
||||
%Options.icon = get_theme_icon("GuiTabMenuHl", "EditorIcons")
|
||||
%OptionsPanel.add_theme_stylebox_override("panel", get_theme_stylebox("PanelForeground", "EditorStyles"))
|
||||
%OptionsPopup.hide()
|
||||
|
||||
%ContentList.add_theme_color_override(
|
||||
"font_hovered_color", get_theme_color("warning_color", "Editor")
|
||||
)
|
||||
%ContentList.add_theme_color_override(
|
||||
"font_selected_color", get_theme_color("property_color_z", "Editor")
|
||||
)
|
||||
|
||||
## RIGHT CLICK MENU
|
||||
%RightClickMenu.clear()
|
||||
%RightClickMenu.add_icon_item(get_theme_icon("Remove", "EditorIcons"), "Remove From List", 1)
|
||||
%RightClickMenu.add_separator()
|
||||
%RightClickMenu.add_icon_item(get_theme_icon("ActionCopy", "EditorIcons"), "Copy Identifier", 4)
|
||||
%RightClickMenu.add_separator()
|
||||
%RightClickMenu.add_icon_item(
|
||||
get_theme_icon("Filesystem", "EditorIcons"), "Show in FileSystem", 2
|
||||
)
|
||||
%RightClickMenu.add_icon_item(
|
||||
get_theme_icon("ExternalLink", "EditorIcons"), "Open in External Program", 3
|
||||
)
|
||||
|
||||
## SORT MENU
|
||||
%GroupingOptions.set_item_icon(0, get_theme_icon("AnimationTrackGroup", "EditorIcons"))
|
||||
%GroupingOptions.set_item_icon(1, get_theme_icon("Folder", "EditorIcons"))
|
||||
%GroupingOptions.set_item_icon(2, get_theme_icon("FolderBrowse", "EditorIcons"))
|
||||
%GroupingOptions.set_item_icon(3, get_theme_icon("AnimationTrackList", "EditorIcons"))
|
||||
%GroupingOptions.item_selected.connect(_on_grouping_changed)
|
||||
|
||||
await get_tree().process_frame
|
||||
if DialogicUtil.get_editor_setting("sidebar_collapsed", false):
|
||||
_hide_sidebar()
|
||||
|
||||
%MainVSplit.split_offset = DialogicUtil.get_editor_setting("sidebar_v_split", 0)
|
||||
group_mode = DialogicUtil.get_editor_setting("sidebar_group_mode", 0)
|
||||
%GroupingOptions.select(%GroupingOptions.get_item_index(group_mode))
|
||||
|
||||
%FolderColors.button_pressed = DialogicUtil.get_editor_setting("sidebar_use_folder_colors", true)
|
||||
%TrimFolderPaths.button_pressed = DialogicUtil.get_editor_setting("sidebar_trim_folder_paths", true)
|
||||
|
||||
update_resource_list()
|
||||
|
||||
|
||||
func set_unsaved_indicator(saved: bool = true) -> void:
|
||||
if saved and %CurrentResource.text.ends_with("(*)"):
|
||||
%CurrentResource.text = %CurrentResource.text.trim_suffix("(*)")
|
||||
if not saved and not %CurrentResource.text.ends_with("(*)"):
|
||||
%CurrentResource.text = %CurrentResource.text + "(*)"
|
||||
|
||||
|
||||
func _on_logo_gui_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
editors_manager.open_editor(editors_manager.editors["HomePage"].node)
|
||||
|
||||
|
||||
#region SHOW/HIDE SIDEBAR
|
||||
################################################################################
|
||||
|
||||
func _show_sidebar() -> void:
|
||||
%VBoxPrimary.show()
|
||||
%VBoxHidden.hide()
|
||||
DialogicUtil.set_editor_setting("sidebar_collapsed", false)
|
||||
show_sidebar.emit(true)
|
||||
|
||||
|
||||
func _hide_sidebar() -> void:
|
||||
%VBoxPrimary.hide()
|
||||
%VBoxHidden.show()
|
||||
DialogicUtil.set_editor_setting("sidebar_collapsed", true)
|
||||
show_sidebar.emit(false)
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
################################################################################
|
||||
## RESOURCE LIST
|
||||
################################################################################
|
||||
|
||||
|
||||
func _on_editors_resource_opened(_resource: Resource) -> void:
|
||||
update_resource_list()
|
||||
|
||||
|
||||
func _on_editors_editor_changed(_previous: DialogicEditor, current: DialogicEditor) -> void:
|
||||
%ContentListSection.visible = current.current_resource is DialogicTimeline
|
||||
update_resource_list()
|
||||
|
||||
|
||||
## Cleans resources that have been deleted from the resource list
|
||||
func clean_resource_list(resources_list: Array = []) -> PackedStringArray:
|
||||
return PackedStringArray(resources_list.filter(func(x): return ResourceLoader.exists(x)))
|
||||
|
||||
|
||||
#region BULDING/FILTERING THE RESOURCE LIST
|
||||
|
||||
func update_resource_list(resources_list: PackedStringArray = []) -> void:
|
||||
var filter: String = %Search.text
|
||||
var current_file := ""
|
||||
if editors_manager.current_editor and editors_manager.current_editor.current_resource:
|
||||
current_file = editors_manager.current_editor.current_resource.resource_path
|
||||
|
||||
var character_directory: Dictionary = DialogicResourceUtil.get_character_directory()
|
||||
var timeline_directory: Dictionary = DialogicResourceUtil.get_timeline_directory()
|
||||
if resources_list.is_empty():
|
||||
resources_list = DialogicUtil.get_editor_setting("last_resources", [])
|
||||
if not current_file in resources_list:
|
||||
resources_list.append(current_file)
|
||||
|
||||
resources_list = clean_resource_list(resources_list)
|
||||
|
||||
%CurrentResource.text = "No Resource"
|
||||
%CurrentResource.add_theme_color_override(
|
||||
"font_uneditable_color", get_theme_color("disabled_font_color", "Editor")
|
||||
)
|
||||
|
||||
resource_tree.clear()
|
||||
|
||||
var character_items: Array = get_directory_items.call(character_directory, filter, load("res://addons/dialogic/Editor/Images/Resources/character.svg"), resources_list)
|
||||
var timeline_items: Array = get_directory_items.call(timeline_directory, filter, get_theme_icon("TripleBar", "EditorIcons"), resources_list)
|
||||
var all_items := character_items + timeline_items
|
||||
|
||||
# BUILD TREE
|
||||
var root: TreeItem = resource_tree.create_item()
|
||||
|
||||
match group_mode:
|
||||
GroupMode.NONE:
|
||||
all_items.sort_custom(_sort_by_item_text)
|
||||
for item in all_items:
|
||||
add_item(item, root, current_file)
|
||||
|
||||
|
||||
GroupMode.TYPE:
|
||||
character_items.sort_custom(_sort_by_item_text)
|
||||
timeline_items.sort_custom(_sort_by_item_text)
|
||||
if character_items.size() > 0:
|
||||
var character_tree := add_folder_item("Characters", root)
|
||||
for item in character_items:
|
||||
add_item(item, character_tree, current_file)
|
||||
|
||||
if timeline_items.size() > 0:
|
||||
var timeline_tree := add_folder_item("Timelines", root)
|
||||
for item in timeline_items:
|
||||
add_item(item, timeline_tree, current_file)
|
||||
|
||||
|
||||
GroupMode.FOLDER:
|
||||
var dirs := {}
|
||||
for item in all_items:
|
||||
var dir := item.get_parent_directory() as String
|
||||
if not dirs.has(dir):
|
||||
dirs[dir] = []
|
||||
dirs[dir].append(item)
|
||||
|
||||
for dir in dirs:
|
||||
var dir_item := add_folder_item(dir, root)
|
||||
|
||||
for item in dirs[dir]:
|
||||
add_item(item, dir_item, current_file)
|
||||
|
||||
|
||||
GroupMode.PATH:
|
||||
# Collect all different directories that contain resources
|
||||
var dirs := {}
|
||||
for item in all_items:
|
||||
var path := (item.metadata.get_base_dir() as String).trim_prefix("res://")
|
||||
if not dirs.has(path):
|
||||
dirs[path] = []
|
||||
dirs[path].append(item)
|
||||
|
||||
# Sort them into ones with the same folder name
|
||||
var dir_names := {}
|
||||
for dir in dirs:
|
||||
var sliced: String = dir.get_slice("/", dir.get_slice_count("/")-1)
|
||||
if not sliced in dir_names:
|
||||
dir_names[sliced] = {"folders":[dir]}
|
||||
else:
|
||||
dir_names[sliced].folders.append(dir)
|
||||
|
||||
# Create a dictionary mapping a unique name to each directory
|
||||
# If two have been found to have the same folder name, the parent directory is added
|
||||
var unique_folder_names := {}
|
||||
for dir_name in dir_names:
|
||||
if dir_names[dir_name].folders.size() > 1:
|
||||
for i in dir_names[dir_name].folders:
|
||||
if "/" in i:
|
||||
unique_folder_names[i.get_slice("/", i.get_slice_count("/")-2)+"/"+i.get_slice("/", i.get_slice_count("/")-1)] = i
|
||||
else:
|
||||
unique_folder_names[i] = i
|
||||
else:
|
||||
unique_folder_names[dir_name] = dir_names[dir_name].folders[0]
|
||||
|
||||
# Sort the folder names by their folder name (not by the full path)
|
||||
var sorted_dir_keys := unique_folder_names.keys()
|
||||
sorted_dir_keys.sort_custom(
|
||||
func(x, y):
|
||||
return x.get_slice("/", x.get_slice_count("/")-1) < y.get_slice("/", y.get_slice_count("/")-1)
|
||||
)
|
||||
var folder_colors: Dictionary = ProjectSettings.get_setting("file_customization/folder_colors", {})
|
||||
|
||||
for dir in sorted_dir_keys:
|
||||
var display_name: String = dir
|
||||
if not %TrimFolderPaths.button_pressed:
|
||||
display_name = unique_folder_names[dir]
|
||||
var dir_path: String = unique_folder_names[dir]
|
||||
var dir_color_path := ""
|
||||
var dir_color := Color.BLACK
|
||||
if %FolderColors.button_pressed:
|
||||
for path in folder_colors:
|
||||
if String("res://"+dir_path+"/").begins_with(path) and len(path) > len(dir_color_path):
|
||||
dir_color_path = path
|
||||
dir_color = folder_colors[path]
|
||||
|
||||
var dir_item := add_folder_item(display_name, root, dir_color, dir_path)
|
||||
|
||||
for item in dirs[dir_path]:
|
||||
add_item(item, dir_item, current_file)
|
||||
|
||||
|
||||
if %CurrentResource.text != "No Resource":
|
||||
%CurrentResource.add_theme_color_override(
|
||||
"font_uneditable_color", get_theme_color("font_color", "Editor")
|
||||
)
|
||||
|
||||
DialogicUtil.set_editor_setting("last_resources", resources_list)
|
||||
|
||||
|
||||
func add_item(item:ResourceListItem, parent:TreeItem, current_file := "") -> TreeItem:
|
||||
var tree_item := resource_tree.create_item(parent)
|
||||
tree_item.set_text(0, item.text)
|
||||
tree_item.set_icon(0, item.icon)
|
||||
tree_item.set_metadata(0, item.metadata)
|
||||
tree_item.set_tooltip_text(0, item.tooltip)
|
||||
|
||||
if item.metadata == current_file:
|
||||
%CurrentResource.text = item.metadata.get_file()
|
||||
resource_tree.set_selected(tree_item, 0)
|
||||
|
||||
var bg_color := parent.get_custom_bg_color(0)
|
||||
if bg_color != get_theme_color("base_color", "Editor"):
|
||||
bg_color.a = 0.1
|
||||
tree_item.set_custom_bg_color(0, bg_color)
|
||||
|
||||
return tree_item
|
||||
|
||||
|
||||
func add_folder_item(label: String, parent:TreeItem, color:= Color.BLACK, tooltip:="") -> TreeItem:
|
||||
var folder_item := resource_tree.create_item(parent)
|
||||
folder_item.set_text(0, label)
|
||||
folder_item.set_icon(0, get_theme_icon("Folder", "EditorIcons"))
|
||||
folder_item.set_tooltip_text(0, tooltip)
|
||||
if color == Color.BLACK:
|
||||
folder_item.set_custom_bg_color(0, get_theme_color("base_color", "Editor"))
|
||||
else:
|
||||
color.a = 0.2
|
||||
folder_item.set_custom_bg_color(0, color)
|
||||
|
||||
if label in DialogicUtil.get_editor_setting("resource_list_collapsed_info", []):
|
||||
folder_item.collapsed = true
|
||||
|
||||
return folder_item
|
||||
|
||||
|
||||
func get_directory_items(directory:Dictionary, filter:String, icon:Texture2D, resources_list:Array) -> Array:
|
||||
var items := []
|
||||
for item_name in directory:
|
||||
if (directory[item_name] in resources_list) and (filter.is_empty() or filter.to_lower() in item_name.to_lower()):
|
||||
var item := ResourceListItem.new()
|
||||
item.text = item_name
|
||||
item.icon = icon
|
||||
item.metadata = directory[item_name]
|
||||
item.tooltip = directory[item_name]
|
||||
items.append(item)
|
||||
return items
|
||||
|
||||
|
||||
class ResourceListItem:
|
||||
extends Object
|
||||
|
||||
var text: String
|
||||
var index: int = -1
|
||||
var icon: Texture
|
||||
var metadata: String
|
||||
var tooltip: String
|
||||
|
||||
func _to_string() -> String:
|
||||
return JSON.stringify(
|
||||
{
|
||||
"text": text,
|
||||
"index": index,
|
||||
"icon": icon.resource_path,
|
||||
"metadata": metadata,
|
||||
"tooltip": tooltip,
|
||||
"parent_dir": get_parent_directory()
|
||||
},
|
||||
"\t",
|
||||
false
|
||||
)
|
||||
|
||||
func get_parent_directory() -> String:
|
||||
return (metadata.get_base_dir() as String).split("/")[-1]
|
||||
|
||||
|
||||
func _sort_by_item_text(a: ResourceListItem, b: ResourceListItem) -> bool:
|
||||
return a.text < b.text
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region INTERACTING WITH RESOURCES
|
||||
|
||||
|
||||
func _on_resources_tree_item_activated() -> void:
|
||||
if resource_tree.get_selected() == null:
|
||||
return
|
||||
var item := resource_tree.get_selected()
|
||||
if item.get_metadata(0) == null:
|
||||
return
|
||||
edit_resource(item.get_metadata(0))
|
||||
|
||||
|
||||
func _on_resources_tree_item_clicked(_pos: Vector2, mouse_button_index: int) -> void:
|
||||
match mouse_button_index:
|
||||
MOUSE_BUTTON_LEFT:
|
||||
var selected_item := resource_tree.get_selected()
|
||||
if selected_item == null:
|
||||
return
|
||||
if selected_item.get_metadata(0) == null:
|
||||
return
|
||||
var resource_item := load(selected_item.get_metadata(0))
|
||||
call_deferred("edit_resource", resource_item)
|
||||
|
||||
MOUSE_BUTTON_MIDDLE:
|
||||
remove_item_from_list(resource_tree.get_selected())
|
||||
|
||||
MOUSE_BUTTON_RIGHT:
|
||||
if resource_tree.get_selected().get_metadata(0):
|
||||
%RightClickMenu.popup_on_parent(Rect2(get_global_mouse_position(), Vector2()))
|
||||
%RightClickMenu.set_meta("item_clicked", resource_tree.get_selected())
|
||||
|
||||
|
||||
func _on_resources_tree_item_collapsed(item:TreeItem) -> void:
|
||||
var collapsed_info := DialogicUtil.get_editor_setting("resource_list_collapsed_info", [])
|
||||
if item.get_text(0) in collapsed_info:
|
||||
if not item.collapsed:
|
||||
collapsed_info.erase(item.get_text(0))
|
||||
else:
|
||||
if item.collapsed:
|
||||
collapsed_info.append(item.get_text(0))
|
||||
DialogicUtil.set_editor_setting("resource_list_collapsed_info", collapsed_info)
|
||||
|
||||
|
||||
func edit_resource(resource_item: Variant) -> void:
|
||||
if resource_item is Resource:
|
||||
editors_manager.edit_resource(resource_item)
|
||||
else:
|
||||
editors_manager.edit_resource(load(resource_item))
|
||||
|
||||
|
||||
func remove_item_from_list(item: TreeItem) -> void:
|
||||
var new_list := []
|
||||
for entry in DialogicUtil.get_editor_setting("last_resources", []):
|
||||
if entry != item.get_metadata(0):
|
||||
new_list.append(entry)
|
||||
DialogicUtil.set_editor_setting("last_resources", new_list)
|
||||
update_resource_list(new_list)
|
||||
|
||||
|
||||
func _on_right_click_menu_id_pressed(id: int) -> void:
|
||||
match id:
|
||||
1: # REMOVE ITEM FROM LIST
|
||||
remove_item_from_list(%RightClickMenu.get_meta("item_clicked"))
|
||||
2: # OPEN IN FILESYSTEM
|
||||
EditorInterface.get_file_system_dock().navigate_to_path(
|
||||
%RightClickMenu.get_meta("item_clicked").get_metadata(0)
|
||||
)
|
||||
3: # OPEN IN EXTERNAL EDITOR
|
||||
OS.shell_open(
|
||||
ProjectSettings.globalize_path(
|
||||
%RightClickMenu.get_meta("item_clicked").get_metadata(0)
|
||||
)
|
||||
)
|
||||
4: # COPY IDENTIFIER
|
||||
DisplayServer.clipboard_set(
|
||||
DialogicResourceUtil.get_unique_identifier(
|
||||
%RightClickMenu.get_meta("item_clicked").get_metadata(0)
|
||||
)
|
||||
)
|
||||
#endregion
|
||||
|
||||
|
||||
#region FILTERING
|
||||
|
||||
func _on_search_text_changed(_new_text: String) -> void:
|
||||
update_resource_list()
|
||||
for item in resource_tree.get_root().get_children():
|
||||
if item.get_children().size() > 0:
|
||||
resource_tree.set_selected(item.get_child(0), 0)
|
||||
break
|
||||
|
||||
|
||||
func _on_search_text_submitted(_new_text: String) -> void:
|
||||
if resource_tree.get_selected() == null:
|
||||
return
|
||||
var item := resource_tree.get_selected()
|
||||
if item.get_metadata(0) == null:
|
||||
return
|
||||
edit_resource(item.get_metadata(0))
|
||||
%Search.clear()
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region CONTENT LIST
|
||||
|
||||
func update_content_list(list: PackedStringArray) -> void:
|
||||
var prev_selected := ""
|
||||
if %ContentList.is_anything_selected():
|
||||
prev_selected = %ContentList.get_item_text(%ContentList.get_selected_items()[0])
|
||||
%ContentList.clear()
|
||||
%ContentList.add_item("~ Top")
|
||||
for i in list:
|
||||
if i.is_empty():
|
||||
continue
|
||||
%ContentList.add_item(i)
|
||||
if i == prev_selected:
|
||||
%ContentList.select(%ContentList.item_count - 1)
|
||||
if list.is_empty():
|
||||
return
|
||||
|
||||
var current_resource: Resource = editors_manager.get_current_editor().current_resource
|
||||
|
||||
var timeline_directory := DialogicResourceUtil.get_timeline_directory()
|
||||
var label_directory := DialogicResourceUtil.get_label_cache()
|
||||
if current_resource != null:
|
||||
for i in timeline_directory:
|
||||
if timeline_directory[i] == current_resource.resource_path:
|
||||
label_directory[i] = list
|
||||
|
||||
# also always store the current timelines labels for easy access
|
||||
label_directory[""] = list
|
||||
|
||||
DialogicResourceUtil.set_label_cache(label_directory)
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region RESOURCE LIST OPTIONS
|
||||
|
||||
func _on_options_pressed() -> void:
|
||||
%OptionsPopup.popup_on_parent(Rect2(%Options.global_position+%Options.size*Vector2(0,1), Vector2()))
|
||||
|
||||
|
||||
func _on_grouping_changed(idx: int) -> void:
|
||||
var id: int = %GroupingOptions.get_item_id(idx)
|
||||
if (GroupMode as Dictionary).values().has(id):
|
||||
group_mode = (id as GroupMode)
|
||||
DialogicUtil.set_editor_setting("sidebar_group_mode", id)
|
||||
update_resource_list()
|
||||
|
||||
%FolderColors.disabled = group_mode != GroupMode.PATH
|
||||
%TrimFolderPaths.disabled = group_mode != GroupMode.PATH
|
||||
|
||||
|
||||
func _on_folder_colors_toggled(toggled_on: bool) -> void:
|
||||
DialogicUtil.set_editor_setting("sidebar_use_folder_colors", toggled_on)
|
||||
update_resource_list()
|
||||
|
||||
|
||||
func _on_trim_folder_paths_toggled(toggled_on: bool) -> void:
|
||||
DialogicUtil.set_editor_setting("sidebar_trim_folder_paths", toggled_on)
|
||||
update_resource_list()
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
func _on_main_v_split_dragged(offset: int) -> void:
|
||||
DialogicUtil.set_editor_setting("sidebar_v_split", offset)
|
||||
1
addons/dialogic/Editor/Common/sidebar.gd.uid
Normal file
1
addons/dialogic/Editor/Common/sidebar.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bbsxh24r01ali
|
||||
49
addons/dialogic/Editor/Common/toolbar.gd
Normal file
49
addons/dialogic/Editor/Common/toolbar.gd
Normal file
@@ -0,0 +1,49 @@
|
||||
@tool
|
||||
extends HBoxContainer
|
||||
|
||||
# Dialogic Editor toolbar. Works together with editors_mangager.
|
||||
|
||||
################################################################################
|
||||
## EDITOR BUTTONS/LABELS
|
||||
################################################################################
|
||||
func _ready() -> void:
|
||||
if owner.get_parent() is SubViewport:
|
||||
return
|
||||
%CustomButtons.custom_minimum_size.y = 33 * DialogicUtil.get_editor_scale()
|
||||
|
||||
for child in get_children():
|
||||
if child is Button:
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func add_icon_button(icon: Texture, tooltip: String) -> Button:
|
||||
var button := Button.new()
|
||||
button.icon = icon
|
||||
button.tooltip_text = tooltip
|
||||
button.flat = true
|
||||
button.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
button.add_theme_color_override('icon_hover_color', get_theme_color('warning_color', 'Editor'))
|
||||
button.add_theme_stylebox_override('focus', StyleBoxEmpty.new())
|
||||
add_child(button)
|
||||
move_child(button, -2)
|
||||
return button
|
||||
|
||||
|
||||
func add_custom_button(label:String, icon:Texture) -> Button:
|
||||
var button := Button.new()
|
||||
button.text = label
|
||||
button.icon = icon
|
||||
# button.flat = true
|
||||
|
||||
button.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
%CustomButtons.add_child(button)
|
||||
# custom_minimum_size.y = button.size.y
|
||||
return button
|
||||
|
||||
|
||||
func hide_all_custom_buttons() -> void:
|
||||
for button in %CustomButtons.get_children():
|
||||
button.hide()
|
||||
|
||||
|
||||
|
||||
1
addons/dialogic/Editor/Common/toolbar.gd.uid
Normal file
1
addons/dialogic/Editor/Common/toolbar.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://btsx2sqodaqns
|
||||
95
addons/dialogic/Editor/Common/unique_identifiers_manager.gd
Normal file
95
addons/dialogic/Editor/Common/unique_identifiers_manager.gd
Normal file
@@ -0,0 +1,95 @@
|
||||
@tool
|
||||
extends PanelContainer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if owner.get_parent() is SubViewport:
|
||||
return
|
||||
|
||||
%TabB.text = "Unique Identifiers"
|
||||
%TabB.icon = get_theme_icon("CryptoKey", "EditorIcons")
|
||||
|
||||
owner.get_parent().visibility_changed.connect(func(): if is_visible_in_tree(): open())
|
||||
|
||||
%RenameNotification.add_theme_color_override("font_color", get_theme_color("warning_color", "Editor"))
|
||||
|
||||
|
||||
func open() -> void:
|
||||
fill_table()
|
||||
%RenameNotification.hide()
|
||||
|
||||
|
||||
func close() -> void:
|
||||
pass
|
||||
|
||||
func fill_table() -> void:
|
||||
var t: Tree = %IdentifierTable
|
||||
t.set_column_expand(1, true)
|
||||
t.clear()
|
||||
t.set_column_title(1, "Identifier")
|
||||
t.set_column_title(0, "Resource Path")
|
||||
t.set_column_title_alignment(0, 0)
|
||||
t.set_column_title_alignment(1, 0)
|
||||
t.create_item()
|
||||
|
||||
for d in [["Characters", 'dch'], ["Timelines", "dtl"]]:
|
||||
var directory := DialogicResourceUtil.get_directory(d[1])
|
||||
var directory_item := t.create_item()
|
||||
directory_item.set_text(0, d[0])
|
||||
directory_item.set_metadata(0, d[1])
|
||||
for key in directory:
|
||||
var item: TreeItem = t.create_item(directory_item)
|
||||
item.set_text(0, directory[key])
|
||||
item.set_text(1, key)
|
||||
item.set_editable(1, true)
|
||||
item.set_metadata(1, key)
|
||||
item.add_button(1, get_theme_icon("Edit", "EditorIcons"), 0, false, "Edit")
|
||||
|
||||
|
||||
func _on_identifier_table_item_edited() -> void:
|
||||
var item: TreeItem = %IdentifierTable.get_edited()
|
||||
var new_identifier: String = item.get_text(1)
|
||||
|
||||
|
||||
if new_identifier == item.get_metadata(1):
|
||||
return
|
||||
|
||||
if new_identifier.is_empty() or not DialogicResourceUtil.is_identifier_unused(item.get_parent().get_metadata(0), new_identifier):
|
||||
item.set_text(1, item.get_metadata(1))
|
||||
return
|
||||
|
||||
DialogicResourceUtil.change_unique_identifier(item.get_text(0), new_identifier)
|
||||
|
||||
match item.get_parent().get_metadata(0):
|
||||
'dch':
|
||||
owner.get_parent().add_character_name_ref_change(item.get_metadata(1), new_identifier)
|
||||
'dtl':
|
||||
owner.get_parent().add_timeline_name_ref_change(item.get_metadata(1), new_identifier)
|
||||
|
||||
%RenameNotification.show()
|
||||
item.set_metadata(1, new_identifier)
|
||||
|
||||
|
||||
func _on_identifier_table_button_clicked(item: TreeItem, column: int, id: int, mouse_button_index: int) -> void:
|
||||
item.select(column)
|
||||
%IdentifierTable.edit_selected(true)
|
||||
|
||||
|
||||
func filter_tree(filter:String= "", item:TreeItem = null) -> bool:
|
||||
if item == null:
|
||||
item = %IdentifierTable.get_root()
|
||||
|
||||
var any := false
|
||||
for child in item.get_children():
|
||||
if child.get_child_count() > 0:
|
||||
child.visible = filter_tree(filter, child)
|
||||
if child.visible: any = true
|
||||
else:
|
||||
child.visible = filter.is_empty() or filter.to_lower() in child.get_text(0).to_lower() or filter.to_lower() in child.get_text(1).to_lower()
|
||||
if child.visible: any = true
|
||||
|
||||
return any
|
||||
|
||||
|
||||
func _on_search_text_changed(new_text: String) -> void:
|
||||
filter_tree(new_text)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cua4voas2kcfm
|
||||
180
addons/dialogic/Editor/Common/update_install_window.gd
Normal file
180
addons/dialogic/Editor/Common/update_install_window.gd
Normal file
@@ -0,0 +1,180 @@
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
var current_info := {}
|
||||
@onready var editor_view := find_parent('EditorView')
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
await editor_view.ready
|
||||
theme = editor_view.theme
|
||||
|
||||
%Install.icon = editor_view.get_theme_icon("AssetLib", "EditorIcons")
|
||||
%LoadingIcon.texture = editor_view.get_theme_icon("KeyTrackScale", "EditorIcons")
|
||||
%InstallWarning.modulate = editor_view.get_theme_color("warning_color", "Editor")
|
||||
%CloseButton.icon = editor_view.get_theme_icon("Close", "EditorIcons")
|
||||
DialogicUtil.get_dialogic_plugin().get_editor_interface().get_resource_filesystem().resources_reimported.connect(_on_resources_reimported)
|
||||
|
||||
|
||||
func open() -> void:
|
||||
get_parent().popup_centered_ratio(0.5)
|
||||
get_parent().mode = Window.MODE_WINDOWED
|
||||
get_parent().move_to_foreground()
|
||||
get_parent().grab_focus()
|
||||
|
||||
|
||||
func load_info(info:Dictionary, update_type:int) -> void:
|
||||
current_info = info
|
||||
if update_type == 2:
|
||||
%State.text = "No Information Available"
|
||||
%UpdateName.text = "Unable to access versions."
|
||||
%UpdateName.add_theme_color_override("font_color", editor_view.get_theme_color("readonly_color", "Editor"))
|
||||
%Content.text = "You are probably not connected to the internet. Fair enough."
|
||||
%ShortInfo.text = "Huh, what happened here?"
|
||||
%ReadFull.hide()
|
||||
%Install.disabled = true
|
||||
return
|
||||
|
||||
# If we are up to date (or beyond):
|
||||
if info.is_empty():
|
||||
info['name'] = "You are in the future, Marty!"
|
||||
info["body"] = "# 😎 You are using the WIP branch!\nSeems like you are using a version that isn't even released yet. Be careful and give us your feedback ;)"
|
||||
info["published_at"] = "????T"
|
||||
info["author"] = {'login':"???"}
|
||||
%State.text = "Where are we Doc?"
|
||||
%UpdateName.add_theme_color_override("font_color", editor_view.get_theme_color("property_color_z", "Editor"))
|
||||
%Install.disabled = true
|
||||
|
||||
elif update_type == 0:
|
||||
%State.text = "Update Available!"
|
||||
%UpdateName.add_theme_color_override("font_color", editor_view.get_theme_color("warning_color", "Editor"))
|
||||
%Install.disabled = false
|
||||
else:
|
||||
%State.text = "You are up to date:"
|
||||
%UpdateName.add_theme_color_override("font_color", editor_view.get_theme_color("success_color", "Editor"))
|
||||
%Install.disabled = true
|
||||
|
||||
%UpdateName.text = info.name
|
||||
%Content.text = markdown_to_bbcode(info.body).get_slice("\n[font_size", 0).strip_edges()
|
||||
%ShortInfo.text = "Published on "+info.published_at.substr(0, info.published_at.find('T'))+" by "+info.author.login
|
||||
if info.has("html_url"):
|
||||
%ReadFull.uri = info.html_url
|
||||
%ReadFull.show()
|
||||
else:
|
||||
%ReadFull.hide()
|
||||
if info.has('reactions'):
|
||||
%Reactions.show()
|
||||
var reactions := {"laugh":"😂", "hooray":"🎉", "confused":"😕", "heart":"❤️", "rocket":"🚀", "eyes":"👀"}
|
||||
for i in reactions:
|
||||
%Reactions.get_node(i.capitalize()).visible = info.reactions[i] > 0
|
||||
%Reactions.get_node(i.capitalize()).text = reactions[i]+" "+str(info.reactions[i]) if info.reactions[i] > 0 else reactions[i]
|
||||
if info.reactions['+1']+info.reactions['-1'] > 0:
|
||||
%Reactions.get_node("Likes").visible = true
|
||||
%Reactions.get_node("Likes").text = "👍 "+str(info.reactions['+1']+info.reactions['-1'])
|
||||
else:
|
||||
%Reactions.get_node("Likes").visible = false
|
||||
else:
|
||||
%Reactions.hide()
|
||||
|
||||
func _on_window_close_requested() -> void:
|
||||
get_parent().visible = false
|
||||
|
||||
|
||||
func _on_install_pressed() -> void:
|
||||
find_parent('UpdateManager').request_update_download()
|
||||
|
||||
%InfoLabel.text = "Downloading. This can take a moment."
|
||||
%Loading.show()
|
||||
%LoadingIcon.create_tween().set_loops().tween_property(%LoadingIcon, 'rotation', 2*PI, 1).from(0)
|
||||
|
||||
|
||||
func _on_refresh_pressed() -> void:
|
||||
find_parent('UpdateManager').request_update_check()
|
||||
|
||||
|
||||
func _on_update_manager_downdload_completed(result:int):
|
||||
%Loading.hide()
|
||||
match result:
|
||||
0: # success
|
||||
%InfoLabel.text = "Installed successfully. Restart needed!"
|
||||
%InfoLabel.modulate = editor_view.get_theme_color("success_color", "Editor")
|
||||
%Restart.show()
|
||||
%Restart.grab_focus()
|
||||
1: # failure
|
||||
%InfoLabel.text = "Download failed."
|
||||
%InfoLabel.modulate = editor_view.get_theme_color("readonly_color", "Editor")
|
||||
|
||||
|
||||
func _on_resources_reimported(resources:Array) -> void:
|
||||
if is_inside_tree():
|
||||
await get_tree().process_frame
|
||||
get_parent().move_to_foreground()
|
||||
|
||||
|
||||
func markdown_to_bbcode(text:String) -> String:
|
||||
var font_sizes := {1:20, 2:16, 3:16,4:14, 5:14}
|
||||
var title_regex := RegEx.create_from_string('(^|\n)((?<level>#+)(?<title>.*))\\n')
|
||||
var res := title_regex.search(text)
|
||||
while res:
|
||||
text = text.replace(res.get_string(2), '[font_size='+str(font_sizes[len(res.get_string('level'))])+']'+res.get_string('title').strip_edges()+'[/font_size]')
|
||||
res = title_regex.search(text)
|
||||
|
||||
var link_regex := RegEx.create_from_string('(?<!\\!)\\[(?<text>[^\\]]*)]\\((?<link>[^)]*)\\)')
|
||||
res = link_regex.search(text)
|
||||
while res:
|
||||
text = text.replace(res.get_string(), '[url='+res.get_string('link')+']'+res.get_string('text').strip_edges()+'[/url]')
|
||||
res = link_regex.search(text)
|
||||
|
||||
var image_regex := RegEx.create_from_string('\\!\\[(?<text>[^\\]]*)]\\((?<link>[^)]*)\\)\n*')
|
||||
res = image_regex.search(text)
|
||||
while res:
|
||||
text = text.replace(res.get_string(), '[url='+res.get_string('link')+']'+res.get_string('text').strip_edges()+'[/url]')
|
||||
res = image_regex.search(text)
|
||||
|
||||
var italics_regex := RegEx.create_from_string('\\*(?<text>[^\\*\\n]*)\\*')
|
||||
res = italics_regex.search(text)
|
||||
while res:
|
||||
text = text.replace(res.get_string(), '[i]'+res.get_string('text').strip_edges()+'[/i]')
|
||||
res = italics_regex.search(text)
|
||||
|
||||
var bullets_regex := RegEx.create_from_string('(?<=\\n)(\\*|-)(?<text>[^\\*\\n]*)\\n')
|
||||
res = bullets_regex.search(text)
|
||||
while res:
|
||||
text = text.replace(res.get_string(), '[ul]'+res.get_string('text').strip_edges()+'[/ul]\n')
|
||||
res = bullets_regex.search(text)
|
||||
|
||||
var small_code_regex := RegEx.create_from_string('(?<!`)`(?<text>[^`]+)`')
|
||||
res = small_code_regex.search(text)
|
||||
while res:
|
||||
text = text.replace(res.get_string(), '[code][color='+get_theme_color("accent_color", "Editor").to_html()+']'+res.get_string('text').strip_edges()+'[/color][/code]')
|
||||
res = small_code_regex.search(text)
|
||||
|
||||
var big_code_regex := RegEx.create_from_string('(?<!`)```(?<text>[^`]+)```')
|
||||
res = big_code_regex.search(text)
|
||||
while res:
|
||||
text = text.replace(res.get_string(), '[code][bgcolor='+get_theme_color("box_selection_fill_color", "Editor").to_html()+']'+res.get_string('text').strip_edges()+'[/bgcolor][/code]')
|
||||
res = big_code_regex.search(text)
|
||||
|
||||
return text
|
||||
|
||||
|
||||
|
||||
func _on_content_meta_clicked(meta:Variant) -> void:
|
||||
OS.shell_open(str(meta))
|
||||
|
||||
|
||||
func _on_install_mouse_entered() -> void:
|
||||
if not %Install.disabled:
|
||||
%InstallWarning.show()
|
||||
|
||||
|
||||
func _on_install_mouse_exited() -> void:
|
||||
%InstallWarning.hide()
|
||||
|
||||
|
||||
func _on_restart_pressed() -> void:
|
||||
DialogicUtil.get_dialogic_plugin().get_editor_interface().restart_editor(true)
|
||||
|
||||
|
||||
func _on_close_button_pressed() -> void:
|
||||
get_parent().hide()
|
||||
@@ -0,0 +1 @@
|
||||
uid://bdjggd3qpyo6l
|
||||
308
addons/dialogic/Editor/Common/update_install_window.tscn
Normal file
308
addons/dialogic/Editor/Common/update_install_window.tscn
Normal file
@@ -0,0 +1,308 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://vv3m5m68fwg7"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/update_install_window.gd" id="1_p1pbx"]
|
||||
[ext_resource type="Texture2D" uid="uid://dybg3l5pwetne" path="res://addons/dialogic/Editor/Images/plugin-icon.svg" id="2_20ke0"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_lt7uf"]
|
||||
colors = PackedColorArray(0.296484, 0.648457, 1, 1, 0.732014, 0.389374, 1, 1)
|
||||
|
||||
[sub_resource type="GradientTexture2D" id="GradientTexture2D_nl8ke"]
|
||||
gradient = SubResource("Gradient_lt7uf")
|
||||
fill_from = Vector2(0.151515, 0.272727)
|
||||
fill_to = Vector2(1, 1)
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1g1am"]
|
||||
content_margin_left = 0.0
|
||||
content_margin_top = 15.0
|
||||
content_margin_right = 15.0
|
||||
content_margin_bottom = 15.0
|
||||
bg_color = Color(0.0627451, 0.0627451, 0.0627451, 0.407843)
|
||||
corner_radius_top_left = 20
|
||||
corner_radius_top_right = 20
|
||||
corner_radius_bottom_right = 20
|
||||
corner_radius_bottom_left = 20
|
||||
expand_margin_left = 20.0
|
||||
expand_margin_right = 20.0
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_j1mw2"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_h4v2s"]
|
||||
content_margin_left = 5.0
|
||||
content_margin_top = 3.0
|
||||
content_margin_right = 5.0
|
||||
content_margin_bottom = 3.0
|
||||
bg_color = Color(0, 0, 0, 0.631373)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_utju1"]
|
||||
content_margin_left = 5.0
|
||||
content_margin_top = 3.0
|
||||
content_margin_right = 5.0
|
||||
content_margin_bottom = 3.0
|
||||
bg_color = Color(0.0470588, 0.0470588, 0.0470588, 1)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[node name="UpdateInstallWindow" type="ColorRect"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.207843, 0.129412, 0.372549, 1)
|
||||
script = ExtResource("1_p1pbx")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
modulate = Color(0.447059, 0.447059, 0.447059, 1)
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = SubResource("GradientTexture2D_nl8ke")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 14.0
|
||||
offset_top = 13.0
|
||||
offset_right = -14.0
|
||||
offset_bottom = -13.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Control" type="Control" parent="VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 7
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="VBoxContainer/HBoxContainer2"]
|
||||
custom_minimum_size = Vector2(450, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 3.74
|
||||
alignment = 1
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/HBoxContainer2/VBox"]
|
||||
clip_contents = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
alignment = 1
|
||||
|
||||
[node name="Panel" type="PanelContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_1g1am")
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Panel"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = -8
|
||||
|
||||
[node name="State" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Panel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"DialogicSubTitle"
|
||||
text = "Update Available!"
|
||||
|
||||
[node name="UpdateName" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Panel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"DialogicTitle"
|
||||
theme_override_font_sizes/font_size = 25
|
||||
text = "Dialogic 2.0 - alpha 9"
|
||||
uppercase = true
|
||||
|
||||
[node name="ShortInfo" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Panel/VBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"DialogicHintText2"
|
||||
theme_override_font_sizes/font_size = 10
|
||||
text = "12/31/23"
|
||||
|
||||
[node name="Refresh" type="Button" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Panel"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 0
|
||||
text = "Refresh
|
||||
"
|
||||
flat = true
|
||||
|
||||
[node name="Content" type="RichTextLabel" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_font_sizes/normal_font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxEmpty_j1mw2")
|
||||
bbcode_enabled = true
|
||||
text = "[font_size=25]🎉 New alpha, new stuff![/font_size]
|
||||
If you are using dialogic 2 alphas then we've got an exciting update. It's not the beta yet, but we are getting closer! As always if you have questions or feedback it's best to reach out on [url=https://discord.gg/2hHQzkf2pX]emilios discord[/url].
|
||||
|
||||
This alpha brings a couple of very useful new features to dialogic as well as some syntax changes and a design overhaul (and many, many bug fixes).
|
||||
"
|
||||
fit_content = true
|
||||
|
||||
[node name="Reactions" type="HBoxContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Likes" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_h4v2s")
|
||||
text = "👍12"
|
||||
|
||||
[node name="Hooray" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_h4v2s")
|
||||
text = "🎉12"
|
||||
|
||||
[node name="Laugh" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_h4v2s")
|
||||
text = "👀12"
|
||||
|
||||
[node name="Heart" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_h4v2s")
|
||||
text = "❤️12"
|
||||
|
||||
[node name="Rocket" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_h4v2s")
|
||||
text = "😕12"
|
||||
|
||||
[node name="Eyes" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_h4v2s")
|
||||
text = "🚀12"
|
||||
|
||||
[node name="Confused" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_h4v2s")
|
||||
text = "😂12"
|
||||
|
||||
[node name="ReadFull" type="LinkButton" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Reactions"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 10
|
||||
text = "Read Full Announcement"
|
||||
|
||||
[node name="Control" type="Control" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 20)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 2
|
||||
|
||||
[node name="InfoLabel" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
horizontal_alignment = 2
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer"]
|
||||
self_modulate = Color(0, 0, 0, 1)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_h4v2s")
|
||||
|
||||
[node name="HBox" type="HBoxContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 2
|
||||
|
||||
[node name="Loading" type="CenterContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(30, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Control" type="Control" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Loading"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="LoadingIcon" type="Sprite2D" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Loading/Control"]
|
||||
unique_name_in_owner = true
|
||||
texture = ExtResource("2_20ke0")
|
||||
|
||||
[node name="Restart" type="Button" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
text = "Restart Now"
|
||||
flat = true
|
||||
|
||||
[node name="Install" type="Button" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
text = "Install"
|
||||
flat = true
|
||||
|
||||
[node name="InstallWarning" type="PanelContainer" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Install"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
self_modulate = Color(0, 0, 0, 1)
|
||||
layout_mode = 1
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -493.0
|
||||
offset_top = -92.0
|
||||
offset_right = 5.0
|
||||
offset_bottom = -8.0
|
||||
grow_horizontal = 0
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_utju1")
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Install/InstallWarning"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Be careful. This will delete the addons/dialogic folder and install the new version. Any custom changes in that folder will be lost.
|
||||
To be on the save side, use version control!"
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="Control2" type="Control" parent="VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 7
|
||||
|
||||
[node name="Close" type="HBoxContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="CloseButton" type="Button" parent="VBoxContainer/Close"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Close"
|
||||
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Panel/Refresh" to="." method="_on_refresh_pressed"]
|
||||
[connection signal="meta_clicked" from="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/Content" to="." method="_on_content_meta_clicked"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Restart" to="." method="_on_restart_pressed"]
|
||||
[connection signal="mouse_entered" from="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Install" to="." method="_on_install_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Install" to="." method="_on_install_mouse_exited"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer2/VBox/ScrollContainer/VBoxContainer/HBoxContainer/PanelContainer/HBox/Install" to="." method="_on_install_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Close/CloseButton" to="." method="_on_close_button_pressed"]
|
||||
190
addons/dialogic/Editor/Common/update_manager.gd
Normal file
190
addons/dialogic/Editor/Common/update_manager.gd
Normal file
@@ -0,0 +1,190 @@
|
||||
@tool
|
||||
extends Node
|
||||
|
||||
## Script that checks for new versions and can install them.
|
||||
|
||||
signal update_check_completed(result:UpdateCheckResult)
|
||||
signal downdload_completed(result:DownloadResult)
|
||||
|
||||
enum UpdateCheckResult {UPDATE_AVAILABLE, UP_TO_DATE, NO_ACCESS}
|
||||
enum DownloadResult {SUCCESS, FAILURE}
|
||||
enum ReleaseState {ALPHA, BETA, STABLE}
|
||||
|
||||
const REMOTE_RELEASES_URL := "https://api.github.com/repos/dialogic-godot/dialogic/releases"
|
||||
const TEMP_FILE_NAME := "user://temp.zip"
|
||||
|
||||
var current_version := ""
|
||||
var update_info: Dictionary
|
||||
var current_info: Dictionary
|
||||
|
||||
var version_indicator: Button
|
||||
|
||||
func _ready() -> void:
|
||||
request_update_check()
|
||||
|
||||
setup_version_indicator()
|
||||
|
||||
|
||||
|
||||
func get_current_version() -> String:
|
||||
var plugin_cfg := ConfigFile.new()
|
||||
plugin_cfg.load("res://addons/dialogic/plugin.cfg")
|
||||
return plugin_cfg.get_value('plugin', 'version', 'unknown version')
|
||||
|
||||
|
||||
func request_update_check() -> void:
|
||||
if $UpdateCheckRequest.get_http_client_status() == HTTPClient.STATUS_DISCONNECTED:
|
||||
$UpdateCheckRequest.request(REMOTE_RELEASES_URL)
|
||||
|
||||
|
||||
func _on_UpdateCheck_request_completed(result:int, response_code:int, headers:PackedStringArray, body:PackedByteArray) -> void:
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
update_check_completed.emit(UpdateCheckResult.NO_ACCESS)
|
||||
return
|
||||
|
||||
# Work out the next version from the releases information on GitHub
|
||||
var response: Variant = JSON.parse_string(body.get_string_from_utf8())
|
||||
if typeof(response) != TYPE_ARRAY: return
|
||||
|
||||
|
||||
var current_release_info := get_release_tag_info(get_current_version())
|
||||
|
||||
# GitHub releases are in order of creation, not order of version
|
||||
var versions: Array = (response as Array).filter(compare_versions.bind(current_release_info))
|
||||
if versions.size() > 0:
|
||||
update_info = versions[0]
|
||||
update_check_completed.emit(UpdateCheckResult.UPDATE_AVAILABLE)
|
||||
else:
|
||||
update_info = current_info
|
||||
update_check_completed.emit(UpdateCheckResult.UP_TO_DATE)
|
||||
|
||||
|
||||
func compare_versions(release, current_release_info:Dictionary) -> bool:
|
||||
var checked_release_info := get_release_tag_info(release.tag_name)
|
||||
|
||||
if checked_release_info.major < current_release_info.major:
|
||||
return false
|
||||
|
||||
if checked_release_info.minor < current_release_info.minor:
|
||||
return false
|
||||
|
||||
if checked_release_info.state < current_release_info.state:
|
||||
return false
|
||||
|
||||
elif checked_release_info.state == current_release_info.state:
|
||||
if checked_release_info.state_version < current_release_info.state_version:
|
||||
return false
|
||||
|
||||
if checked_release_info.state_version == current_release_info.state_version:
|
||||
current_info = release
|
||||
return false
|
||||
|
||||
if checked_release_info.state == ReleaseState.STABLE:
|
||||
if checked_release_info.minor == current_release_info.minor:
|
||||
current_info = release
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
func get_release_tag_info(release_tag:String) -> Dictionary:
|
||||
release_tag = release_tag.strip_edges().trim_prefix('v')
|
||||
release_tag = release_tag.substr(0, release_tag.find('('))
|
||||
release_tag = release_tag.to_lower()
|
||||
|
||||
var regex := RegEx.create_from_string(r"(?<major>\d+\.\d+)(-(?<state>alpha|beta)-)?(?(2)(?<stateversion>\d*)|\.(?<minor>\d*))?")
|
||||
|
||||
var result: RegExMatch = regex.search(release_tag)
|
||||
if !result:
|
||||
return {}
|
||||
|
||||
var info: Dictionary = {'tag':release_tag}
|
||||
info['major'] = float(result.get_string('major'))
|
||||
info['minor'] = int(result.get_string('minor'))
|
||||
|
||||
match result.get_string('state'):
|
||||
'alpha':
|
||||
info['state'] = ReleaseState.ALPHA
|
||||
'beta':
|
||||
info['state'] = ReleaseState.BETA
|
||||
_:
|
||||
info['state'] = ReleaseState.STABLE
|
||||
|
||||
info['state_version'] = int(result.get_string('stateversion'))
|
||||
|
||||
return info
|
||||
|
||||
|
||||
func request_update_download() -> void:
|
||||
# Safeguard the actual dialogue manager repo from accidentally updating itself
|
||||
if DirAccess.dir_exists_absolute("res://test-project/"):
|
||||
prints("[Dialogic] Looks like you are working on the addon. You can't update the addon from within itself.")
|
||||
downdload_completed.emit(DownloadResult.FAILURE)
|
||||
return
|
||||
|
||||
$DownloadRequest.request(update_info.zipball_url)
|
||||
|
||||
|
||||
func _on_DownloadRequest_completed(result:int, response_code:int, headers:PackedStringArray, body:PackedByteArray):
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
downdload_completed.emit(DownloadResult.FAILURE)
|
||||
return
|
||||
|
||||
# Save the downloaded zip
|
||||
var zip_file: FileAccess = FileAccess.open(TEMP_FILE_NAME, FileAccess.WRITE)
|
||||
zip_file.store_buffer(body)
|
||||
zip_file.close()
|
||||
|
||||
OS.move_to_trash(ProjectSettings.globalize_path("res://addons/dialogic"))
|
||||
|
||||
var zip_reader: ZIPReader = ZIPReader.new()
|
||||
zip_reader.open(TEMP_FILE_NAME)
|
||||
var files: PackedStringArray = zip_reader.get_files()
|
||||
|
||||
var base_path: String = files[0].path_join('addons/')
|
||||
for path in files:
|
||||
if not "dialogic/" in path:
|
||||
continue
|
||||
|
||||
var new_file_path: String = path.replace(base_path, "")
|
||||
if path.ends_with("/"):
|
||||
DirAccess.make_dir_recursive_absolute("res://addons/".path_join(new_file_path))
|
||||
else:
|
||||
var file: FileAccess = FileAccess.open("res://addons/".path_join(new_file_path), FileAccess.WRITE)
|
||||
file.store_buffer(zip_reader.read_file(path))
|
||||
|
||||
zip_reader.close()
|
||||
DirAccess.remove_absolute(TEMP_FILE_NAME)
|
||||
|
||||
downdload_completed.emit(DownloadResult.SUCCESS)
|
||||
|
||||
|
||||
###################### SOME UI MANAGEMENT #####################################
|
||||
################################################################################
|
||||
|
||||
func setup_version_indicator() -> void:
|
||||
version_indicator = %Sidebar.get_node('%CurrentVersion')
|
||||
version_indicator.pressed.connect($Window/UpdateInstallWindow.open)
|
||||
version_indicator.text = get_current_version()
|
||||
|
||||
|
||||
func _on_update_check_completed(result:int):
|
||||
var result_color: Color
|
||||
match result:
|
||||
UpdateCheckResult.UPDATE_AVAILABLE:
|
||||
result_color = version_indicator.get_theme_color("warning_color", "Editor")
|
||||
version_indicator.icon = version_indicator.get_theme_icon("StatusWarning", "EditorIcons")
|
||||
$Window/UpdateInstallWindow.load_info(update_info, result)
|
||||
UpdateCheckResult.UP_TO_DATE:
|
||||
result_color = version_indicator.get_theme_color("success_color", "Editor")
|
||||
version_indicator.icon = version_indicator.get_theme_icon("StatusSuccess", "EditorIcons")
|
||||
$Window/UpdateInstallWindow.load_info(current_info, result)
|
||||
UpdateCheckResult.NO_ACCESS:
|
||||
result_color = version_indicator.get_theme_color("success_color", "Editor")
|
||||
version_indicator.icon = version_indicator.get_theme_icon("GuiRadioCheckedDisabled", "EditorIcons")
|
||||
$Window/UpdateInstallWindow.load_info(update_info, result)
|
||||
|
||||
version_indicator.add_theme_color_override('font_color', result_color)
|
||||
version_indicator.add_theme_color_override('font_hover_color', result_color.lightened(0.5))
|
||||
version_indicator.add_theme_color_override('font_pressed_color', result_color)
|
||||
version_indicator.add_theme_color_override('font_focus_color', result_color)
|
||||
1
addons/dialogic/Editor/Common/update_manager.gd.uid
Normal file
1
addons/dialogic/Editor/Common/update_manager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d0tnm3fgvf0kb
|
||||
Reference in New Issue
Block a user