mirror of
https://github.com/ALEZ-DEV/Babylonia-terminal.git
synced 2025-12-16 17:38:51 +00:00
can now download the game
This commit is contained in:
parent
1a6bb86cb5
commit
80836f32ec
@ -14,10 +14,13 @@ use wincompatlib::prelude::Proton;
|
|||||||
|
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
self,
|
self,
|
||||||
pages::steps::{
|
pages::{
|
||||||
|
self,
|
||||||
|
steps::{
|
||||||
self,
|
self,
|
||||||
download_components::{self, DownloadComponentsPageWidgets},
|
download_components::{self, DownloadComponentsPageWidgets},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static PROTON: OnceCell<Proton> = OnceCell::const_new();
|
static PROTON: OnceCell<Proton> = OnceCell::const_new();
|
||||||
@ -51,6 +54,7 @@ pub enum HandleGameProcessMsg {
|
|||||||
RunGame,
|
RunGame,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct HandleGameProcess;
|
pub struct HandleGameProcess;
|
||||||
|
|
||||||
impl Worker for HandleGameProcess {
|
impl Worker for HandleGameProcess {
|
||||||
@ -81,6 +85,114 @@ impl Worker for HandleGameProcess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum HandleGameInstallationMsg {
|
||||||
|
StartInstallation(Arc<pages::game::ProgressBarGameInstallationReporter>),
|
||||||
|
StartPatch,
|
||||||
|
StartUpdate(Arc<pages::game::ProgressBarGameInstallationReporter>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct HandleGameInstallation;
|
||||||
|
|
||||||
|
impl Worker for HandleGameInstallation {
|
||||||
|
type Init = ();
|
||||||
|
|
||||||
|
type Input = HandleGameInstallationMsg;
|
||||||
|
|
||||||
|
type Output = pages::game::GamePageMsg;
|
||||||
|
|
||||||
|
fn init(init: Self::Init, sender: relm4::ComponentSender<Self>) -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender<Self>) {
|
||||||
|
match message {
|
||||||
|
HandleGameInstallationMsg::StartInstallation(progress_bar) => {
|
||||||
|
tokio::runtime::Builder::new_current_thread()
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(async {
|
||||||
|
sender.output(pages::game::GamePageMsg::SetIsDownloading(true));
|
||||||
|
|
||||||
|
let game_dir = if let Some(dir) = GameConfig::get_config().await.game_dir {
|
||||||
|
dir
|
||||||
|
} else {
|
||||||
|
GameConfig::get_config_directory().await
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(error) = GameManager::install_game(game_dir, progress_bar).await
|
||||||
|
{
|
||||||
|
sender.output(pages::game::GamePageMsg::ShowError(format!(
|
||||||
|
"Error while downloading the game : {}",
|
||||||
|
error
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.output(pages::game::GamePageMsg::SetIsDownloading(false));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
HandleGameInstallationMsg::StartPatch => {
|
||||||
|
tokio::runtime::Builder::new_current_thread()
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(async {
|
||||||
|
sender.output(pages::game::GamePageMsg::SetIsPatching(true));
|
||||||
|
|
||||||
|
let game_dir = if let Some(dir) = GameConfig::get_config().await.game_dir {
|
||||||
|
dir
|
||||||
|
} else {
|
||||||
|
GameConfig::get_config_directory().await
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(error) = GameManager::patch_game(game_dir).await {
|
||||||
|
sender.output(pages::game::GamePageMsg::ShowError(format!(
|
||||||
|
"Error while patching the game : {}",
|
||||||
|
error
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.output(pages::game::GamePageMsg::SetIsPatching(false));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
HandleGameInstallationMsg::StartUpdate(progress_bar) => {
|
||||||
|
tokio::runtime::Builder::new_current_thread()
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(async {
|
||||||
|
sender.output(pages::game::GamePageMsg::SetIsDownloading(true));
|
||||||
|
|
||||||
|
if let Err(error) = GameManager::update_game().await {
|
||||||
|
sender.output(pages::game::GamePageMsg::ShowError(format!(
|
||||||
|
"Error while updating the game : {}",
|
||||||
|
error
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
let game_dir = if let Some(dir) = GameConfig::get_config().await.game_dir {
|
||||||
|
dir
|
||||||
|
} else {
|
||||||
|
GameConfig::get_config_directory().await
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(error) = GameManager::install_game(game_dir, progress_bar).await
|
||||||
|
{
|
||||||
|
sender.output(pages::game::GamePageMsg::ShowError(format!(
|
||||||
|
"Error while updating the game : {}",
|
||||||
|
error
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.output(pages::game::GamePageMsg::SetIsDownloading(true));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum HandleComponentInstallationMsg {
|
pub enum HandleComponentInstallationMsg {
|
||||||
StartInstallation(
|
StartInstallation(
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::{manager, IS_DEVEL};
|
|||||||
use babylonia_terminal_sdk::game_state::GameState;
|
use babylonia_terminal_sdk::game_state::GameState;
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use pages::game::GamePageMsg;
|
||||||
use relm4::{
|
use relm4::{
|
||||||
self,
|
self,
|
||||||
component::AsyncConnector,
|
component::AsyncConnector,
|
||||||
@ -51,7 +52,7 @@ impl MainWindow {
|
|||||||
.forward(sender.input_sender(), identity);
|
.forward(sender.input_sender(), identity);
|
||||||
|
|
||||||
let game_page = pages::game::GamePage::builder()
|
let game_page = pages::game::GamePage::builder()
|
||||||
.launch(())
|
.launch(game_state.clone())
|
||||||
.forward(sender.input_sender(), identity);
|
.forward(sender.input_sender(), identity);
|
||||||
|
|
||||||
let about_page = pages::about::AboutPage::builder().launch(());
|
let about_page = pages::about::AboutPage::builder().launch(());
|
||||||
@ -269,6 +270,7 @@ impl SimpleAsyncComponent for MainWindow {
|
|||||||
}
|
}
|
||||||
MainWindowMsg::UpdateGameState => {
|
MainWindowMsg::UpdateGameState => {
|
||||||
self.game_state = GameState::get_current_state().await.unwrap();
|
self.game_state = GameState::get_current_state().await.unwrap();
|
||||||
|
self.game_page.sender().send(GamePageMsg::UpdateGameState);
|
||||||
debug!(
|
debug!(
|
||||||
"is_environment_ready : {}",
|
"is_environment_ready : {}",
|
||||||
self.game_state.is_environment_ready()
|
self.game_state.is_environment_ready()
|
||||||
|
|||||||
@ -1,29 +1,46 @@
|
|||||||
use std::convert::identity;
|
use std::{convert::identity, fmt::format};
|
||||||
|
|
||||||
use libadwaita::prelude::PreferencesPageExt;
|
use arboard::Clipboard;
|
||||||
|
use babylonia_terminal_sdk::game_state::GameState;
|
||||||
|
use libadwaita::prelude::{MessageDialogExt, PreferencesPageExt};
|
||||||
|
use log::error;
|
||||||
use relm4::{
|
use relm4::{
|
||||||
adw,
|
adw,
|
||||||
gtk::{
|
gtk::{
|
||||||
self,
|
self,
|
||||||
prelude::{ButtonExt, WidgetExt},
|
prelude::{ButtonExt, GtkWindowExt, OrientableExt, WidgetExt},
|
||||||
},
|
},
|
||||||
prelude::{AsyncComponentParts, SimpleAsyncComponent},
|
prelude::{AsyncComponentParts, SimpleAsyncComponent},
|
||||||
Component, RelmWidgetExt, WorkerController,
|
Component, RelmWidgetExt, WorkerController,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{manager, ui::MainWindowMsg, APP_RESOURCE_PATH};
|
use crate::{
|
||||||
|
manager,
|
||||||
//use adw::prelude::*;
|
ui::{MainWindowMsg, MAIN_WINDOW},
|
||||||
//use libadwaita as adw;
|
APP_RESOURCE_PATH,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct GamePage {
|
pub struct GamePage {
|
||||||
|
game_state: GameState,
|
||||||
game_handler: WorkerController<manager::HandleGameProcess>,
|
game_handler: WorkerController<manager::HandleGameProcess>,
|
||||||
|
installation_handler: WorkerController<manager::HandleGameInstallation>,
|
||||||
is_game_running: bool,
|
is_game_running: bool,
|
||||||
|
is_downloading: bool,
|
||||||
|
is_patching: bool,
|
||||||
|
progress_bar_reporter: std::sync::Arc<ProgressBarGameInstallationReporter>,
|
||||||
|
progress_bar_message: String,
|
||||||
|
fraction: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum GamePageMsg {
|
pub enum GamePageMsg {
|
||||||
SetIsGameRunning(bool),
|
SetIsGameRunning(bool),
|
||||||
|
SetIsDownloading(bool),
|
||||||
|
SetIsPatching(bool),
|
||||||
|
UpdateGameState,
|
||||||
|
UpdateProgressBar(u64, u64),
|
||||||
|
ShowError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub, async)]
|
#[relm4::component(pub, async)]
|
||||||
@ -32,9 +49,12 @@ impl SimpleAsyncComponent for GamePage {
|
|||||||
|
|
||||||
type Output = MainWindowMsg;
|
type Output = MainWindowMsg;
|
||||||
|
|
||||||
type Init = ();
|
type Init = GameState;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
|
||||||
adw::PreferencesPage {
|
adw::PreferencesPage {
|
||||||
add = &adw::PreferencesGroup {
|
add = &adw::PreferencesGroup {
|
||||||
gtk::Picture {
|
gtk::Picture {
|
||||||
@ -53,6 +73,38 @@ impl SimpleAsyncComponent for GamePage {
|
|||||||
add = &adw::PreferencesGroup {
|
add = &adw::PreferencesGroup {
|
||||||
set_margin_vertical: 48,
|
set_margin_vertical: 48,
|
||||||
|
|
||||||
|
gtk::Button {
|
||||||
|
set_css_classes: &["suggested-action", "pill"],
|
||||||
|
|
||||||
|
set_label: "Install",
|
||||||
|
set_hexpand: false,
|
||||||
|
set_width_request: 200,
|
||||||
|
|
||||||
|
set_visible: model.game_state == GameState::GameNotInstalled,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_sensitive: !model.is_downloading,
|
||||||
|
connect_clicked[sender = model.installation_handler.sender().clone(), progress_bar = model.progress_bar_reporter.clone()] => move |_| {
|
||||||
|
sender.send(manager::HandleGameInstallationMsg::StartInstallation(progress_bar.clone())).unwrap();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Button {
|
||||||
|
set_css_classes: &["suggested-action", "pill"],
|
||||||
|
|
||||||
|
set_label: "Apply patch",
|
||||||
|
set_hexpand: false,
|
||||||
|
set_width_request: 200,
|
||||||
|
|
||||||
|
set_visible: model.game_state == GameState::GameNotPatched,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_sensitive: !model.is_patching,
|
||||||
|
connect_clicked[sender = model.installation_handler.sender().clone()] => move |_| {
|
||||||
|
sender.send(manager::HandleGameInstallationMsg::StartPatch).unwrap();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
set_css_classes: &["suggested-action", "pill"],
|
set_css_classes: &["suggested-action", "pill"],
|
||||||
|
|
||||||
@ -60,26 +112,123 @@ impl SimpleAsyncComponent for GamePage {
|
|||||||
set_hexpand: false,
|
set_hexpand: false,
|
||||||
set_width_request: 200,
|
set_width_request: 200,
|
||||||
|
|
||||||
|
set_visible: model.game_state == GameState::GameInstalled,
|
||||||
|
|
||||||
#[watch]
|
#[watch]
|
||||||
set_sensitive: !model.is_game_running,
|
set_sensitive: !model.is_game_running,
|
||||||
connect_clicked[sender = model.game_handler.sender().clone()] => move |_| {
|
connect_clicked[sender = model.game_handler.sender().clone()] => move |_| {
|
||||||
sender.send(manager::HandleGameProcessMsg::RunGame).unwrap();
|
sender.send(manager::HandleGameProcessMsg::RunGame).unwrap();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
gtk::Button {
|
||||||
|
set_css_classes: &["suggested-action", "pill"],
|
||||||
|
|
||||||
|
set_label: "Update",
|
||||||
|
set_hexpand: false,
|
||||||
|
set_width_request: 200,
|
||||||
|
|
||||||
|
set_visible: model.game_state == GameState::GameNeedUpdate,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_sensitive: !model.is_downloading,
|
||||||
|
connect_clicked[sender = model.installation_handler.sender().clone(), progress_bar = model.progress_bar_reporter.clone()] => move |_| {
|
||||||
|
sender.send(manager::HandleGameInstallationMsg::StartUpdate(progress_bar.clone())).unwrap();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::ProgressBar {
|
||||||
|
#[watch]
|
||||||
|
set_fraction: model.fraction,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_visible: (model.game_state == GameState::GameNotInstalled || model.game_state == GameState::GameNeedUpdate) && model.is_downloading && model.fraction != 0.0,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_text: Some(&model.progress_bar_message),
|
||||||
|
set_show_text: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_visible: (model.game_state == GameState::GameNotInstalled || model.game_state == GameState::GameNeedUpdate) && model.is_downloading && model.fraction == 0.0,
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_halign: gtk::Align::Center,
|
||||||
|
set_margin_bottom: 24,
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_label: "Checking game files",
|
||||||
|
|
||||||
|
add_css_class: "title-2",
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Spinner {
|
||||||
|
set_spinning: true,
|
||||||
|
set_margin_start: 24,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_label: "This can take some time, please wait...",
|
||||||
|
|
||||||
|
add_css_class: "title-4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_visible: model.game_state == GameState::GameNotPatched && model.is_patching,
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_label: "Patching game",
|
||||||
|
|
||||||
|
add_css_class: "title-2",
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Spinner {
|
||||||
|
set_spinning: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_label: "This can take some time, please wait...",
|
||||||
|
|
||||||
|
add_css_class: "title-4",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn init(
|
async fn init(
|
||||||
_: Self::Init,
|
game_state: Self::Init,
|
||||||
root: Self::Root,
|
root: Self::Root,
|
||||||
sender: relm4::AsyncComponentSender<Self>,
|
sender: relm4::AsyncComponentSender<Self>,
|
||||||
) -> relm4::prelude::AsyncComponentParts<Self> {
|
) -> relm4::prelude::AsyncComponentParts<Self> {
|
||||||
let model = GamePage {
|
let model = GamePage {
|
||||||
|
progress_bar_reporter: ProgressBarGameInstallationReporter::create(sender.clone()),
|
||||||
|
game_state,
|
||||||
game_handler: manager::HandleGameProcess::builder()
|
game_handler: manager::HandleGameProcess::builder()
|
||||||
.detach_worker(())
|
.detach_worker(())
|
||||||
.forward(sender.input_sender(), identity),
|
.forward(sender.input_sender(), identity),
|
||||||
|
installation_handler: manager::HandleGameInstallation::builder()
|
||||||
|
.detach_worker(())
|
||||||
|
.forward(sender.input_sender(), identity),
|
||||||
is_game_running: false,
|
is_game_running: false,
|
||||||
|
is_downloading: false,
|
||||||
|
is_patching: false,
|
||||||
|
fraction: 0.0,
|
||||||
|
progress_bar_message: String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
@ -90,6 +239,96 @@ impl SimpleAsyncComponent for GamePage {
|
|||||||
async fn update(&mut self, message: Self::Input, _: relm4::AsyncComponentSender<Self>) -> () {
|
async fn update(&mut self, message: Self::Input, _: relm4::AsyncComponentSender<Self>) -> () {
|
||||||
match message {
|
match message {
|
||||||
GamePageMsg::SetIsGameRunning(value) => self.is_game_running = value,
|
GamePageMsg::SetIsGameRunning(value) => self.is_game_running = value,
|
||||||
|
GamePageMsg::SetIsDownloading(value) => self.is_downloading = value,
|
||||||
|
GamePageMsg::SetIsPatching(value) => self.is_patching = value,
|
||||||
|
GamePageMsg::UpdateGameState => {
|
||||||
|
self.game_state = GameState::get_current_state().await.unwrap()
|
||||||
|
} //TODO: remove unwrap()
|
||||||
|
GamePageMsg::UpdateProgressBar(current, max_progress) => {
|
||||||
|
self.fraction = if current == 0 {
|
||||||
|
0.0
|
||||||
|
} else {
|
||||||
|
current as f64 / max_progress as f64
|
||||||
|
};
|
||||||
|
|
||||||
|
//1024^3 = 1073741824
|
||||||
|
let current_gb = current as f64 / 1073741824 as f64;
|
||||||
|
let max_gb = max_progress as f64 / 1073741824 as f64;
|
||||||
|
|
||||||
|
self.progress_bar_message = format!(
|
||||||
|
"Downloading : {:.2}% ({:.2} / {:.2}GiB)",
|
||||||
|
self.fraction * 100 as f64,
|
||||||
|
current_gb,
|
||||||
|
max_gb,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
GamePageMsg::ShowError(message) => {
|
||||||
|
let dialog = unsafe {
|
||||||
|
adw::MessageDialog::new(
|
||||||
|
MAIN_WINDOW.as_ref(),
|
||||||
|
Some("Something went wrong"),
|
||||||
|
Some(&message),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.add_response("close", "Close");
|
||||||
|
dialog.add_response("copy", "Copy");
|
||||||
|
|
||||||
|
dialog.set_response_appearance("copy", adw::ResponseAppearance::Suggested);
|
||||||
|
|
||||||
|
dialog.connect_response(Some("copy"), move |_, _| {
|
||||||
|
if let Err(err) = Clipboard::new().unwrap().set_text(&message.clone()) {
|
||||||
|
error!("Failed to copy the error to the clipboard : {}", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.present();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ProgressBarGameInstallationReporterPrivate {
|
||||||
|
max_progress: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ProgressBarGameInstallationReporter {
|
||||||
|
private: std::sync::Mutex<Option<ProgressBarGameInstallationReporterPrivate>>,
|
||||||
|
sender: relm4::AsyncComponentSender<GamePage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProgressBarGameInstallationReporter {
|
||||||
|
fn create(page: relm4::AsyncComponentSender<GamePage>) -> std::sync::Arc<Self> {
|
||||||
|
std::sync::Arc::new(Self {
|
||||||
|
private: std::sync::Mutex::new(None),
|
||||||
|
sender: page,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl downloader::progress::Reporter for ProgressBarGameInstallationReporter {
|
||||||
|
fn setup(&self, max_progress: Option<u64>, message: &str) {
|
||||||
|
let private = ProgressBarGameInstallationReporterPrivate { 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(GamePageMsg::UpdateProgressBar(
|
||||||
|
current,
|
||||||
|
p.max_progress.unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_message(&self, _: &str) {}
|
||||||
|
|
||||||
|
fn done(&self) {
|
||||||
|
let mut guard = self.private.lock().unwrap();
|
||||||
|
*guard = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -251,7 +251,7 @@ impl SimpleAsyncComponent for DownloadComponentsPage {
|
|||||||
},
|
},
|
||||||
|
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_valign: gtk::Align::Center,
|
set_halign: gtk::Align::Center,
|
||||||
set_orientation: gtk::Orientation::Horizontal,
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
|
||||||
gtk::Label {
|
gtk::Label {
|
||||||
@ -265,6 +265,7 @@ impl SimpleAsyncComponent for DownloadComponentsPage {
|
|||||||
|
|
||||||
gtk::Spinner {
|
gtk::Spinner {
|
||||||
set_spinning: true,
|
set_spinning: true,
|
||||||
|
set_margin_start: 24,
|
||||||
|
|
||||||
#[watch]
|
#[watch]
|
||||||
set_visible: model.currently_installing == CurrentlyInstalling::Fonts || model.currently_installing == CurrentlyInstalling::Denpendecies,
|
set_visible: model.currently_installing == CurrentlyInstalling::Fonts || model.currently_installing == CurrentlyInstalling::Denpendecies,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user