add chat box, minimap buttons, ui windows, etc

Former-commit-id: 09d3e20b917a9ac9ef6333ee9bb913d01a7fb52c
This commit is contained in:
Imbris 2019-03-15 00:55:52 -04:00
parent 16ed207437
commit f837492284
111 changed files with 1787 additions and 492 deletions

124
voxygen/src/hud/chat.rs Normal file
View File

@ -0,0 +1,124 @@
use crate::ui::Ui;
use conrod_core::{
input::Key,
position::Dimension,
widget::{List, Rectangle, Text, TextEdit},
widget_ids, Color, Colorable, Positionable, Sizeable, UiCell, Widget,
};
use std::collections::VecDeque;
widget_ids! {
struct Ids {
message_box,
message_box_bg,
input,
input_bg,
}
}
// Consider making this a Widget
pub struct Chat {
ids: Ids,
messages: VecDeque<String>,
input: String,
new_messages: bool,
}
impl Chat {
pub fn new(ui: &mut Ui) -> Self {
Chat {
ids: Ids::new(ui.id_generator()),
messages: VecDeque::new(),
input: String::new(),
new_messages: false,
}
}
pub fn new_message(&mut self, msg: String) {
self.messages.push_back(msg);
self.new_messages = true;
}
// Determine if the message box is scrolled to the bottom
// (i.e. the player is viewing new messages)
// If so scroll down when new messages are added
fn scroll_new_messages(&mut 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 scroll.offset >= scroll.offset_bounds.start {
ui_widgets.scroll_widget(self.ids.message_box, [0.0, std::f64::MAX]);
}
}
}
pub fn update_layout(&mut self, ui_widgets: &mut UiCell) {
// If enter is pressed send the current message
if ui_widgets
.widget_input(self.ids.input)
.presses()
.key()
.any(|key_press| match key_press.key {
Key::Return => true,
_ => false,
})
{
self.new_message(self.input.clone());
// Scroll to the bottom
// TODO: uncomment when we can actually get chat messages from other people
//ui_widgets.scroll_widget(self.ids.message_box, [0.0, std::f64::MAX]);
self.input.clear();
}
// Maintain scrolling
if self.new_messages {
self.scroll_new_messages(ui_widgets);
self.new_messages = false;
}
// Chat input with rectangle as background
let text_edit = TextEdit::new(&self.input)
.w(500.0)
.restrict_to_height(false)
.font_size(30)
.bottom_left_with_margin_on(ui_widgets.window, 10.0);
let dims = match (
text_edit.get_x_dimension(ui_widgets),
text_edit.get_y_dimension(ui_widgets),
) {
(Dimension::Absolute(x), Dimension::Absolute(y)) => [x, y],
_ => [0.0, 0.0],
};
Rectangle::fill(dims)
.rgba(0.0, 0.0, 0.0, 0.8)
.x_position(text_edit.get_x_position(ui_widgets))
.y_position(text_edit.get_y_position(ui_widgets))
.set(self.ids.input_bg, ui_widgets);
if let Some(str) = text_edit.set(self.ids.input, ui_widgets) {
self.input = str.to_string();
self.input.retain(|c| c != '\n');
}
// Message box
Rectangle::fill([500.0, 90.0])
.rgba(0.0, 0.0, 0.0, 0.5)
.up_from(self.ids.input, 0.0)
.set(self.ids.message_box_bg, ui_widgets);
let (mut items, scrollbar) = List::flow_down(self.messages.len())
.middle_of(self.ids.message_box_bg)
// Why does scrollbar disappear when the list is the exact same height as its contents?
.scrollbar_next_to()
.scrollbar_thickness(20.0)
.scrollbar_color(Color::Rgba(0.0, 0.0, 0.0, 1.0))
.set(self.ids.message_box, ui_widgets);
while let Some(item) = items.next(ui_widgets) {
item.set(
Text::new(&self.messages[item.i])
.font_size(30)
.rgba(1.0, 1.0, 1.0, 1.0),
ui_widgets,
)
}
if let Some(s) = scrollbar {
s.set(ui_widgets)
}
}
}

1214
voxygen/src/hud/mod.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
#![feature(drain_filter)] #![feature(drain_filter)]
#![recursion_limit="2048"]
pub mod anim; pub mod anim;
pub mod error; pub mod error;
pub mod hud;
pub mod key_state; pub mod key_state;
pub mod menu; pub mod menu;
pub mod mesh; pub mod mesh;

View File

@ -1,19 +1,14 @@
mod ui; mod ui;
use std::time::Duration;
use vek::*;
use common::clock::Clock;
use crate::{ use crate::{
PlayState,
PlayStateResult,
GlobalState,
window::{
Event,
Window,
},
session::SessionState, session::SessionState,
window::{Event, Window},
GlobalState, PlayState, PlayStateResult,
}; };
use common::clock::Clock;
use std::time::Duration;
use ui::MainMenuUi; use ui::MainMenuUi;
use vek::*;
const FPS: u64 = 60; const FPS: u64 = 60;
@ -25,18 +20,21 @@ impl MainMenuState {
/// Create a new `MainMenuState` /// Create a new `MainMenuState`
pub fn new(window: &mut Window) -> Self { pub fn new(window: &mut Window) -> Self {
Self { Self {
main_menu_ui: MainMenuUi::new(window) main_menu_ui: MainMenuUi::new(window),
} }
} }
} }
// The background colour // 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 PlayState for MainMenuState { impl PlayState for MainMenuState {
fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult { fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult {
// Set up an fps clock // Set up an fps clock
let mut clock = Clock::new(); let mut clock = Clock::new();
@ -50,14 +48,15 @@ impl PlayState for MainMenuState {
self.main_menu_ui.handle_event(input); self.main_menu_ui.handle_event(input);
} }
// Ignore all other events // Ignore all other events
_ => {}, _ => {}
} }
} }
global_state.window.renderer_mut().clear(BG_COLOR); global_state.window.renderer_mut().clear(BG_COLOR);
// Maintain the UI // Maintain the UI
self.main_menu_ui.maintain(global_state.window.renderer_mut()); self.main_menu_ui
.maintain(global_state.window.renderer_mut());
// Check if there should be a login attempt // Check if there should be a login attempt
if let Some((username, address)) = self.main_menu_ui.login_attempt() { if let Some((username, address)) = self.main_menu_ui.login_attempt() {
// For now just start a new session // For now just start a new session
@ -71,15 +70,17 @@ impl PlayState for MainMenuState {
// Finish the frame // Finish the frame
global_state.window.renderer_mut().flush(); global_state.window.renderer_mut().flush();
global_state.window global_state
.window
.swap_buffers() .swap_buffers()
.expect("Failed to swap window buffers"); .expect("Failed to swap window buffers");
// Wait for the next tick // Wait for the next tick
clock.tick(Duration::from_millis(1000 / FPS)); clock.tick(Duration::from_millis(1000 / FPS));
} }
} }
fn name(&self) -> &'static str { "Title" } fn name(&self) -> &'static str {
"Title"
}
} }

View File

@ -1,34 +1,27 @@
use crate::{
render::Renderer,
ui::{ScaleMode, Ui},
window::Window,
Error, GlobalState, PlayState, PlayStateResult,
};
use conrod_core::{ use conrod_core::{
Positionable, color::TRANSPARENT,
Sizeable,
Widget,
Labelable,
Colorable,
Borderable,
widget_ids,
event::Input, event::Input,
image::Id as ImgId, image::Id as ImgId,
text::font::Id as FontId, text::font::Id as FontId,
widget::{ widget::{text_box::Event as TextBoxEvent, Button, Canvas, Image, TextBox},
Image, widget_ids, Borderable, Color,
Button, Color::Rgba,
Canvas, Colorable, Labelable, Positionable, Sizeable, Widget,
TextBox,
text_box::Event as TextBoxEvent,
}
};
use crate::{
window::Window,
render::Renderer,
ui::{Ui, ScaleMode}
}; };
widget_ids!{ widget_ids! {
struct Ids { struct Ids {
// Background and logo // Background and logo
bg, bg,
v_logo, v_logo,
// Login alpha_version,
// Login, Singleplayer
login_button, login_button,
login_text, login_text,
address_text, address_text,
@ -37,6 +30,8 @@ widget_ids!{
username_text, username_text,
username_bg, username_bg,
username_field, username_field,
singleplayer_button,
singleplayer_text,
// Buttons // Buttons
servers_button, servers_button,
servers_text, servers_text,
@ -50,6 +45,7 @@ widget_ids!{
struct Imgs { struct Imgs {
bg: ImgId, bg: ImgId,
v_logo: ImgId, v_logo: ImgId,
alpha_version: ImgId,
address_text: ImgId, address_text: ImgId,
username_text: ImgId, username_text: ImgId,
@ -59,6 +55,7 @@ struct Imgs {
login_button: ImgId, login_button: ImgId,
login_button_hover: ImgId, login_button_hover: ImgId,
login_button_press: ImgId, login_button_press: ImgId,
singleplayer_text: ImgId,
servers_text: ImgId, servers_text: ImgId,
settings_text: ImgId, settings_text: ImgId,
@ -70,12 +67,21 @@ struct Imgs {
impl Imgs { impl Imgs {
fn new(ui: &mut Ui, renderer: &mut Renderer) -> Imgs { fn new(ui: &mut Ui, renderer: &mut Renderer) -> Imgs {
let mut load = |filename| { let mut load = |filename| {
let image = image::open(&[env!("CARGO_MANIFEST_DIR"), "/test_assets/ui/main/", filename].concat()).unwrap(); let image = image::open(
&[
env!("CARGO_MANIFEST_DIR"),
"/test_assets/ui/main/",
filename,
]
.concat(),
)
.unwrap();
ui.new_image(renderer, &image).unwrap() ui.new_image(renderer, &image).unwrap()
}; };
Imgs { Imgs {
bg: load("bg.png"), bg: load("bg.png"),
v_logo: load("v_logo_a01.png"), v_logo: load("v_logo.png"),
alpha_version: load("text/a01.png"),
// Input fields // Input fields
address_text: load("text/server_address.png"), address_text: load("text/server_address.png"),
@ -84,6 +90,7 @@ impl Imgs {
// Login button // Login button
login_text: load("text/login.png"), login_text: load("text/login.png"),
singleplayer_text: load("text/singleplayer.png"),
login_button: load("buttons/button_login.png"), login_button: load("buttons/button_login.png"),
login_button_hover: load("buttons/button_login_hover.png"), login_button_hover: load("buttons/button_login_hover.png"),
login_button_press: load("buttons/button_login_press.png"), login_button_press: load("buttons/button_login_press.png"),
@ -103,7 +110,8 @@ pub struct MainMenuUi {
ui: Ui, ui: Ui,
ids: Ids, ids: Ids,
imgs: Imgs, imgs: Imgs,
font_id: FontId, font_metamorph: FontId,
font_whitney: FontId,
username: String, username: String,
server_address: String, server_address: String,
attempt_login: bool, attempt_login: bool,
@ -118,17 +126,29 @@ impl MainMenuUi {
let ids = Ids::new(ui.id_generator()); let ids = Ids::new(ui.id_generator());
// Load images // Load images
let imgs = Imgs::new(&mut ui, window.renderer_mut()); let imgs = Imgs::new(&mut ui, window.renderer_mut());
// Load font // Load fonts
let font_id = ui.new_font(conrod_core::text::font::from_file( let font_whitney = ui.new_font(
concat!(env!("CARGO_MANIFEST_DIR"), "/test_assets/font/Metamorphous-Regular.ttf") conrod_core::text::font::from_file(concat!(
).unwrap()); env!("CARGO_MANIFEST_DIR"),
"/test_assets/font/Whitney-Book.ttf"
))
.unwrap(),
);
let font_metamorph = ui.new_font(
conrod_core::text::font::from_file(concat!(
env!("CARGO_MANIFEST_DIR"),
"/test_assets/font/Metamorphous-Regular.ttf"
))
.unwrap(),
);
Self { Self {
ui, ui,
imgs, imgs,
ids, ids,
font_id, font_metamorph,
font_whitney,
username: "Username".to_string(), username: "Username".to_string(),
server_address: "Server-Address".to_string(), server_address: "Server Address".to_string(),
attempt_login: false, attempt_login: false,
} }
} }
@ -145,13 +165,18 @@ impl MainMenuUi {
fn update_layout(&mut self) { fn update_layout(&mut self) {
let ref mut ui_widgets = self.ui.set_widgets(); let ref mut ui_widgets = self.ui.set_widgets();
// Background image & Veloren logo // Background image, Veloren logo, Alpha-Version Label
Image::new(self.imgs.bg) Image::new(self.imgs.bg)
.middle_of(ui_widgets.window) .middle_of(ui_widgets.window)
.set(self.ids.bg, ui_widgets); .set(self.ids.bg, ui_widgets);
Image::new(self.imgs.v_logo) Button::image(self.imgs.v_logo)
.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_rgba(255.0, 255.0, 255.0, 1.0)
.label_font_size(10)
.label_y(conrod_core::position::Relative::Scalar(-40.0))
.label_x(conrod_core::position::Relative::Scalar(-100.0))
.set(self.ids.v_logo, ui_widgets); .set(self.ids.v_logo, ui_widgets);
// Input fields // Input fields
@ -159,25 +184,21 @@ impl MainMenuUi {
macro_rules! login { macro_rules! login {
() => { () => {
self.attempt_login = true; self.attempt_login = true;
};
} }
}
use conrod_core::color::TRANSPARENT;
// 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)
.w_h(672.0/2.0, 166.0/2.0) .w_h(337.0, 67.0)
.middle_of(ui_widgets.window) .middle_of(ui_widgets.window)
.set(self.ids.username_bg, ui_widgets); .set(self.ids.username_bg, ui_widgets);
Image::new(self.imgs.username_text)
.w_h(149.0, 24.0)
.up(0.0)
.align_left()
.set(self.ids.username_text, ui_widgets);
// TODO: figure out why cursor is rendered inconsistently // TODO: figure out why cursor is rendered inconsistently
for event in TextBox::new(&self.username) for event in TextBox::new(&self.username)
.w_h(580.0/2.0, 60.0/2.0) .w_h(580.0 / 2.0, 60.0 / 2.0)
.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_whitney)
.text_color(Color::Rgba(220.0, 220.0, 220.0, 0.8))
// transparent background // transparent background
.color(TRANSPARENT) .color(TRANSPARENT)
.border_color(TRANSPARENT) .border_color(TRANSPARENT)
@ -192,20 +213,16 @@ impl MainMenuUi {
} }
} }
// Server address // Server address
Image::new(self.imgs.address_text)
.w_h(227.0, 28.0)
.down_from(self.ids.username_bg, 10.0)
.align_left_of(self.ids.username_bg)
.set(self.ids.address_text, ui_widgets);
Image::new(self.imgs.input_bg) Image::new(self.imgs.input_bg)
.w_h(672.0/2.0, 166.0/2.0) .w_h(337.0, 67.0)
.down(0.0) .down_from(self.ids.username_bg, 10.0)
.align_left()
.set(self.ids.address_bg, ui_widgets); .set(self.ids.address_bg, ui_widgets);
for event in TextBox::new(&self.server_address) for event in TextBox::new(&self.server_address)
.w_h(580.0/2.0, 60.0/2.0) .w_h(580.0 / 2.0, 60.0 / 2.0)
.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_whitney)
.text_color(Color::Rgba(220.0, 220.0, 220.0, 0.8))
// transparent background // transparent background
.color(TRANSPARENT) .color(TRANSPARENT)
.border_color(TRANSPARENT) .border_color(TRANSPARENT)
@ -225,54 +242,74 @@ impl MainMenuUi {
.w_h(258.0, 68.0) .w_h(258.0, 68.0)
.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_rgba(220.0, 220.0, 220.0, 0.8)
.label_font_size(28)
.label_y(conrod_core::position::Relative::Scalar(5.0))
.set(self.ids.login_button, ui_widgets) .set(self.ids.login_button, ui_widgets)
.was_clicked() .was_clicked()
{ {
login!(); login!();
} }
Image::new(self.imgs.login_text) //Singleplayer button
.w_h(83.0, 34.0) if Button::image(self.imgs.login_button)
.graphics_for(self.ids.login_button) // capture the input for the button .hover_image(self.imgs.login_button_hover)
.middle_of(self.ids.login_button) .press_image(self.imgs.login_button_press)
.set(self.ids.login_text, ui_widgets); .w_h(258.0, 68.0)
.down_from(self.ids.login_button, 20.0)
// Other buttons .align_middle_x_of(self.ids.address_bg)
.label("Singleplayer")
.label_rgba(220.0, 220.0, 220.0, 0.8)
.label_font_size(26)
.label_y(conrod_core::position::Relative::Scalar(5.0))
.label_x(conrod_core::position::Relative::Scalar(2.0))
.set(self.ids.singleplayer_button, ui_widgets)
.was_clicked()
{
login!();
}
// Quit // Quit
Button::image(self.imgs.button) if Button::image(self.imgs.button)
.w_h(203.0, 53.0) .w_h(203.0, 53.0)
.bottom_left_with_margins_on(ui_widgets.window, 60.0, 30.0) .bottom_left_with_margins_on(ui_widgets.window, 60.0, 30.0)
.hover_image(self.imgs.button_hover) .hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press) .press_image(self.imgs.button_press)
.set(self.ids.quit_button, ui_widgets); .label("Quit")
Image::new(self.imgs.quit_text) .label_rgba(220.0, 220.0, 220.0, 0.8)
.w_h(52.0, 26.0) .label_font_size(20)
.graphics_for(self.ids.quit_button) // capture the input for the button .label_y(conrod_core::position::Relative::Scalar(3.0))
.middle_of(self.ids.quit_button) .set(self.ids.quit_button, ui_widgets)
.set(self.ids.quit_text, ui_widgets); .was_clicked()
{
use PlayStateResult::Shutdown;
PlayStateResult::Pop;
};
// Settings // Settings
Button::image(self.imgs.button) if Button::image(self.imgs.button)
.w_h(203.0, 53.0) .w_h(203.0, 53.0)
.up_from(self.ids.quit_button, 8.0) .up_from(self.ids.quit_button, 8.0)
.hover_image(self.imgs.button_hover) .hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press) .press_image(self.imgs.button_press)
.set(self.ids.settings_button, ui_widgets); .label("Settings")
Image::new(self.imgs.settings_text) .label_rgba(220.0, 220.0, 220.0, 0.8)
.w_h(98.0, 28.0) .label_font_size(20)
.graphics_for(self.ids.settings_button) .label_y(conrod_core::position::Relative::Scalar(3.0))
.middle_of(self.ids.settings_button) .set(self.ids.settings_button, ui_widgets)
.set(self.ids.settings_text, ui_widgets); .was_clicked()
{};
// Servers // Servers
Button::image(self.imgs.button) if Button::image(self.imgs.button)
.w_h(203.0, 53.0) .w_h(203.0, 53.0)
.up_from(self.ids.settings_button, 8.0) .up_from(self.ids.settings_button, 8.0)
.hover_image(self.imgs.button_hover) .hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press) .press_image(self.imgs.button_press)
.set(self.ids.servers_button, ui_widgets); .label("Servers")
Image::new(self.imgs.servers_text) .label_rgba(220.0, 220.0, 220.0, 0.8)
.w_h(93.0, 20.0) .label_font_size(20)
.graphics_for(self.ids.servers_button) .label_y(conrod_core::position::Relative::Scalar(3.0))
.middle_of(self.ids.servers_button) .set(self.ids.servers_button, ui_widgets)
.set(self.ids.servers_text, ui_widgets); .was_clicked()
{};
} }
pub fn handle_event(&mut self, input: Input) { pub fn handle_event(&mut self, input: Input) {

View File

@ -1,3 +1,2 @@
pub mod title;
pub mod main; pub mod main;
pub mod test_hud; pub mod title;

View File

@ -1,273 +0,0 @@
// TODO: figure out where exactly this code should be located
// Library
use conrod_core::{
Positionable,
Sizeable,
Widget,
Labelable,
widget_ids,
event::Input,
image::Id as ImgId,
text::font::Id as FontId,
widget::{
Image,
Button,
Canvas,
}
};
// Crate
use crate::{
window::Window,
render::Renderer,
ui::Ui,
};
widget_ids!{
struct Ids {
bag,
bag_contents,
bag_close,
menu_top,
menu_mid,
menu_bot,
menu_canvas,
menu_buttons[],
bag_belt,
belt_buttons[],
mmap_frame,
sbar_bg
}
}
// TODO: make macro to mimic widget_ids! for images ids or find another solution to simplify addition of new images.
struct Imgs {
//Missing: ActionBar, Health/Mana/Energy Bar & Char Window BG/Frame
// Bag
bag: ImgId,
bag_hover: ImgId,
bag_press: ImgId,
bag_open: ImgId,
bag_open_hover: ImgId,
bag_open_press: ImgId,
bag_contents: ImgId,
// Close button
close_button: ImgId,
close_button_hover: ImgId,
close_button_press: ImgId,
// Settings belt
belt_bg: ImgId,
belt_grid: ImgId,
belt_grid_hover: ImgId,
belt_grid_press: ImgId,
//belt_grid_open: ImgId,
// Menu
menu_top: ImgId,
menu_mid: ImgId,
menu_bot: ImgId,
menu_button: ImgId,
// MiniMap
mmap_frame: ImgId,
// SkillBar
sbar_bg: ImgId
}
impl Imgs {
fn new(ui: &mut Ui, renderer: &mut Renderer) -> Imgs {
let mut load = |filename| {
let image = image::open(&[env!("CARGO_MANIFEST_DIR"), "/test_assets/ui/hud/", filename].concat()).unwrap();
ui.new_image(renderer, &image).unwrap()
};
Imgs {
// Bag
bag: load("bag/icon/0_bag.png"),
bag_hover: load("bag/icon/1_bag_hover.png"),
bag_press: load("bag/icon/2_bag_press.png"),
bag_open: load("bag/icon/3_bag_open.png"),
bag_open_hover: load("bag/icon/4_bag_open_hover.png"),
bag_open_press: load("bag/icon/5_bag_open_press.png"),
bag_contents: load("bag/bg.png"),
// Close button
close_button: load("x/0_x.png"),
close_button_hover: load("x/1_x_hover.png"),
close_button_press: load("x/2_x_press.png"),
// Settings belt
belt_bg: load("belt/belt_bg.png"),
belt_grid: load("belt/belt_grid.png"),
belt_grid_hover: load("belt/belt_hover.png"),
belt_grid_press: load("belt/belt_press.png"),
//belt_grid_open: load("belt/belt_open.png"),
// Menu
menu_button: load("menu/main/menu_button.png"),
menu_top: load("menu/main/menu_top.png"),
menu_mid: load("menu/main/menu_mid.png"),
menu_bot: load("menu/main/menu_bottom.png"),
// MiniMap
mmap_frame: load("mmap/mmap_frame.png"),
// SkillBar
sbar_bg: load("skill_bar/sbar_bg.png"),
}
}
}
pub struct TestHud {
ui: Ui,
ids: Ids,
imgs: Imgs,
bag_open: bool,
menu_open: bool,
font_id: FontId,
}
impl TestHud {
pub fn new(window: &mut Window) -> Self {
let mut ui = Ui::new(window).unwrap();
// Generate ids
let mut ids = Ids::new(ui.id_generator());
ids.menu_buttons.resize(5, &mut ui.id_generator());
ids.belt_buttons.resize(6, &mut ui.id_generator());
// Load images
let imgs = Imgs::new(&mut ui, window.renderer_mut());
// Load font
let font_id = ui.new_font(conrod_core::text::font::from_file(
concat!(env!("CARGO_MANIFEST_DIR"), "/test_assets/font/Metamorphous-Regular.ttf")
).unwrap());
Self {
ui,
imgs,
ids,
bag_open: false,
menu_open: false,
font_id,
}
}
fn update_layout(&mut self) {
let ref mut ui_widgets = self.ui.set_widgets();
// Check if the bag was clicked
// (can't use .was_clicked() because we are changing the image and this is after setting the widget which causes flickering as it takes a frame to change after the mouse button is lifted)
if ui_widgets.widget_input(self.ids.bag).clicks().left().count() % 2 == 1 {
self.bag_open = !self.bag_open;
}
// Bag contents
// Note that display_contents is set before checking if the bag was clicked
// this ensures that the contents and open bag img are displayed on the same frame
if self.bag_open {
// Contents
Image::new(self.imgs.bag_contents)
.w_h(1504.0/4.0, 1760.0/4.0)
.bottom_right_with_margins(88.0, 68.0)
.set(self.ids.bag_contents, ui_widgets);
// X-button
if Button::image(self.imgs.close_button)
.w_h(144.0/4.0, 144.0/4.0)
.hover_image(self.imgs.close_button_hover)
.press_image(self.imgs.close_button_press)
.top_right_with_margins_on(self.ids.bag_contents, 0.0, 12.0)
.set(self.ids.bag_close, ui_widgets)
.was_clicked() {
self.bag_open = false;
}
}
// Belt menu
Image::new(self.imgs.belt_bg)
.w_h(448.0/2.0, 56.0/2.0)
.bottom_left_with_margins_on(self.ids.bag, 5.0, -167.0)
.set(self.ids.bag_belt, ui_widgets);
// Belt buttons
for i in 0..6 {
Button::image(self.imgs.belt_grid)
.w_h(56.0/2.0, 56.0/2.0)
.bottom_left_with_margins_on(self.ids.bag_belt, 0.0, 28.0 * i as f64)
.hover_image(self.imgs.belt_grid_hover)
.press_image(self.imgs.belt_grid_press)
.set(self.ids.belt_buttons[i], ui_widgets);
}
// Minimap frame
Image::new(self.imgs.mmap_frame)
.w_h(1232.0/8.0, 976.0/8.0)
.top_right_of(ui_widgets.window)
.set(self.ids.mmap_frame, ui_widgets);
// Action bar
Image::new(self.imgs.sbar_bg)
.w_h(2240.0/8.0, 906.0/8.0)
.mid_bottom_of(ui_widgets.window)
.set(self.ids.sbar_bg, ui_widgets);
// Bag
Button::image(if self.bag_open {self.imgs.bag_open} else {self.imgs.bag})
.bottom_right_with_margin_on(ui_widgets.window, 20.0)
.hover_image(if self.bag_open {self.imgs.bag_open_hover} else {self.imgs.bag_hover})
.press_image(if self.bag_open {self.imgs.bag_open_press} else {self.imgs.bag_press})
.w_h(420.0/4.0, 480.0/4.0)
.set(self.ids.bag, ui_widgets);
// An attempt to make a resizable image based container for buttons
// Maybe this could be made into a Widget type if it is useful
if self.menu_open {
let num = self.ids.menu_buttons.len();
// Canvas to hold everything together
Canvas::new()
.w_h(106.0, 54.0 + num as f64 * 30.0)
.middle_of(ui_widgets.window)
.set(self.ids.menu_canvas, ui_widgets);
// Top of menu
Image::new(self.imgs.menu_top)
.w_h(106.0, 28.0)
.mid_top_of(self.ids.menu_canvas)
.set(self.ids.menu_top, ui_widgets);
// Bottom of Menu
// Note: conrod defaults to the last used parent
Image::new(self.imgs.menu_bot)
.w_h(106.0, 26.0)
.mid_bottom()
.set(self.ids.menu_bot, ui_widgets);
// Midsection background
Image::new(self.imgs.menu_mid)
.w_h(106.0, num as f64 * 30.0)
.mid_bottom_with_margin(26.0)
.set(self.ids.menu_mid, ui_widgets);
// Menu buttons
if num > 0 {
Button::image(self.imgs.menu_button)
.mid_top_with_margin_on(self.ids.menu_mid, 8.0)
.w_h(48.0, 20.0)
.label(&format!("Button {}", 1))
.label_rgb(1.0, 0.4, 1.0)
.label_font_size(7)
.set(self.ids.menu_buttons[0], ui_widgets);
}
for i in 1..num {
Button::image(self.imgs.menu_button)
.down(10.0)
.label(&format!("Button {}", i + 1))
.label_rgb(1.0, 0.4, 1.0)
.label_font_size(7)
.set(self.ids.menu_buttons[i], ui_widgets);
}
}
}
pub fn toggle_menu(&mut self) {
self.menu_open = !self.menu_open;
}
pub fn handle_event(&mut self, input: Input) {
self.ui.handle_event(input);
}
pub fn maintain(&mut self, renderer: &mut Renderer) {
self.update_layout();
self.ui.maintain(renderer);
}
pub fn render(&self, renderer: &mut Renderer) {
self.ui.render(renderer);
}
}

View File

@ -1,19 +1,14 @@
mod ui; mod ui;
use std::time::Duration;
use vek::*;
use common::clock::Clock;
use crate::{
PlayState,
PlayStateResult,
GlobalState,
window::{
Event,
Window,
},
};
use super::main::MainMenuState; use super::main::MainMenuState;
use crate::{
window::{Event, Window},
GlobalState, PlayState, PlayStateResult,
};
use common::clock::Clock;
use std::time::Duration;
use ui::TitleUi; use ui::TitleUi;
use vek::*;
const FPS: u64 = 60; const FPS: u64 = 60;
@ -25,18 +20,21 @@ impl TitleState {
/// Create a new `TitleState` /// Create a new `TitleState`
pub fn new(window: &mut Window) -> Self { pub fn new(window: &mut Window) -> Self {
Self { Self {
title_ui: TitleUi::new(window) title_ui: TitleUi::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 PlayState for TitleState { impl PlayState for TitleState {
fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult { fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult {
// Set up an fps clock // Set up an fps clock
let mut clock = Clock::new(); let mut clock = Clock::new();
@ -45,16 +43,18 @@ impl PlayState for TitleState {
for event in global_state.window.fetch_events() { for event in global_state.window.fetch_events() {
match event { match event {
Event::Close => return PlayStateResult::Shutdown, Event::Close => return PlayStateResult::Shutdown,
// When space is pressed, go to the main menu // When any key is pressed, go to the main menu
Event::Char(' ') => return PlayStateResult::Push( Event::Char(_) => {
Box::new(MainMenuState::new(&mut global_state.window)), return PlayStateResult::Push(Box::new(MainMenuState::new(
), &mut global_state.window,
)));
}
// Pass events to ui // Pass events to ui
Event::UiEvent(input) => { Event::UiEvent(input) => {
self.title_ui.handle_event(input); self.title_ui.handle_event(input);
} }
// Ignore all other events // Ignore all other events
_ => {}, _ => {}
} }
} }
@ -68,15 +68,17 @@ impl PlayState for TitleState {
// Finish the frame // Finish the frame
global_state.window.renderer_mut().flush(); global_state.window.renderer_mut().flush();
global_state.window global_state
.window
.swap_buffers() .swap_buffers()
.expect("Failed to swap window buffers"); .expect("Failed to swap window buffers");
// Wait for the next tick // Wait for the next tick
clock.tick(Duration::from_millis(1000 / FPS)); clock.tick(Duration::from_millis(1000 / FPS));
} }
} }
fn name(&self) -> &'static str { "Title" } fn name(&self) -> &'static str {
"Title"
}
} }

View File

@ -1,17 +1,9 @@
use crate::{render::Renderer, ui::Ui, window::Window};
use conrod_core::{ use conrod_core::{
Positionable,
Widget,
event::Input, event::Input,
image::Id as ImgId, image::Id as ImgId,
widget::{ widget::{Id as WidgId, Image as ImageWidget},
Image as ImageWidget, Positionable, Widget,
Id as WidgId,
}
};
use crate::{
window::Window,
render::Renderer,
ui::Ui
}; };
pub struct TitleUi { pub struct TitleUi {
@ -24,7 +16,12 @@ impl TitleUi {
pub fn new(window: &mut Window) -> Self { pub fn new(window: &mut Window) -> Self {
let mut ui = Ui::new(window).unwrap(); let mut ui = Ui::new(window).unwrap();
let widget_id = ui.id_generator().next(); let widget_id = ui.id_generator().next();
let image = image::open(concat!(env!("CARGO_MANIFEST_DIR"), "/test_assets/ui/title/test.png")).unwrap(); // TODO: use separate image for logo
let image = image::open(concat!(
env!("CARGO_MANIFEST_DIR"),
"/test_assets/ui/title/splash.png"
))
.unwrap();
let title_img_id = ui.new_image(window.renderer_mut(), &image).unwrap(); let title_img_id = ui.new_image(window.renderer_mut(), &image).unwrap();
Self { Self {
ui, ui,

View File

@ -21,7 +21,7 @@ use crate::{
window::{Event, Key, Window}, window::{Event, Key, Window},
render::Renderer, render::Renderer,
scene::Scene, scene::Scene,
menu::test_hud::TestHud, hud::Hud,
}; };
const FPS: u64 = 60; const FPS: u64 = 60;
@ -30,8 +30,7 @@ pub struct SessionState {
scene: Scene, scene: Scene,
client: Client, client: Client,
key_state: KeyState, key_state: KeyState,
// TODO: remove this hud: Hud,
test_hud: TestHud,
} }
/// Represents an active game session (i.e: one that is being played) /// Represents an active game session (i.e: one that is being played)
@ -44,7 +43,7 @@ impl SessionState {
scene: Scene::new(window.renderer_mut(), &client), scene: Scene::new(window.renderer_mut(), &client),
client, client,
key_state: KeyState::new(), key_state: KeyState::new(),
test_hud: TestHud::new(window), hud: Hud::new(window),
}) })
} }
} }
@ -83,7 +82,7 @@ impl SessionState {
// Render the screen using the global renderer // Render the screen using the global renderer
self.scene.render_to(renderer); self.scene.render_to(renderer);
// Draw the UI to the screen // Draw the UI to the screen
self.test_hud.render(renderer); self.hud.render(renderer);
// Finish the frame // Finish the frame
renderer.flush(); renderer.flush();
@ -111,12 +110,16 @@ impl PlayState for SessionState {
loop { loop {
// Handle window events // Handle window events
for event in global_state.window.fetch_events() { for event in global_state.window.fetch_events() {
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 // When 'q' is pressed, exit the session
Event::Char('q') => return PlayStateResult::Pop, Event::Char('q') => return PlayStateResult::Pop,
// When 'm' is pressed, open/close the in-game test menu // When 'm' is pressed, open/close the in-game test menu
Event::Char('m') => self.test_hud.toggle_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.window.grab_cursor(!global_state.window.is_cursor_grabbed());
@ -133,7 +136,7 @@ impl PlayState for SessionState {
Event::KeyUp(Key::MoveRight) => self.key_state.right = false, Event::KeyUp(Key::MoveRight) => self.key_state.right = false,
// Pass events to ui // Pass events to ui
Event::UiEvent(input) => { Event::UiEvent(input) => {
self.test_hud.handle_event(input); self.hud.handle_event(input);
} }
// 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); },
@ -148,7 +151,7 @@ impl PlayState for SessionState {
// 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);
// Maintain the UI // Maintain the UI
self.test_hud.maintain(global_state.window.renderer_mut()); self.hud.maintain(global_state.window.renderer_mut());
// Render the session // Render the session
self.render(global_state.window.renderer_mut()); self.render(global_state.window.renderer_mut());

View File

@ -28,13 +28,13 @@ impl Window {
let events_loop = glutin::EventsLoop::new(); let events_loop = glutin::EventsLoop::new();
let win_builder = glutin::WindowBuilder::new() let win_builder = glutin::WindowBuilder::new()
.with_title("Veloren (Voxygen)") .with_title("Veloren")
.with_dimensions(glutin::dpi::LogicalSize::new(800.0, 500.0)) .with_dimensions(glutin::dpi::LogicalSize::new(1366.0, 768.0))
.with_maximized(false); .with_maximized(true);
let ctx_builder = glutin::ContextBuilder::new() let ctx_builder = glutin::ContextBuilder::new()
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2))) .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)))
.with_vsync(true); .with_vsync(false);
let ( let (
window, window,
@ -49,7 +49,8 @@ impl Window {
).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::Escape, Key::ToggleCursor); key_map.insert(glutin::VirtualKeyCode::Tab, Key::ToggleCursor);
key_map.insert(glutin::VirtualKeyCode::Escape, Key::Escape);
key_map.insert(glutin::VirtualKeyCode::W, Key::MoveForward); key_map.insert(glutin::VirtualKeyCode::W, Key::MoveForward);
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);
@ -101,6 +102,7 @@ impl Window {
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 {
@ -157,6 +159,7 @@ pub enum Key {
MoveBack, MoveBack,
MoveLeft, MoveLeft,
MoveRight, MoveRight,
Escape,
} }
/// Represents an incoming event from the window /// Represents an incoming event from the window

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/hud/charwindow/bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/charwindow/icon.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/hud/map/bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/map/icon.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/map/window_frame_map.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/hud/menu/Button_dark_press.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/menu/bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/menu/button_dark.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/menu/button_dark_hover.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/menu/fireplace_1.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/mmap/grid.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/mmap/hover.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/mmap/mmap_bg.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/mmap/mmap_icons.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/mmap/open.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/mmap/press.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/hud/questlog/bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/questlog/icon.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/hud/settings/bg.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

BIN
voxygen/test_assets/ui/hud/settings/check.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/check_checked.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/check_checked_mo.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/check_mo.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/check_press.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/icon.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/mo.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/press.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/slider.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/settings/slider_indicator.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

BIN
voxygen/test_assets/ui/hud/skill_bar/health_bar.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/health_bar_filled.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/l.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/mana_bar.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/mana_bar_full.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/r.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/sbar_grid.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/sbar_grid_bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/xp_bar.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/xp_bar_l.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/xp_bar_l_filled.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/skill_bar/xp_bar_r.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/hud/social/bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/social/icon.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/hud/spellbook/bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/spellbook/icon.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/window_frame.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/window_frame_map.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/window_frame_old.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/x/0_x.png (Stored with Git LFS)

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/x/1_x_hover.png (Stored with Git LFS)

Binary file not shown.

BIN
voxygen/test_assets/ui/hud/x/2_x_press.png (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/main/text/White/login.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/White/quit.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/White/server_address.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/White/servers.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/White/settings.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/White/username.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text

BIN
voxygen/test_assets/ui/main/text/Yellow/a01.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/Yellow/login.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/Yellow/quit.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/Yellow/server_address.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/Yellow/servers.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/Yellow/settings.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/Yellow/username.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
voxygen/test_assets/ui/main/text/a01.png (Stored with Git LFS) Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More