From c765448e4389966a8c8d8c6739921f24a1efe0ab Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Wed, 3 May 2023 21:06:24 +0200 Subject: [PATCH] feat: some initial work on adding "game" settings section Is not yet even started, just had to commit changed to checkout to the main branch --- src/ui/about.rs | 4 +- src/ui/main/mod.rs | 4 +- src/ui/preferences/environment.rs | 18 +-- src/ui/preferences/game.rs | 202 ++++++++++++++++++++++++++++++ src/ui/preferences/main.rs | 7 ++ src/ui/preferences/mod.rs | 1 + 6 files changed, 223 insertions(+), 13 deletions(-) create mode 100644 src/ui/preferences/game.rs diff --git a/src/ui/about.rs b/src/ui/about.rs index 9e0105e..2f4f723 100644 --- a/src/ui/about.rs +++ b/src/ui/about.rs @@ -51,10 +51,12 @@ impl SimpleComponent for AboutDialog { ]), add_credit_section: (Some("An Anime Team"), &[ + "Nikita Podvirnyy https://github.com/krypt0nn", "@Marie https://github.com/Mar0xy", "@lane https://github.com/laurinneff", "@jiro-too https://github.com/jiro-too", - "@cybik https://github.com/cybik" + "@cybik https://github.com/cybik", + "@mkrsym1 https://github.com/mkrsym1" ]), set_artists: &[ diff --git a/src/ui/main/mod.rs b/src/ui/main/mod.rs index 383395e..a77e487 100644 --- a/src/ui/main/mod.rs +++ b/src/ui/main/mod.rs @@ -717,10 +717,8 @@ impl SimpleComponent for App { description: if changes.is_empty() { None } else { - let max_len = changes.iter().map(|line| line.len()).max().unwrap_or(80); - Some(changes.into_iter() - .map(|line| format!("- {line}{}", " ".repeat(max_len - line.len()))) + .map(|line| format!("- {line}")) .collect::>() .join("\n")) } diff --git a/src/ui/preferences/environment.rs b/src/ui/preferences/environment.rs index 6cdf707..e34e895 100644 --- a/src/ui/preferences/environment.rs +++ b/src/ui/preferences/environment.rs @@ -16,10 +16,10 @@ struct Variable { #[relm4::factory(async)] impl AsyncFactoryComponent for Variable { type Init = (String, String); - type Input = EnvironmentMsg; - type Output = EnvironmentMsg; + type Input = EnvironmentAppMsg; + type Output = EnvironmentAppMsg; type CommandOutput = (); - type ParentInput = EnvironmentMsg; + type ParentInput = EnvironmentAppMsg; type ParentWidget = adw::PreferencesGroup; view! { @@ -33,7 +33,7 @@ impl AsyncFactoryComponent for Variable { set_valign: gtk::Align::Center, connect_clicked[sender, index] => move |_| { - sender.input(EnvironmentMsg::Remove(index.clone())); + sender.input(EnvironmentAppMsg::Remove(index.clone())); } } } @@ -67,7 +67,7 @@ pub struct EnvironmentApp { } #[derive(Debug, Clone)] -pub enum EnvironmentMsg { +pub enum EnvironmentAppMsg { Add, Remove(DynamicIndex) } @@ -75,7 +75,7 @@ pub enum EnvironmentMsg { #[relm4::component(async, pub)] impl SimpleAsyncComponent for EnvironmentApp { type Init = (); - type Input = EnvironmentMsg; + type Input = EnvironmentAppMsg; type Output = (); view! { @@ -127,7 +127,7 @@ impl SimpleAsyncComponent for EnvironmentApp { set_margin_top: 8, set_halign: gtk::Align::Start, - connect_clicked => EnvironmentMsg::Add + connect_clicked => EnvironmentAppMsg::Add } }, @@ -166,7 +166,7 @@ impl SimpleAsyncComponent for EnvironmentApp { async fn update(&mut self, msg: Self::Input, _sender: AsyncComponentSender) { match msg { - EnvironmentMsg::Add => { + EnvironmentAppMsg::Add => { if let Ok(mut config) = Config::get() { let name = self.name_entry.text().trim().to_string(); let value = self.value_entry.text().trim().to_string(); @@ -184,7 +184,7 @@ impl SimpleAsyncComponent for EnvironmentApp { } } - EnvironmentMsg::Remove(index) => { + EnvironmentAppMsg::Remove(index) => { if let Ok(mut config) = Config::get() { if let Some(var) = self.variables.guard().get(index.current_index()) { config.game.environment.remove(&var.key); diff --git a/src/ui/preferences/game.rs b/src/ui/preferences/game.rs new file mode 100644 index 0000000..4188410 --- /dev/null +++ b/src/ui/preferences/game.rs @@ -0,0 +1,202 @@ +use relm4::prelude::*; +use relm4::component::*; +use relm4::factory::*; + +use adw::prelude::*; + +use crate::i18n::tr; +use crate::*; + +#[derive(Debug)] +struct GameSession { + title: String, + description: Option, + id: usize +} + +#[relm4::factory(async)] +impl AsyncFactoryComponent for GameSession { + type Init = GameSession; + type Input = GameAppMsg; + type Output = GameAppMsg; + type CommandOutput = (); + type ParentInput = GameAppMsg; + type ParentWidget = adw::PreferencesGroup; + + view! { + root = adw::ActionRow { + set_title: &self.title, + + set_subtitle: match &self.description { + Some(description) => description.as_str(), + None => "" + }, + + add_suffix = >k::Button { + set_icon_name: "user-trash-symbolic", + add_css_class: "flat", + set_valign: gtk::Align::Center, + + connect_clicked[sender, index] => move |_| { + sender.input(GameAppMsg::Remove(index.clone())); + } + } + } + } + + fn output_to_parent_input(output: Self::Output) -> Option { + Some(output) + } + + async fn init_model( + init: Self::Init, + _index: &DynamicIndex, + _sender: AsyncFactorySender, + ) -> Self { + init + } + + async fn update(&mut self, msg: Self::Input, sender: AsyncFactorySender) { + sender.output(msg); + } +} + +pub struct GameApp { + variables: AsyncFactoryVecDeque, + + name_entry: adw::EntryRow, + value_entry: adw::EntryRow +} + +#[derive(Debug, Clone)] +pub enum GameAppMsg { + Add, + Remove(DynamicIndex) +} + +#[relm4::component(async, pub)] +impl SimpleAsyncComponent for GameApp { + type Init = (); + type Input = GameAppMsg; + type Output = (); + + view! { + adw::PreferencesPage { + set_title: &tr("environment"), + set_icon_name: Some("document-properties-symbolic"), + + add = &adw::PreferencesGroup { + set_title: &tr("game-command"), + set_description: Some(&tr("game-command-description")), + + adw::EntryRow { + set_title: "%command%", + set_text: CONFIG.game.command.as_ref().unwrap_or(&String::new()).trim(), + + connect_changed => |entry| { + if let Ok(mut config) = Config::get() { + let command = entry.text().trim().to_string(); + + config.game.command = if command.is_empty() { + None + } else { + Some(command) + }; + + Config::update(config); + } + } + } + }, + + add = &adw::PreferencesGroup { + set_title: &tr("new-variable"), + + #[local_ref] + name_entry -> adw::EntryRow { + set_title: &tr("name") + }, + + #[local_ref] + value_entry -> adw::EntryRow { + set_title: &tr("value") + }, + + gtk::Button { + set_label: &tr("add"), + add_css_class: "pill", + + set_margin_top: 8, + set_halign: gtk::Align::Start, + + connect_clicked => GameAppMsg::Add + } + }, + + #[local_ref] + add = variables -> adw::PreferencesGroup {} + } + } + + async fn init( + _init: Self::Init, + root: Self::Root, + sender: AsyncComponentSender, + ) -> AsyncComponentParts { + tracing::info!("Initializing environment settings"); + + let mut model = Self { + variables: AsyncFactoryVecDeque::new(adw::PreferencesGroup::new(), sender.input_sender()), + + name_entry: adw::EntryRow::new(), + value_entry: adw::EntryRow::new() + }; + + /*for (name, value) in &CONFIG.game.environment { + model.variables.guard().push_back(); + }*/ + + let variables = model.variables.widget(); + + let name_entry = &model.name_entry; + let value_entry = &model.value_entry; + + let widgets = view_output!(); + + AsyncComponentParts { model, widgets } + } + + async fn update(&mut self, msg: Self::Input, _sender: AsyncComponentSender) { + match msg { + GameAppMsg::Add => { + if let Ok(mut config) = Config::get() { + let name = self.name_entry.text().trim().to_string(); + let value = self.value_entry.text().trim().to_string(); + + if !name.is_empty() && !value.is_empty() { + self.name_entry.set_text(""); + self.value_entry.set_text(""); + + config.game.environment.insert(name.clone(), value.clone()); + + Config::update(config); + + // self.variables.guard().push_back((name, value)); + } + } + } + + GameAppMsg::Remove(index) => { + if let Ok(mut config) = Config::get() { + if let Some(var) = self.variables.guard().get(index.current_index()) { + // config.game.environment.remove(&var.key); + + Config::update(config); + } + + self.variables.guard().remove(index.current_index()); + } + } + } + } +} diff --git a/src/ui/preferences/main.rs b/src/ui/preferences/main.rs index 7665219..213e6b4 100644 --- a/src/ui/preferences/main.rs +++ b/src/ui/preferences/main.rs @@ -15,6 +15,7 @@ use crate::i18n::tr; use super::general::*; use super::enhancements::*; +use super::game::*; use super::sandbox::*; use super::environment::*; @@ -23,6 +24,7 @@ pub static mut PREFERENCES_WINDOW: Option = None; pub struct PreferencesApp { general: AsyncController, enhancements: AsyncController, + game: AsyncController, sandbox: AsyncController, environment: AsyncController } @@ -69,6 +71,7 @@ impl SimpleAsyncComponent for PreferencesApp { add = model.general.widget(), add = model.enhancements.widget(), + add = model.game.widget(), add = model.sandbox.widget(), add = model.environment.widget(), @@ -101,6 +104,10 @@ impl SimpleAsyncComponent for PreferencesApp { .launch(()) .detach(), + game: GameApp::builder() + .launch(()) + .detach(), + sandbox: SandboxApp::builder() .launch(()) .forward(sender.input_sender(), std::convert::identity), diff --git a/src/ui/preferences/mod.rs b/src/ui/preferences/mod.rs index c066563..3ab11c5 100644 --- a/src/ui/preferences/mod.rs +++ b/src/ui/preferences/mod.rs @@ -1,6 +1,7 @@ pub mod main; pub mod general; pub mod enhancements; +pub mod game; pub mod sandbox; pub mod environment; pub mod gamescope;