Add modified Fragmented project files
This commit is contained in:
parent
f99f1fbc9b
commit
77ce93fb15
57 changed files with 1696 additions and 0 deletions
50
src/Camera.gd
Normal file
50
src/Camera.gd
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
extends Camera2D
|
||||
|
||||
@onready var image_viewport_display = %ImageViewportDisplay
|
||||
|
||||
var drag = false
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("zoom_out"):
|
||||
zoom_out()
|
||||
elif event.is_action_pressed("zoom_in"):
|
||||
zoom_in()
|
||||
if event.is_action_pressed("drag"):
|
||||
self.drag = true
|
||||
elif event.is_action_released("drag"):
|
||||
self.drag = false
|
||||
if self.drag && event is InputEventMouseMotion:
|
||||
self.global_position -= event.relative / self.zoom
|
||||
|
||||
var old_zoom = self.zoom
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if self.zoom != old_zoom:
|
||||
image_viewport_display.update_zoom_texture_filter(self.zoom)
|
||||
image_viewport_display.material.set_shader_parameter("zoom_level", self.zoom)
|
||||
old_zoom = self.zoom
|
||||
|
||||
func fit_image():
|
||||
if Filesystem.original_image != null:
|
||||
var image_size = Filesystem.original_image.get_size()
|
||||
var viewport_size = get_viewport_rect().size
|
||||
var zoomf = 1.0
|
||||
if viewport_size.x / image_size.x * image_size.y > viewport_size.y:
|
||||
zoomf = viewport_size.y / image_size.y / 1.25
|
||||
else:
|
||||
zoomf = viewport_size.x / image_size.x / 1.2
|
||||
self.zoom = Vector2(zoomf, zoomf)
|
||||
self.global_position = Vector2(0, 0)
|
||||
|
||||
func zoom_in():
|
||||
var old_mouse_pos = get_global_mouse_position()
|
||||
self.zoom *= 1.2
|
||||
self.global_position += old_mouse_pos - get_global_mouse_position()
|
||||
|
||||
func zoom_out():
|
||||
var old_mouse_pos = get_global_mouse_position()
|
||||
self.zoom *= 1/1.2
|
||||
self.global_position += old_mouse_pos - get_global_mouse_position()
|
||||
|
||||
func _on_fit_image_button_pressed():
|
||||
fit_image()
|
||||
1
src/Camera.gd.uid
Normal file
1
src/Camera.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b6r8rigubdctk
|
||||
52
src/Filesystem.gd
Normal file
52
src/Filesystem.gd
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
extends Node
|
||||
|
||||
var cwd = "."
|
||||
|
||||
var shader_path = "":
|
||||
get():
|
||||
return shader_path
|
||||
set(v):
|
||||
shader_path = v
|
||||
if "/" in v: # update current working directory
|
||||
cwd = v.substr(0, v.rfind("/"))
|
||||
|
||||
var shader: Shader:
|
||||
get():
|
||||
if shader_path == "":
|
||||
return null
|
||||
print("Load ", shader_path)
|
||||
return load(shader_path)
|
||||
|
||||
var image_path = ""
|
||||
|
||||
var original_image: ImageTexture
|
||||
var result: Image
|
||||
|
||||
var last_image_savepath = ""
|
||||
var last_original_image_path = ""
|
||||
|
||||
func get_absolute_path(p: String) -> String:
|
||||
# this only works on Linux!
|
||||
if !p.begins_with("/"):
|
||||
return self.cwd + "/" + p.lstrip("./")
|
||||
return p
|
||||
|
||||
func load_image() -> String: # returns an error message
|
||||
print("Load ", image_path)
|
||||
var img = Image.new()
|
||||
var err = img.load(image_path)
|
||||
if err == OK:
|
||||
original_image = ImageTexture.create_from_image(img)
|
||||
if self.last_image_savepath == "" or image_path != self.last_original_image_path:
|
||||
self.last_image_savepath = image_path
|
||||
self.last_original_image_path = image_path
|
||||
return ""
|
||||
return error_string(err) + " " + image_path
|
||||
|
||||
func save_result(path: String):
|
||||
print("Export ", path)
|
||||
var err = self.result.save_png(path)
|
||||
if err != OK:
|
||||
print("An error occured!")
|
||||
else:
|
||||
self.last_image_savepath = path
|
||||
1
src/Filesystem.gd.uid
Normal file
1
src/Filesystem.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://rlb041ygdwol
|
||||
90
src/ImageCompositor.gd
Normal file
90
src/ImageCompositor.gd
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
class_name ImageCompositor extends SubViewport
|
||||
|
||||
var image_sprite: Sprite2D
|
||||
|
||||
func _init() -> void:
|
||||
# Overwrite some variables
|
||||
self.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
||||
self.disable_3d = true
|
||||
self.transparent_bg = true
|
||||
self.canvas_item_default_texture_filter = Viewport.DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST
|
||||
self.image_sprite = Sprite2D.new()
|
||||
|
||||
@onready var camera = %Camera
|
||||
@onready var image_viewport_display = %ImageViewportDisplay
|
||||
|
||||
func _ready() -> void:
|
||||
# Add image sprite as child to be rendered
|
||||
self.add_child(image_sprite)
|
||||
|
||||
var _fragment_function_regex: RegEx = RegEx.create_from_string(r'\s*void\s+fragment\s*\(\s*\)\s*{\s*')
|
||||
|
||||
func validate_shader_compilation(shader: Shader) -> bool:
|
||||
# Inject code to validate shader compilation
|
||||
var shader_code = shader.code;
|
||||
# -> get position of fragment shader
|
||||
var fragment_function_match = _fragment_function_regex.search(shader.code)
|
||||
if fragment_function_match == null:
|
||||
return false
|
||||
# -> inject uniform
|
||||
var uniform_name = "shader_compilation_validate_" + str(randi_range(999999999, 100000000))
|
||||
var uniform_code_line = "\nuniform bool " + uniform_name + ";\n"
|
||||
shader_code = shader_code.insert(fragment_function_match.get_start(), uniform_code_line)
|
||||
# -> inject variable access to prevent that the uniform gets optimized away
|
||||
shader_code = shader_code.insert(fragment_function_match.get_end() + len(uniform_code_line), "\n" + uniform_name + ";\n")
|
||||
# apply shader code
|
||||
shader.code = shader_code
|
||||
# test if uniform list is empty -> if it is empty, the shader compilation failed
|
||||
return len(shader.get_shader_uniform_list()) > 0
|
||||
|
||||
func shader_has_uniform(shader: Shader, var_name: String, type: int) -> bool:
|
||||
for u in shader.get_shader_uniform_list():
|
||||
if u["name"] == var_name && u["type"] == type:
|
||||
return true
|
||||
return false
|
||||
|
||||
func set_vsync(enabled: bool):
|
||||
if enabled:
|
||||
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED)
|
||||
else:
|
||||
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
|
||||
|
||||
func update() -> Array: # returns error messages (strings)
|
||||
if Filesystem.image_path == "":
|
||||
return ["No image loaded!"]
|
||||
var shader = Filesystem.shader # read from disk
|
||||
if shader == null:
|
||||
return ["No shader opened!"]
|
||||
# validate shader
|
||||
if not validate_shader_compilation(shader):
|
||||
return ["Shader compilation failed!"]
|
||||
var errors = []
|
||||
# load texture
|
||||
var fit_image = Filesystem.image_path != Filesystem.last_original_image_path
|
||||
var err = Filesystem.load_image()
|
||||
if err != "":
|
||||
errors.append(err)
|
||||
image_viewport_display.hide()
|
||||
return errors
|
||||
# apply texture
|
||||
image_sprite.texture = Filesystem.original_image
|
||||
image_sprite.offset = Filesystem.original_image.get_size() / 2
|
||||
self.size = Filesystem.original_image.get_size()
|
||||
# show the image viewport & fit the image
|
||||
if fit_image: camera.fit_image()
|
||||
image_viewport_display.show()
|
||||
# create shader material
|
||||
var mat = ShaderMaterial.new()
|
||||
mat.shader = shader
|
||||
# assign material
|
||||
image_sprite.material = mat
|
||||
# iterate n times
|
||||
set_vsync(false) # speed up processing
|
||||
# Get viewport texture
|
||||
await RenderingServer.frame_post_draw # wait for next frame to get drawn
|
||||
Filesystem.result = get_texture().get_image()
|
||||
image_sprite.texture = ImageTexture.create_from_image(Filesystem.result)
|
||||
set_vsync(true) # reenable vsync
|
||||
image_sprite.material = null
|
||||
# done
|
||||
return errors
|
||||
1
src/ImageCompositor.gd.uid
Normal file
1
src/ImageCompositor.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://d106170kuigl3
|
||||
10
src/ImageViewportDisplay.gd
Normal file
10
src/ImageViewportDisplay.gd
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
extends Sprite2D
|
||||
|
||||
func _ready() -> void:
|
||||
hide()
|
||||
|
||||
func update_zoom_texture_filter(zoom: Vector2):
|
||||
if zoom.x >= 1.5:
|
||||
texture_filter = TEXTURE_FILTER_NEAREST_WITH_MIPMAPS
|
||||
else:
|
||||
texture_filter = TEXTURE_FILTER_LINEAR
|
||||
1
src/ImageViewportDisplay.gd.uid
Normal file
1
src/ImageViewportDisplay.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://ctc4lhbdsoq7u
|
||||
121
src/Main.gd
Normal file
121
src/Main.gd
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
extends Node
|
||||
|
||||
const BATCH_MODE_SUPPORTED_EXTS = [
|
||||
".bmp", ".dds", ".exr", ".hdr", ".jpeg", ".jpg", ".ktx", ".png", ".svg", ".webp"
|
||||
]
|
||||
|
||||
@onready var app_name = ProjectSettings.get_setting("application/config/name")
|
||||
|
||||
func show_help():
|
||||
print(
|
||||
"Usage:\n\n",
|
||||
"./Pigment <command> <args...>\n\n",
|
||||
"Commands:\n\n",
|
||||
" help\n\n",
|
||||
" | Shows this help text.\n\n",
|
||||
" apply --shader PATH [--load-image PATH]\n\n",
|
||||
" | Applies a shader file.\n\n",
|
||||
" --shader PATH The path to the shader\n",
|
||||
" --input PATH The path to the image.\n",
|
||||
" Passing a folder activates batch mode.\n",
|
||||
" --output PATH Where to write the resulting image to.\n",
|
||||
" In batch mode, this must be a folder.\n")
|
||||
|
||||
func parse_custom_cmdline(args: PackedStringArray):
|
||||
var kwargs: Dictionary = {"--shader": null, "--output": null, "--input": null}
|
||||
var args_len = args.size()
|
||||
var i = 0
|
||||
while i < args_len:
|
||||
var a = args[i]
|
||||
if a in kwargs && args_len > i+1:
|
||||
i += 1
|
||||
kwargs[a] = args[i]
|
||||
i += 1
|
||||
return kwargs
|
||||
|
||||
func cli_handle_errors(errors: Array) -> int:
|
||||
# returns number of errors
|
||||
var n_errors = errors.size()
|
||||
if n_errors > 0:
|
||||
print("One or more errors occurred.")
|
||||
for e in errors:
|
||||
printerr(e)
|
||||
return n_errors
|
||||
|
||||
func cli(args: PackedStringArray):
|
||||
print(
|
||||
"~ Pigment CLI ~\n",
|
||||
"-=============-\n")
|
||||
if "help" in args:
|
||||
show_help()
|
||||
get_tree().quit(1)
|
||||
return
|
||||
var kwargs: Dictionary = parse_custom_cmdline(args)
|
||||
if kwargs["--shader"] == null or kwargs["--output"] == null:
|
||||
show_help()
|
||||
get_tree().quit(1)
|
||||
return
|
||||
var batch_mode = false
|
||||
var load_image_dir: DirAccess
|
||||
if kwargs["--input"] != null:
|
||||
load_image_dir = DirAccess.open(kwargs["--input"])
|
||||
if load_image_dir != null:
|
||||
# batch mode
|
||||
if DirAccess.open(kwargs["--output"]) == null:
|
||||
printerr("If --input is a directory, --output has to be one too.\n")
|
||||
show_help()
|
||||
get_tree().quit(1)
|
||||
return
|
||||
else:
|
||||
batch_mode = true
|
||||
#
|
||||
Filesystem.shader_path = kwargs["--shader"]
|
||||
#
|
||||
if batch_mode:
|
||||
var in_dir_path = load_image_dir.get_current_dir()
|
||||
var out_dir_path: String = kwargs["--output"].rstrip("/")
|
||||
for f in load_image_dir.get_files():
|
||||
var supported = false
|
||||
for e in BATCH_MODE_SUPPORTED_EXTS:
|
||||
if f.ends_with(e):
|
||||
supported = true
|
||||
break
|
||||
if supported:
|
||||
f = in_dir_path + "/" + f
|
||||
print(f)
|
||||
var errors = await $Compositor.update(f)
|
||||
if cli_handle_errors(errors) == 0:
|
||||
var filename = out_dir_path + "/" + f.substr(f.rfind("/"), -1)
|
||||
Filesystem.save_result(filename)
|
||||
else:
|
||||
get_tree().quit(1)
|
||||
return
|
||||
get_tree().quit(0)
|
||||
else:
|
||||
var errors = []
|
||||
if kwargs["--input"] == null:
|
||||
errors = await $Compositor.update()
|
||||
else:
|
||||
errors = await $Compositor.update(kwargs["--input"])
|
||||
if cli_handle_errors(errors) == 0:
|
||||
Filesystem.save_result(kwargs["--output"])
|
||||
get_tree().quit(0)
|
||||
else:
|
||||
get_tree().quit(1)
|
||||
|
||||
func prepare_gui():
|
||||
update_title()
|
||||
|
||||
func _ready():
|
||||
var args = OS.get_cmdline_args()
|
||||
if len(args) > 0 and args[0] in ["apply", "help"]:
|
||||
# use the commandline interface
|
||||
cli(args)
|
||||
else:
|
||||
prepare_gui()
|
||||
|
||||
func update_title(current_file: String = ""):
|
||||
if current_file == "":
|
||||
get_window().title = app_name + " - Viewer"
|
||||
else:
|
||||
get_window().title = current_file + " - " + app_name + " - Viewer"
|
||||
1
src/Main.gd.uid
Normal file
1
src/Main.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://5sbslwysin5a
|
||||
120
src/MainUI.gd
Normal file
120
src/MainUI.gd
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
extends Control
|
||||
|
||||
@onready var open_shader_dialog = %OpenShaderDialog
|
||||
@onready var open_image_dialog = %OpenImageDialog
|
||||
@onready var save_image_dialog = %SaveImageDialog
|
||||
|
||||
@onready var open_shader_button = %OpenShaderButton
|
||||
@onready var open_image_button = %OpenImageButton
|
||||
@onready var save_image_button = %SaveImageButton
|
||||
@onready var fit_image_button = %FitImageButton
|
||||
@onready var apply_shader_button = %ApplyShaderButton
|
||||
|
||||
@onready var status_indicator = %StatusIndicator
|
||||
@onready var error_msg_dialog = %ErrorMessageDialog
|
||||
|
||||
@onready var main = get_tree().root.get_node("Main")
|
||||
@onready var compositor = %Compositor
|
||||
@onready var camera = %Camera
|
||||
|
||||
var status_okay_texture: CompressedTexture2D = preload("uid://m1omb6g45vst")
|
||||
var status_error_texture: CompressedTexture2D = preload("uid://04iv1gogpuhu")
|
||||
|
||||
enum Status {OKAY, ERROR, UNKNOWN = -1}
|
||||
|
||||
#
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("apply_shader"):
|
||||
_on_apply_shader_button_pressed()
|
||||
elif event.is_action_pressed("save_shader"):
|
||||
accept_event() # Event is now handled.
|
||||
|
||||
#
|
||||
|
||||
func set_buttons_disabled(disabled: bool):
|
||||
for b in [open_shader_button, open_image_button, save_image_button, fit_image_button, apply_shader_button, status_indicator]:
|
||||
b.disabled = disabled
|
||||
|
||||
#
|
||||
|
||||
func _on_open_shader_button_pressed():
|
||||
set_buttons_disabled(true)
|
||||
open_shader_dialog.show()
|
||||
|
||||
func _on_open_image_button_pressed():
|
||||
set_buttons_disabled(true)
|
||||
open_image_dialog.show()
|
||||
|
||||
func _on_fit_image_button_pressed():
|
||||
camera.fit_image()
|
||||
|
||||
func _on_apply_shader_button_pressed():
|
||||
set_buttons_disabled(true)
|
||||
var errors = await compositor.update()
|
||||
set_buttons_disabled(false)
|
||||
if len(errors) > 0:
|
||||
update_status(Status.ERROR, "\n".join(errors))
|
||||
else:
|
||||
update_status(Status.OKAY)
|
||||
status_indicator.disabled = true
|
||||
|
||||
func _on_save_image_button_pressed():
|
||||
if Filesystem.result != null:
|
||||
set_buttons_disabled(true)
|
||||
save_image_dialog.current_path = Filesystem.last_image_savepath
|
||||
save_image_dialog.show()
|
||||
|
||||
#
|
||||
|
||||
func _on_open_shader_dialog_file_selected(path: String):
|
||||
Filesystem.shader_path = path
|
||||
main.update_title(path.split("/")[-1])
|
||||
self._on_apply_shader_button_pressed()
|
||||
|
||||
func _on_open_shader_dialog_canceled() -> void:
|
||||
set_buttons_disabled(false)
|
||||
|
||||
func _on_open_shader_dialog_confirmed() -> void:
|
||||
set_buttons_disabled(false)
|
||||
|
||||
|
||||
func _on_open_image_dialog_file_selected(path: String) -> void:
|
||||
Filesystem.image_path = path
|
||||
self._on_apply_shader_button_pressed()
|
||||
|
||||
func _on_open_image_dialog_canceled() -> void:
|
||||
set_buttons_disabled(false)
|
||||
|
||||
func _on_open_image_dialog_confirmed() -> void:
|
||||
set_buttons_disabled(false)
|
||||
|
||||
|
||||
func _on_save_image_dialog_file_selected(path):
|
||||
Filesystem.save_result(path)
|
||||
set_buttons_disabled(false)
|
||||
|
||||
func _on_save_image_dialog_canceled() -> void:
|
||||
set_buttons_disabled(false)
|
||||
|
||||
func _on_save_image_dialog_confirmed() -> void:
|
||||
set_buttons_disabled(false)
|
||||
|
||||
#
|
||||
|
||||
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_status_indicator_pressed() -> void:
|
||||
error_msg_dialog.show()
|
||||
1
src/MainUI.gd.uid
Normal file
1
src/MainUI.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bxgmf2ny7yuc8
|
||||
8
src/VersionLabel.gd
Normal file
8
src/VersionLabel.gd
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
extends Label
|
||||
|
||||
func _ready():
|
||||
text = ProjectSettings.get_setting("application/config/name") \
|
||||
+ " " \
|
||||
+ ProjectSettings.get_setting("application/config/version") \
|
||||
+ " | Godot " \
|
||||
+ Engine.get_version_info()["string"]
|
||||
1
src/VersionLabel.gd.uid
Normal file
1
src/VersionLabel.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bh0gpu3i2p47f
|
||||
BIN
src/assets/bg.png
Normal file
BIN
src/assets/bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 532 B |
40
src/assets/bg.png.import
Normal file
40
src/assets/bg.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d2nwchyd6huob"
|
||||
path="res://.godot/imported/bg.png-7c8713dd1fab321784216191fa747e53.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/assets/bg.png"
|
||||
dest_files=["res://.godot/imported/bg.png-7c8713dd1fab321784216191fa747e53.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
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/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
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
|
||||
80
src/assets/error.svg
Normal file
80
src/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 |
43
src/assets/error.svg.import
Normal file
43
src/assets/error.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://04iv1gogpuhu"
|
||||
path="res://.godot/imported/error.svg-28fb29635cf59d39cabf7052619f602f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/assets/error.svg"
|
||||
dest_files=["res://.godot/imported/error.svg-28fb29635cf59d39cabf7052619f602f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
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/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
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
|
||||
BIN
src/assets/icon.png
Normal file
BIN
src/assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3 KiB |
40
src/assets/icon.png.import
Normal file
40
src/assets/icon.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://kqwc4avs2xdp"
|
||||
path="res://.godot/imported/icon.png-d8298ab6eda392a806be6bb7eec65b9c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/assets/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-d8298ab6eda392a806be6bb7eec65b9c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
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/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
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
|
||||
81
src/assets/okay.svg
Normal file
81
src/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 |
43
src/assets/okay.svg.import
Normal file
43
src/assets/okay.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://m1omb6g45vst"
|
||||
path="res://.godot/imported/okay.svg-de66a022ef37753b085371b7c60aefd1.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/assets/okay.svg"
|
||||
dest_files=["res://.godot/imported/okay.svg-de66a022ef37753b085371b7c60aefd1.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
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/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
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
|
||||
219
src/scenes/main.tscn
Normal file
219
src/scenes/main.tscn
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
[gd_scene load_steps=13 format=3 uid="uid://bjah7k4bxo044"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://5sbslwysin5a" path="res://src/Main.gd" id="1_64y3g"]
|
||||
[ext_resource type="Script" uid="uid://d106170kuigl3" path="res://src/ImageCompositor.gd" id="2_4ykh7"]
|
||||
[ext_resource type="Shader" uid="uid://ctk7jomfyx0fh" path="res://src/shader/ivd_outline.gdshader" id="3_0fllm"]
|
||||
[ext_resource type="Script" uid="uid://ctc4lhbdsoq7u" path="res://src/ImageViewportDisplay.gd" id="4_pbpx2"]
|
||||
[ext_resource type="Script" uid="uid://b6r8rigubdctk" path="res://src/Camera.gd" id="5_hkdq6"]
|
||||
[ext_resource type="Texture2D" uid="uid://d2nwchyd6huob" path="res://src/assets/bg.png" id="6_kokaf"]
|
||||
[ext_resource type="Theme" uid="uid://cwqlns34rj3vx" path="res://src/theme.tres" id="6_rjp5f"]
|
||||
[ext_resource type="Script" uid="uid://bxgmf2ny7yuc8" path="res://src/MainUI.gd" id="7_5puhk"]
|
||||
[ext_resource type="Script" uid="uid://bh0gpu3i2p47f" path="res://src/VersionLabel.gd" id="8_kod8x"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_y2ea0"]
|
||||
shader = ExtResource("3_0fllm")
|
||||
shader_parameter/zoom_level = Vector2(1, 1)
|
||||
|
||||
[sub_resource type="ViewportTexture" id="ViewportTexture_lct1c"]
|
||||
viewport_path = NodePath("Compositor")
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_6o860"]
|
||||
font_size = 12
|
||||
shadow_color = Color(0, 0, 0, 1)
|
||||
|
||||
[node name="Main" type="Node2D"]
|
||||
script = ExtResource("1_64y3g")
|
||||
|
||||
[node name="Compositor" type="SubViewport" parent="."]
|
||||
unique_name_in_owner = true
|
||||
script = ExtResource("2_4ykh7")
|
||||
|
||||
[node name="ImageViewportDisplay" type="Sprite2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
material = SubResource("ShaderMaterial_y2ea0")
|
||||
texture = SubResource("ViewportTexture_lct1c")
|
||||
script = ExtResource("4_pbpx2")
|
||||
|
||||
[node name="Camera" type="Camera2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
offset = Vector2(0, -64)
|
||||
script = ExtResource("5_hkdq6")
|
||||
|
||||
[node name="CanvasLayerBg" type="CanvasLayer" parent="."]
|
||||
layer = -1
|
||||
|
||||
[node name="Control" type="Control" parent="CanvasLayerBg"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="CanvasLayerBg/Control"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = ExtResource("6_kokaf")
|
||||
stretch_mode = 1
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="MainUI" type="Control" parent="CanvasLayer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
pivot_offset = Vector2(320, 320)
|
||||
theme = ExtResource("6_rjp5f")
|
||||
script = ExtResource("7_5puhk")
|
||||
|
||||
[node name="OpenShaderDialog" type="FileDialog" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
auto_translate_mode = 1
|
||||
title = "Load Shader"
|
||||
size = Vector2i(521, 175)
|
||||
ok_button_text = "Open"
|
||||
mode_overrides_title = false
|
||||
file_mode = 0
|
||||
access = 2
|
||||
filters = PackedStringArray("*.gdshader")
|
||||
use_native_dialog = true
|
||||
|
||||
[node name="OpenImageDialog" type="FileDialog" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
auto_translate_mode = 1
|
||||
title = "Load Image"
|
||||
size = Vector2i(521, 175)
|
||||
ok_button_text = "Open"
|
||||
mode_overrides_title = false
|
||||
file_mode = 0
|
||||
access = 2
|
||||
filters = PackedStringArray("*.png", "*.jpg", "*.jpeg")
|
||||
use_native_dialog = true
|
||||
|
||||
[node name="SaveImageDialog" type="FileDialog" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
auto_translate_mode = 1
|
||||
title = "Export Image"
|
||||
size = Vector2i(661, 175)
|
||||
mode_overrides_title = false
|
||||
access = 2
|
||||
filters = PackedStringArray("*.png")
|
||||
use_native_dialog = true
|
||||
|
||||
[node name="ErrorMessageDialog" type="AcceptDialog" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
auto_translate_mode = 1
|
||||
title = "Status"
|
||||
initial_position = 2
|
||||
size = Vector2i(256, 128)
|
||||
popup_window = true
|
||||
ok_button_text = "Close"
|
||||
|
||||
[node name="OpenShaderButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
offset_left = 16.0
|
||||
offset_top = 16.0
|
||||
offset_right = 128.0
|
||||
offset_bottom = 48.0
|
||||
text = "Open Shader"
|
||||
|
||||
[node name="OpenImageButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
offset_left = 16.0
|
||||
offset_top = 56.0
|
||||
offset_right = 128.0
|
||||
offset_bottom = 88.0
|
||||
text = "Open Image"
|
||||
|
||||
[node name="SaveImageButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
offset_left = 144.0
|
||||
offset_top = 16.0
|
||||
offset_right = 216.0
|
||||
offset_bottom = 48.0
|
||||
disabled = true
|
||||
text = "Export"
|
||||
|
||||
[node name="FitImageButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -176.0
|
||||
offset_top = 16.0
|
||||
offset_right = -128.0
|
||||
offset_bottom = 48.0
|
||||
grow_horizontal = 0
|
||||
text = "Fit"
|
||||
|
||||
[node name="ApplyShaderButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -112.0
|
||||
offset_top = 16.0
|
||||
offset_right = -16.0
|
||||
offset_bottom = 48.0
|
||||
grow_horizontal = 0
|
||||
text = "Apply (F5)"
|
||||
|
||||
[node name="StatusIndicator" type="TextureButton" parent="CanvasLayer/MainUI"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -220.0
|
||||
offset_top = 21.0
|
||||
offset_right = -196.0
|
||||
offset_bottom = 45.0
|
||||
grow_horizontal = 0
|
||||
disabled = true
|
||||
ignore_texture_size = true
|
||||
stretch_mode = 0
|
||||
|
||||
[node name="VersionLabel" type="Label" parent="CanvasLayer/MainUI"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 12
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 16.0
|
||||
offset_top = -24.0
|
||||
offset_right = -16.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
label_settings = SubResource("LabelSettings_6o860")
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
script = ExtResource("8_kod8x")
|
||||
|
||||
[connection signal="canceled" from="CanvasLayer/MainUI/OpenShaderDialog" to="CanvasLayer/MainUI" method="_on_open_shader_dialog_canceled"]
|
||||
[connection signal="confirmed" from="CanvasLayer/MainUI/OpenShaderDialog" to="CanvasLayer/MainUI" method="_on_open_shader_dialog_confirmed"]
|
||||
[connection signal="file_selected" from="CanvasLayer/MainUI/OpenShaderDialog" to="CanvasLayer/MainUI" method="_on_open_shader_dialog_file_selected"]
|
||||
[connection signal="canceled" from="CanvasLayer/MainUI/OpenImageDialog" to="CanvasLayer/MainUI" method="_on_open_image_dialog_canceled"]
|
||||
[connection signal="confirmed" from="CanvasLayer/MainUI/OpenImageDialog" to="CanvasLayer/MainUI" method="_on_open_image_dialog_confirmed"]
|
||||
[connection signal="file_selected" from="CanvasLayer/MainUI/OpenImageDialog" to="CanvasLayer/MainUI" method="_on_open_image_dialog_file_selected"]
|
||||
[connection signal="canceled" from="CanvasLayer/MainUI/SaveImageDialog" to="CanvasLayer/MainUI" method="_on_save_image_dialog_canceled"]
|
||||
[connection signal="confirmed" from="CanvasLayer/MainUI/SaveImageDialog" to="CanvasLayer/MainUI" method="_on_save_image_dialog_confirmed"]
|
||||
[connection signal="file_selected" from="CanvasLayer/MainUI/SaveImageDialog" to="CanvasLayer/MainUI" method="_on_save_image_dialog_file_selected"]
|
||||
[connection signal="pressed" from="CanvasLayer/MainUI/OpenShaderButton" to="CanvasLayer/MainUI" method="_on_open_shader_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/MainUI/OpenImageButton" to="CanvasLayer/MainUI" method="_on_open_image_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/MainUI/SaveImageButton" to="CanvasLayer/MainUI" method="_on_save_image_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/MainUI/FitImageButton" to="CanvasLayer/MainUI" method="_on_fit_image_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/MainUI/ApplyShaderButton" to="CanvasLayer/MainUI" method="_on_apply_shader_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/MainUI/StatusIndicator" to="CanvasLayer/MainUI" method="_on_status_indicator_pressed"]
|
||||
16
src/shader/ivd_outline.gdshader
Normal file
16
src/shader/ivd_outline.gdshader
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
shader_type canvas_item;
|
||||
|
||||
uniform vec2 zoom_level = vec2(1.0);
|
||||
const float thickness = 3.0;
|
||||
|
||||
void fragment() {
|
||||
vec2 t = thickness * TEXTURE_PIXEL_SIZE / zoom_level;
|
||||
if (
|
||||
UV.x < t.x ||
|
||||
UV.y < t.y ||
|
||||
UV.x > 1.0-t.x ||
|
||||
UV.y > 1.0-t.y
|
||||
) {
|
||||
COLOR = mix(COLOR, vec4(0.5), 0.5);
|
||||
}
|
||||
}
|
||||
1
src/shader/ivd_outline.gdshader.uid
Normal file
1
src/shader/ivd_outline.gdshader.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://ctk7jomfyx0fh
|
||||
57
src/theme.tres
Normal file
57
src/theme.tres
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
[gd_resource type="Theme" load_steps=4 format=3 uid="uid://cwqlns34rj3vx"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bm5o2"]
|
||||
content_margin_left = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color(0.1, 0.1, 0.1, 0.3)
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
border_color = Color(1, 1, 1, 0.27451)
|
||||
corner_radius_top_left = 3
|
||||
corner_radius_top_right = 3
|
||||
corner_radius_bottom_right = 3
|
||||
corner_radius_bottom_left = 3
|
||||
corner_detail = 5
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l0k8a"]
|
||||
content_margin_left = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color(0.225, 0.225, 0.225, 0.6)
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
border_color = Color(1, 1, 1, 0.784314)
|
||||
corner_radius_top_left = 3
|
||||
corner_radius_top_right = 3
|
||||
corner_radius_bottom_right = 3
|
||||
corner_radius_bottom_left = 3
|
||||
corner_detail = 5
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1dkyv"]
|
||||
content_margin_left = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color(0.1, 0.1, 0.1, 0.6)
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
border_color = Color(1, 1, 1, 0.509804)
|
||||
corner_radius_top_left = 3
|
||||
corner_radius_top_right = 3
|
||||
corner_radius_bottom_right = 3
|
||||
corner_radius_bottom_left = 3
|
||||
corner_detail = 5
|
||||
|
||||
[resource]
|
||||
Button/styles/disabled = SubResource("StyleBoxFlat_bm5o2")
|
||||
Button/styles/hover = SubResource("StyleBoxFlat_l0k8a")
|
||||
Button/styles/normal = SubResource("StyleBoxFlat_1dkyv")
|
||||
Loading…
Add table
Add a link
Reference in a new issue