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

View File

@ -332,10 +332,10 @@ impl Race {
match (self, body_type) { match (self, body_type) {
(Race::Danari, BodyType::Female) => 2, (Race::Danari, BodyType::Female) => 2,
(Race::Danari, BodyType::Male) => 2, (Race::Danari, BodyType::Male) => 2,
(Race::Dwarf, BodyType::Female) => 1, (Race::Dwarf, BodyType::Female) => 2,
(Race::Dwarf, BodyType::Male) => 3, (Race::Dwarf, BodyType::Male) => 3,
(Race::Elf, BodyType::Female) => 21, (Race::Elf, BodyType::Female) => 21,
(Race::Elf, BodyType::Male) => 3, (Race::Elf, BodyType::Male) => 4,
(Race::Human, BodyType::Female) => 19, (Race::Human, BodyType::Female) => 19,
(Race::Human, BodyType::Male) => 17, (Race::Human, BodyType::Male) => 17,
(Race::Orc, BodyType::Female) => 1, (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()); global_state.maintain(clock.get_last_delta().as_secs_f32());
// Maintain the UI. // 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 { match event {
MainMenuEvent::LoginAttempt { MainMenuEvent::LoginAttempt {
username, username,

View File

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