151 lines
4.1 KiB
Rust
151 lines
4.1 KiB
Rust
// Copyright 2016 Matthew Collins
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
mod server_list;
|
|
pub use self::server_list::*;
|
|
mod login;
|
|
pub use self::login::*;
|
|
|
|
pub mod connecting;
|
|
pub mod delete_server;
|
|
pub mod edit_server;
|
|
|
|
pub mod settings_menu;
|
|
pub use self::settings_menu::{AudioSettingsMenu, SettingsMenu, VideoSettingsMenu};
|
|
|
|
use crate::render;
|
|
use crate::ui;
|
|
|
|
pub trait Screen {
|
|
// Called once
|
|
fn init(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) {}
|
|
fn deinit(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) {}
|
|
|
|
// May be called multiple times
|
|
fn on_active(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container);
|
|
fn on_deactive(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container);
|
|
|
|
// Called every frame the screen is active
|
|
fn tick(
|
|
&mut self,
|
|
delta: f64,
|
|
renderer: &mut render::Renderer,
|
|
ui_container: &mut ui::Container,
|
|
) -> Option<Box<dyn Screen>>;
|
|
|
|
// Events
|
|
fn on_scroll(&mut self, _x: f64, _y: f64) {}
|
|
|
|
fn is_closable(&self) -> bool {
|
|
false
|
|
}
|
|
}
|
|
|
|
struct ScreenInfo {
|
|
screen: Box<dyn Screen>,
|
|
init: bool,
|
|
active: bool,
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct ScreenSystem {
|
|
screens: Vec<ScreenInfo>,
|
|
remove_queue: Vec<ScreenInfo>,
|
|
}
|
|
|
|
impl ScreenSystem {
|
|
pub fn new() -> ScreenSystem {
|
|
Default::default()
|
|
}
|
|
|
|
pub fn add_screen(&mut self, screen: Box<dyn Screen>) {
|
|
self.screens.push(ScreenInfo {
|
|
screen,
|
|
init: false,
|
|
active: false,
|
|
});
|
|
}
|
|
|
|
pub fn pop_screen(&mut self) {
|
|
if let Some(screen) = self.screens.pop() {
|
|
self.remove_queue.push(screen);
|
|
}
|
|
}
|
|
|
|
pub fn replace_screen(&mut self, screen: Box<dyn Screen>) {
|
|
self.pop_screen();
|
|
self.add_screen(screen);
|
|
}
|
|
|
|
pub fn is_current_closable(&self) -> bool {
|
|
if let Some(last) = self.screens.last() {
|
|
last.screen.is_closable()
|
|
} else {
|
|
true
|
|
}
|
|
}
|
|
|
|
pub fn tick(
|
|
&mut self,
|
|
delta: f64,
|
|
renderer: &mut render::Renderer,
|
|
ui_container: &mut ui::Container,
|
|
) {
|
|
for screen in &mut self.remove_queue {
|
|
if screen.active {
|
|
screen.screen.on_deactive(renderer, ui_container);
|
|
}
|
|
if screen.init {
|
|
screen.screen.deinit(renderer, ui_container);
|
|
}
|
|
}
|
|
self.remove_queue.clear();
|
|
if self.screens.is_empty() {
|
|
return;
|
|
}
|
|
// Update state for screens
|
|
let len = self.screens.len();
|
|
for screen in &mut self.screens[..len - 1] {
|
|
if screen.active {
|
|
screen.active = false;
|
|
screen.screen.on_deactive(renderer, ui_container);
|
|
}
|
|
}
|
|
let swap = {
|
|
let current = self.screens.last_mut().unwrap();
|
|
if !current.init {
|
|
current.init = true;
|
|
current.screen.init(renderer, ui_container);
|
|
}
|
|
if !current.active {
|
|
current.active = true;
|
|
current.screen.on_active(renderer, ui_container);
|
|
}
|
|
current.screen.tick(delta, renderer, ui_container)
|
|
};
|
|
// Handle current
|
|
if let Some(swap) = swap {
|
|
self.replace_screen(swap);
|
|
}
|
|
}
|
|
|
|
pub fn on_scroll(&mut self, x: f64, y: f64) {
|
|
if self.screens.is_empty() {
|
|
return;
|
|
}
|
|
let current = self.screens.last_mut().unwrap();
|
|
current.screen.on_scroll(x, y);
|
|
}
|
|
}
|