mirror of
https://github.com/an-anime-team/sleepy-launcher.git
synced 2025-03-15 06:28:27 +03:00
Reworked DXVKs UI components to support different builds
This commit is contained in:
parent
00ff5c6409
commit
8a62ed5674
6 changed files with 122 additions and 90 deletions
|
@ -120,14 +120,5 @@ Adw.PreferencesPage page {
|
|||
}
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup {
|
||||
Adw.ExpanderRow dxvk_vanilla {
|
||||
title: "Vanilla";
|
||||
}
|
||||
|
||||
Adw.ExpanderRow dxvk_async {
|
||||
title: "Async";
|
||||
subtitle: "This version is not recommended for usage as can lead to anti-cheat detection. Automatically uses DXVK_ASYNC=1";
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup dxvk_groups {}
|
||||
}
|
||||
|
|
|
@ -9,42 +9,41 @@ use regex::Regex;
|
|||
use crate::lib::config;
|
||||
|
||||
lazy_static! {
|
||||
static ref VANILLA_LIST: Vec<Version> = serde_json::from_str(include_str!("../../components/dxvk/vanilla.json")).unwrap();
|
||||
static ref ASYNC_LIST: Vec<Version> = serde_json::from_str(include_str!("../../components/dxvk/async.json")).unwrap();
|
||||
static ref GROUPS: Vec<Group> = vec![
|
||||
Group {
|
||||
title: String::from("Vanilla"),
|
||||
subtitle: None,
|
||||
versions: serde_json::from_str(include_str!("../../components/dxvk/vanilla.json")).unwrap()
|
||||
},
|
||||
Group {
|
||||
title: String::from("Async"),
|
||||
subtitle: Some(String::from("This version is not recommended for usage as can lead to anti-cheat detection. Automatically uses DXVK_ASYNC=1")),
|
||||
versions: serde_json::from_str(include_str!("../../components/dxvk/async.json")).unwrap()
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct List {
|
||||
pub vanilla: Vec<Version>,
|
||||
pub r#async: Vec<Version>
|
||||
}
|
||||
pub struct List;
|
||||
|
||||
impl List {
|
||||
pub fn get() -> Self {
|
||||
Self {
|
||||
vanilla: VANILLA_LIST.clone(),
|
||||
r#async: ASYNC_LIST.clone()
|
||||
}
|
||||
pub fn get() -> Vec<Group> {
|
||||
GROUPS.clone()
|
||||
}
|
||||
|
||||
/// List only downloaded DXVK versions in some specific folder
|
||||
pub fn list_downloaded<T: ToString>(folder: T) -> std::io::Result<List> {
|
||||
let mut vanilla = Vec::new();
|
||||
let mut r#async = Vec::new();
|
||||
pub fn list_downloaded<T: ToString>(folder: T) -> std::io::Result<Vec<Version>> {
|
||||
let mut downloaded = Vec::new();
|
||||
|
||||
let list = Self::get();
|
||||
|
||||
for entry in std::fs::read_dir(folder.to_string())? {
|
||||
let name = entry?.file_name();
|
||||
|
||||
for (i, versions) in [&list.vanilla, &list.r#async].into_iter().enumerate() {
|
||||
for version in versions {
|
||||
for group in &list {
|
||||
for version in &group.versions {
|
||||
if name == version.name.as_str() {
|
||||
match i {
|
||||
0 => vanilla.push(version.clone()),
|
||||
1 => r#async.push(version.clone()),
|
||||
_ => unreachable!()
|
||||
}
|
||||
downloaded.push(version.clone());
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -52,13 +51,17 @@ impl List {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(List {
|
||||
vanilla,
|
||||
r#async
|
||||
})
|
||||
Ok(downloaded)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Group {
|
||||
pub title: String,
|
||||
pub subtitle: Option<String>,
|
||||
pub versions: Vec<Version>
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Version {
|
||||
pub name: String,
|
||||
|
@ -69,7 +72,7 @@ pub struct Version {
|
|||
|
||||
impl Version {
|
||||
pub fn latest() -> Result<Self, serde_json::Error> {
|
||||
Ok(List::get().vanilla[0].clone())
|
||||
Ok(List::get()[0].versions[0].clone())
|
||||
}
|
||||
|
||||
pub fn is_downloaded_in<T: ToString>(&self, folder: T) -> bool {
|
||||
|
|
43
src/ui/components/dxvk_group.rs
Normal file
43
src/ui/components/dxvk_group.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use libadwaita::{self as adw, prelude::*};
|
||||
|
||||
use crate::lib::dxvk::Group;
|
||||
use super::dxvk_row::DxvkRow;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DxvkGroup {
|
||||
pub group: Group,
|
||||
pub version_components: Vec<DxvkRow>,
|
||||
|
||||
pub expander_row: adw::ExpanderRow
|
||||
}
|
||||
|
||||
impl DxvkGroup {
|
||||
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.versions {
|
||||
let component = DxvkRow::new(version.clone());
|
||||
|
||||
expander_row.add_row(&component.row);
|
||||
|
||||
version_components.push(component);
|
||||
}
|
||||
|
||||
Self {
|
||||
group,
|
||||
version_components,
|
||||
expander_row
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_states<T: ToString>(&self, runners_folder: T) {
|
||||
for component in &self.version_components {
|
||||
component.update_state(runners_folder.to_string());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
pub mod dxvk_row;
|
||||
pub mod wine_group;
|
||||
pub mod wine_row;
|
||||
pub mod dxvk_group;
|
||||
pub mod dxvk_row;
|
||||
pub mod progress_bar;
|
||||
pub mod voiceover_row;
|
||||
|
|
|
@ -62,7 +62,7 @@ impl Page {
|
|||
// Add DXVK versions
|
||||
let model = gtk::StringList::new(&[]);
|
||||
|
||||
for version in &DxvkList::get().vanilla {
|
||||
for version in &DxvkList::get()[0].versions {
|
||||
if version.recommended {
|
||||
model.append(&version.version);
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ use crate::lib::launcher::states::LauncherState;
|
|||
use crate::ui::*;
|
||||
use crate::ui::traits::prelude::*;
|
||||
use crate::ui::components::voiceover_row::VoiceoverRow;
|
||||
use crate::ui::components::dxvk_row::DxvkRow;
|
||||
use crate::ui::components::wine_group::WineGroup;
|
||||
use crate::ui::components::dxvk_group::DxvkGroup;
|
||||
|
||||
/// This structure is used to describe widgets used in application
|
||||
///
|
||||
|
@ -48,11 +48,10 @@ pub struct AppWidgets {
|
|||
|
||||
pub dxvk_selected: adw::ComboRow,
|
||||
|
||||
pub dxvk_groups: adw::PreferencesGroup,
|
||||
pub dxvk_recommended_only: gtk::Switch,
|
||||
pub dxvk_vanilla: adw::ExpanderRow,
|
||||
pub dxvk_async: adw::ExpanderRow,
|
||||
|
||||
pub dxvk_components: Rc<Vec<DxvkRow>>
|
||||
pub dxvk_components: Rc<Vec<DxvkGroup>>
|
||||
}
|
||||
|
||||
impl AppWidgets {
|
||||
|
@ -79,9 +78,8 @@ impl AppWidgets {
|
|||
|
||||
dxvk_selected: get_object(&builder, "dxvk_selected")?,
|
||||
|
||||
dxvk_groups: get_object(&builder, "dxvk_groups")?,
|
||||
dxvk_recommended_only: get_object(&builder, "dxvk_recommended_only")?,
|
||||
dxvk_vanilla: get_object(&builder, "dxvk_vanilla")?,
|
||||
dxvk_async: get_object(&builder, "dxvk_async")?,
|
||||
|
||||
dxvk_components: Default::default()
|
||||
};
|
||||
|
@ -125,24 +123,16 @@ impl AppWidgets {
|
|||
result.wine_components = Rc::new(components);
|
||||
|
||||
// Update DXVK list
|
||||
let list = dxvk::List::get();
|
||||
|
||||
let mut components = Vec::new();
|
||||
|
||||
for (i, versions) in [list.vanilla, list.r#async].into_iter().enumerate() {
|
||||
for version in versions {
|
||||
let row = DxvkRow::new(version);
|
||||
for group in dxvk::List::get() {
|
||||
let group = DxvkGroup::new(group);
|
||||
|
||||
row.update_state(&config.game.dxvk.builds);
|
||||
group.update_states(&config.game.dxvk.builds);
|
||||
|
||||
match i {
|
||||
0 => result.dxvk_vanilla.add_row(&row.row),
|
||||
1 => result.dxvk_async.add_row(&row.row),
|
||||
_ => ()
|
||||
}
|
||||
result.dxvk_groups.add(&group.expander_row);
|
||||
|
||||
components.push(row);
|
||||
}
|
||||
components.push(group);
|
||||
}
|
||||
|
||||
result.dxvk_components = Rc::new(components);
|
||||
|
@ -158,7 +148,7 @@ impl AppWidgets {
|
|||
pub enum Actions {
|
||||
RepairGame,
|
||||
VoiceoverPerformAction(Rc<usize>),
|
||||
DxvkPerformAction(Rc<usize>),
|
||||
DxvkPerformAction(Rc<(usize, usize)>),
|
||||
WinePerformAction(Rc<(usize, usize)>),
|
||||
UpdateDxvkComboRow,
|
||||
SelectDxvkVersion(Rc<usize>),
|
||||
|
@ -275,35 +265,39 @@ impl App {
|
|||
|
||||
// Set DXVK recommended only switcher event
|
||||
self.widgets.dxvk_recommended_only.connect_state_notify(clone!(@weak self as this => move |switcher| {
|
||||
for component in &*this.widgets.dxvk_components {
|
||||
component.row.set_visible(if switcher.state() {
|
||||
component.version.recommended
|
||||
} else {
|
||||
true
|
||||
});
|
||||
for group in &*this.widgets.dxvk_components {
|
||||
for component in &group.version_components {
|
||||
component.row.set_visible(if switcher.state() {
|
||||
component.version.recommended
|
||||
} else {
|
||||
true
|
||||
});
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// DXVK install/remove/apply buttons
|
||||
let components = &*self.widgets.dxvk_components;
|
||||
|
||||
for (i, component) in components.into_iter().enumerate() {
|
||||
component.button.connect_clicked(Actions::DxvkPerformAction(Rc::new(i)).into_fn(&self));
|
||||
for (i, group) in components.into_iter().enumerate() {
|
||||
for (j, component) in (&group.version_components).into_iter().enumerate() {
|
||||
component.button.connect_clicked(Actions::DxvkPerformAction(Rc::new((i, j))).into_fn(&self));
|
||||
|
||||
component.apply_button.connect_clicked(clone!(@strong component, @weak self as this => move |_| {
|
||||
std::thread::spawn(clone!(@strong component, @strong this => move || {
|
||||
let config = config::get().expect("Failed to load config");
|
||||
|
||||
match component.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
||||
Ok(output) => println!("{}", String::from_utf8_lossy(&output.stdout)),
|
||||
Err(err) => {
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to apply DXVK"), err.to_string()
|
||||
)))).unwrap();
|
||||
component.apply_button.connect_clicked(clone!(@strong component, @weak self as this => move |_| {
|
||||
std::thread::spawn(clone!(@strong component, @strong this => move || {
|
||||
let config = config::get().expect("Failed to load config");
|
||||
|
||||
match component.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
||||
Ok(output) => println!("{}", String::from_utf8_lossy(&output.stdout)),
|
||||
Err(err) => {
|
||||
this.update(Actions::Toast(Rc::new((
|
||||
String::from("Failed to apply DXVK"), err.to_string()
|
||||
)))).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
|
@ -377,8 +371,10 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
Actions::DxvkPerformAction(i) => {
|
||||
let component = this.widgets.dxvk_components[*i].clone();
|
||||
Actions::DxvkPerformAction(version) => {
|
||||
let component = this.widgets
|
||||
.dxvk_components[version.0]
|
||||
.version_components[version.1].clone();
|
||||
|
||||
if component.is_downloaded(&config.game.dxvk.builds) {
|
||||
if let Err(err) = component.delete(&config.game.dxvk.builds) {
|
||||
|
@ -449,18 +445,16 @@ impl App {
|
|||
let mut raw_list = Vec::new();
|
||||
let mut selected = 0;
|
||||
|
||||
for (i, group) in [list.vanilla, list.r#async].into_iter().enumerate() {
|
||||
for version in group {
|
||||
model.append(format!("{} {}", if i == 0 { "Vanilla" } else { "Async" }, version.version).as_str());
|
||||
|
||||
if let Some(curr) = &config.game.dxvk.selected {
|
||||
if &version.name == curr {
|
||||
selected = raw_list.len() as u32;
|
||||
}
|
||||
}
|
||||
for version in list {
|
||||
model.append(&version.name);
|
||||
|
||||
raw_list.push(version);
|
||||
if let Some(curr) = &config.game.dxvk.selected {
|
||||
if &version.name == curr {
|
||||
selected = raw_list.len() as u32;
|
||||
}
|
||||
}
|
||||
|
||||
raw_list.push(version);
|
||||
}
|
||||
|
||||
let mut values = this.values.take();
|
||||
|
|
Loading…
Add table
Reference in a new issue