Added an error indicator and error message box and refactored some code in the process - implements #21, prepares #16
This commit is contained in:
parent
ca40971e53
commit
8394ad9d3c
12 changed files with 345 additions and 31 deletions
80
assets/error.svg
Normal file
80
assets/error.svg
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="error.svg"
|
||||
inkscape:export-filename="error.svg"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="px"
|
||||
showgrid="true"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="12.28598"
|
||||
inkscape:cy="16.108776"
|
||||
inkscape:window-width="1854"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="66"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid9"
|
||||
originx="0"
|
||||
originy="0" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2">
|
||||
<rect
|
||||
x="-19.109422"
|
||||
y="15.119667"
|
||||
width="23.697131"
|
||||
height="28.949477"
|
||||
id="rect4519" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="display:none;opacity:0.75;fill:#ff3815;fill-opacity:1;stroke:#ff3815;stroke-width:6;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 4,25 H 26 L 15,6 Z"
|
||||
id="path11345"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<circle
|
||||
style="opacity:0.75;fill:#ff3815;fill-opacity:1;stroke:none;stroke-width:6;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
id="path15121"
|
||||
cx="15"
|
||||
cy="15"
|
||||
r="13" />
|
||||
<g
|
||||
aria-label="!"
|
||||
transform="matrix(0.80238423,0,0,0.80238423,20.811527,-5.9033718)"
|
||||
id="text4517"
|
||||
style="font-size:24px;white-space:pre;shape-inside:url(#rect4519);display:inline;fill:#ffffff;fill-opacity:1">
|
||||
<path
|
||||
d="m -5.6133052,29.164717 h -3.264 L -9.5630195,16.081288 h 4.6354286 z m -4.0045715,4.580571 q 0,-1.261715 0.6857143,-1.755429 0.6857143,-0.521142 1.6731429,-0.521142 0.96,0 1.6457143,0.521142 0.6857143,0.493714 0.6857143,1.755429 0,1.206857 -0.6857143,1.755429 -0.6857143,0.521142 -1.6457143,0.521142 -0.9874286,0 -1.6731429,-0.521142 -0.6857143,-0.548572 -0.6857143,-1.755429 z"
|
||||
style="font-weight:bold;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:1.14286"
|
||||
id="path4674" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
37
assets/error.svg.import
Normal file
37
assets/error.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://04iv1gogpuhu"
|
||||
path="res://.godot/imported/error.svg-75fe5f417585e01e99de8885f1f45c3b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/error.svg"
|
||||
dest_files=["res://.godot/imported/error.svg-75fe5f417585e01e99de8885f1f45c3b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=2.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://kqwc4avs2xdp"
|
||||
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
|
||||
path="res://.godot/imported/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
|
||||
source_file="res://assets/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.ctex"]
|
||||
|
||||
[params]
|
||||
|
81
assets/okay.svg
Normal file
81
assets/okay.svg
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="success.svg"
|
||||
inkscape:export-filename="error.svg"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="px"
|
||||
showgrid="true"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="3.314563"
|
||||
inkscape:cy="14.385204"
|
||||
inkscape:window-width="1854"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="66"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid9"
|
||||
originx="0"
|
||||
originy="0" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2">
|
||||
<rect
|
||||
x="0"
|
||||
y="0"
|
||||
width="30"
|
||||
height="30"
|
||||
id="rect15390" />
|
||||
<rect
|
||||
x="-19.109422"
|
||||
y="15.119667"
|
||||
width="23.697131"
|
||||
height="28.949477"
|
||||
id="rect4519" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="display:none;opacity:0.75;fill:#ff3815;fill-opacity:1;stroke:#ff3815;stroke-width:6;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 4,25 H 26 L 15,6 Z"
|
||||
id="path11345"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<circle
|
||||
style="opacity:0.75;fill:#15ff1e;fill-opacity:1;stroke:none;stroke-width:6;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
id="path15121"
|
||||
cx="15"
|
||||
cy="15"
|
||||
r="13" />
|
||||
<path
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 8.1284306,14.403599 5.2374004,4.840883 8.39167,-9.6564053"
|
||||
id="path20589"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
37
assets/okay.svg.import
Normal file
37
assets/okay.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://m1omb6g45vst"
|
||||
path="res://.godot/imported/okay.svg-7f6df15523471a86f27b6817e9528a4e.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/okay.svg"
|
||||
dest_files=["res://.godot/imported/okay.svg-7f6df15523471a86f27b6817e9528a4e.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=2.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
|
@ -15,7 +15,7 @@ config/version="v5.0"
|
|||
run/main_scene="res://scenes/main.tscn"
|
||||
config/features=PackedStringArray("4.3", "Mobile")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.png"
|
||||
config/icon="res://assets/icon.png"
|
||||
|
||||
[autoload]
|
||||
|
||||
|
|
|
@ -165,6 +165,29 @@ offset_bottom = 31.0
|
|||
grow_horizontal = 0
|
||||
text = "Apply (F5)"
|
||||
|
||||
[node name="StatusIndicator" type="TextureButton" parent="Editor"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -80.0
|
||||
offset_top = 56.0
|
||||
offset_right = -56.0
|
||||
offset_bottom = 80.0
|
||||
grow_horizontal = 0
|
||||
disabled = true
|
||||
ignore_texture_size = true
|
||||
stretch_mode = 0
|
||||
|
||||
[node name="ErrorMessageDialog" type="AcceptDialog" parent="Editor"]
|
||||
unique_name_in_owner = true
|
||||
title = "Status"
|
||||
initial_position = 2
|
||||
size = Vector2i(256, 128)
|
||||
popup_window = true
|
||||
ok_button_text = "Close"
|
||||
|
||||
[connection signal="file_selected" from="Editor/OpenShaderDialog" to="Editor" method="_on_open_shader_dialog_file_selected"]
|
||||
[connection signal="file_selected" from="Editor/SaveShaderDialog" to="Editor" method="_on_save_shader_dialog_file_selected"]
|
||||
[connection signal="file_selected" from="Editor/SaveImageDialog" to="Editor" method="_on_save_image_dialog_file_selected"]
|
||||
|
@ -176,3 +199,4 @@ text = "Apply (F5)"
|
|||
[connection signal="pressed" from="Editor/SaveImageButton" to="Editor" method="_on_save_image_button_pressed"]
|
||||
[connection signal="pressed" from="Editor/FitImageButton" to="Editor" method="_on_fit_image_button_pressed"]
|
||||
[connection signal="pressed" from="Editor/ApplyShaderButton" to="Editor" method="_on_apply_shader_button_pressed"]
|
||||
[connection signal="pressed" from="Editor/StatusIndicator" to="Editor" method="_on_status_indicator_pressed"]
|
||||
|
|
|
@ -6,9 +6,17 @@ extends Control
|
|||
@onready var save_shader_dialog = %SaveShaderDialog
|
||||
@onready var ui_control_filesave = %SaveImageDialog
|
||||
|
||||
@onready var status_indicator = %StatusIndicator
|
||||
@onready var error_msg_dialog = %ErrorMessageDialog
|
||||
|
||||
@onready var image_viewport = get_tree().root.get_node("Main/%ImageViewport")
|
||||
@onready var camera = get_tree().root.get_node("Main/%Camera")
|
||||
|
||||
#
|
||||
|
||||
var status_okay_texture: CompressedTexture2D = preload("uid://m1omb6g45vst")
|
||||
var status_error_texture: CompressedTexture2D = preload("uid://04iv1gogpuhu")
|
||||
|
||||
# # # # # # # # # # #
|
||||
# GDShader keywords #
|
||||
# https://github.com/godotengine/godot/blob/e96ad5af98547df71b50c4c4695ac348638113e0/servers/rendering/shader_language.cpp
|
||||
|
@ -173,7 +181,7 @@ func _on_code_edit_code_completion_requested():
|
|||
func _ready():
|
||||
code_editor.code_completion_enabled = true
|
||||
code_editor.syntax_highlighter = ShaderSyntaxHighlighter.new()
|
||||
self.update()
|
||||
self.update_code_edit()
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("apply_shader"):
|
||||
|
@ -182,15 +190,32 @@ func _input(event):
|
|||
accept_event() # Event is now handled.
|
||||
_on_save_shader_button_pressed()
|
||||
|
||||
func update():
|
||||
func update_code_edit():
|
||||
code_editor.text = Filesystem.shader.code
|
||||
|
||||
enum Status {OKAY, ERROR, UNKNOWN = -1}
|
||||
|
||||
func update_status(status: Status, msg: String = ""):
|
||||
error_msg_dialog.dialog_text = msg
|
||||
error_msg_dialog.reset_size()
|
||||
if status == Status.OKAY:
|
||||
status_indicator.texture_normal = status_okay_texture
|
||||
elif status == Status.ERROR:
|
||||
status_indicator.texture_normal = status_error_texture
|
||||
else:
|
||||
status_indicator.texture_normal = null
|
||||
if msg == "":
|
||||
status_indicator.disabled = true
|
||||
else:
|
||||
status_indicator.disabled = false
|
||||
|
||||
#
|
||||
|
||||
func _on_new_shader_button_pressed():
|
||||
Filesystem.reset()
|
||||
self.update()
|
||||
self.update_code_edit()
|
||||
image_viewport.update()
|
||||
update_status(Status.UNKNOWN)
|
||||
|
||||
func _on_open_shader_button_pressed():
|
||||
open_shader_dialog.show()
|
||||
|
@ -215,7 +240,11 @@ func _on_fit_image_button_pressed():
|
|||
|
||||
func _on_apply_shader_button_pressed():
|
||||
Filesystem.shader.code = code_editor.text
|
||||
image_viewport.update()
|
||||
var errors = await image_viewport.update()
|
||||
if len(errors) > 0:
|
||||
update_status(Status.ERROR, "\n".join(errors))
|
||||
else:
|
||||
update_status(Status.OKAY)
|
||||
|
||||
func _on_save_image_button_pressed():
|
||||
if Filesystem.result != null:
|
||||
|
@ -226,11 +255,16 @@ func _on_save_image_button_pressed():
|
|||
|
||||
func _on_open_shader_dialog_file_selected(path: String):
|
||||
Filesystem.load_shader(path)
|
||||
image_viewport.update()
|
||||
self.update()
|
||||
self.update_code_edit()
|
||||
self._on_apply_shader_button_pressed()
|
||||
|
||||
func _on_save_shader_dialog_file_selected(path):
|
||||
Filesystem.save_shader(path)
|
||||
|
||||
func _on_save_image_dialog_file_selected(path):
|
||||
Filesystem.save_result(path)
|
||||
|
||||
#
|
||||
|
||||
func _on_status_indicator_pressed() -> void:
|
||||
error_msg_dialog.show()
|
||||
|
|
|
@ -2,7 +2,9 @@ extends Node
|
|||
|
||||
@onready var template_shader: Shader = load("res://src/shader/template.gdshader")
|
||||
@onready var shader: Shader = template_shader.duplicate()
|
||||
|
||||
var original_image: ImageTexture
|
||||
var additional_images: Dictionary
|
||||
var result: Image
|
||||
|
||||
var cwd = "."
|
||||
|
@ -24,8 +26,7 @@ func get_absolute_path(p: String) -> String:
|
|||
return self.cwd + "/" + p.lstrip("./")
|
||||
return p
|
||||
|
||||
func load_original_image(path: String):
|
||||
print("Load ", path)
|
||||
func load_original_image(path: String) -> String: # returns an error message
|
||||
var img = Image.new()
|
||||
var err = img.load(path)
|
||||
if err == OK:
|
||||
|
@ -34,12 +35,20 @@ func load_original_image(path: String):
|
|||
self.last_original_image_path = path
|
||||
if self.last_image_savepath == "":
|
||||
self.last_image_savepath = path
|
||||
else:
|
||||
print("An error occured!")
|
||||
return ""
|
||||
return error_string(err) + " " + path
|
||||
|
||||
func load_image(path: String) -> ImageTexture:
|
||||
print("Load ", path)
|
||||
return ImageTexture.create_from_image(Image.load_from_file(path))
|
||||
func clear_additional_images():
|
||||
additional_images.clear()
|
||||
|
||||
func load_additional_image(key: String, path: String) -> String: # returns Error Message String
|
||||
var img = Image.new()
|
||||
var err = img.load(path)
|
||||
if err == OK:
|
||||
additional_images[key] = ImageTexture.create_from_image(img)
|
||||
return ""
|
||||
else:
|
||||
return error_string(err) + " " + path
|
||||
|
||||
func save_result(path: String):
|
||||
print("Export ", path)
|
||||
|
|
|
@ -4,31 +4,42 @@ extends SubViewport
|
|||
@onready var image_sprite = %ImageSprite
|
||||
@onready var image_viewport_display = %ImageViewportDisplay
|
||||
|
||||
func update():
|
||||
func update() -> Array: # returns error messages (strings)
|
||||
var errors = []
|
||||
var fit_image = false
|
||||
# load image from //!load directive -> TEXTURE
|
||||
# load texture(s)
|
||||
Filesystem.clear_additional_images()
|
||||
# ... from //!load directive -> TEXTURE
|
||||
var m = ShaderDirectiveParser.parse_load_directive(Filesystem.shader)
|
||||
if len(m) < 1:
|
||||
return # AAAAAAAa
|
||||
errors.append("Didn't find a load directive!")
|
||||
return errors
|
||||
var original_image_path = Filesystem.get_absolute_path(m[1])
|
||||
if original_image_path != Filesystem.last_original_image_path:
|
||||
fit_image = true
|
||||
Filesystem.load_original_image(original_image_path)
|
||||
if Filesystem.original_image == null:
|
||||
var err = Filesystem.load_original_image(original_image_path)
|
||||
if err != "":
|
||||
errors.append(err)
|
||||
image_viewport_display.hide()
|
||||
return
|
||||
return errors
|
||||
# ... from //!load+ directives
|
||||
for n in ShaderDirectiveParser.parse_load_additional_directive(Filesystem.shader):
|
||||
err = Filesystem.load_additional_image(n[1], Filesystem.get_absolute_path(n[2]))
|
||||
if err != "":
|
||||
errors.append(err)
|
||||
if len(errors) > 0:
|
||||
return errors
|
||||
# apply textures
|
||||
image_sprite.texture = Filesystem.original_image
|
||||
image_sprite.offset = Filesystem.original_image.get_size() / 2
|
||||
self.size = Filesystem.original_image.get_size()
|
||||
var mat = ShaderMaterial.new()
|
||||
mat.shader = Filesystem.shader
|
||||
# load images from //!load+ directives and apply them to
|
||||
# the material as shader parameters
|
||||
for n in ShaderDirectiveParser.parse_load_additional_directive(Filesystem.shader):
|
||||
# ... as shader parameters
|
||||
for key in Filesystem.additional_images:
|
||||
mat.set_shader_parameter(
|
||||
n[1], # uniform param name
|
||||
Filesystem.load_image(Filesystem.get_absolute_path(n[2]))
|
||||
)
|
||||
key, # uniform param name
|
||||
Filesystem.additional_images[key])
|
||||
# assign material
|
||||
image_sprite.material = mat
|
||||
# Get viewport texture
|
||||
|
@ -39,3 +50,5 @@ func update():
|
|||
if fit_image:
|
||||
camera.fit_image()
|
||||
image_viewport_display.show()
|
||||
# done
|
||||
return errors
|
||||
|
|
|
@ -11,8 +11,7 @@ func _ready():
|
|||
|
||||
func parse_load_directive(shader: Shader) -> PackedStringArray:
|
||||
var regex_match = self._load_regex.search(Filesystem.shader.code)
|
||||
if regex_match == null: # Error!
|
||||
printerr("Didn't find any load directives!")
|
||||
if regex_match == null:
|
||||
return []
|
||||
return regex_match.strings
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue