mirror of
https://github.com/ALEZ-DEV/Babylonia-terminal.git
synced 2025-12-15 17:08:51 +00:00
can now download proton from the new gtk launcher
This commit is contained in:
parent
846b4291c6
commit
fa242c1cca
782
Cargo.lock
generated
782
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,8 @@ relm4-components = "0.9.1"
|
||||
wincompatlib = "0.7.5"
|
||||
relm4 = { version = "0.9.1", features = ["libadwaita"] }
|
||||
libadwaita = { version = "0.7.1", features = ["v1_4"] }
|
||||
downloader = { git = "https://github.com/ALEZ-DEV/downloader" } # version = "0.2.7",
|
||||
rfd = "0.15.2"
|
||||
|
||||
[build-dependencies]
|
||||
glib-build-tools = "0.20.0"
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use std::{ops::Deref, sync::Arc};
|
||||
|
||||
use babylonia_terminal_sdk::{
|
||||
components::proton_component::ProtonComponent, game_config::GameConfig,
|
||||
game_manager::GameManager,
|
||||
game_manager::GameManager, utils::github_requester::GithubRelease,
|
||||
};
|
||||
use log::error;
|
||||
use relm4::{
|
||||
@ -9,7 +11,10 @@ use relm4::{
|
||||
};
|
||||
use wincompatlib::prelude::Proton;
|
||||
|
||||
use crate::ui;
|
||||
use crate::ui::{
|
||||
self,
|
||||
pages::steps::{self, download_components},
|
||||
};
|
||||
|
||||
static PROTON: OnceCell<Proton> = OnceCell::const_new();
|
||||
|
||||
@ -71,3 +76,75 @@ impl Worker for HandleGameProcess {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum HandleComponentInstallationMsg {
|
||||
StartInstallation(
|
||||
(
|
||||
usize,
|
||||
usize,
|
||||
Arc<download_components::DownloadComponentProgressBarReporter>,
|
||||
),
|
||||
), // proton release and dxvk release
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HandleComponentInstallation;
|
||||
|
||||
impl Worker for HandleComponentInstallation {
|
||||
type Init = ();
|
||||
|
||||
type Input = HandleComponentInstallationMsg;
|
||||
|
||||
type Output = download_components::DownloadComponentsMsg;
|
||||
|
||||
fn init(_init: Self::Init, _sender: relm4::ComponentSender<Self>) -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender<Self>) {
|
||||
match message {
|
||||
HandleComponentInstallationMsg::StartInstallation((
|
||||
proton_release,
|
||||
dxvk_release,
|
||||
progress_bar,
|
||||
)) => {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap()
|
||||
.block_on(async {
|
||||
let _ = sender.output(
|
||||
download_components::DownloadComponentsMsg::UpdateProgressBarMsg(
|
||||
String::from("Starting download for proton"),
|
||||
),
|
||||
);
|
||||
|
||||
let _ = sender.output(
|
||||
download_components::DownloadComponentsMsg::UpdateDownloadedComponentName(
|
||||
String::from("proton"),
|
||||
),
|
||||
);
|
||||
|
||||
let game_dir = if let Some(dir) = GameConfig::get_config().await.game_dir {
|
||||
dir
|
||||
} else {
|
||||
GameConfig::get_config_directory().await
|
||||
};
|
||||
|
||||
GameManager::install_wine(game_dir, proton_release, Some(progress_bar))
|
||||
.await;
|
||||
|
||||
let _ = sender.output(
|
||||
download_components::DownloadComponentsMsg::UpdateProgressBarMsg(
|
||||
String::from("Unpacking proton"),
|
||||
),
|
||||
);
|
||||
|
||||
let _ = sender
|
||||
.output(download_components::DownloadComponentsMsg::UpdateGameState);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
babylonia-terminal-gui/src/reporter.rs
Normal file
0
babylonia-terminal-gui/src/reporter.rs
Normal file
@ -17,7 +17,7 @@ use libadwaita as adw;
|
||||
|
||||
use crate::APP_RESOURCE_PATH;
|
||||
|
||||
mod pages;
|
||||
pub mod pages;
|
||||
|
||||
pub fn run(app: RelmApp<MainWindowMsg>) {
|
||||
app.run_async::<MainWindow>(None);
|
||||
@ -28,6 +28,7 @@ pub enum MainWindowMsg {
|
||||
ToggleMenuVisibility,
|
||||
SelectPage,
|
||||
SetIsGameRunning(bool),
|
||||
UpdateGameState,
|
||||
}
|
||||
|
||||
struct MainWindow {
|
||||
@ -103,7 +104,7 @@ impl SimpleAsyncComponent for MainWindow {
|
||||
set_valign: gtk::Align::Center,
|
||||
|
||||
#[watch]
|
||||
set_visible: model.game_state == GameState::GameInstalled,
|
||||
set_visible: model.game_state.is_environment_ready(),
|
||||
|
||||
adw::PreferencesPage {
|
||||
add = &adw::PreferencesGroup {
|
||||
@ -142,7 +143,7 @@ impl SimpleAsyncComponent for MainWindow {
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
|
||||
set_visible: model.game_state != GameState::GameInstalled,
|
||||
set_visible: !model.game_state.is_environment_ready(),
|
||||
|
||||
model.setup_page.widget(),
|
||||
}
|
||||
@ -236,6 +237,9 @@ impl SimpleAsyncComponent for MainWindow {
|
||||
MainWindowMsg::ToggleMenuVisibility => self.is_menu_visible = !self.is_menu_visible,
|
||||
MainWindowMsg::SelectPage => println!("Tried to select a new page"),
|
||||
MainWindowMsg::SetIsGameRunning(value) => self.is_game_running = value,
|
||||
MainWindowMsg::UpdateGameState => {
|
||||
self.game_state = GameState::get_current_state().await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
use babylonia_terminal_sdk::{game_config::GameConfig, game_manager::GameManager};
|
||||
use log::info;
|
||||
use relm4::{
|
||||
gtk,
|
||||
prelude::{AsyncComponentParts, SimpleAsyncComponent},
|
||||
view, RelmWidgetExt,
|
||||
};
|
||||
|
||||
use libadwaita::{self as adw, prelude::*};
|
||||
|
||||
use super::SetupPageMsg;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ChooseGameDirectoryMsg {
|
||||
ChoosePath,
|
||||
Next,
|
||||
}
|
||||
|
||||
pub struct ChooseGameDirectoryPage {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
#[relm4::component(async, pub)]
|
||||
impl SimpleAsyncComponent for ChooseGameDirectoryPage {
|
||||
type Input = ChooseGameDirectoryMsg;
|
||||
|
||||
type Output = SetupPageMsg;
|
||||
|
||||
type Init = ();
|
||||
|
||||
view! {
|
||||
#[root]
|
||||
gtk::Box {
|
||||
adw::PreferencesPage {
|
||||
set_hexpand: true,
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
gtk::Label {
|
||||
set_label: "Game directory",
|
||||
add_css_class: "title-1"
|
||||
},
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: "Game directory",
|
||||
set_icon_name: Some("folder-symbolic"),
|
||||
set_activatable: true,
|
||||
|
||||
#[watch]
|
||||
set_subtitle: model.path.to_str().unwrap(),
|
||||
|
||||
connect_activated => ChooseGameDirectoryMsg::ChoosePath,
|
||||
},
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_margin_vertical: 48,
|
||||
|
||||
gtk::Button {
|
||||
set_css_classes: &["suggested-action", "pill"],
|
||||
|
||||
set_label: "Next",
|
||||
set_hexpand: false,
|
||||
set_width_request: 200,
|
||||
|
||||
connect_clicked => ChooseGameDirectoryMsg::Next,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn init(
|
||||
init: Self::Init,
|
||||
root: Self::Root,
|
||||
sender: relm4::AsyncComponentSender<Self>,
|
||||
) -> relm4::prelude::AsyncComponentParts<Self> {
|
||||
let path = if let Some(dir) = GameConfig::get_config().await.game_dir {
|
||||
dir
|
||||
} else {
|
||||
GameConfig::get_config_directory().await
|
||||
};
|
||||
|
||||
let model = ChooseGameDirectoryPage { path };
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
AsyncComponentParts { widgets, model }
|
||||
}
|
||||
|
||||
async fn update(&mut self, message: Self::Input, sender: relm4::AsyncComponentSender<Self>) {
|
||||
match message {
|
||||
ChooseGameDirectoryMsg::ChoosePath => {
|
||||
info!("choose path");
|
||||
let result = rfd::AsyncFileDialog::new()
|
||||
.set_directory(self.path.clone())
|
||||
.pick_folder()
|
||||
.await;
|
||||
|
||||
if let Some(result) = result {
|
||||
self.path = result.path().to_path_buf();
|
||||
}
|
||||
|
||||
GameConfig::set_game_dir(Some(self.path.clone()))
|
||||
.await
|
||||
.unwrap(); // TODO: remove unwrap
|
||||
}
|
||||
ChooseGameDirectoryMsg::Next => {
|
||||
let _ = sender.output(SetupPageMsg::GoToDownloadComponentPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,14 @@
|
||||
use std::{convert::identity, usize};
|
||||
|
||||
use babylonia_terminal_sdk::{
|
||||
components::{
|
||||
dxvk_component::{self, DXVKComponent},
|
||||
proton_component::{self, ProtonComponent},
|
||||
},
|
||||
game_state::GameState,
|
||||
utils::github_requester::{GithubRelease, GithubRequester},
|
||||
};
|
||||
use log::{error, info};
|
||||
use relm4::{
|
||||
self,
|
||||
gtk::{self, prelude::*},
|
||||
@ -15,18 +19,44 @@ use relm4::{
|
||||
use adw::prelude::*;
|
||||
use libadwaita as adw;
|
||||
|
||||
use crate::ui::MainWindowMsg;
|
||||
use crate::{manager, ui::MainWindowMsg};
|
||||
|
||||
use super::SetupPageMsg;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DownloadComponentsMsg {
|
||||
Next,
|
||||
UpdateGameState,
|
||||
UpdateProgressBar((u64, u64)), // current and max_progress
|
||||
UpdateProgressBarMsg(String),
|
||||
UpdateDownloadedComponentName(String),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DownloadComponentsPage {
|
||||
//state
|
||||
game_state: GameState,
|
||||
|
||||
// widgets
|
||||
proton_combo: adw::ComboRow,
|
||||
dxvk_combo: adw::ComboRow,
|
||||
|
||||
// values
|
||||
proton_versions: Vec<GithubRelease>,
|
||||
dxvk_versions: Vec<GithubRelease>,
|
||||
selected_proton_version: Option<GithubRelease>,
|
||||
selected_dxvk_version: Option<GithubRelease>,
|
||||
|
||||
//progress_bar
|
||||
progress_bar_reporter: std::sync::Arc<DownloadComponentProgressBarReporter>,
|
||||
progress_bar_message: String,
|
||||
fraction: f64,
|
||||
show_progress_bar: bool,
|
||||
|
||||
// download part
|
||||
is_installing: bool,
|
||||
installation_handler: WorkerController<manager::HandleComponentInstallation>,
|
||||
downloaded_component_name: String,
|
||||
}
|
||||
|
||||
#[relm4::component(async, pub)]
|
||||
@ -35,68 +65,128 @@ impl SimpleAsyncComponent for DownloadComponentsPage {
|
||||
|
||||
type Output = SetupPageMsg;
|
||||
|
||||
type Init = ();
|
||||
type Init = GameState;
|
||||
|
||||
view! {
|
||||
#[root]
|
||||
adw::PreferencesPage {
|
||||
set_hexpand: true,
|
||||
gtk::Box {
|
||||
adw::PreferencesPage {
|
||||
set_hexpand: true,
|
||||
#[watch]
|
||||
set_visible: !model.is_installing,
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
gtk::Label {
|
||||
set_label: "Install components",
|
||||
add_css_class: "title-1"
|
||||
gtk::Label {
|
||||
set_label: "Install components",
|
||||
add_css_class: "title-1"
|
||||
},
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
#[local_ref]
|
||||
proton_combo -> adw::ComboRow {
|
||||
set_title: "proton version",
|
||||
|
||||
set_model: Some(>k::StringList::new(model
|
||||
.proton_versions
|
||||
.iter()
|
||||
.map(|r| r.tag_name.as_str())
|
||||
.collect::<Vec<&str>>()
|
||||
.as_slice())),
|
||||
},
|
||||
|
||||
#[local_ref]
|
||||
dxvk_combo -> adw::ComboRow {
|
||||
set_title: "dxvk version",
|
||||
|
||||
set_model: Some(>k::StringList::new(model
|
||||
.dxvk_versions
|
||||
.iter()
|
||||
.map(|r| r.tag_name.as_str())
|
||||
.collect::<Vec<&str>>()
|
||||
.as_slice())),
|
||||
},
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_margin_vertical: 48,
|
||||
|
||||
gtk::Button {
|
||||
set_css_classes: &["suggested-action", "pill"],
|
||||
|
||||
set_label: "Next",
|
||||
set_hexpand: false,
|
||||
set_width_request: 200,
|
||||
|
||||
connect_clicked => DownloadComponentsMsg::Next,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
adw::PreferencesPage {
|
||||
set_hexpand: true,
|
||||
#[watch]
|
||||
set_visible: model.is_installing,
|
||||
|
||||
adw::ComboRow {
|
||||
set_title: "Proton version",
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
set_model: Some(>k::StringList::new(model
|
||||
.proton_versions
|
||||
.iter()
|
||||
.map(|r| r.tag_name.as_str())
|
||||
.collect::<Vec<&str>>()
|
||||
.as_slice())),
|
||||
gtk::Label {
|
||||
set_label: "Downloading and installing components",
|
||||
add_css_class: "title-1"
|
||||
},
|
||||
},
|
||||
|
||||
adw::ComboRow {
|
||||
set_title: "DXVK version",
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
set_model: Some(>k::StringList::new(model
|
||||
.dxvk_versions
|
||||
.iter()
|
||||
.map(|r| r.tag_name.as_str())
|
||||
.collect::<Vec<&str>>()
|
||||
.as_slice())),
|
||||
adw::ActionRow {
|
||||
#[watch]
|
||||
set_title: match &model.selected_proton_version {
|
||||
Some(release) => &release.tag_name,
|
||||
None => "WTF??!! there's no proton version found ????",
|
||||
},
|
||||
set_subtitle: "Proton version",
|
||||
|
||||
#[watch]
|
||||
set_icon_name: if model.game_state == GameState::ProtonNotInstalled { Some("emblem-ok-symbolic") } else { Some("process-working") },
|
||||
|
||||
add_prefix = >k::Spinner {
|
||||
set_spinning: true,
|
||||
|
||||
#[watch]
|
||||
set_visible: model.game_state == GameState::ProtonNotInstalled,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
gtk::ProgressBar {
|
||||
#[watch]
|
||||
set_fraction: model.fraction,
|
||||
|
||||
#[watch]
|
||||
set_text: Some(&model.progress_bar_message),
|
||||
set_show_text: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_margin_vertical: 48,
|
||||
|
||||
gtk::Button {
|
||||
set_css_classes: &["suggested-action", "pill"],
|
||||
|
||||
set_label: "Next",
|
||||
set_hexpand: false,
|
||||
set_width_request: 200,
|
||||
|
||||
connect_clicked => DownloadComponentsMsg::Next,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn init(
|
||||
init: Self::Init,
|
||||
game_state: Self::Init,
|
||||
root: Self::Root,
|
||||
sender: AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
@ -113,16 +203,129 @@ impl SimpleAsyncComponent for DownloadComponentsPage {
|
||||
.unwrap(); //TODO: remove unwrap()
|
||||
|
||||
let model = DownloadComponentsPage {
|
||||
game_state,
|
||||
|
||||
proton_combo: adw::ComboRow::new(),
|
||||
dxvk_combo: adw::ComboRow::new(),
|
||||
|
||||
proton_versions: proton_releases,
|
||||
dxvk_versions: dxvk_releases,
|
||||
selected_proton_version: None,
|
||||
selected_dxvk_version: None,
|
||||
|
||||
progress_bar_reporter: DownloadComponentProgressBarReporter::create(sender.clone()),
|
||||
progress_bar_message: String::new(),
|
||||
fraction: 0.0,
|
||||
show_progress_bar: false,
|
||||
|
||||
is_installing: false,
|
||||
installation_handler: manager::HandleComponentInstallation::builder()
|
||||
.detach_worker(())
|
||||
.forward(sender.input_sender(), identity),
|
||||
downloaded_component_name: String::new(),
|
||||
};
|
||||
|
||||
let proton_combo = &model.proton_combo;
|
||||
let dxvk_combo = &model.dxvk_combo;
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
AsyncComponentParts { widgets, model }
|
||||
}
|
||||
|
||||
async fn update(&mut self, message: Self::Input, sender: AsyncComponentSender<Self>) -> () {
|
||||
todo!();
|
||||
match message {
|
||||
DownloadComponentsMsg::Next => {
|
||||
if !self.is_installing {
|
||||
self.is_installing = true;
|
||||
|
||||
let proton_index = self.proton_combo.selected() as usize;
|
||||
let dxvk_index = self.dxvk_combo.selected() as usize;
|
||||
|
||||
let proton_release = self.proton_versions[proton_index].clone();
|
||||
let dxvk_release = self.dxvk_versions[dxvk_index].clone();
|
||||
|
||||
self.selected_proton_version = Some(proton_release);
|
||||
self.selected_dxvk_version = Some(dxvk_release);
|
||||
let _ = self.installation_handler.sender().send(
|
||||
manager::HandleComponentInstallationMsg::StartInstallation((
|
||||
proton_index,
|
||||
dxvk_index,
|
||||
self.progress_bar_reporter.clone(),
|
||||
)),
|
||||
);
|
||||
} else {
|
||||
let _ = sender.output(SetupPageMsg::Finish);
|
||||
}
|
||||
}
|
||||
DownloadComponentsMsg::UpdateDownloadedComponentName(name) => {
|
||||
self.downloaded_component_name = name;
|
||||
}
|
||||
DownloadComponentsMsg::UpdateGameState => {
|
||||
self.game_state = GameState::get_current_state().await.unwrap();
|
||||
}
|
||||
DownloadComponentsMsg::UpdateProgressBar((current, max_progress)) => {
|
||||
self.fraction = if current == 0 {
|
||||
0.0
|
||||
} else {
|
||||
current as f64 / max_progress as f64
|
||||
};
|
||||
|
||||
self.progress_bar_message = format!(
|
||||
"Downloading {} : {:.2}%",
|
||||
self.downloaded_component_name,
|
||||
self.fraction * 100.0
|
||||
);
|
||||
}
|
||||
DownloadComponentsMsg::UpdateProgressBarMsg(message) => {
|
||||
self.progress_bar_message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ProgressBarReporterPrivate {
|
||||
max_progress: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DownloadComponentProgressBarReporter {
|
||||
private: std::sync::Mutex<Option<ProgressBarReporterPrivate>>,
|
||||
sender: relm4::AsyncComponentSender<DownloadComponentsPage>,
|
||||
}
|
||||
|
||||
impl DownloadComponentProgressBarReporter {
|
||||
fn create(page: relm4::AsyncComponentSender<DownloadComponentsPage>) -> std::sync::Arc<Self> {
|
||||
std::sync::Arc::new(Self {
|
||||
private: std::sync::Mutex::new(None),
|
||||
sender: page,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl downloader::progress::Reporter for DownloadComponentProgressBarReporter {
|
||||
fn setup(&self, max_progress: Option<u64>, message: &str) {
|
||||
let private = ProgressBarReporterPrivate { max_progress };
|
||||
|
||||
let mut guard = self.private.lock().unwrap();
|
||||
*guard = Some(private);
|
||||
}
|
||||
|
||||
fn progress(&self, current: u64) {
|
||||
if let Some(p) = self.private.lock().unwrap().as_mut() {
|
||||
self.sender.input(DownloadComponentsMsg::UpdateProgressBar((
|
||||
current,
|
||||
p.max_progress.unwrap(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
fn set_message(&self, message: &str) {}
|
||||
|
||||
fn done(&self) {
|
||||
self.sender.input(DownloadComponentsMsg::Next);
|
||||
let mut guard = self.private.lock().unwrap();
|
||||
*guard = None;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::convert::identity;
|
||||
|
||||
use babylonia_terminal_sdk::game_state::GameState;
|
||||
use babylonia_terminal_sdk::{game_config::GameConfig, game_state::GameState};
|
||||
use choose_game_directory::ChooseGameDirectoryPage;
|
||||
use download_components::DownloadComponentsPage;
|
||||
use libadwaita::prelude::{OrientableExt, WidgetExt};
|
||||
use relm4::{
|
||||
@ -14,17 +15,21 @@ use welcome::WelcomePage;
|
||||
|
||||
use crate::ui::MainWindowMsg;
|
||||
|
||||
mod download_components;
|
||||
mod choose_game_directory;
|
||||
pub mod download_components;
|
||||
mod welcome;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SetupPageMsg {
|
||||
UpdateGameState,
|
||||
GoToChooseGameDirectoryPage,
|
||||
GoToDownloadComponentPage,
|
||||
Finish,
|
||||
}
|
||||
|
||||
pub struct SetupPage {
|
||||
game_state: GameState,
|
||||
welcome_page: Controller<welcome::WelcomePage>,
|
||||
choose_game_directory_page: AsyncController<choose_game_directory::ChooseGameDirectoryPage>,
|
||||
download_components_page: AsyncController<download_components::DownloadComponentsPage>,
|
||||
|
||||
carousel: adw::Carousel,
|
||||
@ -42,6 +47,8 @@ impl SimpleAsyncComponent for SetupPage {
|
||||
#[root]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
|
||||
#[local_ref]
|
||||
carousel -> adw::Carousel {
|
||||
@ -50,6 +57,7 @@ impl SimpleAsyncComponent for SetupPage {
|
||||
set_allow_scroll_wheel: false,
|
||||
|
||||
append = model.welcome_page.widget(),
|
||||
append = model.choose_game_directory_page.widget(),
|
||||
append = model.download_components_page.widget(),
|
||||
},
|
||||
|
||||
@ -68,9 +76,12 @@ impl SimpleAsyncComponent for SetupPage {
|
||||
let welcome_page = WelcomePage::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), identity);
|
||||
let download_components_page = DownloadComponentsPage::builder()
|
||||
let choose_game_directory_page = ChooseGameDirectoryPage::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), identity);
|
||||
let download_components_page = DownloadComponentsPage::builder()
|
||||
.launch(game_state.clone())
|
||||
.forward(sender.input_sender(), identity);
|
||||
|
||||
let carousel = adw::Carousel::new();
|
||||
|
||||
@ -78,6 +89,7 @@ impl SimpleAsyncComponent for SetupPage {
|
||||
|
||||
let model = SetupPage {
|
||||
welcome_page,
|
||||
choose_game_directory_page,
|
||||
download_components_page,
|
||||
game_state,
|
||||
carousel: carousel.clone(),
|
||||
@ -88,24 +100,20 @@ impl SimpleAsyncComponent for SetupPage {
|
||||
}
|
||||
|
||||
async fn update(&mut self, message: Self::Input, sender: AsyncComponentSender<Self>) {
|
||||
match message {
|
||||
SetupPageMsg::UpdateGameState => {
|
||||
self.game_state = GameState::get_current_state().await.unwrap()
|
||||
} // TODO: delete this unwrap()
|
||||
}
|
||||
self.game_state = GameState::get_current_state().await.unwrap(); // TODO: delete this unwrap()
|
||||
|
||||
match self.game_state {
|
||||
GameState::ProtonNotInstalled => {
|
||||
match message {
|
||||
SetupPageMsg::GoToChooseGameDirectoryPage => {
|
||||
self.carousel
|
||||
.scroll_to(self.choose_game_directory_page.widget(), true);
|
||||
}
|
||||
SetupPageMsg::GoToDownloadComponentPage => {
|
||||
self.carousel
|
||||
.scroll_to(self.download_components_page.widget(), true);
|
||||
}
|
||||
GameState::DXVKNotInstalled => todo!(),
|
||||
GameState::FontNotInstalled => todo!(),
|
||||
GameState::DependecieNotInstalled => todo!(),
|
||||
GameState::GameNotInstalled => todo!(),
|
||||
GameState::GameNeedUpdate => todo!(),
|
||||
GameState::GameNotPatched => todo!(),
|
||||
GameState::GameInstalled => todo!(),
|
||||
SetupPageMsg::Finish => {
|
||||
sender.output(MainWindowMsg::UpdateGameState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,9 @@ impl SimpleComponent for WelcomePage {
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||
match message {
|
||||
WelcomePageMsg::Next => sender.output(SetupPageMsg::UpdateGameState).unwrap(),
|
||||
WelcomePageMsg::Next => sender
|
||||
.output(SetupPageMsg::GoToChooseGameDirectoryPage)
|
||||
.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,4 +46,11 @@ impl GameState {
|
||||
|
||||
Ok(GameState::GameInstalled)
|
||||
}
|
||||
|
||||
pub fn is_environment_ready(&self) -> bool {
|
||||
self == &GameState::GameNotInstalled
|
||||
|| self == &GameState::GameNeedUpdate
|
||||
|| self == &GameState::GameNotPatched
|
||||
|| self == &GameState::GameInstalled
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user