feat: added a bunch of features

This commit is contained in:
Bram Dingelstad 2021-12-09 18:43:03 +01:00
parent 247f6b54c2
commit 3ebbbdbf90
124 changed files with 2556 additions and 116 deletions

View file

@ -1,7 +1,7 @@
title: Sally.Watch
tags:
colorID:
position: 500, 400
position: 600, 400
---
Sally: Not really. #line:8c3f98
Sally: Same old nebula, doing the same old thing. #line:24c418
@ -12,24 +12,17 @@ Sally: Oh, Ship wanted to see you. Go say hi to it. #line:df4eaf
Sally: Go say hi again. #line:5df323
<<endif>>
===
title: Sally.Exit
tags:
colorID:
position: 100, 400
---
Sally: Bye. #line:60c282
===
title: Sally.Sorry
tags:
colorID:
position: 900, 400
position: 600, 700
---
Sally: Yeah. Don't do it again. #line:d7df49
===
title: Sally
tags:
colorID:
position: 500, 100
position: -100, 400
---
<<if visited("Sally") is false>>
Player: Hey, Sally. #line:794945
@ -49,4 +42,4 @@ position: 500, 100
[[Sorry about the console.|Sally.Sorry]] #line:0a7e39
<<endif>>
[[See you later.|Sally.Exit]] #line:0facf7
===
===

View file

@ -199,10 +199,8 @@ class Statement extends ParseNode:
while parser.next_symbol_is([Constants.TokenType.TagMarker]):
parser.expect_symbol([Constants.TokenType.TagMarker])
if parser.next_symbol_is([Constants.TokenType.Identifier]):
var tag = parser.expect_symbol([Constants.TokenType.Identifier]).value
tags.append(tag)
var tag = parser.expect_symbol([Constants.TokenType.Identifier]).value
tags.append(tag)
if tags.size() > 0:
self.tags = tags
@ -432,9 +430,9 @@ class ShortCutOption extends ParseNode:
elif parser.next_symbols_are([Constants.TokenType.TagMarker, Constants.TokenType.Identifier]):
parser.expect_symbol([Constants.TokenType.TagMarker])
if parser.next_token_is([Constants.TokenType.Identifier]):
var tag = parser.expect_symbol([Constants.TokenType.Identifier]).value
tags.append(tag)
var tag = parser.expect_symbol([Constants.TokenType.Identifier]).value
tags.append(tag)
self.tags = tags
# parse remaining statements
@ -511,9 +509,9 @@ class OptionStatement extends ParseNode:
# NOTE: if there is a | get the next string
if parser.next_symbol_is([Constants.TokenType.OptionDelimit]):
parser.expect_symbol([Constants.TokenType.OptionDelimit])
if parser.next_symbol_is([Constants.TokenType.Text, Constants.TokenType.Identifier]):
var t = parser.expect_symbol([Constants.TokenType.Text, Constants.TokenType.Identifier])
strings.append(t.value as String)
var t = parser.expect_symbol([Constants.TokenType.Text, Constants.TokenType.Identifier])
strings.append(t.value as String)
label = strings[0] if strings.size() > 1 else ''
destination = strings[1] if strings.size() > 1 else strings[0]
@ -947,12 +945,8 @@ class Assignment extends ParseNode:
func _init(parent, parser).(parent, parser):
parser.expect_symbol([Constants.TokenType.BeginCommand])
parser.expect_symbol([Constants.TokenType.Set])
if parser.next_symbol_is([Constants.TokenType.Variable]):
destination = parser.expect_symbol([Constants.TokenType.Variable]).value
if parser.next_symbol_is(Assignment.valid_ops()):
operation = parser.expect_symbol(Assignment.valid_ops()).type
destination = parser.expect_symbol([Constants.TokenType.Variable]).value
operation = parser.expect_symbol(Assignment.valid_ops()).type
value = ExpressionNode.parse(self, parser)
parser.expect_symbol([Constants.TokenType.EndCommand])

View file

@ -0,0 +1,7 @@
extends WindowDialog
func _ready():
$RichTextLabel.connect('meta_clicked', self, '_on_url_click')
func _on_url_click(url):
OS.shell_open(url)

View file

@ -13,6 +13,10 @@ func _ready():
$Tools/Right/Close.connect('pressed', self, 'close')
$Tools/Right/Delete.connect('pressed', self, '_on_delete_pressed')
for child in $Tools/Left/Title.get_children():
if child is VScrollBar:
child.rect_scale = Vector2.ZERO
func close():
hide()
preview.close()
@ -20,7 +24,7 @@ func close():
func open_node(graph_node):
current_graph_node = graph_node
var text_edit = graph_node.get_node('TextEdit')
var text_edit = graph_node.get_node('Wrapper/TextEdit')
text_edit.get_parent().remove_child(text_edit)
$Content.add_child(text_edit)
toggle_text_edit(text_edit)
@ -61,12 +65,12 @@ 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.node.title = $Tools/Left/Title.text
current_graph_node.compile()
func _on_visibility_changed():
if not visible:
var text_edit = $Content/TextEdit
$Content.remove_child(text_edit)
current_graph_node.add_child(text_edit)
current_graph_node.get_node('Wrapper').add_child(text_edit)
toggle_text_edit(text_edit)

View file

@ -1,48 +0,0 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/Wol/editor/WolGraphNode.gd" type="Script" id=1]
[sub_resource type="StyleBoxFlat" id=1]
content_margin_left = 4.0
content_margin_right = 4.0
content_margin_top = 26.0
content_margin_bottom = 4.0
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4
[node name="GraphNodeTemplate" type="GraphNode"]
margin_left = 500.0
margin_top = 1068.0
margin_right = 937.0
margin_bottom = 1459.0
mouse_filter = 1
custom_styles/frame = SubResource( 1 )
title = "Hello world"
offset = Vector2( 500, 500 )
resizable = true
slot/0/left_enabled = false
slot/0/left_type = 0
slot/0/left_color = Color( 1, 1, 1, 1 )
slot/0/right_enabled = false
slot/0/right_type = 0
slot/0/right_color = Color( 1, 1, 1, 1 )
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TextEdit" type="TextEdit" parent="."]
margin_left = 4.0
margin_top = 26.0
margin_right = 433.0
margin_bottom = 387.0
mouse_filter = 2
size_flags_horizontal = 3
size_flags_vertical = 3
syntax_highlighting = true
fold_gutter = true
context_menu_enabled = false
virtual_keyboard_enabled = false
wrap_enabled = true

View file

@ -0,0 +1,15 @@
extends LineEdit
export var disable_spaces = false
func _ready():
connect('text_changed', self, '_on_text_changed')
func _on_text_changed(_new_text):
if disable_spaces and ' ' in text:
var cursor_position = text.find(' ')
text = text.replace(' ', '')
caret_position = cursor_position
emit_signal('text_changed')

BIN
addons/Wol/editor/Panel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/Panel.png-a2fa39f4cf0ca5f7ab0404c39aed6351.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/Wol/editor/Panel.png"
dest_files=[ "res://.import/Panel.png-a2fa39f4cf0ca5f7ab0404c39aed6351.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View file

@ -19,6 +19,10 @@ func _ready():
$Tools/Left/Restart.connect('pressed', self, 'restart')
$Tools/Right/Close.connect('pressed', self, 'close')
for child in $Tools/Left/Protagonist.get_children():
if child is VScrollBar:
child.rect_scale = Vector2.ZERO
func open_node(graph_node):
current_graph_node = graph_node
@ -124,6 +128,8 @@ func _on_option_pressed(option):
$Options/List.remove_child(child)
child.queue_free()
grab_focus()
func _on_gui_input(event):
if visible:
if event is InputEventMouseButton and event.doubleclick:

View file

@ -0,0 +1,17 @@
extends ScrollContainer
func _ready():
connect('gui_input', self, '_on_gui_input')
func _on_gui_input(event):
if event is InputEventPanGesture:
scroll_vertical += event.delta.y * .1
# NOTE: Maybe smooth the scrolling?
if event is InputEventMouseButton:
var factor = event.factor if event.factor != 0 else 1.0
if event.button_index == BUTTON_WHEEL_UP:
scroll_vertical += 1 * factor
elif event.button_index == BUTTON_WHEEL_DOWN:
scroll_vertical -= 1 * factor

View file

@ -5,35 +5,62 @@ const Compiler = preload('res://addons/Wol/core/compiler/Compiler.gd')
onready var GraphNodeTemplate = $GraphNodeTemplate
var path
var refreshed = false
var selected_node
var saved_all_changes = false
onready var original_delete_node_dialog = $DeleteNodeDialog.dialog_text
onready var inside_godot_editor = not get_tree().current_scene and Engine.editor_hint
# TODO: Conditionally load in theme based on Editor or standalone
# TODO: Make deleting undo-able
# TODO: Implement alternative "single" line style of connecting
# Standalone
# TODO: Add right-click offset scrolling
# TODO: Add ESC as a way to go out of a "Preview" or "Editor"
# TODO: Add confirm window for creating new file if working on another
# TODO: Make arrow keys / WASD select next node
# TODO: Make ENTER key open a editor
# FIXME: Title debounce / space (\s) registering bug
# FIXME: Titles not working
# FIXME: Contextualize global _input events
# Godot Editor
# FIXME: Make all parts of the code "tool"s and safekeep its execution while in editor
# Web version
# 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
# Nice to have
# TODO: Make deleting undo-able
# TODO: Try to replicate positioning from existing Yarn Editor
# TODO: Implement settings
# TODO: Add more settings (like custom theme)
# TODO: Make shortcut for opening preview (CMD+P)
# TODO: More messages in preview for different things (command, start, stop, choices, log)
func _ready():
for menu_button in [$Menu/File]:
menu_button.get_popup().connect('index_pressed', self, '_on_menu_pressed', [menu_button.get_popup()])
$Menu/Settings.connect('pressed', self, 'show_settings')
$Menu/About.connect('pressed', self, 'show_about')
$GraphEdit.connect('gui_input', self, '_on_graph_edit_input')
$GraphEdit.connect('node_selected', self, '_on_node_selected', [true])
$GraphEdit.connect('node_unselected', self, '_on_node_selected', [false])
$GraphEdit.connect('_end_node_move', self, 'reconnect_nodes')
$DeleteNodeDialog.connect('confirmed', self, 'delete_node')
path = 'res://dialogue.wol'
build_nodes()
if inside_godot_editor:
theme = null
for child in $HBoxContainer.get_children():
child.size_flags_horizontal = SIZE_EXPAND_FILL
$HBoxContainer.set('custom_constants/seperation', 0)
func create_node(position = Vector2.ZERO):
var graph_node = GraphNodeTemplate.duplicate()
$GraphEdit.add_child(graph_node)
@ -106,7 +133,6 @@ func save_as(file_path = null):
file.open(file_path, File.WRITE)
file.store_string(serialize_to_file())
file.close()
print('saved file!')
func open():
$FileDialog.mode = $FileDialog.MODE_OPEN_FILE
@ -134,6 +160,12 @@ func new():
path = null
func show_settings():
$SettingsDialog.popup()
func show_about():
$AboutDialog.popup()
func _on_menu_pressed(index, node):
match(node.get_item_text(index)):
'New':
@ -145,10 +177,57 @@ func _on_menu_pressed(index, node):
'Open':
open()
# FIXME: Come up with better way of showing connections between nodes
func _on_graph_node_recompiled(_graph_node):
if refreshed: return
reconnect_nodes()
func reconnect_nodes():
$GraphEdit.clear_connections()
# TODO: Implement setting for determining style
if true:
connect_nodes_single_style()
else:
connect_nodes_godot_style()
func connect_nodes_single_style():
for graph_node in $GraphEdit.get_children():
if not graph_node is GraphNode:
continue
graph_node.set_slot_enabled_left(0, false)
graph_node.set_slot_enabled_right(0, false)
for graph_node in $GraphEdit.get_children():
if not graph_node is GraphNode:
continue
var connections = graph_node.get_connections()
for connection in connections:
if not $GraphEdit.has_node(connection):
continue
var other_graph_node = $GraphEdit.get_node(connection)
var destination_is_to_the_right = graph_node.offset.x <= other_graph_node.offset.x
if destination_is_to_the_right:
graph_node.set_slot_enabled_right(0, true)
graph_node.set_slot_type_right(0, 1)
other_graph_node.set_slot_enabled_left(0, true)
other_graph_node.set_slot_type_left(0, 1)
$GraphEdit.connect_node(graph_node.name, 0, other_graph_node.name, 0)
else:
graph_node.set_slot_enabled_left(0, true)
graph_node.set_slot_type_left(0, 1)
other_graph_node.set_slot_enabled_right(0, true)
other_graph_node.set_slot_type_right(0, 1)
$GraphEdit.connect_node(other_graph_node.name, 0, graph_node.name, 0)
func connect_nodes_godot_style():
for graph_node in $GraphEdit.get_children():
if not graph_node is GraphNode:
continue
@ -167,10 +246,6 @@ func _on_graph_node_recompiled(_graph_node):
$GraphEdit.connect_node(graph_node.name, 0, connection, 0)
refreshed = true
yield(get_tree().create_timer(.3), 'timeout')
refreshed = false
func _on_graph_node_input(event, graph_node):
if event is InputEventMouseButton \
and event.doubleclick and event.button_index == BUTTON_LEFT:
@ -190,8 +265,24 @@ func _on_graph_edit_input(event):
func _input(event):
if event is InputEventKey \
and not event.pressed and event.scancode == KEY_DELETE \
and not event.pressed and event.physical_scancode == KEY_DELETE \
and selected_node \
and not $HBoxContainer/Editor.visible:
confirm_delete_node()
if event is InputEventKey:
var combination = OS.get_scancode_string(event.get_physical_scancode_with_modifiers())
if OS.get_name() == 'OSX':
combination = combination.replace('Command', 'Control')
match combination:
'Control+N':
new()
'Control+S':
save_as(path)
'Shift+Control+S':
save_as()
'Control+O':
open()

BIN
addons/Wol/editor/WolEditor.tscn (Stored with Git LFS)

Binary file not shown.

View file

@ -12,7 +12,7 @@ var error_lines = []
var compiler
var program
onready var text_edit = $TextEdit
onready var text_edit = $Wrapper/TextEdit
# TODO: Add syntax highlighting
@ -38,14 +38,14 @@ func get_connections():
if instruction.operation == Constants.ByteCode.RunNode:
if instruction.operands.size() > 0 \
and instruction.operands.front().value != name:
connections.append(instruction.operands.front().value)
connections.append(instruction.operands.front().value.replace('.', '_'))
# NOTE: When next node is decided through options
if instruction.operation == Constants.ByteCode.AddOption:
if instruction.operands.size() == 2 \
and not label_check.search(instruction.operands[1].value) \
and instruction.operands[1].value != name:
connections.append(instruction.operands[1].value)
connections.append(instruction.operands[1].value.replace('.', '_'))
return connections
@ -74,7 +74,7 @@ func _on_error(message, line_number, _column):
func set_node(_node):
node = _node
title = node.title
name = node.title
name = node.title.replace('.', '_')
text_edit.text = node.body
text_edit.clear_undo_history()
offset = node.position

View file

@ -0,0 +1,8 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://addons/Wol/font/Aileron-Regular.otf" type="DynamicFontData" id=1]
[resource]
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,93 @@
Copyright (c) 2021, Rune Bjørnerås (https://github.com/rubjo)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more