Skip to content

Commit

Permalink
Merge pull request #33 from nndda/dev
Browse files Browse the repository at this point in the history
0.7.0
  • Loading branch information
nndda authored Oct 12, 2024
2 parents c60c9b6 + 36a100b commit 1a113cb
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 34 deletions.
2 changes: 1 addition & 1 deletion addons/Theatre/classes/DialogueParser.gd
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ static func parse_tags(string : String) -> Dictionary:
string = string.replace(string_match, EMPTY)

if tag_key_l.is_valid_int():
var idx = tag_key_l.to_int()
var idx : int = tag_key_l.to_int()
func_pos[tag_pos] = idx

if !func_idx.has(idx):
Expand Down
187 changes: 187 additions & 0 deletions addons/Theatre/classes/DialogueSyntaxHighlighter.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
@tool
class_name DialogueSyntaxHighlighter
extends EditorSyntaxHighlighter

var text_edit : CodeEdit
var text_edit_initialized := false

const COL : String = "color"
const TRANSPARENT : Color = Color(0, 0, 0, 0)

var string : String
var dict : Dictionary = {}

static var actor_name_line : Color
static var actor_name_line_bg : Color
static var actor_name_line_bg_2 : Color
static var base_content : Color
static var symbol : Color
static var comment : Color
static var tag_content : Color
static var tag_braces : Color
static var caller : Color
static var func_name : Color
static var func_args : Color
static var section : Color
static var section_bg : Color
static var invalid : Color

static var COL_actor_name_line : Dictionary
static var COL_base_content : Dictionary
static var COL_symbol : Dictionary
static var COL_comment : Dictionary
static var COL_tag_content : Dictionary
static var COL_tag_braces : Dictionary
static var COL_caller : Dictionary
static var COL_func_name : Dictionary
static var COL_func_args : Dictionary
static var COL_section : Dictionary
static var COL_invalid : Dictionary

static var color_initialized := false

static func initialize_colors() -> void:
var editor_settings : EditorSettings = TheatrePlugin.editor_settings

actor_name_line = editor_settings.get_setting("text_editor/theme/highlighting/base_type_color")
base_content = editor_settings.get_setting("text_editor/theme/highlighting/text_color")
symbol = editor_settings.get_setting("text_editor/theme/highlighting/symbol_color")
comment = editor_settings.get_setting("text_editor/theme/highlighting/comment_color")
tag_content = editor_settings.get_setting("text_editor/theme/highlighting/user_type_color")
tag_braces = Color(editor_settings.get_setting("text_editor/theme/highlighting/user_type_color"), 0.65)
caller = editor_settings.get_setting("text_editor/theme/highlighting/engine_type_color")
func_name = editor_settings.get_setting("text_editor/theme/highlighting/function_color")
func_args = editor_settings.get_setting("text_editor/theme/highlighting/string_color")
section = editor_settings.get_setting("text_editor/theme/highlighting/keyword_color")
invalid = editor_settings.get_setting("text_editor/theme/highlighting/comment_markers/critical_color")

COL_actor_name_line = {COL: actor_name_line}
COL_base_content = {COL: base_content}
COL_symbol = {COL: symbol}
COL_comment = {COL: comment}
COL_tag_content = {COL: tag_content}
COL_tag_braces = {COL: tag_braces}
COL_caller = {COL: caller}
COL_func_name = {COL: func_name}
COL_func_args = {COL: func_args}
COL_section = {COL: section}
COL_invalid = {COL: invalid}

actor_name_line_bg = Color(actor_name_line, 0.0825)
actor_name_line_bg_2 = Color(actor_name_line, 0.04)
section_bg = Color(section, 0.12)

func initialize_text_edit() -> void:
if get_text_edit() != null:
text_edit = get_text_edit()
text_edit.clear_string_delimiters()

func _init() -> void:
if !color_initialized:
initialize_colors()
color_initialized = true

func _get_name() -> String:
return "Theatre Dialogue"

func _get_supported_languages() -> PackedStringArray:
return ["dlg"]

func is_indented(string : String) -> bool:
return string != string.lstrip(" \t")

func _get_line_syntax_highlighting(line: int) -> Dictionary:
#initialize_colors() # NOTE: uncomment on development
if !text_edit_initialized:
initialize_text_edit()
text_edit_initialized = true

text_edit.set_line_background_color(line, TRANSPARENT)

string = text_edit.get_line(line)

dict.clear()
dict[0] = COL_base_content

if is_indented(string):
var match_func := DialogueParser._regex_func_call.search(string)
var match_newline_tag := null \
if match_func != null else DialogueParser._regex_dlg_tags_newline.search(string)

if match_func != null:
dict[match_func.get_start("caller")] = COL_caller
dict[match_func.get_start("name")] = COL_func_name
dict[match_func.get_start("name") - 1] = COL_symbol
dict[match_func.get_end("name")] = COL_symbol
dict[match_func.get_end("name") + 1] = COL_func_args
dict[match_func.get_end() - 1] = COL_symbol
dict[match_func.get_end()] = COL_base_content

elif match_newline_tag != null:
dict[match_newline_tag.get_start("tag")] = COL_tag_content
dict[match_newline_tag.get_start("arg") - 1] = COL_symbol
dict[match_newline_tag.get_start("arg")] = COL_tag_content

else:
for tag in DialogueParser._regex_dlg_tags.search_all(string):
var START : int = tag.get_start()
var END : int = tag.get_end()

if !dict.has(START):
dict[START] = COL_tag_braces

dict[tag.get_start("tag")] = COL_tag_content

if string.contains("="):
dict[tag.get_start("tag") + 1] = COL_symbol
dict[tag.get_start("arg")] = COL_tag_content

dict[END - 1] = COL_tag_braces

if !dict.has(END):
dict[END] = COL_base_content

for bb in DialogueParser._regex_bbcode_tags.search_all(string):
var START : int = bb.get_start()
var END : int = bb.get_end()

if !dict.has(START):
dict[START] = COL_tag_braces

dict[bb.get_start("tag")] = COL_tag_content
dict[END - 1] = COL_tag_braces

if !dict.has(END):
dict[END] = COL_base_content

else:
dict[0] = COL_invalid

if string.begins_with(DialogueParser.HASH):
dict[0] = COL_comment

else:
if string.ends_with(DialogueParser.COLON):
dict[0] = COL_actor_name_line
dict[string.rfind(DialogueParser.COLON)] = COL_symbol
text_edit.toggle_foldable_line

text_edit.set_line_background_color(line, actor_name_line_bg)
if string.strip_edges() == DialogueParser.COLON:
text_edit.set_line_background_color(line, actor_name_line_bg_2)

elif string.begins_with(DialogueParser.COLON):
dict[0] = COL_section
text_edit.set_line_background_color(line, section_bg)

# why does it need to be ordered????
# TODO: performance
var dict_ordered : Dictionary = {}

var dict_keys : PackedInt64Array = dict.keys()
dict_keys.sort()

for n in dict_keys:
dict_ordered[n] = dict[n]

return dict_ordered
40 changes: 19 additions & 21 deletions addons/Theatre/classes/TheatrePlugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,11 @@ class_name TheatrePlugin

class Config extends RefCounted:
const GENERAL_AUTO_UPDATE := "theatre/general/updates/check_updates_automatically"
const DEBUG_SHOW_CRAWL_FOLDER := "theatre/debug/log/show_current_crawling_directory"
const DIALOGUE_IGNORED_DIR := "theatre/resources/dialogue/ignored_directories"

static var debug_show_crawl_dir := false
static var ignored_directories : PackedStringArray

static func init_configs() -> void:
print(" Initializing configs...")
for config_item : Array in [
[ GENERAL_AUTO_UPDATE, TYPE_BOOL, true, PROPERTY_HINT_NONE, "", ],
[ DEBUG_SHOW_CRAWL_FOLDER, TYPE_BOOL, false, PROPERTY_HINT_NONE, "", ],
[ DIALOGUE_IGNORED_DIR, TYPE_STRING, "addons", PROPERTY_HINT_NONE, "", ],
]:
if ProjectSettings.has_setting(config_item[0]):
print(" %s already exist on ProjectSettings" % config_item[0])
Expand All @@ -36,8 +29,6 @@ class Config extends RefCounted:
static func remove_configs() -> void:
for config_item : String in [
GENERAL_AUTO_UPDATE,
DEBUG_SHOW_CRAWL_FOLDER,
DIALOGUE_IGNORED_DIR,
]:
ProjectSettings.set_setting(config_item, null)

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

static func _project_settings_changed() -> void:
debug_show_crawl_dir = ProjectSettings.get_setting(
DEBUG_SHOW_CRAWL_FOLDER, false
)

ignored_directories = (ProjectSettings.get_setting(
DIALOGUE_IGNORED_DIR
) as String ).split(",", false)
#static func _project_settings_changed() -> void:
#pass

var http_update_req : HTTPRequest

var dialogue_importer : DialogueImporter
var dialogue_syntax_highlighter : DialogueSyntaxHighlighter

var editor_settings := EditorInterface.get_editor_settings()
static var editor_settings := EditorInterface.get_editor_settings()
var editor_resource_filesystem := EditorInterface.get_resource_filesystem()

var plugin_submenu : PopupMenu = preload(
Expand All @@ -71,17 +57,22 @@ var plugin_submenu : PopupMenu = preload(
func _enter_tree() -> void:
plugin_submenu.hide()
dialogue_importer = DialogueImporter.new()
dialogue_syntax_highlighter = DialogueSyntaxHighlighter.new()

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

# Compile DialogueParser RegExes
DialogueParser._initialize_regex()

# Initialize syntax highlighter
DialogueSyntaxHighlighter.initialize_colors()
editor_settings.settings_changed.connect(DialogueSyntaxHighlighter.initialize_colors)

# Initialize project settings
Config.init_configs()
ProjectSettings.settings_changed.connect(Config._project_settings_changed)
Config._project_settings_changed()
#ProjectSettings.settings_changed.connect(Config._project_settings_changed)
#Config._project_settings_changed()

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

# Register Dialogue syntax highlighter
EditorInterface.get_script_editor().register_syntax_highlighter(dialogue_syntax_highlighter)

func _ready() -> void:
if DisplayServer.get_name() != "headless":
# Initialize update check
Expand All @@ -127,7 +121,7 @@ func _exit_tree() -> void:

# Clear project settings
Config.remove_configs()
ProjectSettings.settings_changed.disconnect(Config._project_settings_changed)
#ProjectSettings.settings_changed.disconnect(Config._project_settings_changed)

# Clear update check
if http_update_req != null:
Expand All @@ -141,6 +135,10 @@ func _exit_tree() -> void:
remove_import_plugin(dialogue_importer)
dialogue_importer = null

# Unegister Dialogue syntax highlighter
EditorInterface.get_script_editor().unregister_syntax_highlighter(dialogue_syntax_highlighter)
dialogue_syntax_highlighter = null

editor_resource_filesystem = null

func _disable_plugin() -> void:
Expand Down
2 changes: 1 addition & 1 deletion addons/Theatre/plugin.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
name="Theatre"
description="Text-based linear dialogue system."
author="nnda"
version="0.6.1"
version="0.7.0"
script="classes/TheatrePlugin.gd"
6 changes: 3 additions & 3 deletions dialogue/demo_dialogue.dlg
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ Dia:
this is a demo dialogue to demonstrate Theatre addon's core feature."

:
"There are 3 main classes that makes part of Theatre plugin:{delay = 0.7}
"There are 3 main classes that makes part of Theatre plugin:{d = 0.7}
Dialogue, {d = 0.7}
DialogueLabel, {d = 0.7}
& Stage"

:
"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}
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"
Expand All @@ -21,7 +21,7 @@ Dia:

:
"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
In the editor,{d = 0.8} press F1 and look for Theatre's classes
to see its documentation page."

:
Expand Down
16 changes: 8 additions & 8 deletions dialogue/demo_dialogue.dlg.REF.tres
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[gd_resource type="Resource" script_class="Dialogue" load_steps=2 format=3]

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

[resource]
script = ExtResource("1_yvcq1")
script = ExtResource("1_vh82u")
_sets = Array[Dictionary]([{
"actor": "Dia",
"content": "\"Welcome to the Theatre! Hi there! this is a demo dialogue to demonstrate Theatre addon's core feature.\" ",
Expand All @@ -25,7 +25,7 @@ _sets = Array[Dictionary]([{
}, {
"actor": "Dia",
"content": "\"There are 3 main classes that makes part of Theatre plugin: Dialogue, DialogueLabel, & Stage\" ",
"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\" ",
"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\" ",
"func": [],
"func_idx": PackedInt64Array(),
"func_pos": {},
Expand All @@ -44,7 +44,7 @@ _sets = Array[Dictionary]([{
}, {
"actor": "Dia",
"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\" ",
"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\" ",
"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\" ",
"func": [],
"func_idx": PackedInt64Array(),
"func_pos": {},
Expand All @@ -54,7 +54,7 @@ _sets = Array[Dictionary]([{
"tags": {
"delays": {
26: 0.8,
76: 0.5,
77: 0.5,
82: 0.8,
92: 1.0,
129: 0.9,
Expand Down Expand Up @@ -89,8 +89,8 @@ _sets = Array[Dictionary]([{
"vars": PackedStringArray()
}, {
"actor": "Dia",
"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.\" ",
"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.\" ",
"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.\" ",
"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.\" ",
"func": [],
"func_idx": PackedInt64Array(),
"func_pos": {},
Expand Down Expand Up @@ -138,7 +138,7 @@ _sets = Array[Dictionary]([{
},
"vars": PackedStringArray()
}])
_source_path = "res://dialogue/demo_dialogue.dlg"
_source_path = "res://tests/dialogue_test.gd:12"
_used_variables = PackedStringArray()
_used_function_calls = {}
_sections = {}

0 comments on commit 1a113cb

Please sign in to comment.