mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
added status updates to loading screen
This commit is contained in:
parent
b2f1a53865
commit
9a3f53c32c
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -6785,6 +6785,7 @@ dependencies = [
|
|||||||
"authc",
|
"authc",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"clap",
|
"clap",
|
||||||
|
"crossbeam-channel",
|
||||||
"hashbrown 0.13.2",
|
"hashbrown 0.13.2",
|
||||||
"image",
|
"image",
|
||||||
"num 0.4.1",
|
"num 0.4.1",
|
||||||
|
@ -60,3 +60,11 @@ hud-stay= Stay
|
|||||||
hud-sit = Sit
|
hud-sit = Sit
|
||||||
hud-steer = Steer
|
hud-steer = Steer
|
||||||
hud-portal = Portal
|
hud-portal = Portal
|
||||||
|
hud-init-stage-singleplayer = Starting singleplayer server...
|
||||||
|
hud-init-stage-multiplayer = Starting multiplayer
|
||||||
|
hud-init-stage-client-connection-establish = Establishing connection to server
|
||||||
|
hud-init-stage-client-request-server-version = Wating for server version
|
||||||
|
hud-init-stage-client-authentication = Authenticating
|
||||||
|
hud-init-stage-client-load-init-data = Loading initialization data from server
|
||||||
|
hud-init-stage-client-starting-client = Preparing Client...
|
||||||
|
hud-init-stage-render-pipeline = Creating render pipeline ({ $done }/{ $total })
|
||||||
|
@ -30,6 +30,7 @@ tracing = { workspace = true }
|
|||||||
rayon = { workspace = true }
|
rayon = { workspace = true }
|
||||||
specs = { workspace = true, features = ["serde", "storage-event-control", "derive"] }
|
specs = { workspace = true, features = ["serde", "storage-event-control", "derive"] }
|
||||||
vek = { workspace = true }
|
vek = { workspace = true }
|
||||||
|
crossbeam-channel = { workspace = true }
|
||||||
hashbrown = { workspace = true }
|
hashbrown = { workspace = true }
|
||||||
authc = { git = "https://gitlab.com/veloren/auth.git", rev = "abb1a705827984e11706d7bb97fb7a459e1e6533" } # xMAC94x/current_master_till_refactored branch
|
authc = { git = "https://gitlab.com/veloren/auth.git", rev = "abb1a705827984e11706d7bb97fb7a459e1e6533" } # xMAC94x/current_master_till_refactored branch
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ use common_net::{
|
|||||||
use common_state::State;
|
use common_state::State;
|
||||||
use common_systems::add_local_systems;
|
use common_systems::add_local_systems;
|
||||||
use comp::BuffKind;
|
use comp::BuffKind;
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use image::DynamicImage;
|
use image::DynamicImage;
|
||||||
use network::{ConnectAddr, Network, Participant, Pid, Stream};
|
use network::{ConnectAddr, Network, Participant, Pid, Stream};
|
||||||
@ -115,6 +116,22 @@ pub enum Event {
|
|||||||
SpectatePosition(Vec3<f32>),
|
SpectatePosition(Vec3<f32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ClientInitStage {
|
||||||
|
/// A connection to the server is being created
|
||||||
|
ConnectionEstablish,
|
||||||
|
/// Waiting for server version
|
||||||
|
WatingForServerVersion,
|
||||||
|
/// We're currently authenticating with the server
|
||||||
|
Authentication,
|
||||||
|
/// Loading map data, site information, recipe information and other
|
||||||
|
/// initialization data
|
||||||
|
LoadingInitData,
|
||||||
|
/// Prepare data received by the server to be used by the client (insert
|
||||||
|
/// data into the ECS, render map)
|
||||||
|
StartingClient,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WorldData {
|
pub struct WorldData {
|
||||||
/// Just the "base" layer for LOD; currently includes colors and nothing
|
/// Just the "base" layer for LOD; currently includes colors and nothing
|
||||||
/// else. In the future we'll add more layers, like shadows, rivers, and
|
/// else. In the future we'll add more layers, like shadows, rivers, and
|
||||||
@ -290,9 +307,17 @@ impl Client {
|
|||||||
username: &str,
|
username: &str,
|
||||||
password: &str,
|
password: &str,
|
||||||
auth_trusted: impl FnMut(&str) -> bool,
|
auth_trusted: impl FnMut(&str) -> bool,
|
||||||
|
init_stage_update: Option<Sender<ClientInitStage>>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let update_stage = |stage: ClientInitStage| {
|
||||||
|
if let Some(updater) = &init_stage_update {
|
||||||
|
let _ = updater.send(stage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let network = Network::new(Pid::new(), &runtime);
|
let network = Network::new(Pid::new(), &runtime);
|
||||||
|
|
||||||
|
update_stage(ClientInitStage::ConnectionEstablish);
|
||||||
let mut participant = match addr {
|
let mut participant = match addr {
|
||||||
ConnectionArgs::Tcp {
|
ConnectionArgs::Tcp {
|
||||||
hostname,
|
hostname,
|
||||||
@ -322,6 +347,7 @@ impl Client {
|
|||||||
let in_game_stream = participant.opened().await?;
|
let in_game_stream = participant.opened().await?;
|
||||||
let terrain_stream = participant.opened().await?;
|
let terrain_stream = participant.opened().await?;
|
||||||
|
|
||||||
|
update_stage(ClientInitStage::WatingForServerVersion);
|
||||||
register_stream.send(ClientType::Game)?;
|
register_stream.send(ClientType::Game)?;
|
||||||
let server_info: ServerInfo = register_stream.recv().await?;
|
let server_info: ServerInfo = register_stream.recv().await?;
|
||||||
if server_info.git_hash != *common::util::GIT_HASH {
|
if server_info.git_hash != *common::util::GIT_HASH {
|
||||||
@ -340,6 +366,7 @@ impl Client {
|
|||||||
|
|
||||||
ping_stream.send(PingMsg::Ping)?;
|
ping_stream.send(PingMsg::Ping)?;
|
||||||
|
|
||||||
|
update_stage(ClientInitStage::Authentication);
|
||||||
// Register client
|
// Register client
|
||||||
Self::register(
|
Self::register(
|
||||||
username,
|
username,
|
||||||
@ -350,6 +377,7 @@ impl Client {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
update_stage(ClientInitStage::LoadingInitData);
|
||||||
// Wait for initial sync
|
// Wait for initial sync
|
||||||
let mut ping_interval = tokio::time::interval(Duration::from_secs(1));
|
let mut ping_interval = tokio::time::interval(Duration::from_secs(1));
|
||||||
let ServerInit::GameSync {
|
let ServerInit::GameSync {
|
||||||
@ -373,6 +401,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
update_stage(ClientInitStage::StartingClient);
|
||||||
// Spawn in a blocking thread (leaving the network thread free). This is mostly
|
// Spawn in a blocking thread (leaving the network thread free). This is mostly
|
||||||
// useful for bots.
|
// useful for bots.
|
||||||
let mut task = tokio::task::spawn_blocking(move || {
|
let mut task = tokio::task::spawn_blocking(move || {
|
||||||
@ -2978,6 +3007,7 @@ mod tests {
|
|||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
|suggestion: &str| suggestion == auth_server,
|
|suggestion: &str| suggestion == auth_server,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
let localisation = LocalizationHandle::load_expect("en");
|
let localisation = LocalizationHandle::load_expect("en");
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use client::{
|
use client::{
|
||||||
addr::ConnectionArgs,
|
addr::ConnectionArgs,
|
||||||
error::{Error as ClientError, NetworkConnectError, NetworkError},
|
error::{Error as ClientError, NetworkConnectError, NetworkError},
|
||||||
Client, ServerInfo,
|
Client, ClientInitStage, ServerInfo,
|
||||||
};
|
};
|
||||||
use crossbeam_channel::{unbounded, Receiver, Sender, TryRecvError};
|
use crossbeam_channel::{unbounded, Receiver, Sender, TryRecvError};
|
||||||
use std::{
|
use std::{
|
||||||
@ -39,6 +39,7 @@ pub struct AuthTrust(String, bool);
|
|||||||
// server).
|
// server).
|
||||||
pub struct ClientInit {
|
pub struct ClientInit {
|
||||||
rx: Receiver<Msg>,
|
rx: Receiver<Msg>,
|
||||||
|
stage_rx: Receiver<ClientInitStage>,
|
||||||
trust_tx: Sender<AuthTrust>,
|
trust_tx: Sender<AuthTrust>,
|
||||||
cancel: Arc<AtomicBool>,
|
cancel: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
@ -51,6 +52,7 @@ impl ClientInit {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let (tx, rx) = unbounded();
|
let (tx, rx) = unbounded();
|
||||||
let (trust_tx, trust_rx) = unbounded();
|
let (trust_tx, trust_rx) = unbounded();
|
||||||
|
let (init_stage_tx, init_stare_rx) = unbounded();
|
||||||
let cancel = Arc::new(AtomicBool::new(false));
|
let cancel = Arc::new(AtomicBool::new(false));
|
||||||
let cancel2 = Arc::clone(&cancel);
|
let cancel2 = Arc::clone(&cancel);
|
||||||
|
|
||||||
@ -73,6 +75,7 @@ impl ClientInit {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let mut mismatched_server_info = None;
|
let mut mismatched_server_info = None;
|
||||||
|
let new_init_tx = init_stage_tx.clone();
|
||||||
match Client::new(
|
match Client::new(
|
||||||
connection_args.clone(),
|
connection_args.clone(),
|
||||||
Arc::clone(&runtime2),
|
Arc::clone(&runtime2),
|
||||||
@ -80,6 +83,7 @@ impl ClientInit {
|
|||||||
&username,
|
&username,
|
||||||
&password,
|
&password,
|
||||||
trust_fn,
|
trust_fn,
|
||||||
|
Some(new_init_tx),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@ -116,6 +120,7 @@ impl ClientInit {
|
|||||||
|
|
||||||
ClientInit {
|
ClientInit {
|
||||||
rx,
|
rx,
|
||||||
|
stage_rx: init_stare_rx,
|
||||||
trust_tx,
|
trust_tx,
|
||||||
cancel,
|
cancel,
|
||||||
}
|
}
|
||||||
@ -132,6 +137,9 @@ impl ClientInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Poll for connection stage updates from the client
|
||||||
|
pub fn stage_update(&self) -> Option<ClientInitStage> { self.stage_rx.try_recv().ok() }
|
||||||
|
|
||||||
/// Report trust status of auth server
|
/// Report trust status of auth server
|
||||||
pub fn auth_trust(&self, auth_server: String, trusted: bool) {
|
pub fn auth_trust(&self, auth_server: String, trusted: bool) {
|
||||||
let _ = self.trust_tx.send(AuthTrust(auth_server, trusted));
|
let _ = self.trust_tx.send(AuthTrust(auth_server, trusted));
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
use client::{
|
use client::{
|
||||||
addr::ConnectionArgs,
|
addr::ConnectionArgs,
|
||||||
error::{InitProtocolError, NetworkConnectError, NetworkError},
|
error::{InitProtocolError, NetworkConnectError, NetworkError},
|
||||||
Client, ServerInfo,
|
Client, ClientInitStage, ServerInfo,
|
||||||
};
|
};
|
||||||
use client_init::{ClientInit, Error as InitError, Msg as InitMsg};
|
use client_init::{ClientInit, Error as InitError, Msg as InitMsg};
|
||||||
use common::comp;
|
use common::comp;
|
||||||
@ -26,6 +26,14 @@ use tokio::runtime;
|
|||||||
use tracing::error;
|
use tracing::error;
|
||||||
use ui::{Event as MainMenuEvent, MainMenuUi};
|
use ui::{Event as MainMenuEvent, MainMenuUi};
|
||||||
|
|
||||||
|
pub enum DetailedInitializationStage {
|
||||||
|
// TODO: Map generation and server startup progress
|
||||||
|
Singleplayer,
|
||||||
|
StartingMultiplayer,
|
||||||
|
Client(ClientInitStage),
|
||||||
|
CreatingRenderPipeline(usize, usize),
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: show status messages for waiting on server creation, client init, and
|
// TODO: show status messages for waiting on server creation, client init, and
|
||||||
// pipeline creation (we can show progress of pipeline creation)
|
// pipeline creation (we can show progress of pipeline creation)
|
||||||
enum InitState {
|
enum InitState {
|
||||||
@ -187,6 +195,12 @@ impl PlayState for MainMenuState {
|
|||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(client_stage_update) = self.init.client().and_then(|init| init.stage_update()) {
|
||||||
|
self.main_menu_ui
|
||||||
|
.update_stage(DetailedInitializationStage::Client(client_stage_update));
|
||||||
|
}
|
||||||
|
|
||||||
// Poll client creation.
|
// Poll client creation.
|
||||||
match self.init.client().and_then(|init| init.poll()) {
|
match self.init.client().and_then(|init| init.poll()) {
|
||||||
Some(InitMsg::Done(Ok(mut client))) => {
|
Some(InitMsg::Done(Ok(mut client))) => {
|
||||||
@ -263,13 +277,13 @@ impl PlayState for MainMenuState {
|
|||||||
|
|
||||||
// Poll renderer pipeline creation
|
// Poll renderer pipeline creation
|
||||||
if let InitState::Pipeline(..) = &self.init {
|
if let InitState::Pipeline(..) = &self.init {
|
||||||
// If not complete go to char select screen
|
if let Some((done, total)) = &global_state.window.renderer().pipeline_creation_status()
|
||||||
if global_state
|
|
||||||
.window
|
|
||||||
.renderer()
|
|
||||||
.pipeline_creation_status()
|
|
||||||
.is_none()
|
|
||||||
{
|
{
|
||||||
|
self.main_menu_ui.update_stage(
|
||||||
|
DetailedInitializationStage::CreatingRenderPipeline(*done, *total),
|
||||||
|
);
|
||||||
|
// If complete go to char select screen
|
||||||
|
} else {
|
||||||
// Always succeeds since we check above
|
// Always succeeds since we check above
|
||||||
if let InitState::Pipeline(client) =
|
if let InitState::Pipeline(client) =
|
||||||
core::mem::replace(&mut self.init, InitState::None)
|
core::mem::replace(&mut self.init, InitState::None)
|
||||||
|
@ -2,6 +2,7 @@ use super::{ConnectionState, Imgs, Message};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
game_input::GameInput,
|
game_input::GameInput,
|
||||||
|
menu::main::DetailedInitializationStage,
|
||||||
settings::ControlSettings,
|
settings::ControlSettings,
|
||||||
ui::{
|
ui::{
|
||||||
fonts::IcedFonts as Fonts,
|
fonts::IcedFonts as Fonts,
|
||||||
@ -9,6 +10,7 @@ use crate::{
|
|||||||
Graphic,
|
Graphic,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use client::ClientInitStage;
|
||||||
use common::assets::{self, AssetExt};
|
use common::assets::{self, AssetExt};
|
||||||
use i18n::Localization;
|
use i18n::Localization;
|
||||||
use iced::{button, Align, Column, Container, Length, Row, Space, Text};
|
use iced::{button, Align, Column, Container, Length, Row, Space, Text};
|
||||||
@ -85,6 +87,7 @@ impl Screen {
|
|||||||
fonts: &Fonts,
|
fonts: &Fonts,
|
||||||
imgs: &Imgs,
|
imgs: &Imgs,
|
||||||
connection_state: &ConnectionState,
|
connection_state: &ConnectionState,
|
||||||
|
init_stage: &DetailedInitializationStage,
|
||||||
time: f64,
|
time: f64,
|
||||||
i18n: &Localization,
|
i18n: &Localization,
|
||||||
button_style: style::button::Style,
|
button_style: style::button::Style,
|
||||||
@ -133,6 +136,46 @@ impl Screen {
|
|||||||
Space::new(Length::Fill, Length::Fill).into()
|
Space::new(Length::Fill, Length::Fill).into()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let stage = {
|
||||||
|
let stage_message = match init_stage {
|
||||||
|
DetailedInitializationStage::Singleplayer => {
|
||||||
|
i18n.get_msg("hud-init-stage-singleplayer")
|
||||||
|
},
|
||||||
|
DetailedInitializationStage::StartingMultiplayer => {
|
||||||
|
i18n.get_msg("hud-init-stage-multiplayer")
|
||||||
|
},
|
||||||
|
DetailedInitializationStage::Client(client_stage) => match client_stage {
|
||||||
|
ClientInitStage::ConnectionEstablish => {
|
||||||
|
i18n.get_msg("hud-init-stage-client-connection-establish")
|
||||||
|
},
|
||||||
|
ClientInitStage::WatingForServerVersion => {
|
||||||
|
i18n.get_msg("hud-init-stage-client-request-server-version")
|
||||||
|
},
|
||||||
|
ClientInitStage::Authentication => {
|
||||||
|
i18n.get_msg("hud-init-stage-client-authentication")
|
||||||
|
},
|
||||||
|
ClientInitStage::LoadingInitData => {
|
||||||
|
i18n.get_msg("hud-init-stage-client-load-init-data")
|
||||||
|
},
|
||||||
|
ClientInitStage::StartingClient => {
|
||||||
|
i18n.get_msg("hud-init-stage-client-starting-client")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DetailedInitializationStage::CreatingRenderPipeline(done, total) => i18n
|
||||||
|
.get_msg_ctx(
|
||||||
|
"hud-init-stage-render-pipeline",
|
||||||
|
&i18n::fluent_args! { "done" => done, "total" => total },
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
Container::new(Text::new(stage_message).size(fonts.cyri.scale(25)))
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill)
|
||||||
|
.padding(10)
|
||||||
|
.align_y(Align::End)
|
||||||
|
.into()
|
||||||
|
};
|
||||||
|
|
||||||
let cancel = Container::new(neat_button(
|
let cancel = Container::new(neat_button(
|
||||||
&mut self.cancel_button,
|
&mut self.cancel_button,
|
||||||
i18n.get_msg("common-cancel"),
|
i18n.get_msg("common-cancel"),
|
||||||
@ -160,13 +203,10 @@ impl Screen {
|
|||||||
.padding(10)
|
.padding(10)
|
||||||
.align_x(Align::End);
|
.align_x(Align::End);
|
||||||
|
|
||||||
let bottom_content = Row::with_children(vec![
|
let bottom_content =
|
||||||
Space::new(Length::Fill, Length::Shrink).into(),
|
Row::with_children(vec![stage, tip_cancel.into(), gear.into()])
|
||||||
tip_cancel.into(),
|
.align_items(Align::Center)
|
||||||
gear.into(),
|
.width(Length::Fill);
|
||||||
])
|
|
||||||
.align_items(Align::Center)
|
|
||||||
.width(Length::Fill);
|
|
||||||
|
|
||||||
let left_art = Image::new(imgs.loading_art_l)
|
let left_art = Image::new(imgs.loading_art_l)
|
||||||
.width(Length::Units(12))
|
.width(Length::Units(12))
|
||||||
|
@ -29,6 +29,8 @@ use rand::{seq::SliceRandom, thread_rng};
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
|
use super::DetailedInitializationStage;
|
||||||
|
|
||||||
// TODO: what is this? (showed up in rebase)
|
// TODO: what is this? (showed up in rebase)
|
||||||
//const COL1: Color = Color::Rgba(0.07, 0.1, 0.1, 0.9);
|
//const COL1: Color = Color::Rgba(0.07, 0.1, 0.1, 0.9);
|
||||||
|
|
||||||
@ -179,6 +181,7 @@ enum Screen {
|
|||||||
Connecting {
|
Connecting {
|
||||||
screen: connecting::Screen,
|
screen: connecting::Screen,
|
||||||
connection_state: ConnectionState,
|
connection_state: ConnectionState,
|
||||||
|
init_stage: DetailedInitializationStage,
|
||||||
},
|
},
|
||||||
#[cfg(feature = "singleplayer")]
|
#[cfg(feature = "singleplayer")]
|
||||||
WorldSelector {
|
WorldSelector {
|
||||||
@ -405,10 +408,12 @@ impl Controls {
|
|||||||
Screen::Connecting {
|
Screen::Connecting {
|
||||||
screen,
|
screen,
|
||||||
connection_state,
|
connection_state,
|
||||||
|
init_stage,
|
||||||
} => screen.view(
|
} => screen.view(
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
connection_state,
|
connection_state,
|
||||||
|
init_stage,
|
||||||
self.time,
|
self.time,
|
||||||
&self.i18n.read(),
|
&self.i18n.read(),
|
||||||
button_style,
|
button_style,
|
||||||
@ -480,6 +485,7 @@ impl Controls {
|
|||||||
self.screen = Screen::Connecting {
|
self.screen = Screen::Connecting {
|
||||||
screen: connecting::Screen::new(ui),
|
screen: connecting::Screen::new(ui),
|
||||||
connection_state: ConnectionState::InProgress,
|
connection_state: ConnectionState::InProgress,
|
||||||
|
init_stage: DetailedInitializationStage::Singleplayer,
|
||||||
};
|
};
|
||||||
events.push(Event::StartSingleplayer);
|
events.push(Event::StartSingleplayer);
|
||||||
},
|
},
|
||||||
@ -520,6 +526,7 @@ impl Controls {
|
|||||||
self.screen = Screen::Connecting {
|
self.screen = Screen::Connecting {
|
||||||
screen: connecting::Screen::new(ui),
|
screen: connecting::Screen::new(ui),
|
||||||
connection_state: ConnectionState::InProgress,
|
connection_state: ConnectionState::InProgress,
|
||||||
|
init_stage: DetailedInitializationStage::StartingMultiplayer,
|
||||||
};
|
};
|
||||||
|
|
||||||
events.push(Event::LoginAttempt {
|
events.push(Event::LoginAttempt {
|
||||||
@ -629,6 +636,12 @@ impl Controls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_stage(&mut self, stage: DetailedInitializationStage) {
|
||||||
|
if let Screen::Connecting { init_stage, .. } = &mut self.screen {
|
||||||
|
*init_stage = stage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn tab(&mut self) {
|
fn tab(&mut self) {
|
||||||
if let Screen::Login { screen, .. } = &mut self.screen {
|
if let Screen::Login { screen, .. } = &mut self.screen {
|
||||||
// TODO: add select all function in iced
|
// TODO: add select all function in iced
|
||||||
@ -714,6 +727,10 @@ impl MainMenuUi {
|
|||||||
|
|
||||||
pub fn show_info(&mut self, msg: String) { self.controls.connection_error(msg); }
|
pub fn show_info(&mut self, msg: String) { self.controls.connection_error(msg); }
|
||||||
|
|
||||||
|
pub fn update_stage(&mut self, stage: DetailedInitializationStage) {
|
||||||
|
self.controls.init_stage(stage);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn connected(&mut self) { self.controls.exit_connect_screen(); }
|
pub fn connected(&mut self) { self.controls.exit_connect_screen(); }
|
||||||
|
|
||||||
pub fn cancel_connection(&mut self) { self.controls.exit_connect_screen(); }
|
pub fn cancel_connection(&mut self) { self.controls.exit_connect_screen(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user