From 1a877d6f750909036f09cd1f2120b3a3ac1d73c8 Mon Sep 17 00:00:00 2001 From: Sofia Date: Thu, 23 Jul 2026 19:14:17 +0300 Subject: [PATCH] Add simple popup --- godot/scenes/main.tscn | 56 +++++++++++++++++++++++++++++- rust/src/net/network_manager.rs | 16 +++++++++ rust/src/ui/main_menu.rs | 61 ++++++++++++++++++++++++++++++--- 3 files changed, 128 insertions(+), 5 deletions(-) diff --git a/godot/scenes/main.tscn b/godot/scenes/main.tscn index 133bb04..9a44627 100644 --- a/godot/scenes/main.tscn +++ b/godot/scenes/main.tscn @@ -2,7 +2,7 @@ [ext_resource type="PackedScene" uid="uid://bbmc2gmy7g8ag" path="res://scenes/misc/menu_player.tscn" id="1_o5qli"] -[node name="menu" type="MainMenu" unique_id=2036763876 node_paths=PackedStringArray("camera", "main_position", "host_position", "main_panel", "host_panel", "join_panel", "host_port", "join_addr")] +[node name="menu" type="MainMenu" unique_id=2036763876 node_paths=PackedStringArray("camera", "main_position", "host_position", "main_panel", "host_panel", "join_panel", "host_port", "join_addr", "popup_panel", "popup_title", "popup_text", "popup_button")] camera = NodePath("camera_3d") main_position = NodePath("main_pos") host_position = NodePath("host_pos") @@ -11,6 +11,10 @@ host_panel = NodePath("host_panel") join_panel = NodePath("join_panel") host_port = NodePath("host_panel/v_box_container/host_port") join_addr = NodePath("join_panel/v_box_container/address_text") +popup_panel = NodePath("popup_panel") +popup_title = NodePath("popup_panel/v_box_container/title") +popup_text = NodePath("popup_panel/v_box_container/text") +popup_button = NodePath("popup_panel/v_box_container/ok") [node name="camera_3d" type="Camera3D" parent="." unique_id=1513321931] transform = Transform3D(0.98629165, -0.031186381, 0.16203775, -1.4054481e-08, 0.981978, 0.1889952, -0.16501158, -0.18640438, 0.9685167, 1.0974052, 1.7166122, 1.4909106) @@ -176,6 +180,55 @@ transform = Transform3D(0.98629165, -0.031186387, 0.16203767, -1.4054484e-08, 0. [node name="host_pos" type="Node3D" parent="." unique_id=663794107] transform = Transform3D(0.3960592, -0.17354009, 0.90167665, -1.9851193e-08, 0.981978, 0.18899521, -0.9182249, -0.0748533, 0.38892144, -1.0602233, 1.7166122, 3.759781) +[node name="popup_panel" type="Panel" parent="." unique_id=1792775604] +visible = false +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -153.0 +offset_top = -71.0 +offset_right = 153.0 +offset_bottom = 71.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="v_box_container" type="VBoxContainer" parent="popup_panel" unique_id=465766643] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -20.0 +offset_top = -20.0 +offset_right = 20.0 +offset_bottom = 20.0 +grow_horizontal = 2 +grow_vertical = 2 +alignment = 1 + +[node name="title" type="Label" parent="popup_panel/v_box_container" unique_id=1944397487] +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_font_sizes/font_size = 25 +text = "Some Title" +horizontal_alignment = 1 + +[node name="text" type="Label" parent="popup_panel/v_box_container" unique_id=1988165424] +custom_minimum_size = Vector2(300, 0) +custom_maximum_size = Vector2(300, -1) +layout_mode = 2 +size_flags_horizontal = 4 +text = "Some text" +horizontal_alignment = 1 +autowrap_mode = 3 + +[node name="ok" type="Button" parent="popup_panel/v_box_container" unique_id=488898874] +layout_mode = 2 +text = "Ok" + [connection signal="pressed" from="main_panel/v_box_container/host" to="." method="go_to_host_game"] [connection signal="pressed" from="main_panel/v_box_container/join" to="." method="go_to_join_game"] [connection signal="pressed" from="main_panel/v_box_container/quit" to="." method="quit_game"] @@ -183,3 +236,4 @@ transform = Transform3D(0.3960592, -0.17354009, 0.90167665, -1.9851193e-08, 0.98 [connection signal="pressed" from="host_panel/v_box_container/back" to="." method="go_to_main_menu"] [connection signal="pressed" from="join_panel/v_box_container/join" to="." method="join_game"] [connection signal="pressed" from="join_panel/v_box_container/back" to="." method="go_to_main_menu"] +[connection signal="pressed" from="popup_panel/v_box_container/ok" to="." method="hide_popup"] diff --git a/rust/src/net/network_manager.rs b/rust/src/net/network_manager.rs index a5b653e..196b8ad 100644 --- a/rust/src/net/network_manager.rs +++ b/rust/src/net/network_manager.rs @@ -106,6 +106,20 @@ impl INode for NetworkManager { } while let Some(message) = self.poll() { + match &message { + PeerMessage::Disconnected(_, connection_error) => { + if !self.is_host() { + let message = if let Some(err) = connection_error { + format!("{}", err) + } else { + String::new() + }; + self.signals().on_client_disconnected().emit(&message); + } + } + _ => {} + } + self.handle_message(message); } } @@ -116,6 +130,8 @@ impl INode for NetworkManager { impl NetworkManager { #[signal] pub fn lobby_joined(); + #[signal] + pub fn on_client_disconnected(error: GString); fn poll(&mut self) -> Option> { let mut cli = CommandLinePanel::singleton(); diff --git a/rust/src/ui/main_menu.rs b/rust/src/ui/main_menu.rs index e43245e..b9fd736 100644 --- a/rust/src/ui/main_menu.rs +++ b/rust/src/ui/main_menu.rs @@ -1,5 +1,5 @@ use godot::{ - classes::{Camera3D, Panel, SpinBox, TextEdit}, + classes::{Button, Camera3D, Label, Panel, SpinBox, TextEdit}, prelude::*, register::property::SimpleVar, }; @@ -40,6 +40,15 @@ pub struct MainMenu { #[export] join_addr: Option>, + #[export] + popup_panel: Option>, + #[export] + popup_title: Option>, + #[export] + popup_text: Option>, + #[export] + popup_button: Option>, + #[export] current_menu: Menu, @@ -50,6 +59,22 @@ pub struct MainMenu { #[godot_api] impl INode3D for MainMenu { + fn ready(&mut self) { + self.hide_popup(); + + NetworkManager::singleton() + .bind_mut() + .signals() + .on_client_disconnected() + .connect_other(self, |s, msg| { + if msg.is_empty() { + s.show_popup("Disconnected", "disconnected", true); + } else { + s.show_popup("Error", &msg.to_string(), true); + } + }); + } + fn process(&mut self, _delta: f64) { if let Some(camera) = &mut self.camera { let target = match self.current_menu { @@ -123,9 +148,15 @@ impl MainMenu { #[func] pub fn join_game(&mut self) { - if let Some(addr) = &self.join_addr { - if let Ok(addr) = addr.get_text().to_string().parse() { - NetworkManager::singleton().bind_mut().join(addr); + if let Some(addr) = self.join_addr.clone() { + self.show_popup("Joining", "joining game", false); + match addr.get_text().to_string().parse() { + Ok(addr) => { + NetworkManager::singleton().bind_mut().join(addr); + } + Err(err) => { + self.show_popup("Error", &format!("Error joining: {}", err), true); + } } } } @@ -149,4 +180,26 @@ impl MainMenu { pub fn quit_game(&mut self) { self.base().get_tree().quit(); } + + pub fn show_popup(&mut self, title: &str, text: &str, ok: bool) { + if let Some(panel) = &mut self.popup_panel { + panel.set_visible(true); + if let Some(title_label) = &mut self.popup_title { + title_label.set_text(title); + } + if let Some(text_label) = &mut self.popup_text { + text_label.set_text(text); + } + if let Some(button) = &mut self.popup_button { + button.set_visible(ok); + } + } + } + + #[func] + pub fn hide_popup(&mut self) { + if let Some(panel) = &mut self.popup_panel { + panel.set_visible(false); + } + } }