mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-08-01 05:38:44 +00:00
feat: split install wivrn box into its own component
This commit is contained in:
parent
d9c8e6e728
commit
65039c36dd
5 changed files with 270 additions and 201 deletions
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::CMD_NAME,
|
constants::CMD_NAME,
|
||||||
file_utils::{get_config_dir, get_writer},
|
file_utils::{get_config_dir, get_writer}, profile::Profile,
|
||||||
};
|
};
|
||||||
use expect_dialog::ExpectDialog;
|
use expect_dialog::ExpectDialog;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -12,6 +12,15 @@ pub struct Config {
|
||||||
pub debug_view_enabled: bool,
|
pub debug_view_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn get_selected_profile(&self, profiles: &Vec<Profile>) -> Profile {
|
||||||
|
match profiles.iter().find(|p| {p.name == self.selected_profile_name}) {
|
||||||
|
Some(p) => p.clone(),
|
||||||
|
None => profiles.get(0).expect_dialog("No profiles found").clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn config_file_path() -> String {
|
fn config_file_path() -> String {
|
||||||
format!(
|
format!(
|
||||||
"{config}/{name}.json",
|
"{config}/{name}.json",
|
||||||
|
|
|
@ -2,8 +2,7 @@ use super::about_dialog::AboutDialog;
|
||||||
use super::build_window::{BuildStatus, BuildWindow};
|
use super::build_window::{BuildStatus, BuildWindow};
|
||||||
use super::debug_view::{DebugView, DebugViewMsg};
|
use super::debug_view::{DebugView, DebugViewMsg};
|
||||||
use super::libsurvive_setup_window::LibsurviveSetupWindow;
|
use super::libsurvive_setup_window::LibsurviveSetupWindow;
|
||||||
use super::main_view::{InstallWivrnStatus, MainViewMsg};
|
use super::main_view::MainViewMsg;
|
||||||
use crate::adb::get_adb_install_runner;
|
|
||||||
use crate::builders::build_basalt::get_build_basalt_runner;
|
use crate::builders::build_basalt::get_build_basalt_runner;
|
||||||
use crate::builders::build_libsurvive::get_build_libsurvive_runner;
|
use crate::builders::build_libsurvive::get_build_libsurvive_runner;
|
||||||
use crate::builders::build_monado::get_build_monado_runner;
|
use crate::builders::build_monado::get_build_monado_runner;
|
||||||
|
@ -15,7 +14,6 @@ use crate::dependencies::basalt_deps::get_missing_basalt_deps;
|
||||||
use crate::dependencies::libsurvive_deps::get_missing_libsurvive_deps;
|
use crate::dependencies::libsurvive_deps::get_missing_libsurvive_deps;
|
||||||
use crate::dependencies::monado_deps::get_missing_monado_deps;
|
use crate::dependencies::monado_deps::get_missing_monado_deps;
|
||||||
use crate::dependencies::wivrn_deps::get_missing_wivrn_deps;
|
use crate::dependencies::wivrn_deps::get_missing_wivrn_deps;
|
||||||
use crate::downloader::download_file;
|
|
||||||
use crate::file_builders::active_runtime_json::{
|
use crate::file_builders::active_runtime_json::{
|
||||||
set_current_active_runtime_to_profile, set_current_active_runtime_to_steam,
|
set_current_active_runtime_to_profile, set_current_active_runtime_to_steam,
|
||||||
};
|
};
|
||||||
|
@ -23,7 +21,6 @@ use crate::file_builders::openvrpaths_vrpath::{
|
||||||
set_current_openvrpaths_to_profile, set_current_openvrpaths_to_steam,
|
set_current_openvrpaths_to_profile, set_current_openvrpaths_to_steam,
|
||||||
};
|
};
|
||||||
use crate::file_utils::setcap_cap_sys_nice_eip;
|
use crate::file_utils::setcap_cap_sys_nice_eip;
|
||||||
use crate::paths::wivrn_apk_download_path;
|
|
||||||
use crate::profile::{Profile, XRServiceType};
|
use crate::profile::{Profile, XRServiceType};
|
||||||
use crate::profiles::system_valve_index::system_valve_index_profile;
|
use crate::profiles::system_valve_index::system_valve_index_profile;
|
||||||
use crate::profiles::valve_index::valve_index_profile;
|
use crate::profiles::valve_index::valve_index_profile;
|
||||||
|
@ -42,8 +39,6 @@ use relm4::adw::ResponseAppearance;
|
||||||
use relm4::gtk::glib;
|
use relm4::gtk::glib;
|
||||||
use relm4::{new_action_group, new_stateful_action, new_stateless_action, prelude::*};
|
use relm4::{new_action_group, new_stateful_action, new_stateless_action, prelude::*};
|
||||||
use relm4::{ComponentParts, ComponentSender, SimpleComponent};
|
use relm4::{ComponentParts, ComponentSender, SimpleComponent};
|
||||||
use std::cell::Cell;
|
|
||||||
use std::thread::JoinHandle;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
|
@ -75,11 +70,6 @@ pub struct App {
|
||||||
build_pipeline: Option<RunnerPipeline>,
|
build_pipeline: Option<RunnerPipeline>,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
profiles: Vec<Profile>,
|
profiles: Vec<Profile>,
|
||||||
|
|
||||||
#[tracker::do_not_track]
|
|
||||||
download_wivrn_thread: Cell<Option<JoinHandle<Result<(), reqwest::Error>>>>,
|
|
||||||
#[tracker::do_not_track]
|
|
||||||
install_wivrn_runner: Option<Runner>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -92,8 +82,6 @@ pub enum Msg {
|
||||||
SetXRServiceRuntime(bool),
|
SetXRServiceRuntime(bool),
|
||||||
RunSetCap,
|
RunSetCap,
|
||||||
OpenLibsurviveSetup,
|
OpenLibsurviveSetup,
|
||||||
DownloadWivrnApk,
|
|
||||||
InstallWivrnApk,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
@ -106,11 +94,8 @@ impl App {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_selected_profile(&self) -> &Profile {
|
pub fn get_selected_profile(&self) -> Profile {
|
||||||
match self.get_profile_by_name(&self.config.selected_profile_name) {
|
self.config.get_selected_profile(&self.profiles)
|
||||||
Some(profile) => profile,
|
|
||||||
None => self.profiles.get(0).expect_dialog("No profiles found"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_xrservice(&mut self) {
|
pub fn start_xrservice(&mut self) {
|
||||||
|
@ -221,49 +206,7 @@ impl SimpleComponent for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if self.download_wivrn_thread.get_mut().is_some() {
|
self.main_view.sender().emit(MainViewMsg::ClockTicking);
|
||||||
let finished = self
|
|
||||||
.download_wivrn_thread
|
|
||||||
.get_mut()
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.is_finished();
|
|
||||||
if finished {
|
|
||||||
let joinh = self.download_wivrn_thread.take().unwrap();
|
|
||||||
match joinh.join().unwrap() {
|
|
||||||
Ok(_) => {
|
|
||||||
sender.input(Msg::InstallWivrnApk);
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
self.main_view.sender().emit(
|
|
||||||
MainViewMsg::UpdateInstallWivrnStatus(
|
|
||||||
InstallWivrnStatus::Done(Some(
|
|
||||||
"Error downloading WiVRn APK".into(),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match &mut self.install_wivrn_runner {
|
|
||||||
None => {}
|
|
||||||
Some(runner) => match runner.status() {
|
|
||||||
RunnerStatus::Running => {}
|
|
||||||
RunnerStatus::Stopped(status) => {
|
|
||||||
self.install_wivrn_runner.take();
|
|
||||||
self.main_view
|
|
||||||
.sender()
|
|
||||||
.emit(MainViewMsg::UpdateInstallWivrnStatus(match status {
|
|
||||||
None | Some(0) => InstallWivrnStatus::Success,
|
|
||||||
Some(err_code) => InstallWivrnStatus::Done(Some(format!(
|
|
||||||
"ADB exited with code \"{c}\"",
|
|
||||||
c = err_code
|
|
||||||
))),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Msg::EnableDebugViewChanged(val) => {
|
Msg::EnableDebugViewChanged(val) => {
|
||||||
self.set_enable_debug_view(val);
|
self.set_enable_debug_view(val);
|
||||||
|
@ -389,8 +332,8 @@ impl SimpleComponent for App {
|
||||||
let profile = self.get_selected_profile();
|
let profile = self.get_selected_profile();
|
||||||
self.main_view
|
self.main_view
|
||||||
.sender()
|
.sender()
|
||||||
.emit(MainViewMsg::UpdateXRServiceType(
|
.emit(MainViewMsg::UpdateSelectedProfile(
|
||||||
profile.clone().xrservice_type,
|
profile.clone()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Msg::SetXRServiceRuntime(is_rex) => {
|
Msg::SetXRServiceRuntime(is_rex) => {
|
||||||
|
@ -411,23 +354,6 @@ impl SimpleComponent for App {
|
||||||
))
|
))
|
||||||
.expect_dialog("Failed to present Libsurvive Setup Window");
|
.expect_dialog("Failed to present Libsurvive Setup Window");
|
||||||
}
|
}
|
||||||
Msg::DownloadWivrnApk => {
|
|
||||||
self.main_view
|
|
||||||
.sender()
|
|
||||||
.emit(MainViewMsg::UpdateInstallWivrnStatus(
|
|
||||||
InstallWivrnStatus::InProgress,
|
|
||||||
));
|
|
||||||
self.download_wivrn_thread.set(Some(download_file(
|
|
||||||
// TODO: always download latest
|
|
||||||
"https://github.com/Meumeu/WiVRn/releases/latest/download/WiVRn-oculus-release.apk".into(),
|
|
||||||
wivrn_apk_download_path()
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
Msg::InstallWivrnApk => {
|
|
||||||
let mut runner = get_adb_install_runner(&wivrn_apk_download_path());
|
|
||||||
runner.start();
|
|
||||||
self.install_wivrn_runner = Some(runner);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,6 +404,7 @@ impl SimpleComponent for App {
|
||||||
main_view: MainView::builder()
|
main_view: MainView::builder()
|
||||||
.launch(MainViewInit {
|
.launch(MainViewInit {
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
|
selected_profile: config.get_selected_profile(&profiles),
|
||||||
})
|
})
|
||||||
.forward(sender.input_sender(), |message| match message {
|
.forward(sender.input_sender(), |message| match message {
|
||||||
MainViewOutMsg::UpdateView => Msg::UpdateView,
|
MainViewOutMsg::UpdateView => Msg::UpdateView,
|
||||||
|
@ -485,7 +412,6 @@ impl SimpleComponent for App {
|
||||||
MainViewOutMsg::DoStartStopXRService => Msg::DoStartStopXRService,
|
MainViewOutMsg::DoStartStopXRService => Msg::DoStartStopXRService,
|
||||||
MainViewOutMsg::ProfileSelected(name) => Msg::ProfileSelected(name),
|
MainViewOutMsg::ProfileSelected(name) => Msg::ProfileSelected(name),
|
||||||
MainViewOutMsg::SetXRServiceRuntime(is_rex) => Msg::SetXRServiceRuntime(is_rex),
|
MainViewOutMsg::SetXRServiceRuntime(is_rex) => Msg::SetXRServiceRuntime(is_rex),
|
||||||
MainViewOutMsg::InstallWivrnApk => Msg::DownloadWivrnApk,
|
|
||||||
}),
|
}),
|
||||||
debug_view: DebugView::builder()
|
debug_view: DebugView::builder()
|
||||||
.launch(DebugViewInit {
|
.launch(DebugViewInit {
|
||||||
|
@ -515,8 +441,6 @@ impl SimpleComponent for App {
|
||||||
xrservice_runner: None,
|
xrservice_runner: None,
|
||||||
xrservice_log: vec![],
|
xrservice_log: vec![],
|
||||||
build_pipeline: None,
|
build_pipeline: None,
|
||||||
download_wivrn_thread: Cell::new(None),
|
|
||||||
install_wivrn_runner: None,
|
|
||||||
};
|
};
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
|
209
src/ui/install_wivrn_box.rs
Normal file
209
src/ui/install_wivrn_box.rs
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
use crate::{
|
||||||
|
adb::get_adb_install_runner,
|
||||||
|
downloader::download_file,
|
||||||
|
paths::wivrn_apk_download_path,
|
||||||
|
profile::{Profile, XRServiceType},
|
||||||
|
runner::{Runner, RunnerStatus},
|
||||||
|
};
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use relm4::prelude::*;
|
||||||
|
use std::{cell::Cell, thread::JoinHandle};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
|
pub enum InstallWivrnStatus {
|
||||||
|
Success,
|
||||||
|
Done(Option<String>),
|
||||||
|
InProgress,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracker::track]
|
||||||
|
pub struct InstallWivrnBox {
|
||||||
|
selected_profile: Profile,
|
||||||
|
install_wivrn_status: InstallWivrnStatus,
|
||||||
|
#[tracker::do_not_track]
|
||||||
|
download_thread: Cell<Option<JoinHandle<Result<(), reqwest::Error>>>>,
|
||||||
|
#[tracker::do_not_track]
|
||||||
|
install_runner: Option<Runner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum InstallWivrnBoxMsg {
|
||||||
|
ClockTicking,
|
||||||
|
UpdateSelectedProfile(Profile),
|
||||||
|
DownloadWivrn,
|
||||||
|
InstallWivrnApk,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InstallWivrnBoxInit {
|
||||||
|
pub selected_profile: Profile,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub)]
|
||||||
|
impl SimpleComponent for InstallWivrnBox {
|
||||||
|
type Init = InstallWivrnBoxInit;
|
||||||
|
type Input = InstallWivrnBoxMsg;
|
||||||
|
type Output = ();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 12,
|
||||||
|
set_margin_top: 12,
|
||||||
|
set_margin_bottom: 12,
|
||||||
|
#[track = "model.changed(Self::selected_profile())"]
|
||||||
|
set_visible: match model.selected_profile.xrservice_type {
|
||||||
|
XRServiceType::Wivrn => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
gtk::Separator {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_hexpand: true,
|
||||||
|
},
|
||||||
|
gtk::Label {
|
||||||
|
add_css_class: "heading",
|
||||||
|
set_hexpand: true,
|
||||||
|
set_xalign: 0.0,
|
||||||
|
set_margin_start: 12,
|
||||||
|
set_margin_end: 12,
|
||||||
|
set_label: "Install WiVRn APK",
|
||||||
|
set_wrap: true,
|
||||||
|
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||||
|
},
|
||||||
|
gtk::Label {
|
||||||
|
add_css_class: "dim-label",
|
||||||
|
set_hexpand: true,
|
||||||
|
set_xalign: 0.0,
|
||||||
|
set_margin_start: 12,
|
||||||
|
set_margin_end: 12,
|
||||||
|
set_label: concat!(
|
||||||
|
"Install the WiVRn APK on your standalong Android headset. ",
|
||||||
|
"You will need to enable Developer Mode on your headset, ",
|
||||||
|
"then press the \"Install WiVRn\" button."
|
||||||
|
),
|
||||||
|
set_wrap: true,
|
||||||
|
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||||
|
},
|
||||||
|
gtk::Button {
|
||||||
|
add_css_class: "suggested-action",
|
||||||
|
set_label: "Install WiVRn",
|
||||||
|
set_margin_start: 12,
|
||||||
|
set_margin_end: 12,
|
||||||
|
set_halign: gtk::Align::Start,
|
||||||
|
#[track = "model.changed(Self::install_wivrn_status())"]
|
||||||
|
set_sensitive: match model.install_wivrn_status {
|
||||||
|
InstallWivrnStatus::InProgress => false,
|
||||||
|
_ => true,
|
||||||
|
},
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.input(Self::Input::DownloadWivrn);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gtk::Label {
|
||||||
|
add_css_class: "error",
|
||||||
|
set_margin_start: 12,
|
||||||
|
set_margin_end: 12,
|
||||||
|
set_xalign: 0.0,
|
||||||
|
#[track = "model.changed(Self::install_wivrn_status())"]
|
||||||
|
set_visible: match &model.install_wivrn_status {
|
||||||
|
InstallWivrnStatus::Done(Some(_)) => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
#[track = "model.changed(Self::install_wivrn_status())"]
|
||||||
|
set_label: match &model.install_wivrn_status {
|
||||||
|
InstallWivrnStatus::Done(Some(err)) => err.as_str(),
|
||||||
|
_ => "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gtk::Label {
|
||||||
|
add_css_class: "success",
|
||||||
|
set_margin_start: 12,
|
||||||
|
set_margin_end: 12,
|
||||||
|
set_xalign: 0.0,
|
||||||
|
#[track = "model.changed(Self::install_wivrn_status())"]
|
||||||
|
set_visible: match &model.install_wivrn_status {
|
||||||
|
InstallWivrnStatus::Success => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
set_label: "WiVRn Installed Successfully",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||||
|
self.reset();
|
||||||
|
|
||||||
|
match message {
|
||||||
|
Self::Input::ClockTicking => {
|
||||||
|
if self.download_thread.get_mut().is_some() {
|
||||||
|
let finished = self
|
||||||
|
.download_thread
|
||||||
|
.get_mut()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.is_finished();
|
||||||
|
if finished {
|
||||||
|
let joinh = self.download_thread.take().unwrap();
|
||||||
|
match joinh.join().unwrap() {
|
||||||
|
Ok(_) => {
|
||||||
|
sender.input(Self::Input::InstallWivrnApk);
|
||||||
|
}
|
||||||
|
Err(_) => self.set_install_wivrn_status(InstallWivrnStatus::Done(
|
||||||
|
Some("Error downloading WiVRn APK".into()),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.install_runner.is_some() {
|
||||||
|
let runner = self.install_runner.as_mut().unwrap();
|
||||||
|
match runner.status() {
|
||||||
|
RunnerStatus::Running => {}
|
||||||
|
RunnerStatus::Stopped(status) => {
|
||||||
|
self.install_runner.take();
|
||||||
|
self.set_install_wivrn_status(match status {
|
||||||
|
None | Some(0) => InstallWivrnStatus::Success,
|
||||||
|
Some(err_code) => InstallWivrnStatus::Done(Some(format!(
|
||||||
|
"ADB exited with code \"{c}\"",
|
||||||
|
c = err_code
|
||||||
|
))),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Input::DownloadWivrn => {
|
||||||
|
self.set_install_wivrn_status(InstallWivrnStatus::InProgress);
|
||||||
|
self.download_thread.set(Some(download_file(
|
||||||
|
"https://github.com/Meumeu/WiVRn/releases/latest/download/WiVRn-oculus-release.apk".into(),
|
||||||
|
wivrn_apk_download_path()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Self::Input::InstallWivrnApk => {
|
||||||
|
let mut runner = get_adb_install_runner(&wivrn_apk_download_path());
|
||||||
|
runner.start();
|
||||||
|
self.install_runner = Some(runner);
|
||||||
|
}
|
||||||
|
Self::Input::UpdateSelectedProfile(p) => {
|
||||||
|
self.set_selected_profile(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: &Self::Root,
|
||||||
|
sender: ComponentSender<Self>,
|
||||||
|
) -> ComponentParts<Self> {
|
||||||
|
let model = Self {
|
||||||
|
selected_profile: init.selected_profile,
|
||||||
|
install_wivrn_status: InstallWivrnStatus::Done(None),
|
||||||
|
download_thread: Cell::new(None),
|
||||||
|
install_runner: None,
|
||||||
|
tracker: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
ComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::constants::APP_NAME;
|
use crate::constants::APP_NAME;
|
||||||
use crate::file_builders::active_runtime_json::{self, get_current_active_runtime};
|
use crate::file_builders::active_runtime_json::{self, get_current_active_runtime};
|
||||||
use crate::profile::XRServiceType;
|
use crate::profile::{Profile, XRServiceType};
|
||||||
use crate::ui::app::{
|
use crate::ui::app::{
|
||||||
AboutAction, BuildProfileAction, DebugViewToggleAction, LibsurviveSetupAction,
|
AboutAction, BuildProfileAction, DebugViewToggleAction, LibsurviveSetupAction,
|
||||||
};
|
};
|
||||||
|
@ -13,12 +11,9 @@ use relm4::prelude::*;
|
||||||
use relm4::{ComponentParts, ComponentSender, SimpleComponent};
|
use relm4::{ComponentParts, ComponentSender, SimpleComponent};
|
||||||
use relm4_icons::icon_name;
|
use relm4_icons::icon_name;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
use super::install_wivrn_box::{
|
||||||
pub enum InstallWivrnStatus {
|
InstallWivrnBox, InstallWivrnBoxInit, InstallWivrnBoxMsg
|
||||||
Success,
|
};
|
||||||
Done(Option<String>),
|
|
||||||
InProgress,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct MainView {
|
pub struct MainView {
|
||||||
|
@ -29,11 +24,13 @@ pub struct MainView {
|
||||||
steam_launch_options: String,
|
steam_launch_options: String,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
profiles_dropdown: Option<gtk::DropDown>,
|
profiles_dropdown: Option<gtk::DropDown>,
|
||||||
install_wivrn_status: InstallWivrnStatus,
|
#[tracker::do_not_track]
|
||||||
|
install_wivrn_box: Controller<InstallWivrnBox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MainViewMsg {
|
pub enum MainViewMsg {
|
||||||
|
ClockTicking,
|
||||||
StartStopClicked,
|
StartStopClicked,
|
||||||
XRServiceActiveChanged(bool),
|
XRServiceActiveChanged(bool),
|
||||||
EnableDebugViewChanged(bool),
|
EnableDebugViewChanged(bool),
|
||||||
|
@ -42,8 +39,7 @@ pub enum MainViewMsg {
|
||||||
ProfileSelected(u32),
|
ProfileSelected(u32),
|
||||||
SteamLaunchOptionsChanged(String),
|
SteamLaunchOptionsChanged(String),
|
||||||
CopySteamLaunchOptions,
|
CopySteamLaunchOptions,
|
||||||
UpdateXRServiceType(XRServiceType),
|
UpdateSelectedProfile(Profile),
|
||||||
UpdateInstallWivrnStatus(InstallWivrnStatus),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -53,11 +49,11 @@ pub enum MainViewOutMsg {
|
||||||
DoStartStopXRService,
|
DoStartStopXRService,
|
||||||
ProfileSelected(String),
|
ProfileSelected(String),
|
||||||
SetXRServiceRuntime(bool),
|
SetXRServiceRuntime(bool),
|
||||||
InstallWivrnApk,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MainViewInit {
|
pub struct MainViewInit {
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
|
pub selected_profile: Profile,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
|
@ -83,7 +79,7 @@ impl SimpleComponent for MainView {
|
||||||
view! {
|
view! {
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
#[track = "model.changed(MainView::enable_debug_view())"]
|
#[track = "model.changed(Self::enable_debug_view())"]
|
||||||
set_hexpand: !model.enable_debug_view,
|
set_hexpand: !model.enable_debug_view,
|
||||||
set_vexpand: true,
|
set_vexpand: true,
|
||||||
set_size_request: (270, 350),
|
set_size_request: (270, 350),
|
||||||
|
@ -102,7 +98,7 @@ impl SimpleComponent for MainView {
|
||||||
},
|
},
|
||||||
pack_start: profiles_dropdown = >k::DropDown {
|
pack_start: profiles_dropdown = >k::DropDown {
|
||||||
set_tooltip_text: Some("Profiles"),
|
set_tooltip_text: Some("Profiles"),
|
||||||
#[track = "model.changed(MainView::profile_names())"]
|
#[track = "model.changed(Self::profile_names())"]
|
||||||
set_model: Some(&{
|
set_model: Some(&{
|
||||||
let names: Vec<_> = model.profile_names.iter().map(String::as_str).collect();
|
let names: Vec<_> = model.profile_names.iter().map(String::as_str).collect();
|
||||||
gtk::StringList::new(&names)
|
gtk::StringList::new(&names)
|
||||||
|
@ -111,7 +107,7 @@ impl SimpleComponent for MainView {
|
||||||
sender.input(MainViewMsg::ProfileSelected(this.selected()));
|
sender.input(MainViewMsg::ProfileSelected(this.selected()));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
#[track = "model.changed(MainView::enable_debug_view())"]
|
#[track = "model.changed(Self::enable_debug_view())"]
|
||||||
set_show_end_title_buttons: !model.enable_debug_view,
|
set_show_end_title_buttons: !model.enable_debug_view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -130,9 +126,9 @@ impl SimpleComponent for MainView {
|
||||||
add_css_class: "destructive-action",
|
add_css_class: "destructive-action",
|
||||||
set_hexpand: true,
|
set_hexpand: true,
|
||||||
set_halign: gtk::Align::Center,
|
set_halign: gtk::Align::Center,
|
||||||
#[track = "model.changed(MainView::xrservice_active())"]
|
#[track = "model.changed(Self::xrservice_active())"]
|
||||||
set_class_active: ("suggested-action", !model.xrservice_active),
|
set_class_active: ("suggested-action", !model.xrservice_active),
|
||||||
#[track = "model.changed(MainView::xrservice_active())"]
|
#[track = "model.changed(Self::xrservice_active())"]
|
||||||
set_label: match model.xrservice_active {
|
set_label: match model.xrservice_active {
|
||||||
true => "Stop",
|
true => "Stop",
|
||||||
false => "Start",
|
false => "Start",
|
||||||
|
@ -179,7 +175,7 @@ impl SimpleComponent for MainView {
|
||||||
set_spacing: 12,
|
set_spacing: 12,
|
||||||
set_margin_top: 12,
|
set_margin_top: 12,
|
||||||
set_margin_bottom: 12,
|
set_margin_bottom: 12,
|
||||||
#[track = "model.changed(MainView::xrservice_active())"]
|
#[track = "model.changed(Self::xrservice_active())"]
|
||||||
set_visible: model.xrservice_active,
|
set_visible: model.xrservice_active,
|
||||||
gtk::Separator {
|
gtk::Separator {
|
||||||
set_orientation: gtk::Orientation::Horizontal,
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
@ -227,7 +223,7 @@ impl SimpleComponent for MainView {
|
||||||
set_size_request: (-1, 150),
|
set_size_request: (-1, 150),
|
||||||
#[wrap(Some)]
|
#[wrap(Some)]
|
||||||
set_buffer: cmdbuf = >k::TextBuffer {
|
set_buffer: cmdbuf = >k::TextBuffer {
|
||||||
#[track = "model.changed(MainView::steam_launch_options())"]
|
#[track = "model.changed(Self::steam_launch_options())"]
|
||||||
set_text: model.steam_launch_options.as_str(),
|
set_text: model.steam_launch_options.as_str(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -244,88 +240,7 @@ impl SimpleComponent for MainView {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gtk::Box {
|
model.install_wivrn_box.widget(),
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
|
||||||
set_spacing: 12,
|
|
||||||
set_margin_top: 12,
|
|
||||||
set_margin_bottom: 12,
|
|
||||||
#[track = "model.changed(MainView::xrservice_type())"]
|
|
||||||
set_visible: match model.xrservice_type {
|
|
||||||
XRServiceType::Wivrn => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
gtk::Separator {
|
|
||||||
set_orientation: gtk::Orientation::Horizontal,
|
|
||||||
set_hexpand: true,
|
|
||||||
},
|
|
||||||
gtk::Label {
|
|
||||||
add_css_class: "heading",
|
|
||||||
set_hexpand: true,
|
|
||||||
set_xalign: 0.0,
|
|
||||||
set_margin_start: 12,
|
|
||||||
set_margin_end: 12,
|
|
||||||
set_label: "Install WiVRn APK",
|
|
||||||
set_wrap: true,
|
|
||||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
|
||||||
},
|
|
||||||
gtk::Label {
|
|
||||||
add_css_class: "dim-label",
|
|
||||||
set_hexpand: true,
|
|
||||||
set_xalign: 0.0,
|
|
||||||
set_margin_start: 12,
|
|
||||||
set_margin_end: 12,
|
|
||||||
set_label: concat!(
|
|
||||||
"Install the WiVRn APK on your standalong Android headset. ",
|
|
||||||
"You will need to enable Developer Mode on your headset, ",
|
|
||||||
"then press the \"Install WiVRn\" button."
|
|
||||||
),
|
|
||||||
set_wrap: true,
|
|
||||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
|
||||||
},
|
|
||||||
gtk::Button {
|
|
||||||
add_css_class: "suggested-action",
|
|
||||||
set_label: "Install WiVRn",
|
|
||||||
set_margin_start: 12,
|
|
||||||
set_margin_end: 12,
|
|
||||||
set_halign: gtk::Align::Start,
|
|
||||||
#[track = "model.changed(MainView::install_wivrn_status())"]
|
|
||||||
set_sensitive: match model.install_wivrn_status {
|
|
||||||
InstallWivrnStatus::InProgress => false,
|
|
||||||
_ => true,
|
|
||||||
},
|
|
||||||
connect_clicked[sender] => move |_| {
|
|
||||||
sender.output(MainViewOutMsg::InstallWivrnApk);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
gtk::Label {
|
|
||||||
add_css_class: "error",
|
|
||||||
set_margin_start: 12,
|
|
||||||
set_margin_end: 12,
|
|
||||||
set_xalign: 0.0,
|
|
||||||
#[track = "model.changed(MainView::install_wivrn_status())"]
|
|
||||||
set_visible: match &model.install_wivrn_status {
|
|
||||||
InstallWivrnStatus::Done(Some(_)) => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
#[track = "model.changed(MainView::install_wivrn_status())"]
|
|
||||||
set_label: match &model.install_wivrn_status {
|
|
||||||
InstallWivrnStatus::Done(Some(err)) => err.as_str(),
|
|
||||||
_ => "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
gtk::Label {
|
|
||||||
add_css_class: "success",
|
|
||||||
set_margin_start: 12,
|
|
||||||
set_margin_end: 12,
|
|
||||||
set_xalign: 0.0,
|
|
||||||
#[track = "model.changed(MainView::install_wivrn_status())"]
|
|
||||||
set_visible: match &model.install_wivrn_status {
|
|
||||||
InstallWivrnStatus::Success => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
set_label: "WiVRn Installed Successfully",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,19 +250,27 @@ impl SimpleComponent for MainView {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
MainViewMsg::StartStopClicked => {
|
Self::Input::ClockTicking => {
|
||||||
|
self.install_wivrn_box
|
||||||
|
.sender()
|
||||||
|
.emit(InstallWivrnBoxMsg::ClockTicking);
|
||||||
|
}
|
||||||
|
Self::Input::StartStopClicked => {
|
||||||
sender.output(MainViewOutMsg::DoStartStopXRService);
|
sender.output(MainViewOutMsg::DoStartStopXRService);
|
||||||
}
|
}
|
||||||
MainViewMsg::XRServiceActiveChanged(active) => {
|
Self::Input::XRServiceActiveChanged(active) => {
|
||||||
self.set_xrservice_active(active);
|
self.set_xrservice_active(active);
|
||||||
}
|
}
|
||||||
MainViewMsg::EnableDebugViewChanged(val) => {
|
Self::Input::EnableDebugViewChanged(val) => {
|
||||||
self.set_enable_debug_view(val);
|
self.set_enable_debug_view(val);
|
||||||
}
|
}
|
||||||
MainViewMsg::UpdateXRServiceType(typ) => {
|
Self::Input::UpdateSelectedProfile(prof) => {
|
||||||
self.set_xrservice_type(typ);
|
self.set_xrservice_type(prof.xrservice_type.clone());
|
||||||
|
self.install_wivrn_box
|
||||||
|
.sender()
|
||||||
|
.emit(InstallWivrnBoxMsg::UpdateSelectedProfile(prof.clone()));
|
||||||
}
|
}
|
||||||
MainViewMsg::UpdateProfileNames(names, config) => {
|
Self::Input::UpdateProfileNames(names, config) => {
|
||||||
self.set_profile_names(names);
|
self.set_profile_names(names);
|
||||||
// why send another message to set the dropdown selection?
|
// why send another message to set the dropdown selection?
|
||||||
// set_* from tracker likely updates the view obj in the next
|
// set_* from tracker likely updates the view obj in the next
|
||||||
|
@ -364,26 +287,25 @@ impl SimpleComponent for MainView {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
MainViewMsg::SetSelectedProfile(index) => {
|
Self::Input::SetSelectedProfile(index) => {
|
||||||
self.profiles_dropdown
|
self.profiles_dropdown
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.set_selected(index);
|
.set_selected(index);
|
||||||
}
|
}
|
||||||
MainViewMsg::SteamLaunchOptionsChanged(lo) => self.set_steam_launch_options(lo),
|
Self::Input::SteamLaunchOptionsChanged(lo) => self.set_steam_launch_options(lo),
|
||||||
MainViewMsg::CopySteamLaunchOptions => gtk::gdk::Display::default()
|
Self::Input::CopySteamLaunchOptions => gtk::gdk::Display::default()
|
||||||
.expect_dialog("Could not find default display")
|
.expect_dialog("Could not find default display")
|
||||||
.clipboard()
|
.clipboard()
|
||||||
.set_text(self.steam_launch_options.as_str()),
|
.set_text(self.steam_launch_options.as_str()),
|
||||||
MainViewMsg::ProfileSelected(position) => {
|
Self::Input::ProfileSelected(position) => {
|
||||||
|
// self.install_wivrn_box.sender.emit(InstallWivrnBoxMsg::Upda);
|
||||||
|
// TODO: send profile to install_wivrn_box
|
||||||
sender.output(MainViewOutMsg::ProfileSelected(
|
sender.output(MainViewOutMsg::ProfileSelected(
|
||||||
self.profile_names.get(position as usize).unwrap().clone(),
|
self.profile_names.get(position as usize).unwrap().clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
MainViewMsg::UpdateInstallWivrnStatus(status) => {
|
|
||||||
self.set_install_wivrn_status(status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,14 +314,18 @@ impl SimpleComponent for MainView {
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let mut model = MainView {
|
let mut model = Self {
|
||||||
xrservice_active: false,
|
xrservice_active: false,
|
||||||
xrservice_type: XRServiceType::Monado,
|
xrservice_type: XRServiceType::Monado,
|
||||||
enable_debug_view: init.config.debug_view_enabled,
|
enable_debug_view: init.config.debug_view_enabled,
|
||||||
profiles_dropdown: None,
|
profiles_dropdown: None,
|
||||||
profile_names: vec![],
|
profile_names: vec![],
|
||||||
steam_launch_options: "".into(),
|
steam_launch_options: "".into(),
|
||||||
install_wivrn_status: InstallWivrnStatus::Done(None),
|
install_wivrn_box: InstallWivrnBox::builder()
|
||||||
|
.launch(InstallWivrnBoxInit {
|
||||||
|
selected_profile: init.selected_profile,
|
||||||
|
})
|
||||||
|
.detach(),
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
|
@ -4,3 +4,4 @@ pub mod about_dialog;
|
||||||
pub mod debug_view;
|
pub mod debug_view;
|
||||||
pub mod build_window;
|
pub mod build_window;
|
||||||
pub mod libsurvive_setup_window;
|
pub mod libsurvive_setup_window;
|
||||||
|
pub mod install_wivrn_box;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue