Preparations for preferences updates

- added `update` methods for preferences pages
- added wine hud option synchronization
This commit is contained in:
Observer KRypt0n_ 2022-07-01 20:40:45 +02:00
parent 59405f440c
commit 919d7eaaa9
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
5 changed files with 160 additions and 77 deletions

View file

@ -7,7 +7,7 @@ Adw.PreferencesPage enhanced_page {
Adw.PreferencesGroup {
title: "Wine";
Adw.ComboRow {
Adw.ComboRow hud_combo {
title: "HUD";
model: Gtk.StringList {
@ -19,7 +19,7 @@ Adw.PreferencesPage enhanced_page {
};
}
Adw.ComboRow {
Adw.ComboRow sync_combo {
title: "Synchronization";
subtitle: "Technology used to synchronize inner wine events";
@ -33,7 +33,7 @@ Adw.PreferencesPage enhanced_page {
};
}
Adw.ComboRow {
Adw.ComboRow fsr_combo {
title: "FSR";
subtitle: "AMD FSR scales game resolution while rendering the game with the lower one";

View file

@ -52,7 +52,43 @@ pub fn update(config: Config) -> Result<(), Error> {
}
}
#[derive(Debug, Serialize, Deserialize, Default)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum WineHUD {
None,
DXVK,
MangoHUD
}
impl Default for WineHUD {
fn default() -> Self {
Self::None
}
}
impl TryFrom<u32> for WineHUD {
type Error = String;
fn try_from(value: u32) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::None),
1 => Ok(Self::DXVK),
2 => Ok(Self::MangoHUD),
_ => Err(String::from("Failed to convert number to HUD enum"))
}
}
}
impl Into<u32> for WineHUD {
fn into(self) -> u32 {
match self {
WineHUD::None => 0,
WineHUD::DXVK => 1,
WineHUD::MangoHUD => 2
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Config {
pub launcher: Launcher,
pub game: Game,
@ -105,7 +141,7 @@ impl Config {
}
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Launcher {
pub language: String
}
@ -118,7 +154,7 @@ impl Default for Launcher {
}
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Patch {
pub path: String,
pub servers: Vec<String>
@ -136,7 +172,7 @@ impl Default for Patch {
}
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Game {
pub path: String,
pub voices: Vec<String>,
@ -162,7 +198,7 @@ impl Default for Game {
}
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Wine {
pub prefix: String,
pub builds: String,
@ -187,13 +223,14 @@ impl Default for Wine {
}
}
#[derive(Debug, Serialize, Deserialize, Default)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
pub struct Enhancements {
pub fsr: Fsr,
pub gamemode: bool
pub gamemode: bool,
pub hud: WineHUD
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Fsr {
pub strength: u8,
pub enabled: bool

View file

@ -1,23 +1,56 @@
use gtk4::{self as gtk, prelude::*};
use libadwaita::{self as adw, prelude::*};
use std::io::Error;
use crate::ui::get_object;
use crate::lib::config;
#[derive(Clone)]
pub struct Page {
pub page: adw::PreferencesPage
pub page: adw::PreferencesPage,
pub hud_combo: adw::ComboRow,
pub sync_combo: adw::ComboRow,
pub fsr_combo: adw::ComboRow
}
impl Page {
pub fn new() -> Result<Self, String> {
let builder = gtk::Builder::from_string(include_str!("../../../assets/ui/.dist/preferences_enhanced.ui"));
Ok(Self {
page: get_object(&builder, "enhanced_page")?
})
let result = Self {
page: get_object(&builder, "enhanced_page")?,
hud_combo: get_object(&builder, "hud_combo")?,
sync_combo: get_object(&builder, "sync_combo")?,
fsr_combo: get_object(&builder, "fsr_combo")?
};
// Wine HUD selection
result.hud_combo.connect_selected_notify(|hud| {
if let Ok(mut config) = config::get() {
// TODO: show toast
config.game.enhancements.hud = config::WineHUD::try_from(hud.selected()).unwrap();
config::update(config).unwrap();
}
});
Ok(result)
}
pub fn title() -> String {
String::from("Enhanced")
}
/// This method is being called by the `PreferencesStack::update`
pub fn update(&self) -> Result<(), Error> {
let config = config::get()?;
// Update Wine HUD
self.hud_combo.set_selected(config.game.enhancements.hud.into());
Ok(())
}
}

View file

@ -1,11 +1,17 @@
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;
#[derive(Clone)]
pub struct Page {
pub page: adw::PreferencesPage,
pub game_version: gtk::Label,
pub patch_version: gtk::Label
}
@ -24,4 +30,68 @@ impl Page {
pub fn title() -> String {
String::from("General")
}
/// This method is being called by the `PreferencesStack::update`
pub fn update(&self) -> Result<(), Error> {
let config = config::get()?;
let game = Game::new(config.game.path);
self.game_version.set_tooltip_text(None);
self.patch_version.set_tooltip_text(None);
match game.try_get_diff()? {
VersionDiff::Latest(version) => {
self.game_version.set_label(&version.to_string());
},
VersionDiff::Diff { current, latest, .. } => {
self.game_version.set_label(&current.to_string());
self.game_version.set_css_classes(&["warning"]);
self.game_version.set_tooltip_text(Some(&format!("Game update available: {} -> {}", current, latest)));
},
VersionDiff::Outdated { current, latest } => {
self.game_version.set_label(&current.to_string());
self.game_version.set_css_classes(&["error"]);
self.game_version.set_tooltip_text(Some(&format!("Game is too outdated and can't be updated. Latest version: {}", latest)));
},
VersionDiff::NotInstalled { .. } => {
self.game_version.set_label("not installed");
self.game_version.set_css_classes(&[]);
}
}
match Patch::try_fetch(config.patch.servers)? {
Patch::NotAvailable => {
self.patch_version.set_label("not available");
self.patch_version.set_css_classes(&["error"]);
self.patch_version.set_tooltip_text(Some("Patch is not available"));
},
Patch::Outdated { current, latest, .. } => {
self.patch_version.set_label("outdated");
self.patch_version.set_css_classes(&["warning"]);
self.patch_version.set_tooltip_text(Some(&format!("Patch is outdated ({} -> {})", current, latest)));
},
Patch::Preparation { .. } => {
self.patch_version.set_label("preparation");
self.patch_version.set_css_classes(&["warning"]);
self.patch_version.set_tooltip_text(Some("Patch is in preparation state and will be available later"));
},
Patch::Testing { version, .. } => {
self.patch_version.set_label(&version.to_string());
self.patch_version.set_css_classes(&["warning"]);
self.patch_version.set_tooltip_text(Some("Patch is in testing phase"));
},
Patch::Available { version, .. } => {
self.patch_version.set_label(&version.to_string());
self.patch_version.set_css_classes(&["success"]);
}
}
Ok(())
}
}

View file

@ -3,10 +3,7 @@ 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;
@ -20,7 +17,9 @@ pub mod pages {
pub struct PreferencesStack {
pub preferences: gtk::Box,
pub preferences_go_back: gtk::Button,
pub stack: gtk::Stack,
pub general_page: pages::GeneralPage,
pub enhanced_page: pages::EnhancedPage
}
@ -47,66 +46,10 @@ impl PreferencesStack {
///
/// Being called from the `MainApp` struct
///
/// TODO: do it asynchronously
/// TODO: do it asynchronously. The problem is that I somehow need to handle this function's error to display it as a toast
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"]);
}
}
self.general_page.update()?;
self.enhanced_page.update()?;
Ok(())
}