mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-08-06 16:18:53 +00:00
feat: stub stardust section in main view
This commit is contained in:
parent
c76293eea5
commit
ece8da4210
4 changed files with 277 additions and 214 deletions
|
@ -2,9 +2,9 @@ use super::alert::alert;
|
|||
use super::devices_box::{DevicesBox, DevicesBoxMsg};
|
||||
use super::install_wivrn_box::{InstallWivrnBox, InstallWivrnBoxInit, InstallWivrnBoxMsg};
|
||||
use super::profile_editor::{ProfileEditor, ProfileEditorMsg, ProfileEditorOutMsg};
|
||||
use super::stardust::stardust_view::StardustView;
|
||||
use super::steam_launch_options_box::{SteamLaunchOptionsBox, SteamLaunchOptionsBoxMsg};
|
||||
use crate::config::Config;
|
||||
use crate::constants::APP_NAME;
|
||||
use crate::file_utils::mount_has_nosuid;
|
||||
use crate::gpu_profile::{
|
||||
get_amd_gpu_power_profile, get_first_amd_gpu, get_set_amd_vr_pow_prof_cmd, GpuPowerProfile,
|
||||
|
@ -48,6 +48,8 @@ pub struct MainView {
|
|||
profile_editor: Option<Controller<ProfileEditor>>,
|
||||
#[tracker::do_not_track]
|
||||
root_win: gtk::Window,
|
||||
#[tracker::do_not_track]
|
||||
stardust_view: Controller<StardustView>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -146,234 +148,241 @@ impl SimpleComponent for MainView {
|
|||
},
|
||||
},
|
||||
#[wrap(Some)]
|
||||
set_content: content = >k::ScrolledWindow {
|
||||
set_hscrollbar_policy: gtk::PolicyType::Never,
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
adw::Clamp {
|
||||
set_maximum_size: 600,
|
||||
gtk::Box {
|
||||
set_spacing: 12,
|
||||
set_margin_all: 12,
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_content: section_stack = &adw::ViewStack {
|
||||
add: main_page = >k::ScrolledWindow {
|
||||
set_hscrollbar_policy: gtk::PolicyType::Never,
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
adw::Clamp {
|
||||
set_maximum_size: 600,
|
||||
gtk::Box {
|
||||
set_hexpand: true,
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
add_css_class: "linked",
|
||||
gtk::Button {
|
||||
add_css_class: "suggested-action",
|
||||
add_css_class: "destructive-action",
|
||||
set_hexpand: true,
|
||||
#[track = "model.changed(Self::xrservice_active())"]
|
||||
set_class_active: ("suggested-action", !model.xrservice_active),
|
||||
#[track = "model.changed(Self::xrservice_active())"]
|
||||
set_label: match model.xrservice_active {
|
||||
true => "Stop",
|
||||
false => "Start",
|
||||
},
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(MainViewMsg::StartStopClicked);
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_label: "Start with GDB",
|
||||
#[track = "model.changed(Self::xrservice_active()) || model.changed(Self::enable_debug_view())"]
|
||||
set_visible: model.enable_debug_view && !model.xrservice_active,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(MainViewMsg::StartWithDebug);
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_halign: gtk::Align::Center,
|
||||
set_valign: gtk::Align::Center,
|
||||
set_icon_name: "view-refresh-symbolic",
|
||||
set_tooltip_text: Some("Restart"),
|
||||
#[track = "model.changed(Self::xrservice_active())"]
|
||||
set_visible: model.xrservice_active,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(MainViewMsg::RestartXRService)
|
||||
},
|
||||
},
|
||||
},
|
||||
model.devices_box.widget(),
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: match mount_has_nosuid(model.selected_profile.prefix.as_str()) {
|
||||
Ok(b) => b,
|
||||
Err(_) => {
|
||||
// TODO: handle this error better
|
||||
println!(
|
||||
"Warning: could not get stat on path {}",
|
||||
model.selected_profile.prefix);
|
||||
false
|
||||
},
|
||||
},
|
||||
warning_heading(),
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"Your current prefix is inside a partition ",
|
||||
"mounted with the nosuid option. This will prevent ",
|
||||
"the Envision runtime from acquiring certain privileges ",
|
||||
"and will cause noticeable stutter when running XR ",
|
||||
"applications."
|
||||
),
|
||||
add_css_class: "warning",
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_margin_all: 12,
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: model.selected_profile.lighthouse_driver == LighthouseDriver::SteamVR && !chaperone_info_exists(),
|
||||
warning_heading(),
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"SteamVR room configuration not found.\n",
|
||||
"To use the SteamVR lighthouse driver, you ",
|
||||
"will need to run SteamVR and perform the room setup.",
|
||||
),
|
||||
add_css_class: "warning",
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: match get_amd_gpu_power_profile() {
|
||||
None => false,
|
||||
Some(GpuPowerProfile::VR) => false,
|
||||
Some(_) => true,
|
||||
},
|
||||
warning_heading(),
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"Your AMD GPU Power Profile is not set to VR. ",
|
||||
"This will cause noticeable stutter when running XR ",
|
||||
"applications. Activate the VR profile with the ",
|
||||
"following command:",
|
||||
),
|
||||
add_css_class: "warning",
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
},
|
||||
gtk::Box {
|
||||
set_hexpand: true,
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 6,
|
||||
gtk::ScrolledWindow {
|
||||
add_css_class: "card",
|
||||
set_vscrollbar_policy: gtk::PolicyType::Never,
|
||||
set_overflow: gtk::Overflow::Hidden,
|
||||
gtk::TextView {
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_monospace: true,
|
||||
set_editable: false,
|
||||
set_left_margin: 6,
|
||||
set_right_margin: 6,
|
||||
set_top_margin: 6,
|
||||
set_bottom_margin: 18,
|
||||
#[wrap(Some)]
|
||||
set_buffer: cmdbuf = >k::TextBuffer {
|
||||
set_text: &{
|
||||
let mut res = String::new();
|
||||
if let Some(GpuSysDrm::Amd(d)) = get_first_amd_gpu() {
|
||||
let ds = d.as_str();
|
||||
res = get_set_amd_vr_pow_prof_cmd(ds);
|
||||
}
|
||||
res
|
||||
},
|
||||
set_enable_undo: false,
|
||||
}
|
||||
}
|
||||
add_css_class: "linked",
|
||||
gtk::Button {
|
||||
add_css_class: "suggested-action",
|
||||
add_css_class: "destructive-action",
|
||||
set_hexpand: true,
|
||||
#[track = "model.changed(Self::xrservice_active())"]
|
||||
set_class_active: ("suggested-action", !model.xrservice_active),
|
||||
#[track = "model.changed(Self::xrservice_active())"]
|
||||
set_label: match model.xrservice_active {
|
||||
true => "Stop",
|
||||
false => "Start",
|
||||
},
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(MainViewMsg::StartStopClicked);
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
add_css_class: "flat",
|
||||
add_css_class: "circular",
|
||||
set_tooltip_text: Some("Copy"),
|
||||
set_icon_name: "edit-copy-symbolic",
|
||||
set_vexpand: false,
|
||||
set_label: "Start with GDB",
|
||||
#[track = "model.changed(Self::xrservice_active()) || model.changed(Self::enable_debug_view())"]
|
||||
set_visible: model.enable_debug_view && !model.xrservice_active,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(MainViewMsg::StartWithDebug);
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_halign: gtk::Align::Center,
|
||||
set_valign: gtk::Align::Center,
|
||||
connect_clicked => move |_| {
|
||||
if let Some(GpuSysDrm::Amd(d)) = get_first_amd_gpu() {
|
||||
gtk::gdk::Display::default()
|
||||
.expect("Could not find default display")
|
||||
.clipboard()
|
||||
.set_text(get_set_amd_vr_pow_prof_cmd(d.as_str()).as_str());
|
||||
set_icon_name: "view-refresh-symbolic",
|
||||
set_tooltip_text: Some("Restart"),
|
||||
#[track = "model.changed(Self::xrservice_active())"]
|
||||
set_visible: model.xrservice_active,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(MainViewMsg::RestartXRService)
|
||||
},
|
||||
},
|
||||
},
|
||||
model.devices_box.widget(),
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: match mount_has_nosuid(model.selected_profile.prefix.as_str()) {
|
||||
Ok(b) => b,
|
||||
Err(_) => {
|
||||
// TODO: handle this error better
|
||||
println!(
|
||||
"Warning: could not get stat on path {}",
|
||||
model.selected_profile.prefix);
|
||||
false
|
||||
},
|
||||
},
|
||||
warning_heading(),
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"Your current prefix is inside a partition ",
|
||||
"mounted with the nosuid option. This will prevent ",
|
||||
"the Envision runtime from acquiring certain privileges ",
|
||||
"and will cause noticeable stutter when running XR ",
|
||||
"applications."
|
||||
),
|
||||
add_css_class: "warning",
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: model.selected_profile.lighthouse_driver == LighthouseDriver::SteamVR && !chaperone_info_exists(),
|
||||
warning_heading(),
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"SteamVR room configuration not found.\n",
|
||||
"To use the SteamVR lighthouse driver, you ",
|
||||
"will need to run SteamVR and perform the room setup.",
|
||||
),
|
||||
add_css_class: "warning",
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: match get_amd_gpu_power_profile() {
|
||||
None => false,
|
||||
Some(GpuPowerProfile::VR) => false,
|
||||
Some(_) => true,
|
||||
},
|
||||
warning_heading(),
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"Your AMD GPU Power Profile is not set to VR. ",
|
||||
"This will cause noticeable stutter when running XR ",
|
||||
"applications. Activate the VR profile with the ",
|
||||
"following command:",
|
||||
),
|
||||
add_css_class: "warning",
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 6,
|
||||
gtk::ScrolledWindow {
|
||||
add_css_class: "card",
|
||||
set_vscrollbar_policy: gtk::PolicyType::Never,
|
||||
set_overflow: gtk::Overflow::Hidden,
|
||||
gtk::TextView {
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_monospace: true,
|
||||
set_editable: false,
|
||||
set_left_margin: 6,
|
||||
set_right_margin: 6,
|
||||
set_top_margin: 6,
|
||||
set_bottom_margin: 18,
|
||||
#[wrap(Some)]
|
||||
set_buffer: cmdbuf = >k::TextBuffer {
|
||||
set_text: &{
|
||||
let mut res = String::new();
|
||||
if let Some(GpuSysDrm::Amd(d)) = get_first_amd_gpu() {
|
||||
let ds = d.as_str();
|
||||
res = get_set_amd_vr_pow_prof_cmd(ds);
|
||||
}
|
||||
res
|
||||
},
|
||||
set_enable_undo: false,
|
||||
}
|
||||
}
|
||||
},
|
||||
gtk::Button {
|
||||
add_css_class: "flat",
|
||||
add_css_class: "circular",
|
||||
set_tooltip_text: Some("Copy"),
|
||||
set_icon_name: "edit-copy-symbolic",
|
||||
set_vexpand: false,
|
||||
set_valign: gtk::Align::Center,
|
||||
connect_clicked => move |_| {
|
||||
if let Some(GpuSysDrm::Amd(d)) = get_first_amd_gpu() {
|
||||
gtk::gdk::Display::default()
|
||||
.expect("Could not find default display")
|
||||
.clipboard()
|
||||
.set_text(get_set_amd_vr_pow_prof_cmd(d.as_str()).as_str());
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_halign: gtk::Align::Start,
|
||||
set_label: "Refresh",
|
||||
connect_clicked[sender, profiles_dropdown] => move |_| {
|
||||
sender.input(Self::Input::SetSelectedProfile(profiles_dropdown.selected()));
|
||||
}
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_halign: gtk::Align::Start,
|
||||
set_label: "Refresh",
|
||||
connect_clicked[sender, profiles_dropdown] => move |_| {
|
||||
sender.input(Self::Input::SetSelectedProfile(profiles_dropdown.selected()));
|
||||
}
|
||||
},
|
||||
},
|
||||
model.steam_launch_options_box.widget(),
|
||||
model.install_wivrn_box.widget(),
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: model.selected_profile.lighthouse_driver == LighthouseDriver::Survive,
|
||||
gtk::Label {
|
||||
add_css_class: "heading",
|
||||
model.steam_launch_options_box.widget(),
|
||||
model.install_wivrn_box.widget(),
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_xalign: 0.0,
|
||||
set_label: "Libsurvive Calibration",
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: model.selected_profile.lighthouse_driver == LighthouseDriver::Survive,
|
||||
gtk::Label {
|
||||
add_css_class: "heading",
|
||||
set_hexpand: true,
|
||||
set_xalign: 0.0,
|
||||
set_label: "Libsurvive Calibration",
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
},
|
||||
gtk::Label {
|
||||
add_css_class: "dim-label",
|
||||
set_hexpand: true,
|
||||
set_label: concat!(
|
||||
"Libsurvive needs to import your SteamVR calibration to work ",
|
||||
"properly. You need to have used SteamVR with this setup ",
|
||||
"before to be able to import its calibration."
|
||||
),
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
},
|
||||
gtk::Button {
|
||||
add_css_class: "suggested-action",
|
||||
set_label: "Calibrate",
|
||||
set_halign: gtk::Align::Start,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.output(Self::Output::OpenLibsurviveSetup).expect("Sender outut failed");
|
||||
}
|
||||
},
|
||||
},
|
||||
gtk::Label {
|
||||
add_css_class: "dim-label",
|
||||
set_hexpand: true,
|
||||
set_label: concat!(
|
||||
"Libsurvive needs to import your SteamVR calibration to work ",
|
||||
"properly. You need to have used SteamVR with this setup ",
|
||||
"before to be able to import its calibration."
|
||||
),
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
},
|
||||
gtk::Button {
|
||||
add_css_class: "suggested-action",
|
||||
set_label: "Calibrate",
|
||||
set_halign: gtk::Align::Start,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.output(Self::Output::OpenLibsurviveSetup).expect("Sender outut failed");
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
} -> {
|
||||
set_name: Some("main_view"),
|
||||
set_title: Some("XR"),
|
||||
set_icon_name: Some("org.gabmus.envision-symbolic"),
|
||||
},
|
||||
add_titled_with_icon: (model.stardust_view.widget(), Some("stardust_view"), "Stardust", "starred-symbolic"),
|
||||
},
|
||||
add_bottom_bar: bottom_bar = >k::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
|
@ -435,6 +444,10 @@ impl SimpleComponent for MainView {
|
|||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
add_bottom_bar: section_switcher = &adw::ViewSwitcherBar {
|
||||
set_reveal: true,
|
||||
set_stack: Some(§ion_stack),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -648,6 +661,7 @@ impl SimpleComponent for MainView {
|
|||
profile_delete_confirm_dialog,
|
||||
root_win: init.root_win.clone(),
|
||||
profile_editor: None,
|
||||
stardust_view: StardustView::builder().launch(()).detach(),
|
||||
tracker: 0,
|
||||
};
|
||||
let widgets = view_output!();
|
||||
|
|
|
@ -17,3 +17,4 @@ pub mod profile_editor;
|
|||
pub mod steam_launch_options_box;
|
||||
pub mod util;
|
||||
pub mod wivrn_conf_editor;
|
||||
pub mod stardust;
|
||||
|
|
1
src/ui/stardust/mod.rs
Normal file
1
src/ui/stardust/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod stardust_view;
|
47
src/ui/stardust/stardust_view.rs
Normal file
47
src/ui/stardust/stardust_view.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use relm4::prelude::*;
|
||||
use gtk::prelude::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum StardustViewMsg {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum StardustViewOutMsg {}
|
||||
|
||||
#[tracker::track]
|
||||
pub struct StardustView {}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for StardustView {
|
||||
type Init = ();
|
||||
type Input = StardustViewMsg;
|
||||
type Output = StardustViewOutMsg;
|
||||
|
||||
view! {
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
gtk::Label {
|
||||
set_label: "Stardust",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||
self.reset();
|
||||
|
||||
match message {}
|
||||
}
|
||||
|
||||
fn init(
|
||||
init: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let model = Self {
|
||||
tracker: 0,
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue