Loading screen: show animated gears instead of status message, show tips

This commit is contained in:
Imbris 2020-09-18 01:44:28 -04:00
parent 489a8a8f9e
commit 0ab1a1ebb0
2 changed files with 71 additions and 59 deletions

View File

@ -1,17 +1,19 @@
use super::{ConnectionState, Message};
use super::{ConnectionState, Imgs, Message};
use crate::{
i18n::Localization,
ui::{
fonts::IcedFonts as Fonts,
ice::{component::neat_button, style, Element},
ice::{component::neat_button, style, widget::Image, Element},
},
};
use iced::{button, Align, Color, Column, Container, Length, Row, Space, Text};
use iced::{button, Align, Column, Container, Length, Row, Space, Text};
const GEAR_ANIMATION_SPEED_FACTOR: f64 = 10.0;
/// Connecting screen for the main menu
pub struct Screen {
cancel_button: button::State,
add_button: button::State,
tip_number: u16,
}
impl Screen {
@ -19,49 +21,76 @@ impl Screen {
Self {
cancel_button: Default::default(),
add_button: Default::default(),
tip_number: rand::random(),
}
}
pub(super) fn view(
&mut self,
fonts: &Fonts,
imgs: &Imgs,
connection_state: &ConnectionState,
time: f32,
time: f64,
i18n: &Localization,
button_style: style::button::Style,
show_tip: bool,
) -> Element<Message> {
let fade_msg = (time * 2.0).sin() * 0.5 + 0.51;
let gear_anim_time = time * GEAR_ANIMATION_SPEED_FACTOR;
// TODO: add built in support for animated images
let gear_anim_image = match (gear_anim_time % 5.0).trunc() as u8 {
0 => imgs.f1,
1 => imgs.f2,
2 => imgs.f3,
3 => imgs.f4,
_ => imgs.f5,
};
let children = match connection_state {
ConnectionState::InProgress { status } => {
let status = Text::new(status)
.size(fonts.alkhemi.scale(80))
.font(fonts.alkhemi.id)
.color(Color::from_rgba(1.0, 1.0, 1.0, fade_msg));
ConnectionState::InProgress => {
let tip = if show_tip {
let tip = format!(
"{} {}",
&i18n.get("main.tip"),
&i18n.get_variation("loading.tips", self.tip_number)
);
Container::new(Text::new(tip).size(fonts.cyri.scale(25)))
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.align_y(Align::End)
.into()
} else {
Space::new(Length::Fill, Length::Fill).into()
};
let status = Container::new(Row::with_children(vec![
Space::new(Length::Units(80), Length::Shrink).into(),
status.into(),
]))
.width(Length::Fill)
.height(Length::Fill)
.align_y(Align::End);
let gear = Container::new(
Image::new(gear_anim_image)
.width(Length::Units(74))
.height(Length::Units(62)),
)
.width(Length::Fill);
let cancel = neat_button(
let cancel = Container::new(neat_button(
&mut self.cancel_button,
i18n.get("common.cancel"),
0.7,
button_style,
Some(Message::CancelConnect),
);
))
.width(Length::Fill)
.height(Length::Units(fonts.cyri.scale(50)))
.center_x()
.padding(3);
let cancel = Container::new(cancel)
.width(Length::Fill)
.height(Length::Units(fonts.cyri.scale(50)))
.center_x()
.padding(3);
let gear_cancel = Row::with_children(vec![
gear.into(),
cancel.into(),
Space::new(Length::Fill, Length::Shrink).into(),
])
.width(Length::Fill)
.align_items(Align::End);
vec![status.into(), cancel.into()]
vec![tip, gear_cancel.into()]
},
ConnectionState::AuthTrustPrompt { msg, .. } => {
let text = Text::new(msg).size(fonts.cyri.scale(25));

View File

@ -54,6 +54,13 @@ image_ids_ice! {
selection: "voxygen.element.frames.selection",
selection_hover: "voxygen.element.frames.selection_hover",
selection_press: "voxygen.element.frames.selection_press",
// Animation
f1: "voxygen.element.animation.gears.1",
f2: "voxygen.element.animation.gears.2",
f3: "voxygen.element.animation.gears.3",
f4: "voxygen.element.animation.gears.4",
f5: "voxygen.element.animation.gears.5",
}
}
@ -100,23 +107,8 @@ pub struct LoginInfo {
}
enum ConnectionState {
InProgress {
status: String,
},
AuthTrustPrompt {
auth_server: String,
msg: String,
// To remember when we switch back
status: String,
},
}
impl ConnectionState {
fn take_status_string(&mut self) -> String {
std::mem::take(match self {
Self::InProgress { status } => status,
Self::AuthTrustPrompt { status, .. } => status,
})
}
InProgress,
AuthTrustPrompt { auth_server: String, msg: String },
}
enum Screen {
@ -153,7 +145,7 @@ struct Controls {
is_selecting_language: bool,
selected_language_index: Option<usize>,
time: f32,
time: f64,
screen: Screen,
}
@ -244,7 +236,7 @@ impl Controls {
}
fn view(&mut self, settings: &Settings, dt: f32) -> Element<Message> {
self.time = self.time + dt;
self.time = self.time + dt as f64;
// TODO: consider setting this as the default in the renderer
let button_style = style::button::Style::new(self.imgs.button)
@ -311,10 +303,12 @@ impl Controls {
connection_state,
} => screen.view(
&self.fonts,
&self.imgs,
&connection_state,
self.time,
&self.i18n,
button_style,
settings.gameplay.loading_tips,
),
};
@ -354,19 +348,14 @@ impl Controls {
Message::Singleplayer => {
self.screen = Screen::Connecting {
screen: connecting::Screen::new(),
connection_state: ConnectionState::InProgress {
status: [self.i18n.get("main.creating_world"), "..."].concat(),
},
connection_state: ConnectionState::InProgress,
};
events.push(Event::StartSingleplayer);
},
Message::Multiplayer => {
self.screen = Screen::Connecting {
screen: connecting::Screen::new(),
connection_state: ConnectionState::InProgress {
status: [self.i18n.get("main.connecting"), "..."].concat(),
},
connection_state: ConnectionState::InProgress,
};
events.push(Event::LoginAttempt {
@ -406,15 +395,13 @@ impl Controls {
{
if let ConnectionState::AuthTrustPrompt {
auth_server,
status,
..
} = connection_state
{
let auth_server = std::mem::take(auth_server);
let status = std::mem::take(status);
let added = matches!(msg, Message::TrustPromptAdd);
*connection_state = ConnectionState::InProgress { status };
*connection_state = ConnectionState::InProgress;
events.push(Event::AuthServerTrust(auth_server, added));
}
}
@ -462,11 +449,7 @@ impl Controls {
&auth_server
);
*connection_state = ConnectionState::AuthTrustPrompt {
auth_server,
msg,
status: connection_state.take_status_string(),
};
*connection_state = ConnectionState::AuthTrustPrompt { auth_server, msg };
}
}