Loading Screen with pulsating text, 2 new hairstyles

This commit is contained in:
Monty Marz 2019-11-23 00:51:18 +00:00
parent b804c18eb0
commit 370e94b1ad
9 changed files with 442 additions and 391 deletions

BIN
assets/voxygen/background/bg_load.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/dwarf/female-1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/elf/male-3.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -113,6 +113,7 @@
Some(("figure.hair.elf.male-0", (2, 1, 1))),
Some(("figure.hair.elf.male-1", (1, -1, 0))),
Some(("figure.hair.elf.male-2", (-2, -4, -7))),
Some(("figure.hair.elf.male-3", (-7, -10, -8))),
],
beard: [None],
accessory: [
@ -150,7 +151,7 @@
beard: [None],
accessory: [
None,
Some(("figure.accessory.elf.warpaint-0", (6, 9, 4))), ]
Some(("figure.accessory.elf.warpaint-0", (6, 9, 5))),]
),
(Dwarf, Male): (
offset: (-6.0, -4.5, -6.0),
@ -193,7 +194,8 @@
head: ("figure.head.dwarf.female", (0, 3, 0)),
eyes: ("figure.eyes.dwarf.female-0", (1, 10, 2)),
hair: [
Some(("figure.hair.dwarf.female-0", (0, 0, -7))),
Some(("figure.hair.dwarf.female-0", (-9, -9, -7))),
Some(("figure.hair.dwarf.female-1", (-9, -9, -7))),
],
beard: [None],
accessory: [

View File

@ -332,10 +332,10 @@ impl Race {
match (self, body_type) {
(Race::Danari, BodyType::Female) => 2,
(Race::Danari, BodyType::Male) => 2,
(Race::Dwarf, BodyType::Female) => 1,
(Race::Dwarf, BodyType::Female) => 2,
(Race::Dwarf, BodyType::Male) => 3,
(Race::Elf, BodyType::Female) => 21,
(Race::Elf, BodyType::Male) => 3,
(Race::Elf, BodyType::Male) => 4,
(Race::Human, BodyType::Female) => 19,
(Race::Human, BodyType::Male) => 17,
(Race::Orc, BodyType::Female) => 1,

View File

@ -98,7 +98,10 @@ impl PlayState for MainMenuState {
global_state.maintain(clock.get_last_delta().as_secs_f32());
// Maintain the UI.
for event in self.main_menu_ui.maintain(global_state) {
for event in self
.main_menu_ui
.maintain(global_state, clock.get_last_delta())
{
match event {
MainMenuEvent::LoginAttempt {
username,

View File

@ -14,6 +14,7 @@ use conrod_core::{
widget::{text_box::Event as TextBoxEvent, Button, Image, List, Rectangle, Text, TextBox},
widget_ids, Borderable, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
};
use std::time::Duration;
widget_ids! {
struct Ids {
@ -83,6 +84,7 @@ image_ids! {
<ImageGraphic>
bg: "voxygen.background.bg_main",
load: "voxygen.background.bg_load",
<BlankGraphic>
nothing: (),
@ -127,7 +129,6 @@ pub enum PopupType {
Error,
ConnectionInfo,
}
pub struct PopupData {
msg: String,
button_text: String,
@ -145,8 +146,10 @@ pub struct MainMenuUi {
server_address: String,
popup: Option<PopupData>,
connecting: Option<std::time::Instant>,
connect: bool,
show_servers: bool,
show_disclaimer: bool,
time: f32,
}
impl MainMenuUi {
@ -177,12 +180,16 @@ impl MainMenuUi {
popup: None,
connecting: None,
show_servers: false,
connect: false,
time: 0.0,
show_disclaimer: global_state.settings.show_disclaimer,
}
}
fn update_layout(&mut self, global_state: &mut GlobalState) -> Vec<Event> {
fn update_layout(&mut self, global_state: &mut GlobalState, dt: Duration) -> Vec<Event> {
let mut events = Vec::new();
self.time = self.time + dt.as_secs_f32();
let fade_msg = (self.time * 2.0).sin() * 0.5 + 0.51;
let (ref mut ui_widgets, ref mut _tooltip_manager) = self.ui.set_widgets();
let version = format!(
"{}-{}",
@ -196,9 +203,6 @@ impl MainMenuUi {
\n\
The name you put in will be your character name ingame.\n\
\n\
Starting Singleplayer needs some time to load.\n\
During this time the game may appear unresponsive.\n\
\n\
As of now you can't save your characters.\n\
Changing their appearance is possible though.";
@ -222,429 +226,459 @@ impl MainMenuUi {
// Background image, Veloren logo, Alpha-Version Label
Image::new(self.imgs.bg)
.middle_of(ui_widgets.window)
.set(self.ids.bg, ui_widgets);
Image::new(self.imgs.banner)
.w_h(65.0 * 6.0, 100.0 * 6.0)
.middle_of(self.ids.bg)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.9)))
.set(self.ids.banner, ui_widgets);
Image::new(self.imgs.banner_top)
.w_h(65.0 * 6.0, 1.0 * 6.0)
.mid_top_with_margin_on(self.ids.banner, 0.0)
.set(self.ids.banner_top, ui_widgets);
// Logo
Image::new(self.imgs.v_logo)
.w_h(123.0 * 2.5, 35.0 * 2.5)
.mid_top_with_margin_on(self.ids.banner_top, 40.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.95)))
.set(self.ids.v_logo, ui_widgets);
Image::new(if self.connect {
self.imgs.load
} else {
self.imgs.bg
})
.middle_of(ui_widgets.window)
.set(self.ids.bg, ui_widgets);
// Version displayed top right corner
Text::new(&version)
.color(TEXT_COLOR)
.top_right_with_margins_on(ui_widgets.window, 5.0, 5.0)
.font_id(self.fonts.cyri)
.font_size(14)
.font_id(self.fonts.cyri)
.color(TEXT_COLOR)
.set(self.ids.version, ui_widgets);
if self.show_disclaimer {
Image::new(self.imgs.disclaimer)
.w_h(1800.0, 800.0)
.middle_of(ui_widgets.window)
.scroll_kids()
.scroll_kids_vertically()
.set(self.ids.disc_window, ui_widgets);
Text::new("Disclaimer")
.top_left_with_margins_on(self.ids.disc_window, 30.0, 40.0)
.font_size(35)
.font_id(self.fonts.alkhemi)
.color(TEXT_COLOR)
.set(self.ids.disc_text_1, ui_widgets);
Text::new(
"Welcome to the alpha version of Veloren!\n\
\n\
\n\
Before you dive into the fun, please keep a few things in mind:\n\
\n\
- This is a very early alpha. Expect bugs, extremely unfinished gameplay, unpolished mechanics, and missing features. \n\
\n\
-If you have constructive feedback or bug reports, you can contact us via Reddit, GitLab, or our community Discord server.\n\
\n\
- Veloren is licensed under the GPL 3 open-source licence. That means you're free to play, modify, and redistribute the game however you wish \n\
(provided derived work is also under GPL 3).
\n\
- Veloren is a non-profit community project, and everybody working on it is a volunteer.\n\
If you like what you see, you're welcome to join the development or art teams!
\n\
- 'Voxel RPG' is a genre in its own right. First-person shooters used to be called Doom clones.\n\
Like them, we're trying to build a niche. This game is not a clone, and its development will diverge from existing games in the future.\n\
\n\
Thanks for taking the time to read this notice, we hope you enjoy the game!\n\
\n\
~ The Veloren Devs")
.top_left_with_margins_on(self.ids.disc_window, 110.0, 40.0)
.font_size(26)
.font_id(self.fonts.cyri)
.color(TEXT_COLOR)
.set(self.ids.disc_text_2, ui_widgets);
// Popup (Error/Info)
if let Some(popup_data) = &self.popup {
let text = Text::new(&popup_data.msg)
.rgba(1.0, 1.0, 1.0, if self.connect { fade_msg } else { 1.0 })
.font_id(self.fonts.cyri);
Rectangle::fill_with([65.0 * 6.0, 140.0], color::TRANSPARENT)
.rgba(0.1, 0.1, 0.1, if self.connect { 0.0 } else { 1.0 })
.parent(ui_widgets.window)
.up_from(self.ids.banner_top, 15.0)
.set(self.ids.login_error_bg, ui_widgets);
Image::new(self.imgs.info_frame)
.w_h(65.0 * 6.0, 140.0)
.color(Some(Color::Rgba(
1.0,
1.0,
1.0,
if self.connect { 0.0 } else { 1.0 },
)))
.middle_of(self.ids.login_error_bg)
.set(self.ids.error_frame, ui_widgets);
if self.connect {
text.mid_top_with_margin_on(self.ids.error_frame, 10.0)
.font_id(self.fonts.alkhemi)
.bottom_left_with_margins_on(ui_widgets.window, 60.0, 60.0)
.font_size(70)
.set(self.ids.login_error, ui_widgets);
} else {
text.mid_top_with_margin_on(self.ids.error_frame, 10.0)
.font_id(self.fonts.cyri)
.font_size(25)
.set(self.ids.login_error, ui_widgets);
};
if Button::image(self.imgs.button)
.w_h(300.0, 50.0)
.mid_bottom_with_margin_on(self.ids.disc_window, 30.0)
.w_h(100.0, 30.0)
.mid_bottom_with_margin_on(
if self.connect {
ui_widgets.window
} else {
self.ids.login_error_bg
},
10.0,
)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label_y(Relative::Scalar(2.0))
.label("Accept")
.label_font_size(22)
.label_color(TEXT_COLOR)
.label(&popup_data.button_text)
.label_font_id(self.fonts.cyri)
.set(self.ids.disc_button, ui_widgets)
.label_font_size(15)
.label_color(TEXT_COLOR)
.set(self.ids.button_ok, ui_widgets)
.was_clicked()
{
self.show_disclaimer = false;
events.push(Event::DisclaimerClosed);
}
} else {
// TODO: Don't use macros for this?
// Input fields
// Used when the login button is pressed, or enter is pressed within input field
macro_rules! login {
() => {
self.connecting = Some(std::time::Instant::now());
self.popup = Some(PopupData {
msg: "Connecting...".to_string(),
button_text: "Cancel".to_string(),
popup_type: PopupType::ConnectionInfo,
});
events.push(Event::LoginAttempt {
username: self.username.clone(),
password: self.password.clone(),
server_address: self.server_address.clone(),
});
match popup_data.popup_type {
PopupType::ConnectionInfo => {
events.push(Event::CancelLoginAttempt);
}
_ => (),
};
}
// Info Window
Rectangle::fill_with([550.0, 200.0], color::BLACK)
.top_left_with_margins_on(ui_widgets.window, 40.0, 40.0)
.color(Color::Rgba(0.0, 0.0, 0.0, 0.95))
.set(self.ids.info_frame, ui_widgets);
Image::new(self.imgs.banner_bottom)
.mid_bottom_with_margin_on(self.ids.info_frame, -50.0)
.w_h(550.0, 50.0)
.color(Some(Color::Rgba(0.0, 0.0, 0.0, 0.95)))
.set(self.ids.info_bottom, ui_widgets);
Text::new(intro_text)
.top_left_with_margins_on(self.ids.info_frame, 15.0, 15.0)
.font_size(20)
.font_id(self.fonts.cyri)
.color(TEXT_COLOR)
.set(self.ids.info_text, ui_widgets);
self.popup = None;
};
}
if !self.connect {
Image::new(self.imgs.banner)
.w_h(65.0 * 6.0, 100.0 * 6.0)
.middle_of(self.ids.bg)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.9)))
.set(self.ids.banner, ui_widgets);
// Singleplayer
// Used when the singleplayer button is pressed
#[cfg(feature = "singleplayer")]
macro_rules! singleplayer {
() => {
events.push(Event::StartSingleplayer);
self.connecting = Some(std::time::Instant::now());
self.popup = Some(PopupData {
msg: "Connecting...".to_string(),
button_text: "Cancel".to_string(),
popup_type: PopupType::ConnectionInfo,
});
};
}
Image::new(self.imgs.banner_top)
.w_h(65.0 * 6.0, 1.0 * 6.0)
.mid_top_with_margin_on(self.ids.banner, 0.0)
.set(self.ids.banner_top, ui_widgets);
// Username
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.97))
.mid_top_with_margin_on(self.ids.banner_top, 160.0)
.set(self.ids.usrnm_bg, ui_widgets);
Image::new(self.imgs.input_bg)
.w_h(337.0, 67.0)
.middle_of(self.ids.usrnm_bg)
.set(self.ids.username_bg, ui_widgets);
for event in TextBox::new(&self.username)
.w_h(290.0, 30.0)
.mid_bottom_with_margin_on(self.ids.username_bg, 44.0 / 2.0)
.font_size(22)
.font_id(self.fonts.cyri)
.text_color(TEXT_COLOR)
// transparent background
.color(TRANSPARENT)
.border_color(TRANSPARENT)
.set(self.ids.username_field, ui_widgets)
{
match event {
TextBoxEvent::Update(username) => {
// Note: TextBox limits the input string length to what fits in it
self.username = username.to_string();
}
TextBoxEvent::Enter => {
login!();
}
}
}
// Password
// TODO: REACTIVATE THIS WHEN A PROPER ACCOUNT SYSTEM IS IN PLACE
/*Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.97))
.down_from(self.ids.usrnm_bg, 30.0)
.set(self.ids.passwd_bg, ui_widgets);
Image::new(self.imgs.input_bg)
.w_h(337.0, 67.0)
.middle_of(self.ids.passwd_bg)
.color(Some(INACTIVE))
.set(self.ids.password_bg, ui_widgets);
for event in TextBox::new(&self.password)
.w_h(290.0, 30.0)
.mid_bottom_with_margin_on(self.ids.password_bg, 44.0 / 2.0)
.font_size(22)
.font_id(self.fonts.cyri)
.text_color(TEXT_COLOR)
// transparent background
.color(TRANSPARENT)
.border_color(TRANSPARENT)
.set(self.ids.password_field, ui_widgets)
{
match event {
TextBoxEvent::Update(password) => {
// Note: TextBox limits the input string length to what fits in it
self.password = password;
}
TextBoxEvent::Enter => {
login!();
}
}
}*/
// Popup (Error/Info)
if let Some(popup_data) = &self.popup {
let text = Text::new(&popup_data.msg)
.rgba(1.0, 1.0, 1.0, 1.0)
.font_size(25)
.font_id(self.fonts.cyri);
Rectangle::fill_with([65.0 * 6.0, 140.0], color::TRANSPARENT)
.rgba(0.1, 0.1, 0.1, 1.0)
.parent(ui_widgets.window)
.up_from(self.ids.banner_top, 15.0)
.set(self.ids.login_error_bg, ui_widgets);
Image::new(self.imgs.info_frame)
.w_h(65.0 * 6.0, 140.0)
.middle_of(self.ids.login_error_bg)
.set(self.ids.error_frame, ui_widgets);
text.mid_top_with_margin_on(self.ids.error_frame, 10.0)
.set(self.ids.login_error, ui_widgets);
// Logo
Image::new(self.imgs.v_logo)
.w_h(123.0 * 2.5, 35.0 * 2.5)
.mid_top_with_margin_on(self.ids.banner_top, 40.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.95)))
.set(self.ids.v_logo, ui_widgets);
if self.show_disclaimer {
Image::new(self.imgs.disclaimer)
.w_h(1800.0, 800.0)
.middle_of(ui_widgets.window)
.scroll_kids()
.scroll_kids_vertically()
.set(self.ids.disc_window, ui_widgets);
Text::new("Disclaimer")
.top_left_with_margins_on(self.ids.disc_window, 30.0, 40.0)
.font_size(35)
.font_id(self.fonts.alkhemi)
.color(TEXT_COLOR)
.set(self.ids.disc_text_1, ui_widgets);
Text::new(
"Welcome to the alpha version of Veloren!\n\
\n\
\n\
Before you dive into the fun, please keep a few things in mind:\n\
\n\
- This is a very early alpha. Expect bugs, extremely unfinished gameplay, unpolished mechanics, and missing features. \n\
\n\
-If you have constructive feedback or bug reports, you can contact us via Reddit, GitLab, or our community Discord server.\n\
\n\
- Veloren is licensed under the GPL 3 open-source licence. That means you're free to play, modify, and redistribute the game however you wish \n\
(provided derived work is also under GPL 3).
\n\
- Veloren is a non-profit community project, and everybody working on it is a volunteer.\n\
If you like what you see, you're welcome to join the development or art teams!
\n\
- 'Voxel RPG' is a genre in its own right. First-person shooters used to be called Doom clones.\n\
Like them, we're trying to build a niche. This game is not a clone, and its development will diverge from existing games in the future.\n\
\n\
Thanks for taking the time to read this notice, we hope you enjoy the game!\n\
\n\
~ The Veloren Devs")
.top_left_with_margins_on(self.ids.disc_window, 110.0, 40.0)
.font_size(26)
.font_id(self.fonts.cyri)
.color(TEXT_COLOR)
.set(self.ids.disc_text_2, ui_widgets);
if Button::image(self.imgs.button)
.w_h(100.0, 30.0)
.mid_bottom_with_margin_on(self.ids.login_error_bg, 10.0)
.w_h(300.0, 50.0)
.mid_bottom_with_margin_on(self.ids.disc_window, 30.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label_y(Relative::Scalar(2.0))
.label(&popup_data.button_text)
.label_font_id(self.fonts.cyri)
.label_font_size(15)
.label("Accept")
.label_font_size(22)
.label_color(TEXT_COLOR)
.set(self.ids.button_ok, ui_widgets)
.label_font_id(self.fonts.cyri)
.set(self.ids.disc_button, ui_widgets)
.was_clicked()
{
match popup_data.popup_type {
PopupType::ConnectionInfo => {
events.push(Event::CancelLoginAttempt);
}
_ => (),
self.show_disclaimer = false;
events.push(Event::DisclaimerClosed);
}
} else {
// TODO: Don't use macros for this?
// Input fields
// Used when the login button is pressed, or enter is pressed within input field
macro_rules! login {
() => {
self.connect = true;
self.connecting = Some(std::time::Instant::now());
self.popup = Some(PopupData {
msg: "Connecting...".to_string(),
button_text: "Cancel".to_string(),
popup_type: PopupType::ConnectionInfo,
});
events.push(Event::LoginAttempt {
username: self.username.clone(),
password: self.password.clone(),
server_address: self.server_address.clone(),
});
};
self.popup = None;
};
}
if self.show_servers {
Image::new(self.imgs.info_frame)
.mid_top_with_margin_on(self.ids.username_bg, -320.0)
.w_h(400.0, 300.0)
.set(self.ids.servers_frame, ui_widgets);
}
// Info Window
Rectangle::fill_with([550.0, 200.0], color::BLACK)
.top_left_with_margins_on(ui_widgets.window, 40.0, 40.0)
.color(Color::Rgba(0.0, 0.0, 0.0, 0.95))
.set(self.ids.info_frame, ui_widgets);
Image::new(self.imgs.banner_bottom)
.mid_bottom_with_margin_on(self.ids.info_frame, -50.0)
.w_h(550.0, 50.0)
.color(Some(Color::Rgba(0.0, 0.0, 0.0, 0.95)))
.set(self.ids.info_bottom, ui_widgets);
Text::new(intro_text)
.top_left_with_margins_on(self.ids.info_frame, 15.0, 15.0)
.font_size(20)
.font_id(self.fonts.cyri)
.color(TEXT_COLOR)
.set(self.ids.info_text, ui_widgets);
let ref mut net_settings = global_state.settings.networking;
// Singleplayer
// Used when the singleplayer button is pressed
#[cfg(feature = "singleplayer")]
macro_rules! singleplayer {
() => {
events.push(Event::StartSingleplayer);
self.connect = true;
self.connecting = Some(std::time::Instant::now());
self.popup = Some(PopupData {
msg: "Creating World...".to_string(),
button_text: "Cancel".to_string(),
popup_type: PopupType::ConnectionInfo,
});
};
}
// TODO: Draw scroll bar or remove it.
let (mut items, _scrollbar) = List::flow_down(net_settings.servers.len())
.top_left_with_margins_on(self.ids.servers_frame, 0.0, 5.0)
.w_h(400.0, 300.0)
.scrollbar_next_to()
.scrollbar_thickness(18.0)
.scrollbar_color(TEXT_COLOR)
.set(self.ids.servers_text, ui_widgets);
while let Some(item) = items.next(ui_widgets) {
let mut text = "".to_string();
if &net_settings.servers[item.i] == &self.server_address {
text.push_str("-> ")
} else {
text.push_str(" ")
// Username
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.97))
.mid_top_with_margin_on(self.ids.banner_top, 160.0)
.set(self.ids.usrnm_bg, ui_widgets);
Image::new(self.imgs.input_bg)
.w_h(337.0, 67.0)
.middle_of(self.ids.usrnm_bg)
.set(self.ids.username_bg, ui_widgets);
for event in TextBox::new(&self.username)
.w_h(290.0, 30.0)
.mid_bottom_with_margin_on(self.ids.username_bg, 44.0 / 2.0)
.font_size(22)
.font_id(self.fonts.cyri)
.text_color(TEXT_COLOR)
// transparent background
.color(TRANSPARENT)
.border_color(TRANSPARENT)
.set(self.ids.username_field, ui_widgets)
{
match event {
TextBoxEvent::Update(username) => {
// Note: TextBox limits the input string length to what fits in it
self.username = username.to_string();
}
TextBoxEvent::Enter => {
login!();
}
}
text.push_str(&net_settings.servers[item.i]);
}
// Password
// TODO: REACTIVATE THIS WHEN A PROPER ACCOUNT SYSTEM IS IN PLACE
/*Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.97))
.down_from(self.ids.usrnm_bg, 30.0)
.set(self.ids.passwd_bg, ui_widgets);
Image::new(self.imgs.input_bg)
.w_h(337.0, 67.0)
.middle_of(self.ids.passwd_bg)
.color(Some(INACTIVE))
.set(self.ids.password_bg, ui_widgets);
for event in TextBox::new(&self.password)
.w_h(290.0, 30.0)
.mid_bottom_with_margin_on(self.ids.password_bg, 44.0 / 2.0)
.font_size(22)
.font_id(self.fonts.cyri)
.text_color(TEXT_COLOR)
// transparent background
.color(TRANSPARENT)
.border_color(TRANSPARENT)
.set(self.ids.password_field, ui_widgets)
{
match event {
TextBoxEvent::Update(password) => {
// Note: TextBox limits the input string length to what fits in it
self.password = password;
}
TextBoxEvent::Enter => {
login!();
}
}
}*/
if self.show_servers {
Image::new(self.imgs.info_frame)
.mid_top_with_margin_on(self.ids.username_bg, -320.0)
.w_h(400.0, 300.0)
.set(self.ids.servers_frame, ui_widgets);
if item
.set(
Button::image(self.imgs.nothing)
.w_h(100.0, 50.0)
.mid_top_with_margin_on(self.ids.servers_frame, 10.0)
//.hover_image(self.imgs.button_hover)
//.press_image(self.imgs.button_press)
.label_y(Relative::Scalar(2.0))
.label(&text)
.label_font_size(20)
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR),
ui_widgets,
)
let ref mut net_settings = global_state.settings.networking;
// TODO: Draw scroll bar or remove it.
let (mut items, _scrollbar) = List::flow_down(net_settings.servers.len())
.top_left_with_margins_on(self.ids.servers_frame, 0.0, 5.0)
.w_h(400.0, 300.0)
.scrollbar_next_to()
.scrollbar_thickness(18.0)
.scrollbar_color(TEXT_COLOR)
.set(self.ids.servers_text, ui_widgets);
while let Some(item) = items.next(ui_widgets) {
let mut text = "".to_string();
if &net_settings.servers[item.i] == &self.server_address {
text.push_str("-> ")
} else {
text.push_str(" ")
}
text.push_str(&net_settings.servers[item.i]);
if item
.set(
Button::image(self.imgs.nothing)
.w_h(100.0, 50.0)
.mid_top_with_margin_on(self.ids.servers_frame, 10.0)
//.hover_image(self.imgs.button_hover)
//.press_image(self.imgs.button_press)
.label_y(Relative::Scalar(2.0))
.label(&text)
.label_font_size(20)
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR),
ui_widgets,
)
.was_clicked()
{
self.server_address = net_settings.servers[item.i].clone();
net_settings.default_server = item.i;
}
}
if Button::image(self.imgs.button)
.w_h(200.0, 53.0)
.mid_bottom_with_margin_on(self.ids.servers_frame, 5.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label_y(Relative::Scalar(2.0))
.label("Close")
.label_font_size(20)
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.set(self.ids.servers_close, ui_widgets)
.was_clicked()
{
self.server_address = net_settings.servers[item.i].clone();
net_settings.default_server = item.i;
}
self.show_servers = false
};
}
if Button::image(self.imgs.button)
.w_h(200.0, 53.0)
.mid_bottom_with_margin_on(self.ids.servers_frame, 5.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label_y(Relative::Scalar(2.0))
.label("Close")
.label_font_size(20)
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.set(self.ids.servers_close, ui_widgets)
.was_clicked()
// Server address
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.97))
.down_from(self.ids.usrnm_bg, 30.0)
.set(self.ids.srvr_bg, ui_widgets);
Image::new(self.imgs.input_bg)
.w_h(337.0, 67.0)
.middle_of(self.ids.srvr_bg)
.set(self.ids.address_bg, ui_widgets);
for event in TextBox::new(&self.server_address)
.w_h(290.0, 30.0)
.mid_bottom_with_margin_on(self.ids.address_bg, 44.0 / 2.0)
.font_size(22)
.font_id(self.fonts.cyri)
.text_color(TEXT_COLOR)
// transparent background
.color(TRANSPARENT)
.border_color(TRANSPARENT)
.set(self.ids.address_field, ui_widgets)
{
self.show_servers = false
};
}
// Server address
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.97))
.down_from(self.ids.usrnm_bg, 30.0)
.set(self.ids.srvr_bg, ui_widgets);
Image::new(self.imgs.input_bg)
.w_h(337.0, 67.0)
.middle_of(self.ids.srvr_bg)
.set(self.ids.address_bg, ui_widgets);
for event in TextBox::new(&self.server_address)
.w_h(290.0, 30.0)
.mid_bottom_with_margin_on(self.ids.address_bg, 44.0 / 2.0)
.font_size(22)
.font_id(self.fonts.cyri)
.text_color(TEXT_COLOR)
// transparent background
.color(TRANSPARENT)
.border_color(TRANSPARENT)
.set(self.ids.address_field, ui_widgets)
{
match event {
TextBoxEvent::Update(server_address) => {
self.server_address = server_address.to_string();
}
TextBoxEvent::Enter => {
login!();
match event {
TextBoxEvent::Update(server_address) => {
self.server_address = server_address.to_string();
}
TextBoxEvent::Enter => {
login!();
}
}
}
}
// Login button
if Button::image(self.imgs.button)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.w_h(258.0, 55.0)
.down_from(self.ids.address_bg, 20.0)
.align_middle_x_of(self.ids.address_bg)
.label("Multiplayer")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.label_font_size(22)
.label_y(Relative::Scalar(5.0))
/*.with_tooltip(
tooltip_manager,
"Login",
"Click to login with the entered details",
&tooltip,
)
.tooltip_image(self.imgs.v_logo)*/
.set(self.ids.login_button, ui_widgets)
.was_clicked()
{
login!();
}
// Singleplayer button
#[cfg(feature = "singleplayer")]
{
// Login button
if Button::image(self.imgs.button)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.w_h(258.0, 55.0)
.down_from(self.ids.login_button, 20.0)
.down_from(self.ids.address_bg, 20.0)
.align_middle_x_of(self.ids.address_bg)
.label("Singleplayer")
.label("Multiplayer")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.label_font_size(22)
.label_y(Relative::Scalar(5.0))
.label_x(Relative::Scalar(2.0))
.set(self.ids.singleplayer_button, ui_widgets)
/*.with_tooltip(
tooltip_manager,
"Login",
"Click to login with the entered details",
&tooltip,
)
.tooltip_image(self.imgs.v_logo)*/
.set(self.ids.login_button, ui_widgets)
.was_clicked()
{
singleplayer!();
login!();
}
}
// Quit
if Button::image(self.imgs.button)
.w_h(190.0, 40.0)
.bottom_left_with_margins_on(ui_widgets.window, 60.0, 30.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label("Quit")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.label_font_size(20)
.label_y(Relative::Scalar(3.0))
.set(self.ids.quit_button, ui_widgets)
.was_clicked()
{
events.push(Event::Quit);
}
// Settings
if Button::image(self.imgs.button)
.w_h(190.0, 40.0)
.up_from(self.ids.quit_button, 8.0)
//.hover_image(self.imgs.button_hover)
//.press_image(self.imgs.button_press)
.label("Settings")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR_2)
.label_font_size(20)
.label_y(Relative::Scalar(3.0))
.set(self.ids.settings_button, ui_widgets)
.was_clicked()
{
events.push(Event::Settings);
}
// Singleplayer button
#[cfg(feature = "singleplayer")]
{
if Button::image(self.imgs.button)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.w_h(258.0, 55.0)
.down_from(self.ids.login_button, 20.0)
.align_middle_x_of(self.ids.address_bg)
.label("Singleplayer")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.label_font_size(22)
.label_y(Relative::Scalar(5.0))
.label_x(Relative::Scalar(2.0))
.set(self.ids.singleplayer_button, ui_widgets)
.was_clicked()
{
singleplayer!();
}
}
// Quit
if Button::image(self.imgs.button)
.w_h(190.0, 40.0)
.bottom_left_with_margins_on(ui_widgets.window, 60.0, 30.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label("Quit")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.label_font_size(20)
.label_y(Relative::Scalar(3.0))
.set(self.ids.quit_button, ui_widgets)
.was_clicked()
{
events.push(Event::Quit);
}
// Servers
if Button::image(self.imgs.button)
.w_h(190.0, 40.0)
.up_from(self.ids.settings_button, 8.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label("Servers")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.label_font_size(20)
.label_y(Relative::Scalar(3.0))
.set(self.ids.servers_button, ui_widgets)
.was_clicked()
{
self.show_servers = !self.show_servers;
};
// Settings
if Button::image(self.imgs.button)
.w_h(190.0, 40.0)
.up_from(self.ids.quit_button, 8.0)
//.hover_image(self.imgs.button_hover)
//.press_image(self.imgs.button_press)
.label("Settings")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR_2)
.label_font_size(20)
.label_y(Relative::Scalar(3.0))
.set(self.ids.settings_button, ui_widgets)
.was_clicked()
{
events.push(Event::Settings);
}
// Servers
if Button::image(self.imgs.button)
.w_h(190.0, 40.0)
.up_from(self.ids.settings_button, 8.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label("Servers")
.label_font_id(self.fonts.cyri)
.label_color(TEXT_COLOR)
.label_font_size(20)
.label_y(Relative::Scalar(3.0))
.set(self.ids.servers_button, ui_widgets)
.was_clicked()
{
self.show_servers = !self.show_servers;
};
}
}
events
@ -657,24 +691,27 @@ impl MainMenuUi {
popup_type: PopupType::Error,
});
self.connecting = None;
self.connect = false;
}
pub fn connected(&mut self) {
self.popup = None;
self.connecting = None;
self.connect = false;
}
pub fn cancel_connection(&mut self) {
self.popup = None;
self.connecting = None;
self.connect = false;
}
pub fn handle_event(&mut self, event: ui::Event) {
self.ui.handle_event(event);
}
pub fn maintain(&mut self, global_state: &mut GlobalState) -> Vec<Event> {
let events = self.update_layout(global_state);
pub fn maintain(&mut self, global_state: &mut GlobalState, dt: Duration) -> Vec<Event> {
let events = self.update_layout(global_state, dt);
self.ui.maintain(global_state.window.renderer_mut(), None);
events
}