general settings: added test launcher style switcher
- classic style loads its background from "config's_tmp_path/background" so from "launcher folder/background" by default - icons will be changed in some future
This commit is contained in:
parent
949a0f37e9
commit
5870316724
8 changed files with 228 additions and 18 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 8a32066c07cd471fe2a33ecfa778edffb8796f19
|
Subproject commit a62aeef9cd9caa0e147fddcf05f4c412c942b736
|
12
assets/images/classic.svg
Normal file
12
assets/images/classic.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="90" height="60" viewBox="0 0 90 60" xml:space="preserve">
|
||||||
|
<defs>
|
||||||
|
</defs>
|
||||||
|
<g transform="matrix(1.58 0 0 0.39 62.57 51.18)" id="HUkKwqLQOm47Zs9qaMmTc" >
|
||||||
|
<path style="stroke: rgb(242,144,30); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(53,132,228); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(0, 0)" d="M -8.25689 0.69081 C -8.25689 -4.25086 -7.26151 -8.256879999999999 -6.03365 -8.256879999999999 L 6.03365 -8.256879999999999 L 6.03365 -8.256879999999999 C 7.2615099999999995 -8.256879999999999 8.25689 -4.2508599999999985 8.25689 0.6908100000000008 L 8.25689 0.6908100000000008 L 8.25689 0.6908100000000008 C 8.25689 4.869440000000001 7.41521 8.256890000000002 6.37694 8.256890000000002 L -6.37694 8.256890000000002 L -6.37694 8.256890000000002 C -7.41521 8.256890000000002 -8.25689 4.869440000000003 -8.25689 0.6908100000000017 z" stroke-linecap="round" />
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(0.39 0 0 0.39 79.98 51.2)" id="3u3imhfuSenPkHHelxk_U" >
|
||||||
|
<path style="stroke: rgb(242,144,30); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(230,230,230); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(0, 0)" d="M -8.25689 0.72542 C -8.25689 -4.2353700000000005 -4.26412 -8.25688 0.6612200000000001 -8.25688 L 0.6612200000000001 -8.25688 L 0.6612200000000001 -8.25688 C 4.85619 -8.25688 8.25689 -4.8317000000000005 8.25689 -0.6065400000000007 L 8.25689 0.6615399999999994 L 8.25689 0.6615399999999994 C 8.25689 4.85633 4.88064 8.256889999999999 0.7158300000000004 8.256889999999999 L -0.7792399999999995 8.256889999999999 L -0.7792399999999995 8.256889999999999 C -4.90902 8.256889999999999 -8.256879999999999 4.8849399999999985 -8.256879999999999 0.7254299999999985 z" stroke-linecap="round" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
12
assets/images/modern.svg
Normal file
12
assets/images/modern.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="90" height="60" viewBox="0 0 90 60" xml:space="preserve">
|
||||||
|
<defs>
|
||||||
|
</defs>
|
||||||
|
<g transform="matrix(1.58 0 0 0.39 41.18 39.34)" id="HUkKwqLQOm47Zs9qaMmTc" >
|
||||||
|
<path style="stroke: rgb(242,144,30); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(53,132,228); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(0, 0)" d="M -8.25689 0.69081 C -8.25689 -4.25086 -7.26151 -8.256879999999999 -6.03365 -8.256879999999999 L 6.03365 -8.256879999999999 L 6.03365 -8.256879999999999 C 7.2615099999999995 -8.256879999999999 8.25689 -4.2508599999999985 8.25689 0.6908100000000008 L 8.25689 0.6908100000000008 L 8.25689 0.6908100000000008 C 8.25689 4.869440000000001 7.41521 8.256890000000002 6.37694 8.256890000000002 L -6.37694 8.256890000000002 L -6.37694 8.256890000000002 C -7.41521 8.256890000000002 -8.25689 4.869440000000003 -8.25689 0.6908100000000017 z" stroke-linecap="round" />
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(0.39 0 0 0.39 58.59 39.36)" id="3u3imhfuSenPkHHelxk_U" >
|
||||||
|
<path style="stroke: rgb(242,144,30); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(230,230,230); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(0, 0)" d="M -8.25689 0.72542 C -8.25689 -4.2353700000000005 -4.26412 -8.25688 0.6612200000000001 -8.25688 L 0.6612200000000001 -8.25688 L 0.6612200000000001 -8.25688 C 4.85619 -8.25688 8.25689 -4.8317000000000005 8.25689 -0.6065400000000007 L 8.25689 0.6615399999999994 L 8.25689 0.6615399999999994 C 8.25689 4.85633 4.88064 8.256889999999999 0.7158300000000004 8.256889999999999 L -0.7792399999999995 8.256889999999999 L -0.7792399999999995 8.256889999999999 C -4.90902 8.256889999999999 -8.256879999999999 4.8849399999999985 -8.256879999999999 0.7254299999999985 z" stroke-linecap="round" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -3,4 +3,10 @@
|
||||||
<gresource prefix="/org/app">
|
<gresource prefix="/org/app">
|
||||||
<file compressed="true">images/icon.png</file>
|
<file compressed="true">images/icon.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
|
<gresource prefix="/org/app">
|
||||||
|
<file compressed="true">images/modern.svg</file>
|
||||||
|
</gresource>
|
||||||
|
<gresource prefix="/org/app">
|
||||||
|
<file compressed="true">images/classic.svg</file>
|
||||||
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
20
src/main.rs
20
src/main.rs
|
@ -6,6 +6,8 @@ use anime_launcher_sdk::anime_game_core::genshin::prelude::*;
|
||||||
|
|
||||||
use tracing_subscriber::prelude::*;
|
use tracing_subscriber::prelude::*;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub mod i18n;
|
pub mod i18n;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
|
@ -110,14 +112,22 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the app
|
// Create the app
|
||||||
let app = RelmApp::new("moe.launcher.an-anime-game-launcher");
|
let app = RelmApp::new(APP_ID);
|
||||||
|
|
||||||
// Set global css
|
// Set global css
|
||||||
relm4::set_global_css("
|
relm4::set_global_css(&format!("
|
||||||
progressbar > text {
|
progressbar > text {{
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}}
|
||||||
");
|
|
||||||
|
window.classic-style {{
|
||||||
|
background: url(\"file://{}/background\");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
}}
|
||||||
|
",
|
||||||
|
CONFIG.launcher.temp.as_ref().unwrap_or(&PathBuf::from("/tmp")).to_string_lossy()
|
||||||
|
));
|
||||||
|
|
||||||
// Run the app
|
// Run the app
|
||||||
app.run::<ui::main::App>(());
|
app.run::<ui::main::App>(());
|
||||||
|
|
102
src/ui/main.rs
102
src/ui/main.rs
|
@ -8,6 +8,9 @@ use relm4::{
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
|
|
||||||
|
use anime_launcher_sdk::config::launcher::LauncherStyle;
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
use crate::i18n::tr;
|
use crate::i18n::tr;
|
||||||
|
|
||||||
use super::preferences::main::App as PreferencesApp;
|
use super::preferences::main::App as PreferencesApp;
|
||||||
|
@ -25,13 +28,16 @@ static mut PREFERENCES_WINDOW: Option<AsyncController<PreferencesApp>> = None;
|
||||||
static mut ABOUT_DIALOG: Option<Controller<AboutDialog>> = None;
|
static mut ABOUT_DIALOG: Option<Controller<AboutDialog>> = None;
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
loading: Option<Option<String>>
|
loading: Option<Option<String>>,
|
||||||
|
style: LauncherStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AppMsg {
|
pub enum AppMsg {
|
||||||
|
PerformAction,
|
||||||
OpenPreferences,
|
OpenPreferences,
|
||||||
ClosePreferences
|
ClosePreferences,
|
||||||
|
UpdateLauncherStyle(LauncherStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
|
@ -57,12 +63,47 @@ impl SimpleComponent for App {
|
||||||
view! {
|
view! {
|
||||||
main_window = adw::Window {
|
main_window = adw::Window {
|
||||||
set_title: Some("An Anime Game Launcher"),
|
set_title: Some("An Anime Game Launcher"),
|
||||||
set_default_size: (900, 600),
|
|
||||||
|
#[watch]
|
||||||
|
set_default_size: (
|
||||||
|
match model.style {
|
||||||
|
LauncherStyle::Modern => 900,
|
||||||
|
LauncherStyle::Classic => 1094 // (w = 1280 / 730 * h, where 1280x730 is default background picture resolution)
|
||||||
|
},
|
||||||
|
match model.style {
|
||||||
|
LauncherStyle::Modern => 600,
|
||||||
|
LauncherStyle::Classic => 624
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
add_css_class: match model.style {
|
||||||
|
LauncherStyle::Modern => "",
|
||||||
|
LauncherStyle::Classic => "classic-style"
|
||||||
|
},
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
remove_css_class: match model.style {
|
||||||
|
LauncherStyle::Modern => "classic-style",
|
||||||
|
LauncherStyle::Classic => ""
|
||||||
|
},
|
||||||
|
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
|
||||||
adw::HeaderBar {
|
adw::HeaderBar {
|
||||||
|
#[watch]
|
||||||
|
add_css_class: match model.style {
|
||||||
|
LauncherStyle::Modern => "",
|
||||||
|
LauncherStyle::Classic => "flat"
|
||||||
|
},
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
remove_css_class: match model.style {
|
||||||
|
LauncherStyle::Modern => "flat",
|
||||||
|
LauncherStyle::Classic => ""
|
||||||
|
},
|
||||||
|
|
||||||
pack_end = >k::MenuButton {
|
pack_end = >k::MenuButton {
|
||||||
set_icon_name: "open-menu-symbolic",
|
set_icon_name: "open-menu-symbolic",
|
||||||
set_menu_model: Some(&main_menu)
|
set_menu_model: Some(&main_menu)
|
||||||
|
@ -89,6 +130,9 @@ impl SimpleComponent for App {
|
||||||
set_visible: model.loading.is_none(),
|
set_visible: model.loading.is_none(),
|
||||||
|
|
||||||
add = &adw::PreferencesGroup {
|
add = &adw::PreferencesGroup {
|
||||||
|
#[watch]
|
||||||
|
set_visible: model.style == LauncherStyle::Modern,
|
||||||
|
|
||||||
gtk::Image {
|
gtk::Image {
|
||||||
set_resource: Some("/org/app/images/icon.png"),
|
set_resource: Some("/org/app/images/icon.png"),
|
||||||
set_vexpand: true,
|
set_vexpand: true,
|
||||||
|
@ -103,11 +147,33 @@ impl SimpleComponent for App {
|
||||||
},
|
},
|
||||||
|
|
||||||
add = &adw::PreferencesGroup {
|
add = &adw::PreferencesGroup {
|
||||||
set_valign: gtk::Align::Center,
|
#[watch]
|
||||||
|
set_valign: match model.style {
|
||||||
|
LauncherStyle::Modern => gtk::Align::Center,
|
||||||
|
LauncherStyle::Classic => gtk::Align::End
|
||||||
|
},
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_width_request: match model.style {
|
||||||
|
LauncherStyle::Modern => -1,
|
||||||
|
LauncherStyle::Classic => 800
|
||||||
|
},
|
||||||
|
|
||||||
set_vexpand: true,
|
set_vexpand: true,
|
||||||
|
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_halign: gtk::Align::Center,
|
#[watch]
|
||||||
|
set_halign: match model.style {
|
||||||
|
LauncherStyle::Modern => gtk::Align::Center,
|
||||||
|
LauncherStyle::Classic => gtk::Align::End
|
||||||
|
},
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_height_request: match model.style {
|
||||||
|
LauncherStyle::Modern => -1,
|
||||||
|
LauncherStyle::Classic => 40
|
||||||
|
},
|
||||||
|
|
||||||
set_margin_top: 64,
|
set_margin_top: 64,
|
||||||
set_spacing: 8,
|
set_spacing: 8,
|
||||||
|
|
||||||
|
@ -117,12 +183,16 @@ impl SimpleComponent for App {
|
||||||
set_width_request: 200,
|
set_width_request: 200,
|
||||||
add_css_class: "suggested-action",
|
add_css_class: "suggested-action",
|
||||||
|
|
||||||
connect_clicked => |_| {
|
connect_clicked => AppMsg::PerformAction
|
||||||
anime_launcher_sdk::game::run().expect("Failed to run the game");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
|
#[watch]
|
||||||
|
set_width_request: match model.style {
|
||||||
|
LauncherStyle::Modern => -1,
|
||||||
|
LauncherStyle::Classic => 40
|
||||||
|
},
|
||||||
|
|
||||||
set_icon_name: "emblem-system-symbolic",
|
set_icon_name: "emblem-system-symbolic",
|
||||||
|
|
||||||
connect_clicked => AppMsg::OpenPreferences
|
connect_clicked => AppMsg::OpenPreferences
|
||||||
|
@ -137,12 +207,13 @@ impl SimpleComponent for App {
|
||||||
fn init(
|
fn init(
|
||||||
_counter: Self::Init,
|
_counter: Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
_sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
tracing::info!("Initializing main window");
|
tracing::info!("Initializing main window");
|
||||||
|
|
||||||
let model = App {
|
let model = App {
|
||||||
loading: None
|
loading: None,
|
||||||
|
style: CONFIG.launcher.style
|
||||||
};
|
};
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
@ -156,7 +227,7 @@ impl SimpleComponent for App {
|
||||||
unsafe {
|
unsafe {
|
||||||
PREFERENCES_WINDOW = Some(PreferencesApp::builder()
|
PREFERENCES_WINDOW = Some(PreferencesApp::builder()
|
||||||
.launch(widgets.main_window.clone().into())
|
.launch(widgets.main_window.clone().into())
|
||||||
.detach());
|
.forward(sender.input_sender(), std::convert::identity));
|
||||||
|
|
||||||
ABOUT_DIALOG = Some(AboutDialog::builder()
|
ABOUT_DIALOG = Some(AboutDialog::builder()
|
||||||
.transient_for(widgets.main_window.clone())
|
.transient_for(widgets.main_window.clone())
|
||||||
|
@ -166,6 +237,7 @@ impl SimpleComponent for App {
|
||||||
|
|
||||||
let group = RelmActionGroup::<WindowActionGroup>::new();
|
let group = RelmActionGroup::<WindowActionGroup>::new();
|
||||||
|
|
||||||
|
// TODO
|
||||||
group.add_action::<LauncherFolder>(&RelmAction::new_stateless(move |_| {
|
group.add_action::<LauncherFolder>(&RelmAction::new_stateless(move |_| {
|
||||||
println!("Open launcher folder!");
|
println!("Open launcher folder!");
|
||||||
}));
|
}));
|
||||||
|
@ -197,6 +269,10 @@ impl SimpleComponent for App {
|
||||||
tracing::debug!("Called main window event: {:?}", msg);
|
tracing::debug!("Called main window event: {:?}", msg);
|
||||||
|
|
||||||
match msg {
|
match msg {
|
||||||
|
AppMsg::PerformAction => {
|
||||||
|
anime_launcher_sdk::game::run().expect("Failed to run the game");
|
||||||
|
}
|
||||||
|
|
||||||
AppMsg::OpenPreferences => unsafe {
|
AppMsg::OpenPreferences => unsafe {
|
||||||
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widget().show();
|
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widget().show();
|
||||||
}
|
}
|
||||||
|
@ -204,6 +280,10 @@ impl SimpleComponent for App {
|
||||||
AppMsg::ClosePreferences => unsafe {
|
AppMsg::ClosePreferences => unsafe {
|
||||||
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widget().hide();
|
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widget().hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppMsg::UpdateLauncherStyle(style) => {
|
||||||
|
self.style = style;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,61 @@ impl WidgetTemplate for General {
|
||||||
set_title: &tr("general"),
|
set_title: &tr("general"),
|
||||||
set_icon_name: Some("applications-system-symbolic"),
|
set_icon_name: Some("applications-system-symbolic"),
|
||||||
|
|
||||||
|
add = &adw::PreferencesGroup {
|
||||||
|
set_title: "Appearance",
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_halign: gtk::Align::Center,
|
||||||
|
|
||||||
|
set_spacing: 32,
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
|
||||||
|
#[name(modern_style_button)]
|
||||||
|
gtk::ToggleButton {
|
||||||
|
add_css_class: "card",
|
||||||
|
|
||||||
|
set_width_request: 180,
|
||||||
|
set_height_request: 120,
|
||||||
|
|
||||||
|
gtk::Image {
|
||||||
|
set_from_resource: Some("/org/app/images/modern.svg")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_text: "Modern",
|
||||||
|
|
||||||
|
set_margin_top: 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
|
||||||
|
#[name(classic_style_button)]
|
||||||
|
gtk::ToggleButton {
|
||||||
|
add_css_class: "card",
|
||||||
|
|
||||||
|
set_width_request: 180,
|
||||||
|
set_height_request: 120,
|
||||||
|
|
||||||
|
gtk::Image {
|
||||||
|
set_from_resource: Some("/org/app/images/classic.svg")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_text: "Classic",
|
||||||
|
|
||||||
|
set_margin_top: 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
add = &adw::PreferencesGroup {
|
add = &adw::PreferencesGroup {
|
||||||
set_title: &tr("general"),
|
set_title: &tr("general"),
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use gtk::prelude::*;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
|
|
||||||
use anime_launcher_sdk::config;
|
use anime_launcher_sdk::config;
|
||||||
|
use anime_launcher_sdk::config::launcher::LauncherStyle;
|
||||||
use anime_launcher_sdk::components::*;
|
use anime_launcher_sdk::components::*;
|
||||||
use anime_launcher_sdk::wincompatlib::prelude::*;
|
use anime_launcher_sdk::wincompatlib::prelude::*;
|
||||||
|
|
||||||
|
@ -20,6 +21,8 @@ pub struct App {
|
||||||
wine_components: AsyncController<ComponentsList>,
|
wine_components: AsyncController<ComponentsList>,
|
||||||
dxvk_components: AsyncController<ComponentsList>,
|
dxvk_components: AsyncController<ComponentsList>,
|
||||||
|
|
||||||
|
style: LauncherStyle,
|
||||||
|
|
||||||
downloaded_wine_versions: Vec<wine::Version>,
|
downloaded_wine_versions: Vec<wine::Version>,
|
||||||
downloaded_dxvk_versions: Vec<dxvk::Version>,
|
downloaded_dxvk_versions: Vec<dxvk::Version>,
|
||||||
|
|
||||||
|
@ -36,6 +39,7 @@ pub enum AppMsg {
|
||||||
title: String,
|
title: String,
|
||||||
description: Option<String>
|
description: Option<String>
|
||||||
},
|
},
|
||||||
|
UpdateLauncherStyle(LauncherStyle),
|
||||||
WineRecommendedOnly(bool),
|
WineRecommendedOnly(bool),
|
||||||
DxvkRecommendedOnly(bool),
|
DxvkRecommendedOnly(bool),
|
||||||
UpdateDownloadedWine,
|
UpdateDownloadedWine,
|
||||||
|
@ -50,7 +54,7 @@ pub enum AppMsg {
|
||||||
impl SimpleAsyncComponent for App {
|
impl SimpleAsyncComponent for App {
|
||||||
type Init = gtk::Window;
|
type Init = gtk::Window;
|
||||||
type Input = AppMsg;
|
type Input = AppMsg;
|
||||||
type Output = ();
|
type Output = crate::ui::main::AppMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
preferences_window = adw::PreferencesWindow {
|
preferences_window = adw::PreferencesWindow {
|
||||||
|
@ -65,6 +69,22 @@ impl SimpleAsyncComponent for App {
|
||||||
// but I have no idea how to do it other way
|
// but I have no idea how to do it other way
|
||||||
// There're no graphical glitches so don't care
|
// There're no graphical glitches so don't care
|
||||||
|
|
||||||
|
#[template_child]
|
||||||
|
modern_style_button {
|
||||||
|
#[watch]
|
||||||
|
set_active: model.style == LauncherStyle::Modern,
|
||||||
|
|
||||||
|
connect_clicked => AppMsg::UpdateLauncherStyle(LauncherStyle::Modern)
|
||||||
|
},
|
||||||
|
|
||||||
|
#[template_child]
|
||||||
|
classic_style_button {
|
||||||
|
#[watch]
|
||||||
|
set_active: model.style == LauncherStyle::Classic,
|
||||||
|
|
||||||
|
connect_clicked => AppMsg::UpdateLauncherStyle(LauncherStyle::Classic)
|
||||||
|
},
|
||||||
|
|
||||||
#[template_child]
|
#[template_child]
|
||||||
wine_versions {
|
wine_versions {
|
||||||
add = model.wine_components.widget(),
|
add = model.wine_components.widget(),
|
||||||
|
@ -191,6 +211,8 @@ impl SimpleAsyncComponent for App {
|
||||||
})
|
})
|
||||||
.forward(sender.input_sender(), std::convert::identity),
|
.forward(sender.input_sender(), std::convert::identity),
|
||||||
|
|
||||||
|
style: CONFIG.launcher.style,
|
||||||
|
|
||||||
downloaded_wine_versions: vec![],
|
downloaded_wine_versions: vec![],
|
||||||
downloaded_dxvk_versions: vec![],
|
downloaded_dxvk_versions: vec![],
|
||||||
|
|
||||||
|
@ -253,6 +275,19 @@ impl SimpleAsyncComponent for App {
|
||||||
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().add_toast(&toast);
|
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().add_toast(&toast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_must_use)]
|
||||||
|
AppMsg::UpdateLauncherStyle(style) => {
|
||||||
|
if let Ok(mut config) = config::get() {
|
||||||
|
config.launcher.style = style;
|
||||||
|
|
||||||
|
config::update(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.style = style;
|
||||||
|
|
||||||
|
sender.output(Self::Output::UpdateLauncherStyle(style));
|
||||||
|
}
|
||||||
|
|
||||||
AppMsg::WineRecommendedOnly(state) => {
|
AppMsg::WineRecommendedOnly(state) => {
|
||||||
// todo
|
// todo
|
||||||
self.wine_components.sender().send(components::list::AppMsg::ShowRecommendedOnly(state)).unwrap();
|
self.wine_components.sender().send(components::list::AppMsg::ShowRecommendedOnly(state)).unwrap();
|
||||||
|
|
Loading…
Reference in a new issue