mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2025-02-03 14:30:50 +03:00
Reworked pages code
- added usage of `clone!` macro - rewritten general and enhanced pages to follow new standard pattern
This commit is contained in:
parent
0524cf80d4
commit
8f65f6f3a8
4 changed files with 278 additions and 136 deletions
src/ui
|
@ -1,6 +1,9 @@
|
|||
use gtk4::{self as gtk, prelude::*};
|
||||
use libadwaita::{self as adw, prelude::*};
|
||||
|
||||
use gtk4::glib;
|
||||
use gtk4::glib::clone;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::Cell;
|
||||
|
||||
|
@ -16,7 +19,7 @@ use crate::lib::game;
|
|||
/// `AppWidgets::try_get` function loads UI file from `.assets/ui/.dist` folder and returns structure with references to its widgets
|
||||
///
|
||||
/// This function does not implement events
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, glib::Downgrade)]
|
||||
pub struct AppWidgets {
|
||||
pub window: adw::ApplicationWindow,
|
||||
pub toast_overlay: adw::ToastOverlay,
|
||||
|
@ -80,7 +83,7 @@ pub enum Actions {
|
|||
/// In this example we store a counter here to know what should we increment or decrement
|
||||
///
|
||||
/// This must implement `Default` trait
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, glib::Downgrade)]
|
||||
pub struct Values;
|
||||
|
||||
/// The main application structure
|
||||
|
@ -94,7 +97,7 @@ pub struct Values;
|
|||
///
|
||||
/// So we have a shared reference to some value that can be changed without mutable reference.
|
||||
/// That's what we need and what we use in `App::update` method
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, glib::Downgrade)]
|
||||
pub struct App {
|
||||
widgets: AppWidgets,
|
||||
values: Rc<Cell<Values>>
|
||||
|
@ -117,25 +120,19 @@ impl App {
|
|||
/// Add default events and values to the widgets
|
||||
fn init_events(self) -> Self {
|
||||
// Open preferences page
|
||||
let self_copy = self.clone();
|
||||
|
||||
self.widgets.open_preferences.connect_clicked(move |_| {
|
||||
self_copy.update(Actions::OpenPreferencesPage);
|
||||
});
|
||||
self.widgets.open_preferences.connect_clicked(clone!(@strong self as this => move |_| {
|
||||
this.update(Actions::OpenPreferencesPage);
|
||||
}));
|
||||
|
||||
// Go back button for preferences page
|
||||
let self_copy = self.clone();
|
||||
|
||||
self.widgets.preferences_stack.preferences_go_back.connect_clicked(move |_| {
|
||||
self_copy.update(Actions::PreferencesGoBack);
|
||||
});
|
||||
self.widgets.preferences_stack.preferences_go_back.connect_clicked(clone!(@strong self as this => move |_| {
|
||||
this.update(Actions::PreferencesGoBack);
|
||||
}));
|
||||
|
||||
// Launch game
|
||||
let self_copy = self.clone();
|
||||
|
||||
self.widgets.launch_game.connect_clicked(move |_| {
|
||||
self_copy.update(Actions::LaunchGame);
|
||||
});
|
||||
self.widgets.launch_game.connect_clicked(clone!(@strong self as this => move |_| {
|
||||
this.update(Actions::LaunchGame);
|
||||
}));
|
||||
|
||||
self
|
||||
}
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
use gtk4::{self as gtk, prelude::*};
|
||||
use libadwaita::{self as adw, prelude::*};
|
||||
|
||||
use gtk4::glib;
|
||||
use gtk4::glib::clone;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::Cell;
|
||||
use std::io::Error;
|
||||
|
||||
use crate::ui::get_object;
|
||||
use crate::lib::config;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Page {
|
||||
/// This structure is used to describe widgets used in application
|
||||
///
|
||||
/// `AppWidgets::try_get` function loads UI file from `.assets/ui/.dist` folder and returns structure with references to its widgets
|
||||
///
|
||||
/// This function does not implement events
|
||||
#[derive(Clone, glib::Downgrade)]
|
||||
pub struct AppWidgets {
|
||||
pub page: adw::PreferencesPage,
|
||||
|
||||
pub sync_combo: adw::ComboRow,
|
||||
|
@ -19,8 +29,8 @@ pub struct Page {
|
|||
pub gamemode_switcher: gtk::Switch
|
||||
}
|
||||
|
||||
impl Page {
|
||||
pub fn new() -> Result<Self, String> {
|
||||
impl AppWidgets {
|
||||
fn try_get() -> Result<Self, String> {
|
||||
let builder = gtk::Builder::from_string(include_str!("../../../assets/ui/.dist/preferences_enhanced.ui"));
|
||||
|
||||
let result = Self {
|
||||
|
@ -35,103 +45,155 @@ impl Page {
|
|||
gamemode_switcher: get_object(&builder, "gamemode_switcher")?
|
||||
};
|
||||
|
||||
// Wine sync selection
|
||||
result.sync_combo.connect_selected_notify(|hud| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
// TODO: show toast
|
||||
config.game.wine.sync = config::WineSync::try_from(hud.selected()).unwrap();
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
config::update(config).unwrap();
|
||||
}
|
||||
});
|
||||
/// This enum is used to describe an action inside of this application
|
||||
///
|
||||
/// It may be helpful if you want to add the same event for several widgets, or call an action inside of another action
|
||||
#[derive(Debug)]
|
||||
pub enum Actions<T> {
|
||||
OptionSelection(fn(crate::lib::config::Config, T) -> crate::lib::config::Config, T)
|
||||
}
|
||||
|
||||
// Wine language selection
|
||||
result.wine_lang.connect_selected_notify(|hud| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
// TODO: show toast
|
||||
config.game.wine.language = config::WineLang::try_from(hud.selected()).unwrap();
|
||||
/// This enum is used to store some of this application data
|
||||
///
|
||||
/// In this example we store a counter here to know what should we increment or decrement
|
||||
///
|
||||
/// This must implement `Default` trait
|
||||
#[derive(Debug, Default, glib::Downgrade)]
|
||||
pub struct Values;
|
||||
|
||||
config::update(config).unwrap();
|
||||
}
|
||||
});
|
||||
/// The main application structure
|
||||
///
|
||||
/// `Default` macro automatically calls `AppWidgets::default`, i.e. loads UI file and reference its widgets
|
||||
///
|
||||
/// `Rc<Cell<Values>>` means this:
|
||||
/// - `Rc` addeds ability to reference the same value from various clones of the structure.
|
||||
/// This will guarantee us that inner `Cell<Values>` is the same for all the `App::clone()` values
|
||||
/// - `Cell` addeds inner mutability to its value, so we can mutate it even without mutable reference.
|
||||
///
|
||||
/// So we have a shared reference to some value that can be changed without mutable reference.
|
||||
/// That's what we need and what we use in `App::update` method
|
||||
#[derive(Clone, glib::Downgrade)]
|
||||
pub struct App {
|
||||
widgets: AppWidgets,
|
||||
values: Rc<Cell<Values>>
|
||||
}
|
||||
|
||||
// HUD selection
|
||||
result.hud_combo.connect_selected_notify(|hud| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
// TODO: show toast
|
||||
config.game.enhancements.hud = config::HUD::try_from(hud.selected()).unwrap();
|
||||
|
||||
config::update(config).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
// FSR strength selection
|
||||
result.fsr_combo.connect_selected_notify(|hud| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
// TODO: show toast
|
||||
|
||||
// Ultra Quality = 5
|
||||
// Quality = 4
|
||||
// Balanced = 3
|
||||
// Performance = 2
|
||||
//
|
||||
// Source: Bottles (https://github.com/bottlesdevs/Bottles/blob/22fa3573a13f4e9b9c429e4cdfe4ca29787a2832/src/ui/details-preferences.ui#L88)
|
||||
config.game.enhancements.fsr.strength = 5 - hud.selected();
|
||||
|
||||
config::update(config).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
// FSR switching
|
||||
result.fsr_switcher.connect_state_notify(|switcher| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
// TODO: show toast
|
||||
config.game.enhancements.fsr.enabled = switcher.state();
|
||||
|
||||
config::update(config).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
// Gamemode switching
|
||||
result.gamemode_switcher.connect_state_notify(|switcher| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
// TODO: show toast
|
||||
config.game.enhancements.gamemode = switcher.state();
|
||||
|
||||
config::update(config).unwrap();
|
||||
}
|
||||
});
|
||||
impl App {
|
||||
/// Create new application
|
||||
pub fn new() -> Result<Self, String> {
|
||||
let result = Self {
|
||||
widgets: AppWidgets::try_get()?,
|
||||
values: Default::default()
|
||||
}.init_events();
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Add default events and values to the widgets
|
||||
fn init_events(self) -> Self {
|
||||
// Wine sync selection
|
||||
self.widgets.sync_combo.connect_selected_notify(clone!(@weak self as this => move |hud| {
|
||||
this.update(Actions::OptionSelection(|mut config, value| {
|
||||
config.game.wine.sync = value; config
|
||||
}, config::WineSync::try_from(hud.selected()).unwrap()));
|
||||
}));
|
||||
|
||||
// Wine language selection
|
||||
self.widgets.wine_lang.connect_selected_notify(clone!(@weak self as this => move |hud| {
|
||||
this.update(Actions::OptionSelection(|mut config, value| {
|
||||
config.game.wine.language = value; config
|
||||
}, config::WineLang::try_from(hud.selected()).unwrap()));
|
||||
}));
|
||||
|
||||
// HUD selection
|
||||
self.widgets.hud_combo.connect_selected_notify(clone!(@weak self as this => move |hud| {
|
||||
this.update(Actions::OptionSelection(|mut config, value| {
|
||||
config.game.enhancements.hud = value; config
|
||||
}, config::HUD::try_from(hud.selected()).unwrap()));
|
||||
}));
|
||||
|
||||
// FSR strength selection
|
||||
//
|
||||
// Ultra Quality = 5
|
||||
// Quality = 4
|
||||
// Balanced = 3
|
||||
// Performance = 2
|
||||
//
|
||||
// Source: Bottles (https://github.com/bottlesdevs/Bottles/blob/22fa3573a13f4e9b9c429e4cdfe4ca29787a2832/src/ui/details-preferences.ui#L88)
|
||||
self.widgets.fsr_combo.connect_selected_notify(clone!(@weak self as this => move |hud| {
|
||||
this.update(Actions::OptionSelection(|mut config, value| {
|
||||
config.game.enhancements.fsr.strength = value; config
|
||||
}, 5 - hud.selected()));
|
||||
}));
|
||||
|
||||
// FSR switching
|
||||
self.widgets.fsr_switcher.connect_state_notify(clone!(@weak self as this => move |switcher| {
|
||||
this.update(Actions::OptionSelection(|mut config, value| {
|
||||
config.game.enhancements.fsr.enabled = value; config
|
||||
}, switcher.state()));
|
||||
}));
|
||||
|
||||
// Gamemode switching
|
||||
self.widgets.gamemode_switcher.connect_state_notify(clone!(@weak self as this => move |switcher| {
|
||||
this.update(Actions::OptionSelection(|mut config, value| {
|
||||
config.game.enhancements.gamemode = value; config
|
||||
}, switcher.state()));
|
||||
}));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Update widgets state by calling some action
|
||||
pub fn update<T>(&self, action: Actions<T>) {
|
||||
let values = self.values.take();
|
||||
|
||||
match action {
|
||||
Actions::OptionSelection(update, value) => {
|
||||
if let Ok(config) = config::get() {
|
||||
// TODO: show toast
|
||||
config::update((update)(config, value)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.values.set(values);
|
||||
}
|
||||
|
||||
pub fn title() -> String {
|
||||
String::from("Enhanced")
|
||||
}
|
||||
|
||||
pub fn get_page(&self) -> adw::PreferencesPage {
|
||||
self.widgets.page.clone()
|
||||
}
|
||||
|
||||
/// This method is being called by the `PreferencesStack::update`
|
||||
pub fn update(&self, status_page: &adw::StatusPage) -> Result<(), Error> {
|
||||
pub fn prepare(&self, status_page: &adw::StatusPage) -> Result<(), Error> {
|
||||
let config = config::get()?;
|
||||
|
||||
status_page.set_description(Some("Loading preferences..."));
|
||||
|
||||
// Update Wine sync
|
||||
self.sync_combo.set_selected(config.game.wine.sync.into());
|
||||
self.widgets.sync_combo.set_selected(config.game.wine.sync.into());
|
||||
|
||||
// Update wine language
|
||||
self.wine_lang.set_selected(config.game.wine.language.into());
|
||||
self.widgets.wine_lang.set_selected(config.game.wine.language.into());
|
||||
|
||||
// Update HUD
|
||||
self.hud_combo.set_selected(config.game.enhancements.hud.into());
|
||||
self.widgets.hud_combo.set_selected(config.game.enhancements.hud.into());
|
||||
|
||||
// FSR strength selection
|
||||
self.fsr_combo.set_selected(5 - config.game.enhancements.fsr.strength);
|
||||
self.widgets.fsr_combo.set_selected(5 - config.game.enhancements.fsr.strength);
|
||||
|
||||
// FSR switching
|
||||
self.fsr_switcher.set_state(config.game.enhancements.fsr.enabled);
|
||||
self.widgets.fsr_switcher.set_state(config.game.enhancements.fsr.enabled);
|
||||
|
||||
// Gamemode switching
|
||||
self.fsr_switcher.set_state(config.game.enhancements.gamemode);
|
||||
self.widgets.fsr_switcher.set_state(config.game.enhancements.gamemode);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
use gtk4::{self as gtk, prelude::*};
|
||||
use libadwaita::{self as adw, prelude::*};
|
||||
|
||||
use gtk4::glib;
|
||||
use gtk4::glib::clone;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::Cell;
|
||||
use std::io::Error;
|
||||
|
||||
use anime_game_core::prelude::*;
|
||||
|
@ -9,8 +14,13 @@ use crate::ui::get_object;
|
|||
use crate::lib::config;
|
||||
use crate::lib::dxvk;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Page {
|
||||
/// This structure is used to describe widgets used in application
|
||||
///
|
||||
/// `AppWidgets::try_get` function loads UI file from `.assets/ui/.dist` folder and returns structure with references to its widgets
|
||||
///
|
||||
/// This function does not implement events
|
||||
#[derive(Clone, glib::Downgrade)]
|
||||
pub struct AppWidgets {
|
||||
pub page: adw::PreferencesPage,
|
||||
|
||||
pub game_version: gtk::Label,
|
||||
|
@ -18,14 +28,16 @@ pub struct Page {
|
|||
|
||||
pub dxvk_recommended_only: gtk::Switch,
|
||||
pub dxvk_vanilla: adw::ExpanderRow,
|
||||
pub dxvk_async: adw::ExpanderRow
|
||||
pub dxvk_async: adw::ExpanderRow,
|
||||
|
||||
pub dxvk_components: Rc<Vec<(adw::ActionRow, dxvk::Version)>>
|
||||
}
|
||||
|
||||
impl Page {
|
||||
pub fn new() -> Result<Self, String> {
|
||||
impl AppWidgets {
|
||||
fn try_get() -> Result<Self, String> {
|
||||
let builder = gtk::Builder::from_string(include_str!("../../../assets/ui/.dist/preferences_general.ui"));
|
||||
|
||||
let result = Self {
|
||||
let mut result = Self {
|
||||
page: get_object(&builder, "general_page")?,
|
||||
|
||||
game_version: get_object(&builder, "game_version")?,
|
||||
|
@ -33,7 +45,9 @@ impl Page {
|
|||
|
||||
dxvk_recommended_only: get_object(&builder, "dxvk_recommended_only")?,
|
||||
dxvk_vanilla: get_object(&builder, "dxvk_vanilla")?,
|
||||
dxvk_async: get_object(&builder, "dxvk_async")?
|
||||
dxvk_async: get_object(&builder, "dxvk_async")?,
|
||||
|
||||
dxvk_components: Default::default()
|
||||
};
|
||||
|
||||
// Update DXVK list
|
||||
|
@ -77,55 +91,122 @@ impl Page {
|
|||
result.dxvk_async.add_row(&row);
|
||||
components.push((row, version));
|
||||
}
|
||||
|
||||
|
||||
result.dxvk_components = Rc::new(components);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
/// This enum is used to describe an action inside of this application
|
||||
///
|
||||
/// It may be helpful if you want to add the same event for several widgets, or call an action inside of another action
|
||||
#[derive(Debug)]
|
||||
pub enum Actions {
|
||||
|
||||
}
|
||||
|
||||
/// This enum is used to store some of this application data
|
||||
///
|
||||
/// In this example we store a counter here to know what should we increment or decrement
|
||||
///
|
||||
/// This must implement `Default` trait
|
||||
#[derive(Debug, Default, glib::Downgrade)]
|
||||
pub struct Values;
|
||||
|
||||
/// The main application structure
|
||||
///
|
||||
/// `Default` macro automatically calls `AppWidgets::default`, i.e. loads UI file and reference its widgets
|
||||
///
|
||||
/// `Rc<Cell<Values>>` means this:
|
||||
/// - `Rc` addeds ability to reference the same value from various clones of the structure.
|
||||
/// This will guarantee us that inner `Cell<Values>` is the same for all the `App::clone()` values
|
||||
/// - `Cell` addeds inner mutability to its value, so we can mutate it even without mutable reference.
|
||||
///
|
||||
/// So we have a shared reference to some value that can be changed without mutable reference.
|
||||
/// That's what we need and what we use in `App::update` method
|
||||
#[derive(Clone, glib::Downgrade)]
|
||||
pub struct App {
|
||||
widgets: AppWidgets,
|
||||
values: Rc<Cell<Values>>
|
||||
}
|
||||
|
||||
impl App {
|
||||
/// Create new application
|
||||
pub fn new() -> Result<Self, String> {
|
||||
let result = Self {
|
||||
widgets: AppWidgets::try_get()?,
|
||||
values: Default::default()
|
||||
}.init_events();
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Add default events and values to the widgets
|
||||
fn init_events(self) -> Self {
|
||||
// Set DXVK recommended only switcher event
|
||||
result.dxvk_recommended_only.connect_state_notify(move |switcher| {
|
||||
for (component, version) in &components {
|
||||
self.widgets.dxvk_recommended_only.connect_state_notify(clone!(@weak self as this => move |switcher| {
|
||||
for (component, version) in &*this.widgets.dxvk_components {
|
||||
component.set_visible(if switcher.state() {
|
||||
version.recommended
|
||||
} else {
|
||||
true
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
Ok(result)
|
||||
self
|
||||
}
|
||||
|
||||
/// Update widgets state by calling some action
|
||||
pub fn update(&self, action: Actions) {
|
||||
/*let values = self.values.take();
|
||||
|
||||
match action {
|
||||
|
||||
}
|
||||
|
||||
self.values.set(values);*/
|
||||
}
|
||||
|
||||
pub fn title() -> String {
|
||||
String::from("General")
|
||||
}
|
||||
|
||||
pub fn get_page(&self) -> adw::PreferencesPage {
|
||||
self.widgets.page.clone()
|
||||
}
|
||||
|
||||
/// This method is being called by the `PreferencesStack::update`
|
||||
pub fn update(&self, status_page: &adw::StatusPage) -> Result<(), Error> {
|
||||
pub fn prepare(&self, status_page: &adw::StatusPage) -> 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);
|
||||
self.widgets.game_version.set_tooltip_text(None);
|
||||
self.widgets.patch_version.set_tooltip_text(None);
|
||||
|
||||
// Update game version
|
||||
status_page.set_description(Some("Updating game info..."));
|
||||
|
||||
match game.try_get_diff()? {
|
||||
VersionDiff::Latest(version) => {
|
||||
self.game_version.set_label(&version.to_string());
|
||||
self.widgets.game_version.set_label(&version.to_string());
|
||||
},
|
||||
VersionDiff::Diff { current, latest, .. } => {
|
||||
self.game_version.set_label(¤t.to_string());
|
||||
self.game_version.set_css_classes(&["warning"]);
|
||||
self.widgets.game_version.set_label(¤t.to_string());
|
||||
self.widgets.game_version.set_css_classes(&["warning"]);
|
||||
|
||||
self.game_version.set_tooltip_text(Some(&format!("Game update available: {} -> {}", current, latest)));
|
||||
self.widgets.game_version.set_tooltip_text(Some(&format!("Game update available: {} -> {}", current, latest)));
|
||||
},
|
||||
VersionDiff::Outdated { current, latest } => {
|
||||
self.game_version.set_label(¤t.to_string());
|
||||
self.game_version.set_css_classes(&["error"]);
|
||||
self.widgets.game_version.set_label(¤t.to_string());
|
||||
self.widgets.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)));
|
||||
self.widgets.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(&[]);
|
||||
self.widgets.game_version.set_label("not installed");
|
||||
self.widgets.game_version.set_css_classes(&[]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,32 +215,32 @@ impl Page {
|
|||
|
||||
match Patch::try_fetch(config.patch.servers)? {
|
||||
Patch::NotAvailable => {
|
||||
self.patch_version.set_label("not available");
|
||||
self.patch_version.set_css_classes(&["error"]);
|
||||
self.widgets.patch_version.set_label("not available");
|
||||
self.widgets.patch_version.set_css_classes(&["error"]);
|
||||
|
||||
self.patch_version.set_tooltip_text(Some("Patch is not available"));
|
||||
self.widgets.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.widgets.patch_version.set_label("outdated");
|
||||
self.widgets.patch_version.set_css_classes(&["warning"]);
|
||||
|
||||
self.patch_version.set_tooltip_text(Some(&format!("Patch is outdated ({} -> {})", current, latest)));
|
||||
self.widgets.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.widgets.patch_version.set_label("preparation");
|
||||
self.widgets.patch_version.set_css_classes(&["warning"]);
|
||||
|
||||
self.patch_version.set_tooltip_text(Some("Patch is in preparation state and will be available later"));
|
||||
self.widgets.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.widgets.patch_version.set_label(&version.to_string());
|
||||
self.widgets.patch_version.set_css_classes(&["warning"]);
|
||||
|
||||
self.patch_version.set_tooltip_text(Some("Patch is in testing phase"));
|
||||
self.widgets.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"]);
|
||||
self.widgets.patch_version.set_label(&version.to_string());
|
||||
self.widgets.patch_version.set_css_classes(&["success"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use gtk4::{self as gtk, prelude::*};
|
||||
use libadwaita::{self as adw, prelude::*};
|
||||
|
||||
use gtk4::glib;
|
||||
|
||||
use std::io::Error;
|
||||
|
||||
use crate::ui::get_object;
|
||||
|
@ -10,11 +12,11 @@ mod general_page;
|
|||
mod enhanced_page;
|
||||
|
||||
pub mod pages {
|
||||
pub use super::general_page::Page as GeneralPage;
|
||||
pub use super::enhanced_page::Page as EnhancedPage;
|
||||
pub use super::general_page::App as GeneralPage;
|
||||
pub use super::enhanced_page::App as EnhancedPage;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, glib::Downgrade)]
|
||||
pub struct PreferencesStack {
|
||||
pub window: adw::ApplicationWindow,
|
||||
pub toast_overlay: adw::ToastOverlay,
|
||||
|
@ -51,8 +53,8 @@ impl PreferencesStack {
|
|||
enhanced_page: pages::EnhancedPage::new()?
|
||||
};
|
||||
|
||||
result.stack.add_titled(&result.general_page.page, None, &pages::GeneralPage::title());
|
||||
result.stack.add_titled(&result.enhanced_page.page, None, &pages::EnhancedPage::title());
|
||||
result.stack.add_titled(&result.general_page.get_page(), None, &pages::GeneralPage::title());
|
||||
result.stack.add_titled(&result.enhanced_page.get_page(), None, &pages::EnhancedPage::title());
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -67,8 +69,8 @@ impl PreferencesStack {
|
|||
self.status_page.set_description(None);
|
||||
self.flap.set_visible(false);
|
||||
|
||||
self.general_page.update(&self.status_page)?;
|
||||
self.enhanced_page.update(&self.status_page)?;
|
||||
self.general_page.prepare(&self.status_page)?;
|
||||
self.enhanced_page.prepare(&self.status_page)?;
|
||||
|
||||
self.status_page.set_visible(false);
|
||||
self.flap.set_visible(true);
|
||||
|
|
Loading…
Add table
Reference in a new issue