Attempt at moving away some of the launcher logic from the GUI
This commit is contained in:
54
src/infos.rs
54
src/infos.rs
@@ -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,
|
||||||
|
|||||||
81
src/main.rs
81
src/main.rs
@@ -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(),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user