Added game and patch status updating in settings

This commit is contained in:
Observer KRypt0n_ 2022-07-01 20:12:25 +02:00
parent 86de977e05
commit 59405f440c
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
8 changed files with 180 additions and 22 deletions

View file

@ -58,7 +58,7 @@ Adw.ApplicationWindow window {
styles ["suggested-action"]
popover: Gtk.Popover {
Gtk.Button {
Gtk.Button launch_game_debug {
label: "Launch in debug mode";
}
};

View file

@ -26,7 +26,7 @@ Adw.PreferencesPage general_page {
Adw.ActionRow {
title: "Game version";
Gtk.Label {
Gtk.Label game_version {
label: "2.7.0";
styles ["success"]
@ -36,7 +36,7 @@ Adw.PreferencesPage general_page {
Adw.ActionRow {
title: "Patch version";
Gtk.Label {
Gtk.Label patch_version {
label: "2.7.0";
styles ["success"]

View file

@ -27,6 +27,22 @@ impl Terminal {
Terminal::Xfce4Terminal
].into_iter()
}
pub fn get_args(&self, bash_command: &str) -> Vec<String> {
match self {
Terminal::GnomeTerminal => vec![
String::from("--"),
String::from("bash"),
String::from("-c"),
format!("{} && bash", bash_command)
],
Terminal::Konsole | Terminal::Xfce4Terminal => vec![
String::from("--hold"),
String::from("-e"),
format!("\"bash -c '{} && bash'\"", bash_command)
]
}
}
}
/// Try to get GUI terminal installed in system
@ -43,7 +59,9 @@ pub fn try_get_terminal() -> Option<Terminal> {
}
/// Try to run the game
pub fn run() -> Result<(), Error> {
///
/// If `debug = true`, then the game will be run in the new terminal window
pub fn run(debug: bool) -> Result<(), Error> {
let config = config::get()?;
if !Path::new(&config.game.path).exists() {
@ -57,12 +75,31 @@ pub fn run() -> Result<(), Error> {
let mut command = Command::new(wine_executable);
if debug {
// Is not supported now because new spawned terminal needs
// to have cwd and env variables specified directly
// which is kinda difficult
todo!();
match try_get_terminal() {
Some(terminal) => {
command = Command::new(terminal.get_command());
command.args(terminal.get_args("launcher.bat"));
},
None => return Err(Error::new(ErrorKind::Other, "Couldn't find terminal application"))
}
}
else {
command.arg("launcher.bat");
}
command.env("WINEPREFIX", &config.game.wine.prefix);
command.envs(config.get_wine_sync_env_vars());
command.envs(config.game.environment)
.current_dir(config.game.path)
.arg("launcher.bat")
.spawn()?;
Ok(())

View file

@ -20,8 +20,12 @@ fn main() {
application.connect_activate(|app| {
let app = MainApp::new(app).unwrap();
let app_copy = app.clone();
app.open_preferences.connect_clicked(move |_| {
app.leaflet.set_visible_child_name("preferences_page");
if let Err(err) = app_copy.open_preferences_page() {
app_copy.toast_error("Failed to open settings page", err);
}
});
app.window.show();

View file

@ -1,6 +1,8 @@
use gtk4::{self as gtk, prelude::*};
use libadwaita::{self as adw, prelude::*};
use std::io::Error;
use super::{get_object, add_action};
use super::preferences::PreferencesStack;
@ -11,8 +13,11 @@ pub struct App {
pub window: adw::ApplicationWindow,
pub leaflet: adw::Leaflet,
pub launch_game: adw::SplitButton,
pub launch_game_debug: gtk::Button,
pub open_preferences: gtk::Button,
pub toast_overlay: adw::ToastOverlay
pub toast_overlay: adw::ToastOverlay,
pub preferences_stack: PreferencesStack
}
impl App {
@ -25,18 +30,20 @@ impl App {
window: get_object(&builder, "window")?,
leaflet: get_object(&builder, "leaflet")?,
launch_game: get_object(&builder, "launch_game")?,
launch_game_debug: get_object(&builder, "launch_game_debug")?,
open_preferences: get_object(&builder, "open_preferences")?,
toast_overlay: get_object(&builder, "toast_overlay")?
toast_overlay: get_object(&builder, "toast_overlay")?,
preferences_stack: PreferencesStack::new()?
};
// Add preferences page to the leaflet
let stack = PreferencesStack::new()?;
let leaflet = result.leaflet.clone();
result.leaflet.append(&stack.preferences).set_name(Some("preferences_page"));
result.leaflet.append(&result.preferences_stack.preferences).set_name(Some("preferences_page"));
// Go back button for preferences page
stack.preferences_go_back.connect_clicked(move |_| {
result.preferences_stack.preferences_go_back.connect_clicked(move |_| {
leaflet.navigate(adw::NavigationDirection::Back);
});
@ -45,11 +52,21 @@ impl App {
result.launch_game.connect_clicked(move |_| {
// Display toast message if the game is failed to run
if let Err(err) = game::run() {
if let Err(err) = game::run(false) {
app_copy.toast_error("Failed to run game", err);
}
});
// Launch game in debug mode
/*let app_copy = result.clone();
result.launch_game_debug.connect_clicked(move |_| {
// Display toast message if the game is failed to run
if let Err(err) = game::run(true) {
app_copy.toast_error("Failed to run game", err);
}
});*/
// Bind app to the window
result.window.set_application(Some(app));
@ -86,4 +103,12 @@ impl App {
self.toast_overlay.add_toast(&toast);
}
pub fn open_preferences_page(&self) -> Result<(), Error> {
self.preferences_stack.update()?;
self.leaflet.set_visible_child_name("preferences_page");
Ok(())
}
}

View file

@ -3,13 +3,18 @@ use libadwaita::{self as adw, prelude::*};
use crate::ui::get_object;
pub struct Page;
#[derive(Clone)]
pub struct Page {
pub page: adw::PreferencesPage
}
impl Page {
pub fn get() -> Result<adw::PreferencesPage, String> {
pub fn new() -> Result<Self, String> {
let builder = gtk::Builder::from_string(include_str!("../../../assets/ui/.dist/preferences_enhanced.ui"));
Ok(get_object(&builder, "enhanced_page")?)
Ok(Self {
page: get_object(&builder, "enhanced_page")?
})
}
pub fn title() -> String {

View file

@ -3,13 +3,22 @@ use libadwaita::{self as adw, prelude::*};
use crate::ui::get_object;
pub struct Page;
#[derive(Clone)]
pub struct Page {
pub page: adw::PreferencesPage,
pub game_version: gtk::Label,
pub patch_version: gtk::Label
}
impl Page {
pub fn get() -> Result<adw::PreferencesPage, String> {
pub fn new() -> Result<Self, String> {
let builder = gtk::Builder::from_string(include_str!("../../../assets/ui/.dist/preferences_general.ui"));
Ok(get_object(&builder, "general_page")?)
Ok(Self {
page: get_object(&builder, "general_page")?,
game_version: get_object(&builder, "game_version")?,
patch_version: get_object(&builder, "patch_version")?
})
}
pub fn title() -> String {

View file

@ -1,7 +1,12 @@
use gtk4::{self as gtk, prelude::*};
use libadwaita::{self as adw, prelude::*};
use std::io::Error;
use anime_game_core::prelude::*;
use crate::ui::get_object;
use crate::lib::config;
mod general_page;
mod enhanced_page;
@ -11,10 +16,13 @@ pub mod pages {
pub use super::enhanced_page::Page as EnhancedPage;
}
#[derive(Clone)]
pub struct PreferencesStack {
pub preferences: gtk::Box,
pub preferences_go_back: gtk::Button,
pub stack: gtk::Stack
pub stack: gtk::Stack,
pub general_page: pages::GeneralPage,
pub enhanced_page: pages::EnhancedPage
}
impl PreferencesStack {
@ -24,12 +32,82 @@ impl PreferencesStack {
let result = Self {
preferences: get_object(&builder, "preferences")?,
preferences_go_back: get_object(&builder, "preferences_go_back")?,
stack: get_object(&builder, "stack")?
stack: get_object(&builder, "stack")?,
general_page: pages::GeneralPage::new()?,
enhanced_page: pages::EnhancedPage::new()?
};
result.stack.add_titled(&pages::GeneralPage::get()?, None, &pages::GeneralPage::title());
result.stack.add_titled(&pages::EnhancedPage::get()?, None, &pages::EnhancedPage::title());
result.stack.add_titled(&result.general_page.page, None, &pages::GeneralPage::title());
result.stack.add_titled(&result.enhanced_page.page, None, &pages::EnhancedPage::title());
Ok(result)
}
/// Update page info before opening it
///
/// Being called from the `MainApp` struct
///
/// TODO: do it asynchronously
pub fn update(&self) -> Result<(), Error> {
let config = config::get()?;
let game = Game::new(config.game.path);
self.general_page.game_version.set_tooltip_text(None);
self.general_page.patch_version.set_tooltip_text(None);
match game.try_get_diff()? {
VersionDiff::Latest(version) => {
self.general_page.game_version.set_label(&version.to_string());
},
VersionDiff::Diff { current, latest, .. } => {
self.general_page.game_version.set_label(&current.to_string());
self.general_page.game_version.set_css_classes(&["warning"]);
self.general_page.game_version.set_tooltip_text(Some(&format!("Game update available: {} -> {}", current, latest)));
},
VersionDiff::Outdated { current, latest } => {
self.general_page.game_version.set_label(&current.to_string());
self.general_page.game_version.set_css_classes(&["error"]);
self.general_page.game_version.set_tooltip_text(Some(&format!("Game is too outdated and can't be updated. Latest version: {}", latest)));
},
VersionDiff::NotInstalled { .. } => {
self.general_page.game_version.set_label("not installed");
self.general_page.game_version.set_css_classes(&[]);
}
}
match Patch::try_fetch(config.patch.servers)? {
Patch::NotAvailable => {
self.general_page.patch_version.set_label("not available");
self.general_page.patch_version.set_css_classes(&["error"]);
self.general_page.patch_version.set_tooltip_text(Some("Patch is not available"));
},
Patch::Outdated { current, latest, .. } => {
self.general_page.patch_version.set_label("outdated");
self.general_page.patch_version.set_css_classes(&["warning"]);
self.general_page.patch_version.set_tooltip_text(Some(&format!("Patch is outdated ({} -> {})", current, latest)));
},
Patch::Preparation { .. } => {
self.general_page.patch_version.set_label("preparation");
self.general_page.patch_version.set_css_classes(&["warning"]);
self.general_page.patch_version.set_tooltip_text(Some("Patch is in preparation state and will be available later"));
},
Patch::Testing { version, .. } => {
self.general_page.patch_version.set_label(&version.to_string());
self.general_page.patch_version.set_css_classes(&["warning"]);
self.general_page.patch_version.set_tooltip_text(Some("Patch is in testing phase"));
},
Patch::Available { version, .. } => {
self.general_page.patch_version.set_label(&version.to_string());
self.general_page.patch_version.set_css_classes(&["success"]);
}
}
Ok(())
}
}