From 1e1bb8936f2255c24c491f681c013cfe9e3251aa Mon Sep 17 00:00:00 2001 From: Bram Dingelstad Date: Wed, 8 Dec 2021 20:29:52 +0100 Subject: [PATCH] feat: added colors and protagonist to preview --- .gitignore | 1 + README.md | 2 +- addons/Wol/core/Program.gd | 14 ++++- addons/Wol/core/compiler/Compiler.gd | 2 +- addons/Wol/editor/Editor.gd | 5 ++ addons/Wol/editor/Preview.gd | 85 +++++++++++++++++++++++----- addons/Wol/editor/WolEditor.gd | 26 +++++++-- addons/Wol/editor/WolEditor.tscn | 4 +- 8 files changed, 113 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 271f639..33265de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .import .DS_Store +export diff --git a/README.md b/README.md index accd4ea..34fa97c 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ There are few things that need to be ironed out to be 100% feature compatible wi - [ ] Support for [format functions](https://yarnspinner.dev/docs/syntax/#format-functions). - [ ] ~Support~ Fix for conditional options. - [ ] In-editor dialogue editor with preview. - - [ ] Lines connecting different nodes if they refer to eachother. + - [x] Lines connecting different nodes if they refer to eachother. - [x] Error hints when doing something wrong. - [x] Basic saving, opening and saving-as. - [ ] Remove all `printerr` in favor of (soft) `assert`s. diff --git a/addons/Wol/core/Program.gd b/addons/Wol/core/Program.gd index 4b9d282..876dcc6 100644 --- a/addons/Wol/core/Program.gd +++ b/addons/Wol/core/Program.gd @@ -50,12 +50,13 @@ class Command: class WolNode: var name = '' + var program var instructions = [] var labels = {} var tags = [] var source_id = '' - func _init(other = null): + func _init(_program, other = null): if other != null and other.get_script() == self.get_script(): name = other.name instructions += other.instructions @@ -64,6 +65,8 @@ class WolNode: tags += other.tags source_id = other.source_id + program = _program + func equals(other): if other.get_script() != get_script(): return false @@ -80,6 +83,15 @@ class WolNode: func _to_string(): return "WolNode[%s:%s]" % [name, source_id] + func get_lines(): + var lines = [] + + for instruction in instructions: + if instruction.operation == Constants.ByteCode.RunLine: + lines.append(program.strings[instruction.operands.front().value]) + + return lines + # TODO: Make this make sense class Operand: enum ValueType { diff --git a/addons/Wol/core/compiler/Compiler.gd b/addons/Wol/core/compiler/Compiler.gd index f40cbc8..88a7efa 100644 --- a/addons/Wol/core/compiler/Compiler.gd +++ b/addons/Wol/core/compiler/Compiler.gd @@ -163,7 +163,7 @@ func compile(): func compile_node(program, parsed_node): self.assert(not program.nodes.has(parsed_node.name), 'Duplicate node in program: %s' % parsed_node.name) - var node_compiled = Program.WolNode.new() + var node_compiled = Program.WolNode.new(program) node_compiled.name = parsed_node.name node_compiled.tags = parsed_node.tags diff --git a/addons/Wol/editor/Editor.gd b/addons/Wol/editor/Editor.gd index 47aac83..16318d6 100644 --- a/addons/Wol/editor/Editor.gd +++ b/addons/Wol/editor/Editor.gd @@ -4,12 +4,14 @@ extends Panel var current_graph_node onready var preview = get_node('../Preview') +onready var wol_editor = find_parent('WolEditor') func _ready(): hide() connect('visibility_changed', self, '_on_visibility_changed') $Tools/Left/Play.connect('pressed', self, '_on_play') $Tools/Right/Close.connect('pressed', self, 'close') + $Tools/Right/Delete.connect('pressed', self, '_on_delete_pressed') func close(): hide() @@ -55,6 +57,9 @@ func toggle_text_edit(text_edit): func _on_play(): preview.open_node(current_graph_node) +func _on_delete_pressed(): + wol_editor.confirm_delete_node(current_graph_node) + func _on_title_changed(): current_graph_node.node.title = $HBoxContainer/TextEdit.text current_graph_node.compile() diff --git a/addons/Wol/editor/Preview.gd b/addons/Wol/editor/Preview.gd index d0d8503..5396303 100644 --- a/addons/Wol/editor/Preview.gd +++ b/addons/Wol/editor/Preview.gd @@ -1,3 +1,4 @@ +tool extends Panel var current_graph_node @@ -7,14 +8,15 @@ onready var button_template = $Options/List/ButtonTemplate onready var wol_editor = find_parent('WolEditor') -# TODO: Make sure all focus is lost when clicking this pane -# TODO: Add restart button -# TODO: Add next button - func _ready(): hide() $Wol.connect('line', self, '_on_line') $Wol.connect('options', self, '_on_options') + + connect('gui_input', self, '_on_gui_input') + + $Tools/Left/Next.connect('pressed', self, 'next') + $Tools/Left/Restart.connect('pressed', self, 'restart') $Tools/Right/Close.connect('pressed', self, 'close') func open_node(graph_node): @@ -22,6 +24,23 @@ func open_node(graph_node): $Wol.stop() + yield(get_tree(), 'idle_frame') + + clear_chat() + + $Tools/Left/Protagonist.text = guess_protagonist() + + $Wol.variable_storage = {} + $Wol.set_program(wol_editor.get_program()) + + yield(get_tree(), 'idle_frame') + + $Wol.start(current_graph_node.node.title) + + show() + grab_focus() + +func clear_chat(): for child in $Content/List.get_children(): if child != line_template and not 'Padding' in child.name: $Content/List.remove_child(child) @@ -31,11 +50,24 @@ func open_node(graph_node): if child != button_template: $Options/List.remove_child(child) child.queue_free() - - $Wol.variable_storage = {} - $Wol.set_program(wol_editor.get_program()) - $Wol.start(current_graph_node.node.title) - show() + + +func guess_protagonist(): + var protagonist = 'You' + var wol_node = wol_editor.get_program().nodes[current_graph_node.node.title] + + for line in wol_node.get_lines(): + if get_protagonist(line): + protagonist = get_protagonist(line) + if protagonist == 'You': + break + + return protagonist + +func get_protagonist(line): + if ':' in line.text and line.text.find(':') < 30: + return line.text.split(':')[0] + return func close(): hide() @@ -45,14 +77,33 @@ func close(): func next(): $Wol.resume() +func restart(): + $Wol.stop() + + yield(get_tree(), 'idle_frame') + + clear_chat() + + yield(get_tree(), 'idle_frame') + + $Wol.start(current_graph_node.node.title) + func _on_line(line): var line_node = line_template.duplicate() $Content/List.add_child(line_node) $Content/List/PaddingBottom.raise() - # TODO: Add hash() based color from speaker + # TODO: Add hash() based color from speaker line_node.get_node('RichTextLabel').bbcode_text = line.text + + var padding_node = 'PaddingRight' if get_protagonist(line) == $Tools/Left/Protagonist.text else 'PaddingLeft' + line_node.get_node(padding_node).size_flags_horizontal = SIZE_EXPAND_FILL + var panel = line_node.get_node('RichTextLabel/Panel').get('custom_styles/panel').duplicate() + panel.bg_color = Color(hash(get_protagonist(line))) + line_node.get_node('RichTextLabel/Panel').set('custom_styles/panel', panel) + line_node.show() + yield(get_tree(), 'idle_frame') $Content.scroll_vertical = $Content/List.rect_size.y @@ -73,10 +124,14 @@ func _on_option_pressed(option): $Options/List.remove_child(child) child.queue_free() +func _on_gui_input(event): + if visible: + if event is InputEventMouseButton and event.doubleclick: + next() + + if event is InputEventMouseButton and event.pressed: + grab_focus() + func _input(event): - if visible \ - and ( \ - (event is InputEventMouseButton and event.doubleclick) \ - or (event is InputEventKey and not event.pressed and event.scancode in [KEY_SPACE, KEY_ENTER]) \ - ): + if visible and has_focus() and event is InputEventKey and not event.pressed and event.scancode in [KEY_SPACE, KEY_ENTER]: next() diff --git a/addons/Wol/editor/WolEditor.gd b/addons/Wol/editor/WolEditor.gd index 174b5b2..6d1ff4a 100644 --- a/addons/Wol/editor/WolEditor.gd +++ b/addons/Wol/editor/WolEditor.gd @@ -10,6 +10,17 @@ var selected_node onready var original_delete_node_dialog = $DeleteNodeDialog.dialog_text +# TODO: Conditionally load in theme based on Editor or standalone +# TODO: Make deleting undo-able +# TODO: Implement alternative "single" line style of connecting +# TODO: Test out web version +# TODO: Make web loading / saving work +# TODO: Make theme for standalone editor +# TODO: Make a "Godot editor" version of the editor theme +# FIXME: Make lines render appropriately after connecting +# FIXME: Make all parts of the code "tool"s and safekeep its execution while in editor +# FIXME: Fix changing of titles + func _ready(): for menu_button in [$Menu/File]: menu_button.get_popup().connect('index_pressed', self, '_on_menu_pressed', [menu_button.get_popup()]) @@ -20,13 +31,10 @@ func _ready(): $DeleteNodeDialog.connect('confirmed', self, 'delete_node') - # TODO: Conditionally load in theme based on Editor or standalone - path = 'res://dialogue.wol' build_nodes() func create_node(position = Vector2.ZERO): - print('creating node!') var graph_node = GraphNodeTemplate.duplicate() $GraphEdit.add_child(graph_node) @@ -43,9 +51,16 @@ func create_node(position = Vector2.ZERO): graph_node.show() func delete_node(node = selected_node): + if $HBoxContainer/Editor.visible: + $HBoxContainer/Editor.close() $GraphEdit.remove_child(node) node.queue_free() +func confirm_delete_node(node = selected_node): + selected_node = node + $DeleteNodeDialog.dialog_text = original_delete_node_dialog % selected_node.name + $DeleteNodeDialog.popup() + func build_nodes(): for node in Compiler.new(path).get_nodes(): var graph_node = GraphNodeTemplate.duplicate() @@ -178,6 +193,5 @@ func _input(event): and not event.pressed and event.scancode == KEY_DELETE \ and selected_node \ and not $HBoxContainer/Editor.visible: - $DeleteNodeDialog.dialog_text = original_delete_node_dialog % selected_node.name - $DeleteNodeDialog.popup() - + confirm_delete_node() + diff --git a/addons/Wol/editor/WolEditor.tscn b/addons/Wol/editor/WolEditor.tscn index 29f694f..569e23b 100644 --- a/addons/Wol/editor/WolEditor.tscn +++ b/addons/Wol/editor/WolEditor.tscn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef446d59a4c2bd4cf042b55abf92d9c816c2af021f81e6c8f6fd83a07ba75a55 -size 610584 +oid sha256:20608d086e461b0de5a212791ad0d6e3213b20de161612463fff159618137ef9 +size 611270