game picker
This commit is contained in:
@@ -2,7 +2,7 @@ use std::{f32::consts::E, path::PathBuf, sync::Arc, thread, time::Duration};
|
||||
|
||||
use crossbeam_channel::Receiver;
|
||||
use egui::{mutex::Mutex};
|
||||
use log::debug;
|
||||
use log::{debug, info};
|
||||
|
||||
use crate::{config::{self, ConfigProvider}, omori_locator};
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{config::{self, ConfigProvider}, omori_locator};
|
||||
pub enum UiState {
|
||||
Loading,
|
||||
KeyRequired(String),
|
||||
PickGame(Result<PathBuf, String>, Vec<PathBuf>),
|
||||
PickGame(Result<PathBuf, String>, Vec<(PathBuf, u64)>),
|
||||
Error(String)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ pub struct UiStateHolder {
|
||||
}
|
||||
|
||||
pub enum UiEvent {
|
||||
SetKey(Vec<u8>)
|
||||
SetKey(Vec<u8>),
|
||||
UsePath(PathBuf),
|
||||
UseSteamPath
|
||||
}
|
||||
|
||||
pub struct AppThread {
|
||||
@@ -49,7 +51,7 @@ impl AppThread {
|
||||
}
|
||||
}
|
||||
|
||||
fn pick_game(&mut self, provider: &ConfigProvider) -> anyhow::Result<()> {
|
||||
fn pick_game(&mut self, provider: &mut ConfigProvider) -> anyhow::Result<PathBuf> {
|
||||
let steam_location = match omori_locator::get_omori_path() {
|
||||
Ok(l) => Ok(l),
|
||||
Err(e) => Err(String::from(format!("{:#}", e)))
|
||||
@@ -59,7 +61,20 @@ impl AppThread {
|
||||
|
||||
self.commit(UiState::PickGame(steam_location.clone(), location_history.clone()));
|
||||
|
||||
Ok(())
|
||||
loop {
|
||||
match self.ui_event_channel.recv()? {
|
||||
UiEvent::UsePath(path) => {
|
||||
provider.set_game_path_used(&path)?;
|
||||
self.commit(UiState::Loading);
|
||||
return Ok(path);
|
||||
},
|
||||
UiEvent::UseSteamPath => {
|
||||
self.commit(UiState::Loading);
|
||||
return Ok(steam_location.expect("The steam location was not set even if the UI told us to use it. This should never happen"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(state_holder: &UiStateHolder, context: &egui::Context, ui_event_channel: &Receiver<UiEvent>) -> AppThread {
|
||||
@@ -87,7 +102,8 @@ impl AppThread {
|
||||
|
||||
config_provider.set_key(&self.decryption_key)?;
|
||||
|
||||
self.pick_game(&config_provider);
|
||||
let game_path = self.pick_game(&mut config_provider)?;
|
||||
info!("Will use {:?}", game_path);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -66,11 +66,11 @@ impl ConfigProvider {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_game_paths(&self) -> anyhow::Result<Vec<PathBuf>> {
|
||||
pub fn get_game_paths(&self) -> anyhow::Result<Vec<(PathBuf, u64)>> {
|
||||
let mut paths: Vec<(&PathBuf, &u64)> = self.config.recently_used_game_paths.iter().collect();
|
||||
paths.sort_by(|a, b| a.1.cmp(b.1));
|
||||
paths.sort_by(|a, b| a.1.cmp(b.1).reverse());
|
||||
|
||||
Ok(paths.iter().map(|v| v.0.clone()).collect())
|
||||
Ok(paths.iter().map(|v| (v.0.clone(), *v.1)).collect())
|
||||
}
|
||||
|
||||
pub fn set_game_path_used(&mut self, which: &PathBuf) -> anyhow::Result<()> {
|
||||
|
||||
47
src/main.rs
47
src/main.rs
@@ -2,13 +2,14 @@ mod omori_locator;
|
||||
mod app_logic;
|
||||
mod config;
|
||||
|
||||
use std::{sync::Arc, thread, time::Duration};
|
||||
use std::{sync::Arc, thread, time::{Duration, SystemTime}};
|
||||
|
||||
use app_logic::{AppThread, UiEvent, UiState, UiStateHolder};
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use eframe::egui;
|
||||
use egui::{mutex::{Mutex, RwLock}, Align, Layout, RichText, ThemePreference};
|
||||
use egui_alignments::{center_horizontal, center_vertical, top_horizontal, Aligner};
|
||||
use egui_extras::{Column, TableBuilder};
|
||||
use egui_modal::Modal;
|
||||
use sha2::Digest;
|
||||
|
||||
@@ -39,6 +40,9 @@ fn main() -> anyhow::Result<()> {
|
||||
|
||||
eframe::run_native("TundleBool", options, Box::new(|cc| {
|
||||
cc.egui_ctx.set_theme(ThemePreference::System);
|
||||
cc.egui_ctx.style_mut(|style| {
|
||||
style.interaction.selectable_labels = false;
|
||||
});
|
||||
|
||||
let mut app_thread = AppThread::create(&app_state, &cc.egui_ctx, &receiver);
|
||||
|
||||
@@ -164,7 +168,9 @@ impl eframe::App for Application {
|
||||
Ok(path) => {
|
||||
ui.label(RichText::new(format!("Found game at:\n{}", path.display())).italics());
|
||||
ui.separator();
|
||||
ui.button(RichText::new("Use Steam version").size(16.0));
|
||||
if ui.button(RichText::new("Use Steam version").size(16.0)).clicked() {
|
||||
self.sender.send(UiEvent::UseSteamPath).expect("Failed to send");
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
ui.label(RichText::new(format!("Failed to find game:\n{}", e)).color(ui.visuals().error_fg_color));
|
||||
@@ -175,11 +181,44 @@ impl eframe::App for Application {
|
||||
columns[1].vertical(|ui| {
|
||||
ui.label(RichText::new("Custom").size(24.0));
|
||||
if ui.button(RichText::new("Pick game location").size(16.0)).clicked() {
|
||||
rfd::FileDialog::new().pick_folder();
|
||||
invalid_path_modal.open();
|
||||
match rfd::FileDialog::new().pick_folder() {
|
||||
Some(path) => {
|
||||
if omori_locator::validate_omori_installation(&path) {
|
||||
self.sender.send(UiEvent::UsePath(path)).expect("Failed to send");
|
||||
} else {
|
||||
invalid_path_modal.open();
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
ui.separator();
|
||||
|
||||
if others.len() > 0 {
|
||||
ui.label("History of game locations");
|
||||
|
||||
TableBuilder::new(ui)
|
||||
.striped(true)
|
||||
.column(Column::remainder())
|
||||
.column(Column::auto())
|
||||
.body(|body| {
|
||||
body.rows(20.0, others.len(), |mut row| {
|
||||
let item = &others[row.index()];
|
||||
let dt =
|
||||
(item.1 as i64) -
|
||||
(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("Failed to get the time").as_secs() as i64);
|
||||
|
||||
let dt = chrono::Duration::from(chrono::TimeDelta::seconds(dt as i64));
|
||||
|
||||
row.col(|ui| {
|
||||
ui.label(format!("{}", item.0.display()));
|
||||
});
|
||||
|
||||
row.col(|ui| {
|
||||
ui.label(format!("{}", chrono_humanize::HumanTime::from(dt)));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
ui.label("Once you use a custom location, it will be remembered here.");
|
||||
|
||||
Reference in New Issue
Block a user