diff --git a/scripts/_clone_or_pull.sh b/scripts/_clone_or_pull.sh index c2aedee..d0e4ff2 100755 --- a/scripts/_clone_or_pull.sh +++ b/scripts/_clone_or_pull.sh @@ -6,9 +6,10 @@ set -ev GIT_URL=$1 REPO_DIR=$2 +DO_PULL=$3 _usage() { - echo "Usage: $0 GIT_URL REPO_DIR" + echo "Usage: $0 GIT_URL REPO_DIR [DO_PULL]" exit 1 } @@ -20,12 +21,19 @@ if [[ -z $GIT_URL ]]; then _usage fi +if [[ -z $DO_PULL ]]; then + DO_PULL=1 +fi + if [[ -d "$REPO_DIR" ]]; then if [[ ! -d "$REPO_DIR/.git" ]]; then - echo "Error: $REPO_DIR exists but is not a git repository" - exit 1 + rmdir "$REPO_DIR" + git clone "$GIT_URL" "$REPO_DIR" --recurse-submodules + else + if [[ "$DO_PULL" -eq 1 ]]; then + git -C "$REPO_DIR" pull + fi fi - git -C "$REPO_DIR" pull else git clone "$GIT_URL" "$REPO_DIR" --recurse-submodules fi diff --git a/scripts/build_basalt.sh b/scripts/build_basalt.sh index f8496d2..239d228 100644 --- a/scripts/build_basalt.sh +++ b/scripts/build_basalt.sh @@ -9,13 +9,22 @@ exit 1 # # PREFIX=$2 # -# if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]]; then -# echo "Usage: $0 REPO_DIR PREFIX" +# DO_PULL=$3 +# +# REPO_URL=$4 +# +# if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]] || [[ -z $DO_PULL ]]; then +# echo "Usage: $0 REPO_DIR PREFIX DO_PULL [REPO_URL]" # exit 1 # fi # -# "$(dirname -- "$0")/_clone_or_pull.sh" "https://github.com/cntools/libsurvive" "$REPO_DIR" +# if [[ -z $REPO_URL ]]; then +# REPO_URL="https://gitlab.freedesktop.org/mateosss/basalt" +# fi +# +# "$(dirname -- "$0")/_clone_or_pull.sh" "$REPO_URL" "$REPO_DIR" "$DO_PULL" # # cd "$REPO_DIR" +# rm -rf build # mkdir -p build # cd build diff --git a/scripts/build_libsurvive.sh b/scripts/build_libsurvive.sh index 92c11f1..7cf9c4f 100755 --- a/scripts/build_libsurvive.sh +++ b/scripts/build_libsurvive.sh @@ -6,14 +6,23 @@ REPO_DIR=$1 PREFIX=$2 -if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]]; then - echo "Usage: $0 REPO_DIR PREFIX" +DO_PULL=$3 + +REPO_URL=$4 + +if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]] || [[ -z $DO_PULL ]]; then + echo "Usage: $0 REPO_DIR PREFIX DO_PULL [REPO_URL]" exit 1 fi -"$(dirname -- "$0")/_clone_or_pull.sh" "https://github.com/cntools/libsurvive" "$REPO_DIR" +if [[ -z $REPO_URL ]]; then + REPO_URL="https://github.com/cntools/libsurvive" +fi + +"$(dirname -- "$0")/_clone_or_pull.sh" "$REPO_URL" "$REPO_DIR" "$DO_PULL" cd "$REPO_DIR" +rm -rf build mkdir -p build cd build cmake -DCMAKE_BUILD_TYPE=Release \ @@ -23,6 +32,5 @@ cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ -DCMAKE_INSTALL_LIBDIR="${PREFIX}/lib" \ .. -make clean make -j$(nproc) make install diff --git a/scripts/build_monado.sh b/scripts/build_monado.sh index ba7045d..c6aefdb 100755 --- a/scripts/build_monado.sh +++ b/scripts/build_monado.sh @@ -8,14 +8,23 @@ REPO_DIR=$1 PREFIX=$2 -if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]]; then - echo "Usage: $0 REPO_DIR PREFIX" +DO_PULL=$3 + +REPO_URL=$4 + +if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]] || [[ -z $DO_PULL ]]; then + echo "Usage: $0 REPO_DIR PREFIX DO_PULL [REPO_URL]" exit 1 fi -"$(dirname -- "$0")/_clone_or_pull.sh" "https://gitlab.freedesktop.org/monado/monado" "$REPO_DIR" +if [[ -z $REPO_URL ]]; then + REPO_URL="https://gitlab.freedesktop.org/monado/monado" +fi + +"$(dirname -- "$0")/_clone_or_pull.sh" "$REPO_URL" "$REPO_DIR" "$DO_PULL" cd "$REPO_DIR" +rm -rf build mkdir -p build cd build export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig" @@ -25,6 +34,5 @@ cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_FLAGS="-Wl,-rpath ${PREFIX}/lib" \ -DCMAKE_CXX_FLAGS="-Wl,-rpath ${PREFIX}/lib" \ .. -make clean make -j$(nproc) make install diff --git a/scripts/build_opencomposite.sh b/scripts/build_opencomposite.sh index 9199dd6..7833cfa 100755 --- a/scripts/build_opencomposite.sh +++ b/scripts/build_opencomposite.sh @@ -6,9 +6,23 @@ set -ev REPO_DIR=$1 -"$(dirname -- "$0")/_clone_or_pull.sh" "https://gitlab.com/znixian/OpenOVR.git" "$REPO_DIR" +DO_PULL=$2 + +REPO_URL=$3 + +if [[ -z $REPO_DIR ]] || [[ -z $DO_PULL ]]; then + echo "Usage: $0 REPO_DIR DO_PULL [REPO_URL]" + exit 1 +fi + +if [[ -z $REPO_URL ]]; then + REPO_URL="https://gitlab.com/znixian/OpenOVR.git" +fi + +"$(dirname -- "$0")/_clone_or_pull.sh" "$REPO_URL" "$REPO_DIR" "$DO_PULL" cd "$REPO_DIR" +rm -rf build mkdir -p build cd build cmake -DCMAKE_BUILD_TYPE=Release .. diff --git a/scripts/build_wivrn.sh b/scripts/build_wivrn.sh index 563fddc..2b3fc66 100755 --- a/scripts/build_wivrn.sh +++ b/scripts/build_wivrn.sh @@ -8,14 +8,23 @@ REPO_DIR=$1 PREFIX=$2 -if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]]; then - echo "Usage: $0 REPO_DIR PREFIX" +DO_PULL=$3 + +REPO_URL=$4 + +if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]] || [[ -z $DO_PULL ]]; then + echo "Usage: $0 REPO_DIR PREFIX DO_PULL [REPO_URL]" exit 1 fi -"$(dirname -- "$0")/_clone_or_pull.sh" "https://github.com/Meumeu/WiVRn" "$REPO_DIR" +if [[ -z $REPO_URL ]]; then + REPO_URL="https://github.com/Meumeu/WiVRn" +fi + +"$(dirname -- "$0")/_clone_or_pull.sh" "$REPO_URL" "$REPO_DIR" "$DO_PULL" cd "$REPO_DIR" +rm -rf build mkdir -p build cd build cmake -B build-server -DCMAKE_BUILD_TYPE=Release \ diff --git a/src/builders/build_basalt.rs b/src/builders/build_basalt.rs index 5c5c8fc..24e445c 100644 --- a/src/builders/build_basalt.rs +++ b/src/builders/build_basalt.rs @@ -1,17 +1,24 @@ use expect_dialog::ExpectDialog; - use crate::{constants::PKG_DATA_DIR, profile::Profile, runner::Runner}; pub fn get_build_basalt_runner(profile: Profile) -> Runner { + let mut args = vec![ + profile + .basalt_path + .expect_dialog("Missing basalt path for given profile"), + profile.prefix, + match profile.pull_on_build { + true => "1".into(), + false => "0".into(), + }, + ]; + if profile.basalt_repo.is_some() { + args.push(profile.basalt_repo.unwrap()); + } let runner = Runner::new( None, format!("{sysdata}/scripts/build_basalt.sh", sysdata = PKG_DATA_DIR), - vec![ - profile - .basalt_path - .expect_dialog("Missing basalt path for given profile"), - profile.prefix, - ], + args, ); runner } diff --git a/src/builders/build_libsurvive.rs b/src/builders/build_libsurvive.rs index d5c9fdc..df9f7ff 100644 --- a/src/builders/build_libsurvive.rs +++ b/src/builders/build_libsurvive.rs @@ -1,16 +1,27 @@ -use crate::{profile::Profile, runner::Runner, constants::PKG_DATA_DIR}; +use crate::{constants::PKG_DATA_DIR, profile::Profile, runner::Runner}; use expect_dialog::ExpectDialog; pub fn get_build_libsurvive_runner(profile: Profile) -> Runner { + let mut args = vec![ + profile + .libsurvive_path + .expect_dialog("Missing libsurvive path for given profile"), + profile.prefix, + match profile.pull_on_build { + true => "1".into(), + false => "0".into(), + }, + ]; + if profile.libsurvive_repo.is_some() { + args.push(profile.libsurvive_repo.unwrap()); + } let runner = Runner::new( None, - format!("{sysdata}/scripts/build_libsurvive.sh", sysdata = PKG_DATA_DIR), - vec![ - profile - .libsurvive_path - .expect_dialog("Missing libsurvive path for given profile"), - profile.prefix, - ], + format!( + "{sysdata}/scripts/build_libsurvive.sh", + sysdata = PKG_DATA_DIR + ), + args, ); runner } diff --git a/src/builders/build_monado.rs b/src/builders/build_monado.rs index 988639f..24bbd36 100644 --- a/src/builders/build_monado.rs +++ b/src/builders/build_monado.rs @@ -1,13 +1,21 @@ -use crate::{runner::Runner, profile::Profile, constants::PKG_DATA_DIR}; +use crate::{constants::PKG_DATA_DIR, profile::Profile, runner::Runner}; pub fn get_build_monado_runner(profile: Profile) -> Runner { + let mut args = vec![ + profile.xrservice_path, + profile.prefix, + match profile.pull_on_build { + true => "1".into(), + false => "0".into(), + }, + ]; + if profile.xrservice_repo.is_some() { + args.push(profile.xrservice_repo.unwrap()); + } let runner = Runner::new( None, format!("{sysdata}/scripts/build_monado.sh", sysdata = PKG_DATA_DIR), - vec![ - profile.xrservice_path, - profile.prefix, - ] + args, ); runner } diff --git a/src/builders/build_opencomposite.rs b/src/builders/build_opencomposite.rs index 206b1ab..5ac68e9 100644 --- a/src/builders/build_opencomposite.rs +++ b/src/builders/build_opencomposite.rs @@ -1,12 +1,23 @@ -use crate::{profile::Profile, runner::Runner, constants::PKG_DATA_DIR}; +use crate::{constants::PKG_DATA_DIR, profile::Profile, runner::Runner}; pub fn get_build_opencomposite_runner(profile: Profile) -> Runner { + let mut args = vec![ + profile.opencomposite_path, + match profile.pull_on_build { + true => "1".into(), + false => "0".into(), + }, + ]; + if profile.opencomposite_repo.is_some() { + args.push(profile.opencomposite_repo.unwrap()); + } let runner = Runner::new( None, - format!("{sysdata}/scripts/build_opencomposite.sh", sysdata = PKG_DATA_DIR), - vec![ - profile.opencomposite_path, - ] + format!( + "{sysdata}/scripts/build_opencomposite.sh", + sysdata = PKG_DATA_DIR + ), + args, ); runner } diff --git a/src/builders/build_wivrn.rs b/src/builders/build_wivrn.rs index dcbaba6..8091617 100644 --- a/src/builders/build_wivrn.rs +++ b/src/builders/build_wivrn.rs @@ -1,14 +1,21 @@ -use crate::{profile::Profile, runner::Runner, constants::PKG_DATA_DIR}; +use crate::{constants::PKG_DATA_DIR, profile::Profile, runner::Runner}; pub fn get_build_wivrn_runner(profile: Profile) -> Runner { + let mut args = vec![ + profile.xrservice_path, + profile.prefix, + match profile.pull_on_build { + true => "1".into(), + false => "0".into(), + }, + ]; + if profile.xrservice_repo.is_some() { + args.push(profile.xrservice_repo.unwrap()); + } let runner = Runner::new( None, format!("{sysdata}/scripts/build_wivrn.sh", sysdata = PKG_DATA_DIR), - vec![ - profile.xrservice_path, - profile.prefix, - ] + args, ); runner } - diff --git a/src/profile.rs b/src/profile.rs index cf08115..cafd1d1 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -56,11 +56,17 @@ pub struct Profile { pub libsurvive_enabled: bool, pub basalt_enabled: bool, pub mercury_enabled: bool, + pub xrservice_repo: Option, + pub opencomposite_repo: Option, + pub libsurvive_repo: Option, + pub basalt_repo: Option, + pub mercury_repo: Option, pub environment: HashMap, /** Install prefix */ pub prefix: String, pub can_be_built: bool, pub editable: bool, + pub pull_on_build: bool, } impl Display for Profile { @@ -89,6 +95,12 @@ impl Default for Profile { data = get_data_dir() ), can_be_built: true, + pull_on_build: true, + xrservice_repo: None, + opencomposite_repo: None, + libsurvive_repo: None, + basalt_repo: None, + mercury_repo: None, editable: true, } } @@ -203,8 +215,8 @@ mod tests { mercury_enabled: false, environment: env, prefix: String::from("/home/user/rex2prefix"), - can_be_built: true, editable: true, + ..Default::default() }; let fpath = String::from("./target/testout/testprofile.json"); p.dump_profile(&fpath); diff --git a/src/profiles/system_valve_index.rs b/src/profiles/system_valve_index.rs index 6b71bbf..23b9fd4 100644 --- a/src/profiles/system_valve_index.rs +++ b/src/profiles/system_valve_index.rs @@ -23,5 +23,6 @@ pub fn system_valve_index_profile() -> Profile { prefix: SYSTEM_PREFIX.into(), can_be_built: false, editable: false, + ..Default::default() } } diff --git a/src/profiles/valve_index.rs b/src/profiles/valve_index.rs index e276d04..cd02a47 100644 --- a/src/profiles/valve_index.rs +++ b/src/profiles/valve_index.rs @@ -26,5 +26,6 @@ pub fn valve_index_profile() -> Profile { prefix, can_be_built: true, editable: false, + ..Default::default() } } diff --git a/src/profiles/wivrn.rs b/src/profiles/wivrn.rs index 96bacb9..729c09d 100644 --- a/src/profiles/wivrn.rs +++ b/src/profiles/wivrn.rs @@ -23,5 +23,6 @@ pub fn wivrn_profile() -> Profile { prefix, can_be_built: true, editable: false, + ..Default::default() } } diff --git a/src/ui/factories/entry_row_factory.rs b/src/ui/factories/entry_row_factory.rs new file mode 100644 index 0000000..278120d --- /dev/null +++ b/src/ui/factories/entry_row_factory.rs @@ -0,0 +1,83 @@ +use crate::ui::profile_editor::ProfileEditorMsg; +use adw::prelude::*; +use gtk::prelude::*; +use relm4::prelude::*; + +#[derive(Debug)] +pub struct EntryModel { + key: String, + name: String, + value: String, +} + +pub struct EntryModelInit { + pub key: String, + pub name: String, + pub value: String, +} + +#[derive(Debug)] +pub enum EntryModelMsg { + Changed(String), +} + +#[derive(Debug)] +pub enum EntryModelOutMsg { + Changed(String, String), +} + +#[relm4::factory(pub)] +impl FactoryComponent for EntryModel { + type Init = EntryModelInit; + type Input = EntryModelMsg; + type Output = EntryModelOutMsg; + type CommandOutput = (); + type Widgets = EntryModelWidgets; + type ParentInput = ProfileEditorMsg; + type ParentWidget = adw::PreferencesGroup; + + view! { + root = adw::EntryRow { + set_title: &self.name, + set_text: &self.value, + add_suffix: clear_btn = >k::Button { + set_icon_name: "edit-clear-symbolic", + set_tooltip_text: Some("Clear"), + set_valign: gtk::Align::Center, + add_css_class: "flat", + add_css_class: "circular", + connect_clicked[root] => move |_| { + root.set_text(""); + } + }, + connect_changed[sender] => move |entry| { + sender.input_sender().emit(Self::Input::Changed(entry.text().to_string())); + }, + } + } + + fn update(&mut self, message: Self::Input, sender: FactorySender) { + match message { + Self::Input::Changed(val) => { + self.value = val.clone(); + sender + .output_sender() + .emit(Self::Output::Changed(self.key.clone(), val)); + } + } + } + + fn forward_to_parent(output: Self::Output) -> Option { + Some(match output { + Self::Output::Changed(key, value) => ProfileEditorMsg::EntryChanged(key, value), + }) + } + + fn init_model(init: Self::Init, index: &Self::Index, sender: FactorySender) -> Self { + Self { + key: init.key, + name: init.name, + value: init.value, + } + } +} diff --git a/src/ui/factories/mod.rs b/src/ui/factories/mod.rs index bdf58f9..c731438 100644 --- a/src/ui/factories/mod.rs +++ b/src/ui/factories/mod.rs @@ -1,3 +1,4 @@ pub mod env_var_row_factory; pub mod switch_row_factory; pub mod path_row_factory; +pub mod entry_row_factory; diff --git a/src/ui/factories/path_row_factory.rs b/src/ui/factories/path_row_factory.rs index 6908b33..2986e95 100644 --- a/src/ui/factories/path_row_factory.rs +++ b/src/ui/factories/path_row_factory.rs @@ -52,7 +52,7 @@ impl FactoryComponent for PathModel { set_valign: gtk::Align::Center, add_css_class: "flat", add_css_class: "circular", - set_icon_name: "edit-clear", + set_icon_name: "edit-clear-symbolic", set_tooltip_text: Some("Clear Path"), connect_clicked[sender] => move |_| { sender.input(Self::Input::Changed(None)); diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 584b04c..5ae31e7 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -261,6 +261,7 @@ impl SimpleComponent for MainView { .unwrap() .clone() .set_selected(index); + self.set_selected_profile(self.profiles.get(index as usize).unwrap().clone()); } Self::Input::ProfileSelected(position) => { sender.output(MainViewOutMsg::ProfileSelected( diff --git a/src/ui/profile_editor.rs b/src/ui/profile_editor.rs index 76b553e..6dd4fa4 100644 --- a/src/ui/profile_editor.rs +++ b/src/ui/profile_editor.rs @@ -1,4 +1,5 @@ use super::factories::{ + entry_row_factory::{EntryModel, EntryModelInit}, env_var_row_factory::{EnvVarModel, EnvVarModelInit}, path_row_factory::{PathModel, PathModelInit}, switch_row_factory::{SwitchModel, SwitchModelInit}, @@ -24,11 +25,15 @@ pub struct ProfileEditor { #[tracker::do_not_track] type_row: adw::ComboRow, #[tracker::do_not_track] + pull_on_build_switch: Option, + #[tracker::do_not_track] env_rows: FactoryVecDeque, #[tracker::do_not_track] switch_rows: FactoryVecDeque, #[tracker::do_not_track] path_rows: FactoryVecDeque, + #[tracker::do_not_track] + repo_rows: FactoryVecDeque, } #[derive(Debug)] @@ -36,7 +41,7 @@ pub enum ProfileEditorMsg { Present(Profile), EnvVarChanged(String, String), EnvVarDelete(String), - TextChanged(String, String), + EntryChanged(String, String), PathChanged(String, Option), SwitchChanged(String, bool), ComboChanged(String, String), @@ -69,13 +74,25 @@ impl SimpleComponent for ProfileEditor { }, add: mainpage = &adw::PreferencesPage { add: maingrp = &adw::PreferencesGroup { - set_title: "Profile Info", + set_title: "General", model.name_row.clone(), model.type_row.clone(), + adw::ActionRow { + set_title: "Update on Build", + add_suffix: pull_on_build_switch = >k::Switch { + set_valign: gtk::Align::Center, + connect_state_set[sender] => move |_, state| { + sender.input(Self::Input::SwitchChanged("pull_on_build".into(), state)); + gtk::Inhibit(false) + } + }, + set_activatable_widget: Some(&pull_on_build_switch), + } }, add: model.env_rows.widget(), add: model.switch_rows.widget(), add: model.path_rows.widget(), + add: model.repo_rows.widget(), add: save_grp = &adw::PreferencesGroup { add: save_box = >k::Box { set_orientation: gtk::Orientation::Vertical, @@ -106,65 +123,106 @@ impl SimpleComponent for ProfileEditor { self.type_row.set_selected(prof.xrservice_type.as_number()); - self.env_rows.guard().clear(); - for (k, v) in p.environment.iter() { - self.env_rows.guard().push_back(EnvVarModelInit { - name: k.clone(), - value: v.clone(), + self.pull_on_build_switch.as_ref().unwrap().set_active(prof.pull_on_build); + + { + let mut guard = self.env_rows.guard(); + guard.clear(); + for (k, v) in p.environment.iter() { + guard.push_back(EnvVarModelInit { + name: k.clone(), + value: v.clone(), + }); + } + } + + { + let mut guard = self.switch_rows.guard(); + guard.clear(); + guard.push_back(SwitchModelInit { + name: "Libsurvive".into(), + description: Some("Lighthouse based spacial tracking".into()), + key: "libsurvive_enabled".into(), + value: p.libsurvive_enabled, + }); + guard.push_back(SwitchModelInit { + name: "Basalt".into(), + description: Some("Camera based SLAM tracking".into()), + key: "basalt_enabled".into(), + value: p.basalt_enabled, + }); + guard.push_back(SwitchModelInit { + name: "Mercury".into(), + description: Some("Camera based hand tracking".into()), + key: "mercury_enabled".into(), + value: p.mercury_enabled, }); } - self.switch_rows.guard().clear(); - self.switch_rows.guard().push_back(SwitchModelInit { - name: "Libsurvive".into(), - description: Some("Lighthouse based spacial tracking".into()), - key: "libsurvive_enabled".into(), - value: p.libsurvive_enabled, - }); - self.switch_rows.guard().push_back(SwitchModelInit { - name: "Basalt".into(), - description: Some("Camera based SLAM tracking".into()), - key: "basalt_enabled".into(), - value: p.basalt_enabled, - }); - self.switch_rows.guard().push_back(SwitchModelInit { - name: "Mercury".into(), - description: Some("Camera based hand tracking".into()), - key: "mercury_enabled".into(), - value: p.mercury_enabled, - }); + { + let mut guard = self.path_rows.guard(); + guard.clear(); + guard.push_back(PathModelInit { + name: "XR Service Path".into(), + key: "xrservice_path".into(), + value: Some(p.xrservice_path), + }); + guard.push_back(PathModelInit { + name: "OpenComposite Path".into(), + key: "opencomposite_path".into(), + value: Some(p.opencomposite_path), + }); + guard.push_back(PathModelInit { + name: "Libsurvive Path".into(), + key: "libsurvive_path".into(), + value: p.libsurvive_path, + }); + guard.push_back(PathModelInit { + name: "Basalt Path".into(), + key: "basalt_path".into(), + value: p.basalt_path, + }); + guard.push_back(PathModelInit { + name: "Mercury Path".into(), + key: "mercury_path".into(), + value: p.mercury_path, + }); + guard.push_back(PathModelInit { + name: "Install Prefix".into(), + key: "prefix".into(), + value: Some(p.prefix), + }); + } - self.path_rows.guard().clear(); - self.path_rows.guard().push_back(PathModelInit { - name: "XR Service Path".into(), - key: "xrservice_path".into(), - value: Some(p.xrservice_path), - }); - self.path_rows.guard().push_back(PathModelInit { - name: "OpenComposite Path".into(), - key: "opencomposite_path".into(), - value: Some(p.opencomposite_path), - }); - self.path_rows.guard().push_back(PathModelInit { - name: "Libsurvive Path".into(), - key: "libsurvive_path".into(), - value: p.libsurvive_path, - }); - self.path_rows.guard().push_back(PathModelInit { - name: "Basalt Path".into(), - key: "basalt_path".into(), - value: p.basalt_path, - }); - self.path_rows.guard().push_back(PathModelInit { - name: "Mercury Path".into(), - key: "mercury_path".into(), - value: p.mercury_path, - }); - self.path_rows.guard().push_back(PathModelInit { - name: "Install Prefix".into(), - key: "prefix".into(), - value: Some(p.prefix), - }); + { + let mut guard = self.repo_rows.guard(); + guard.clear(); + guard.push_back(EntryModelInit { + key: "xrservice_repo".into(), + name: "XR Service Repo".into(), + value: p.xrservice_repo.unwrap_or("".into()), + }); + guard.push_back(EntryModelInit { + key: "opencomposite_repo".into(), + name: "OpenComposite Repo".into(), + value: p.opencomposite_repo.unwrap_or("".into()), + }); + guard.push_back(EntryModelInit { + key: "libsurvive_repo".into(), + name: "Libsurvive Repo".into(), + value: p.libsurvive_repo.unwrap_or("".into()), + }); + guard.push_back(EntryModelInit { + key: "basalt_repo".into(), + name: "Basalt Repo".into(), + value: p.basalt_repo.unwrap_or("".into()), + }); + guard.push_back(EntryModelInit { + key: "mercury_repo".into(), + name: "Mercury Repo".into(), + value: p.mercury_repo.unwrap_or("".into()), + }); + } self.set_profile(Some(prof.clone())); @@ -221,13 +279,44 @@ impl SimpleComponent for ProfileEditor { "libsurvive_enabled" => prof.libsurvive_enabled = value, "basalt_enabled" => prof.basalt_enabled = value, "mercury_enabled" => prof.mercury_enabled = value, + "pull_on_build" => prof.pull_on_build = value, _ => panic!("Unknown profile switch key"), } } - Self::Input::TextChanged(key, value) => { + Self::Input::EntryChanged(key, value) => { let prof = self.profile.as_mut().unwrap(); match key.as_str() { "name" => prof.name = value, + "xrservice_repo" => { + prof.xrservice_repo = match value.trim() { + "" => None, + s => Some(s.to_string()), + } + } + "opencomposite_repo" => { + prof.opencomposite_repo = match value.trim() { + "" => None, + s => Some(s.to_string()), + } + } + "libsurvive_repo" => { + prof.libsurvive_repo = match value.trim() { + "" => None, + s => Some(s.to_string()), + } + } + "basalt_repo" => { + prof.basalt_repo = match value.trim() { + "" => None, + s => Some(s.to_string()), + } + } + "mercury_repo" => { + prof.mercury_repo = match value.trim() { + "" => None, + s => Some(s.to_string()), + } + } _ => panic!("Unknown profile text key"), } } @@ -315,6 +404,7 @@ impl SimpleComponent for ProfileEditor { .as_slice(), )) .build(), + pull_on_build_switch: None, env_rows: FactoryVecDeque::new( adw::PreferencesGroup::builder() .title("Environment Variables") @@ -337,13 +427,20 @@ impl SimpleComponent for ProfileEditor { .build(), sender.input_sender(), ), + repo_rows: FactoryVecDeque::new( + adw::PreferencesGroup::builder() + .title("Repositories") + .description("Change the repositories from which various components are pulled.\n\nLeave empty to use the default repository.") + .build(), + sender.input_sender(), + ), tracker: 0, }; { let name_sender = sender.clone(); model.name_row.connect_changed(move |nr| { - name_sender.input(Self::Input::TextChanged( + name_sender.input(Self::Input::EntryChanged( "name".to_string(), nr.text().to_string(), )); @@ -366,6 +463,7 @@ impl SimpleComponent for ProfileEditor { let widgets = view_output!(); model.win = Some(widgets.win.clone()); + model.pull_on_build_switch = Some(widgets.pull_on_build_switch.clone()); ComponentParts { model, widgets } } diff --git a/test/files/profile.json b/test/files/profile.json index d6b4378..ba94c82 100644 --- a/test/files/profile.json +++ b/test/files/profile.json @@ -1,4 +1,5 @@ { + "uuid": "demo", "name": "Demo profile", "xrservice_path": "/home/user/monado", "xrservice_type": "Monado", @@ -15,5 +16,12 @@ "SURVIVE_GLOBALSCENESOLVER": "0" }, "prefix": "/home/user/rex2prefix", - "can_be_built": true + "can_be_built": true, + "editable": true, + "pull_on_build": true, + "xrservice_repo": null, + "opencomposite_repo": null, + "libsurvive_repo": null, + "basalt_repo": null, + "mercury_repo": null }