2019-05-04 10:43:37 +00:00
|
|
|
mod bag;
|
2019-05-07 05:40:03 +00:00
|
|
|
mod buttons;
|
|
|
|
mod character_window;
|
|
|
|
mod chat;
|
2019-05-03 16:56:18 +00:00
|
|
|
mod esc_menu;
|
2019-05-07 05:40:03 +00:00
|
|
|
mod img_ids;
|
|
|
|
mod map;
|
2019-05-07 17:50:53 +00:00
|
|
|
mod minimap;
|
2019-05-07 05:40:03 +00:00
|
|
|
mod settings_window;
|
|
|
|
mod skillbar;
|
|
|
|
mod small_window;
|
2019-04-26 20:24:05 +00:00
|
|
|
|
2019-05-04 10:43:37 +00:00
|
|
|
use bag::Bag;
|
|
|
|
use buttons::Buttons;
|
2019-05-07 05:40:03 +00:00
|
|
|
use character_window::CharacterWindow;
|
|
|
|
use chat::Chat;
|
2019-05-03 16:56:18 +00:00
|
|
|
use esc_menu::EscMenu;
|
2019-05-07 05:40:03 +00:00
|
|
|
use img_ids::Imgs;
|
|
|
|
use map::Map;
|
2019-05-07 17:50:53 +00:00
|
|
|
use minimap::MiniMap;
|
2019-05-07 05:40:03 +00:00
|
|
|
use settings_window::SettingsWindow;
|
|
|
|
use skillbar::Skillbar;
|
|
|
|
use small_window::{SmallWindow, SmallWindowType};
|
2019-03-15 04:55:52 +00:00
|
|
|
|
|
|
|
use crate::{
|
|
|
|
render::Renderer,
|
2019-04-29 21:23:31 +00:00
|
|
|
settings::{ControlSettings, Settings},
|
2019-05-04 17:24:26 +00:00
|
|
|
ui::{ScaleMode, Ui},
|
2019-04-01 20:31:29 +00:00
|
|
|
window::{Event as WinEvent, Key, Window},
|
2019-04-20 18:08:39 +00:00
|
|
|
GlobalState,
|
2019-03-15 04:55:52 +00:00
|
|
|
};
|
|
|
|
use conrod_core::{
|
2019-05-07 05:40:03 +00:00
|
|
|
color, graph,
|
|
|
|
widget::{self, Button, Image, Rectangle, Text},
|
|
|
|
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
2019-03-15 04:55:52 +00:00
|
|
|
};
|
2019-05-03 16:56:18 +00:00
|
|
|
use std::collections::VecDeque;
|
2019-03-15 04:55:52 +00:00
|
|
|
|
2019-04-30 20:43:55 +00:00
|
|
|
const XP_COLOR: Color = Color::Rgba(0.59, 0.41, 0.67, 1.0);
|
2019-04-26 20:24:05 +00:00
|
|
|
const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
|
|
|
const HP_COLOR: Color = Color::Rgba(0.33, 0.63, 0.0, 1.0);
|
|
|
|
const MANA_COLOR: Color = Color::Rgba(0.42, 0.41, 0.66, 1.0);
|
|
|
|
|
2019-03-15 04:55:52 +00:00
|
|
|
widget_ids! {
|
|
|
|
struct Ids {
|
2019-04-02 04:54:27 +00:00
|
|
|
// Test
|
|
|
|
bag_space_add,
|
2019-04-26 16:13:30 +00:00
|
|
|
// Debug
|
2019-04-22 18:47:22 +00:00
|
|
|
debug_bg,
|
|
|
|
fps_counter,
|
2019-05-23 08:18:25 +00:00
|
|
|
ping,
|
2019-05-07 05:40:03 +00:00
|
|
|
|
2019-04-26 16:13:30 +00:00
|
|
|
// Game Version
|
|
|
|
version,
|
2019-04-02 14:25:14 +00:00
|
|
|
|
2019-04-25 12:20:35 +00:00
|
|
|
// Help
|
2019-03-28 02:25:08 +00:00
|
|
|
help,
|
|
|
|
help_bg,
|
2019-04-25 12:20:35 +00:00
|
|
|
|
|
|
|
// Window Frames
|
2019-03-15 04:55:52 +00:00
|
|
|
window_frame_0,
|
|
|
|
window_frame_1,
|
|
|
|
window_frame_2,
|
|
|
|
window_frame_3,
|
|
|
|
window_frame_4,
|
|
|
|
window_frame_5,
|
2019-04-25 12:20:35 +00:00
|
|
|
|
|
|
|
// Contents
|
2019-03-16 02:03:21 +00:00
|
|
|
button_help2,
|
2019-04-30 14:39:19 +00:00
|
|
|
|
|
|
|
// External
|
2019-05-03 16:56:18 +00:00
|
|
|
chat,
|
2019-04-30 14:39:19 +00:00
|
|
|
map,
|
|
|
|
character_window,
|
2019-05-07 17:21:53 +00:00
|
|
|
minimap,
|
2019-05-04 10:43:37 +00:00
|
|
|
bag,
|
2019-05-04 06:07:23 +00:00
|
|
|
skillbar,
|
2019-05-04 10:43:37 +00:00
|
|
|
buttons,
|
2019-05-03 16:56:18 +00:00
|
|
|
esc_menu,
|
|
|
|
small_window,
|
|
|
|
settings_window,
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-08 20:25:15 +00:00
|
|
|
font_ids! {
|
|
|
|
pub struct Fonts {
|
2019-05-18 18:05:15 +00:00
|
|
|
opensans: "voxygen/font/OpenSans-Regular.ttf",
|
|
|
|
metamorph: "voxygen/font/Metamorphous-Regular.ttf",
|
2019-05-08 20:25:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-16 02:03:21 +00:00
|
|
|
pub enum Event {
|
|
|
|
SendMessage(String),
|
2019-05-19 00:45:02 +00:00
|
|
|
AdjustViewDistance(u32),
|
2019-05-19 19:31:32 +00:00
|
|
|
AdjustVolume(f32),
|
2019-05-20 14:53:12 +00:00
|
|
|
ChangeAudioDevice(String),
|
2019-03-16 02:03:21 +00:00
|
|
|
Logout,
|
|
|
|
Quit,
|
|
|
|
}
|
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// TODO: Are these the possible layouts we want?
|
|
|
|
// TODO: Maybe replace this with bitflags.
|
|
|
|
// `map` is not here because it currently is displayed over the top of other open windows.
|
2019-05-04 10:43:37 +00:00
|
|
|
#[derive(PartialEq)]
|
|
|
|
pub enum Windows {
|
2019-05-17 09:22:32 +00:00
|
|
|
Settings, // Display settings window.
|
|
|
|
CharacterAnd(Option<SmallWindowType>), // Show character window + optionally another.
|
2019-05-03 16:56:18 +00:00
|
|
|
Small(SmallWindowType),
|
2019-03-28 04:00:51 +00:00
|
|
|
None,
|
|
|
|
}
|
|
|
|
|
2019-05-04 17:24:26 +00:00
|
|
|
pub struct Show {
|
|
|
|
ui: bool,
|
|
|
|
help: bool,
|
|
|
|
debug: bool,
|
|
|
|
bag: bool,
|
|
|
|
esc_menu: bool,
|
|
|
|
open_windows: Windows,
|
|
|
|
map: bool,
|
|
|
|
inventory_test_button: bool,
|
2019-05-07 05:40:03 +00:00
|
|
|
mini_map: bool,
|
2019-05-07 20:00:03 +00:00
|
|
|
|
2019-05-09 16:55:13 +00:00
|
|
|
want_grab: bool,
|
2019-05-04 17:24:26 +00:00
|
|
|
}
|
|
|
|
impl Show {
|
|
|
|
fn toggle_bag(&mut self) {
|
2019-05-07 20:00:03 +00:00
|
|
|
self.bag = !self.bag;
|
2019-05-09 16:55:13 +00:00
|
|
|
self.want_grab = !self.bag;
|
2019-05-04 17:24:26 +00:00
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-04 17:24:26 +00:00
|
|
|
fn toggle_map(&mut self) {
|
|
|
|
self.map = !self.map;
|
|
|
|
self.bag = false;
|
2019-05-09 16:55:13 +00:00
|
|
|
self.want_grab = !self.map;
|
2019-05-04 17:24:26 +00:00
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-04 17:24:26 +00:00
|
|
|
fn toggle_mini_map(&mut self) {
|
|
|
|
self.mini_map = !self.mini_map;
|
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-04 17:24:26 +00:00
|
|
|
fn toggle_small(&mut self, target: SmallWindowType) {
|
|
|
|
self.open_windows = match self.open_windows {
|
|
|
|
Windows::Small(small) if small == target => Windows::None,
|
|
|
|
Windows::None | Windows::Small(_) => Windows::Small(target),
|
|
|
|
Windows::CharacterAnd(small) => match small {
|
|
|
|
Some(small) if small == target => Windows::CharacterAnd(None),
|
|
|
|
_ => Windows::CharacterAnd(Some(target)),
|
|
|
|
},
|
|
|
|
Windows::Settings => Windows::Settings,
|
|
|
|
};
|
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
fn toggle_char_window(&mut self) {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.open_windows = match self.open_windows {
|
|
|
|
Windows::CharacterAnd(small) => match small {
|
|
|
|
Some(small) => Windows::Small(small),
|
|
|
|
None => Windows::None,
|
|
|
|
},
|
|
|
|
Windows::Small(small) => Windows::CharacterAnd(Some(small)),
|
|
|
|
Windows::None => Windows::CharacterAnd(None),
|
|
|
|
Windows::Settings => Windows::Settings,
|
|
|
|
}
|
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-04 17:24:26 +00:00
|
|
|
fn toggle_settings(&mut self) {
|
|
|
|
self.open_windows = match self.open_windows {
|
|
|
|
Windows::Settings => Windows::None,
|
|
|
|
_ => Windows::Settings,
|
|
|
|
};
|
|
|
|
self.bag = false;
|
2019-05-09 16:55:13 +00:00
|
|
|
self.want_grab = self.open_windows != Windows::Settings;
|
2019-05-04 17:24:26 +00:00
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-04 17:24:26 +00:00
|
|
|
fn toggle_help(&mut self) {
|
|
|
|
self.help = !self.help
|
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-04 17:24:26 +00:00
|
|
|
fn toggle_ui(&mut self) {
|
|
|
|
self.ui = !self.ui;
|
|
|
|
}
|
|
|
|
|
2019-05-07 20:00:03 +00:00
|
|
|
fn toggle_windows(&mut self) {
|
2019-05-04 17:24:26 +00:00
|
|
|
if self.bag
|
|
|
|
|| self.esc_menu
|
|
|
|
|| self.map
|
|
|
|
|| match self.open_windows {
|
|
|
|
Windows::None => false,
|
|
|
|
_ => true,
|
|
|
|
}
|
|
|
|
{
|
|
|
|
self.bag = false;
|
|
|
|
self.esc_menu = false;
|
|
|
|
self.map = false;
|
|
|
|
self.open_windows = Windows::None;
|
2019-05-09 16:55:13 +00:00
|
|
|
self.want_grab = true;
|
2019-05-04 17:24:26 +00:00
|
|
|
} else {
|
|
|
|
self.esc_menu = true;
|
2019-05-09 16:55:13 +00:00
|
|
|
self.want_grab = false;
|
2019-05-04 17:24:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-15 04:55:52 +00:00
|
|
|
pub struct Hud {
|
|
|
|
ui: Ui,
|
|
|
|
ids: Ids,
|
|
|
|
imgs: Imgs,
|
2019-04-30 20:43:55 +00:00
|
|
|
fonts: Fonts,
|
2019-05-03 16:56:18 +00:00
|
|
|
new_messages: VecDeque<String>,
|
2019-04-04 13:51:36 +00:00
|
|
|
inventory_space: u32,
|
2019-05-04 17:24:26 +00:00
|
|
|
show: Show,
|
2019-05-07 03:25:25 +00:00
|
|
|
to_focus: Option<Option<widget::Id>>,
|
2019-05-09 08:55:32 +00:00
|
|
|
force_ungrab: bool,
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Hud {
|
2019-05-21 01:21:31 +00:00
|
|
|
pub fn new(window: &mut Window) -> Self {
|
2019-03-15 04:55:52 +00:00
|
|
|
let mut ui = Ui::new(window).unwrap();
|
2019-05-17 09:22:32 +00:00
|
|
|
// TODO: Adjust/remove this, right now it is used to demonstrate window scaling functionality.
|
2019-03-15 04:55:52 +00:00
|
|
|
ui.scaling_mode(ScaleMode::RelativeToWindow([1920.0, 1080.0].into()));
|
2019-05-17 09:22:32 +00:00
|
|
|
// Generate ids.
|
2019-03-16 02:03:21 +00:00
|
|
|
let ids = Ids::new(ui.id_generator());
|
2019-05-17 09:22:32 +00:00
|
|
|
// Load images.
|
|
|
|
let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
|
|
|
|
// Load fonts.
|
|
|
|
let fonts = Fonts::load(&mut ui).expect("Failed to load fonts!");
|
2019-04-20 22:02:48 +00:00
|
|
|
|
2019-03-15 04:55:52 +00:00
|
|
|
Self {
|
|
|
|
ui,
|
|
|
|
imgs,
|
2019-04-30 20:43:55 +00:00
|
|
|
fonts,
|
2019-03-15 04:55:52 +00:00
|
|
|
ids,
|
2019-05-03 16:56:18 +00:00
|
|
|
new_messages: VecDeque::new(),
|
2019-04-05 22:36:04 +00:00
|
|
|
inventory_space: 0,
|
2019-05-04 17:24:26 +00:00
|
|
|
show: Show {
|
2019-05-18 19:03:13 +00:00
|
|
|
help: false,
|
|
|
|
debug: true,
|
2019-05-04 17:24:26 +00:00
|
|
|
bag: false,
|
|
|
|
esc_menu: false,
|
|
|
|
open_windows: Windows::None,
|
|
|
|
map: false,
|
|
|
|
ui: true,
|
|
|
|
inventory_test_button: false,
|
|
|
|
mini_map: false,
|
2019-05-09 16:55:13 +00:00
|
|
|
want_grab: true,
|
2019-05-06 12:28:57 +00:00
|
|
|
},
|
|
|
|
to_focus: None,
|
2019-05-09 08:55:32 +00:00
|
|
|
force_ungrab: false,
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-23 08:18:25 +00:00
|
|
|
fn update_layout(&mut self, tps: f64, ping_ms: f64, global_state: &GlobalState) -> Vec<Event> {
|
2019-03-16 02:03:21 +00:00
|
|
|
let mut events = Vec::new();
|
2019-03-17 17:52:54 +00:00
|
|
|
let ref mut ui_widgets = self.ui.set_widgets();
|
2019-04-18 13:21:25 +00:00
|
|
|
let version = env!("CARGO_PKG_VERSION");
|
2019-04-02 04:54:27 +00:00
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Don't show anything if the UI is toggled off.
|
2019-05-04 17:24:26 +00:00
|
|
|
if !self.show.ui {
|
2019-04-20 15:17:29 +00:00
|
|
|
return events;
|
|
|
|
}
|
2019-04-22 18:47:22 +00:00
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Display debug window.
|
2019-05-04 17:24:26 +00:00
|
|
|
if self.show.debug {
|
2019-04-26 16:13:30 +00:00
|
|
|
// Alpha Version
|
|
|
|
Text::new(version)
|
|
|
|
.top_left_with_margins_on(ui_widgets.window, 5.0, 5.0)
|
|
|
|
.font_size(14)
|
2019-05-04 17:29:19 +00:00
|
|
|
.font_id(self.fonts.opensans)
|
2019-04-26 16:13:30 +00:00
|
|
|
.color(TEXT_COLOR)
|
|
|
|
.set(self.ids.version, ui_widgets);
|
2019-04-22 18:47:22 +00:00
|
|
|
Text::new(&format!("FPS: {:.1}", tps))
|
|
|
|
.color(TEXT_COLOR)
|
2019-04-26 16:13:30 +00:00
|
|
|
.down_from(self.ids.version, 5.0)
|
2019-04-30 20:43:55 +00:00
|
|
|
.font_id(self.fonts.opensans)
|
2019-04-26 16:13:30 +00:00
|
|
|
.font_size(14)
|
2019-04-22 18:47:22 +00:00
|
|
|
.set(self.ids.fps_counter, ui_widgets);
|
2019-05-23 08:18:25 +00:00
|
|
|
Text::new(&format!("Ping: {:.1}ms", ping_ms))
|
|
|
|
.color(TEXT_COLOR)
|
|
|
|
.down_from(self.ids.fps_counter, 5.0)
|
|
|
|
.font_id(self.fonts.opensans)
|
|
|
|
.font_size(14)
|
|
|
|
.set(self.ids.ping, ui_widgets);
|
2019-04-22 18:47:22 +00:00
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Add Bag-Space Button.
|
2019-05-04 17:24:26 +00:00
|
|
|
if self.show.inventory_test_button {
|
2019-04-28 13:56:40 +00:00
|
|
|
if Button::image(self.imgs.grid_button)
|
2019-04-20 15:17:29 +00:00
|
|
|
.w_h(100.0, 100.0)
|
|
|
|
.middle_of(ui_widgets.window)
|
|
|
|
.label("1 Up!")
|
|
|
|
.label_font_size(20)
|
2019-04-28 13:56:40 +00:00
|
|
|
.hover_image(self.imgs.grid_button_hover)
|
|
|
|
.press_image(self.imgs.grid_button_press)
|
2019-04-20 15:17:29 +00:00
|
|
|
.set(self.ids.bag_space_add, ui_widgets)
|
|
|
|
.was_clicked()
|
2019-03-15 04:55:52 +00:00
|
|
|
{
|
2019-05-04 10:43:37 +00:00
|
|
|
self.inventory_space += 1;
|
2019-04-20 15:17:29 +00:00
|
|
|
};
|
2019-05-07 05:40:03 +00:00
|
|
|
}
|
2019-05-07 17:21:53 +00:00
|
|
|
|
2019-04-20 15:17:29 +00:00
|
|
|
// Help Text
|
2019-05-04 17:24:26 +00:00
|
|
|
if self.show.help {
|
2019-04-20 15:17:29 +00:00
|
|
|
Image::new(self.imgs.window_frame_2)
|
|
|
|
.top_left_with_margins_on(ui_widgets.window, 3.0, 3.0)
|
2019-04-24 19:55:22 +00:00
|
|
|
.w_h(300.0, 190.0)
|
2019-04-20 15:17:29 +00:00
|
|
|
.set(self.ids.help_bg, ui_widgets);
|
2019-05-21 01:21:31 +00:00
|
|
|
Text::new(get_help_text(&global_state.settings.controls).as_str())
|
2019-04-24 20:33:34 +00:00
|
|
|
.color(TEXT_COLOR)
|
2019-04-24 19:55:22 +00:00
|
|
|
.top_left_with_margins_on(self.ids.help_bg, 20.0, 20.0)
|
2019-04-30 20:43:55 +00:00
|
|
|
.font_id(self.fonts.opensans)
|
2019-04-24 19:55:22 +00:00
|
|
|
.font_size(18)
|
|
|
|
.set(self.ids.help, ui_widgets);
|
2019-04-24 20:33:34 +00:00
|
|
|
// X-button
|
2019-04-28 16:44:44 +00:00
|
|
|
if Button::image(self.imgs.close_button)
|
2019-04-24 20:33:34 +00:00
|
|
|
.w_h(100.0 * 0.2, 100.0 * 0.2)
|
2019-04-28 16:44:44 +00:00
|
|
|
.hover_image(self.imgs.close_button_hover)
|
|
|
|
.press_image(self.imgs.close_button_press)
|
2019-05-11 15:36:10 +00:00
|
|
|
.top_right_with_margins_on(self.ids.help_bg, 4.0, 4.0)
|
2019-04-24 20:33:34 +00:00
|
|
|
.set(self.ids.button_help2, ui_widgets)
|
|
|
|
.was_clicked()
|
|
|
|
{
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.help = false;
|
2019-04-24 20:33:34 +00:00
|
|
|
};
|
2019-04-20 15:17:29 +00:00
|
|
|
}
|
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Bag button and nearby icons
|
2019-05-07 05:40:03 +00:00
|
|
|
match Buttons::new(
|
|
|
|
&self.show.open_windows,
|
|
|
|
self.show.map,
|
|
|
|
self.show.bag,
|
|
|
|
&self.imgs,
|
|
|
|
&self.fonts,
|
|
|
|
)
|
|
|
|
.set(self.ids.buttons, ui_widgets)
|
2019-05-03 13:49:05 +00:00
|
|
|
{
|
2019-05-04 17:24:26 +00:00
|
|
|
Some(buttons::Event::ToggleBag) => self.show.toggle_bag(),
|
|
|
|
Some(buttons::Event::ToggleSettings) => self.show.toggle_settings(),
|
2019-05-17 09:22:32 +00:00
|
|
|
Some(buttons::Event::ToggleCharacter) => self.show.toggle_char_window(),
|
2019-05-04 17:24:26 +00:00
|
|
|
Some(buttons::Event::ToggleSmall(small)) => self.show.toggle_small(small),
|
|
|
|
Some(buttons::Event::ToggleMap) => self.show.toggle_map(),
|
|
|
|
None => {}
|
2019-05-04 10:43:37 +00:00
|
|
|
}
|
2019-04-26 13:13:30 +00:00
|
|
|
|
2019-05-07 17:21:53 +00:00
|
|
|
// MiniMap
|
2019-05-07 17:50:53 +00:00
|
|
|
match MiniMap::new(&self.show, &self.imgs, &self.fonts).set(self.ids.minimap, ui_widgets) {
|
|
|
|
Some(minimap::Event::Toggle) => self.show.toggle_mini_map(),
|
|
|
|
None => {}
|
|
|
|
}
|
2019-04-20 15:17:29 +00:00
|
|
|
|
|
|
|
// Bag contents
|
2019-05-04 17:24:26 +00:00
|
|
|
if self.show.bag {
|
2019-05-04 10:43:37 +00:00
|
|
|
match Bag::new(self.inventory_space, &self.imgs, &self.fonts)
|
2019-05-07 05:40:03 +00:00
|
|
|
.set(self.ids.bag, ui_widgets)
|
2019-04-26 16:13:30 +00:00
|
|
|
{
|
2019-05-04 17:24:26 +00:00
|
|
|
Some(bag::Event::Close) => self.show.bag = false,
|
2019-05-04 10:43:37 +00:00
|
|
|
None => {}
|
2019-03-22 03:55:42 +00:00
|
|
|
}
|
2019-04-26 16:13:30 +00:00
|
|
|
}
|
2019-04-24 19:55:22 +00:00
|
|
|
|
2019-05-07 17:21:53 +00:00
|
|
|
// Skillbar
|
2019-05-07 05:40:03 +00:00
|
|
|
Skillbar::new(&self.imgs, &self.fonts).set(self.ids.skillbar, ui_widgets);
|
2019-05-04 06:07:23 +00:00
|
|
|
|
2019-05-03 16:56:18 +00:00
|
|
|
// Chat box
|
2019-05-07 03:25:25 +00:00
|
|
|
match Chat::new(&mut self.new_messages, &self.imgs, &self.fonts)
|
|
|
|
.set(self.ids.chat, ui_widgets)
|
|
|
|
{
|
2019-05-03 16:56:18 +00:00
|
|
|
Some(chat::Event::SendMessage(message)) => {
|
|
|
|
events.push(Event::SendMessage(message));
|
|
|
|
}
|
2019-05-06 12:28:57 +00:00
|
|
|
Some(chat::Event::Focus(focus_id)) => {
|
|
|
|
self.to_focus = Some(Some(focus_id));
|
|
|
|
}
|
2019-05-03 16:56:18 +00:00
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
self.new_messages = VecDeque::new();
|
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Windows
|
2019-03-15 04:55:52 +00:00
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Char Window will always appear at the left side. Other Windows default to the
|
|
|
|
// left side, but when the Char Window is opened they will appear to the right of it.
|
2019-03-15 04:55:52 +00:00
|
|
|
|
2019-05-03 16:56:18 +00:00
|
|
|
// Settings
|
2019-05-04 17:24:26 +00:00
|
|
|
if let Windows::Settings = self.show.open_windows {
|
2019-05-21 01:21:31 +00:00
|
|
|
for event in SettingsWindow::new(&self.show, &self.imgs, &self.fonts, &global_state)
|
2019-05-20 17:40:35 +00:00
|
|
|
.set(self.ids.settings_window, ui_widgets)
|
2019-03-15 04:55:52 +00:00
|
|
|
{
|
2019-05-18 23:55:06 +00:00
|
|
|
match event {
|
|
|
|
settings_window::Event::ToggleHelp => self.show.toggle_help(),
|
|
|
|
settings_window::Event::ToggleInventoryTestButton => {
|
|
|
|
self.show.inventory_test_button = !self.show.inventory_test_button
|
|
|
|
}
|
|
|
|
settings_window::Event::ToggleDebug => self.show.debug = !self.show.debug,
|
|
|
|
settings_window::Event::Close => self.show.open_windows = Windows::None,
|
2019-05-19 00:45:02 +00:00
|
|
|
settings_window::Event::AdjustViewDistance(view_distance) => {
|
|
|
|
events.push(Event::AdjustViewDistance(view_distance));
|
2019-05-18 23:55:06 +00:00
|
|
|
}
|
2019-05-19 19:31:32 +00:00
|
|
|
settings_window::Event::AdjustVolume(volume) => {
|
|
|
|
events.push(Event::AdjustVolume(volume));
|
|
|
|
}
|
2019-05-20 14:53:12 +00:00
|
|
|
settings_window::Event::ChangeAudioDevice(name) => {
|
|
|
|
events.push(Event::ChangeAudioDevice(name));
|
|
|
|
}
|
2019-05-07 17:50:53 +00:00
|
|
|
}
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-24 20:33:34 +00:00
|
|
|
|
2019-05-03 16:56:18 +00:00
|
|
|
// Small Window
|
2019-05-07 03:25:25 +00:00
|
|
|
if let Windows::Small(small) | Windows::CharacterAnd(Some(small)) = self.show.open_windows {
|
2019-05-06 19:17:29 +00:00
|
|
|
match SmallWindow::new(small, &self.show, &self.imgs, &self.fonts)
|
2019-05-07 05:40:03 +00:00
|
|
|
.set(self.ids.small_window, ui_widgets)
|
2019-05-03 16:56:18 +00:00
|
|
|
{
|
2019-05-07 05:40:03 +00:00
|
|
|
Some(small_window::Event::Close) => {
|
|
|
|
self.show.open_windows = match self.show.open_windows {
|
|
|
|
Windows::Small(_) => Windows::None,
|
|
|
|
Windows::CharacterAnd(_) => Windows::CharacterAnd(None),
|
|
|
|
_ => Windows::Settings,
|
|
|
|
}
|
|
|
|
}
|
2019-05-03 16:56:18 +00:00
|
|
|
None => {}
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-30 20:43:55 +00:00
|
|
|
// Character Window
|
2019-05-04 17:24:26 +00:00
|
|
|
if let Windows::CharacterAnd(small) = self.show.open_windows {
|
2019-04-30 20:43:55 +00:00
|
|
|
match CharacterWindow::new(&self.imgs, &self.fonts)
|
2019-05-07 05:40:03 +00:00
|
|
|
.set(self.ids.character_window, ui_widgets)
|
2019-04-28 04:44:13 +00:00
|
|
|
{
|
2019-05-07 05:40:03 +00:00
|
|
|
Some(character_window::Event::Close) => {
|
|
|
|
self.show.open_windows = match small {
|
|
|
|
Some(small) => Windows::Small(small),
|
|
|
|
None => Windows::None,
|
|
|
|
}
|
|
|
|
}
|
2019-05-03 16:56:18 +00:00
|
|
|
None => {}
|
2019-04-28 04:44:13 +00:00
|
|
|
}
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2019-04-30 20:43:55 +00:00
|
|
|
// Map
|
2019-05-04 17:24:26 +00:00
|
|
|
if self.show.map {
|
2019-05-07 05:40:03 +00:00
|
|
|
match Map::new(&self.imgs, &self.fonts).set(self.ids.map, ui_widgets) {
|
2019-05-04 17:24:26 +00:00
|
|
|
Some(map::Event::Close) => self.show.map = false,
|
2019-05-03 16:56:18 +00:00
|
|
|
None => {}
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-03 16:56:18 +00:00
|
|
|
// Esc-menu
|
2019-05-04 17:24:26 +00:00
|
|
|
if self.show.esc_menu {
|
2019-05-07 05:40:03 +00:00
|
|
|
match EscMenu::new(&self.imgs, &self.fonts).set(self.ids.esc_menu, ui_widgets) {
|
2019-05-03 16:56:18 +00:00
|
|
|
Some(esc_menu::Event::OpenSettings) => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.esc_menu = false;
|
|
|
|
self.show.open_windows = Windows::Settings;
|
2019-05-03 16:56:18 +00:00
|
|
|
}
|
2019-05-04 17:24:26 +00:00
|
|
|
Some(esc_menu::Event::Close) => self.show.esc_menu = false,
|
2019-05-03 16:56:18 +00:00
|
|
|
Some(esc_menu::Event::Logout) => events.push(Event::Logout),
|
|
|
|
Some(esc_menu::Event::Quit) => events.push(Event::Quit),
|
2019-05-07 05:40:03 +00:00
|
|
|
None => {}
|
2019-05-03 16:56:18 +00:00
|
|
|
}
|
|
|
|
}
|
2019-05-07 05:40:03 +00:00
|
|
|
|
2019-03-16 02:03:21 +00:00
|
|
|
events
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 05:26:51 +00:00
|
|
|
pub fn new_message(&mut self, msg: String) {
|
2019-05-03 16:56:18 +00:00
|
|
|
self.new_messages.push_back(msg);
|
2019-03-17 05:26:51 +00:00
|
|
|
}
|
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Checks if a TextEdit widget has the keyboard captured.
|
2019-05-07 03:25:25 +00:00
|
|
|
fn typing(&self) -> bool {
|
|
|
|
if let Some(id) = self.ui.widget_capturing_keyboard() {
|
|
|
|
self.ui
|
|
|
|
.widget_graph()
|
|
|
|
.widget(id)
|
|
|
|
.and_then(graph::Container::unique_widget_state::<widget::TextEdit>)
|
|
|
|
.is_some()
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-20 18:08:39 +00:00
|
|
|
pub fn handle_event(&mut self, event: WinEvent, global_state: &mut GlobalState) -> bool {
|
|
|
|
let cursor_grabbed = global_state.window.is_cursor_grabbed();
|
2019-05-07 20:00:03 +00:00
|
|
|
let handled = match event {
|
2019-03-22 03:55:42 +00:00
|
|
|
WinEvent::Ui(event) => {
|
2019-05-07 03:25:25 +00:00
|
|
|
if (self.typing() && event.is_keyboard() && self.show.ui)
|
2019-04-20 18:08:39 +00:00
|
|
|
|| !(cursor_grabbed && event.is_keyboard_or_mouse())
|
2019-04-01 20:31:29 +00:00
|
|
|
{
|
2019-03-22 03:55:42 +00:00
|
|
|
self.ui.handle_event(event);
|
|
|
|
}
|
|
|
|
true
|
2019-04-01 20:31:29 +00:00
|
|
|
}
|
2019-04-20 15:17:29 +00:00
|
|
|
WinEvent::KeyDown(Key::ToggleInterface) => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_ui();
|
2019-04-20 15:17:29 +00:00
|
|
|
true
|
|
|
|
}
|
2019-05-11 14:59:48 +00:00
|
|
|
WinEvent::KeyDown(Key::ToggleCursor) => {
|
|
|
|
self.force_ungrab = !self.force_ungrab;
|
|
|
|
if self.force_ungrab {
|
|
|
|
global_state.window.grab_cursor(false);
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
2019-05-04 17:24:26 +00:00
|
|
|
_ if !self.show.ui => false,
|
2019-04-20 18:08:39 +00:00
|
|
|
WinEvent::Zoom(_) => !cursor_grabbed && !self.ui.no_widget_capturing_mouse(),
|
2019-03-30 02:15:27 +00:00
|
|
|
WinEvent::KeyDown(Key::Enter) => {
|
2019-05-07 03:25:25 +00:00
|
|
|
self.ui.focus_widget(if self.typing() {
|
2019-05-06 12:28:57 +00:00
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(self.ids.chat)
|
|
|
|
});
|
2019-03-30 02:15:27 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-09 16:30:13 +00:00
|
|
|
WinEvent::KeyDown(Key::Escape) => {
|
2019-05-07 03:25:25 +00:00
|
|
|
if self.typing() {
|
2019-03-30 02:15:27 +00:00
|
|
|
self.ui.focus_widget(None);
|
|
|
|
} else {
|
2019-04-09 16:30:13 +00:00
|
|
|
// Close windows on esc
|
2019-05-07 20:00:03 +00:00
|
|
|
self.show.toggle_windows();
|
2019-03-30 02:15:27 +00:00
|
|
|
}
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
2019-04-02 04:54:27 +00:00
|
|
|
}
|
2019-05-07 03:25:25 +00:00
|
|
|
WinEvent::KeyDown(key) if !self.typing() => match key {
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::Map => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_map();
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::Bag => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_bag();
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::QuestLog => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_small(SmallWindowType::QuestLog);
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::CharacterWindow => {
|
2019-05-17 09:22:32 +00:00
|
|
|
self.show.toggle_char_window();
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::Social => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_small(SmallWindowType::Social);
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::Spellbook => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_small(SmallWindowType::Spellbook);
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::Settings => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_settings();
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-04-10 20:23:49 +00:00
|
|
|
Key::Help => {
|
2019-05-04 17:24:26 +00:00
|
|
|
self.show.toggle_help();
|
2019-04-09 16:30:13 +00:00
|
|
|
true
|
|
|
|
}
|
2019-05-18 21:16:35 +00:00
|
|
|
Key::ToggleDebug => {
|
|
|
|
self.show.debug = !self.show.debug;
|
|
|
|
true
|
|
|
|
}
|
2019-04-09 16:30:13 +00:00
|
|
|
_ => false,
|
|
|
|
},
|
2019-03-22 03:55:42 +00:00
|
|
|
WinEvent::KeyDown(key) | WinEvent::KeyUp(key) => match key {
|
|
|
|
Key::ToggleCursor => false,
|
2019-05-07 03:25:25 +00:00
|
|
|
_ => self.typing(),
|
2019-03-22 03:55:42 +00:00
|
|
|
},
|
2019-05-07 03:25:25 +00:00
|
|
|
WinEvent::Char(_) => self.typing(),
|
2019-03-22 03:55:42 +00:00
|
|
|
_ => false,
|
2019-05-07 20:00:03 +00:00
|
|
|
};
|
2019-05-17 09:22:32 +00:00
|
|
|
// Handle cursor grab.
|
2019-05-09 08:55:32 +00:00
|
|
|
if !self.force_ungrab {
|
2019-05-09 16:55:13 +00:00
|
|
|
if cursor_grabbed != self.show.want_grab {
|
|
|
|
global_state.window.grab_cursor(self.show.want_grab);
|
2019-05-09 08:55:32 +00:00
|
|
|
}
|
2019-03-22 03:55:42 +00:00
|
|
|
}
|
2019-05-08 20:15:58 +00:00
|
|
|
|
|
|
|
handled
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2019-05-23 08:18:25 +00:00
|
|
|
pub fn maintain(
|
|
|
|
&mut self,
|
|
|
|
global_state: &mut GlobalState,
|
|
|
|
tps: f64,
|
|
|
|
ping_ms: f64,
|
|
|
|
) -> Vec<Event> {
|
2019-05-06 12:28:57 +00:00
|
|
|
if let Some(maybe_id) = self.to_focus.take() {
|
|
|
|
self.ui.focus_widget(maybe_id);
|
|
|
|
}
|
2019-05-23 08:18:25 +00:00
|
|
|
let events = self.update_layout(tps, ping_ms, &global_state);
|
2019-05-21 01:21:31 +00:00
|
|
|
self.ui.maintain(&mut global_state.window.renderer_mut());
|
2019-03-16 02:03:21 +00:00
|
|
|
events
|
2019-03-15 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn render(&self, renderer: &mut Renderer) {
|
|
|
|
self.ui.render(renderer);
|
|
|
|
}
|
|
|
|
}
|
2019-04-25 13:10:01 +00:00
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Get the text to show in the help window and use the
|
|
|
|
// length of the longest line to resize the window.
|
2019-04-25 13:10:01 +00:00
|
|
|
fn get_help_text(cs: &ControlSettings) -> String {
|
2019-05-01 22:15:43 +00:00
|
|
|
format!(
|
|
|
|
"{free_cursor:?} = Free cursor\n\
|
|
|
|
{escape:?} = Open/close menus\n\
|
|
|
|
\n\
|
|
|
|
{help:?} = Toggle this window\n\
|
|
|
|
{toggle_interface:?} = Toggle interface\n\
|
|
|
|
\n\
|
|
|
|
{chat:?} = Open chat\n\
|
|
|
|
Mouse Wheel = Scroll chat/zoom",
|
|
|
|
free_cursor = cs.toggle_cursor,
|
|
|
|
escape = cs.escape,
|
|
|
|
help = cs.help,
|
|
|
|
toggle_interface = cs.toggle_interface,
|
|
|
|
chat = cs.enter
|
|
|
|
)
|
2019-04-29 21:23:31 +00:00
|
|
|
}
|