Add more NPCs, update dialogue manager to 4.4 compatible version
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
@tool
|
||||
extends CodeEdit
|
||||
class_name DMCodeEdit extends CodeEdit
|
||||
|
||||
|
||||
signal active_title_change(title: String)
|
||||
@@ -7,10 +7,6 @@ signal error_clicked(line_number: int)
|
||||
signal external_file_requested(path: String, title: String)
|
||||
|
||||
|
||||
const DialogueManagerParser = preload("./parser.gd")
|
||||
const DialogueSyntaxHighlighter = preload("./code_edit_syntax_highlighter.gd")
|
||||
|
||||
|
||||
# A link back to the owner `MainView`
|
||||
var main_view
|
||||
|
||||
@@ -19,7 +15,7 @@ var theme_overrides: Dictionary:
|
||||
set(value):
|
||||
theme_overrides = value
|
||||
|
||||
syntax_highlighter = DialogueSyntaxHighlighter.new()
|
||||
syntax_highlighter = DMSyntaxHighlighter.new()
|
||||
|
||||
# General UI
|
||||
add_theme_color_override("font_color", theme_overrides.text_color)
|
||||
@@ -67,7 +63,7 @@ func _ready() -> void:
|
||||
if not has_comment_delimiter("#"):
|
||||
add_comment_delimiter("#", "", true)
|
||||
|
||||
syntax_highlighter = DialogueSyntaxHighlighter.new()
|
||||
syntax_highlighter = DMSyntaxHighlighter.new()
|
||||
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
@@ -111,26 +107,34 @@ func _can_drop_data(at_position: Vector2, data) -> bool:
|
||||
if typeof(data) != TYPE_DICTIONARY: return false
|
||||
if data.type != "files": return false
|
||||
|
||||
var files: PackedStringArray = Array(data.files).filter(func(f): return f.get_extension() == "dialogue")
|
||||
var files: PackedStringArray = Array(data.files)
|
||||
return files.size() > 0
|
||||
|
||||
|
||||
func _drop_data(at_position: Vector2, data) -> void:
|
||||
var replace_regex: RegEx = RegEx.create_from_string("[^a-zA-Z_0-9]+")
|
||||
|
||||
var files: PackedStringArray = Array(data.files).filter(func(f): return f.get_extension() == "dialogue")
|
||||
var files: PackedStringArray = Array(data.files)
|
||||
for file in files:
|
||||
# Don't import the file into itself
|
||||
if file == main_view.current_file_path: continue
|
||||
|
||||
var path = file.replace("res://", "").replace(".dialogue", "")
|
||||
# Find the first non-import line in the file to add our import
|
||||
var lines = text.split("\n")
|
||||
for i in range(0, lines.size()):
|
||||
if not lines[i].begins_with("import "):
|
||||
insert_line_at(i, "import \"%s\" as %s\n" % [file, replace_regex.sub(path, "_", true)])
|
||||
set_caret_line(i)
|
||||
break
|
||||
if file.get_extension() == "dialogue":
|
||||
var path = file.replace("res://", "").replace(".dialogue", "")
|
||||
# Find the first non-import line in the file to add our import
|
||||
var lines = text.split("\n")
|
||||
for i in range(0, lines.size()):
|
||||
if not lines[i].begins_with("import "):
|
||||
insert_line_at(i, "import \"%s\" as %s\n" % [file, replace_regex.sub(path, "_", true)])
|
||||
set_caret_line(i)
|
||||
break
|
||||
else:
|
||||
var cursor: Vector2 = get_line_column_at_pos(at_position)
|
||||
if cursor.x > -1 and cursor.y > -1:
|
||||
set_cursor(cursor)
|
||||
remove_secondary_carets()
|
||||
insert_text("\"%s\"" % file, cursor.y, cursor.x)
|
||||
grab_focus()
|
||||
|
||||
|
||||
func _request_code_completion(force: bool) -> void:
|
||||
@@ -151,17 +155,18 @@ func _request_code_completion(force: bool) -> void:
|
||||
add_code_completion_option(CodeEdit.KIND_CLASS, "END!", "END!".substr(prompt.length()), theme_overrides.text_color, get_theme_icon("Stop", "EditorIcons"))
|
||||
|
||||
# Get all titles, including those in imports
|
||||
var parser: DialogueManagerParser = DialogueManagerParser.new()
|
||||
parser.prepare(text, main_view.current_file_path, false)
|
||||
for title in parser.titles:
|
||||
if "/" in title:
|
||||
for title: String in DMCompiler.get_titles_in_text(text, main_view.current_file_path):
|
||||
# Ignore any imported titles that aren't resolved to human readable.
|
||||
if title.to_int() > 0:
|
||||
continue
|
||||
|
||||
elif "/" in title:
|
||||
var bits = title.split("/")
|
||||
if matches_prompt(prompt, bits[0]) or matches_prompt(prompt, bits[1]):
|
||||
add_code_completion_option(CodeEdit.KIND_CLASS, title, title.substr(prompt.length()), theme_overrides.text_color, get_theme_icon("CombineLines", "EditorIcons"))
|
||||
elif matches_prompt(prompt, title):
|
||||
add_code_completion_option(CodeEdit.KIND_CLASS, title, title.substr(prompt.length()), theme_overrides.text_color, get_theme_icon("ArrowRight", "EditorIcons"))
|
||||
update_code_completion_options(true)
|
||||
parser.free()
|
||||
return
|
||||
|
||||
var name_so_far: String = WEIGHTED_RANDOM_PREFIX.sub(current_line.strip_edges(), "")
|
||||
@@ -205,8 +210,8 @@ func get_cursor() -> Vector2:
|
||||
|
||||
# Set the caret from a Vector2
|
||||
func set_cursor(from_cursor: Vector2) -> void:
|
||||
set_caret_line(from_cursor.y)
|
||||
set_caret_column(from_cursor.x)
|
||||
set_caret_line(from_cursor.y, false)
|
||||
set_caret_column(from_cursor.x, false)
|
||||
|
||||
|
||||
# Check if a prompt is the start of a string without actually being that string
|
||||
@@ -219,8 +224,9 @@ func get_titles() -> PackedStringArray:
|
||||
var titles = PackedStringArray([])
|
||||
var lines = text.split("\n")
|
||||
for line in lines:
|
||||
if line.begins_with("~ "):
|
||||
titles.append(line.substr(2).strip_edges())
|
||||
if line.strip_edges().begins_with("~ "):
|
||||
titles.append(line.strip_edges().substr(2))
|
||||
|
||||
return titles
|
||||
|
||||
|
||||
@@ -259,6 +265,11 @@ func get_character_names(beginning_with: String) -> PackedStringArray:
|
||||
|
||||
# Mark a line as an error or not
|
||||
func mark_line_as_error(line_number: int, is_error: bool) -> void:
|
||||
# Lines display counting from 1 but are actually indexed from 0
|
||||
line_number -= 1
|
||||
|
||||
if line_number < 0: return
|
||||
|
||||
if is_error:
|
||||
set_line_background_color(line_number, theme_overrides.error_line_color)
|
||||
set_line_gutter_icon(line_number, 0, get_theme_icon("StatusError", "EditorIcons"))
|
||||
@@ -372,6 +383,7 @@ func delete_current_line() -> void:
|
||||
func move_line(offset: int) -> void:
|
||||
offset = clamp(offset, -1, 1)
|
||||
|
||||
var starting_scroll := scroll_vertical
|
||||
var cursor = get_cursor()
|
||||
var reselect: bool = false
|
||||
var from: int = cursor.y
|
||||
@@ -395,12 +407,14 @@ func move_line(offset: int) -> void:
|
||||
text = "\n".join(lines)
|
||||
|
||||
cursor.y += offset
|
||||
set_cursor(cursor)
|
||||
from += offset
|
||||
to += offset
|
||||
if reselect:
|
||||
select(from, 0, to, get_line_width(to))
|
||||
set_cursor(cursor)
|
||||
|
||||
text_changed.emit()
|
||||
scroll_vertical = starting_scroll + offset
|
||||
|
||||
|
||||
### Signals
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://1ymv6jff0eay
|
||||
uid://djeybvlb332mp
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://civ6shmka5e8u"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/code_edit_syntax_highlighter.gd" id="1_58cfo"]
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/code_edit.gd" id="1_g324i"]
|
||||
[ext_resource type="Script" uid="uid://klpiq4tk3t7a" path="res://addons/dialogue_manager/components/code_edit_syntax_highlighter.gd" id="1_58cfo"]
|
||||
[ext_resource type="Script" uid="uid://djeybvlb332mp" path="res://addons/dialogue_manager/components/code_edit.gd" id="1_g324i"]
|
||||
|
||||
[sub_resource type="SyntaxHighlighter" id="SyntaxHighlighter_cobxx"]
|
||||
script = ExtResource("1_58cfo")
|
||||
|
||||
@@ -1,55 +1,18 @@
|
||||
@tool
|
||||
extends SyntaxHighlighter
|
||||
class_name DMSyntaxHighlighter extends SyntaxHighlighter
|
||||
|
||||
|
||||
const DialogueManagerParser = preload("./parser.gd")
|
||||
|
||||
|
||||
enum ExpressionType {DO, SET, IF}
|
||||
|
||||
|
||||
var dialogue_manager_parser: DialogueManagerParser = DialogueManagerParser.new()
|
||||
|
||||
var regex_titles: RegEx = RegEx.create_from_string("^\\s*(?<title>~\\s+[^\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\-\\=\\+\\{\\}\\[\\]\\;\\:\\\"\\'\\,\\.\\<\\>\\?\\/\\s]+)")
|
||||
var regex_comments: RegEx = RegEx.create_from_string("(?:(?>\"(?:\\\\\"|[^\"\\n])*\")[^\"\\n]*?\\s*(?<comment>#[^\\n]*)$|^[^\"#\\n]*?\\s*(?<comment2>#[^\\n]*))")
|
||||
var regex_mutation: RegEx = RegEx.create_from_string("^\\s*(do|do!|set) (?<mutation>.*)")
|
||||
var regex_condition: RegEx = RegEx.create_from_string("^\\s*(if|elif|while|else if) (?<condition>.*)")
|
||||
var regex_wcondition: RegEx = RegEx.create_from_string("\\[if (?<condition>((?:[^\\[\\]]*)|(?:\\[(?1)\\]))*?)\\]")
|
||||
var regex_wendif: RegEx = RegEx.create_from_string("\\[(\\/if|else)\\]")
|
||||
var regex_rgroup: RegEx = RegEx.create_from_string("\\[\\[(?<options>.*?)\\]\\]")
|
||||
var regex_endconditions: RegEx = RegEx.create_from_string("^\\s*(endif|else):?\\s*$")
|
||||
var regex_tags: RegEx = RegEx.create_from_string("\\[(?<tag>(?!(?:ID:.*)|if)[a-zA-Z_][a-zA-Z0-9_]*!?)(?:[= ](?<val>[^\\[\\]]+))?\\](?:(?<text>(?!\\[\\/\\k<tag>\\]).*?)?(?<end>\\[\\/\\k<tag>\\]))?")
|
||||
var regex_dialogue: RegEx = RegEx.create_from_string("^\\s*(?:(?<random>\\%[\\d.]* )|(?<response>- ))?(?:(?<character>[^#:]*): )?(?<dialogue>.*)$")
|
||||
var regex_goto: RegEx = RegEx.create_from_string("=><? (?:(?<file>[^\\/]+)\\/)?(?<title>[^\\/]*)")
|
||||
var regex_string: RegEx = RegEx.create_from_string("^&?(?<delimiter>[\"'])(?<content>(?:\\\\{2})*|(?:.*?[^\\\\](?:\\\\{2})*))\\1$")
|
||||
var regex_escape: RegEx = RegEx.create_from_string("\\\\.")
|
||||
var regex_number: RegEx = RegEx.create_from_string("^-?(?:(?:0x(?:[0-9A-Fa-f]{2})+)|(?:0b[01]+)|(?:\\d+(?:(?:[\\.]\\d*)?(?:e\\d+)?)|(?:_\\d+)+)?)$")
|
||||
var regex_array: RegEx = RegEx.create_from_string("\\[((?>[^\\[\\]]+|(?R))*)\\]")
|
||||
var regex_dict: RegEx = RegEx.create_from_string("^\\{((?>[^\\{\\}]+|(?R))*)\\}$")
|
||||
var regex_kvdict: RegEx = RegEx.create_from_string("^\\s*(?<left>.*?)\\s*(?<colon>:|=)\\s*(?<right>[^\\/]+)$")
|
||||
var regex_commas: RegEx = RegEx.create_from_string("([^,]+)(?:\\s*,\\s*)?")
|
||||
var regex_assignment: RegEx = RegEx.create_from_string("^\\s*(?<var>[a-zA-Z_][a-zA-Z_0-9]*)(?:(?<attr>(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)+)|(?:\\[(?<key>[^\\]]+)\\]))?\\s*(?<op>(?:\\/|\\*|-|\\+)?=)\\s*(?<val>.*)$")
|
||||
var regex_varname: RegEx = RegEx.create_from_string("^\\s*(?!true|false|and|or|&&|\\|\\|not|in|null)(?<var>[a-zA-Z_][a-zA-Z_0-9]*)(?:(?<attr>(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)+)|(?:\\[(?<key>[^\\]]+)\\]))?\\s*$")
|
||||
var regex_keyword: RegEx = RegEx.create_from_string("^\\s*(true|false|null)\\s*$")
|
||||
var regex_function: RegEx = RegEx.create_from_string("^\\s*([a-zA-Z_][a-zA-Z_0-9]*\\s*)\\(")
|
||||
var regex_comparison: RegEx = RegEx.create_from_string("^(?<left>.*?)\\s*(?<op>==|>=|<=|<|>|!=)\\s*(?<right>.*)$")
|
||||
var regex_blogical: RegEx = RegEx.create_from_string("^(?<left>.*?)\\s+(?<op>and|or|in|&&|\\|\\|)\\s+(?<right>.*)$")
|
||||
var regex_ulogical: RegEx = RegEx.create_from_string("^\\s*(?<op>not)\\s+(?<right>.*)$")
|
||||
var regex_paren: RegEx = RegEx.create_from_string("\\((?<paren>((?:[^\\(\\)]*)|(?:\\((?1)\\)))*?)\\)")
|
||||
var regex: DMCompilerRegEx = DMCompilerRegEx.new()
|
||||
var compilation: DMCompilation = DMCompilation.new()
|
||||
var expression_parser = DMExpressionParser.new()
|
||||
|
||||
var cache: Dictionary = {}
|
||||
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
if what == NOTIFICATION_PREDELETE:
|
||||
dialogue_manager_parser.free()
|
||||
|
||||
|
||||
func _clear_highlighting_cache() -> void:
|
||||
cache = {}
|
||||
cache.clear()
|
||||
|
||||
|
||||
## Returns the syntax coloring for a dialogue file line
|
||||
func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
||||
var colors: Dictionary = {}
|
||||
var text_edit: TextEdit = get_text_edit()
|
||||
@@ -63,323 +26,194 @@ func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
||||
if text in cache:
|
||||
return cache[text]
|
||||
|
||||
# Comments have to be removed to make the remaining processing easier.
|
||||
# Count both end-of-line and single-line comments
|
||||
# Comments are not allowed within dialogue lines or response lines, so we ask the parser what it thinks the current line is
|
||||
if not (dialogue_manager_parser.is_dialogue_line(text) or dialogue_manager_parser.is_response_line(text)) or dialogue_manager_parser.is_line_empty(text) or dialogue_manager_parser.is_import_line(text):
|
||||
var comment_matches: Array[RegExMatch] = regex_comments.search_all(text)
|
||||
for comment_match in comment_matches:
|
||||
for i in ["comment", "comment2"]:
|
||||
if i in comment_match.names:
|
||||
colors[comment_match.get_start(i)] = {"color": text_edit.theme_overrides.comments_color}
|
||||
text = text.substr(0, comment_match.get_start(i))
|
||||
var theme: Dictionary = text_edit.theme_overrides
|
||||
|
||||
# Dialogues
|
||||
var dialogue_matches: Array[RegExMatch] = regex_dialogue.search_all(text)
|
||||
for dialogue_match in dialogue_matches:
|
||||
if "random" in dialogue_match.names:
|
||||
colors[dialogue_match.get_start("random")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[dialogue_match.get_end("random")] = {"color": text_edit.theme_overrides.text_color}
|
||||
if "response" in dialogue_match.names:
|
||||
colors[dialogue_match.get_start("response")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[dialogue_match.get_end("response")] = {"color": text_edit.theme_overrides.text_color}
|
||||
if "character" in dialogue_match.names:
|
||||
colors[dialogue_match.get_start("character")] = {"color": text_edit.theme_overrides.members_color}
|
||||
colors[dialogue_match.get_end("character")] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_dialogue_syntax_highlighting(dialogue_match.get_start("dialogue"), dialogue_match.get_string("dialogue")), true)
|
||||
var index: int = 0
|
||||
|
||||
# Title lines
|
||||
if dialogue_manager_parser.is_title_line(text):
|
||||
var title_matches: Array[RegExMatch] = regex_titles.search_all(text)
|
||||
for title_match in title_matches:
|
||||
colors[title_match.get_start("title")] = {"color": text_edit.theme_overrides.titles_color}
|
||||
match DMCompiler.get_line_type(text):
|
||||
DMConstants.TYPE_USING:
|
||||
colors[index] = { color = theme.conditions_color }
|
||||
colors[index + "using ".length()] = { color = theme.text_color }
|
||||
|
||||
# Import lines
|
||||
var import_matches: Array[RegExMatch] = dialogue_manager_parser.IMPORT_REGEX.search_all(text)
|
||||
for import_match in import_matches:
|
||||
colors[import_match.get_start(0)] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[import_match.get_start("path") - 1] = {"color": text_edit.theme_overrides.strings_color}
|
||||
colors[import_match.get_end("path") + 1] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[import_match.get_start("prefix")] = {"color": text_edit.theme_overrides.members_color}
|
||||
colors[import_match.get_end("prefix")] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
DMConstants.TYPE_IMPORT:
|
||||
colors[index] = { color = theme.conditions_color }
|
||||
var import: RegExMatch = regex.IMPORT_REGEX.search(text)
|
||||
colors[index + import.get_start("path") - 1] = { color = theme.strings_color }
|
||||
colors[index + import.get_end("path") + 1] = { color = theme.conditions_color }
|
||||
colors[index + import.get_start("prefix")] = { color = theme.text_color }
|
||||
|
||||
# Using clauses
|
||||
var using_matches: Array[RegExMatch] = dialogue_manager_parser.USING_REGEX.search_all(text)
|
||||
for using_match in using_matches:
|
||||
colors[using_match.get_start(0)] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[using_match.get_start("state") - 1] = {"color": text_edit.theme_overrides.text_color}
|
||||
DMConstants.TYPE_COMMENT:
|
||||
colors[index] = { color = theme.comments_color }
|
||||
|
||||
# Condition keywords and expressions
|
||||
var condition_matches: Array[RegExMatch] = regex_condition.search_all(text)
|
||||
for condition_match in condition_matches:
|
||||
colors[condition_match.get_start(0)] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[condition_match.get_end(1)] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_expression_syntax_highlighting(condition_match.get_start("condition"), ExpressionType.IF, condition_match.get_string("condition")), true)
|
||||
# endif/else
|
||||
var endcondition_matches: Array[RegExMatch] = regex_endconditions.search_all(text)
|
||||
for endcondition_match in endcondition_matches:
|
||||
colors[endcondition_match.get_start(1)] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[endcondition_match.get_end(1)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
DMConstants.TYPE_TITLE:
|
||||
colors[index] = { color = theme.titles_color }
|
||||
|
||||
# Mutations
|
||||
var mutation_matches: Array[RegExMatch] = regex_mutation.search_all(text)
|
||||
for mutation_match in mutation_matches:
|
||||
colors[mutation_match.get_start(0)] = {"color": text_edit.theme_overrides.mutations_color}
|
||||
colors.merge(_get_expression_syntax_highlighting(mutation_match.get_start("mutation"), ExpressionType.DO if mutation_match.strings[1] == "do" else ExpressionType.SET, mutation_match.get_string("mutation")), true)
|
||||
DMConstants.TYPE_CONDITION, DMConstants.TYPE_WHILE, DMConstants.TYPE_MATCH, DMConstants.TYPE_WHEN:
|
||||
colors[0] = { color = theme.conditions_color }
|
||||
index = text.find(" ")
|
||||
if index > -1:
|
||||
var expression: Array = expression_parser.tokenise(text.substr(index), DMConstants.TYPE_CONDITION, 0)
|
||||
if expression.size() == 0 or expression[0].type == DMConstants.TYPE_ERROR:
|
||||
colors[index] = { color = theme.critical_color }
|
||||
else:
|
||||
_highlight_expression(expression, colors, index)
|
||||
|
||||
DMConstants.TYPE_MUTATION:
|
||||
colors[0] = { color = theme.mutations_color }
|
||||
index = text.find(" ")
|
||||
var expression: Array = expression_parser.tokenise(text.substr(index), DMConstants.TYPE_MUTATION, 0)
|
||||
if expression.size() == 0 or expression[0].type == DMConstants.TYPE_ERROR:
|
||||
colors[index] = { color = theme.critical_color }
|
||||
else:
|
||||
_highlight_expression(expression, colors, index)
|
||||
|
||||
DMConstants.TYPE_GOTO:
|
||||
if text.strip_edges().begins_with("%"):
|
||||
colors[index] = { color = theme.symbols_color }
|
||||
index = text.find(" ")
|
||||
_highlight_goto(text, colors, index)
|
||||
|
||||
DMConstants.TYPE_RANDOM:
|
||||
colors[index] = { color = theme.symbols_color }
|
||||
|
||||
DMConstants.TYPE_DIALOGUE, DMConstants.TYPE_RESPONSE:
|
||||
if text.strip_edges().begins_with("%"):
|
||||
colors[index] = { color = theme.symbols_color }
|
||||
index = text.find(" ", text.find("%"))
|
||||
colors[index] = { color = theme.text_color.lerp(theme.symbols_color, 0.5) }
|
||||
|
||||
var dialogue_text: String = text.substr(index, text.find("=>"))
|
||||
|
||||
# Highlight character name
|
||||
var split_index: int = dialogue_text.replace("\\:", "??").find(":")
|
||||
colors[index + split_index + 1] = { color = theme.text_color }
|
||||
|
||||
# Interpolation
|
||||
var replacements: Array[RegExMatch] = regex.REPLACEMENTS_REGEX.search_all(dialogue_text)
|
||||
for replacement: RegExMatch in replacements:
|
||||
var expression_text: String = replacement.get_string().substr(0, replacement.get_string().length() - 2).substr(2)
|
||||
var expression: Array = expression_parser.tokenise(expression_text, DMConstants.TYPE_MUTATION, replacement.get_start())
|
||||
var expression_index: int = index + replacement.get_start()
|
||||
colors[expression_index] = { color = theme.symbols_color }
|
||||
if expression.size() == 0 or expression[0].type == DMConstants.TYPE_ERROR:
|
||||
colors[expression_index] = { color = theme.critical_color }
|
||||
else:
|
||||
_highlight_expression(expression, colors, index + 2)
|
||||
colors[expression_index + expression_text.length() + 2] = { color = theme.symbols_color }
|
||||
colors[expression_index + expression_text.length() + 4] = { color = theme.text_color }
|
||||
# Tags (and inline mutations)
|
||||
var resolved_line_data: DMResolvedLineData = DMResolvedLineData.new("")
|
||||
var bbcodes: Array[Dictionary] = resolved_line_data.find_bbcode_positions_in_string(dialogue_text, true, true)
|
||||
for bbcode: Dictionary in bbcodes:
|
||||
var tag: String = bbcode.code
|
||||
var code: String = bbcode.raw_args
|
||||
if code.begins_with("["):
|
||||
colors[index + bbcode.start] = { color = theme.symbols_color }
|
||||
colors[index + bbcode.start + 2] = { color = theme.text_color }
|
||||
var pipe_cursor: int = code.find("|")
|
||||
while pipe_cursor > -1:
|
||||
colors[index + bbcode.start + pipe_cursor + 1] = { color = theme.symbols_color }
|
||||
colors[index + bbcode.start + pipe_cursor + 2] = { color = theme.text_color }
|
||||
pipe_cursor = code.find("|", pipe_cursor + 1)
|
||||
colors[index + bbcode.end - 1] = { color = theme.symbols_color }
|
||||
colors[index + bbcode.end + 1] = { color = theme.text_color }
|
||||
else:
|
||||
colors[index + bbcode.start] = { color = theme.symbols_color }
|
||||
if tag.begins_with("do") or tag.begins_with("set") or tag.begins_with("if"):
|
||||
if tag.begins_with("if"):
|
||||
colors[index + bbcode.start + 1] = { color = theme.conditions_color }
|
||||
else:
|
||||
colors[index + bbcode.start + 1] = { color = theme.mutations_color }
|
||||
var expression: Array = expression_parser.tokenise(code, DMConstants.TYPE_MUTATION, bbcode.start + bbcode.code.length())
|
||||
if expression.size() == 0 or expression[0].type == DMConstants.TYPE_ERROR:
|
||||
colors[index + bbcode.start + tag.length() + 1] = { color = theme.critical_color }
|
||||
else:
|
||||
_highlight_expression(expression, colors, index + 2)
|
||||
# else and closing if have no expression
|
||||
elif tag.begins_with("else") or tag.begins_with("/if"):
|
||||
colors[index + bbcode.start + 1] = { color = theme.conditions_color }
|
||||
colors[index + bbcode.end] = { color = theme.symbols_color }
|
||||
colors[index + bbcode.end + 1] = { color = theme.text_color }
|
||||
# Jumps
|
||||
if "=> " in text or "=>< " in text:
|
||||
_highlight_goto(text, colors, index)
|
||||
|
||||
# Order the dictionary keys to prevent CodeEdit from having issues
|
||||
var new_colors: Dictionary = {}
|
||||
var ordered_colors: Dictionary = {}
|
||||
var ordered_keys: Array = colors.keys()
|
||||
ordered_keys.sort()
|
||||
for index in ordered_keys:
|
||||
new_colors[index] = colors[index]
|
||||
for key_index: int in ordered_keys:
|
||||
ordered_colors[key_index] = colors[key_index]
|
||||
|
||||
cache[text] = new_colors
|
||||
return new_colors
|
||||
cache[text] = ordered_colors
|
||||
return ordered_colors
|
||||
|
||||
|
||||
## Return the syntax highlighting for a dialogue line
|
||||
func _get_dialogue_syntax_highlighting(start_index: int, text: String) -> Dictionary:
|
||||
var text_edit: TextEdit = get_text_edit()
|
||||
var colors: Dictionary = {}
|
||||
func _highlight_expression(tokens: Array, colors: Dictionary, index: int) -> int:
|
||||
var theme: Dictionary = get_text_edit().theme_overrides
|
||||
var last_index: int = index
|
||||
for token: Dictionary in tokens:
|
||||
last_index = token.i
|
||||
match token.type:
|
||||
DMConstants.TOKEN_CONDITION, DMConstants.TOKEN_AND_OR:
|
||||
colors[index + token.i] = { color = theme.conditions_color }
|
||||
|
||||
# #tag style tags
|
||||
var hashtag_matches: Array[RegExMatch] = dialogue_manager_parser.TAGS_REGEX.search_all(text)
|
||||
for hashtag_match in hashtag_matches:
|
||||
colors[start_index + hashtag_match.get_start(0)] = { "color": text_edit.theme_overrides.comments_color }
|
||||
colors[start_index + hashtag_match.get_end(0)] = { "color": text_edit.theme_overrides.text_color }
|
||||
DMConstants.TOKEN_VARIABLE:
|
||||
if token.value in ["true", "false"]:
|
||||
colors[index + token.i] = { color = theme.conditions_color }
|
||||
else:
|
||||
colors[index + token.i] = { color = theme.members_color }
|
||||
|
||||
# bbcode-like global tags
|
||||
var tag_matches: Array[RegExMatch] = regex_tags.search_all(text)
|
||||
for tag_match in tag_matches:
|
||||
colors[start_index + tag_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
if "val" in tag_match.names:
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + tag_match.get_start("val"), tag_match.get_string("val")), true)
|
||||
colors[start_index + tag_match.get_end("val")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
# Show the text color straight in the editor for better ease-of-use
|
||||
if tag_match.get_string("tag") == "color":
|
||||
colors[start_index + tag_match.get_start("val")] = {"color": Color.from_string(tag_match.get_string("val"), text_edit.theme_overrides.text_color)}
|
||||
if "text" in tag_match.names:
|
||||
colors[start_index + tag_match.get_start("text")] = {"color": text_edit.theme_overrides.text_color}
|
||||
# Text can still contain tags if several effects are applied ([center][b]Something[/b][/center], so recursing
|
||||
colors.merge(_get_dialogue_syntax_highlighting(start_index + tag_match.get_start("text"), tag_match.get_string("text")), true)
|
||||
colors[start_index + tag_match.get_end("text")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
if "end" in tag_match.names:
|
||||
colors[start_index + tag_match.get_start("end")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + tag_match.get_end("end")] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors[start_index + tag_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
DMConstants.TOKEN_OPERATOR, DMConstants.TOKEN_COLON, DMConstants.TOKEN_COMMA, DMConstants.TOKEN_NUMBER, DMConstants.TOKEN_ASSIGNMENT:
|
||||
colors[index + token.i] = { color = theme.symbols_color }
|
||||
|
||||
# ID tag
|
||||
var translation_matches: Array[RegExMatch] = dialogue_manager_parser.TRANSLATION_REGEX.search_all(text)
|
||||
for translation_match in translation_matches:
|
||||
colors[start_index + translation_match.get_start(0)] = {"color": text_edit.theme_overrides.comments_color}
|
||||
colors[start_index + translation_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
DMConstants.TOKEN_STRING:
|
||||
colors[index + token.i] = { color = theme.strings_color }
|
||||
|
||||
# Replacements
|
||||
var replacement_matches: Array[RegExMatch] = dialogue_manager_parser.REPLACEMENTS_REGEX.search_all(text)
|
||||
for replacement_match in replacement_matches:
|
||||
colors[start_index + replacement_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + replacement_match.get_start(1)] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + replacement_match.get_start(1), replacement_match.strings[1]), true)
|
||||
colors[start_index + replacement_match.get_end(1)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + replacement_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
DMConstants.TOKEN_FUNCTION:
|
||||
colors[index + token.i] = { color = theme.mutations_color }
|
||||
colors[index + token.i + token.function.length()] = { color = theme.symbols_color }
|
||||
for parameter: Array in token.value:
|
||||
last_index = _highlight_expression(parameter, colors, index)
|
||||
DMConstants.TOKEN_PARENS_CLOSE:
|
||||
colors[index + token.i] = { color = theme.symbols_color }
|
||||
|
||||
# Jump at the end of a response
|
||||
var goto_matches: Array[RegExMatch] = regex_goto.search_all(text)
|
||||
for goto_match in goto_matches:
|
||||
colors[start_index + goto_match.get_start(0)] = {"color": text_edit.theme_overrides.jumps_color}
|
||||
if "file" in goto_match.names:
|
||||
colors[start_index + goto_match.get_start("file")] = {"color": text_edit.theme_overrides.jumps_color}
|
||||
colors[start_index + goto_match.get_end("file")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + goto_match.get_start("title")] = {"color": text_edit.theme_overrides.jumps_color}
|
||||
colors[start_index + goto_match.get_end("title")] = {"color": text_edit.theme_overrides.jumps_color}
|
||||
colors[start_index + goto_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
DMConstants.TOKEN_DICTIONARY_REFERENCE:
|
||||
colors[index + token.i] = { color = theme.members_color }
|
||||
colors[index + token.i + token.variable.length()] = { color = theme.symbols_color }
|
||||
last_index = _highlight_expression(token.value, colors, index)
|
||||
DMConstants.TOKEN_ARRAY:
|
||||
colors[index + token.i] = { color = theme.symbols_color }
|
||||
for item: Array in token.value:
|
||||
last_index = _highlight_expression(item, colors, index)
|
||||
DMConstants.TOKEN_BRACKET_CLOSE:
|
||||
colors[index + token.i] = { color = theme.symbols_color }
|
||||
|
||||
# Wrapped condition
|
||||
var wcondition_matches: Array[RegExMatch] = regex_wcondition.search_all(text)
|
||||
for wcondition_match in wcondition_matches:
|
||||
colors[start_index + wcondition_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + wcondition_match.get_start(0) + 1] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[start_index + wcondition_match.get_start(0) + 3] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + wcondition_match.get_start("condition"), wcondition_match.get_string("condition")), true)
|
||||
colors[start_index + wcondition_match.get_end("condition")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + wcondition_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
# [/if] tag for color matching with the opening tag
|
||||
var wendif_matches: Array[RegExMatch] = regex_wendif.search_all(text)
|
||||
for wendif_match in wendif_matches:
|
||||
colors[start_index + wendif_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + wendif_match.get_start(1)] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[start_index + wendif_match.get_end(1)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + wendif_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
DMConstants.TOKEN_DICTIONARY:
|
||||
colors[index + token.i] = { color = theme.symbols_color }
|
||||
last_index = _highlight_expression(token.value.keys() + token.value.values(), colors, index)
|
||||
DMConstants.TOKEN_BRACE_CLOSE:
|
||||
colors[index + token.i] = { color = theme.symbols_color }
|
||||
last_index += 1
|
||||
|
||||
# Random groups
|
||||
var rgroup_matches: Array[RegExMatch] = regex_rgroup.search_all(text)
|
||||
for rgroup_match in rgroup_matches:
|
||||
colors[start_index + rgroup_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + rgroup_match.get_start("options")] = {"color": text_edit.theme_overrides.text_color}
|
||||
var separator_matches: Array[RegExMatch] = RegEx.create_from_string("\\|").search_all(rgroup_match.get_string("options"))
|
||||
for separator_match in separator_matches:
|
||||
colors[start_index + rgroup_match.get_start("options") + separator_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + rgroup_match.get_start("options") + separator_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors[start_index + rgroup_match.get_end("options")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + rgroup_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
|
||||
DMConstants.TOKEN_GROUP:
|
||||
last_index = _highlight_expression(token.value, colors, index)
|
||||
|
||||
return colors
|
||||
return last_index
|
||||
|
||||
|
||||
## Returns the syntax highlighting for an expression (mutation set/do, or condition)
|
||||
func _get_expression_syntax_highlighting(start_index: int, type: ExpressionType, text: String) -> Dictionary:
|
||||
var text_edit: TextEdit = get_text_edit()
|
||||
var colors: Dictionary = {}
|
||||
func _highlight_goto(text: String, colors: Dictionary, index: int) -> int:
|
||||
var theme: Dictionary = get_text_edit().theme_overrides
|
||||
var goto_data: DMResolvedGotoData = DMResolvedGotoData.new(text, {})
|
||||
colors[goto_data.index] = { color = theme.jumps_color }
|
||||
if "{{" in text:
|
||||
index = text.find("{{", goto_data.index)
|
||||
var last_index: int = 0
|
||||
if goto_data.error:
|
||||
colors[index + 2] = { color = theme.critical_color }
|
||||
else:
|
||||
last_index = _highlight_expression(goto_data.expression, colors, index)
|
||||
index = text.find("}}", index + last_index)
|
||||
colors[index] = { color = theme.jumps_color }
|
||||
|
||||
if type == ExpressionType.SET:
|
||||
var assignment_matches: Array[RegExMatch] = regex_assignment.search_all(text)
|
||||
for assignment_match in assignment_matches:
|
||||
colors[start_index + assignment_match.get_start("var")] = {"color": text_edit.theme_overrides.text_color}
|
||||
if "attr" in assignment_match.names:
|
||||
colors[start_index + assignment_match.get_start("attr")] = {"color": text_edit.theme_overrides.members_color}
|
||||
colors[start_index + assignment_match.get_end("attr")] = {"color": text_edit.theme_overrides.text_color}
|
||||
if "key" in assignment_match.names:
|
||||
# Braces are outside of the key, so coloring them symbols_color
|
||||
colors[start_index + assignment_match.get_start("key") - 1] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + assignment_match.get_start("key"), assignment_match.get_string("key")), true)
|
||||
colors[start_index + assignment_match.get_end("key")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + assignment_match.get_end("key") + 1] = {"color": text_edit.theme_overrides.text_color}
|
||||
|
||||
colors[start_index + assignment_match.get_start("op")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + assignment_match.get_end("op")] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + assignment_match.get_start("val"), assignment_match.get_string("val")), true)
|
||||
else:
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index, text), true)
|
||||
|
||||
return colors
|
||||
|
||||
|
||||
## Return the syntax highlighting for a literal
|
||||
## For this purpose, "literal" refers to a regular code line that could be used to get a value out of:
|
||||
## - function calls
|
||||
## - real literals (bool, string, int, float, etc.)
|
||||
## - logical operators (>, <, >=, or, and, not, etc.)
|
||||
func _get_literal_syntax_highlighting(start_index: int, text: String) -> Dictionary:
|
||||
var text_edit: TextEdit = get_text_edit()
|
||||
var colors: Dictionary = {}
|
||||
|
||||
# Remove spaces at start/end of the literal
|
||||
var text_length: int = text.length()
|
||||
text = text.lstrip(" ")
|
||||
start_index += text_length - text.length()
|
||||
text = text.rstrip(" ")
|
||||
|
||||
# Parenthesis expression.
|
||||
var paren_matches: Array[RegExMatch] = regex_paren.search_all(text)
|
||||
for paren_match in paren_matches:
|
||||
colors[start_index + paren_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + paren_match.get_start(0) + 1] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + paren_match.get_start("paren"), paren_match.get_string("paren")), true)
|
||||
colors[start_index + paren_match.get_end(0) - 1] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
|
||||
# Strings
|
||||
var string_matches: Array[RegExMatch] = regex_string.search_all(text)
|
||||
for string_match in string_matches:
|
||||
colors[start_index + string_match.get_start(0)] = {"color": text_edit.theme_overrides.strings_color}
|
||||
if "content" in string_match.names:
|
||||
var escape_matches: Array[RegExMatch] = regex_escape.search_all(string_match.get_string("content"))
|
||||
for escape_match in escape_matches:
|
||||
colors[start_index + string_match.get_start("content") + escape_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + string_match.get_start("content") + escape_match.get_end(0)] = {"color": text_edit.theme_overrides.strings_color}
|
||||
|
||||
# Numbers
|
||||
var number_matches: Array[RegExMatch] = regex_number.search_all(text)
|
||||
for number_match in number_matches:
|
||||
colors[start_index + number_match.get_start(0)] = {"color": text_edit.theme_overrides.numbers_color}
|
||||
|
||||
# Arrays
|
||||
var array_matches: Array[RegExMatch] = regex_array.search_all(text)
|
||||
for array_match in array_matches:
|
||||
colors[start_index + array_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors.merge(_get_list_syntax_highlighting(start_index + array_match.get_start(1), array_match.strings[1]), true)
|
||||
colors[start_index + array_match.get_end(1)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
|
||||
# Dictionaries
|
||||
var dict_matches: Array[RegExMatch] = regex_dict.search_all(text)
|
||||
for dict_match in dict_matches:
|
||||
colors[start_index + dict_match.get_start(0)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors.merge(_get_list_syntax_highlighting(start_index + dict_match.get_start(1), dict_match.strings[1]), true)
|
||||
colors[start_index + dict_match.get_end(1)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
|
||||
# Dictionary key: value pairs
|
||||
var kvdict_matches: Array[RegExMatch] = regex_kvdict.search_all(text)
|
||||
for kvdict_match in kvdict_matches:
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + kvdict_match.get_start("left"), kvdict_match.get_string("left")), true)
|
||||
colors[start_index + kvdict_match.get_start("colon")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + kvdict_match.get_end("colon")] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + kvdict_match.get_start("right"), kvdict_match.get_string("right")), true)
|
||||
|
||||
# Booleans
|
||||
var bool_matches: Array[RegExMatch] = regex_keyword.search_all(text)
|
||||
for bool_match in bool_matches:
|
||||
colors[start_index + bool_match.get_start(0)] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
|
||||
# Functions
|
||||
var function_matches: Array[RegExMatch] = regex_function.search_all(text)
|
||||
for function_match in function_matches:
|
||||
var last_brace_index: int = text.rfind(")")
|
||||
colors[start_index + function_match.get_start(1)] = {"color": text_edit.theme_overrides.mutations_color}
|
||||
colors[start_index + function_match.get_end(1)] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors.merge(_get_list_syntax_highlighting(start_index + function_match.get_end(0), text.substr(function_match.get_end(0), last_brace_index - function_match.get_end(0))), true)
|
||||
colors[start_index + last_brace_index] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
|
||||
# Variables
|
||||
var varname_matches: Array[RegExMatch] = regex_varname.search_all(text)
|
||||
for varname_match in varname_matches:
|
||||
colors[start_index + varname_match.get_start("var")] = {"color": text_edit.theme_overrides.text_color}
|
||||
if "attr" in varname_match.names:
|
||||
colors[start_index + varname_match.get_start("attr")] = {"color": text_edit.theme_overrides.members_color}
|
||||
colors[start_index + varname_match.get_end("attr")] = {"color": text_edit.theme_overrides.text_color}
|
||||
if "key" in varname_match.names:
|
||||
# Braces are outside of the key, so coloring them symbols_color
|
||||
colors[start_index + varname_match.get_start("key") - 1] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + varname_match.get_start("key"), varname_match.get_string("key")), true)
|
||||
colors[start_index + varname_match.get_end("key")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
|
||||
# Comparison operators
|
||||
var comparison_matches: Array[RegExMatch] = regex_comparison.search_all(text)
|
||||
for comparison_match in comparison_matches:
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + comparison_match.get_start("left"), comparison_match.get_string("left")), true)
|
||||
colors[start_index + comparison_match.get_start("op")] = {"color": text_edit.theme_overrides.symbols_color}
|
||||
colors[start_index + comparison_match.get_end("op")] = {"color": text_edit.theme_overrides.text_color}
|
||||
var right = comparison_match.get_string("right")
|
||||
if right.ends_with(":"):
|
||||
right = right.substr(0, right.length() - 1)
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + comparison_match.get_start("right"), right), true)
|
||||
colors[start_index + comparison_match.get_start("right") + right.length()] = { "color": text_edit.theme_overrides.symbols_color }
|
||||
|
||||
# Logical binary operators
|
||||
var blogical_matches: Array[RegExMatch] = regex_blogical.search_all(text)
|
||||
for blogical_match in blogical_matches:
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + blogical_match.get_start("left"), blogical_match.get_string("left")), true)
|
||||
colors[start_index + blogical_match.get_start("op")] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[start_index + blogical_match.get_end("op")] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + blogical_match.get_start("right"), blogical_match.get_string("right")), true)
|
||||
|
||||
# Logical unary operators
|
||||
var ulogical_matches: Array[RegExMatch] = regex_ulogical.search_all(text)
|
||||
for ulogical_match in ulogical_matches:
|
||||
colors[start_index + ulogical_match.get_start("op")] = {"color": text_edit.theme_overrides.conditions_color}
|
||||
colors[start_index + ulogical_match.get_end("op")] = {"color": text_edit.theme_overrides.text_color}
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + ulogical_match.get_start("right"), ulogical_match.get_string("right")), true)
|
||||
|
||||
return colors
|
||||
|
||||
|
||||
## Returns the syntax coloring for a list of literals separated by commas
|
||||
func _get_list_syntax_highlighting(start_index: int, text: String) -> Dictionary:
|
||||
var text_edit: TextEdit = get_text_edit()
|
||||
var colors: Dictionary = {}
|
||||
|
||||
# Comma-separated list of literals (for arrays and function arguments)
|
||||
var element_matches: Array[RegExMatch] = regex_commas.search_all(text)
|
||||
for element_match in element_matches:
|
||||
colors.merge(_get_literal_syntax_highlighting(start_index + element_match.get_start(1), element_match.strings[1]), true)
|
||||
|
||||
return colors
|
||||
return index
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://c2pb8gpka0t0u
|
||||
uid://klpiq4tk3t7a
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
extends Node
|
||||
|
||||
|
||||
const DialogueConstants = preload("../constants.gd")
|
||||
const DialogueSettings = preload("../settings.gd")
|
||||
const DialogueManagerParseResult = preload("./parse_result.gd")
|
||||
|
||||
|
||||
signal file_content_changed(path: String, new_content: String)
|
||||
|
||||
|
||||
# Keep track of errors and dependencies
|
||||
# {
|
||||
# <dialogue file path> = {
|
||||
# path = <dialogue file path>,
|
||||
# dependencies = [<dialogue file path>, <dialogue file path>],
|
||||
# errors = [<error>, <error>]
|
||||
# }
|
||||
# }
|
||||
var _cache: Dictionary = {}
|
||||
|
||||
var _update_dependency_timer: Timer = Timer.new()
|
||||
var _update_dependency_paths: PackedStringArray = []
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
add_child(_update_dependency_timer)
|
||||
_update_dependency_timer.timeout.connect(_on_update_dependency_timeout)
|
||||
|
||||
_build_cache()
|
||||
|
||||
|
||||
func reimport_files(files: PackedStringArray = []) -> void:
|
||||
if files.is_empty(): files = get_files()
|
||||
|
||||
var file_system: EditorFileSystem = Engine.get_meta("DialogueManagerPlugin") \
|
||||
.get_editor_interface() \
|
||||
.get_resource_filesystem()
|
||||
|
||||
# NOTE: Godot 4.2rc1 has an issue with reimporting more than one
|
||||
# file at a time so we do them one by one
|
||||
for file in files:
|
||||
file_system.reimport_files([file])
|
||||
await get_tree().create_timer(0.2)
|
||||
|
||||
|
||||
## Add a dialogue file to the cache.
|
||||
func add_file(path: String, parse_results: DialogueManagerParseResult = null) -> void:
|
||||
_cache[path] = {
|
||||
path = path,
|
||||
dependencies = [],
|
||||
errors = []
|
||||
}
|
||||
|
||||
if parse_results != null:
|
||||
_cache[path].dependencies = Array(parse_results.imported_paths).filter(func(d): return d != path)
|
||||
_cache[path].parsed_at = Time.get_ticks_msec()
|
||||
|
||||
# If this is a fresh cache entry, check for dependencies
|
||||
if parse_results == null and not _update_dependency_paths.has(path):
|
||||
queue_updating_dependencies(path)
|
||||
|
||||
|
||||
## Get the file paths in the cache
|
||||
func get_files() -> PackedStringArray:
|
||||
return _cache.keys()
|
||||
|
||||
|
||||
## Check if a file is known to the cache
|
||||
func has_file(path: String) -> bool:
|
||||
return _cache.has(path)
|
||||
|
||||
|
||||
## Remember any errors in a dialogue file
|
||||
func add_errors_to_file(path: String, errors: Array[Dictionary]) -> void:
|
||||
if _cache.has(path):
|
||||
_cache[path].errors = errors
|
||||
else:
|
||||
_cache[path] = {
|
||||
path = path,
|
||||
resource_path = "",
|
||||
dependencies = [],
|
||||
errors = errors
|
||||
}
|
||||
|
||||
|
||||
## Get a list of files that have errors
|
||||
func get_files_with_errors() -> Array[Dictionary]:
|
||||
var files_with_errors: Array[Dictionary] = []
|
||||
for dialogue_file in _cache.values():
|
||||
if dialogue_file and dialogue_file.errors.size() > 0:
|
||||
files_with_errors.append(dialogue_file)
|
||||
return files_with_errors
|
||||
|
||||
|
||||
## Queue a file to have its dependencies checked
|
||||
func queue_updating_dependencies(of_path: String) -> void:
|
||||
_update_dependency_timer.stop()
|
||||
if not _update_dependency_paths.has(of_path):
|
||||
_update_dependency_paths.append(of_path)
|
||||
_update_dependency_timer.start(0.5)
|
||||
|
||||
|
||||
## Update any references to a file path that has moved
|
||||
func move_file_path(from_path: String, to_path: String) -> void:
|
||||
if not _cache.has(from_path): return
|
||||
|
||||
if to_path != "":
|
||||
_cache[to_path] = _cache[from_path].duplicate()
|
||||
_cache.erase(from_path)
|
||||
|
||||
|
||||
## Get every dialogue file that imports on a file of a given path
|
||||
func get_files_with_dependency(imported_path: String) -> Array:
|
||||
return _cache.values().filter(func(d): return d.dependencies.has(imported_path))
|
||||
|
||||
|
||||
## Get any paths that are dependent on a given path
|
||||
func get_dependent_paths_for_reimport(on_path: String) -> PackedStringArray:
|
||||
return get_files_with_dependency(on_path) \
|
||||
.filter(func(d): return Time.get_ticks_msec() - d.get("parsed_at", 0) > 3000) \
|
||||
.map(func(d): return d.path)
|
||||
|
||||
|
||||
# Build the initial cache for dialogue files
|
||||
func _build_cache() -> void:
|
||||
var current_files: PackedStringArray = _get_dialogue_files_in_filesystem()
|
||||
for file in current_files:
|
||||
add_file(file)
|
||||
|
||||
|
||||
# Recursively find any dialogue files in a directory
|
||||
func _get_dialogue_files_in_filesystem(path: String = "res://") -> PackedStringArray:
|
||||
var files: PackedStringArray = []
|
||||
|
||||
if DirAccess.dir_exists_absolute(path):
|
||||
var dir = DirAccess.open(path)
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
var file_path: String = (path + "/" + file_name).simplify_path()
|
||||
if dir.current_is_dir():
|
||||
if not file_name in [".godot", ".tmp"]:
|
||||
files.append_array(_get_dialogue_files_in_filesystem(file_path))
|
||||
elif file_name.get_extension() == "dialogue":
|
||||
files.append(file_path)
|
||||
file_name = dir.get_next()
|
||||
|
||||
return files
|
||||
|
||||
|
||||
### Signals
|
||||
|
||||
|
||||
func _on_update_dependency_timeout() -> void:
|
||||
_update_dependency_timer.stop()
|
||||
var import_regex: RegEx = RegEx.create_from_string("import \"(?<path>.*?)\"")
|
||||
var file: FileAccess
|
||||
var found_imports: Array[RegExMatch]
|
||||
for path in _update_dependency_paths:
|
||||
# Open the file and check for any "import" lines
|
||||
file = FileAccess.open(path, FileAccess.READ)
|
||||
found_imports = import_regex.search_all(file.get_as_text())
|
||||
var dependencies: PackedStringArray = []
|
||||
for found in found_imports:
|
||||
dependencies.append(found.strings[found.names.path])
|
||||
_cache[path].dependencies = dependencies
|
||||
_update_dependency_paths.clear()
|
||||
@@ -1 +0,0 @@
|
||||
uid://cvqm0f453kjn1
|
||||
@@ -34,7 +34,7 @@ func _ready() -> void:
|
||||
|
||||
func _on_download_button_pressed() -> void:
|
||||
# Safeguard the actual dialogue manager repo from accidentally updating itself
|
||||
if FileAccess.file_exists("res://examples/test_scenes/test_scene.gd"):
|
||||
if FileAccess.file_exists("res://tests/test_basic_dialogue.gd"):
|
||||
prints("You can't update the addon from within itself.")
|
||||
failed.emit()
|
||||
return
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dtgq7prk0yh50
|
||||
uid://kpwo418lb2t2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://qdxrxv3c3hxk"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/download_update_panel.gd" id="1_4tm1k"]
|
||||
[ext_resource type="Script" uid="uid://kpwo418lb2t2" path="res://addons/dialogue_manager/components/download_update_panel.gd" id="1_4tm1k"]
|
||||
[ext_resource type="Texture2D" uid="uid://d3baj6rygkb3f" path="res://addons/dialogue_manager/assets/update.svg" id="2_4o2m6"]
|
||||
|
||||
[node name="DownloadUpdatePanel" type="Control"]
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://du1qxltygjocp
|
||||
uid://nyypeje1a036
|
||||
|
||||
@@ -63,7 +63,7 @@ func build_menu() -> void:
|
||||
func _on_new_dialog_file_selected(path: String) -> void:
|
||||
editor_plugin.main_view.new_file(path)
|
||||
is_waiting_for_file = false
|
||||
if Engine.get_meta("DialogueCache").has_file(path):
|
||||
if Engine.get_meta("DMCache").has_file(path):
|
||||
resource_changed.emit(load(path))
|
||||
else:
|
||||
var next_resource: Resource = await editor_plugin.import_plugin.compiled_resource
|
||||
@@ -81,7 +81,7 @@ func _on_file_dialog_canceled() -> void:
|
||||
|
||||
func _on_resource_button_pressed() -> void:
|
||||
if is_instance_valid(resource):
|
||||
editor_plugin.get_editor_interface().call_deferred("edit_resource", resource)
|
||||
EditorInterface.call_deferred("edit_resource", resource)
|
||||
else:
|
||||
build_menu()
|
||||
menu.position = get_viewport().position + Vector2i(
|
||||
@@ -112,7 +112,7 @@ func _on_menu_id_pressed(id: int) -> void:
|
||||
|
||||
ITEM_QUICK_LOAD:
|
||||
quick_selected_file = ""
|
||||
files_list.files = Engine.get_meta("DialogueCache").get_files()
|
||||
files_list.files = Engine.get_meta("DMCache").get_files()
|
||||
if resource:
|
||||
files_list.select_file(resource.resource_path)
|
||||
quick_open_dialog.popup_centered()
|
||||
@@ -123,13 +123,13 @@ func _on_menu_id_pressed(id: int) -> void:
|
||||
open_dialog.popup_centered()
|
||||
|
||||
ITEM_EDIT:
|
||||
editor_plugin.get_editor_interface().call_deferred("edit_resource", resource)
|
||||
EditorInterface.call_deferred("edit_resource", resource)
|
||||
|
||||
ITEM_CLEAR:
|
||||
resource_changed.emit(null)
|
||||
|
||||
ITEM_FILESYSTEM:
|
||||
var file_system = editor_plugin.get_editor_interface().get_file_system_dock()
|
||||
var file_system = EditorInterface.get_file_system_dock()
|
||||
file_system.navigate_to_path(resource.resource_path)
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://d1wvrhfmr8ry6
|
||||
uid://dooe2pflnqtve
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://ycn6uaj7dsrh"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/editor_property/editor_property_control.gd" id="1_het12"]
|
||||
[ext_resource type="Script" uid="uid://dooe2pflnqtve" path="res://addons/dialogue_manager/components/editor_property/editor_property_control.gd" id="1_het12"]
|
||||
[ext_resource type="PackedScene" uid="uid://b16uuqjuof3n5" path="res://addons/dialogue_manager/components/editor_property/resource_button.tscn" id="2_hh3d4"]
|
||||
[ext_resource type="PackedScene" uid="uid://dnufpcdrreva3" path="res://addons/dialogue_manager/components/files_list.tscn" id="3_l8fp6"]
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://b8gxhsrredou6
|
||||
uid://damhqta55t67c
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://b16uuqjuof3n5"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/editor_property/resource_button.gd" id="1_7u2i7"]
|
||||
[ext_resource type="Script" uid="uid://damhqta55t67c" path="res://addons/dialogue_manager/components/editor_property/resource_button.gd" id="1_7u2i7"]
|
||||
|
||||
[node name="ResourceButton" type="Button"]
|
||||
offset_right = 8.0
|
||||
|
||||
@@ -59,7 +59,7 @@ func show_error() -> void:
|
||||
show()
|
||||
count_label.text = DialogueConstants.translate(&"n_of_n").format({ index = error_index + 1, total = errors.size() })
|
||||
var error = errors[error_index]
|
||||
error_button.text = DialogueConstants.translate(&"errors.line_and_message").format({ line = error.line_number + 1, column = error.column_number, message = DialogueConstants.get_error_message(error.error) })
|
||||
error_button.text = DialogueConstants.translate(&"errors.line_and_message").format({ line = error.line_number, column = error.column_number, message = DialogueConstants.get_error_message(error.error) })
|
||||
if error.has("external_error"):
|
||||
error_button.text += " " + DialogueConstants.get_error_message(error.external_error)
|
||||
|
||||
@@ -72,7 +72,7 @@ func _on_errors_panel_theme_changed() -> void:
|
||||
|
||||
|
||||
func _on_error_button_pressed() -> void:
|
||||
emit_signal("error_pressed", errors[error_index].line_number, errors[error_index].column_number)
|
||||
error_pressed.emit(errors[error_index].line_number, errors[error_index].column_number)
|
||||
|
||||
|
||||
func _on_previous_button_pressed() -> void:
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bodru4vhssqjm
|
||||
uid://d2l8nlb6hhrfp
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://cs8pwrxr5vxix"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/errors_panel.gd" id="1_nfm3c"]
|
||||
[ext_resource type="Script" uid="uid://d2l8nlb6hhrfp" path="res://addons/dialogue_manager/components/errors_panel.gd" id="1_nfm3c"]
|
||||
|
||||
[sub_resource type="Image" id="Image_d2tnf"]
|
||||
[sub_resource type="Image" id="Image_w0gko"]
|
||||
data = {
|
||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
||||
"format": "RGBA8",
|
||||
@@ -12,7 +12,7 @@ data = {
|
||||
}
|
||||
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_s6fxl"]
|
||||
image = SubResource("Image_d2tnf")
|
||||
image = SubResource("Image_w0gko")
|
||||
|
||||
[node name="ErrorsPanel" type="HBoxContainer"]
|
||||
visible = false
|
||||
|
||||
@@ -21,6 +21,7 @@ const MODIFIED_SUFFIX = "(*)"
|
||||
var file_map: Dictionary = {}
|
||||
|
||||
var current_file_path: String = ""
|
||||
var last_selected_file_path: String = ""
|
||||
|
||||
var files: PackedStringArray = []:
|
||||
set(next_files):
|
||||
@@ -33,7 +34,7 @@ var files: PackedStringArray = []:
|
||||
|
||||
var unsaved_files: Array[String] = []
|
||||
|
||||
var filter: String:
|
||||
var filter: String = "":
|
||||
set(next_filter):
|
||||
filter = next_filter
|
||||
apply_filter()
|
||||
@@ -57,6 +58,7 @@ func select_file(file: String) -> void:
|
||||
var item_text = list.get_item_text(i).replace(MODIFIED_SUFFIX, "")
|
||||
if item_text == get_nice_file(file, item_text.count("/") + 1):
|
||||
list.select(i)
|
||||
last_selected_file_path = file
|
||||
|
||||
|
||||
func mark_file_as_unsaved(file: String, is_unsaved: bool) -> void:
|
||||
@@ -112,6 +114,8 @@ func apply_filter() -> void:
|
||||
func apply_theme() -> void:
|
||||
if is_instance_valid(filter_edit):
|
||||
filter_edit.right_icon = get_theme_icon("Search", "EditorIcons")
|
||||
if is_instance_valid(list):
|
||||
list.add_theme_stylebox_override("panel", get_theme_stylebox("panel", "Panel"))
|
||||
|
||||
|
||||
### Signals
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cxxkkarhbbf07
|
||||
uid://dqa4a4wwoo0aa
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dnufpcdrreva3"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/files_list.gd" id="1_cytii"]
|
||||
[ext_resource type="Script" uid="uid://dqa4a4wwoo0aa" path="res://addons/dialogue_manager/components/files_list.gd" id="1_cytii"]
|
||||
[ext_resource type="Texture2D" uid="uid://d3lr2uas6ax8v" path="res://addons/dialogue_manager/assets/icon.svg" id="2_3ijx1"]
|
||||
|
||||
[node name="FilesList" type="VBoxContainer"]
|
||||
@@ -9,6 +9,7 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource("1_cytii")
|
||||
icon = ExtResource("2_3ijx1")
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func find_in_files() -> Dictionary:
|
||||
var results: Dictionary = {}
|
||||
|
||||
var q: String = input.text
|
||||
var cache = Engine.get_meta("DialogueCache")
|
||||
var cache = Engine.get_meta("DMCache")
|
||||
var file: FileAccess
|
||||
for path in cache.get_files():
|
||||
var path_results: Array = []
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://xe50vmll2xq4
|
||||
uid://q368fmxxa8sd
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://0n7hwviyyly4"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/find_in_files.gd" id="1_3xicy"]
|
||||
[ext_resource type="Script" uid="uid://q368fmxxa8sd" path="res://addons/dialogue_manager/components/find_in_files.gd" id="1_3xicy"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_owohg"]
|
||||
bg_color = Color(0.266667, 0.278431, 0.352941, 0.243137)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
class_name DialogueManagerParseResult extends RefCounted
|
||||
|
||||
var imported_paths: PackedStringArray = []
|
||||
var using_states: PackedStringArray = []
|
||||
var titles: Dictionary = {}
|
||||
var character_names: PackedStringArray = []
|
||||
var first_title: String = ""
|
||||
var lines: Dictionary = {}
|
||||
var errors: Array[Dictionary] = []
|
||||
var raw_text: String = ""
|
||||
@@ -1 +0,0 @@
|
||||
uid://nkbwbj4jt5h5
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
uid://kmwjxv2fbqfk
|
||||
@@ -1,15 +0,0 @@
|
||||
extends RefCounted
|
||||
|
||||
var text: String = ""
|
||||
var pauses: Dictionary = {}
|
||||
var speeds: Dictionary = {}
|
||||
var mutations: Array[Array] = []
|
||||
var time: String = ""
|
||||
|
||||
|
||||
func _init(data: Dictionary) -> void:
|
||||
text = data.text
|
||||
pauses = data.pauses
|
||||
speeds = data.speeds
|
||||
mutations = data.mutations
|
||||
time = data.time
|
||||
@@ -1 +0,0 @@
|
||||
uid://dubbguqmg0y3y
|
||||
@@ -1,10 +0,0 @@
|
||||
extends RefCounted
|
||||
|
||||
|
||||
var tags: PackedStringArray = []
|
||||
var line_without_tags: String = ""
|
||||
|
||||
|
||||
func _init(data: Dictionary) -> void:
|
||||
tags = data.tags
|
||||
line_without_tags = data.line_without_tags
|
||||
@@ -1 +0,0 @@
|
||||
uid://do3qcb4qvked0
|
||||
@@ -1 +1 @@
|
||||
uid://bs2b6vbxavpev
|
||||
uid://cijsmjkq21cdq
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://gr8nakpbrhby"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/search_and_replace.gd" id="1_8oj1f"]
|
||||
[ext_resource type="Script" uid="uid://cijsmjkq21cdq" path="res://addons/dialogue_manager/components/search_and_replace.gd" id="1_8oj1f"]
|
||||
|
||||
[node name="SearchAndReplace" type="VBoxContainer"]
|
||||
visible = false
|
||||
|
||||
@@ -48,6 +48,8 @@ func apply_filter() -> void:
|
||||
func apply_theme() -> void:
|
||||
if is_instance_valid(filter_edit):
|
||||
filter_edit.right_icon = get_theme_icon("Search", "EditorIcons")
|
||||
if is_instance_valid(list):
|
||||
list.add_theme_stylebox_override("panel", get_theme_stylebox("panel", "Panel"))
|
||||
|
||||
|
||||
### Signals
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://5t2mxrdh0xm3
|
||||
uid://d0k2wndjj0ifm
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://ctns6ouwwd68i"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/title_list.gd" id="1_5qqmd"]
|
||||
[ext_resource type="Script" uid="uid://d0k2wndjj0ifm" path="res://addons/dialogue_manager/components/title_list.gd" id="1_5qqmd"]
|
||||
|
||||
[node name="TitleList" type="VBoxContainer"]
|
||||
anchors_preset = 15
|
||||
|
||||
@@ -86,9 +86,9 @@ func _on_update_button_pressed() -> void:
|
||||
if needs_reload:
|
||||
var will_refresh = on_before_refresh.call()
|
||||
if will_refresh:
|
||||
Engine.get_meta("DialogueManagerPlugin").get_editor_interface().restart_editor(true)
|
||||
EditorInterface.restart_editor(true)
|
||||
else:
|
||||
var scale: float = Engine.get_meta("DialogueManagerPlugin").get_editor_interface().get_editor_scale()
|
||||
var scale: float = EditorInterface.get_editor_scale()
|
||||
download_dialog.min_size = Vector2(300, 250) * scale
|
||||
download_dialog.popup_centered()
|
||||
|
||||
@@ -117,7 +117,7 @@ func _on_download_update_panel_failed() -> void:
|
||||
|
||||
|
||||
func _on_needs_reload_dialog_confirmed() -> void:
|
||||
Engine.get_meta("DialogueManagerPlugin").get_editor_interface().restart_editor(true)
|
||||
EditorInterface.restart_editor(true)
|
||||
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://boqd8cx71f1af
|
||||
uid://cr1tt12dh5ecr
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://co8yl23idiwbi"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogue_manager/components/update_button.gd" id="1_d2tpb"]
|
||||
[ext_resource type="Script" uid="uid://cr1tt12dh5ecr" path="res://addons/dialogue_manager/components/update_button.gd" id="1_d2tpb"]
|
||||
[ext_resource type="PackedScene" uid="uid://qdxrxv3c3hxk" path="res://addons/dialogue_manager/components/download_update_panel.tscn" id="2_iwm7r"]
|
||||
|
||||
[node name="UpdateButton" type="Button"]
|
||||
|
||||
Reference in New Issue
Block a user