diff --git a/Cargo.toml b/Cargo.toml index 935c53e..aef7f8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] expect-dialog = "1.0.0" gtk4 = { version = "0.6.6", features = [ + "v4_6", "v4_10" ] } nix = "0.26.2" diff --git a/src/ui/app.rs b/src/ui/app.rs index c981eed..49e628c 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -18,8 +18,8 @@ use crate::file_builders::openvrpaths_vrpath::{ }; use crate::file_utils::setcap_cap_sys_nice_eip; use crate::profile::Profile; -use crate::profiles::valve_index::valve_index_profile; use crate::profiles::system_valve_index::system_valve_index_profile; +use crate::profiles::valve_index::valve_index_profile; use crate::runner::{Runner, RunnerStatus}; use crate::runner_pipeline::RunnerPipeline; use crate::ui::build_window::BuildWindowMsg; @@ -187,7 +187,7 @@ impl SimpleComponent for App { match code { 0 => { self.build_window.sender().emit( - BuildWindowMsg::UpdateBuildStatus(BuildStatus::Done) + BuildWindowMsg::UpdateBuildStatus(BuildStatus::Done), ); self.setcap_confirm_dialog.present(); self.build_window @@ -306,6 +306,9 @@ impl SimpleComponent for App { setcap_cap_sys_nice_eip(format!("{pfx}/bin/monado-service", pfx = profile.prefix)); } Msg::ProfileSelected(prof_name) => { + if prof_name == self.config.selected_profile_name { + return; + } self.config.selected_profile_name = prof_name; save_config(&self.config); } @@ -336,10 +339,7 @@ impl SimpleComponent for App { sender: ComponentSender, ) -> ComponentParts { let config = get_config(); - let profiles = vec![ - valve_index_profile(), - system_valve_index_profile(), - ]; + let profiles = vec![valve_index_profile(), system_valve_index_profile()]; let dependencies_dialog = adw::MessageDialog::builder() .modal(true) .transient_for(root) @@ -462,6 +462,7 @@ impl SimpleComponent for App { .sender() .emit(MainViewMsg::UpdateProfileNames( model.profiles.iter().map(|p| p.clone().name).collect(), + model.config.clone() )); let timer_sender = sender.clone(); diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 91b84ab..d38bf6a 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -1,7 +1,9 @@ use crate::config::Config; use crate::constants::APP_NAME; use crate::file_builders::active_runtime_json::{self, get_current_active_runtime}; -use crate::ui::app::{AboutAction, BuildProfileAction, DebugViewToggleAction, LibsurviveSetupAction}; +use crate::ui::app::{ + AboutAction, BuildProfileAction, DebugViewToggleAction, LibsurviveSetupAction, +}; use expect_dialog::ExpectDialog; use gtk::prelude::*; use relm4::prelude::*; @@ -14,6 +16,8 @@ pub struct MainView { enable_debug_view: bool, profile_names: Vec, steam_launch_options: String, + #[tracker::do_not_track] + profiles_dropdown: Option, } #[derive(Debug)] @@ -21,7 +25,8 @@ pub enum MainViewMsg { StartStopClicked, MonadoActiveChanged(bool), EnableDebugViewChanged(bool), - UpdateProfileNames(Vec), + UpdateProfileNames(Vec, Config), + ProfileSelected(u32), SteamLaunchOptionsChanged(String), CopySteamLaunchOptions, } @@ -86,6 +91,9 @@ impl SimpleComponent for MainView { let names: Vec<_> = model.profile_names.iter().map(String::as_str).collect(); gtk::StringList::new(&names) }), + connect_selected_item_notify[sender] => move |this| { + sender.input(MainViewMsg::ProfileSelected(this.selected())); + }, }, #[track = "model.changed(MainView::enable_debug_view())"] set_show_end_title_buttons: !model.enable_debug_view, @@ -235,14 +243,27 @@ impl SimpleComponent for MainView { MainViewMsg::EnableDebugViewChanged(val) => { self.set_enable_debug_view(val); } - MainViewMsg::UpdateProfileNames(names) => { + MainViewMsg::UpdateProfileNames(names, config) => { self.set_profile_names(names); + self.profiles_dropdown.as_ref().unwrap().clone().set_selected({ + let pos = self.profile_names.iter() + .position(|p| p.clone() == config.selected_profile_name); + match pos { + Some(idx) => idx as u32, + None => 0, + } + }); } MainViewMsg::SteamLaunchOptionsChanged(lo) => self.set_steam_launch_options(lo), MainViewMsg::CopySteamLaunchOptions => gtk::gdk::Display::default() .expect_dialog("Could not find default display") .clipboard() .set_text(self.steam_launch_options.as_str()), + MainViewMsg::ProfileSelected(position) => { + sender.output(MainViewOutMsg::ProfileSelected( + self.profile_names.get(position as usize).unwrap().clone(), + )); + } } } @@ -251,9 +272,10 @@ impl SimpleComponent for MainView { root: &Self::Root, sender: ComponentSender, ) -> ComponentParts { - let model = MainView { + let mut model = MainView { monado_active: false, enable_debug_view: init.config.debug_view_enabled, + profiles_dropdown: None, profile_names: vec![], steam_launch_options: "".into(), tracker: 0, @@ -275,6 +297,8 @@ impl SimpleComponent for MainView { }); } + model.profiles_dropdown = Some(widgets.profiles_dropdown.clone()); + ComponentParts { model, widgets } } }