mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-11-28 18:08:46 +03:00
Several changes
- renamed `ToastError` trait to `Toast`; renamed its `toast_error` method to `toast`; now `toast` method will not display button if toast's message is empty - updated `game::run` function, now it prints running command and supports `gamemoderun`
This commit is contained in:
parent
85b2e6741e
commit
114d388a8c
7 changed files with 105 additions and 82 deletions
|
@ -61,7 +61,7 @@ pub fn try_get_terminal() -> Option<Terminal> {
|
|||
/// Try to run the game
|
||||
///
|
||||
/// If `debug = true`, then the game will be run in the new terminal window
|
||||
pub fn run(debug: bool) -> Result<(), Error> {
|
||||
pub fn run(debug: bool) -> std::io::Result<()> {
|
||||
let config = config::get()?;
|
||||
|
||||
if !Path::new(&config.game.path).exists() {
|
||||
|
@ -73,7 +73,15 @@ pub fn run(debug: bool) -> Result<(), Error> {
|
|||
None => return Err(Error::new(ErrorKind::Other, "Couldn't find wine executable"))
|
||||
};
|
||||
|
||||
let mut command = Command::new(wine_executable);
|
||||
// Prepare bash -c '<command>'
|
||||
|
||||
let mut bash_chain = String::new();
|
||||
|
||||
if config.game.enhancements.gamemode {
|
||||
bash_chain += "gamemoderun ";
|
||||
}
|
||||
|
||||
bash_chain += &format!("'{}' ", wine_executable);
|
||||
|
||||
if debug {
|
||||
// Is not supported now because new spawned terminal needs
|
||||
|
@ -92,9 +100,16 @@ pub fn run(debug: bool) -> Result<(), Error> {
|
|||
}
|
||||
|
||||
else {
|
||||
command.arg("launcher.bat");
|
||||
bash_chain += "launcher.bat";
|
||||
}
|
||||
|
||||
let mut command = Command::new("bash");
|
||||
|
||||
command.arg("-c");
|
||||
command.arg(&bash_chain);
|
||||
|
||||
// Setup environment
|
||||
|
||||
command.env("WINEPREFIX", &config.game.wine.prefix);
|
||||
|
||||
// Add DXVK_ASYNC=1 for dxvk-async builds automatically
|
||||
|
@ -109,9 +124,13 @@ pub fn run(debug: bool) -> Result<(), Error> {
|
|||
command.envs(config.game.enhancements.fsr.get_env_vars());
|
||||
command.envs(config.game.wine.language.get_env_vars());
|
||||
|
||||
command.envs(config.game.environment)
|
||||
.current_dir(config.game.path)
|
||||
.spawn()?;
|
||||
command.envs(config.game.environment);
|
||||
|
||||
// Run command
|
||||
|
||||
println!("Running command: bash -c \"{}\"", bash_chain);
|
||||
|
||||
command.current_dir(config.game.path).spawn()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use wait_not_await::Await;
|
|||
use crate::ui::*;
|
||||
|
||||
use super::preferences::PreferencesStack;
|
||||
use super::traits::toast_error::ToastError;
|
||||
use super::traits::toast::Toast;
|
||||
use super::components::progress_bar::*;
|
||||
|
||||
use crate::lib::config;
|
||||
|
@ -135,7 +135,7 @@ pub enum Actions {
|
|||
ShowProgressBar,
|
||||
UpdateProgress { fraction: Rc<f64>, title: Rc<String> },
|
||||
HideProgressBar,
|
||||
ToastError(Rc<(String, Error)>)
|
||||
Toast(Rc<(String, Error)>)
|
||||
}
|
||||
|
||||
impl Actions {
|
||||
|
@ -239,7 +239,7 @@ impl App {
|
|||
glib::MainContext::default().invoke(move || {
|
||||
this.update(Actions::PreferencesGoBack).unwrap();
|
||||
|
||||
this.toast_error("Failed to update preferences", err);
|
||||
this.toast("Failed to update preferences", err);
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
@ -270,7 +270,7 @@ impl App {
|
|||
if let Err(err) = game::run(false) {
|
||||
this.widgets.window.show();
|
||||
|
||||
this.toast_error("Failed to run game", err);
|
||||
this.toast("Failed to run game", err);
|
||||
}
|
||||
|
||||
else {
|
||||
|
@ -318,20 +318,20 @@ impl App {
|
|||
Ok(true) => synced = true,
|
||||
|
||||
Ok(false) => {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to sync patch folder"), Error::last_os_error()
|
||||
)))).unwrap();
|
||||
}
|
||||
|
||||
Err(err) => {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to sync patch folder"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(err) => this.update(Actions::ToastError(Rc::new((
|
||||
Err(err) => this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to check patch folder state"), err
|
||||
)))).unwrap()
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ impl App {
|
|||
Ok(_) => (),
|
||||
|
||||
Err(err) => {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to patch game"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ impl App {
|
|||
ProgressUpdateResult::Error(msg, err) => {
|
||||
this.widgets.progress_bar.hide();
|
||||
|
||||
this.toast_error(msg, err);
|
||||
this.toast(msg, err);
|
||||
}
|
||||
|
||||
ProgressUpdateResult::Finished => {
|
||||
|
@ -419,10 +419,10 @@ impl App {
|
|||
});
|
||||
});
|
||||
},
|
||||
Err(err) => this.toast_error("Failed to init wine version installer", err)
|
||||
Err(err) => this.toast("Failed to init wine version installer", err)
|
||||
}
|
||||
},
|
||||
Err(err) => this.toast_error("Failed to get latest wine version", err)
|
||||
Err(err) => this.toast("Failed to get latest wine version", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,7 +430,7 @@ impl App {
|
|||
this.update_state();
|
||||
}
|
||||
},
|
||||
Err(err) => this.toast_error("Failed to list downloaded wine versions", err)
|
||||
Err(err) => this.toast("Failed to list downloaded wine versions", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ impl App {
|
|||
this.widgets.launch_game.set_sensitive(false);
|
||||
|
||||
if let Err(err) = prefix.update(&config.game.wine.builds, wine) {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to create wine prefix"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ impl App {
|
|||
this.update_state();
|
||||
});
|
||||
},
|
||||
None => this.toast_error("Failed to get selected wine version", Error::last_os_error())
|
||||
None => this.toast("Failed to get selected wine version", Error::last_os_error())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +477,7 @@ impl App {
|
|||
ProgressUpdateResult::Error(msg, err) => {
|
||||
this.widgets.progress_bar.hide();
|
||||
|
||||
this.toast_error(msg, err);
|
||||
this.toast(msg, err);
|
||||
}
|
||||
|
||||
ProgressUpdateResult::Finished => {
|
||||
|
@ -516,7 +516,7 @@ impl App {
|
|||
LauncherState::VoiceOutdated(_) => ()
|
||||
}
|
||||
},
|
||||
Err(err) => this.toast_error("Failed to load config", err)
|
||||
Err(err) => this.toast("Failed to load config", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,7 +648,7 @@ impl App {
|
|||
for (i, file) in broken.into_iter().enumerate() {
|
||||
if !is_patch_applied || !should_ignore(&file.path) {
|
||||
if let Err(err) = file.repair(&config.game.path) {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to repair game file"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -666,7 +666,7 @@ impl App {
|
|||
this.update(Actions::HideProgressBar).unwrap();
|
||||
},
|
||||
Err(err) => {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to get integrity files"), err
|
||||
)))).unwrap();
|
||||
|
||||
|
@ -675,7 +675,7 @@ impl App {
|
|||
}
|
||||
});
|
||||
},
|
||||
Err(err) => this.toast_error("Failed to load config", err)
|
||||
Err(err) => this.toast("Failed to load config", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,10 +691,10 @@ impl App {
|
|||
this.widgets.progress_bar.hide();
|
||||
}
|
||||
|
||||
Actions::ToastError(toast) => {
|
||||
Actions::Toast(toast) => {
|
||||
let (msg, err) = (toast.0.clone(), toast.1.to_string());
|
||||
|
||||
this.toast_error(msg, err);
|
||||
this.toast(msg, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -829,7 +829,7 @@ impl App {
|
|||
send.send(Err(err.to_string())).unwrap();
|
||||
|
||||
glib::MainContext::default().invoke(move || {
|
||||
this.toast_error("Failed to get initial launcher state", err);
|
||||
this.toast("Failed to get initial launcher state", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -841,7 +841,7 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToastError for App {
|
||||
impl Toast for App {
|
||||
fn get_toast_widgets(&self) -> (adw::ApplicationWindow, adw::ToastOverlay) {
|
||||
(self.widgets.window.clone(), self.widgets.toast_overlay.clone())
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ pub enum Actions {
|
|||
SelectDxvkVersion(Rc<usize>),
|
||||
UpdateWineComboRow,
|
||||
SelectWineVersion(Rc<usize>),
|
||||
ToastError(Rc<(String, Error)>)
|
||||
Toast(Rc<(String, Error)>)
|
||||
}
|
||||
|
||||
impl Actions {
|
||||
|
@ -304,7 +304,7 @@ impl App {
|
|||
match component.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
||||
Ok(output) => println!("{}", output),
|
||||
Err(err) => {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to apply DXVK"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ impl App {
|
|||
|
||||
std::thread::spawn(move || {
|
||||
if let Err(err) = component.package.delete_in(&config.game.path) {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to delete voiceover"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -389,7 +389,7 @@ impl App {
|
|||
|
||||
if component.is_downloaded(&config.game.dxvk.builds) {
|
||||
if let Err(err) = component.delete(&config.game.dxvk.builds) {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to delete DXVK"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ impl App {
|
|||
match component.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
||||
Ok(output) => println!("{}", output),
|
||||
Err(err) => {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to apply DXVK"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ impl App {
|
|||
|
||||
if component.is_downloaded(&config.game.wine.builds) {
|
||||
if let Err(err) = component.delete(&config.game.wine.builds) {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to delete wine"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ impl App {
|
|||
match version.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
||||
Ok(output) => println!("{}", output),
|
||||
Err(err) => {
|
||||
this.update(Actions::ToastError(Rc::new((
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to apply DXVK"), err
|
||||
)))).unwrap();
|
||||
}
|
||||
|
@ -566,10 +566,10 @@ impl App {
|
|||
config::update(config);
|
||||
}
|
||||
|
||||
Actions::ToastError(toast) => {
|
||||
Actions::Toast(toast) => {
|
||||
let (msg, err) = (toast.0.clone(), toast.1.to_string());
|
||||
|
||||
this.toast_error(msg, err);
|
||||
this.toast(msg, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,7 +697,7 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToastError for App {
|
||||
impl Toast for App {
|
||||
fn get_toast_widgets(&self) -> (adw::ApplicationWindow, adw::ToastOverlay) {
|
||||
let app = (&*self.app).take();
|
||||
self.app.set(app.clone());
|
||||
|
|
|
@ -89,7 +89,7 @@ impl PreferencesStack {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToastError for PreferencesStack {
|
||||
impl Toast for PreferencesStack {
|
||||
fn get_toast_widgets(&self) -> (adw::ApplicationWindow, adw::ToastOverlay) {
|
||||
let app = (&*self.app).take();
|
||||
self.app.set(app.clone());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pub mod toast_error;
|
||||
pub mod toast;
|
||||
pub mod download_component;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::toast_error::*;
|
||||
pub use super::toast::*;
|
||||
pub use super::download_component::*;
|
||||
}
|
||||
|
|
44
src/ui/traits/toast.rs
Normal file
44
src/ui/traits/toast.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use gtk4::{self as gtk, prelude::*};
|
||||
use libadwaita as adw;
|
||||
|
||||
use crate::ui::add_action;
|
||||
|
||||
pub trait Toast {
|
||||
fn get_toast_widgets(&self) -> (adw::ApplicationWindow, adw::ToastOverlay);
|
||||
|
||||
/// Show toast with `toast` title and `See message` button
|
||||
///
|
||||
/// This button will show message dialog with some message
|
||||
fn toast<T: ToString, F: std::fmt::Display + 'static>(&self, toast: T, message: F) {
|
||||
let toast = adw::Toast::new(toast.to_string().as_str());
|
||||
let (window, toast_overlay) = self.get_toast_widgets();
|
||||
|
||||
toast.set_timeout(0);
|
||||
|
||||
let message = format!("{}", message);
|
||||
|
||||
if message.len() > 0 {
|
||||
toast.set_button_label(Some("See message"));
|
||||
toast.set_action_name(Some("see-message.see-message"));
|
||||
|
||||
// Show message in a dialog window
|
||||
add_action(&toast_overlay, "see-message", move || {
|
||||
let dialog = gtk::MessageDialog::new(
|
||||
Some(&window),
|
||||
gtk::DialogFlags::all(),
|
||||
gtk::MessageType::Info,
|
||||
gtk::ButtonsType::Close,
|
||||
&message
|
||||
);
|
||||
|
||||
dialog.connect_response(move |dialog, _| {
|
||||
dialog.close();
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
});
|
||||
}
|
||||
|
||||
toast_overlay.add_toast(&toast);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
use gtk4::{self as gtk, prelude::*};
|
||||
use libadwaita as adw;
|
||||
|
||||
use crate::ui::add_action;
|
||||
|
||||
pub trait ToastError {
|
||||
fn get_toast_widgets(&self) -> (adw::ApplicationWindow, adw::ToastOverlay);
|
||||
|
||||
/// Show toast with `toast` title and `See message` button
|
||||
///
|
||||
/// This button will show message dialog with error message
|
||||
fn toast_error<T: ToString, F: std::fmt::Display + 'static>(&self, toast: T, err: F) {
|
||||
let toast = adw::Toast::new(toast.to_string().as_str());
|
||||
|
||||
toast.set_button_label(Some("See message"));
|
||||
toast.set_action_name(Some("see-message.see-message"));
|
||||
toast.set_timeout(0);
|
||||
|
||||
let (window, toast_overlay) = self.get_toast_widgets();
|
||||
|
||||
// Show error message in a dialog window
|
||||
add_action(&toast_overlay, "see-message", move || {
|
||||
let dialog = gtk::MessageDialog::new(
|
||||
Some(&window),
|
||||
gtk::DialogFlags::all(),
|
||||
gtk::MessageType::Info,
|
||||
gtk::ButtonsType::Close,
|
||||
&format!("{}", err)
|
||||
);
|
||||
|
||||
dialog.connect_response(move |dialog, _| {
|
||||
dialog.close();
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
});
|
||||
|
||||
toast_overlay.add_toast(&toast);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue