mirror of
https://codeberg.org/StreamGraph/StreamGraph.git
synced 2024-11-13 19:49:55 +01:00
add toast notifications (#148)
closes #138 Reviewed-on: https://codeberg.org/StreamGraph/StreamGraph/pulls/148 Co-authored-by: Lera Elvoé <yagich@poto.cafe> Co-committed-by: Lera Elvoé <yagich@poto.cafe>
This commit is contained in:
parent
f24906715d
commit
a80af97377
15 changed files with 301 additions and 42 deletions
|
@ -367,37 +367,37 @@ func copy_nodes(nodes_to_copy: Array[String]) -> Dictionary:
|
||||||
for node_id: String in nodes_to_copy:
|
for node_id: String in nodes_to_copy:
|
||||||
d.nodes[node_id] = get_node(node_id).to_dict()
|
d.nodes[node_id] = get_node(node_id).to_dict()
|
||||||
|
|
||||||
for node: String in d.nodes:
|
#for node: String in d.nodes:
|
||||||
var outgoing_connections: Dictionary = d.nodes[node].outgoing_connections.duplicate(true)
|
#var outgoing_connections: Dictionary = d.nodes[node].outgoing_connections.duplicate(true)
|
||||||
|
#
|
||||||
for from_port: int in outgoing_connections:
|
#for from_port: int in outgoing_connections:
|
||||||
for to_node: String in outgoing_connections[from_port]:
|
#for to_node: String in outgoing_connections[from_port]:
|
||||||
if to_node not in nodes_to_copy:
|
#if to_node not in nodes_to_copy:
|
||||||
(d.nodes[node].outgoing_connections[from_port] as Dictionary).erase(to_node)
|
#(d.nodes[node].outgoing_connections[from_port] as Dictionary).erase(to_node)
|
||||||
|
#
|
||||||
var keys_to_erase := []
|
#var keys_to_erase := []
|
||||||
for from_port: int in d.nodes[node].outgoing_connections:
|
#for from_port: int in d.nodes[node].outgoing_connections:
|
||||||
if (d.nodes[node].outgoing_connections[from_port] as Dictionary).is_empty():
|
#if (d.nodes[node].outgoing_connections[from_port] as Dictionary).is_empty():
|
||||||
keys_to_erase.append(from_port)
|
#keys_to_erase.append(from_port)
|
||||||
|
#
|
||||||
for key in keys_to_erase:
|
#for key in keys_to_erase:
|
||||||
(d.nodes[node].outgoing_connections as Dictionary).erase(key)
|
#(d.nodes[node].outgoing_connections as Dictionary).erase(key)
|
||||||
|
#
|
||||||
var incoming_connections: Dictionary = d.nodes[node].incoming_connections.duplicate(true)
|
#var incoming_connections: Dictionary = d.nodes[node].incoming_connections.duplicate(true)
|
||||||
|
#
|
||||||
for to_port: int in incoming_connections:
|
#for to_port: int in incoming_connections:
|
||||||
for from_node: String in incoming_connections[to_port]:
|
#for from_node: String in incoming_connections[to_port]:
|
||||||
if from_node not in nodes_to_copy:
|
#if from_node not in nodes_to_copy:
|
||||||
(d.nodes[node].incoming_connections[to_port] as Dictionary).erase(from_node)
|
#(d.nodes[node].incoming_connections[to_port] as Dictionary).erase(from_node)
|
||||||
|
#
|
||||||
keys_to_erase.clear()
|
#keys_to_erase.clear()
|
||||||
for to_port: int in d.nodes[node].incoming_connections:
|
#for to_port: int in d.nodes[node].incoming_connections:
|
||||||
if (d.nodes[node].incoming_connections[to_port] as Dictionary).is_empty():
|
#if (d.nodes[node].incoming_connections[to_port] as Dictionary).is_empty():
|
||||||
keys_to_erase.append(to_port)
|
#keys_to_erase.append(to_port)
|
||||||
|
#
|
||||||
for key in keys_to_erase:
|
#for key in keys_to_erase:
|
||||||
(d.nodes[node].incoming_connections as Dictionary).erase(key)
|
#(d.nodes[node].incoming_connections as Dictionary).erase(key)
|
||||||
keys_to_erase.clear()
|
#keys_to_erase.clear()
|
||||||
|
|
||||||
for node: Dictionary in d.nodes.values().slice(1):
|
for node: Dictionary in d.nodes.values().slice(1):
|
||||||
node.position.x = node.position.x - d.nodes.values()[0].position.x
|
node.position.x = node.position.x - d.nodes.values()[0].position.x
|
||||||
|
@ -468,10 +468,15 @@ func paste_nodes_from_dict(nodes_to_paste: Dictionary, position: Vector2 = Vecto
|
||||||
add_node_inst(node, ids_map[node_id])
|
add_node_inst(node, ids_map[node_id])
|
||||||
if group_needs_unique:
|
if group_needs_unique:
|
||||||
node.make_unique()
|
node.make_unique()
|
||||||
|
DeckHolder.logger.toast_warn("Group was made unique.")
|
||||||
|
|
||||||
|
|
||||||
func paste_nodes_from_json(json: String, position: Vector2 = Vector2()) -> void:
|
func paste_nodes_from_json(json: String, position: Vector2 = Vector2()) -> void:
|
||||||
paste_nodes_from_dict(JSON.parse_string(json), position)
|
var d = JSON.parse_string(json)
|
||||||
|
if not d:
|
||||||
|
DeckHolder.logger.toast_error("Paste failed.")
|
||||||
|
return
|
||||||
|
paste_nodes_from_dict(d, position)
|
||||||
|
|
||||||
|
|
||||||
func duplicate_nodes(nodes_to_copy: Array[String]) -> void:
|
func duplicate_nodes(nodes_to_copy: Array[String]) -> void:
|
||||||
|
@ -595,7 +600,7 @@ static func from_dict(data: Dictionary, path: String = "") -> Deck:
|
||||||
var nodes_data: Dictionary = data.deck.nodes as Dictionary
|
var nodes_data: Dictionary = data.deck.nodes as Dictionary
|
||||||
|
|
||||||
for node_id in nodes_data:
|
for node_id in nodes_data:
|
||||||
var node := DeckNode.from_dict(nodes_data[node_id])
|
var node := DeckNode.from_dict(nodes_data[node_id], deck.connections)
|
||||||
deck.add_node_inst(node, node_id)
|
deck.add_node_inst(node, node_id)
|
||||||
|
|
||||||
var groups_data: Dictionary = data.deck.groups as Dictionary
|
var groups_data: Dictionary = data.deck.groups as Dictionary
|
||||||
|
|
|
@ -239,7 +239,7 @@ func _pre_port_load() -> void:
|
||||||
|
|
||||||
|
|
||||||
## Virtual function that's called after the node has been deserialized.
|
## Virtual function that's called after the node has been deserialized.
|
||||||
func _post_load() -> void:
|
func _post_load(connections: Deck.NodeConnections) -> void:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ func to_dict(with_meta: bool = true) -> Dictionary:
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
static func from_dict(data: Dictionary) -> DeckNode:
|
static func from_dict(data: Dictionary, connections: Deck.NodeConnections = null) -> DeckNode:
|
||||||
var node := NodeDB.instance_node(data.node_type)
|
var node := NodeDB.instance_node(data.node_type)
|
||||||
#node._id = data._id
|
#node._id = data._id
|
||||||
node.name = data.name
|
node.name = data.name
|
||||||
|
@ -326,7 +326,7 @@ static func from_dict(data: Dictionary) -> DeckNode:
|
||||||
for key in data.meta:
|
for key in data.meta:
|
||||||
node.set_meta(key, str_to_var(data.meta[key]))
|
node.set_meta(key, str_to_var(data.meta[key]))
|
||||||
|
|
||||||
node._post_load()
|
node._post_load(connections)
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ enum LogCategory {
|
||||||
}
|
}
|
||||||
|
|
||||||
signal log_message(text: String, type: LogType, category: LogCategory)
|
signal log_message(text: String, type: LogType, category: LogCategory)
|
||||||
|
signal log_toast(text: String, type: LogType)
|
||||||
|
|
||||||
|
|
||||||
func log_node(text: Variant, type: LogType = LogType.INFO) -> void:
|
func log_node(text: Variant, type: LogType = LogType.INFO) -> void:
|
||||||
|
@ -40,3 +41,22 @@ func log(text: String, type: LogType, category: LogCategory) -> void:
|
||||||
|
|
||||||
if OS.has_feature("editor"):
|
if OS.has_feature("editor"):
|
||||||
prints(LogType.keys()[type].capitalize(), LogCategory.keys()[category].capitalize(), text)
|
prints(LogType.keys()[type].capitalize(), LogCategory.keys()[category].capitalize(), text)
|
||||||
|
|
||||||
|
|
||||||
|
func toast_info(text: String) -> void:
|
||||||
|
toast(text, LogType.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
func toast_warn(text: String) -> void:
|
||||||
|
toast(text, LogType.WARN)
|
||||||
|
|
||||||
|
|
||||||
|
func toast_error(text: String) -> void:
|
||||||
|
toast(text, LogType.ERROR)
|
||||||
|
|
||||||
|
|
||||||
|
func toast(text: String, type: LogType) -> void:
|
||||||
|
log_toast.emit(text, type)
|
||||||
|
|
||||||
|
if OS.has_feature("editor"):
|
||||||
|
prints("(t)", LogType.keys()[type].capitalize(), text)
|
||||||
|
|
|
@ -59,10 +59,10 @@ func _pre_port_load() -> void:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func _post_load() -> void:
|
func _post_load(connections: Deck.NodeConnections) -> void:
|
||||||
# ensure we have enough ports after connections
|
# ensure we have enough ports after connections
|
||||||
var last_connected_port := 0
|
var last_connected_port := 0
|
||||||
var outgoing_connections = _belonging_to.connections.get_all_outgoing_connections(_id)
|
var outgoing_connections = connections.get_all_outgoing_connections(_id)
|
||||||
for port: int in outgoing_connections:
|
for port: int in outgoing_connections:
|
||||||
last_connected_port = port if outgoing_connections.has(port) else last_connected_port
|
last_connected_port = port if outgoing_connections.has(port) else last_connected_port
|
||||||
|
|
||||||
|
|
|
@ -60,10 +60,10 @@ func _pre_port_load() -> void:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func _post_load() -> void:
|
func _post_load(connections: Deck.NodeConnections) -> void:
|
||||||
# ensure we have enough ports after connections
|
# ensure we have enough ports after connections
|
||||||
var last_connected_port := 0
|
var last_connected_port := 0
|
||||||
var incoming_connections := _belonging_to.connections.get_all_incoming_connections(_id)
|
var incoming_connections := connections.get_all_incoming_connections(_id)
|
||||||
for port: int in incoming_connections:
|
for port: int in incoming_connections:
|
||||||
last_connected_port = port if incoming_connections.has(port) else last_connected_port
|
last_connected_port = port if incoming_connections.has(port) else last_connected_port
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=18 format=3 uid="uid://duaah5x0jhkn6"]
|
[gd_scene load_steps=19 format=3 uid="uid://duaah5x0jhkn6"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://graph_node_renderer/deck_holder_renderer.gd" id="1_67g2g"]
|
[ext_resource type="Script" path="res://graph_node_renderer/deck_holder_renderer.gd" id="1_67g2g"]
|
||||||
[ext_resource type="PackedScene" uid="uid://b84f2ngtcm5b8" path="res://graph_node_renderer/tab_container_custom.tscn" id="1_s3ug2"]
|
[ext_resource type="PackedScene" uid="uid://b84f2ngtcm5b8" path="res://graph_node_renderer/tab_container_custom.tscn" id="1_s3ug2"]
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
[ext_resource type="Script" path="res://addons/no_twitch/twitch_connection.gd" id="5_3n36q"]
|
[ext_resource type="Script" path="res://addons/no_twitch/twitch_connection.gd" id="5_3n36q"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cddfyvpf5nqq7" path="res://graph_node_renderer/debug_nodes_list.tscn" id="5_pnfg8"]
|
[ext_resource type="PackedScene" uid="uid://cddfyvpf5nqq7" path="res://graph_node_renderer/debug_nodes_list.tscn" id="5_pnfg8"]
|
||||||
[ext_resource type="PackedScene" uid="uid://eioso6jb42jy" path="res://graph_node_renderer/obs_websocket_setup_dialog.tscn" id="5_uo2gj"]
|
[ext_resource type="PackedScene" uid="uid://eioso6jb42jy" path="res://graph_node_renderer/obs_websocket_setup_dialog.tscn" id="5_uo2gj"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://234k3tn8ny01" path="res://graph_node_renderer/toast_renderer.tscn" id="6_5532r"]
|
||||||
[ext_resource type="PackedScene" uid="uid://b56hjad0ih0gu" path="res://graph_node_renderer/sidebar/sidebar.tscn" id="7_0lv5b"]
|
[ext_resource type="PackedScene" uid="uid://b56hjad0ih0gu" path="res://graph_node_renderer/sidebar/sidebar.tscn" id="7_0lv5b"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bq2lxmbnic4lc" path="res://graph_node_renderer/twitch_setup_dialog.tscn" id="7_7rhap"]
|
[ext_resource type="PackedScene" uid="uid://bq2lxmbnic4lc" path="res://graph_node_renderer/twitch_setup_dialog.tscn" id="7_7rhap"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cuwou2aa7qfc2" path="res://graph_node_renderer/unsaved_changes_dialog_single_deck.tscn" id="8_qf6ve"]
|
[ext_resource type="PackedScene" uid="uid://cuwou2aa7qfc2" path="res://graph_node_renderer/unsaved_changes_dialog_single_deck.tscn" id="8_qf6ve"]
|
||||||
|
@ -128,6 +129,9 @@ item_1/id = 1
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="ToastRenderer" parent="MarginContainer/SidebarSplit/BottomSplit/VBoxContainer" instance=ExtResource("6_5532r")]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="BottomDock" parent="MarginContainer/SidebarSplit/BottomSplit" instance=ExtResource("4_gwnhy")]
|
[node name="BottomDock" parent="MarginContainer/SidebarSplit/BottomSplit" instance=ExtResource("4_gwnhy")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_resource type="Theme" load_steps=5 format=3 uid="uid://dqqdqscid2iem"]
|
[gd_resource type="Theme" load_steps=6 format=3 uid="uid://dqqdqscid2iem"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dt61u"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dt61u"]
|
||||||
content_margin_left = 4.0
|
content_margin_left = 4.0
|
||||||
|
@ -36,6 +36,18 @@ corner_radius_bottom_left = 4
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q56mu"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q56mu"]
|
||||||
bg_color = Color(0.623529, 0.564706, 0.909804, 0.0588235)
|
bg_color = Color(0.623529, 0.564706, 0.909804, 0.0588235)
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_w8gqp"]
|
||||||
|
content_margin_left = 8.0
|
||||||
|
content_margin_top = 8.0
|
||||||
|
content_margin_right = 8.0
|
||||||
|
content_margin_bottom = 8.0
|
||||||
|
bg_color = Color(0.12549, 0.12549, 0.12549, 0.627451)
|
||||||
|
border_color = Color(0.545098, 0.545098, 0.545098, 0.627451)
|
||||||
|
corner_radius_top_left = 4
|
||||||
|
corner_radius_top_right = 4
|
||||||
|
corner_radius_bottom_right = 4
|
||||||
|
corner_radius_bottom_left = 4
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
default_font_size = 14
|
default_font_size = 14
|
||||||
AccordionButton/base_type = &"Button"
|
AccordionButton/base_type = &"Button"
|
||||||
|
@ -43,3 +55,5 @@ AccordionButton/styles/hover = SubResource("StyleBoxFlat_dt61u")
|
||||||
AccordionButton/styles/normal = SubResource("StyleBoxFlat_fmm5o")
|
AccordionButton/styles/normal = SubResource("StyleBoxFlat_fmm5o")
|
||||||
AccordionButton/styles/pressed = SubResource("StyleBoxFlat_5q5t0")
|
AccordionButton/styles/pressed = SubResource("StyleBoxFlat_5q5t0")
|
||||||
AccordionMenu/styles/background = SubResource("StyleBoxFlat_q56mu")
|
AccordionMenu/styles/background = SubResource("StyleBoxFlat_q56mu")
|
||||||
|
ToastPanel/base_type = &"PanelContainer"
|
||||||
|
ToastPanel/styles/panel = SubResource("StyleBoxFlat_w8gqp")
|
||||||
|
|
1
graph_node_renderer/textures/error_icon_color.svg
Normal file
1
graph_node_renderer/textures/error_icon_color.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zM5.172 3.758 8 6.586l2.828-2.828 1.414 1.414L9.414 8l2.828 2.828-1.414 1.414L8 9.414l-2.828 2.828-1.414-1.414L6.586 8 3.758 5.172l1.414-1.414z" fill="#ff5f5f"/></svg>
|
After Width: | Height: | Size: 293 B |
37
graph_node_renderer/textures/error_icon_color.svg.import
Normal file
37
graph_node_renderer/textures/error_icon_color.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://t3s83w2wkyqp"
|
||||||
|
path="res://.godot/imported/error_icon_color.svg-36e8290c5e271c0fa763289e90b46d3d.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://graph_node_renderer/textures/error_icon_color.svg"
|
||||||
|
dest_files=["res://.godot/imported/error_icon_color.svg-36e8290c5e271c0fa763289e90b46d3d.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=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
graph_node_renderer/textures/info_icon.svg
Normal file
1
graph_node_renderer/textures/info_icon.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zM7 4h2v2H7zm0 3h2v5H7z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 170 B |
37
graph_node_renderer/textures/info_icon.svg.import
Normal file
37
graph_node_renderer/textures/info_icon.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bdv8ejbjaujvm"
|
||||||
|
path="res://.godot/imported/info_icon.svg-c3f8f29486a0a0cd1cfd29f9859897eb.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://graph_node_renderer/textures/info_icon.svg"
|
||||||
|
dest_files=["res://.godot/imported/info_icon.svg-c3f8f29486a0a0cd1cfd29f9859897eb.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=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
graph_node_renderer/textures/warning_icon_color.svg
Normal file
1
graph_node_renderer/textures/warning_icon_color.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a1 1 0 0 0-.85.484l-6 10A1 1 0 0 0 2 14h12a1 1 0 0 0 .857-1.514l-6-10a1 1 0 0 0-.85-.484zM7 5h2v5H7zm0 6h2v2H7z" fill="#ffdd65"/></svg>
|
After Width: | Height: | Size: 232 B |
37
graph_node_renderer/textures/warning_icon_color.svg.import
Normal file
37
graph_node_renderer/textures/warning_icon_color.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cmqrl3e53unmv"
|
||||||
|
path="res://.godot/imported/warning_icon_color.svg-944b7caf1a46684fe55272e6b2f36f61.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://graph_node_renderer/textures/warning_icon_color.svg"
|
||||||
|
dest_files=["res://.godot/imported/warning_icon_color.svg-944b7caf1a46684fe55272e6b2f36f61.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=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
75
graph_node_renderer/toast_renderer.gd
Normal file
75
graph_node_renderer/toast_renderer.gd
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# (c) 2023-present Eroax
|
||||||
|
# (c) 2023-present Yagich
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
extends Control
|
||||||
|
class_name ToastRenderer
|
||||||
|
|
||||||
|
|
||||||
|
const ERROR_ICON = preload("res://graph_node_renderer/textures/error_icon_color.svg")
|
||||||
|
const WARNING_ICON = preload("res://graph_node_renderer/textures/warning_icon_color.svg")
|
||||||
|
const INFO_ICON = preload("res://graph_node_renderer/textures/info_icon.svg")
|
||||||
|
|
||||||
|
@export var hold_time: float = 1.5
|
||||||
|
@export var limit: int = 5
|
||||||
|
|
||||||
|
@onready var vbox: VBoxContainer = %VBoxContainer
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
DeckHolder.logger.log_toast.connect(_on_logger_toast)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_logger_toast(text: String, type: Logger.LogType) -> void:
|
||||||
|
var panel := PanelContainer.new()
|
||||||
|
panel.theme_type_variation = &"ToastPanel"
|
||||||
|
var hb := HBoxContainer.new()
|
||||||
|
var icon := TextureRect.new()
|
||||||
|
icon.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
|
||||||
|
|
||||||
|
match type:
|
||||||
|
Logger.LogType.INFO:
|
||||||
|
icon.texture = INFO_ICON
|
||||||
|
Logger.LogType.WARN:
|
||||||
|
icon.texture = WARNING_ICON
|
||||||
|
Logger.LogType.ERROR:
|
||||||
|
icon.texture = ERROR_ICON
|
||||||
|
|
||||||
|
var label := Label.new()
|
||||||
|
label.text = text
|
||||||
|
|
||||||
|
hb.add_child(icon)
|
||||||
|
hb.add_child(label)
|
||||||
|
|
||||||
|
panel.add_child(hb)
|
||||||
|
|
||||||
|
move_and_remove()
|
||||||
|
|
||||||
|
panel.modulate.a = 0.0
|
||||||
|
vbox.add_child(panel)
|
||||||
|
var t := panel.create_tween()
|
||||||
|
t.tween_property(panel, ^"modulate:a", 1.0, 0.1)
|
||||||
|
t.tween_interval(hold_time)
|
||||||
|
t.tween_property(panel, ^"modulate:a", 0.0, 1.0)
|
||||||
|
t.finished.connect(
|
||||||
|
func():
|
||||||
|
panel.queue_free()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func move_and_remove() -> void:
|
||||||
|
if not (vbox.get_child_count() + 1 > limit):
|
||||||
|
return
|
||||||
|
|
||||||
|
for i: Node in vbox.get_children().slice(0, limit):
|
||||||
|
if i.get_meta(&"queued", false):
|
||||||
|
continue
|
||||||
|
|
||||||
|
i.set_meta(&"queued", true)
|
||||||
|
var t := i.create_tween()
|
||||||
|
t.tween_property(i, ^"position:x", i.position.x + i.size.x + 32, 0.4).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_IN)
|
||||||
|
t.finished.connect(
|
||||||
|
func():
|
||||||
|
i.queue_free()
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
27
graph_node_renderer/toast_renderer.tscn
Normal file
27
graph_node_renderer/toast_renderer.tscn
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://234k3tn8ny01"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://graph_node_renderer/toast_renderer.gd" id="1_446pb"]
|
||||||
|
|
||||||
|
[node name="ToastRenderer" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 0
|
||||||
|
script = ExtResource("1_446pb")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -490.0
|
||||||
|
offset_top = -312.0
|
||||||
|
offset_right = -32.0
|
||||||
|
offset_bottom = -32.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
alignment = 2
|
||||||
|
|
||||||
|
[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
Loading…
Reference in a new issue