Add simple popup

This commit is contained in:
Sofia 2026-07-23 19:14:17 +03:00
parent 0712265d55
commit 643e20060a
3 changed files with 128 additions and 5 deletions

View File

@ -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"]

View File

@ -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<PeerMessage<Package>> {
let mut cli = CommandLinePanel::singleton();

View File

@ -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<Gd<TextEdit>>,
#[export]
popup_panel: Option<Gd<Panel>>,
#[export]
popup_title: Option<Gd<Label>>,
#[export]
popup_text: Option<Gd<Label>>,
#[export]
popup_button: Option<Gd<Button>>,
#[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,10 +148,16 @@ 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() {
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);
}
}
}