mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-08-03 06:38:52 +00:00
Merge branch 'main' into feat/stardust
This commit is contained in:
commit
21d84252ca
37 changed files with 354 additions and 191 deletions
|
@ -22,7 +22,7 @@ cargo:test:
|
||||||
script:
|
script:
|
||||||
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
||||||
- apt-get update
|
- apt-get update
|
||||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
||||||
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||||
- chmod +x /tmp/rustup.sh
|
- chmod +x /tmp/rustup.sh
|
||||||
|
@ -41,7 +41,7 @@ appimage:
|
||||||
script:
|
script:
|
||||||
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
||||||
- apt-get update
|
- apt-get update
|
||||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
||||||
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||||
- chmod +x /tmp/rustup.sh
|
- chmod +x /tmp/rustup.sh
|
||||||
|
|
36
Cargo.lock
generated
36
Cargo.lock
generated
|
@ -301,7 +301,6 @@ dependencies = [
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sourceview5",
|
|
||||||
"tracker",
|
"tracker",
|
||||||
"uuid",
|
"uuid",
|
||||||
"zoha-vte4",
|
"zoha-vte4",
|
||||||
|
@ -1877,41 +1876,6 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sourceview5"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "88c5f976a113e947bc5ec67758b2960c0db4ca76f80fb410d7cd86cd456d9ee5"
|
|
||||||
dependencies = [
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"gdk-pixbuf",
|
|
||||||
"gdk4",
|
|
||||||
"gio",
|
|
||||||
"glib",
|
|
||||||
"gtk4",
|
|
||||||
"libc",
|
|
||||||
"pango",
|
|
||||||
"sourceview5-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sourceview5-sys"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "29637cccd56075a37ba72c0cc8b8d599dbc1d857e30dadea97eaacbc29b7fd46"
|
|
||||||
dependencies = [
|
|
||||||
"gdk-pixbuf-sys",
|
|
||||||
"gdk4-sys",
|
|
||||||
"gio-sys",
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"gtk4-sys",
|
|
||||||
"libc",
|
|
||||||
"pango-sys",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.9.8"
|
version = "0.9.8"
|
||||||
|
|
|
@ -36,9 +36,6 @@ serde = { version = "1.0.188", features = [
|
||||||
"derive"
|
"derive"
|
||||||
] }
|
] }
|
||||||
serde_json = "1.0.106"
|
serde_json = "1.0.106"
|
||||||
sourceview5 = { version = "0.7.1", features = [
|
|
||||||
"v5_6"
|
|
||||||
] }
|
|
||||||
tracker = "0.2.1"
|
tracker = "0.2.1"
|
||||||
uuid = { version = "1.4.1", features = ["v4", "fast-rng"] }
|
uuid = { version = "1.4.1", features = ["v4", "fast-rng"] }
|
||||||
zoha-vte4 = { version = "0.0.2", features = ["v0_72"] }
|
zoha-vte4 = { version = "0.0.2", features = ["v0_72"] }
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
.padded {
|
.padded {
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceview-transparent-bg, .sourceview-transparent-bg * {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
2
dist/arch/PKGBUILD
vendored
2
dist/arch/PKGBUILD
vendored
|
@ -9,7 +9,6 @@ url='https://gitlab.com/gabmus/envision'
|
||||||
license=(GPL)
|
license=(GPL)
|
||||||
depends=(
|
depends=(
|
||||||
gtk4
|
gtk4
|
||||||
gtksourceview5
|
|
||||||
libadwaita
|
libadwaita
|
||||||
openxr
|
openxr
|
||||||
libgl
|
libgl
|
||||||
|
@ -23,6 +22,7 @@ depends=(
|
||||||
ninja
|
ninja
|
||||||
shaderc
|
shaderc
|
||||||
vulkan-headers
|
vulkan-headers
|
||||||
|
vte4
|
||||||
)
|
)
|
||||||
makedepends=(
|
makedepends=(
|
||||||
meson
|
meson
|
||||||
|
|
|
@ -18,7 +18,7 @@ description = 'GUI for Monado' # temporary
|
||||||
dependency('glib-2.0', version: '>= 2.66')
|
dependency('glib-2.0', version: '>= 2.66')
|
||||||
dependency('gio-2.0', version: '>= 2.66')
|
dependency('gio-2.0', version: '>= 2.66')
|
||||||
dependency('gtk4', version: '>= 4.10.0')
|
dependency('gtk4', version: '>= 4.10.0')
|
||||||
dependency('gtksourceview-5', version: '>= 5.6.0')
|
dependency('vte-2.91-gtk4', version: '>= 0.72.0')
|
||||||
|
|
||||||
glib_compile_resources = find_program('glib-compile-resources', required: true)
|
glib_compile_resources = find_program('glib-compile-resources', required: true)
|
||||||
# glib_compile_schemas = find_program('glib-compile-schemas', required: true)
|
# glib_compile_schemas = find_program('glib-compile-schemas', required: true)
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::path::Path;
|
||||||
pub struct Git {
|
pub struct Git {
|
||||||
pub repo: String,
|
pub repo: String,
|
||||||
pub dir: String,
|
pub dir: String,
|
||||||
pub default_branch: String,
|
pub branch: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Git {
|
impl Git {
|
||||||
|
@ -88,7 +88,7 @@ impl Git {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_checkout_ref_job(&self) -> WorkerJob {
|
pub fn get_checkout_ref_job(&self) -> WorkerJob {
|
||||||
let gref = self.get_ref().unwrap_or(self.default_branch.clone());
|
let gref = self.get_ref().unwrap_or(self.branch.clone());
|
||||||
self.cmd(vec!["checkout".into(), gref])
|
self.cmd(vec!["checkout".into(), gref])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,10 @@ pub fn get_build_basalt_jobs(profile: &Profile, clean_build: bool) -> VecDeque<W
|
||||||
None => "https://gitlab.freedesktop.org/mateosss/basalt.git".into(),
|
None => "https://gitlab.freedesktop.org/mateosss/basalt.git".into(),
|
||||||
},
|
},
|
||||||
dir: profile.features.basalt.path.as_ref().unwrap().clone(),
|
dir: profile.features.basalt.path.as_ref().unwrap().clone(),
|
||||||
default_branch: "main".into(),
|
branch: match profile.features.basalt.branch.as_ref() {
|
||||||
|
Some(r) => r.clone(),
|
||||||
|
None => "main".into(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||||
|
|
|
@ -18,7 +18,10 @@ pub fn get_build_libsurvive_jobs(profile: &Profile, clean_build: bool) -> VecDeq
|
||||||
None => "https://github.com/cntools/libsurvive".into(),
|
None => "https://github.com/cntools/libsurvive".into(),
|
||||||
},
|
},
|
||||||
dir: profile.features.libsurvive.path.as_ref().unwrap().clone(),
|
dir: profile.features.libsurvive.path.as_ref().unwrap().clone(),
|
||||||
default_branch: "master".into(),
|
branch: match profile.features.libsurvive.branch.as_ref() {
|
||||||
|
Some(r) => r.clone(),
|
||||||
|
None => "master".into(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||||
|
|
|
@ -22,7 +22,10 @@ pub fn get_build_monado_jobs(
|
||||||
None => "https://gitlab.freedesktop.org/monado/monado".into(),
|
None => "https://gitlab.freedesktop.org/monado/monado".into(),
|
||||||
},
|
},
|
||||||
dir: profile.xrservice_path.clone(),
|
dir: profile.xrservice_path.clone(),
|
||||||
default_branch: "main".into(),
|
branch: match profile.xrservice_branch.as_ref() {
|
||||||
|
Some(r) => r.clone(),
|
||||||
|
None => "main".into(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||||
|
|
|
@ -22,7 +22,10 @@ pub fn get_build_opencomposite_jobs(
|
||||||
None => "https://gitlab.com/znixian/OpenOVR.git".into(),
|
None => "https://gitlab.com/znixian/OpenOVR.git".into(),
|
||||||
},
|
},
|
||||||
dir: profile.opencomposite_path.clone(),
|
dir: profile.opencomposite_path.clone(),
|
||||||
default_branch: "openxr".into(),
|
branch: match profile.opencomposite_branch.as_ref() {
|
||||||
|
Some(r) => r.clone(),
|
||||||
|
None => "openxr".into(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||||
|
|
|
@ -18,7 +18,10 @@ pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque<
|
||||||
None => "https://github.com/OpenHMD/OpenHMD".into(),
|
None => "https://github.com/OpenHMD/OpenHMD".into(),
|
||||||
},
|
},
|
||||||
dir: profile.features.openhmd.path.as_ref().unwrap().clone(),
|
dir: profile.features.openhmd.path.as_ref().unwrap().clone(),
|
||||||
default_branch: "master".into(),
|
branch: match profile.features.openhmd.branch.as_ref() {
|
||||||
|
Some(r) => r.clone(),
|
||||||
|
None => "master".into(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||||
|
|
|
@ -22,7 +22,10 @@ pub fn get_build_wivrn_jobs(
|
||||||
None => "https://github.com/Meumeu/WiVRn".into(),
|
None => "https://github.com/Meumeu/WiVRn".into(),
|
||||||
},
|
},
|
||||||
dir: profile.xrservice_path.clone(),
|
dir: profile.xrservice_path.clone(),
|
||||||
default_branch: "master".into(),
|
branch: match profile.xrservice_branch.as_ref() {
|
||||||
|
Some(r) => r.clone(),
|
||||||
|
None => "master".into(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||||
|
|
|
@ -40,6 +40,16 @@ fn monado_deps() -> Vec<Dependency> {
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
dep_glslang_validator(),
|
dep_glslang_validator(),
|
||||||
|
Dependency {
|
||||||
|
name: "sdl2".into(),
|
||||||
|
dep_type: DepType::SharedObject,
|
||||||
|
filename: "libSDL2.so".into(),
|
||||||
|
packages: HashMap::from([
|
||||||
|
(LinuxDistro::Arch, "sdl2".into()),
|
||||||
|
(LinuxDistro::Debian, "libsdl2".into()),
|
||||||
|
(LinuxDistro::Fedora, "SDL2".into()),
|
||||||
|
]),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub static ENV_VAR_DESCRIPTIONS: Map<&str, &str> = phf_map! {
|
||||||
"XRT_DEBUG_GUI" => "Set to 1 to enable the Monado debug UI.",
|
"XRT_DEBUG_GUI" => "Set to 1 to enable the Monado debug UI.",
|
||||||
"XRT_CURATED_GUI" => "Set to 1 to enable the Monado preview UI. Requires XRT_DEBUG_GUI=1 to work.",
|
"XRT_CURATED_GUI" => "Set to 1 to enable the Monado preview UI. Requires XRT_DEBUG_GUI=1 to work.",
|
||||||
"XRT_JSON_LOG" => "Set to 1 to enable JSON logging for Monado. This enables better log visualization and log level filtering.",
|
"XRT_JSON_LOG" => "Set to 1 to enable JSON logging for Monado. This enables better log visualization and log level filtering.",
|
||||||
|
"QWERTY_ENABLE" => "Set to 1 to enable QWERTY Simulation driver. This enables simulated driver that allows you to use Monado without HMD and controllers. It's also possible to mix and match different profiles with this.",
|
||||||
"LH_DRIVER" => "Lighthouse driver, this overrides the \"Lighthouse driver option in the profile\"; Valid options are: \"vive\" for the default built-in driver, \"survive\" for Libsurvive, \"steamvr\" for the SteamVR based implementation.",
|
"LH_DRIVER" => "Lighthouse driver, this overrides the \"Lighthouse driver option in the profile\"; Valid options are: \"vive\" for the default built-in driver, \"survive\" for Libsurvive, \"steamvr\" for the SteamVR based implementation.",
|
||||||
"LH_LOG" => "Lighthouse log level. Can be one of: \"trace\", \"debug\", \"info\", \"warn\", \"error\".",
|
"LH_LOG" => "Lighthouse log level. Can be one of: \"trace\", \"debug\", \"info\", \"warn\", \"error\".",
|
||||||
"LIGHTHOUSE_LOG" => "Lighthouse driver log level. Can be one of: \"trace\", \"debug\", \"info\", \"warn\", \"error\"."
|
"LIGHTHOUSE_LOG" => "Lighthouse driver log level. Can be one of: \"trace\", \"debug\", \"info\", \"warn\", \"error\"."
|
||||||
|
|
|
@ -85,6 +85,10 @@ pub struct WivrnConfEncoder {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub height: Option<f32>,
|
pub height: Option<f32>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub offset_x: Option<f32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub offset_y: Option<f32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub group: Option<i32>,
|
pub group: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +100,8 @@ impl Default for WivrnConfEncoder {
|
||||||
bitrate: None,
|
bitrate: None,
|
||||||
width: None,
|
width: None,
|
||||||
height: None,
|
height: None,
|
||||||
|
offset_x: None,
|
||||||
|
offset_y: None,
|
||||||
group: None,
|
group: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +124,8 @@ impl Default for WivrnConfig {
|
||||||
bitrate: Some(100000000),
|
bitrate: Some(100000000),
|
||||||
width: Some(1.0),
|
width: Some(1.0),
|
||||||
height: Some(1.0),
|
height: Some(1.0),
|
||||||
|
offset_x: Some(0.0),
|
||||||
|
offset_y: Some(0.0),
|
||||||
group: None,
|
group: None,
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
@ -162,5 +170,7 @@ mod tests {
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().bitrate, Some(100000000));
|
assert_eq!(conf.encoders.get(0).unwrap().bitrate, Some(100000000));
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().width, Some(1.0));
|
assert_eq!(conf.encoders.get(0).unwrap().width, Some(1.0));
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().height, Some(1.0));
|
assert_eq!(conf.encoders.get(0).unwrap().height, Some(1.0));
|
||||||
|
assert_eq!(conf.encoders.get(0).unwrap().offset_x, Some(0.0));
|
||||||
|
assert_eq!(conf.encoders.get(0).unwrap().offset_y, Some(0.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ pub struct ProfileFeature {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub path: Option<String>,
|
pub path: Option<String>,
|
||||||
pub repo: Option<String>,
|
pub repo: Option<String>,
|
||||||
|
pub branch: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ProfileFeature {
|
impl Default for ProfileFeature {
|
||||||
|
@ -99,6 +100,7 @@ impl Default for ProfileFeature {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
path: None,
|
path: None,
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,10 +212,12 @@ pub struct Profile {
|
||||||
pub xrservice_type: XRServiceType,
|
pub xrservice_type: XRServiceType,
|
||||||
pub xrservice_path: String,
|
pub xrservice_path: String,
|
||||||
pub xrservice_repo: Option<String>,
|
pub xrservice_repo: Option<String>,
|
||||||
|
pub xrservice_branch: Option<String>,
|
||||||
#[serde(default = "HashMap::<String, String>::default")]
|
#[serde(default = "HashMap::<String, String>::default")]
|
||||||
pub xrservice_cmake_flags: HashMap<String, String>,
|
pub xrservice_cmake_flags: HashMap<String, String>,
|
||||||
pub opencomposite_path: String,
|
pub opencomposite_path: String,
|
||||||
pub opencomposite_repo: Option<String>,
|
pub opencomposite_repo: Option<String>,
|
||||||
|
pub opencomposite_branch: Option<String>,
|
||||||
pub features: ProfileFeatures,
|
pub features: ProfileFeatures,
|
||||||
pub environment: HashMap<String, String>,
|
pub environment: HashMap<String, String>,
|
||||||
/** Install prefix */
|
/** Install prefix */
|
||||||
|
@ -243,24 +247,28 @@ impl Default for Profile {
|
||||||
xrservice_path: format!("{}/xrservice", profile_dir),
|
xrservice_path: format!("{}/xrservice", profile_dir),
|
||||||
xrservice_type: XRServiceType::Monado,
|
xrservice_type: XRServiceType::Monado,
|
||||||
xrservice_repo: None,
|
xrservice_repo: None,
|
||||||
|
xrservice_branch: None,
|
||||||
xrservice_cmake_flags: HashMap::<String, String>::default(),
|
xrservice_cmake_flags: HashMap::<String, String>::default(),
|
||||||
features: ProfileFeatures {
|
features: ProfileFeatures {
|
||||||
libsurvive: ProfileFeature {
|
libsurvive: ProfileFeature {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
path: Some(format!("{}/libsurvive", profile_dir)),
|
path: Some(format!("{}/libsurvive", profile_dir)),
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
feature_type: ProfileFeatureType::Libsurvive,
|
feature_type: ProfileFeatureType::Libsurvive,
|
||||||
},
|
},
|
||||||
basalt: ProfileFeature {
|
basalt: ProfileFeature {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
path: Some(format!("{}/basalt", profile_dir)),
|
path: Some(format!("{}/basalt", profile_dir)),
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
feature_type: ProfileFeatureType::Basalt,
|
feature_type: ProfileFeatureType::Basalt,
|
||||||
},
|
},
|
||||||
openhmd: ProfileFeature {
|
openhmd: ProfileFeature {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
path: Some(format!("{}/openhmd", profile_dir)),
|
path: Some(format!("{}/openhmd", profile_dir)),
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
feature_type: ProfileFeatureType::OpenHmd,
|
feature_type: ProfileFeatureType::OpenHmd,
|
||||||
},
|
},
|
||||||
mercury_enabled: false,
|
mercury_enabled: false,
|
||||||
|
@ -269,8 +277,9 @@ impl Default for Profile {
|
||||||
prefix: format!("{}/prefixes/{}", get_data_dir(), uuid),
|
prefix: format!("{}/prefixes/{}", get_data_dir(), uuid),
|
||||||
can_be_built: true,
|
can_be_built: true,
|
||||||
pull_on_build: true,
|
pull_on_build: true,
|
||||||
opencomposite_repo: None,
|
|
||||||
opencomposite_path: format!("{}/opencomposite", profile_dir),
|
opencomposite_path: format!("{}/opencomposite", profile_dir),
|
||||||
|
opencomposite_repo: None,
|
||||||
|
opencomposite_branch: None,
|
||||||
editable: true,
|
editable: true,
|
||||||
lighthouse_driver: LighthouseDriver::default(),
|
lighthouse_driver: LighthouseDriver::default(),
|
||||||
xrservice_launch_options: String::default(),
|
xrservice_launch_options: String::default(),
|
||||||
|
@ -337,17 +346,28 @@ impl Profile {
|
||||||
dup.name = format!("Duplicate of {}", self.name);
|
dup.name = format!("Duplicate of {}", self.name);
|
||||||
dup.xrservice_type = self.xrservice_type.clone();
|
dup.xrservice_type = self.xrservice_type.clone();
|
||||||
dup.xrservice_repo = self.xrservice_repo.clone();
|
dup.xrservice_repo = self.xrservice_repo.clone();
|
||||||
|
dup.xrservice_branch = self.xrservice_branch.clone();
|
||||||
dup.xrservice_cmake_flags = self.xrservice_cmake_flags.clone();
|
dup.xrservice_cmake_flags = self.xrservice_cmake_flags.clone();
|
||||||
dup.features.libsurvive.enabled = self.features.libsurvive.enabled;
|
dup.features.libsurvive.enabled = self.features.libsurvive.enabled;
|
||||||
dup.features.libsurvive.repo = self.features.libsurvive.repo.clone();
|
dup.features.libsurvive.repo = self.features.libsurvive.repo.clone();
|
||||||
|
dup.features.libsurvive.branch = self.features.libsurvive.branch.clone();
|
||||||
dup.features.basalt.enabled = self.features.basalt.enabled;
|
dup.features.basalt.enabled = self.features.basalt.enabled;
|
||||||
dup.features.basalt.repo = self.features.basalt.repo.clone();
|
dup.features.basalt.repo = self.features.basalt.repo.clone();
|
||||||
|
dup.features.basalt.branch = self.features.basalt.branch.clone();
|
||||||
dup.features.openhmd.enabled = self.features.openhmd.enabled;
|
dup.features.openhmd.enabled = self.features.openhmd.enabled;
|
||||||
dup.features.openhmd.repo = self.features.openhmd.repo.clone();
|
dup.features.openhmd.repo = self.features.openhmd.repo.clone();
|
||||||
|
dup.features.openhmd.branch = self.features.openhmd.branch.clone();
|
||||||
dup.features.mercury_enabled = self.features.mercury_enabled;
|
dup.features.mercury_enabled = self.features.mercury_enabled;
|
||||||
dup.environment = self.environment.clone();
|
dup.environment = self.environment.clone();
|
||||||
|
if dup.environment.contains_key("LD_LIBRARY_PATH".into()) {
|
||||||
|
dup.environment.insert(
|
||||||
|
"LD_LIBRARY_PATH".into(),
|
||||||
|
prepare_ld_library_path(&dup.prefix),
|
||||||
|
);
|
||||||
|
}
|
||||||
dup.pull_on_build = self.pull_on_build;
|
dup.pull_on_build = self.pull_on_build;
|
||||||
dup.opencomposite_repo = self.opencomposite_repo.clone();
|
dup.opencomposite_repo = self.opencomposite_repo.clone();
|
||||||
|
dup.opencomposite_branch = self.opencomposite_branch.clone();
|
||||||
dup.lighthouse_driver = self.lighthouse_driver;
|
dup.lighthouse_driver = self.lighthouse_driver;
|
||||||
dup.xrservice_launch_options = self.xrservice_launch_options.clone();
|
dup.xrservice_launch_options = self.xrservice_launch_options.clone();
|
||||||
dup
|
dup
|
||||||
|
@ -467,6 +487,7 @@ mod tests {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
path: Some(String::from("/home/user/libsurvive")),
|
path: Some(String::from("/home/user/libsurvive")),
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
},
|
},
|
||||||
basalt: ProfileFeature::default_basalt(),
|
basalt: ProfileFeature::default_basalt(),
|
||||||
openhmd: ProfileFeature::default_openhmd(),
|
openhmd: ProfileFeature::default_openhmd(),
|
||||||
|
@ -494,3 +515,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prepare_ld_library_path(prefix: &str) -> String {
|
||||||
|
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix)
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::APP_NAME,
|
constants::APP_NAME,
|
||||||
paths::{data_monado_path, data_opencomposite_path, get_data_dir},
|
paths::{data_monado_path, data_opencomposite_path, get_data_dir},
|
||||||
profile::{LighthouseDriver, Profile, ProfileFeatures, XRServiceType},
|
profile::{prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeatures, XRServiceType},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -15,10 +15,7 @@ pub fn lighthouse_profile() -> Profile {
|
||||||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||||
environment.insert(
|
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||||
"LD_LIBRARY_PATH".into(),
|
|
||||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
|
||||||
);
|
|
||||||
Profile {
|
Profile {
|
||||||
uuid: "lighthouse-default".into(),
|
uuid: "lighthouse-default".into(),
|
||||||
name: format!("Lighthouse Driver - {name} Default", name = APP_NAME),
|
name: format!("Lighthouse Driver - {name} Default", name = APP_NAME),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod lighthouse;
|
pub mod lighthouse;
|
||||||
pub mod openhmd;
|
pub mod openhmd;
|
||||||
|
pub mod simulated;
|
||||||
pub mod survive;
|
pub mod survive;
|
||||||
pub mod wivrn;
|
pub mod wivrn;
|
||||||
pub mod wmr;
|
pub mod wmr;
|
||||||
|
|
|
@ -2,8 +2,8 @@ use crate::{
|
||||||
constants::APP_NAME,
|
constants::APP_NAME,
|
||||||
paths::{data_monado_path, data_opencomposite_path, data_openhmd_path, get_data_dir},
|
paths::{data_monado_path, data_opencomposite_path, data_openhmd_path, get_data_dir},
|
||||||
profile::{
|
profile::{
|
||||||
LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures,
|
prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType,
|
||||||
XRServiceType,
|
ProfileFeatures, XRServiceType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -18,10 +18,7 @@ pub fn openhmd_profile() -> Profile {
|
||||||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||||
environment.insert(
|
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||||
"LD_LIBRARY_PATH".into(),
|
|
||||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
|
||||||
);
|
|
||||||
Profile {
|
Profile {
|
||||||
uuid: "openhmd-default".into(),
|
uuid: "openhmd-default".into(),
|
||||||
name: format!("OpenHMD - {name} Default", name = APP_NAME),
|
name: format!("OpenHMD - {name} Default", name = APP_NAME),
|
||||||
|
@ -34,6 +31,7 @@ pub fn openhmd_profile() -> Profile {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
path: Some(data_openhmd_path()),
|
path: Some(data_openhmd_path()),
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|
36
src/profiles/simulated.rs
Normal file
36
src/profiles/simulated.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use crate::{
|
||||||
|
constants::APP_NAME,
|
||||||
|
paths::{data_monado_path, data_opencomposite_path, get_data_dir},
|
||||||
|
profile::{Profile, ProfileFeatures, XRServiceType},
|
||||||
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub fn simulated_profile() -> Profile {
|
||||||
|
let data_dir = get_data_dir();
|
||||||
|
let prefix = format!("{data}/prefixes/simulated_default", data = data_dir);
|
||||||
|
let mut environment: HashMap<String, String> = HashMap::new();
|
||||||
|
environment.insert("QWERTY_ENABLE".into(), "1".into());
|
||||||
|
environment.insert("XRT_JSON_LOG".into(), "1".into());
|
||||||
|
environment.insert("XRT_COMPOSITOR_SCALE_PERCENTAGE".into(), "140".into());
|
||||||
|
environment.insert("XRT_COMPOSITOR_COMPUTE".into(), "1".into());
|
||||||
|
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||||
|
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||||
|
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||||
|
environment.insert(
|
||||||
|
"LD_LIBRARY_PATH".into(),
|
||||||
|
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
||||||
|
);
|
||||||
|
Profile {
|
||||||
|
uuid: "simulated-default".into(),
|
||||||
|
name: format!("Simulated Driver - {name} Default", name = APP_NAME),
|
||||||
|
xrservice_path: data_monado_path(),
|
||||||
|
xrservice_type: XRServiceType::Monado,
|
||||||
|
opencomposite_path: data_opencomposite_path(),
|
||||||
|
features: ProfileFeatures::default(),
|
||||||
|
environment,
|
||||||
|
prefix,
|
||||||
|
can_be_built: true,
|
||||||
|
editable: false,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,8 +2,8 @@ use crate::{
|
||||||
constants::APP_NAME,
|
constants::APP_NAME,
|
||||||
paths::{data_libsurvive_path, data_monado_path, data_opencomposite_path, get_data_dir},
|
paths::{data_libsurvive_path, data_monado_path, data_opencomposite_path, get_data_dir},
|
||||||
profile::{
|
profile::{
|
||||||
LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures,
|
prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType,
|
||||||
XRServiceType,
|
ProfileFeatures, XRServiceType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -20,10 +20,7 @@ pub fn survive_profile() -> Profile {
|
||||||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||||
environment.insert(
|
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||||
"LD_LIBRARY_PATH".into(),
|
|
||||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
|
||||||
);
|
|
||||||
Profile {
|
Profile {
|
||||||
uuid: "survive-default".into(),
|
uuid: "survive-default".into(),
|
||||||
name: format!("Survive - {name} Default", name = APP_NAME),
|
name: format!("Survive - {name} Default", name = APP_NAME),
|
||||||
|
@ -36,6 +33,7 @@ pub fn survive_profile() -> Profile {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
path: Some(data_libsurvive_path()),
|
path: Some(data_libsurvive_path()),
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::APP_NAME,
|
constants::APP_NAME,
|
||||||
paths::{data_opencomposite_path, data_wivrn_path, get_data_dir},
|
paths::{data_opencomposite_path, data_wivrn_path, get_data_dir},
|
||||||
profile::{Profile, ProfileFeatures, XRServiceType},
|
profile::{prepare_ld_library_path, Profile, ProfileFeatures, XRServiceType},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -9,10 +9,7 @@ pub fn wivrn_profile() -> Profile {
|
||||||
let data_dir = get_data_dir();
|
let data_dir = get_data_dir();
|
||||||
let prefix = format!("{data}/prefixes/wivrn_default", data = data_dir);
|
let prefix = format!("{data}/prefixes/wivrn_default", data = data_dir);
|
||||||
let mut environment: HashMap<String, String> = HashMap::new();
|
let mut environment: HashMap<String, String> = HashMap::new();
|
||||||
environment.insert(
|
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||||
"LD_LIBRARY_PATH".into(),
|
|
||||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
|
||||||
);
|
|
||||||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||||
|
|
|
@ -2,8 +2,8 @@ use crate::{
|
||||||
constants::APP_NAME,
|
constants::APP_NAME,
|
||||||
paths::{data_basalt_path, data_monado_path, data_opencomposite_path, get_data_dir},
|
paths::{data_basalt_path, data_monado_path, data_opencomposite_path, get_data_dir},
|
||||||
profile::{
|
profile::{
|
||||||
LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures,
|
prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType,
|
||||||
XRServiceType,
|
ProfileFeatures, XRServiceType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -18,10 +18,7 @@ pub fn wmr_profile() -> Profile {
|
||||||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||||
environment.insert(
|
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||||
"LD_LIBRARY_PATH".into(),
|
|
||||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
|
||||||
);
|
|
||||||
Profile {
|
Profile {
|
||||||
uuid: "wmr-default".into(),
|
uuid: "wmr-default".into(),
|
||||||
name: format!("WMR - {name} Default", name = APP_NAME),
|
name: format!("WMR - {name} Default", name = APP_NAME),
|
||||||
|
@ -34,6 +31,7 @@ pub fn wmr_profile() -> Profile {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
path: Some(data_basalt_path()),
|
path: Some(data_basalt_path()),
|
||||||
repo: None,
|
repo: None,
|
||||||
|
branch: None,
|
||||||
},
|
},
|
||||||
mercury_enabled: true,
|
mercury_enabled: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -40,6 +40,7 @@ use crate::paths::{get_data_dir, get_ipc_file_path};
|
||||||
use crate::profile::{Profile, XRServiceType};
|
use crate::profile::{Profile, XRServiceType};
|
||||||
use crate::profiles::lighthouse::lighthouse_profile;
|
use crate::profiles::lighthouse::lighthouse_profile;
|
||||||
use crate::profiles::openhmd::openhmd_profile;
|
use crate::profiles::openhmd::openhmd_profile;
|
||||||
|
use crate::profiles::simulated::simulated_profile;
|
||||||
use crate::profiles::survive::survive_profile;
|
use crate::profiles::survive::survive_profile;
|
||||||
use crate::profiles::wivrn::wivrn_profile;
|
use crate::profiles::wivrn::wivrn_profile;
|
||||||
use crate::profiles::wmr::wmr_profile;
|
use crate::profiles::wmr::wmr_profile;
|
||||||
|
@ -256,6 +257,7 @@ impl App {
|
||||||
wivrn_profile(),
|
wivrn_profile(),
|
||||||
wmr_profile(),
|
wmr_profile(),
|
||||||
openhmd_profile(),
|
openhmd_profile(),
|
||||||
|
simulated_profile(),
|
||||||
];
|
];
|
||||||
profiles.extend(config.user_profiles.clone());
|
profiles.extend(config.user_profiles.clone());
|
||||||
profiles.sort_unstable_by(|a, b| a.name.cmp(&b.name));
|
profiles.sort_unstable_by(|a, b| a.name.cmp(&b.name));
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use super::term_widget::TermWidget;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
|
|
||||||
|
@ -11,20 +12,15 @@ pub enum BuildStatus {
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct BuildWindow {
|
pub struct BuildWindow {
|
||||||
title: String,
|
title: String,
|
||||||
content: String,
|
|
||||||
can_close: bool,
|
can_close: bool,
|
||||||
build_status: BuildStatus,
|
build_status: BuildStatus,
|
||||||
|
|
||||||
#[tracker::do_not_track]
|
|
||||||
pub textbuf: gtk::TextBuffer,
|
|
||||||
#[tracker::do_not_track]
|
|
||||||
pub textview: Option<gtk::TextView>,
|
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
pub win: Option<adw::Window>,
|
pub win: Option<adw::Window>,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
build_status_label: Option<gtk::Label>,
|
build_status_label: Option<gtk::Label>,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
scrolledwin: Option<gtk::ScrolledWindow>,
|
term: TermWidget,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -108,26 +104,7 @@ impl SimpleComponent for BuildWindow {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
#[name(scrolledwin)]
|
model.term.container.clone(),
|
||||||
gtk::ScrolledWindow {
|
|
||||||
set_hexpand: true,
|
|
||||||
set_vexpand: true,
|
|
||||||
set_margin_all: 12,
|
|
||||||
add_css_class: "card",
|
|
||||||
set_overflow: gtk::Overflow::Hidden,
|
|
||||||
#[name(textview)]
|
|
||||||
gtk::TextView {
|
|
||||||
set_hexpand: true,
|
|
||||||
set_vexpand: true,
|
|
||||||
set_editable: false,
|
|
||||||
set_monospace: true,
|
|
||||||
set_left_margin: 6,
|
|
||||||
set_right_margin: 6,
|
|
||||||
set_top_margin: 6,
|
|
||||||
set_bottom_margin: 6,
|
|
||||||
set_buffer: Some(&model.textbuf),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
add_bottom_bar: bottom_bar = >k::Button {
|
add_bottom_bar: bottom_bar = >k::Button {
|
||||||
add_css_class: "pill",
|
add_css_class: "pill",
|
||||||
|
@ -150,10 +127,10 @@ impl SimpleComponent for BuildWindow {
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
Self::Input::Present => {
|
Self::Input::Present => {
|
||||||
self.win.as_ref().unwrap().present();
|
self.term.set_color_scheme();
|
||||||
sender.input(BuildWindowMsg::UpdateBuildStatus(BuildStatus::Building));
|
sender.input(BuildWindowMsg::UpdateBuildStatus(BuildStatus::Building));
|
||||||
self.set_content("".into());
|
self.term.clear();
|
||||||
self.textbuf.set_text("");
|
self.win.as_ref().unwrap().present();
|
||||||
}
|
}
|
||||||
Self::Input::UpdateTitle(t) => {
|
Self::Input::UpdateTitle(t) => {
|
||||||
self.set_title(t);
|
self.set_title(t);
|
||||||
|
@ -161,17 +138,7 @@ impl SimpleComponent for BuildWindow {
|
||||||
Self::Input::UpdateContent(c) => {
|
Self::Input::UpdateContent(c) => {
|
||||||
if !c.is_empty() {
|
if !c.is_empty() {
|
||||||
let n_lines = c.concat();
|
let n_lines = c.concat();
|
||||||
let mut n_content = self.content.clone();
|
self.term.feed(&n_lines);
|
||||||
n_content.push_str(n_lines.as_str());
|
|
||||||
self.set_content(n_content);
|
|
||||||
self.textbuf
|
|
||||||
.insert(&mut self.textbuf.end_iter(), n_lines.as_str());
|
|
||||||
let textbuf = self.textbuf.clone();
|
|
||||||
let textview = self.textview.as_ref().unwrap().clone();
|
|
||||||
gtk::glib::idle_add_local_once(move || {
|
|
||||||
let end_mark = textbuf.create_mark(None, &textbuf.end_iter(), false);
|
|
||||||
textview.scroll_mark_onscreen(&end_mark);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Input::UpdateBuildStatus(status) => {
|
Self::Input::UpdateBuildStatus(status) => {
|
||||||
|
@ -202,20 +169,21 @@ impl SimpleComponent for BuildWindow {
|
||||||
let mut model = Self {
|
let mut model = Self {
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
title: "".into(),
|
title: "".into(),
|
||||||
content: "".into(),
|
|
||||||
can_close: false,
|
can_close: false,
|
||||||
textbuf: gtk::TextBuffer::builder().enable_undo(false).build(),
|
|
||||||
textview: None,
|
|
||||||
build_status: BuildStatus::Building,
|
build_status: BuildStatus::Building,
|
||||||
win: None,
|
win: None,
|
||||||
scrolledwin: None,
|
|
||||||
build_status_label: None,
|
build_status_label: None,
|
||||||
|
term: {
|
||||||
|
let t = TermWidget::new();
|
||||||
|
t.container.add_css_class("card");
|
||||||
|
t.container.set_margin_all(12);
|
||||||
|
t.container.set_overflow(gtk::Overflow::Hidden);
|
||||||
|
t
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
model.win = Some(widgets.win.clone());
|
model.win = Some(widgets.win.clone());
|
||||||
model.build_status_label = Some(widgets.build_status_label.clone());
|
model.build_status_label = Some(widgets.build_status_label.clone());
|
||||||
model.textview = Some(widgets.textview.clone());
|
|
||||||
model.scrolledwin = Some(widgets.scrolledwin.clone());
|
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ use gtk::glib::clone;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
use relm4::{ComponentSender, SimpleComponent};
|
use relm4::{ComponentSender, SimpleComponent};
|
||||||
use zoha_vte4::{Terminal, TerminalExt};
|
use zoha_vte4::TerminalExt;
|
||||||
|
|
||||||
|
use super::term_widget::TermWidget;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SearchDirection {
|
pub enum SearchDirection {
|
||||||
|
@ -37,13 +39,11 @@ pub struct DebugView {
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
log_level: LogLevel,
|
log_level: LogLevel,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
vte_terminal: Terminal,
|
term: TermWidget,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DebugViewInit {}
|
pub struct DebugViewInit {}
|
||||||
|
|
||||||
const MAX_SCROLLBACK: u32 = 2000;
|
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for DebugView {
|
impl SimpleComponent for DebugView {
|
||||||
type Init = DebugViewInit;
|
type Init = DebugViewInit;
|
||||||
|
@ -115,16 +115,11 @@ impl SimpleComponent for DebugView {
|
||||||
},
|
},
|
||||||
connect_entry: &search_entry,
|
connect_entry: &search_entry,
|
||||||
},
|
},
|
||||||
#[wrap(Some)]
|
set_content: Some(&model.term.container),
|
||||||
set_content: sw = >k::ScrolledWindow {
|
|
||||||
set_hexpand: true,
|
|
||||||
set_vexpand: true,
|
|
||||||
model.vte_terminal.clone(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
|
@ -142,19 +137,17 @@ impl SimpleComponent for DebugView {
|
||||||
let search_entry = self.search_entry.as_ref().unwrap().clone();
|
let search_entry = self.search_entry.as_ref().unwrap().clone();
|
||||||
let search_text = search_entry.text().to_string();
|
let search_text = search_entry.text().to_string();
|
||||||
if searchbar.is_search_mode() && !search_text.is_empty() {
|
if searchbar.is_search_mode() && !search_text.is_empty() {
|
||||||
if let Ok(regex) = zoha_vte4::Regex::for_search(&search_text, 0) {
|
self.term.set_search_term(Some(&search_text));
|
||||||
self.vte_terminal.search_set_regex(Some(®ex), 0);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self.vte_terminal.search_set_regex(None, 0);
|
self.term.set_search_term(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Input::SearchFindMatch(direction) => match direction {
|
Self::Input::SearchFindMatch(direction) => match direction {
|
||||||
SearchDirection::Forward => {
|
SearchDirection::Forward => {
|
||||||
self.vte_terminal.search_find_next();
|
self.term.search_next();
|
||||||
}
|
}
|
||||||
SearchDirection::Backward => {
|
SearchDirection::Backward => {
|
||||||
self.vte_terminal.search_find_previous();
|
self.term.search_prev();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Self::Input::LogUpdated(n_log) => {
|
Self::Input::LogUpdated(n_log) => {
|
||||||
|
@ -173,15 +166,15 @@ impl SimpleComponent for DebugView {
|
||||||
None => Some(row),
|
None => Some(row),
|
||||||
};
|
};
|
||||||
if let Some(t) = txt {
|
if let Some(t) = txt {
|
||||||
self.vte_terminal.feed(t.as_bytes())
|
self.term.feed(&t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Input::ClearLog => {
|
Self::Input::ClearLog => {
|
||||||
self.vte_terminal.feed("\x1bc".as_bytes());
|
self.term.clear();
|
||||||
}
|
}
|
||||||
Self::Input::SetColorScheme => {
|
Self::Input::SetColorScheme => {
|
||||||
Self::set_color_scheme(&self.vte_terminal);
|
self.term.set_color_scheme();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,24 +216,13 @@ impl SimpleComponent for DebugView {
|
||||||
search_entry: None,
|
search_entry: None,
|
||||||
dropdown: None,
|
dropdown: None,
|
||||||
log_level: LogLevel::Trace,
|
log_level: LogLevel::Trace,
|
||||||
vte_terminal: {
|
term: TermWidget::new(),
|
||||||
let t = Terminal::builder()
|
|
||||||
.scroll_on_output(true)
|
|
||||||
.scrollback_lines(MAX_SCROLLBACK)
|
|
||||||
.scroll_unit_is_pixels(true)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
t.set_clear_background(false);
|
|
||||||
t.search_set_wrap_around(true);
|
|
||||||
Self::set_color_scheme(&t);
|
|
||||||
t
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
model.term.set_color_scheme();
|
||||||
|
|
||||||
{
|
{
|
||||||
let sc = gtk::ShortcutController::new();
|
let sc = gtk::ShortcutController::new();
|
||||||
let term = model.vte_terminal.clone();
|
let term = model.term.term.clone();
|
||||||
sc.add_shortcut(gtk::Shortcut::new(
|
sc.add_shortcut(gtk::Shortcut::new(
|
||||||
gtk::ShortcutTrigger::parse_string("<Control>c"),
|
gtk::ShortcutTrigger::parse_string("<Control>c"),
|
||||||
Some(gtk::CallbackAction::new(move |_, _| {
|
Some(gtk::CallbackAction::new(move |_, _| {
|
||||||
|
@ -250,7 +232,7 @@ impl SimpleComponent for DebugView {
|
||||||
true
|
true
|
||||||
})),
|
})),
|
||||||
));
|
));
|
||||||
let term = model.vte_terminal.clone();
|
let term = model.term.term.clone();
|
||||||
sc.add_shortcut(gtk::Shortcut::new(
|
sc.add_shortcut(gtk::Shortcut::new(
|
||||||
gtk::ShortcutTrigger::parse_string("<Control>a"),
|
gtk::ShortcutTrigger::parse_string("<Control>a"),
|
||||||
Some(gtk::CallbackAction::new(move |_, _| {
|
Some(gtk::CallbackAction::new(move |_, _| {
|
||||||
|
@ -258,7 +240,7 @@ impl SimpleComponent for DebugView {
|
||||||
true
|
true
|
||||||
})),
|
})),
|
||||||
));
|
));
|
||||||
model.vte_terminal.add_controller(sc);
|
model.term.term.add_controller(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
@ -269,13 +251,3 @@ impl SimpleComponent for DebugView {
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugView {
|
|
||||||
fn set_color_scheme(term: &Terminal) {
|
|
||||||
if adw::StyleManager::default().is_dark() {
|
|
||||||
term.set_color_foreground(>k::gdk::RGBA::new(1.0, 1.0, 1.0, 1.0));
|
|
||||||
} else {
|
|
||||||
term.set_color_foreground(>k::gdk::RGBA::new(0.0, 0.0, 0.0, 1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
||||||
file_builders::wivrn_config::{Codec, Encoder, WivrnConfEncoder},
|
file_builders::wivrn_config::{Codec, Encoder, WivrnConfEncoder},
|
||||||
ui::{
|
ui::{
|
||||||
preference_rows::{combo_row, number_entry_row, spin_row},
|
preference_rows::{combo_row, number_entry_row, spin_row},
|
||||||
|
util::{bits_from_mbits, bits_to_mbits},
|
||||||
wivrn_conf_editor::WivrnConfEditorMsg,
|
wivrn_conf_editor::WivrnConfEditorMsg,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -24,6 +25,8 @@ pub enum WivrnEncoderModelMsg {
|
||||||
BitrateChanged(Option<u32>),
|
BitrateChanged(Option<u32>),
|
||||||
WidthChanged(Option<f32>),
|
WidthChanged(Option<f32>),
|
||||||
HeightChanged(Option<f32>),
|
HeightChanged(Option<f32>),
|
||||||
|
OffsetXChanged(Option<f32>),
|
||||||
|
OffsetYChanged(Option<f32>),
|
||||||
GroupChanged(Option<i32>),
|
GroupChanged(Option<i32>),
|
||||||
Delete,
|
Delete,
|
||||||
}
|
}
|
||||||
|
@ -83,9 +86,13 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
||||||
}
|
}
|
||||||
) -> adw::ComboRow,
|
) -> adw::ComboRow,
|
||||||
add: bitrate_row = &number_entry_row(
|
add: bitrate_row = &number_entry_row(
|
||||||
"Bitrate",
|
"Bitrate (Mbps)",
|
||||||
&self.encoder_conf.bitrate
|
&self.encoder_conf.bitrate
|
||||||
.and_then(|n| Some(n.to_string()))
|
.and_then(|n| if let Some(mbits) = bits_to_mbits(n) {
|
||||||
|
Some(mbits.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
false,
|
false,
|
||||||
{
|
{
|
||||||
|
@ -96,7 +103,10 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
||||||
if txt.is_empty() {
|
if txt.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(txt.parse::<u32>().unwrap())
|
match txt.parse::<u32>() {
|
||||||
|
Ok(bits) => bits_from_mbits(bits),
|
||||||
|
Err(e) => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -134,6 +144,38 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) -> adw::SpinRow,
|
) -> adw::SpinRow,
|
||||||
|
add: offset_x_row = &spin_row(
|
||||||
|
"Offset X",
|
||||||
|
None,
|
||||||
|
self.encoder_conf.offset_x.unwrap_or(0.0).into(),
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
0.01,
|
||||||
|
{
|
||||||
|
let sender = sender.clone();
|
||||||
|
move |adj| {
|
||||||
|
sender.input(Self::Input::OffsetXChanged(
|
||||||
|
Some(adj.value() as f32)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) -> adw::SpinRow,
|
||||||
|
add: offset_y_row = &spin_row(
|
||||||
|
"Offset Y",
|
||||||
|
None,
|
||||||
|
self.encoder_conf.offset_y.unwrap_or(0.0).into(),
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
0.01,
|
||||||
|
{
|
||||||
|
let sender = sender.clone();
|
||||||
|
move |adj| {
|
||||||
|
sender.input(Self::Input::OffsetYChanged(
|
||||||
|
Some(adj.value() as f32)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) -> adw::SpinRow,
|
||||||
add: group_row = &spin_row(
|
add: group_row = &spin_row(
|
||||||
"Group",
|
"Group",
|
||||||
None,
|
None,
|
||||||
|
@ -170,6 +212,12 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
||||||
Self::Input::HeightChanged(val) => {
|
Self::Input::HeightChanged(val) => {
|
||||||
self.encoder_conf.height = val;
|
self.encoder_conf.height = val;
|
||||||
}
|
}
|
||||||
|
Self::Input::OffsetXChanged(val) => {
|
||||||
|
self.encoder_conf.offset_x = val;
|
||||||
|
}
|
||||||
|
Self::Input::OffsetYChanged(val) => {
|
||||||
|
self.encoder_conf.offset_y = val;
|
||||||
|
}
|
||||||
Self::Input::GroupChanged(val) => {
|
Self::Input::GroupChanged(val) => {
|
||||||
self.encoder_conf.group = val;
|
self.encoder_conf.group = val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,11 +174,11 @@ impl InternalJobWorker {
|
||||||
let mut launch_opts = prof.xrservice_launch_options.trim();
|
let mut launch_opts = prof.xrservice_launch_options.trim();
|
||||||
let debug_launch_opts = if debug {
|
let debug_launch_opts = if debug {
|
||||||
if launch_opts.contains(LAUNCH_OPTS_CMD_PLACEHOLDER) {
|
if launch_opts.contains(LAUNCH_OPTS_CMD_PLACEHOLDER) {
|
||||||
format!("{} {}", "gdb -batch -ex run -ex bt --args", launch_opts)
|
format!("{} {}", "gdbserver localhost:9000", launch_opts)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"{} {} {}",
|
"{} {} {}",
|
||||||
"gdb -batch -ex run -ex bt --args", LAUNCH_OPTS_CMD_PLACEHOLDER, launch_opts
|
"gdbserver localhost:9000", LAUNCH_OPTS_CMD_PLACEHOLDER, launch_opts
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
use crate::{cmd_runner::CmdRunner, profile::Profile, runner::Runner};
|
use super::alert::alert;
|
||||||
|
use crate::{
|
||||||
|
cmd_runner::CmdRunner,
|
||||||
|
profile::{prepare_ld_library_path, Profile},
|
||||||
|
runner::Runner,
|
||||||
|
};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
use std::{cell::Cell, collections::HashMap, path::Path, rc::Rc, time::Duration};
|
use std::{cell::Cell, collections::HashMap, path::Path, rc::Rc, time::Duration};
|
||||||
|
|
||||||
use super::alert::alert;
|
|
||||||
|
|
||||||
const NO_FILE_MSG: &str = "(No file selected)";
|
const NO_FILE_MSG: &str = "(No file selected)";
|
||||||
const CALIBRATION_RUN_TIME_SECONDS: f64 = 30.0;
|
const CALIBRATION_RUN_TIME_SECONDS: f64 = 30.0;
|
||||||
|
|
||||||
|
@ -57,9 +60,10 @@ impl LibsurviveSetupWindow {
|
||||||
fn create_calibration_runner(&mut self, survive_cli_path: String) -> CmdRunner {
|
fn create_calibration_runner(&mut self, survive_cli_path: String) -> CmdRunner {
|
||||||
let lh_path = self.steam_lighthouse_path.clone();
|
let lh_path = self.steam_lighthouse_path.clone();
|
||||||
let mut env = HashMap::new();
|
let mut env = HashMap::new();
|
||||||
|
let profile_prefix = &self.profile.as_ref().unwrap().prefix;
|
||||||
env.insert(
|
env.insert(
|
||||||
"LD_LIBRARY_PATH".to_string(),
|
"LD_LIBRARY_PATH".into(),
|
||||||
format!("{pfx}/lib", pfx = self.profile.as_ref().unwrap().prefix),
|
prepare_ld_library_path(&profile_prefix),
|
||||||
);
|
);
|
||||||
CmdRunner::new(
|
CmdRunner::new(
|
||||||
Some(env),
|
Some(env),
|
||||||
|
|
|
@ -185,7 +185,7 @@ impl SimpleComponent for MainView {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
set_label: "Start with GDB",
|
set_label: "Start with gdbserver",
|
||||||
#[track = "model.changed(Self::xrservice_active()) || model.changed(Self::enable_debug_view())"]
|
#[track = "model.changed(Self::xrservice_active()) || model.changed(Self::enable_debug_view())"]
|
||||||
set_visible: model.enable_debug_view && !model.xrservice_active,
|
set_visible: model.enable_debug_view && !model.xrservice_active,
|
||||||
connect_clicked[sender] => move |_| {
|
connect_clicked[sender] => move |_| {
|
||||||
|
|
|
@ -16,5 +16,6 @@ pub mod profile_editor;
|
||||||
pub mod stardust;
|
pub mod stardust;
|
||||||
pub mod steam_launch_options_box;
|
pub mod steam_launch_options_box;
|
||||||
mod steamvr_calibration_box;
|
mod steamvr_calibration_box;
|
||||||
|
pub mod term_widget;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod wivrn_conf_editor;
|
pub mod wivrn_conf_editor;
|
||||||
|
|
|
@ -176,6 +176,14 @@ impl SimpleComponent for ProfileEditor {
|
||||||
prof.borrow_mut().xrservice_repo = (!n_val.is_empty()).then_some(n_val);
|
prof.borrow_mut().xrservice_repo = (!n_val.is_empty()).then_some(n_val);
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
add: &entry_row(
|
||||||
|
"XR Service Branch",
|
||||||
|
model.profile.borrow().xrservice_branch.clone().unwrap_or_default().as_str(),
|
||||||
|
clone!(@strong prof => move |row| {
|
||||||
|
let n_val = row.text().to_string();
|
||||||
|
prof.borrow_mut().xrservice_branch = (!n_val.is_empty()).then_some(n_val);
|
||||||
|
})
|
||||||
|
),
|
||||||
},
|
},
|
||||||
add: model.xrservice_cmake_flags_rows.widget(),
|
add: model.xrservice_cmake_flags_rows.widget(),
|
||||||
add: opencompgrp = &adw::PreferencesGroup {
|
add: opencompgrp = &adw::PreferencesGroup {
|
||||||
|
@ -197,6 +205,14 @@ impl SimpleComponent for ProfileEditor {
|
||||||
prof.borrow_mut().opencomposite_repo = (!n_val.is_empty()).then_some(n_val);
|
prof.borrow_mut().opencomposite_repo = (!n_val.is_empty()).then_some(n_val);
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
add: &entry_row(
|
||||||
|
"OpenComposite Branch",
|
||||||
|
model.profile.borrow().opencomposite_branch.clone().unwrap_or_default().as_str(),
|
||||||
|
clone!(@strong prof => move |row| {
|
||||||
|
let n_val = row.text().to_string();
|
||||||
|
prof.borrow_mut().opencomposite_branch = (!n_val.is_empty()).then_some(n_val);
|
||||||
|
})
|
||||||
|
),
|
||||||
},
|
},
|
||||||
add: libsurvivegrp = &adw::PreferencesGroup {
|
add: libsurvivegrp = &adw::PreferencesGroup {
|
||||||
set_title: "Libsurvive",
|
set_title: "Libsurvive",
|
||||||
|
@ -225,6 +241,14 @@ impl SimpleComponent for ProfileEditor {
|
||||||
prof.borrow_mut().features.libsurvive.repo = (!n_val.is_empty()).then_some(n_val);
|
prof.borrow_mut().features.libsurvive.repo = (!n_val.is_empty()).then_some(n_val);
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
add: &entry_row(
|
||||||
|
"Libsurvive Branch",
|
||||||
|
model.profile.borrow().features.libsurvive.branch.clone().unwrap_or_default().as_str(),
|
||||||
|
clone!(@strong prof => move |row| {
|
||||||
|
let n_val = row.text().to_string();
|
||||||
|
prof.borrow_mut().features.libsurvive.branch = (!n_val.is_empty()).then_some(n_val);
|
||||||
|
})
|
||||||
|
),
|
||||||
},
|
},
|
||||||
add: openhmdgrp = &adw::PreferencesGroup {
|
add: openhmdgrp = &adw::PreferencesGroup {
|
||||||
set_title: "OpenHMD",
|
set_title: "OpenHMD",
|
||||||
|
@ -253,6 +277,14 @@ impl SimpleComponent for ProfileEditor {
|
||||||
prof.borrow_mut().features.openhmd.repo = (!n_val.is_empty()).then_some(n_val);
|
prof.borrow_mut().features.openhmd.repo = (!n_val.is_empty()).then_some(n_val);
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
add: &entry_row(
|
||||||
|
"OpenHMD Branch",
|
||||||
|
model.profile.borrow().features.openhmd.branch.clone().unwrap_or_default().as_str(),
|
||||||
|
clone!(@strong prof => move |row| {
|
||||||
|
let n_val = row.text().to_string();
|
||||||
|
prof.borrow_mut().features.openhmd.branch = (!n_val.is_empty()).then_some(n_val);
|
||||||
|
})
|
||||||
|
),
|
||||||
},
|
},
|
||||||
add: basaltgrp = &adw::PreferencesGroup {
|
add: basaltgrp = &adw::PreferencesGroup {
|
||||||
set_title: "Basalt",
|
set_title: "Basalt",
|
||||||
|
@ -281,6 +313,14 @@ impl SimpleComponent for ProfileEditor {
|
||||||
prof.borrow_mut().features.basalt.repo = n_val.is_empty().then_some(n_val);
|
prof.borrow_mut().features.basalt.repo = n_val.is_empty().then_some(n_val);
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
add: &entry_row(
|
||||||
|
"Basalt Branch",
|
||||||
|
model.profile.borrow().features.basalt.branch.clone().unwrap_or_default().as_str(),
|
||||||
|
clone!(@strong prof => move |row| {
|
||||||
|
let n_val = row.text().to_string();
|
||||||
|
prof.borrow_mut().features.basalt.branch = n_val.is_empty().then_some(n_val);
|
||||||
|
})
|
||||||
|
),
|
||||||
},
|
},
|
||||||
add: mercurygrp = &adw::PreferencesGroup {
|
add: mercurygrp = &adw::PreferencesGroup {
|
||||||
set_title: "Mercury",
|
set_title: "Mercury",
|
||||||
|
|
68
src/ui/term_widget.rs
Normal file
68
src/ui/term_widget.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
use gtk4::gdk;
|
||||||
|
use relm4::adw;
|
||||||
|
use zoha_vte4::{Terminal, TerminalExt};
|
||||||
|
|
||||||
|
const MAX_SCROLLBACK: u32 = 2000;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TermWidget {
|
||||||
|
pub container: gtk4::ScrolledWindow,
|
||||||
|
pub term: Terminal,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TermWidget {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let term = Terminal::builder()
|
||||||
|
.scroll_on_output(true)
|
||||||
|
.scrollback_lines(MAX_SCROLLBACK)
|
||||||
|
.scroll_unit_is_pixels(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
term.set_clear_background(false);
|
||||||
|
term.search_set_wrap_around(true);
|
||||||
|
let container = gtk4::ScrolledWindow::builder()
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.child(&term)
|
||||||
|
.build();
|
||||||
|
let this = Self { container, term };
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_color_scheme(&self) {
|
||||||
|
// TODO: use theme colors
|
||||||
|
if adw::StyleManager::default().is_dark() {
|
||||||
|
self.term
|
||||||
|
.set_color_foreground(&gdk::RGBA::new(1.0, 1.0, 1.0, 1.0));
|
||||||
|
} else {
|
||||||
|
self.term
|
||||||
|
.set_color_foreground(&gdk::RGBA::new(0.0, 0.0, 0.0, 1.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn feed(&self, txt: &str) {
|
||||||
|
self.term.feed(txt.replace('\n', "\r\n").as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&self) {
|
||||||
|
self.term.feed("\x1bc".as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_search_term(&self, term: Option<&str>) {
|
||||||
|
self.term.search_set_regex(
|
||||||
|
term.map(|txt| zoha_vte4::Regex::for_search(txt, 0).ok())
|
||||||
|
.flatten()
|
||||||
|
.as_ref(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn search_next(&self) {
|
||||||
|
self.term.search_find_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn search_prev(&self) {
|
||||||
|
self.term.search_find_previous();
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,3 +61,11 @@ pub fn copy_text(txt: &str) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bits_to_mbits(bits: u32) -> Option<u32> {
|
||||||
|
bits.checked_div(1000000)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bits_from_mbits(mbits: u32) -> Option<u32> {
|
||||||
|
mbits.checked_mul(1000000)
|
||||||
|
}
|
||||||
|
|
|
@ -4,20 +4,24 @@
|
||||||
"xrservice_type": "Monado",
|
"xrservice_type": "Monado",
|
||||||
"xrservice_path": "/home/user/monado",
|
"xrservice_path": "/home/user/monado",
|
||||||
"xrservice_repo": null,
|
"xrservice_repo": null,
|
||||||
|
"xrservice_branch": null,
|
||||||
"opencomposite_path": "/home/user/opencomposite",
|
"opencomposite_path": "/home/user/opencomposite",
|
||||||
"opencomposite_repo": null,
|
"opencomposite_repo": null,
|
||||||
|
"opencomposite_branch": null,
|
||||||
"features": {
|
"features": {
|
||||||
"libsurvive": {
|
"libsurvive": {
|
||||||
"feature_type": "Libsurvive",
|
"feature_type": "Libsurvive",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"path": "/home/user/libsurvive",
|
"path": "/home/user/libsurvive",
|
||||||
"repo": null
|
"repo": null,
|
||||||
|
"branch": null
|
||||||
},
|
},
|
||||||
"basalt": {
|
"basalt": {
|
||||||
"feature_type": "Basalt",
|
"feature_type": "Basalt",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"path": null,
|
"path": null,
|
||||||
"repo": null
|
"repo": null,
|
||||||
|
"branch": null
|
||||||
},
|
},
|
||||||
"mercury_enabled": false
|
"mercury_enabled": false
|
||||||
},
|
},
|
||||||
|
@ -30,4 +34,4 @@
|
||||||
"can_be_built": true,
|
"can_be_built": true,
|
||||||
"editable": true,
|
"editable": true,
|
||||||
"pull_on_build": true
|
"pull_on_build": true
|
||||||
}
|
}
|
|
@ -6,7 +6,9 @@
|
||||||
"codec": "h264",
|
"codec": "h264",
|
||||||
"bitrate": 100000000,
|
"bitrate": 100000000,
|
||||||
"width": 1.0,
|
"width": 1.0,
|
||||||
"height": 1.0
|
"height": 1.0,
|
||||||
|
"offset_x": 0.0,
|
||||||
|
"offset_y": 0.0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue