Skip to content

Commit 1a113cb

Browse files
authored
Merge pull request #33 from nndda/dev
0.7.0
2 parents c60c9b6 + 36a100b commit 1a113cb

6 files changed

+219
-34
lines changed

addons/Theatre/classes/DialogueParser.gd

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ static func parse_tags(string : String) -> Dictionary:
402402
string = string.replace(string_match, EMPTY)
403403

404404
if tag_key_l.is_valid_int():
405-
var idx = tag_key_l.to_int()
405+
var idx : int = tag_key_l.to_int()
406406
func_pos[tag_pos] = idx
407407

408408
if !func_idx.has(idx):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
@tool
2+
class_name DialogueSyntaxHighlighter
3+
extends EditorSyntaxHighlighter
4+
5+
var text_edit : CodeEdit
6+
var text_edit_initialized := false
7+
8+
const COL : String = "color"
9+
const TRANSPARENT : Color = Color(0, 0, 0, 0)
10+
11+
var string : String
12+
var dict : Dictionary = {}
13+
14+
static var actor_name_line : Color
15+
static var actor_name_line_bg : Color
16+
static var actor_name_line_bg_2 : Color
17+
static var base_content : Color
18+
static var symbol : Color
19+
static var comment : Color
20+
static var tag_content : Color
21+
static var tag_braces : Color
22+
static var caller : Color
23+
static var func_name : Color
24+
static var func_args : Color
25+
static var section : Color
26+
static var section_bg : Color
27+
static var invalid : Color
28+
29+
static var COL_actor_name_line : Dictionary
30+
static var COL_base_content : Dictionary
31+
static var COL_symbol : Dictionary
32+
static var COL_comment : Dictionary
33+
static var COL_tag_content : Dictionary
34+
static var COL_tag_braces : Dictionary
35+
static var COL_caller : Dictionary
36+
static var COL_func_name : Dictionary
37+
static var COL_func_args : Dictionary
38+
static var COL_section : Dictionary
39+
static var COL_invalid : Dictionary
40+
41+
static var color_initialized := false
42+
43+
static func initialize_colors() -> void:
44+
var editor_settings : EditorSettings = TheatrePlugin.editor_settings
45+
46+
actor_name_line = editor_settings.get_setting("text_editor/theme/highlighting/base_type_color")
47+
base_content = editor_settings.get_setting("text_editor/theme/highlighting/text_color")
48+
symbol = editor_settings.get_setting("text_editor/theme/highlighting/symbol_color")
49+
comment = editor_settings.get_setting("text_editor/theme/highlighting/comment_color")
50+
tag_content = editor_settings.get_setting("text_editor/theme/highlighting/user_type_color")
51+
tag_braces = Color(editor_settings.get_setting("text_editor/theme/highlighting/user_type_color"), 0.65)
52+
caller = editor_settings.get_setting("text_editor/theme/highlighting/engine_type_color")
53+
func_name = editor_settings.get_setting("text_editor/theme/highlighting/function_color")
54+
func_args = editor_settings.get_setting("text_editor/theme/highlighting/string_color")
55+
section = editor_settings.get_setting("text_editor/theme/highlighting/keyword_color")
56+
invalid = editor_settings.get_setting("text_editor/theme/highlighting/comment_markers/critical_color")
57+
58+
COL_actor_name_line = {COL: actor_name_line}
59+
COL_base_content = {COL: base_content}
60+
COL_symbol = {COL: symbol}
61+
COL_comment = {COL: comment}
62+
COL_tag_content = {COL: tag_content}
63+
COL_tag_braces = {COL: tag_braces}
64+
COL_caller = {COL: caller}
65+
COL_func_name = {COL: func_name}
66+
COL_func_args = {COL: func_args}
67+
COL_section = {COL: section}
68+
COL_invalid = {COL: invalid}
69+
70+
actor_name_line_bg = Color(actor_name_line, 0.0825)
71+
actor_name_line_bg_2 = Color(actor_name_line, 0.04)
72+
section_bg = Color(section, 0.12)
73+
74+
func initialize_text_edit() -> void:
75+
if get_text_edit() != null:
76+
text_edit = get_text_edit()
77+
text_edit.clear_string_delimiters()
78+
79+
func _init() -> void:
80+
if !color_initialized:
81+
initialize_colors()
82+
color_initialized = true
83+
84+
func _get_name() -> String:
85+
return "Theatre Dialogue"
86+
87+
func _get_supported_languages() -> PackedStringArray:
88+
return ["dlg"]
89+
90+
func is_indented(string : String) -> bool:
91+
return string != string.lstrip(" \t")
92+
93+
func _get_line_syntax_highlighting(line: int) -> Dictionary:
94+
#initialize_colors() # NOTE: uncomment on development
95+
if !text_edit_initialized:
96+
initialize_text_edit()
97+
text_edit_initialized = true
98+
99+
text_edit.set_line_background_color(line, TRANSPARENT)
100+
101+
string = text_edit.get_line(line)
102+
103+
dict.clear()
104+
dict[0] = COL_base_content
105+
106+
if is_indented(string):
107+
var match_func := DialogueParser._regex_func_call.search(string)
108+
var match_newline_tag := null \
109+
if match_func != null else DialogueParser._regex_dlg_tags_newline.search(string)
110+
111+
if match_func != null:
112+
dict[match_func.get_start("caller")] = COL_caller
113+
dict[match_func.get_start("name")] = COL_func_name
114+
dict[match_func.get_start("name") - 1] = COL_symbol
115+
dict[match_func.get_end("name")] = COL_symbol
116+
dict[match_func.get_end("name") + 1] = COL_func_args
117+
dict[match_func.get_end() - 1] = COL_symbol
118+
dict[match_func.get_end()] = COL_base_content
119+
120+
elif match_newline_tag != null:
121+
dict[match_newline_tag.get_start("tag")] = COL_tag_content
122+
dict[match_newline_tag.get_start("arg") - 1] = COL_symbol
123+
dict[match_newline_tag.get_start("arg")] = COL_tag_content
124+
125+
else:
126+
for tag in DialogueParser._regex_dlg_tags.search_all(string):
127+
var START : int = tag.get_start()
128+
var END : int = tag.get_end()
129+
130+
if !dict.has(START):
131+
dict[START] = COL_tag_braces
132+
133+
dict[tag.get_start("tag")] = COL_tag_content
134+
135+
if string.contains("="):
136+
dict[tag.get_start("tag") + 1] = COL_symbol
137+
dict[tag.get_start("arg")] = COL_tag_content
138+
139+
dict[END - 1] = COL_tag_braces
140+
141+
if !dict.has(END):
142+
dict[END] = COL_base_content
143+
144+
for bb in DialogueParser._regex_bbcode_tags.search_all(string):
145+
var START : int = bb.get_start()
146+
var END : int = bb.get_end()
147+
148+
if !dict.has(START):
149+
dict[START] = COL_tag_braces
150+
151+
dict[bb.get_start("tag")] = COL_tag_content
152+
dict[END - 1] = COL_tag_braces
153+
154+
if !dict.has(END):
155+
dict[END] = COL_base_content
156+
157+
else:
158+
dict[0] = COL_invalid
159+
160+
if string.begins_with(DialogueParser.HASH):
161+
dict[0] = COL_comment
162+
163+
else:
164+
if string.ends_with(DialogueParser.COLON):
165+
dict[0] = COL_actor_name_line
166+
dict[string.rfind(DialogueParser.COLON)] = COL_symbol
167+
text_edit.toggle_foldable_line
168+
169+
text_edit.set_line_background_color(line, actor_name_line_bg)
170+
if string.strip_edges() == DialogueParser.COLON:
171+
text_edit.set_line_background_color(line, actor_name_line_bg_2)
172+
173+
elif string.begins_with(DialogueParser.COLON):
174+
dict[0] = COL_section
175+
text_edit.set_line_background_color(line, section_bg)
176+
177+
# why does it need to be ordered????
178+
# TODO: performance
179+
var dict_ordered : Dictionary = {}
180+
181+
var dict_keys : PackedInt64Array = dict.keys()
182+
dict_keys.sort()
183+
184+
for n in dict_keys:
185+
dict_ordered[n] = dict[n]
186+
187+
return dict_ordered

addons/Theatre/classes/TheatrePlugin.gd

+19-21
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,11 @@ class_name TheatrePlugin
55

66
class Config extends RefCounted:
77
const GENERAL_AUTO_UPDATE := "theatre/general/updates/check_updates_automatically"
8-
const DEBUG_SHOW_CRAWL_FOLDER := "theatre/debug/log/show_current_crawling_directory"
9-
const DIALOGUE_IGNORED_DIR := "theatre/resources/dialogue/ignored_directories"
10-
11-
static var debug_show_crawl_dir := false
12-
static var ignored_directories : PackedStringArray
138

149
static func init_configs() -> void:
1510
print(" Initializing configs...")
1611
for config_item : Array in [
1712
[ GENERAL_AUTO_UPDATE, TYPE_BOOL, true, PROPERTY_HINT_NONE, "", ],
18-
[ DEBUG_SHOW_CRAWL_FOLDER, TYPE_BOOL, false, PROPERTY_HINT_NONE, "", ],
19-
[ DIALOGUE_IGNORED_DIR, TYPE_STRING, "addons", PROPERTY_HINT_NONE, "", ],
2013
]:
2114
if ProjectSettings.has_setting(config_item[0]):
2215
print(" %s already exist on ProjectSettings" % config_item[0])
@@ -36,8 +29,6 @@ class Config extends RefCounted:
3629
static func remove_configs() -> void:
3730
for config_item : String in [
3831
GENERAL_AUTO_UPDATE,
39-
DEBUG_SHOW_CRAWL_FOLDER,
40-
DIALOGUE_IGNORED_DIR,
4132
]:
4233
ProjectSettings.set_setting(config_item, null)
4334

@@ -48,20 +39,15 @@ class Config extends RefCounted:
4839
if err != OK:
4940
push_error("Error saving Theatre config: ", err)
5041

51-
static func _project_settings_changed() -> void:
52-
debug_show_crawl_dir = ProjectSettings.get_setting(
53-
DEBUG_SHOW_CRAWL_FOLDER, false
54-
)
55-
56-
ignored_directories = (ProjectSettings.get_setting(
57-
DIALOGUE_IGNORED_DIR
58-
) as String ).split(",", false)
42+
#static func _project_settings_changed() -> void:
43+
#pass
5944

6045
var http_update_req : HTTPRequest
6146

6247
var dialogue_importer : DialogueImporter
48+
var dialogue_syntax_highlighter : DialogueSyntaxHighlighter
6349

64-
var editor_settings := EditorInterface.get_editor_settings()
50+
static var editor_settings := EditorInterface.get_editor_settings()
6551
var editor_resource_filesystem := EditorInterface.get_resource_filesystem()
6652

6753
var plugin_submenu : PopupMenu = preload(
@@ -71,17 +57,22 @@ var plugin_submenu : PopupMenu = preload(
7157
func _enter_tree() -> void:
7258
plugin_submenu.hide()
7359
dialogue_importer = DialogueImporter.new()
60+
dialogue_syntax_highlighter = DialogueSyntaxHighlighter.new()
7461

7562
# Initialize Theatre config
7663
print("🎭 Theatre v%s by nnda" % get_plugin_version())
7764

7865
# Compile DialogueParser RegExes
7966
DialogueParser._initialize_regex()
8067

68+
# Initialize syntax highlighter
69+
DialogueSyntaxHighlighter.initialize_colors()
70+
editor_settings.settings_changed.connect(DialogueSyntaxHighlighter.initialize_colors)
71+
8172
# Initialize project settings
8273
Config.init_configs()
83-
ProjectSettings.settings_changed.connect(Config._project_settings_changed)
84-
Config._project_settings_changed()
74+
#ProjectSettings.settings_changed.connect(Config._project_settings_changed)
75+
#Config._project_settings_changed()
8576

8677
# Add `.dlg` text file extension
8778
var text_files_ext : String = editor_settings\
@@ -110,6 +101,9 @@ func _enter_tree() -> void:
110101
# Initialize Dialogue importer
111102
add_import_plugin(dialogue_importer)
112103

104+
# Register Dialogue syntax highlighter
105+
EditorInterface.get_script_editor().register_syntax_highlighter(dialogue_syntax_highlighter)
106+
113107
func _ready() -> void:
114108
if DisplayServer.get_name() != "headless":
115109
# Initialize update check
@@ -127,7 +121,7 @@ func _exit_tree() -> void:
127121

128122
# Clear project settings
129123
Config.remove_configs()
130-
ProjectSettings.settings_changed.disconnect(Config._project_settings_changed)
124+
#ProjectSettings.settings_changed.disconnect(Config._project_settings_changed)
131125

132126
# Clear update check
133127
if http_update_req != null:
@@ -141,6 +135,10 @@ func _exit_tree() -> void:
141135
remove_import_plugin(dialogue_importer)
142136
dialogue_importer = null
143137

138+
# Unegister Dialogue syntax highlighter
139+
EditorInterface.get_script_editor().unregister_syntax_highlighter(dialogue_syntax_highlighter)
140+
dialogue_syntax_highlighter = null
141+
144142
editor_resource_filesystem = null
145143

146144
func _disable_plugin() -> void:

addons/Theatre/plugin.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
name="Theatre"
44
description="Text-based linear dialogue system."
55
author="nnda"
6-
version="0.6.1"
6+
version="0.7.0"
77
script="classes/TheatrePlugin.gd"

dialogue/demo_dialogue.dlg

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ Dia:
33
this is a demo dialogue to demonstrate Theatre addon's core feature."
44

55
:
6-
"There are 3 main classes that makes part of Theatre plugin:{delay = 0.7}
6+
"There are 3 main classes that makes part of Theatre plugin:{d = 0.7}
77
Dialogue, {d = 0.7}
88
DialogueLabel, {d = 0.7}
99
& Stage"
1010

1111
:
1212
"Lets start with Dialogue:{d = 0.8}
1313
Its a resource, containing the writing of
14-
your{s = 0.035}...{s}{d = 0.5} well,{d = 0.8} dialogue!{d = 1.0}
14+
your{s = 0.035}...{s} {d = 0.5}well,{d = 0.8} dialogue!{d = 1.0}
1515
You write them in a plain text file,{d = 0.9}
1616
the written dialogue then get parsed to a resource,{d = 0.9}
1717
that you can then use in your project"
@@ -21,7 +21,7 @@ Dia:
2121

2222
:
2323
"Most of the classes references are documented directly in the addon.{d = 0.8}
24-
In the editor,{d = 0.8} You can press F1 and look for Theatre's classes
24+
In the editor,{d = 0.8} press F1 and look for Theatre's classes
2525
to see its documentation page."
2626

2727
:

dialogue/demo_dialogue.dlg.REF.tres

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[gd_resource type="Resource" script_class="Dialogue" load_steps=2 format=3]
22

3-
[ext_resource type="Script" path="res://addons/Theatre/classes/Dialogue.gd" id="1_yvcq1"]
3+
[ext_resource type="Script" path="res://addons/Theatre/classes/Dialogue.gd" id="1_vh82u"]
44

55
[resource]
6-
script = ExtResource("1_yvcq1")
6+
script = ExtResource("1_vh82u")
77
_sets = Array[Dictionary]([{
88
"actor": "Dia",
99
"content": "\"Welcome to the Theatre! Hi there! this is a demo dialogue to demonstrate Theatre addon's core feature.\" ",
@@ -25,7 +25,7 @@ _sets = Array[Dictionary]([{
2525
}, {
2626
"actor": "Dia",
2727
"content": "\"There are 3 main classes that makes part of Theatre plugin: Dialogue, DialogueLabel, & Stage\" ",
28-
"content_raw": "\"There are 3 main classes that makes part of Theatre plugin:{delay = 0.7} Dialogue, {d = 0.7} DialogueLabel, {d = 0.7} & Stage\" ",
28+
"content_raw": "\"There are 3 main classes that makes part of Theatre plugin:{d = 0.7} Dialogue, {d = 0.7} DialogueLabel, {d = 0.7} & Stage\" ",
2929
"func": [],
3030
"func_idx": PackedInt64Array(),
3131
"func_pos": {},
@@ -44,7 +44,7 @@ _sets = Array[Dictionary]([{
4444
}, {
4545
"actor": "Dia",
4646
"content": "\"Lets start with Dialogue: Its a resource, containing the writing of your... well, dialogue! You write them in a plain text file, the written dialogue then get parsed to a resource, that you can then use in your project\" ",
47-
"content_raw": "\"Lets start with Dialogue:{d = 0.8} Its a resource, containing the writing of your{s = 0.035}...{s}{d = 0.5} well,{d = 0.8} dialogue!{d = 1.0} You write them in a plain text file,{d = 0.9} the written dialogue then get parsed to a resource,{d = 0.9} that you can then use in your project\" ",
47+
"content_raw": "\"Lets start with Dialogue:{d = 0.8} Its a resource, containing the writing of your{s = 0.035}...{s} {d = 0.5}well,{d = 0.8} dialogue!{d = 1.0} You write them in a plain text file,{d = 0.9} the written dialogue then get parsed to a resource,{d = 0.9} that you can then use in your project\" ",
4848
"func": [],
4949
"func_idx": PackedInt64Array(),
5050
"func_pos": {},
@@ -54,7 +54,7 @@ _sets = Array[Dictionary]([{
5454
"tags": {
5555
"delays": {
5656
26: 0.8,
57-
76: 0.5,
57+
77: 0.5,
5858
82: 0.8,
5959
92: 1.0,
6060
129: 0.9,
@@ -89,8 +89,8 @@ _sets = Array[Dictionary]([{
8989
"vars": PackedStringArray()
9090
}, {
9191
"actor": "Dia",
92-
"content": "\"Most of the classes references are documented directly in the addon. In the editor, You can press F1 and look for Theatre's classes to see its documentation page.\" ",
93-
"content_raw": "\"Most of the classes references are documented directly in the addon.{d = 0.8} In the editor,{d = 0.8} You can press F1 and look for Theatre's classes to see its documentation page.\" ",
92+
"content": "\"Most of the classes references are documented directly in the addon. In the editor, press F1 and look for Theatre's classes to see its documentation page.\" ",
93+
"content_raw": "\"Most of the classes references are documented directly in the addon.{d = 0.8} In the editor,{d = 0.8} press F1 and look for Theatre's classes to see its documentation page.\" ",
9494
"func": [],
9595
"func_idx": PackedInt64Array(),
9696
"func_pos": {},
@@ -138,7 +138,7 @@ _sets = Array[Dictionary]([{
138138
},
139139
"vars": PackedStringArray()
140140
}])
141-
_source_path = "res://dialogue/demo_dialogue.dlg"
141+
_source_path = "res://tests/dialogue_test.gd:12"
142142
_used_variables = PackedStringArray()
143143
_used_function_calls = {}
144144
_sections = {}

0 commit comments

Comments
 (0)