mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
add char selection playstate
Former-commit-id: 1d97cf90686532cb354d12f79a129a0a9c7fde98
This commit is contained in:
parent
03b20fa1bd
commit
d82adb7e71
@ -9,8 +9,8 @@ use conrod_core::{
|
||||
event::Input,
|
||||
image::Id as ImgId,
|
||||
text::font::Id as FontId,
|
||||
widget::{text_box::Event as TextBoxEvent, Button, Canvas, Image, TextBox, Text, TitleBar},
|
||||
widget_ids, Borderable, Color,
|
||||
widget::{Button, Image, Text, TitleBar},
|
||||
widget_ids, Borderable,
|
||||
Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||
};
|
||||
|
||||
@ -374,8 +374,8 @@ impl Hud {
|
||||
}
|
||||
|
||||
fn update_layout(&mut self) -> Vec<Event> {
|
||||
let ref mut ui_widgets = self.ui.set_widgets();
|
||||
let mut events = Vec::new();
|
||||
let ref mut ui_widgets = self.ui.set_widgets();
|
||||
|
||||
// Chat box
|
||||
if let Some(msg) = self.chat.update_layout(ui_widgets) {
|
||||
|
83
voxygen/src/menu/char_selection/mod.rs
Normal file
83
voxygen/src/menu/char_selection/mod.rs
Normal file
@ -0,0 +1,83 @@
|
||||
mod ui;
|
||||
|
||||
use crate::{
|
||||
window::{Event, Window},
|
||||
session::SessionState,
|
||||
GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use common::clock::Clock;
|
||||
use std::time::Duration;
|
||||
use ui::CharSelectionUi;
|
||||
use vek::*;
|
||||
|
||||
const FPS: u64 = 60;
|
||||
|
||||
pub struct CharSelectionState {
|
||||
char_selection_ui: CharSelectionUi,
|
||||
}
|
||||
|
||||
impl CharSelectionState {
|
||||
/// Create a new `CharSelectionState`
|
||||
pub fn new(window: &mut Window) -> Self {
|
||||
Self {
|
||||
char_selection_ui: CharSelectionUi::new(window),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The background colour
|
||||
const BG_COLOR: Rgba<f32> = Rgba {
|
||||
r: 0.0,
|
||||
g: 0.3,
|
||||
b: 1.0,
|
||||
a: 1.0,
|
||||
};
|
||||
|
||||
impl PlayState for CharSelectionState {
|
||||
fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
// Set up an fps clock
|
||||
let mut clock = Clock::new();
|
||||
|
||||
loop {
|
||||
// Handle window events
|
||||
for event in global_state.window.fetch_events() {
|
||||
match event {
|
||||
Event::Close => return PlayStateResult::Shutdown,
|
||||
// When any key is pressed, go to the main menu
|
||||
Event::Char(_) =>
|
||||
return PlayStateResult::Push(
|
||||
Box::new(SessionState::new(&mut global_state.window).unwrap()) // TODO: Handle this error
|
||||
),
|
||||
// Pass events to ui
|
||||
Event::UiEvent(input) => {
|
||||
self.char_selection_ui.handle_event(input);
|
||||
}
|
||||
// Ignore all other events
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
global_state.window.renderer_mut().clear(BG_COLOR);
|
||||
|
||||
// Maintain the UI
|
||||
self.char_selection_ui.maintain(global_state.window.renderer_mut());
|
||||
|
||||
// Draw the UI to the screen
|
||||
self.char_selection_ui.render(global_state.window.renderer_mut());
|
||||
|
||||
// Finish the frame
|
||||
global_state.window.renderer_mut().flush();
|
||||
global_state
|
||||
.window
|
||||
.swap_buffers()
|
||||
.expect("Failed to swap window buffers");
|
||||
|
||||
// Wait for the next tick
|
||||
clock.tick(Duration::from_millis(1000 / FPS));
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Title"
|
||||
}
|
||||
}
|
51
voxygen/src/menu/char_selection/ui.rs
Normal file
51
voxygen/src/menu/char_selection/ui.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use crate::{render::Renderer, ui::Ui, window::Window};
|
||||
use conrod_core::{
|
||||
event::Input,
|
||||
image::Id as ImgId,
|
||||
widget::{Id as WidgId, Image as ImageWidget},
|
||||
Positionable, Widget,
|
||||
};
|
||||
|
||||
pub struct CharSelectionUi {
|
||||
ui: Ui,
|
||||
widget_id: WidgId,
|
||||
splash_img_id: ImgId,
|
||||
}
|
||||
|
||||
impl CharSelectionUi {
|
||||
pub fn new(window: &mut Window) -> Self {
|
||||
let mut ui = Ui::new(window).unwrap();
|
||||
let widget_id = ui.id_generator().next();
|
||||
let image = image::open(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/test_assets/ui/char_selection/splash.png"
|
||||
))
|
||||
.unwrap();
|
||||
let splash_img_id = ui.new_image(window.renderer_mut(), &image).unwrap();
|
||||
Self {
|
||||
ui,
|
||||
widget_id,
|
||||
splash_img_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn ui_layout(&mut self) {
|
||||
let mut ui_cell = self.ui.set_widgets();
|
||||
ImageWidget::new(self.splash_img_id)
|
||||
.top_left()
|
||||
.set(self.widget_id, &mut ui_cell);
|
||||
}
|
||||
|
||||
pub fn handle_event(&mut self, input: Input) {
|
||||
self.ui.handle_event(input);
|
||||
}
|
||||
|
||||
pub fn maintain(&mut self, renderer: &mut Renderer) {
|
||||
self.ui_layout();
|
||||
self.ui.maintain(renderer);
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
self.ui.render(renderer);
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
mod ui;
|
||||
|
||||
use super::char_selection::CharSelectionState;
|
||||
use crate::{
|
||||
session::SessionState,
|
||||
window::{Event, Window},
|
||||
GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use common::clock::Clock;
|
||||
use std::time::Duration;
|
||||
use ui::MainMenuUi;
|
||||
use ui::{Event as MainMenuEvent, MainMenuUi};
|
||||
use vek::*;
|
||||
|
||||
const FPS: u64 = 60;
|
||||
@ -55,14 +55,15 @@ impl PlayState for MainMenuState {
|
||||
global_state.window.renderer_mut().clear(BG_COLOR);
|
||||
|
||||
// Maintain the UI
|
||||
self.main_menu_ui
|
||||
.maintain(global_state.window.renderer_mut());
|
||||
// Check if there should be a login attempt
|
||||
if let Some((username, address)) = self.main_menu_ui.login_attempt() {
|
||||
// For now just start a new session
|
||||
return PlayStateResult::Push(
|
||||
Box::new(SessionState::new(&mut global_state.window).unwrap()) // TODO: Handle this error
|
||||
);
|
||||
for event in self.main_menu_ui.maintain(global_state.window.renderer_mut()) {
|
||||
match event {
|
||||
MainMenuEvent::LoginAttempt{ username, server_address } =>
|
||||
// For now just start a new session
|
||||
return PlayStateResult::Push(
|
||||
Box::new(CharSelectionState::new(&mut global_state.window))
|
||||
),
|
||||
MainMenuEvent::Quit => return PlayStateResult::Shutdown,
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the UI to the screen
|
||||
|
@ -2,16 +2,14 @@ use crate::{
|
||||
render::Renderer,
|
||||
ui::{ScaleMode, Ui},
|
||||
window::Window,
|
||||
Error, GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use conrod_core::{
|
||||
color::TRANSPARENT,
|
||||
event::Input,
|
||||
image::Id as ImgId,
|
||||
text::font::Id as FontId,
|
||||
widget::{text_box::Event as TextBoxEvent, Button, Canvas, Image, TextBox},
|
||||
widget::{text_box::Event as TextBoxEvent, Button, Image, TextBox},
|
||||
widget_ids, Borderable, Color,
|
||||
Color::Rgba,
|
||||
Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||
};
|
||||
|
||||
@ -34,32 +32,21 @@ widget_ids! {
|
||||
singleplayer_text,
|
||||
// Buttons
|
||||
servers_button,
|
||||
servers_text,
|
||||
settings_button,
|
||||
settings_text,
|
||||
quit_button,
|
||||
quit_text,
|
||||
}
|
||||
}
|
||||
|
||||
struct Imgs {
|
||||
bg: ImgId,
|
||||
v_logo: ImgId,
|
||||
alpha_version: ImgId,
|
||||
|
||||
address_text: ImgId,
|
||||
username_text: ImgId,
|
||||
input_bg: ImgId,
|
||||
|
||||
login_text: ImgId,
|
||||
login_button: ImgId,
|
||||
login_button_hover: ImgId,
|
||||
login_button_press: ImgId,
|
||||
singleplayer_text: ImgId,
|
||||
|
||||
servers_text: ImgId,
|
||||
settings_text: ImgId,
|
||||
quit_text: ImgId,
|
||||
button: ImgId,
|
||||
button_hover: ImgId,
|
||||
button_press: ImgId,
|
||||
@ -81,24 +68,16 @@ impl Imgs {
|
||||
Imgs {
|
||||
bg: load("bg.png"),
|
||||
v_logo: load("v_logo.png"),
|
||||
alpha_version: load("text/a01.png"),
|
||||
|
||||
// Input fields
|
||||
address_text: load("text/server_address.png"),
|
||||
username_text: load("text/username.png"),
|
||||
input_bg: load("input_bg.png"),
|
||||
|
||||
// Login button
|
||||
login_text: load("text/login.png"),
|
||||
singleplayer_text: load("text/singleplayer.png"),
|
||||
login_button: load("buttons/button_login.png"),
|
||||
login_button_hover: load("buttons/button_login_hover.png"),
|
||||
login_button_press: load("buttons/button_login_press.png"),
|
||||
|
||||
// Servers, settings, and quit buttons
|
||||
servers_text: load("text/servers.png"),
|
||||
settings_text: load("text/settings.png"),
|
||||
quit_text: load("text/quit.png"),
|
||||
button: load("buttons/button.png"),
|
||||
button_hover: load("buttons/button_hover.png"),
|
||||
button_press: load("buttons/button_press.png"),
|
||||
@ -106,6 +85,14 @@ impl Imgs {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Event {
|
||||
LoginAttempt {
|
||||
username: String,
|
||||
server_address: String,
|
||||
},
|
||||
Quit,
|
||||
}
|
||||
|
||||
pub struct MainMenuUi {
|
||||
ui: Ui,
|
||||
ids: Ids,
|
||||
@ -114,7 +101,6 @@ pub struct MainMenuUi {
|
||||
font_whitney: FontId,
|
||||
username: String,
|
||||
server_address: String,
|
||||
attempt_login: bool,
|
||||
}
|
||||
|
||||
impl MainMenuUi {
|
||||
@ -149,21 +135,11 @@ impl MainMenuUi {
|
||||
font_whitney,
|
||||
username: "Username".to_string(),
|
||||
server_address: "Server Address".to_string(),
|
||||
attempt_login: false,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: probably a better way to do this
|
||||
pub fn login_attempt(&mut self) -> Option<(String, String)> {
|
||||
if self.attempt_login {
|
||||
self.attempt_login = false;
|
||||
Some((self.username.clone(), self.server_address.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn update_layout(&mut self) {
|
||||
fn update_layout(&mut self) -> Vec<Event> {
|
||||
let mut events = Vec::new();
|
||||
let ref mut ui_widgets = self.ui.set_widgets();
|
||||
// Background image, Veloren logo, Alpha-Version Label
|
||||
Image::new(self.imgs.bg)
|
||||
@ -183,7 +159,10 @@ impl MainMenuUi {
|
||||
// Used when the login button is pressed, or enter is pressed within input field
|
||||
macro_rules! login {
|
||||
() => {
|
||||
self.attempt_login = true;
|
||||
events.push(Event::LoginAttempt {
|
||||
username: self.username.clone(),
|
||||
server_address: self.server_address.clone(),
|
||||
});
|
||||
};
|
||||
}
|
||||
// Username
|
||||
@ -281,8 +260,7 @@ impl MainMenuUi {
|
||||
.set(self.ids.quit_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
use PlayStateResult::Shutdown;
|
||||
PlayStateResult::Pop;
|
||||
events.push(Event::Quit);
|
||||
};
|
||||
// Settings
|
||||
if Button::image(self.imgs.button)
|
||||
@ -310,15 +288,18 @@ impl MainMenuUi {
|
||||
.set(self.ids.servers_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{};
|
||||
|
||||
events
|
||||
}
|
||||
|
||||
pub fn handle_event(&mut self, input: Input) {
|
||||
self.ui.handle_event(input);
|
||||
}
|
||||
|
||||
pub fn maintain(&mut self, renderer: &mut Renderer) {
|
||||
self.update_layout();
|
||||
pub fn maintain(&mut self, renderer: &mut Renderer) -> Vec<Event> {
|
||||
let events = self.update_layout();
|
||||
self.ui.maintain(renderer);
|
||||
events
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
|
@ -1,2 +1,3 @@
|
||||
pub mod char_selection;
|
||||
pub mod main;
|
||||
pub mod title;
|
||||
|
1
voxygen/test_assets/ui/char_selection/.gitattributes
vendored
Normal file
1
voxygen/test_assets/ui/char_selection/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
BIN
voxygen/test_assets/ui/char_selection/splash.png
(Stored with Git LFS)
Normal file
BIN
voxygen/test_assets/ui/char_selection/splash.png
(Stored with Git LFS)
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user