mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'ui' into 'master'
Key commands, bag changes See merge request veloren/veloren!16 Former-commit-id: fd08a4a51272c82ff5007cbb88c65efe8b959de2
This commit is contained in:
commit
1dee192e5b
4
.gitignore
vendored
4
.gitignore
vendored
@ -20,3 +20,7 @@
|
|||||||
**/server_conf.toml
|
**/server_conf.toml
|
||||||
**/keybinds.toml
|
**/keybinds.toml
|
||||||
assets/voxygen
|
assets/voxygen
|
||||||
|
UI3.rar
|
||||||
|
assets.rar
|
||||||
|
*.rar
|
||||||
|
assets/voxygen
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
pub mod data;
|
pub mod data;
|
||||||
pub mod error;
|
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod postbox;
|
|
||||||
pub mod postoffice;
|
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use self::{
|
pub use self::{
|
||||||
|
@ -116,7 +116,7 @@ impl<S: PostSend, R: PostRecv> PostOffice<S, R> {
|
|||||||
pub fn new_connections(&mut self) -> impl ExactSizeIterator<Item=PostBox<S, R>> {
|
pub fn new_connections(&mut self) -> impl ExactSizeIterator<Item=PostBox<S, R>> {
|
||||||
let mut conns = VecDeque::new();
|
let mut conns = VecDeque::new();
|
||||||
|
|
||||||
if let Some(_) = self.err {
|
if self.err.is_some() {
|
||||||
return conns.into_iter();
|
return conns.into_iter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ impl<S: PostSend, R: PostRecv> PostOffice<S, R> {
|
|||||||
for event in events {
|
for event in events {
|
||||||
match event.token() {
|
match event.token() {
|
||||||
// Keep reading new postboxes from the channel
|
// Keep reading new postboxes from the channel
|
||||||
POSTBOX_TOKEN => loop {
|
POSTBOX_TOK => loop {
|
||||||
match self.postbox_rx.try_recv() {
|
match self.postbox_rx.try_recv() {
|
||||||
Ok(Ok(conn)) => conns.push_back(conn),
|
Ok(Ok(conn)) => conns.push_back(conn),
|
||||||
Err(TryRecvError::Empty) => break,
|
Err(TryRecvError::Empty) => break,
|
||||||
@ -141,7 +141,7 @@ impl<S: PostSend, R: PostRecv> PostOffice<S, R> {
|
|||||||
return conns.into_iter();
|
return conns.into_iter();
|
||||||
},
|
},
|
||||||
Ok(Err(err)) => {
|
Ok(Err(err)) => {
|
||||||
self.err = Some(err.into());
|
self.err = Some(err);
|
||||||
return conns.into_iter();
|
return conns.into_iter();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ pub struct PostBox<S: PostSend, R: PostRecv> {
|
|||||||
|
|
||||||
impl<S: PostSend, R: PostRecv> PostBox<S, R> {
|
impl<S: PostSend, R: PostRecv> PostBox<S, R> {
|
||||||
pub fn to_server<A: Into<SocketAddr>>(addr: A) -> Result<Self, Error> {
|
pub fn to_server<A: Into<SocketAddr>>(addr: A) -> Result<Self, Error> {
|
||||||
Self::from_tcpstream(TcpStream::connect(&addr.into())?)
|
Self::from_tcpstream(TcpStream::from_stream(std::net::TcpStream::connect(&addr.into())?)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_tcpstream(tcp_stream: TcpStream) -> Result<Self, Error> {
|
fn from_tcpstream(tcp_stream: TcpStream) -> Result<Self, Error> {
|
||||||
@ -254,7 +254,7 @@ impl<S: PostSend, R: PostRecv> PostBox<S, R> {
|
|||||||
pub fn new_messages(&mut self) -> impl ExactSizeIterator<Item=R> {
|
pub fn new_messages(&mut self) -> impl ExactSizeIterator<Item=R> {
|
||||||
let mut msgs = VecDeque::new();
|
let mut msgs = VecDeque::new();
|
||||||
|
|
||||||
if let Some(_) = self.err {
|
if self.err.is_some() {
|
||||||
return msgs.into_iter();
|
return msgs.into_iter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ impl<S: PostSend, R: PostRecv> PostBox<S, R> {
|
|||||||
for event in events {
|
for event in events {
|
||||||
match event.token() {
|
match event.token() {
|
||||||
// Keep reading new messages from the channel
|
// Keep reading new messages from the channel
|
||||||
RECV_TOKEN => loop {
|
RECV_TOK => loop {
|
||||||
match self.recv_rx.try_recv() {
|
match self.recv_rx.try_recv() {
|
||||||
Ok(Ok(msg)) => msgs.push_back(msg),
|
Ok(Ok(msg)) => msgs.push_back(msg),
|
||||||
Err(TryRecvError::Empty) => break,
|
Err(TryRecvError::Empty) => break,
|
||||||
@ -279,7 +279,7 @@ impl<S: PostSend, R: PostRecv> PostBox<S, R> {
|
|||||||
return msgs.into_iter();
|
return msgs.into_iter();
|
||||||
},
|
},
|
||||||
Ok(Err(err)) => {
|
Ok(Err(err)) => {
|
||||||
self.err = Some(err.into());
|
self.err = Some(err);
|
||||||
return msgs.into_iter();
|
return msgs.into_iter();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -322,17 +322,16 @@ fn postbox_worker<S: PostSend, R: PostRecv>(
|
|||||||
|
|
||||||
for event in &events {
|
for event in &events {
|
||||||
match event.token() {
|
match event.token() {
|
||||||
CTRL_TOK => loop {
|
CTRL_TOK =>
|
||||||
match ctrl_rx.try_recv() {
|
match ctrl_rx.try_recv() {
|
||||||
Ok(CtrlMsg::Shutdown) => {
|
Ok(CtrlMsg::Shutdown) => {
|
||||||
break 'work;
|
break 'work;
|
||||||
},
|
},
|
||||||
Err(TryRecvError::Empty) => break,
|
Err(TryRecvError::Empty) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
recv_tx.send(Err(err.into()))?;
|
recv_tx.send(Err(err.into()))?;
|
||||||
break 'work;
|
break 'work;
|
||||||
},
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
SEND_TOK => loop {
|
SEND_TOK => loop {
|
||||||
match send_rx.try_recv() {
|
match send_rx.try_recv() {
|
||||||
@ -340,7 +339,7 @@ fn postbox_worker<S: PostSend, R: PostRecv>(
|
|||||||
let mut msg_bytes = match bincode::serialize(&outgoing_msg) {
|
let mut msg_bytes = match bincode::serialize(&outgoing_msg) {
|
||||||
Ok(bytes) => bytes,
|
Ok(bytes) => bytes,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
recv_tx.send(Err((*err).into()));
|
recv_tx.send(Err((*err).into()))?;
|
||||||
break 'work;
|
break 'work;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -355,7 +354,7 @@ fn postbox_worker<S: PostSend, R: PostRecv>(
|
|||||||
match tcp_stream.write_all(&packet) {
|
match tcp_stream.write_all(&packet) {
|
||||||
Ok(()) => {},
|
Ok(()) => {},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
recv_tx.send(Err(err.into()));
|
recv_tx.send(Err(err.into()))?;
|
||||||
break 'work;
|
break 'work;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -368,11 +367,11 @@ fn postbox_worker<S: PostSend, R: PostRecv>(
|
|||||||
match tcp_stream.take_error() {
|
match tcp_stream.take_error() {
|
||||||
Ok(None) => {},
|
Ok(None) => {},
|
||||||
Ok(Some(err)) => {
|
Ok(Some(err)) => {
|
||||||
recv_tx.send(Err(err.into()));
|
recv_tx.send(Err(err.into()))?;
|
||||||
break 'work;
|
break 'work;
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
recv_tx.send(Err(err.into()));
|
recv_tx.send(Err(err.into()))?;
|
||||||
break 'work;
|
break 'work;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -380,7 +379,7 @@ fn postbox_worker<S: PostSend, R: PostRecv>(
|
|||||||
RecvState::ReadHead(head) => if head.len() == 8 {
|
RecvState::ReadHead(head) => if head.len() == 8 {
|
||||||
let len = usize::from_le_bytes(<[u8; 8]>::try_from(head.as_slice()).unwrap());
|
let len = usize::from_le_bytes(<[u8; 8]>::try_from(head.as_slice()).unwrap());
|
||||||
if len > MAX_MSG_BYTES {
|
if len > MAX_MSG_BYTES {
|
||||||
recv_tx.send(Err(Error::InvalidMsg));
|
recv_tx.send(Err(Error::InvalidMsg))?;
|
||||||
break 'work;
|
break 'work;
|
||||||
} else if len == 0 {
|
} else if len == 0 {
|
||||||
recv_state = RecvState::ReadHead(Vec::with_capacity(8));
|
recv_state = RecvState::ReadHead(Vec::with_capacity(8));
|
||||||
@ -427,7 +426,7 @@ fn postbox_worker<S: PostSend, R: PostRecv>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp_stream.shutdown(Shutdown::Both);
|
tcp_stream.shutdown(Shutdown::Both)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,6 +452,21 @@ fn connect() {
|
|||||||
assert_eq!(postoffice.error(), None);
|
assert_eq!(postoffice.error(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn connect_fail() {
|
||||||
|
let listen_addr = ([0; 4], 12345);
|
||||||
|
let connect_addr = ([127, 0, 0, 1], 12212);
|
||||||
|
|
||||||
|
let mut postoffice = PostOffice::<u32, f32>::bind(listen_addr).unwrap();
|
||||||
|
|
||||||
|
// We should start off with 0 incoming connections
|
||||||
|
thread::sleep(Duration::from_millis(250));
|
||||||
|
assert_eq!(postoffice.new_connections().len(), 0);
|
||||||
|
assert_eq!(postoffice.error(), None);
|
||||||
|
|
||||||
|
assert!(PostBox::<f32, u32>::to_server(connect_addr).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn connection_count() {
|
fn connection_count() {
|
||||||
let srv_addr = ([127, 0, 0, 1], 12346);
|
let srv_addr = ([127, 0, 0, 1], 12346);
|
||||||
@ -469,7 +483,7 @@ fn connection_count() {
|
|||||||
postboxes.push(PostBox::<f32, u32>::to_server(srv_addr).unwrap());
|
postboxes.push(PostBox::<f32, u32>::to_server(srv_addr).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10 postboxes created, we should have 10
|
// 5 postboxes created, we should have 5
|
||||||
thread::sleep(Duration::from_millis(3500));
|
thread::sleep(Duration::from_millis(3500));
|
||||||
let incoming = postoffice.new_connections();
|
let incoming = postoffice.new_connections();
|
||||||
assert_eq!(incoming.len(), 5);
|
assert_eq!(incoming.len(), 5);
|
||||||
|
@ -50,17 +50,11 @@ impl Chat {
|
|||||||
// (i.e. the player is viewing new messages)
|
// (i.e. the player is viewing new messages)
|
||||||
// If so scroll down when new messages are added
|
// If so scroll down when new messages are added
|
||||||
fn scroll_new_messages(&self, ui_widgets: &mut UiCell) {
|
fn scroll_new_messages(&self, ui_widgets: &mut UiCell) {
|
||||||
if let Some(scroll) = ui_widgets
|
|
||||||
.widget_graph()
|
|
||||||
.widget(self.ids.message_box)
|
|
||||||
.and_then(|widget| widget.maybe_y_scroll_state)
|
|
||||||
{
|
|
||||||
// If previously scrolled to the bottom stay there
|
// If previously scrolled to the bottom stay there
|
||||||
if self.scrolled_to_bottom(ui_widgets) {
|
if self.scrolled_to_bottom(ui_widgets) {
|
||||||
self.scroll_to_bottom(ui_widgets);
|
self.scroll_to_bottom(ui_widgets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
fn scrolled_to_bottom(&self, ui_widgets: &UiCell) -> bool {
|
fn scrolled_to_bottom(&self, ui_widgets: &UiCell) -> bool {
|
||||||
// could be more efficient to cache result and update it when a scroll event has occurred instead of every frame
|
// could be more efficient to cache result and update it when a scroll event has occurred instead of every frame
|
||||||
if let Some(scroll) = ui_widgets
|
if let Some(scroll) = ui_widgets
|
||||||
@ -76,7 +70,7 @@ impl Chat {
|
|||||||
fn scroll_to_bottom(&self, ui_widgets: &mut UiCell) {
|
fn scroll_to_bottom(&self, ui_widgets: &mut UiCell) {
|
||||||
ui_widgets.scroll_widget(self.ids.message_box, [0.0, std::f64::MAX]);
|
ui_widgets.scroll_widget(self.ids.message_box, [0.0, std::f64::MAX]);
|
||||||
}
|
}
|
||||||
pub fn update_layout(&mut self, ui_widgets: &mut UiCell, font: FontId, imgs: &super::Imgs) -> Option<String> {
|
pub(super) fn update_layout(&mut self, ui_widgets: &mut UiCell, font: FontId, imgs: &super::Imgs) -> Option<String> {
|
||||||
// Maintain scrolling
|
// Maintain scrolling
|
||||||
if self.new_messages {
|
if self.new_messages {
|
||||||
self.scroll_new_messages(ui_widgets);
|
self.scroll_new_messages(ui_widgets);
|
||||||
@ -123,7 +117,7 @@ impl Chat {
|
|||||||
Text::new(&self.messages[item.i])
|
Text::new(&self.messages[item.i])
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.font_id(font)
|
.font_id(font)
|
||||||
.rgba(220.0, 220.0, 220.0, 1.0),
|
.rgba(0.86 , 0.86, 0.86, 1.0),
|
||||||
ui_widgets,
|
ui_widgets,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,9 @@ use crate::{
|
|||||||
session::SessionState,
|
session::SessionState,
|
||||||
GlobalState, PlayState, PlayStateResult,
|
GlobalState, PlayState, PlayStateResult,
|
||||||
};
|
};
|
||||||
|
use client::{self, Client};
|
||||||
use common::clock::Clock;
|
use common::clock::Clock;
|
||||||
use std::time::Duration;
|
use std::{cell::RefCell, rc::Rc, time::Duration};
|
||||||
use ui::CharSelectionUi;
|
use ui::CharSelectionUi;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -14,13 +15,15 @@ const FPS: u64 = 60;
|
|||||||
|
|
||||||
pub struct CharSelectionState {
|
pub struct CharSelectionState {
|
||||||
char_selection_ui: CharSelectionUi,
|
char_selection_ui: CharSelectionUi,
|
||||||
|
client: Rc<RefCell<Client>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharSelectionState {
|
impl CharSelectionState {
|
||||||
/// Create a new `CharSelectionState`
|
/// Create a new `CharSelectionState`
|
||||||
pub fn new(window: &mut Window) -> Self {
|
pub fn new(window: &mut Window, client: Rc<RefCell<Client>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
char_selection_ui: CharSelectionUi::new(window),
|
char_selection_ui: CharSelectionUi::new(window),
|
||||||
|
client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +62,7 @@ impl PlayState for CharSelectionState {
|
|||||||
match event {
|
match event {
|
||||||
ui::Event::Logout => return PlayStateResult::Pop,
|
ui::Event::Logout => return PlayStateResult::Pop,
|
||||||
ui::Event::Play => return PlayStateResult::Push(
|
ui::Event::Play => return PlayStateResult::Push(
|
||||||
Box::new(SessionState::new(&mut global_state.window).unwrap()) // TODO: Handle this error
|
Box::new(SessionState::new(&mut global_state.window, self.client.clone()))
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,6 +70,11 @@ impl PlayState for CharSelectionState {
|
|||||||
// Draw the UI to the screen
|
// Draw the UI to the screen
|
||||||
self.char_selection_ui.render(global_state.window.renderer_mut());
|
self.char_selection_ui.render(global_state.window.renderer_mut());
|
||||||
|
|
||||||
|
// Tick the client (currently only to keep the connection alive)
|
||||||
|
self.client.borrow_mut().tick(client::Input::default(), clock.get_last_delta())
|
||||||
|
.expect("Failed to tick the client");
|
||||||
|
self.client.borrow_mut().cleanup();
|
||||||
|
|
||||||
// Finish the frame
|
// Finish the frame
|
||||||
global_state.window.renderer_mut().flush();
|
global_state.window.renderer_mut().flush();
|
||||||
global_state
|
global_state
|
||||||
|
@ -6,10 +6,9 @@ use crate::{
|
|||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
color,
|
color,
|
||||||
color::TRANSPARENT,
|
color::TRANSPARENT,
|
||||||
event::Input,
|
|
||||||
image::Id as ImgId,
|
image::Id as ImgId,
|
||||||
text::font::Id as FontId,
|
text::font::Id as FontId,
|
||||||
widget::{text_box::Event as TextBoxEvent, Button, Image, Rectangle, Text, TextBox, TitleBar},
|
widget::{text_box::Event as TextBoxEvent, Button, Image, Rectangle, Text, TextBox},
|
||||||
widget_ids, Borderable, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
widget_ids, Borderable, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,6 +22,8 @@ widget_ids! {
|
|||||||
|
|
||||||
// Windows
|
// Windows
|
||||||
selection_window,
|
selection_window,
|
||||||
|
char_name,
|
||||||
|
char_level,
|
||||||
creation_window,
|
creation_window,
|
||||||
select_window_title,
|
select_window_title,
|
||||||
race_heading,
|
race_heading,
|
||||||
@ -345,6 +346,8 @@ pub enum Event {
|
|||||||
Play,
|
Play,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TEXT_COLOR: Color = Color::Rgba(0.86, 0.86, 0.86, 0.8);
|
||||||
|
|
||||||
pub struct CharSelectionUi {
|
pub struct CharSelectionUi {
|
||||||
ui: Ui,
|
ui: Ui,
|
||||||
ids: Ids,
|
ids: Ids,
|
||||||
@ -427,7 +430,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.button_dark_hover)
|
.hover_image(self.imgs.button_dark_hover)
|
||||||
.press_image(self.imgs.button_dark_press)
|
.press_image(self.imgs.button_dark_press)
|
||||||
.label("Logout")
|
.label("Logout")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(18)
|
.label_font_size(18)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.logout_button, ui_widgets)
|
.set(self.ids.logout_button, ui_widgets)
|
||||||
@ -443,7 +446,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.button_dark_hover)
|
.hover_image(self.imgs.button_dark_hover)
|
||||||
.press_image(self.imgs.button_dark_press)
|
.press_image(self.imgs.button_dark_press)
|
||||||
.label("Create Character")
|
.label("Create Character")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(20)
|
.label_font_size(20)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.create_character_button, ui_widgets)
|
.set(self.ids.create_character_button, ui_widgets)
|
||||||
@ -462,7 +465,6 @@ impl CharSelectionUi {
|
|||||||
.was_clicked()
|
.was_clicked()
|
||||||
{
|
{
|
||||||
self.selected_char_no = Some(1);
|
self.selected_char_no = Some(1);
|
||||||
self.creation_state = CreationState::Race;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Veloren Logo and Alpha Version
|
// Veloren Logo and Alpha Version
|
||||||
@ -470,7 +472,7 @@ impl CharSelectionUi {
|
|||||||
.w_h(346.0, 111.0)
|
.w_h(346.0, 111.0)
|
||||||
.top_left_with_margins_on(self.ids.bg_selection, 30.0, 40.0)
|
.top_left_with_margins_on(self.ids.bg_selection, 30.0, 40.0)
|
||||||
.label("Alpha 0.1")
|
.label("Alpha 0.1")
|
||||||
.label_rgba(255.0, 255.0, 255.0, 1.0)
|
.label_rgba(1.0, 1.0, 1.0, 1.0)
|
||||||
.label_font_size(10)
|
.label_font_size(10)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(-40.0))
|
.label_y(conrod_core::position::Relative::Scalar(-40.0))
|
||||||
.label_x(conrod_core::position::Relative::Scalar(-100.0))
|
.label_x(conrod_core::position::Relative::Scalar(-100.0))
|
||||||
@ -482,10 +484,23 @@ impl CharSelectionUi {
|
|||||||
.w_h(522.0, 722.0)
|
.w_h(522.0, 722.0)
|
||||||
.mid_right_with_margin_on(ui_widgets.window, 10.0)
|
.mid_right_with_margin_on(ui_widgets.window, 10.0)
|
||||||
.set(self.ids.selection_window, ui_widgets);
|
.set(self.ids.selection_window, ui_widgets);
|
||||||
|
// Character Name & Level
|
||||||
|
Text::new("Character Name")
|
||||||
|
.mid_top_with_margin_on(self.ids.selection_window, 80.0)
|
||||||
|
.font_size(30)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(self.ids.char_name, ui_widgets);
|
||||||
|
Text::new("1")
|
||||||
|
.mid_top_with_margin_on(self.ids.char_name, 40.0)
|
||||||
|
.font_size(30)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(self.ids.char_level, ui_widgets);
|
||||||
|
|
||||||
|
|
||||||
// Selected Character
|
// Selected Character
|
||||||
if no == 1 {
|
if no == 1 {
|
||||||
Image::new(self.imgs.test_char_l_big)
|
Image::new(self.imgs.test_char_l_big)
|
||||||
|
.w_h(522.0, 722.0)
|
||||||
.middle_of(self.ids.selection_window)
|
.middle_of(self.ids.selection_window)
|
||||||
.set(self.ids.test_char_l_big, ui_widgets);
|
.set(self.ids.test_char_l_big, ui_widgets);
|
||||||
}
|
}
|
||||||
@ -497,7 +512,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.button_dark_hover)
|
.hover_image(self.imgs.button_dark_hover)
|
||||||
.press_image(self.imgs.button_dark_press)
|
.press_image(self.imgs.button_dark_press)
|
||||||
.label("Enter World")
|
.label("Enter World")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(22)
|
.label_font_size(22)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.enter_world_button, ui_widgets)
|
.set(self.ids.enter_world_button, ui_widgets)
|
||||||
@ -514,7 +529,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.button_dark_red_hover)
|
.hover_image(self.imgs.button_dark_red_hover)
|
||||||
.press_image(self.imgs.button_dark_red_press)
|
.press_image(self.imgs.button_dark_red_press)
|
||||||
.label("Delete")
|
.label("Delete")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(12)
|
.label_font_size(12)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.delete_button, ui_widgets)
|
.set(self.ids.delete_button, ui_widgets)
|
||||||
@ -535,7 +550,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.button_dark_hover)
|
.hover_image(self.imgs.button_dark_hover)
|
||||||
.press_image(self.imgs.button_dark_press)
|
.press_image(self.imgs.button_dark_press)
|
||||||
.label("Back")
|
.label("Back")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(18)
|
.label_font_size(18)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.back_button, ui_widgets)
|
.set(self.ids.back_button, ui_widgets)
|
||||||
@ -550,7 +565,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.button_dark_hover)
|
.hover_image(self.imgs.button_dark_hover)
|
||||||
.press_image(self.imgs.button_dark_press)
|
.press_image(self.imgs.button_dark_press)
|
||||||
.label("Create")
|
.label("Create")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(18)
|
.label_font_size(18)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.create_button, ui_widgets)
|
.set(self.ids.create_button, ui_widgets)
|
||||||
@ -569,7 +584,7 @@ impl CharSelectionUi {
|
|||||||
.font_size(26)
|
.font_size(26)
|
||||||
.font_id(self.font_metamorph)
|
.font_id(self.font_metamorph)
|
||||||
.center_justify()
|
.center_justify()
|
||||||
.text_color(Color::Rgba(220.0, 220.0, 220.0, 0.8))
|
.text_color(TEXT_COLOR)
|
||||||
.color(TRANSPARENT)
|
.color(TRANSPARENT)
|
||||||
.border_color(TRANSPARENT)
|
.border_color(TRANSPARENT)
|
||||||
.set(self.ids.name_field, ui_widgets)
|
.set(self.ids.name_field, ui_widgets)
|
||||||
@ -665,7 +680,7 @@ impl CharSelectionUi {
|
|||||||
Text::new("Choose your Race")
|
Text::new("Choose your Race")
|
||||||
.mid_top_with_margin_on(self.ids.creation_window, 74.0)
|
.mid_top_with_margin_on(self.ids.creation_window, 74.0)
|
||||||
.font_size(28)
|
.font_size(28)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.select_window_title, ui_widgets);
|
.set(self.ids.select_window_title, ui_widgets);
|
||||||
|
|
||||||
// Male/Female/Race Icons
|
// Male/Female/Race Icons
|
||||||
@ -907,14 +922,14 @@ impl CharSelectionUi {
|
|||||||
Text::new(race_str)
|
Text::new(race_str)
|
||||||
.mid_top_with_margin_on(self.ids.creation_window, 370.0)
|
.mid_top_with_margin_on(self.ids.creation_window, 370.0)
|
||||||
.font_size(30)
|
.font_size(30)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.race_heading, ui_widgets);
|
.set(self.ids.race_heading, ui_widgets);
|
||||||
Text::new(race_desc)
|
Text::new(race_desc)
|
||||||
.mid_top_with_margin_on(self.ids.creation_window, 410.0)
|
.mid_top_with_margin_on(self.ids.creation_window, 410.0)
|
||||||
.w(500.0)
|
.w(500.0)
|
||||||
.font_size(20)
|
.font_size(20)
|
||||||
.font_id(self.font_opensans)
|
.font_id(self.font_opensans)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.wrap_by_word()
|
.wrap_by_word()
|
||||||
.set(self.ids.race_description, ui_widgets);
|
.set(self.ids.race_description, ui_widgets);
|
||||||
// Races Descriptions
|
// Races Descriptions
|
||||||
@ -924,7 +939,7 @@ impl CharSelectionUi {
|
|||||||
Text::new("Choose your Weapon")
|
Text::new("Choose your Weapon")
|
||||||
.mid_top_with_margin_on(self.ids.creation_window, 74.0)
|
.mid_top_with_margin_on(self.ids.creation_window, 74.0)
|
||||||
.font_size(28)
|
.font_size(28)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.select_window_title, ui_widgets);
|
.set(self.ids.select_window_title, ui_widgets);
|
||||||
// BG for Alignment
|
// BG for Alignment
|
||||||
Rectangle::fill_with([470.0, 60.0], color::TRANSPARENT)
|
Rectangle::fill_with([470.0, 60.0], color::TRANSPARENT)
|
||||||
@ -1081,14 +1096,14 @@ impl CharSelectionUi {
|
|||||||
Text::new(weapon_str)
|
Text::new(weapon_str)
|
||||||
.mid_top_with_margin_on(self.ids.creation_window, 370.0)
|
.mid_top_with_margin_on(self.ids.creation_window, 370.0)
|
||||||
.font_size(30)
|
.font_size(30)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.race_heading, ui_widgets);
|
.set(self.ids.race_heading, ui_widgets);
|
||||||
Text::new(weapon_desc)
|
Text::new(weapon_desc)
|
||||||
.mid_top_with_margin_on(self.ids.creation_window, 410.0)
|
.mid_top_with_margin_on(self.ids.creation_window, 410.0)
|
||||||
.w(500.0)
|
.w(500.0)
|
||||||
.font_size(20)
|
.font_size(20)
|
||||||
.font_id(self.font_opensans)
|
.font_id(self.font_opensans)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.wrap_by_word()
|
.wrap_by_word()
|
||||||
.set(self.ids.race_description, ui_widgets);
|
.set(self.ids.race_description, ui_widgets);
|
||||||
// Races Descriptions
|
// Races Descriptions
|
||||||
@ -1103,7 +1118,7 @@ impl CharSelectionUi {
|
|||||||
Text::new("Body Customization")
|
Text::new("Body Customization")
|
||||||
.mid_top_with_margin_on(self.ids.creation_window, 74.0)
|
.mid_top_with_margin_on(self.ids.creation_window, 74.0)
|
||||||
.font_size(28)
|
.font_size(28)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.select_window_title, ui_widgets);
|
.set(self.ids.select_window_title, ui_widgets);
|
||||||
|
|
||||||
match state {
|
match state {
|
||||||
@ -1120,7 +1135,7 @@ impl CharSelectionUi {
|
|||||||
//.hover_image(self.imgs.frame_open_mo)
|
//.hover_image(self.imgs.frame_open_mo)
|
||||||
//.press_image(self.imgs.frame_open_press)
|
//.press_image(self.imgs.frame_open_press)
|
||||||
.label("Skin & Eyes")
|
.label("Skin & Eyes")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(4.0))
|
.label_y(conrod_core::position::Relative::Scalar(4.0))
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.skin_eyes_button, ui_widgets)
|
.set(self.ids.skin_eyes_button, ui_widgets)
|
||||||
@ -1135,7 +1150,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.frame_closed_mo)
|
.hover_image(self.imgs.frame_closed_mo)
|
||||||
.press_image(self.imgs.frame_closed_press)
|
.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Hair")
|
.label("Hair")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.hair_button, ui_widgets)
|
.set(self.ids.hair_button, ui_widgets)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
@ -1149,7 +1164,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.frame_closed_mo)
|
.hover_image(self.imgs.frame_closed_mo)
|
||||||
.press_image(self.imgs.frame_closed_press)
|
.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Accessories")
|
.label("Accessories")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.accessories_button, ui_widgets)
|
.set(self.ids.accessories_button, ui_widgets)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
@ -1171,7 +1186,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.frame_closed_mo)
|
.hover_image(self.imgs.frame_closed_mo)
|
||||||
.press_image(self.imgs.frame_closed_press)
|
.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Skin & Eyes")
|
.label("Skin & Eyes")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.skin_eyes_button, ui_widgets)
|
.set(self.ids.skin_eyes_button, ui_widgets)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
@ -1185,7 +1200,7 @@ impl CharSelectionUi {
|
|||||||
//.hover_image(self.imgs.frame_closed_mo)
|
//.hover_image(self.imgs.frame_closed_mo)
|
||||||
//.press_image(self.imgs.frame_closed_press)
|
//.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Hair")
|
.label("Hair")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(4.0))
|
.label_y(conrod_core::position::Relative::Scalar(4.0))
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.hair_button, ui_widgets)
|
.set(self.ids.hair_button, ui_widgets)
|
||||||
@ -1200,7 +1215,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.frame_closed_mo)
|
.hover_image(self.imgs.frame_closed_mo)
|
||||||
.press_image(self.imgs.frame_closed_press)
|
.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Accessories")
|
.label("Accessories")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.accessories_button, ui_widgets)
|
.set(self.ids.accessories_button, ui_widgets)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
@ -1222,7 +1237,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.frame_closed_mo)
|
.hover_image(self.imgs.frame_closed_mo)
|
||||||
.press_image(self.imgs.frame_closed_press)
|
.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Skin & Eyes")
|
.label("Skin & Eyes")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.skin_eyes_button, ui_widgets)
|
.set(self.ids.skin_eyes_button, ui_widgets)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
@ -1236,7 +1251,7 @@ impl CharSelectionUi {
|
|||||||
.hover_image(self.imgs.frame_closed_mo)
|
.hover_image(self.imgs.frame_closed_mo)
|
||||||
.press_image(self.imgs.frame_closed_press)
|
.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Hair")
|
.label("Hair")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.hair_button, ui_widgets)
|
.set(self.ids.hair_button, ui_widgets)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
@ -1251,7 +1266,7 @@ impl CharSelectionUi {
|
|||||||
//.press_image(self.imgs.frame_closed_press)
|
//.press_image(self.imgs.frame_closed_press)
|
||||||
.label("Accessories")
|
.label("Accessories")
|
||||||
.label_y(conrod_core::position::Relative::Scalar(4.0))
|
.label_y(conrod_core::position::Relative::Scalar(4.0))
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(16)
|
.label_font_size(16)
|
||||||
.set(self.ids.accessories_button, ui_widgets)
|
.set(self.ids.accessories_button, ui_widgets)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
@ -1268,7 +1283,7 @@ impl CharSelectionUi {
|
|||||||
Text::new("Skin Color")
|
Text::new("Skin Color")
|
||||||
.top_left_with_margins_on(self.ids.skin_rect, 0.0, -250.0)
|
.top_left_with_margins_on(self.ids.skin_rect, 0.0, -250.0)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.skin_color_text, ui_widgets);
|
.set(self.ids.skin_color_text, ui_widgets);
|
||||||
// TODO: Align Buttons here
|
// TODO: Align Buttons here
|
||||||
// They set an i32 to a value from 0-14
|
// They set an i32 to a value from 0-14
|
||||||
@ -1276,7 +1291,7 @@ impl CharSelectionUi {
|
|||||||
// Here only the BG image changes depending on the race.
|
// Here only the BG image changes depending on the race.
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
.top_right_with_margins_on(self.ids.skin_eyes_window, 60.0, 30.0)
|
.top_right_with_margins_on(self.ids.skin_eyes_window, 60.0, 30.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.skin_rect, ui_widgets);
|
.set(self.ids.skin_rect, ui_widgets);
|
||||||
|
|
||||||
// TODO:Slider
|
// TODO:Slider
|
||||||
@ -1294,7 +1309,7 @@ impl CharSelectionUi {
|
|||||||
|
|
||||||
Text::new("Brightness")
|
Text::new("Brightness")
|
||||||
.top_left_with_margins_on(self.ids.skin_color_slider_range, -27.0, 0.0)
|
.top_left_with_margins_on(self.ids.skin_color_slider_range, -27.0, 0.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.skin_color_slider_text, ui_widgets);
|
.set(self.ids.skin_color_slider_text, ui_widgets);
|
||||||
|
|
||||||
@ -1302,7 +1317,7 @@ impl CharSelectionUi {
|
|||||||
Text::new("Eye Color")
|
Text::new("Eye Color")
|
||||||
.top_left_with_margins_on(self.ids.eyes_rect, 0.0, -250.0)
|
.top_left_with_margins_on(self.ids.eyes_rect, 0.0, -250.0)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.eye_color_text, ui_widgets);
|
.set(self.ids.eye_color_text, ui_widgets);
|
||||||
// TODO: Align 16 Buttons here
|
// TODO: Align 16 Buttons here
|
||||||
//
|
//
|
||||||
@ -1311,7 +1326,7 @@ impl CharSelectionUi {
|
|||||||
// Only the BG image (190x114 -> 2px border!) changes depending on the race.
|
// Only the BG image (190x114 -> 2px border!) changes depending on the race.
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
.top_right_with_margins_on(self.ids.skin_eyes_window, 186.0, 30.0)
|
.top_right_with_margins_on(self.ids.skin_eyes_window, 186.0, 30.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.eyes_rect, ui_widgets);
|
.set(self.ids.eyes_rect, ui_widgets);
|
||||||
|
|
||||||
// TODO:Slider
|
// TODO:Slider
|
||||||
@ -1328,7 +1343,7 @@ impl CharSelectionUi {
|
|||||||
|
|
||||||
Text::new("Brightness")
|
Text::new("Brightness")
|
||||||
.top_left_with_margins_on(self.ids.eye_color_slider_range, -27.0, 0.0)
|
.top_left_with_margins_on(self.ids.eye_color_slider_range, -27.0, 0.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.eye_color_slider_text, ui_widgets);
|
.set(self.ids.eye_color_slider_text, ui_widgets);
|
||||||
}
|
}
|
||||||
@ -1343,7 +1358,7 @@ impl CharSelectionUi {
|
|||||||
// Hair
|
// Hair
|
||||||
Text::new("Hair Style")
|
Text::new("Hair Style")
|
||||||
.mid_top_with_margin_on(self.ids.hair_window, 60.0)
|
.mid_top_with_margin_on(self.ids.hair_window, 60.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.hair_style_text, ui_widgets);
|
.set(self.ids.hair_style_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1366,12 +1381,12 @@ impl CharSelectionUi {
|
|||||||
Text::new("Hair Color")
|
Text::new("Hair Color")
|
||||||
.top_left_with_margins_on(self.ids.hair_color_picker_bg, 0.0, -250.0)
|
.top_left_with_margins_on(self.ids.hair_color_picker_bg, 0.0, -250.0)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.hair_color_text, ui_widgets);
|
.set(self.ids.hair_color_text, ui_widgets);
|
||||||
|
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
.top_right_with_margins_on(self.ids.hair_window, 114.0, 30.0)
|
.top_right_with_margins_on(self.ids.hair_window, 114.0, 30.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.hair_color_picker_bg, ui_widgets);
|
.set(self.ids.hair_color_picker_bg, ui_widgets);
|
||||||
|
|
||||||
Image::new(self.imgs.slider_range)
|
Image::new(self.imgs.slider_range)
|
||||||
@ -1390,13 +1405,13 @@ impl CharSelectionUi {
|
|||||||
|
|
||||||
Text::new("Brightness")
|
Text::new("Brightness")
|
||||||
.top_left_with_margins_on(self.ids.hair_color_slider_range, -27.0, 0.0)
|
.top_left_with_margins_on(self.ids.hair_color_slider_range, -27.0, 0.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.hair_color_slider_text, ui_widgets);
|
.set(self.ids.hair_color_slider_text, ui_widgets);
|
||||||
// Eyebrows
|
// Eyebrows
|
||||||
Text::new("Eyebrow Style")
|
Text::new("Eyebrow Style")
|
||||||
.mid_top_with_margin_on(self.ids.hair_window, 280.0)
|
.mid_top_with_margin_on(self.ids.hair_window, 280.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.eyebrow_style_text, ui_widgets);
|
.set(self.ids.eyebrow_style_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1419,7 +1434,7 @@ impl CharSelectionUi {
|
|||||||
if let Sex::Male = self.sex {
|
if let Sex::Male = self.sex {
|
||||||
Text::new("Beard Style")
|
Text::new("Beard Style")
|
||||||
.mid_top_with_margin_on(self.ids.hair_window, 340.0)
|
.mid_top_with_margin_on(self.ids.hair_window, 340.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.beard_style_text, ui_widgets);
|
.set(self.ids.beard_style_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1451,7 +1466,7 @@ impl CharSelectionUi {
|
|||||||
Races::Human => {
|
Races::Human => {
|
||||||
Text::new("Head Band")
|
Text::new("Head Band")
|
||||||
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.warpaint_text, ui_widgets);
|
.set(self.ids.warpaint_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1478,7 +1493,7 @@ impl CharSelectionUi {
|
|||||||
-250.0,
|
-250.0,
|
||||||
)
|
)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_text, ui_widgets);
|
.set(self.ids.warpaint_color_text, ui_widgets);
|
||||||
|
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
@ -1487,7 +1502,7 @@ impl CharSelectionUi {
|
|||||||
114.0,
|
114.0,
|
||||||
30.0,
|
30.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
||||||
|
|
||||||
Image::new(self.imgs.slider_range)
|
Image::new(self.imgs.slider_range)
|
||||||
@ -1510,14 +1525,14 @@ impl CharSelectionUi {
|
|||||||
-27.0,
|
-27.0,
|
||||||
0.0,
|
0.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.warpaint_slider_text, ui_widgets);
|
.set(self.ids.warpaint_slider_text, ui_widgets);
|
||||||
} // Human
|
} // Human
|
||||||
Races::Orc => {
|
Races::Orc => {
|
||||||
Text::new("Head Band")
|
Text::new("Head Band")
|
||||||
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.warpaint_text, ui_widgets);
|
.set(self.ids.warpaint_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1544,7 +1559,7 @@ impl CharSelectionUi {
|
|||||||
-250.0,
|
-250.0,
|
||||||
)
|
)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_text, ui_widgets);
|
.set(self.ids.warpaint_color_text, ui_widgets);
|
||||||
|
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
@ -1553,7 +1568,7 @@ impl CharSelectionUi {
|
|||||||
114.0,
|
114.0,
|
||||||
30.0,
|
30.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
||||||
|
|
||||||
Image::new(self.imgs.slider_range)
|
Image::new(self.imgs.slider_range)
|
||||||
@ -1576,14 +1591,14 @@ impl CharSelectionUi {
|
|||||||
-27.0,
|
-27.0,
|
||||||
0.0,
|
0.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.warpaint_slider_text, ui_widgets);
|
.set(self.ids.warpaint_slider_text, ui_widgets);
|
||||||
} // Orc
|
} // Orc
|
||||||
Races::Elf => {
|
Races::Elf => {
|
||||||
Text::new("Tribe Markings")
|
Text::new("Tribe Markings")
|
||||||
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.warpaint_text, ui_widgets);
|
.set(self.ids.warpaint_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1610,7 +1625,7 @@ impl CharSelectionUi {
|
|||||||
-250.0,
|
-250.0,
|
||||||
)
|
)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_text, ui_widgets);
|
.set(self.ids.warpaint_color_text, ui_widgets);
|
||||||
|
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
@ -1619,7 +1634,7 @@ impl CharSelectionUi {
|
|||||||
114.0,
|
114.0,
|
||||||
30.0,
|
30.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
||||||
|
|
||||||
Image::new(self.imgs.slider_range)
|
Image::new(self.imgs.slider_range)
|
||||||
@ -1642,14 +1657,14 @@ impl CharSelectionUi {
|
|||||||
-27.0,
|
-27.0,
|
||||||
0.0,
|
0.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.warpaint_slider_text, ui_widgets);
|
.set(self.ids.warpaint_slider_text, ui_widgets);
|
||||||
} // Elf
|
} // Elf
|
||||||
Races::Dwarf => {
|
Races::Dwarf => {
|
||||||
Text::new("War Paint")
|
Text::new("War Paint")
|
||||||
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.warpaint_text, ui_widgets);
|
.set(self.ids.warpaint_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1676,7 +1691,7 @@ impl CharSelectionUi {
|
|||||||
-250.0,
|
-250.0,
|
||||||
)
|
)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_text, ui_widgets);
|
.set(self.ids.warpaint_color_text, ui_widgets);
|
||||||
|
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
@ -1685,7 +1700,7 @@ impl CharSelectionUi {
|
|||||||
114.0,
|
114.0,
|
||||||
30.0,
|
30.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
||||||
|
|
||||||
Image::new(self.imgs.slider_range)
|
Image::new(self.imgs.slider_range)
|
||||||
@ -1708,14 +1723,14 @@ impl CharSelectionUi {
|
|||||||
-27.0,
|
-27.0,
|
||||||
0.0,
|
0.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.warpaint_slider_text, ui_widgets);
|
.set(self.ids.warpaint_slider_text, ui_widgets);
|
||||||
} // Dwarf
|
} // Dwarf
|
||||||
Races::Undead => {
|
Races::Undead => {
|
||||||
Text::new("Teeth")
|
Text::new("Teeth")
|
||||||
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.warpaint_text, ui_widgets);
|
.set(self.ids.warpaint_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1742,7 +1757,7 @@ impl CharSelectionUi {
|
|||||||
-250.0,
|
-250.0,
|
||||||
)
|
)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_text, ui_widgets);
|
.set(self.ids.warpaint_color_text, ui_widgets);
|
||||||
|
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
@ -1751,7 +1766,7 @@ impl CharSelectionUi {
|
|||||||
114.0,
|
114.0,
|
||||||
30.0,
|
30.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
||||||
|
|
||||||
Image::new(self.imgs.slider_range)
|
Image::new(self.imgs.slider_range)
|
||||||
@ -1774,14 +1789,14 @@ impl CharSelectionUi {
|
|||||||
-27.0,
|
-27.0,
|
||||||
0.0,
|
0.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.warpaint_slider_text, ui_widgets);
|
.set(self.ids.warpaint_slider_text, ui_widgets);
|
||||||
} // Undead
|
} // Undead
|
||||||
Races::Danari => {
|
Races::Danari => {
|
||||||
Text::new("Horns")
|
Text::new("Horns")
|
||||||
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
.mid_top_with_margin_on(self.ids.accessories_window, 60.0)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(24)
|
.font_size(24)
|
||||||
.set(self.ids.warpaint_text, ui_widgets);
|
.set(self.ids.warpaint_text, ui_widgets);
|
||||||
if Button::image(self.imgs.arrow_right)
|
if Button::image(self.imgs.arrow_right)
|
||||||
@ -1808,7 +1823,7 @@ impl CharSelectionUi {
|
|||||||
-250.0,
|
-250.0,
|
||||||
)
|
)
|
||||||
.font_size(25)
|
.font_size(25)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_text, ui_widgets);
|
.set(self.ids.warpaint_color_text, ui_widgets);
|
||||||
|
|
||||||
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
Rectangle::fill_with([192.0, 116.0], color::WHITE)
|
||||||
@ -1817,7 +1832,7 @@ impl CharSelectionUi {
|
|||||||
114.0,
|
114.0,
|
||||||
30.0,
|
30.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
.set(self.ids.warpaint_color_picker_bg, ui_widgets);
|
||||||
|
|
||||||
Image::new(self.imgs.slider_range)
|
Image::new(self.imgs.slider_range)
|
||||||
@ -1840,7 +1855,7 @@ impl CharSelectionUi {
|
|||||||
-27.0,
|
-27.0,
|
||||||
0.0,
|
0.0,
|
||||||
)
|
)
|
||||||
.rgba(220.0, 220.0, 220.0, 0.8)
|
.color(TEXT_COLOR)
|
||||||
.font_size(14)
|
.font_size(14)
|
||||||
.set(self.ids.warpaint_slider_text, ui_widgets);
|
.set(self.ids.warpaint_slider_text, ui_widgets);
|
||||||
} // Danari
|
} // Danari
|
||||||
|
@ -5,6 +5,7 @@ use crate::{
|
|||||||
window::{Event, Window},
|
window::{Event, Window},
|
||||||
GlobalState, PlayState, PlayStateResult,
|
GlobalState, PlayState, PlayStateResult,
|
||||||
};
|
};
|
||||||
|
use client::{self, Client};
|
||||||
use common::clock::Clock;
|
use common::clock::Clock;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use ui::{Event as MainMenuEvent, MainMenuUi};
|
use ui::{Event as MainMenuEvent, MainMenuUi};
|
||||||
@ -57,11 +58,39 @@ impl PlayState for MainMenuState {
|
|||||||
// Maintain the UI
|
// Maintain the UI
|
||||||
for event in self.main_menu_ui.maintain(global_state.window.renderer_mut()) {
|
for event in self.main_menu_ui.maintain(global_state.window.renderer_mut()) {
|
||||||
match event {
|
match event {
|
||||||
MainMenuEvent::LoginAttempt{ username, server_address } =>
|
MainMenuEvent::LoginAttempt{ username, server_address } => {
|
||||||
// For now just start a new session
|
use std::net::ToSocketAddrs;
|
||||||
|
const DEFAULT_PORT: u16 = 59003;
|
||||||
|
// Parses ip address or resolves hostname
|
||||||
|
// Note: if you use an ipv6 address the number after the last colon will be used as the port unless you use [] around the address
|
||||||
|
match server_address.to_socket_addrs().or((server_address.as_str(), DEFAULT_PORT).to_socket_addrs()) {
|
||||||
|
Ok(mut socket_adders) => {
|
||||||
|
while let Some(socket_addr) = socket_adders.next() {
|
||||||
|
// TODO: handle error
|
||||||
|
match Client::new(socket_addr) {
|
||||||
|
Ok(client) => {
|
||||||
return PlayStateResult::Push(
|
return PlayStateResult::Push(
|
||||||
Box::new(CharSelectionState::new(&mut global_state.window))
|
Box::new(CharSelectionState::new(
|
||||||
),
|
&mut global_state.window,
|
||||||
|
std::rc::Rc::new(std::cell::RefCell::new(client.with_test_state())) // <--- TODO: Remove this
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(client::Error::Network(_)) => {} // assume connection failed and try next address
|
||||||
|
Err(err) => {
|
||||||
|
panic!("Unexpected non Network error when creating client: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Parsing/host name resolution successful but no connection succeeded
|
||||||
|
self.main_menu_ui.login_error("Could not connect to address".to_string());
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
// Error parsing input string or error resolving host name
|
||||||
|
self.main_menu_ui.login_error("No such host is known".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
MainMenuEvent::Quit => return PlayStateResult::Shutdown,
|
MainMenuEvent::Quit => return PlayStateResult::Shutdown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,9 @@ use crate::{
|
|||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
color::TRANSPARENT,
|
color::TRANSPARENT,
|
||||||
image::Id as ImgId,
|
image::Id as ImgId,
|
||||||
|
position::Dimension,
|
||||||
text::font::Id as FontId,
|
text::font::Id as FontId,
|
||||||
widget::{text_box::Event as TextBoxEvent, Button, Image, TextBox},
|
widget::{text_box::Event as TextBoxEvent, Button, Image, Rectangle, Text, TextBox},
|
||||||
widget_ids, Borderable, Color,
|
widget_ids, Borderable, Color,
|
||||||
Colorable, Labelable, Positionable, Sizeable, Widget,
|
Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||||
};
|
};
|
||||||
@ -21,6 +22,8 @@ widget_ids! {
|
|||||||
// Login, Singleplayer
|
// Login, Singleplayer
|
||||||
login_button,
|
login_button,
|
||||||
login_text,
|
login_text,
|
||||||
|
login_error,
|
||||||
|
login_error_bg,
|
||||||
address_text,
|
address_text,
|
||||||
address_bg,
|
address_bg,
|
||||||
address_field,
|
address_field,
|
||||||
@ -101,6 +104,7 @@ pub struct MainMenuUi {
|
|||||||
font_opensans: FontId,
|
font_opensans: FontId,
|
||||||
username: String,
|
username: String,
|
||||||
server_address: String,
|
server_address: String,
|
||||||
|
login_error: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MainMenuUi {
|
impl MainMenuUi {
|
||||||
@ -134,7 +138,8 @@ impl MainMenuUi {
|
|||||||
font_metamorph,
|
font_metamorph,
|
||||||
font_opensans,
|
font_opensans,
|
||||||
username: "Username".to_string(),
|
username: "Username".to_string(),
|
||||||
server_address: "Server Address".to_string(),
|
server_address: "veloren.mac94.de".to_string(),
|
||||||
|
login_error: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +154,7 @@ impl MainMenuUi {
|
|||||||
.w_h(346.0, 111.0)
|
.w_h(346.0, 111.0)
|
||||||
.top_left_with_margins(30.0, 40.0)
|
.top_left_with_margins(30.0, 40.0)
|
||||||
.label("Alpha 0.1")
|
.label("Alpha 0.1")
|
||||||
.label_rgba(255.0, 255.0, 255.0, 1.0)
|
.label_rgba(1.0, 1.0, 1.0, 1.0)
|
||||||
.label_font_size(10)
|
.label_font_size(10)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(-40.0))
|
.label_y(conrod_core::position::Relative::Scalar(-40.0))
|
||||||
.label_x(conrod_core::position::Relative::Scalar(-100.0))
|
.label_x(conrod_core::position::Relative::Scalar(-100.0))
|
||||||
@ -159,12 +164,14 @@ impl MainMenuUi {
|
|||||||
// Used when the login button is pressed, or enter is pressed within input field
|
// Used when the login button is pressed, or enter is pressed within input field
|
||||||
macro_rules! login {
|
macro_rules! login {
|
||||||
() => {
|
() => {
|
||||||
|
self.login_error = None;
|
||||||
events.push(Event::LoginAttempt {
|
events.push(Event::LoginAttempt {
|
||||||
username: self.username.clone(),
|
username: self.username.clone(),
|
||||||
server_address: self.server_address.clone(),
|
server_address: self.server_address.clone(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
const TEXT_COLOR: Color = Color::Rgba(0.94, 0.94, 0.94, 0.8);
|
||||||
// Username
|
// Username
|
||||||
// TODO: get a lower resolution and cleaner input_bg.png
|
// TODO: get a lower resolution and cleaner input_bg.png
|
||||||
Image::new(self.imgs.input_bg)
|
Image::new(self.imgs.input_bg)
|
||||||
@ -176,7 +183,7 @@ impl MainMenuUi {
|
|||||||
.mid_bottom_with_margin_on(self.ids.username_bg, 44.0 / 2.0)
|
.mid_bottom_with_margin_on(self.ids.username_bg, 44.0 / 2.0)
|
||||||
.font_size(20)
|
.font_size(20)
|
||||||
.font_id(self.font_opensans)
|
.font_id(self.font_opensans)
|
||||||
.text_color(Color::Rgba(220.0, 220.0, 220.0, 0.8))
|
.text_color(TEXT_COLOR)
|
||||||
// transparent background
|
// transparent background
|
||||||
.color(TRANSPARENT)
|
.color(TRANSPARENT)
|
||||||
.border_color(TRANSPARENT)
|
.border_color(TRANSPARENT)
|
||||||
@ -187,9 +194,28 @@ impl MainMenuUi {
|
|||||||
// Note: TextBox limits the input string length to what fits in it
|
// Note: TextBox limits the input string length to what fits in it
|
||||||
self.username = username.to_string();
|
self.username = username.to_string();
|
||||||
}
|
}
|
||||||
TextBoxEvent::Enter => login!(),
|
TextBoxEvent::Enter => { login!(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Login error
|
||||||
|
if let Some(msg) = &self.login_error {
|
||||||
|
let text = Text::new(&msg)
|
||||||
|
.rgba(0.5, 0.0, 0.0, 1.0)
|
||||||
|
.font_size(30)
|
||||||
|
.font_id(self.font_opensans);
|
||||||
|
let x = match text.get_x_dimension(ui_widgets) {
|
||||||
|
Dimension::Absolute(x) => x + 10.0,
|
||||||
|
_ => 0.0,
|
||||||
|
};
|
||||||
|
Rectangle::fill([x, 40.0])
|
||||||
|
.rgba(0.2, 0.3, 0.3, 0.7)
|
||||||
|
.parent(ui_widgets.window)
|
||||||
|
.up_from(self.ids.username_bg, 35.0)
|
||||||
|
.set(self.ids.login_error_bg, ui_widgets);
|
||||||
|
text
|
||||||
|
.middle_of(self.ids.login_error_bg)
|
||||||
|
.set(self.ids.login_error, ui_widgets);
|
||||||
|
}
|
||||||
// Server address
|
// Server address
|
||||||
Image::new(self.imgs.input_bg)
|
Image::new(self.imgs.input_bg)
|
||||||
.w_h(337.0, 67.0)
|
.w_h(337.0, 67.0)
|
||||||
@ -200,7 +226,7 @@ impl MainMenuUi {
|
|||||||
.mid_bottom_with_margin_on(self.ids.address_bg, 44.0 / 2.0)
|
.mid_bottom_with_margin_on(self.ids.address_bg, 44.0 / 2.0)
|
||||||
.font_size(20)
|
.font_size(20)
|
||||||
.font_id(self.font_opensans)
|
.font_id(self.font_opensans)
|
||||||
.text_color(Color::Rgba(220.0, 220.0, 220.0, 0.8))
|
.text_color(TEXT_COLOR)
|
||||||
// transparent background
|
// transparent background
|
||||||
.color(TRANSPARENT)
|
.color(TRANSPARENT)
|
||||||
.border_color(TRANSPARENT)
|
.border_color(TRANSPARENT)
|
||||||
@ -210,7 +236,7 @@ impl MainMenuUi {
|
|||||||
TextBoxEvent::Update(server_address) => {
|
TextBoxEvent::Update(server_address) => {
|
||||||
self.server_address = server_address.to_string();
|
self.server_address = server_address.to_string();
|
||||||
}
|
}
|
||||||
TextBoxEvent::Enter => login!(),
|
TextBoxEvent::Enter => { login!(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Login button
|
// Login button
|
||||||
@ -221,7 +247,7 @@ impl MainMenuUi {
|
|||||||
.down_from(self.ids.address_bg, 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("Login")
|
.label("Login")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(28)
|
.label_font_size(28)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(5.0))
|
.label_y(conrod_core::position::Relative::Scalar(5.0))
|
||||||
.set(self.ids.login_button, ui_widgets)
|
.set(self.ids.login_button, ui_widgets)
|
||||||
@ -229,7 +255,7 @@ impl MainMenuUi {
|
|||||||
{
|
{
|
||||||
login!();
|
login!();
|
||||||
}
|
}
|
||||||
//Singleplayer button
|
// Singleplayer button
|
||||||
if Button::image(self.imgs.login_button)
|
if Button::image(self.imgs.login_button)
|
||||||
.hover_image(self.imgs.login_button_hover)
|
.hover_image(self.imgs.login_button_hover)
|
||||||
.press_image(self.imgs.login_button_press)
|
.press_image(self.imgs.login_button_press)
|
||||||
@ -237,7 +263,7 @@ impl MainMenuUi {
|
|||||||
.down_from(self.ids.login_button, 20.0)
|
.down_from(self.ids.login_button, 20.0)
|
||||||
.align_middle_x_of(self.ids.address_bg)
|
.align_middle_x_of(self.ids.address_bg)
|
||||||
.label("Singleplayer")
|
.label("Singleplayer")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(26)
|
.label_font_size(26)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(5.0))
|
.label_y(conrod_core::position::Relative::Scalar(5.0))
|
||||||
.label_x(conrod_core::position::Relative::Scalar(2.0))
|
.label_x(conrod_core::position::Relative::Scalar(2.0))
|
||||||
@ -253,7 +279,7 @@ impl MainMenuUi {
|
|||||||
.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("Quit")
|
.label("Quit")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(20)
|
.label_font_size(20)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.quit_button, ui_widgets)
|
.set(self.ids.quit_button, ui_widgets)
|
||||||
@ -268,7 +294,7 @@ impl MainMenuUi {
|
|||||||
.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")
|
.label("Settings")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(20)
|
.label_font_size(20)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.settings_button, ui_widgets)
|
.set(self.ids.settings_button, ui_widgets)
|
||||||
@ -281,7 +307,7 @@ impl MainMenuUi {
|
|||||||
.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("Servers")
|
||||||
.label_rgba(220.0, 220.0, 220.0, 0.8)
|
.label_color(TEXT_COLOR)
|
||||||
.label_font_size(20)
|
.label_font_size(20)
|
||||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||||
.set(self.ids.servers_button, ui_widgets)
|
.set(self.ids.servers_button, ui_widgets)
|
||||||
@ -291,6 +317,10 @@ impl MainMenuUi {
|
|||||||
events
|
events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn login_error(&mut self, msg: String) {
|
||||||
|
self.login_error = Some(msg);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use super::super::{
|
|||||||
Pipeline,
|
Pipeline,
|
||||||
TgtColorFmt,
|
TgtColorFmt,
|
||||||
TgtDepthFmt,
|
TgtDepthFmt,
|
||||||
Mesh,
|
|
||||||
Quad,
|
Quad,
|
||||||
Tri,
|
Tri,
|
||||||
};
|
};
|
||||||
|
@ -78,7 +78,7 @@ impl Scene {
|
|||||||
test_figure: Figure::new(
|
test_figure: Figure::new(
|
||||||
renderer,
|
renderer,
|
||||||
[
|
[
|
||||||
Some(load_segment("head.vox").generate_mesh(Vec3::new(-7.0, -5.5, -1.0))),
|
Some(load_segment("head.vox").generate_mesh(Vec3::new(-7.0, -6.5, -6.0))),
|
||||||
Some(load_segment("chest.vox").generate_mesh(Vec3::new(-6.0, -3.0, 0.0))),
|
Some(load_segment("chest.vox").generate_mesh(Vec3::new(-6.0, -3.0, 0.0))),
|
||||||
Some(load_segment("belt.vox").generate_mesh(Vec3::new(-5.0, -3.0, 0.0))),
|
Some(load_segment("belt.vox").generate_mesh(Vec3::new(-5.0, -3.0, 0.0))),
|
||||||
Some(load_segment("pants.vox").generate_mesh(Vec3::new(-5.0, -3.0, 0.0))),
|
Some(load_segment("pants.vox").generate_mesh(Vec3::new(-5.0, -3.0, 0.0))),
|
||||||
|
@ -1,17 +1,10 @@
|
|||||||
// Standard
|
use std::{cell::RefCell, rc::Rc, time::Duration};
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
// Library
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
// Project
|
|
||||||
use common::clock::Clock;
|
use common::clock::Clock;
|
||||||
use client::{
|
use client::{
|
||||||
self,
|
self,
|
||||||
Client,
|
Client,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Crate
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Error,
|
Error,
|
||||||
PlayState,
|
PlayState,
|
||||||
@ -28,28 +21,35 @@ const FPS: u64 = 60;
|
|||||||
|
|
||||||
pub struct SessionState {
|
pub struct SessionState {
|
||||||
scene: Scene,
|
scene: Scene,
|
||||||
client: Client,
|
client: Rc<RefCell<Client>>,
|
||||||
key_state: KeyState,
|
key_state: KeyState,
|
||||||
hud: Hud,
|
hud: Hud,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Represents an active game session (i.e: one that is being played)
|
/// Represents an active game session (i.e: one that is being played)
|
||||||
impl SessionState {
|
impl SessionState {
|
||||||
/// Create a new `SessionState`
|
/// Create a new `SessionState`
|
||||||
pub fn new(window: &mut Window) -> Result<Self, Error> {
|
pub fn new(window: &mut Window, client: Rc<RefCell<Client>>) -> Self {
|
||||||
let client = Client::new(([127, 0, 0, 1], 59003))?.with_test_state(); // <--- TODO: Remove this
|
|
||||||
Ok(Self {
|
|
||||||
// Create a scene for this session. The scene handles visible elements of the game world
|
// Create a scene for this session. The scene handles visible elements of the game world
|
||||||
scene: Scene::new(window.renderer_mut(), &client),
|
let scene = Scene::new(window.renderer_mut(), &client.borrow());
|
||||||
|
Self {
|
||||||
|
scene,
|
||||||
client,
|
client,
|
||||||
key_state: KeyState::new(),
|
key_state: KeyState::new(),
|
||||||
hud: Hud::new(window),
|
hud: Hud::new(window),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The background colour
|
// The background colour
|
||||||
const BG_COLOR: Rgba<f32> = Rgba { r: 0.0, g: 0.3, b: 1.0, a: 1.0 };
|
const BG_COLOR: Rgba<f32> = Rgba {
|
||||||
|
r: 0.0,
|
||||||
|
g: 0.3,
|
||||||
|
b: 1.0,
|
||||||
|
a: 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
impl SessionState {
|
impl SessionState {
|
||||||
/// Tick the session (and the client attached to it)
|
/// Tick the session (and the client attached to it)
|
||||||
@ -63,7 +63,7 @@ impl SessionState {
|
|||||||
let dir_vec = self.key_state.dir_vec();
|
let dir_vec = self.key_state.dir_vec();
|
||||||
let move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1];
|
let move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1];
|
||||||
|
|
||||||
for event in self.client.tick(client::Input { move_dir }, dt)? {
|
for event in self.client.borrow_mut().tick(client::Input { move_dir }, dt)? {
|
||||||
match event {
|
match event {
|
||||||
client::Event::Chat(msg) => {
|
client::Event::Chat(msg) => {
|
||||||
self.hud.new_message(msg);
|
self.hud.new_message(msg);
|
||||||
@ -76,7 +76,7 @@ impl SessionState {
|
|||||||
|
|
||||||
/// Clean up the session (and the client attached to it) after a tick
|
/// Clean up the session (and the client attached to it) after a tick
|
||||||
pub fn cleanup(&mut self) {
|
pub fn cleanup(&mut self) {
|
||||||
self.client.cleanup();
|
self.client.borrow_mut().cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the session to the screen.
|
/// Render the session to the screen.
|
||||||
@ -108,7 +108,7 @@ impl PlayState for SessionState {
|
|||||||
for x in -6..7 {
|
for x in -6..7 {
|
||||||
for y in -6..7 {
|
for y in -6..7 {
|
||||||
for z in -1..2 {
|
for z in -1..2 {
|
||||||
self.client.load_chunk(Vec3::new(x, y, z));
|
self.client.borrow_mut().load_chunk(Vec3::new(x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,17 +124,14 @@ impl PlayState for SessionState {
|
|||||||
}
|
}
|
||||||
let _handled = match event {
|
let _handled = match event {
|
||||||
Event::Close => return PlayStateResult::Shutdown,
|
Event::Close => return PlayStateResult::Shutdown,
|
||||||
// When 'q' is pressed, exit the session
|
|
||||||
Event::Char('q') => return PlayStateResult::Pop,
|
|
||||||
// When 'm' is pressed, open/close the in-game test menu
|
|
||||||
Event::Char('m') => self.hud.toggle_menu(),
|
|
||||||
// Close windows on esc
|
|
||||||
Event::KeyDown(Key::Escape) => self.hud.toggle_windows(),
|
|
||||||
// Toggle cursor grabbing
|
// Toggle cursor grabbing
|
||||||
Event::KeyDown(Key::ToggleCursor) => {
|
Event::KeyDown(Key::ToggleCursor) => {
|
||||||
global_state.window.grab_cursor(!global_state.window.is_cursor_grabbed());
|
global_state
|
||||||
self.hud.update_grab(global_state.window.is_cursor_grabbed());
|
.window
|
||||||
},
|
.grab_cursor(!global_state.window.is_cursor_grabbed());
|
||||||
|
self.hud
|
||||||
|
.update_grab(global_state.window.is_cursor_grabbed());
|
||||||
|
}
|
||||||
// Movement Key Pressed
|
// Movement Key Pressed
|
||||||
Event::KeyDown(Key::MoveForward) => self.key_state.up = true,
|
Event::KeyDown(Key::MoveForward) => self.key_state.up = true,
|
||||||
Event::KeyDown(Key::MoveBack) => self.key_state.down = true,
|
Event::KeyDown(Key::MoveBack) => self.key_state.down = true,
|
||||||
@ -146,7 +143,9 @@ impl PlayState for SessionState {
|
|||||||
Event::KeyUp(Key::MoveLeft) => self.key_state.left = false,
|
Event::KeyUp(Key::MoveLeft) => self.key_state.left = false,
|
||||||
Event::KeyUp(Key::MoveRight) => self.key_state.right = false,
|
Event::KeyUp(Key::MoveRight) => self.key_state.right = false,
|
||||||
// Pass all other events to the scene
|
// Pass all other events to the scene
|
||||||
event => { self.scene.handle_input_event(event); },
|
event => {
|
||||||
|
self.scene.handle_input_event(event);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// TODO: Do something if the event wasn't handled?
|
// TODO: Do something if the event wasn't handled?
|
||||||
}
|
}
|
||||||
@ -156,13 +155,13 @@ impl PlayState for SessionState {
|
|||||||
.expect("Failed to tick the scene");
|
.expect("Failed to tick the scene");
|
||||||
|
|
||||||
// Maintain the scene
|
// Maintain the scene
|
||||||
self.scene.maintain(global_state.window.renderer_mut(), &self.client);
|
self.scene.maintain(global_state.window.renderer_mut(), &self.client.borrow());
|
||||||
// Maintain the UI
|
// Maintain the UI
|
||||||
for event in self.hud.maintain(global_state.window.renderer_mut()) {
|
for event in self.hud.maintain(global_state.window.renderer_mut()) {
|
||||||
match event {
|
match event {
|
||||||
HudEvent::SendMessage(msg) => {
|
HudEvent::SendMessage(msg) => {
|
||||||
// TODO: Handle result
|
// TODO: Handle result
|
||||||
self.client.send_chat(msg);
|
self.client.borrow_mut().send_chat(msg);
|
||||||
},
|
},
|
||||||
HudEvent::Logout => return PlayStateResult::Pop,
|
HudEvent::Logout => return PlayStateResult::Pop,
|
||||||
HudEvent::Quit => return PlayStateResult::Shutdown,
|
HudEvent::Quit => return PlayStateResult::Shutdown,
|
||||||
@ -173,7 +172,8 @@ impl PlayState for SessionState {
|
|||||||
self.render(global_state.window.renderer_mut());
|
self.render(global_state.window.renderer_mut());
|
||||||
|
|
||||||
// Display the frame on the window
|
// Display the frame on the window
|
||||||
global_state.window
|
global_state
|
||||||
|
.window
|
||||||
.swap_buffers()
|
.swap_buffers()
|
||||||
.expect("Failed to swap window buffers");
|
.expect("Failed to swap window buffers");
|
||||||
|
|
||||||
@ -185,5 +185,7 @@ impl PlayState for SessionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &'static str { "Session" }
|
fn name(&self) -> &'static str {
|
||||||
|
"Session"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,6 @@ impl Ui {
|
|||||||
|
|
||||||
use conrod_core::render::PrimitiveKind;
|
use conrod_core::render::PrimitiveKind;
|
||||||
match kind {
|
match kind {
|
||||||
// TODO: use source_rect
|
|
||||||
PrimitiveKind::Image { image_id, color, source_rect } => {
|
PrimitiveKind::Image { image_id, color, source_rect } => {
|
||||||
|
|
||||||
// Switch to the `Image` state for this image if we're not in it already.
|
// Switch to the `Image` state for this image if we're not in it already.
|
||||||
@ -389,7 +388,7 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let color = color.unwrap_or(conrod_core::color::WHITE).to_fsa();
|
let color = srgb_to_linear(color.unwrap_or(conrod_core::color::WHITE).to_fsa());
|
||||||
|
|
||||||
// Transform the source rectangle into uv coordinates
|
// Transform the source rectangle into uv coordinates
|
||||||
let (image_w, image_h) = self.image_map
|
let (image_w, image_h) = self.image_map
|
||||||
@ -443,8 +442,7 @@ impl Ui {
|
|||||||
renderer.update_texture(cache_tex, offset, size, &new_data);
|
renderer.update_texture(cache_tex, offset, size, &new_data);
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
// TODO: consider gamma....
|
let color = srgb_to_linear(color.to_fsa());
|
||||||
let color = color.to_fsa();
|
|
||||||
|
|
||||||
for g in positioned_glyphs {
|
for g in positioned_glyphs {
|
||||||
if let Ok(Some((uv_rect, screen_rect))) = glyph_cache.rect_for(font_id.index(), g) {
|
if let Ok(Some((uv_rect, screen_rect))) = glyph_cache.rect_for(font_id.index(), g) {
|
||||||
@ -472,8 +470,7 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrimitiveKind::Rectangle { color } => {
|
PrimitiveKind::Rectangle { color } => {
|
||||||
// TODO: consider gamma/linear conversion....
|
let color = srgb_to_linear(color.to_fsa());
|
||||||
let color = color.to_fsa();
|
|
||||||
// Don't draw a transparent rectangle
|
// Don't draw a transparent rectangle
|
||||||
if color[3] == 0.0 {
|
if color[3] == 0.0 {
|
||||||
continue;
|
continue;
|
||||||
@ -493,7 +490,7 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
PrimitiveKind::TrianglesSingleColor { color, triangles } => {
|
PrimitiveKind::TrianglesSingleColor { color, triangles } => {
|
||||||
// Don't draw transparent triangle or switch state if there are actually no triangles
|
// Don't draw transparent triangle or switch state if there are actually no triangles
|
||||||
let color: [f32; 4] = color.into();
|
let color: [f32; 4] = srgb_to_linear(color.into());
|
||||||
if triangles.is_empty() || color[3] == 0.0 {
|
if triangles.is_empty() || color[3] == 0.0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -577,3 +574,15 @@ fn default_scissor(renderer: &mut Renderer) -> Aabr<u16> {
|
|||||||
max: Vec2 { x: screen_w, y: screen_h }
|
max: Vec2 { x: screen_w, y: screen_h }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn srgb_to_linear(color: [f32; 4]) -> [f32; 4] {
|
||||||
|
fn linearize(comp: f32) -> f32 {
|
||||||
|
if comp <= 0.04045 {
|
||||||
|
comp / 12.92
|
||||||
|
} else {
|
||||||
|
((comp + 0.055) / 1.055).powf(2.4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[linearize(color[0]), linearize(color[1]), linearize(color[2]), color[3]]
|
||||||
|
}
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
use vek::*;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Error,
|
render::{Renderer, TgtColorFmt, TgtDepthFmt},
|
||||||
render::{
|
ui, Error,
|
||||||
Renderer,
|
|
||||||
TgtColorFmt,
|
|
||||||
TgtDepthFmt,
|
|
||||||
},
|
|
||||||
ui,
|
|
||||||
};
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
events_loop: glutin::EventsLoop,
|
events_loop: glutin::EventsLoop,
|
||||||
@ -19,7 +14,6 @@ pub struct Window {
|
|||||||
key_map: HashMap<glutin::VirtualKeyCode, Key>,
|
key_map: HashMap<glutin::VirtualKeyCode, Key>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new() -> Result<Window, Error> {
|
pub fn new() -> Result<Window, Error> {
|
||||||
let events_loop = glutin::EventsLoop::new();
|
let events_loop = glutin::EventsLoop::new();
|
||||||
@ -33,17 +27,13 @@ impl Window {
|
|||||||
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)))
|
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)))
|
||||||
.with_vsync(false);
|
.with_vsync(false);
|
||||||
|
|
||||||
let (
|
let (window, device, factory, tgt_color_view, tgt_depth_view) =
|
||||||
window,
|
gfx_window_glutin::init::<TgtColorFmt, TgtDepthFmt>(
|
||||||
device,
|
|
||||||
factory,
|
|
||||||
tgt_color_view,
|
|
||||||
tgt_depth_view,
|
|
||||||
) = gfx_window_glutin::init::<TgtColorFmt, TgtDepthFmt>(
|
|
||||||
win_builder,
|
win_builder,
|
||||||
ctx_builder,
|
ctx_builder,
|
||||||
&events_loop,
|
&events_loop,
|
||||||
).map_err(|err| Error::BackendError(Box::new(err)))?;
|
)
|
||||||
|
.map_err(|err| Error::BackendError(Box::new(err)))?;
|
||||||
|
|
||||||
let mut key_map = HashMap::new();
|
let mut key_map = HashMap::new();
|
||||||
key_map.insert(glutin::VirtualKeyCode::Tab, Key::ToggleCursor);
|
key_map.insert(glutin::VirtualKeyCode::Tab, Key::ToggleCursor);
|
||||||
@ -53,15 +43,19 @@ impl Window {
|
|||||||
key_map.insert(glutin::VirtualKeyCode::A, Key::MoveLeft);
|
key_map.insert(glutin::VirtualKeyCode::A, Key::MoveLeft);
|
||||||
key_map.insert(glutin::VirtualKeyCode::S, Key::MoveBack);
|
key_map.insert(glutin::VirtualKeyCode::S, Key::MoveBack);
|
||||||
key_map.insert(glutin::VirtualKeyCode::D, Key::MoveRight);
|
key_map.insert(glutin::VirtualKeyCode::D, Key::MoveRight);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::M, Key::Map);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::B, Key::Bag);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::L, Key::QuestLog);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::C, Key::CharacterWindow);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::O, Key::Social);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::P, Key::Spellbook);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::N, Key::Settings);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::F1, Key::Help);
|
||||||
|
key_map.insert(glutin::VirtualKeyCode::F2, Key::Interface);
|
||||||
|
|
||||||
let tmp = Ok(Self {
|
let tmp = Ok(Self {
|
||||||
events_loop,
|
events_loop,
|
||||||
renderer: Renderer::new(
|
renderer: Renderer::new(device, factory, tgt_color_view, tgt_depth_view)?,
|
||||||
device,
|
|
||||||
factory,
|
|
||||||
tgt_color_view,
|
|
||||||
tgt_depth_view,
|
|
||||||
)?,
|
|
||||||
window,
|
window,
|
||||||
cursor_grabbed: false,
|
cursor_grabbed: false,
|
||||||
needs_refresh_resize: false,
|
needs_refresh_resize: false,
|
||||||
@ -70,8 +64,12 @@ impl Window {
|
|||||||
tmp
|
tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn renderer(&self) -> &Renderer { &self.renderer }
|
pub fn renderer(&self) -> &Renderer {
|
||||||
pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer }
|
&self.renderer
|
||||||
|
}
|
||||||
|
pub fn renderer_mut(&mut self) -> &mut Renderer {
|
||||||
|
&mut self.renderer
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fetch_events(&mut self) -> Vec<Event> {
|
pub fn fetch_events(&mut self) -> Vec<Event> {
|
||||||
let mut events = vec![];
|
let mut events = vec![];
|
||||||
@ -99,44 +97,45 @@ impl Window {
|
|||||||
glutin::WindowEvent::CloseRequested => events.push(Event::Close),
|
glutin::WindowEvent::CloseRequested => events.push(Event::Close),
|
||||||
glutin::WindowEvent::Resized(glutin::dpi::LogicalSize { width, height }) => {
|
glutin::WindowEvent::Resized(glutin::dpi::LogicalSize { width, height }) => {
|
||||||
let (mut color_view, mut depth_view) = renderer.target_views_mut();
|
let (mut color_view, mut depth_view) = renderer.target_views_mut();
|
||||||
gfx_window_glutin::update_views(
|
gfx_window_glutin::update_views(&window, &mut color_view, &mut depth_view);
|
||||||
&window,
|
|
||||||
&mut color_view,
|
|
||||||
&mut depth_view,
|
|
||||||
);
|
|
||||||
events.push(Event::Resize(Vec2::new(width as u32, height as u32)));
|
events.push(Event::Resize(Vec2::new(width as u32, height as u32)));
|
||||||
},
|
}
|
||||||
glutin::WindowEvent::ReceivedCharacter(c) => events.push(Event::Char(c)),
|
glutin::WindowEvent::ReceivedCharacter(c) => events.push(Event::Char(c)),
|
||||||
|
|
||||||
glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode {
|
glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode
|
||||||
|
{
|
||||||
Some(keycode) => match key_map.get(&keycode) {
|
Some(keycode) => match key_map.get(&keycode) {
|
||||||
Some(&key) => events.push(match input.state {
|
Some(&key) => events.push(match input.state {
|
||||||
glutin::ElementState::Pressed => Event::KeyDown(key),
|
glutin::ElementState::Pressed => Event::KeyDown(key),
|
||||||
_ => Event::KeyUp(key),
|
_ => Event::KeyUp(key),
|
||||||
}),
|
}),
|
||||||
_ => {},
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {}
|
||||||
},
|
},
|
||||||
glutin::Event::DeviceEvent { event, .. } => match event {
|
glutin::Event::DeviceEvent { event, .. } => match event {
|
||||||
glutin::DeviceEvent::MouseMotion { delta: (dx, dy), .. } if cursor_grabbed =>
|
glutin::DeviceEvent::MouseMotion {
|
||||||
events.push(Event::CursorPan(Vec2::new(dx as f32, dy as f32))),
|
delta: (dx, dy), ..
|
||||||
|
} if cursor_grabbed => {
|
||||||
|
events.push(Event::CursorPan(Vec2::new(dx as f32, dy as f32)))
|
||||||
|
}
|
||||||
glutin::DeviceEvent::MouseWheel {
|
glutin::DeviceEvent::MouseWheel {
|
||||||
delta: glutin::MouseScrollDelta::LineDelta(_x, y),
|
delta: glutin::MouseScrollDelta::LineDelta(_x, y),
|
||||||
..
|
..
|
||||||
} if cursor_grabbed => events.push(Event::Zoom(y as f32)),
|
} if cursor_grabbed => events.push(Event::Zoom(y as f32)),
|
||||||
_ => {},
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
events
|
events
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn swap_buffers(&self) -> Result<(), Error> {
|
pub fn swap_buffers(&self) -> Result<(), Error> {
|
||||||
self.window.swap_buffers()
|
self.window
|
||||||
|
.swap_buffers()
|
||||||
.map_err(|err| Error::BackendError(Box::new(err)))
|
.map_err(|err| Error::BackendError(Box::new(err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +146,8 @@ impl Window {
|
|||||||
pub fn grab_cursor(&mut self, grab: bool) {
|
pub fn grab_cursor(&mut self, grab: bool) {
|
||||||
self.cursor_grabbed = grab;
|
self.cursor_grabbed = grab;
|
||||||
self.window.hide_cursor(grab);
|
self.window.hide_cursor(grab);
|
||||||
self.window.grab_cursor(grab)
|
self.window
|
||||||
|
.grab_cursor(grab)
|
||||||
.expect("Failed to grab/ungrab cursor");
|
.expect("Failed to grab/ungrab cursor");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +156,11 @@ impl Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn logical_size(&self) -> Vec2<f64> {
|
pub fn logical_size(&self) -> Vec2<f64> {
|
||||||
let (w, h) = self.window.get_inner_size().unwrap_or(glutin::dpi::LogicalSize::new(0.0, 0.0)).into();
|
let (w, h) = self
|
||||||
|
.window
|
||||||
|
.get_inner_size()
|
||||||
|
.unwrap_or(glutin::dpi::LogicalSize::new(0.0, 0.0))
|
||||||
|
.into();
|
||||||
Vec2::new(w, h)
|
Vec2::new(w, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,6 +175,15 @@ pub enum Key {
|
|||||||
MoveRight,
|
MoveRight,
|
||||||
Enter,
|
Enter,
|
||||||
Escape,
|
Escape,
|
||||||
|
Map,
|
||||||
|
Bag,
|
||||||
|
QuestLog,
|
||||||
|
CharacterWindow,
|
||||||
|
Social,
|
||||||
|
Spellbook,
|
||||||
|
Settings,
|
||||||
|
Interface,
|
||||||
|
Help,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an incoming event from the window
|
/// Represents an incoming event from the window
|
||||||
|
Loading…
Reference in New Issue
Block a user