Add Settings with fullscreen and windowed options, a config file
(settings.toml) to persist settings, fix a bug in platform code where innner window size wasn't updated on resize, various other tweaks
This commit is contained in:
parent
b17a7636d8
commit
f5a16213fa
10 changed files with 277 additions and 19 deletions
|
|
@ -1,8 +1,9 @@
|
|||
use std::{cell::RefCell, rc::Rc};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use winit::event::Event;
|
||||
use raidillon_assets::ModelManagerRef;
|
||||
use raidillon_core::EguiQueue;
|
||||
use crate::settings::Settings;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PlatformContext {
|
||||
|
|
@ -13,6 +14,7 @@ pub struct PlatformContext {
|
|||
pub time_ctx: TimeContext,
|
||||
pub window: Arc<Mutex<winit::window::Window>>,
|
||||
pub egui_queue: Rc<RefCell<EguiQueue>>,
|
||||
pub settings: Arc<RwLock<Settings>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ pub mod platform;
|
|||
mod camera;
|
||||
mod event;
|
||||
pub mod context;
|
||||
pub mod settings;
|
||||
|
||||
pub use platform::Platform;
|
||||
pub use camera::Camera;
|
||||
|
|
|
|||
101
platform/src/settings.rs
Normal file
101
platform/src/settings.rs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
use winit::dpi::LogicalSize;
|
||||
use winit::window::{Fullscreen, Window};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn default_config_path() -> PathBuf {
|
||||
let exe_path = std::env::current_exe().unwrap();
|
||||
let exe_dir = exe_path
|
||||
.parent()
|
||||
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "executable has no parent")).unwrap();
|
||||
|
||||
exe_dir.join("settings.toml")
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum WindowMode {
|
||||
BorderlessFullscreen,
|
||||
#[default]
|
||||
Windowed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct Settings {
|
||||
pub display_settings: DisplaySettings,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
pub fn load_from_file(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
|
||||
let path = path.as_ref();
|
||||
let text = fs::read_to_string(path)?;
|
||||
let settings: Settings = toml::from_str(&text)?;
|
||||
Ok(settings)
|
||||
}
|
||||
|
||||
pub fn save_to_file(&self, path: impl AsRef<Path>) -> Result<(), Box<dyn Error>> {
|
||||
let path = path.as_ref();
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
let toml_str = toml::to_string_pretty(self)?;
|
||||
fs::write(path, toml_str)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_or_default(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
|
||||
let path = path.as_ref();
|
||||
|
||||
match fs::read_to_string(path) {
|
||||
Ok(text) => {
|
||||
let settings: Settings = toml::from_str(&text)?;
|
||||
Ok(settings)
|
||||
}
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => {
|
||||
let settings = Settings::default();
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
let toml_str = toml::to_string_pretty(&settings)?;
|
||||
fs::write(path, toml_str)?;
|
||||
Ok(settings)
|
||||
}
|
||||
Err(err) => Err(Box::new(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct DisplaySettings {
|
||||
pub fullscreen_mode: WindowMode,
|
||||
#[serde(skip)]
|
||||
pub dirty: bool,
|
||||
}
|
||||
|
||||
impl Default for DisplaySettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
fullscreen_mode: WindowMode::Windowed,
|
||||
dirty: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DisplaySettings {
|
||||
pub fn apply(&self, window: &Window) {
|
||||
// apply fullscreen mode
|
||||
match self.fullscreen_mode {
|
||||
WindowMode::BorderlessFullscreen => {
|
||||
let monitor = window.current_monitor().or_else(|| window.primary_monitor());
|
||||
window.set_fullscreen(Some(Fullscreen::Borderless(monitor)));
|
||||
}
|
||||
WindowMode::Windowed => {
|
||||
window.set_fullscreen(None);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue