Attempt at moving away some of the launcher logic from the GUI

This commit is contained in:
2023-06-16 18:40:01 +01:00
parent 587b81c69e
commit b60eb87e34
2 changed files with 90 additions and 47 deletions

View File

@@ -20,6 +20,60 @@ pub struct LauncherInfo {
pub name: String, pub name: String,
} }
pub struct LauncherManager {
pub launchers: Vec<LauncherInfo>,
pub current_selected: Option<usize>,
}
impl LauncherManager {
pub fn new() -> LauncherManager {
LauncherManager {
launchers: Vec::new(),
current_selected: None,
}
}
pub fn add(&mut self, launcher: LauncherInfo) {
self.launchers.push(launcher);
}
pub fn get(&self, index: usize) -> Option<(&LauncherInfo, bool)> {
if index > self.launchers.len() {
None
} else {
Some((self.launchers.get(index).unwrap(), index == self.current_selected.unwrap_or(std::usize::MAX)))
}
}
pub fn get_current(&self) -> Option<&LauncherInfo> {
match self.current_selected {
None => None,
Some(pos) => Some(self.launchers.get(pos).unwrap()),
}
}
pub fn set_current(&mut self, index: usize) {
assert!(index <= self.launchers.len());
self.current_selected = Some(index);
}
pub fn clear_current(&mut self) {
self.current_selected = None;
}
pub fn remove_launcher(&mut self, index: usize) {
assert!(index <= self.launchers.len());
self.launchers.remove(index);
}
pub fn iter_with_pos_and_selected(
&mut self,
) -> impl Iterator<Item = (&mut LauncherInfo, usize, bool)> + '_ {
self.launchers
.iter_mut()
.enumerate()
.map(|(i, l)| (l, i, i == self.current_selected.unwrap_or(std::usize::MAX)))
}
}
pub struct IwadManager {
pub wads: Vec<WadInfo>,
pub current_selected: Option<usize>,
}
#[derive(PartialEq, Clone, Copy)] #[derive(PartialEq, Clone, Copy)]
pub enum Difficulty { pub enum Difficulty {
None, None,

View File

@@ -1,7 +1,7 @@
use config::{default_save_filename, load_config, save_config, Config}; use config::{default_save_filename, load_config, save_config, Config};
use eframe::egui; use eframe::egui;
use eframe::egui::Color32; use eframe::egui::Color32;
use infos::{Difficulty, LauncherInfo, WadInfo}; use infos::{Difficulty, LauncherInfo, LauncherManager, WadInfo};
use native_dialog::{MessageDialog, MessageType}; use native_dialog::{MessageDialog, MessageType};
use std::path::PathBuf; use std::path::PathBuf;
use std::process::Command; use std::process::Command;
@@ -21,10 +21,9 @@ fn main() -> Result<(), eframe::Error> {
} }
struct RustDoomLauncher { struct RustDoomLauncher {
all_launchers: Vec<LauncherInfo>, launcher_manager: LauncherManager,
all_iwads: Vec<WadInfo>, all_iwads: Vec<WadInfo>,
all_pwads: Vec<WadInfo>, all_pwads: Vec<WadInfo>,
selected_launcher: Option<usize>,
selected_iwad: Option<usize>, selected_iwad: Option<usize>,
selected_pwads: Vec<usize>, selected_pwads: Vec<usize>,
name: String, name: String,
@@ -55,10 +54,9 @@ enum MyErrors {
impl Default for RustDoomLauncher { impl Default for RustDoomLauncher {
fn default() -> Self { fn default() -> Self {
Self { Self {
all_launchers: Vec::new(), launcher_manager: LauncherManager::new(),
all_iwads: Vec::new(), all_iwads: Vec::new(),
all_pwads: Vec::new(), all_pwads: Vec::new(),
selected_launcher: None,
selected_iwad: None, selected_iwad: None,
selected_pwads: Vec::new(), selected_pwads: Vec::new(),
name: "".to_string(), name: "".to_string(),
@@ -93,7 +91,7 @@ impl RustDoomLauncher {
} }
if let Some(launchers) = config.launchers { if let Some(launchers) = config.launchers {
for launcher in launchers { for launcher in launchers {
self.all_launchers.push(launcher.clone()); self.launcher_manager.add(launcher);
} }
} }
} }
@@ -164,8 +162,8 @@ impl RustDoomLauncher {
} }
fn launcher_and_iwad(&self) -> Result<(&LauncherInfo, &WadInfo), MyErrors> { fn launcher_and_iwad(&self) -> Result<(&LauncherInfo, &WadInfo), MyErrors> {
let launcher = match self.selected_launcher { let launcher = match self.launcher_manager.get_current() {
Some(l) => self.all_launchers.get(l).unwrap(), Some(l) => l,
None => { None => {
return Err(MyErrors::NoLauncher); return Err(MyErrors::NoLauncher);
} }
@@ -185,7 +183,7 @@ impl eframe::App for RustDoomLauncher {
let config = Config { let config = Config {
iwads: Some(self.all_iwads.clone()), iwads: Some(self.all_iwads.clone()),
pwads: Some(self.all_pwads.clone()), pwads: Some(self.all_pwads.clone()),
launchers: Some(self.all_launchers.clone()), launchers: Some(self.launcher_manager.launchers.clone()),
}; };
save_config(&self.config_filename, &config).unwrap(); save_config(&self.config_filename, &config).unwrap();
true true
@@ -214,25 +212,32 @@ impl eframe::App for RustDoomLauncher {
ui.vertical(|ui| { ui.vertical(|ui| {
ui.label("Launchers"); ui.label("Launchers");
let mut remove_pos: Option<usize> = None; let mut remove_pos: Option<usize> = None;
for (pos, launcher) in self.all_launchers.iter().enumerate() { let mut add_pos: Option<usize> = None;
for (launcher, pos, selected) in
self.launcher_manager.iter_with_pos_and_selected()
{
ui.horizontal(|ui| { ui.horizontal(|ui| {
if ui if ui
.add(egui::SelectableLabel::new( .add(egui::SelectableLabel::new(selected, &launcher.name))
self.selected_launcher.is_some()
&& *self.selected_launcher.as_ref().unwrap() == pos,
&launcher.name,
))
.clicked() .clicked()
{ {
self.selected_launcher = Some(pos); add_pos = Some(pos);
} }
if ui.button("").clicked() { if ui.button("").clicked() {
remove_pos = Some(pos); remove_pos = Some(pos);
} }
}); });
} }
// I'm unsure whether there's a better way to do this.
// The iterator borrow is a mutable borrow - thus compiler doesn't let me
// do a mutable thing in the middle of that, which I guess is fair enough,
// but I would like to break out of the loop as soon as that occurs...
// Completely unsure
if let Some(rp) = remove_pos { if let Some(rp) = remove_pos {
self.all_launchers.remove(rp); self.launcher_manager.remove_launcher(rp);
}
if let Some(ap) = add_pos {
self.launcher_manager.set_current(ap);
} }
}); });
ui.separator(); ui.separator();
@@ -261,21 +266,10 @@ impl eframe::App for RustDoomLauncher {
self.selected_pwads.contains(&pos), self.selected_pwads.contains(&pos),
&pwad.name, &pwad.name,
); );
/*
let tmp = ui.add(pwad_label);
let click_response = tmp.interact(egui::Sense::click());
let right_click_response = tmp.interact(egui::Sense::secondary_click());
*/
if ui.add(pwad_label).clicked() { if ui.add(pwad_label).clicked() {
self.selected_pwads.push(pos); self.selected_pwads.push(pos);
} }
/*
TODO - no idea how this works
if ui.add(pwad_label).secondary_clicked() {
self.all_pwads.remove(pos);
continue;
}
*/
} }
}); });
}); });
@@ -317,20 +311,15 @@ impl eframe::App for RustDoomLauncher {
ui.horizontal_wrapped(|ui| { ui.horizontal_wrapped(|ui| {
// I don't actually think using SelectableLabel is correct here - // I don't actually think using SelectableLabel is correct here -
// but it'll at least do the highlighting when hovered nicely // but it'll at least do the highlighting when hovered nicely
if let Some(l) = self.selected_launcher {
if let Some(iwad) = self.all_launchers.get(l) { if let Some(l) = self.launcher_manager.get_current() {
if ui if ui.add(egui::SelectableLabel::new(false, &l.name)).clicked() {
.add(egui::SelectableLabel::new(false, &iwad.name)) self.launcher_manager.clear_current();
.clicked()
{
self.selected_launcher = None;
}
} else {
self.selected_launcher = None;
} }
} else { } else {
ui.label("Select a launcher plz"); ui.label("Select a launcher plz");
} }
if let Some(i) = self.selected_iwad { if let Some(i) = self.selected_iwad {
if let Some(iwad) = self.all_iwads.get(i) { if let Some(iwad) = self.all_iwads.get(i) {
if ui if ui
@@ -403,12 +392,12 @@ impl eframe::App for RustDoomLauncher {
ui.label("What sort of file is it?"); ui.label("What sort of file is it?");
if ui if ui
.add(egui::SelectableLabel::new( .add(egui::SelectableLabel::new(
self.selected_file_type == FileType::Pwad, self.selected_file_type == FileType::Launcher,
"PWAD", "Launcher",
)) ))
.clicked() .clicked()
{ {
self.selected_file_type = FileType::Pwad self.selected_file_type = FileType::Launcher
} }
if ui if ui
.add(egui::SelectableLabel::new( .add(egui::SelectableLabel::new(
@@ -421,12 +410,12 @@ impl eframe::App for RustDoomLauncher {
} }
if ui if ui
.add(egui::SelectableLabel::new( .add(egui::SelectableLabel::new(
self.selected_file_type == FileType::Launcher, self.selected_file_type == FileType::Pwad,
"Launcher", "PWAD",
)) ))
.clicked() .clicked()
{ {
self.selected_file_type = FileType::Launcher self.selected_file_type = FileType::Pwad
} }
}); });
if ui.button("Add!").clicked() { if ui.button("Add!").clicked() {
@@ -447,7 +436,7 @@ impl eframe::App for RustDoomLauncher {
}); });
} }
FileType::Launcher => { FileType::Launcher => {
self.all_launchers.push(LauncherInfo { self.launcher_manager.add(LauncherInfo {
name: self.name.clone(), name: self.name.clone(),
path: self.selected_file_path.clone(), path: self.selected_file_path.clone(),
}); });