From fb021a074263042544a5253c0d48af25e69d1b77 Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Thu, 14 Jul 2022 15:35:33 +0200 Subject: [PATCH] Added WineRow and WineGroup components, made dynamic loading --- assets/ui/preferences_general.blp | 89 +---------- assets/wine.json | 231 +---------------------------- src/lib/mod.rs | 3 +- src/lib/wine.rs | 35 +++++ src/ui/components/mod.rs | 2 + src/ui/components/wine_group.rs | 41 +++++ src/ui/components/wine_row.rs | 78 ++++++++++ src/ui/preferences/general_page.rs | 43 ++++++ 8 files changed, 206 insertions(+), 316 deletions(-) create mode 100644 src/lib/wine.rs create mode 100644 src/ui/components/wine_group.rs create mode 100644 src/ui/components/wine_row.rs diff --git a/assets/ui/preferences_general.blp b/assets/ui/preferences_general.blp index b5a434a..6905135 100644 --- a/assets/ui/preferences_general.blp +++ b/assets/ui/preferences_general.blp @@ -123,99 +123,14 @@ Adw.PreferencesPage general_page { title: "Recommended only"; subtitle: "Show only recommended wine versions"; - Gtk.Switch { + Gtk.Switch wine_recommended_only { valign: center; state: true; } } } - Adw.PreferencesGroup { - Adw.ExpanderRow { - title: "Wine-GE"; - - Adw.ActionRow { - title: "7-16"; - } - - Adw.ActionRow { - title: "7-15"; - } - - Adw.ActionRow { - title: "7-14"; - } - - Adw.ActionRow { - title: "7-12"; - } - - Adw.ActionRow { - title: "7-10"; - } - - Adw.ActionRow { - title: "7-9"; - } - } - - Adw.ExpanderRow { - title: "Proton-GE"; - subtitle: "This version includes its own DXVK builds and you can use DXVK_ASYNC variable"; - - Adw.ActionRow { - title: "7-16"; - } - - Adw.ActionRow { - title: "7-15"; - } - - Adw.ActionRow { - title: "7-14"; - } - - Adw.ActionRow { - title: "7-12"; - } - - Adw.ActionRow { - title: "7-10"; - } - - Adw.ActionRow { - title: "7-9"; - } - } - - Adw.ExpanderRow { - title: "Lutris"; - - Adw.ActionRow { - title: "7-16"; - } - - Adw.ActionRow { - title: "7-15"; - } - - Adw.ActionRow { - title: "7-14"; - } - - Adw.ActionRow { - title: "7-12"; - } - - Adw.ActionRow { - title: "7-10"; - } - - Adw.ActionRow { - title: "7-9"; - } - } - } + Adw.PreferencesGroup wine_groups {} Adw.PreferencesGroup { title: "DXVK version"; diff --git a/assets/wine.json b/assets/wine.json index 124c932..c67565f 100644 --- a/assets/wine.json +++ b/assets/wine.json @@ -1,6 +1,7 @@ [ { "title": "Wine-GE-Proton", + "subtitle": null, "runners": [ { "family": "Wine-GE-Proton", @@ -181,107 +182,12 @@ "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" }, "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-7.2-2-x86_64", - "title": "Wine 7.2 GE 2", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/7.2-GE-2/wine-lutris-ge-7.2-2-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-7.2-1-x86_64", - "title": "Wine 7.2 GE 1", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/7.2-GE-1/wine-lutris-ge-7.2-1-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-7.1-1-x86_64", - "title": "Wine 7.1 GE 1", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/7.1-GE-1/wine-lutris-ge-7.1-1-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-6.21-1-x86_64", - "title": "Wine 6.21 GE 1", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/6.21-GE-1/wine-lutris-ge-6.21-1-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-6.20-1-x86_64", - "title": "Wine 6.20 GE 1", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/6.20-GE-1/wine-lutris-ge-6.20-1-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-6.19-1-x86_64", - "title": "Wine 6.19 GE 1", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/6.19-GE-1/wine-lutris-ge-6.19-1-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-6.18-1-x86_64", - "title": "Wine 6.18 GE 1", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/6.18-GE-1/wine-lutris-ge-6.18-1-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "Wine-GE-Proton", - "name": "lutris-ge-6.16-1-x86_64", - "title": "Wine 6.16 GE 1", - "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/6.16-GE-1/lutris-ge-6.16-1-x86_64.tar.xz", - "files": { - "wine": "bin/wine64", - "wineserver": "bin/wineserver", - "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false } ] }, { "title": "GE-Proton", + "subtitle": "This version includes its own DXVK builds and you can use DXVK_ASYNC variable", "runners": [ { "family": "GE-Proton", @@ -486,143 +392,12 @@ "winecfg": "dist/lib64/wine/x86_64-windows/winecfg.exe" }, "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-7.2-GE-2", - "title": "Proton 7.2 GE 2", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/7.2-GE-2/Proton-7.2-GE-2.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-7.2-GE-1", - "title": "Proton 7.2 GE 1", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/7.2-GE-1/Proton-7.2-GE-1.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-7.1-GE-2", - "title": "Proton 7.1 GE 2", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/7.1-GE-2/Proton-7.1-GE-2.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-7.1-GE-1", - "title": "Proton 7.1 GE 1", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/7.1-GE-1/Proton-7.1-GE-1.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-6.21-GE-2", - "title": "Proton 6.21 GE 2", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.21-GE-2/Proton-6.21-GE-2.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-6.20-GE-1", - "title": "Proton 6.20 GE 1", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.20-GE-1/Proton-6.20-GE-1.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-6.19-GE-2", - "title": "Proton 6.19 GE 2", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.19-GE-2/Proton-6.19-GE-2.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-6.19-GE-1", - "title": "Proton 6.19 GE 1", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.19-GE-1/Proton-6.19-GE-1.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-6.18-GE-2", - "title": "Proton 6.18 GE 2", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.18-GE-2/Proton-6.18-GE-2.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-6.18-GE-1", - "title": "Proton 6.18 GE 1", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.18-GE-1/Proton-6.18-GE-1.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false - }, - { - "family": "GE-Proton", - "name": "Proton-6.16-GE-1", - "title": "Proton 6.16 GE 1", - "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.16-GE-1/Proton-6.16-GE-1.tar.gz", - "files": { - "wine": "files/bin/wine64", - "wineserver": "files/bin/wineserver", - "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" - }, - "recommended": false } ] }, { "title": "Lutris", + "subtitle": null, "runners": [ { "family": "Lutris", diff --git a/src/lib/mod.rs b/src/lib/mod.rs index 234967f..91a097a 100644 --- a/src/lib/mod.rs +++ b/src/lib/mod.rs @@ -1,5 +1,6 @@ pub mod consts; pub mod config; +pub mod tasks; pub mod game; pub mod dxvk; -pub mod tasks; +pub mod wine; diff --git a/src/lib/wine.rs b/src/lib/wine.rs new file mode 100644 index 0000000..d4133b7 --- /dev/null +++ b/src/lib/wine.rs @@ -0,0 +1,35 @@ +use serde::{Serialize, Deserialize}; + +const LIST: &str = include_str!("../../assets/wine.json"); + +pub struct List; + +impl List { + pub fn get() -> Result, serde_json::Error> { + Ok(serde_json::from_str(LIST)?) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Group { + pub title: String, + pub subtitle: Option, + pub runners: Vec +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Version { + pub family: String, + pub name: String, + pub title: String, + pub uri: String, + pub files: Files, + pub recommended: bool +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Files { + pub wine: String, + pub wineserver: String, + pub winecfg: String +} diff --git a/src/ui/components/mod.rs b/src/ui/components/mod.rs index 6fbcd3c..d5db4b8 100644 --- a/src/ui/components/mod.rs +++ b/src/ui/components/mod.rs @@ -1 +1,3 @@ pub mod dxvk_row; +pub mod wine_group; +pub mod wine_row; diff --git a/src/ui/components/wine_group.rs b/src/ui/components/wine_group.rs new file mode 100644 index 0000000..aba0873 --- /dev/null +++ b/src/ui/components/wine_group.rs @@ -0,0 +1,41 @@ +use gtk4::{self as gtk, prelude::*}; +use libadwaita::{self as adw, prelude::*}; + +use gtk::glib; +use gtk::Align; + +use crate::lib::wine::Group; +use super::wine_row::WineRow; + +#[derive(Debug, Clone)] +pub struct WineGroup { + pub group: Group, + pub version_components: Vec, + + pub expander_row: adw::ExpanderRow +} + +impl WineGroup { + pub fn new(group: Group) -> Self { + let expander_row = adw::ExpanderRow::new(); + + expander_row.set_title(&group.title); + expander_row.set_subtitle(group.subtitle.as_ref().unwrap_or(&String::new())); + + let mut version_components = Vec::new(); + + for version in &group.runners { + let component = WineRow::new(version.clone()); + + expander_row.add_row(&component.row); + + version_components.push(component); + } + + Self { + group, + version_components, + expander_row + } + } +} diff --git a/src/ui/components/wine_row.rs b/src/ui/components/wine_row.rs new file mode 100644 index 0000000..7b12c63 --- /dev/null +++ b/src/ui/components/wine_row.rs @@ -0,0 +1,78 @@ +use gtk4::{self as gtk, prelude::*}; +use libadwaita::{self as adw, prelude::*}; + +use gtk::glib; +use gtk::Align; + +use crate::lib::wine::Version; + +#[derive(Debug, Clone)] +pub struct WineRow { + pub version: Version, + + pub row: adw::ActionRow, + pub button: gtk::Button, + pub progress_bar: gtk::ProgressBar +} + +impl WineRow { + pub fn new(version: Version) -> Self { + let row = adw::ActionRow::new(); + let button = gtk::Button::new(); + + row.set_title(&version.title); + row.set_visible(version.recommended); + + button.set_icon_name("document-save-symbolic"); + button.set_valign(gtk::Align::Center); + button.add_css_class("flat"); + + row.add_suffix(&button); + + let progress_bar = gtk::ProgressBar::new(); + + progress_bar.set_text(Some("Downloading: 0%")); + progress_bar.set_show_text(true); + + progress_bar.set_width_request(200); + progress_bar.set_valign(Align::Center); + progress_bar.set_visible(false); + + row.add_suffix(&progress_bar); + + Self { + version, + row, + button, + progress_bar + } + } + + pub fn download(&self) { + let (sender, receiver) = glib::MainContext::channel::(glib::PRIORITY_DEFAULT); + let this = self.clone(); + + this.progress_bar.set_visible(true); + this.button.set_visible(false); + + receiver.attach(None, move |fraction| { + this.progress_bar.set_fraction(fraction as f64 / 100f64); + this.progress_bar.set_text(Some(&format!("Downloading: {}%", fraction))); + + if fraction == 100 { + this.progress_bar.set_visible(false); + this.button.set_visible(true); + } + + glib::Continue(true) + }); + + std::thread::spawn(move || { + for i in 1..101 { + std::thread::sleep(std::time::Duration::from_millis(150)); + + sender.send(i); + } + }); + } +} diff --git a/src/ui/preferences/general_page.rs b/src/ui/preferences/general_page.rs index 5fd95da..f4a176a 100644 --- a/src/ui/preferences/general_page.rs +++ b/src/ui/preferences/general_page.rs @@ -14,8 +14,10 @@ use anime_game_core::prelude::*; use crate::ui::get_object; use crate::lib::config; use crate::lib::dxvk; +use crate::lib::wine; use crate::ui::components::dxvk_row::DxvkRow; +use crate::ui::components::wine_group::WineGroup; /// This structure is used to describe widgets used in application /// @@ -29,6 +31,11 @@ pub struct AppWidgets { pub game_version: gtk::Label, pub patch_version: gtk::Label, + pub wine_groups: adw::PreferencesGroup, + pub wine_recommended_only: gtk::Switch, + + pub wine_components: Rc>, + pub dxvk_recommended_only: gtk::Switch, pub dxvk_vanilla: adw::ExpanderRow, pub dxvk_async: adw::ExpanderRow, @@ -46,6 +53,11 @@ impl AppWidgets { game_version: get_object(&builder, "game_version")?, patch_version: get_object(&builder, "patch_version")?, + wine_groups: get_object(&builder, "wine_groups")?, + wine_recommended_only: get_object(&builder, "wine_recommended_only")?, + + wine_components: Default::default(), + dxvk_recommended_only: get_object(&builder, "dxvk_recommended_only")?, dxvk_vanilla: get_object(&builder, "dxvk_vanilla")?, dxvk_async: get_object(&builder, "dxvk_async")?, @@ -53,6 +65,24 @@ impl AppWidgets { dxvk_components: Default::default() }; + // Update wine versions lists + let groups = match wine::List::get() { + Ok(list) => list, + Err(err) => return Err(err.to_string()) + }; + + let mut components = Vec::new(); + + for group in groups { + let group = WineGroup::new(group); + + result.wine_groups.add(&group.expander_row); + + components.push(group); + } + + result.wine_components = Rc::new(components); + // Update DXVK list let list = match dxvk::List::get() { Ok(list) => list, @@ -137,6 +167,19 @@ impl App { /// Add default events and values to the widgets fn init_events(self) -> Self { + // Set wine recommended only switcher event + self.widgets.wine_recommended_only.connect_state_notify(clone!(@strong self as this => move |switcher| { + for group in &*this.widgets.wine_components { + for component in &group.version_components { + component.row.set_visible(if switcher.state() { + component.version.recommended + } else { + true + }); + } + } + })); + // Set DXVK recommended only switcher event self.widgets.dxvk_recommended_only.connect_state_notify(clone!(@strong self as this => move |switcher| { for component in &*this.widgets.dxvk_components {