mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-08-03 06:38:52 +00:00
feat(stardust): start/stop & server settings
This commit is contained in:
parent
468fd9a269
commit
eb7fdb2b08
2 changed files with 213 additions and 13 deletions
|
@ -17,6 +17,7 @@ use crate::ui::app::{
|
||||||
BuildProfileDebugAction, ConfigFbtAction, DebugViewToggleAction,
|
BuildProfileDebugAction, ConfigFbtAction, DebugViewToggleAction,
|
||||||
};
|
};
|
||||||
use crate::ui::profile_editor::ProfileEditorInit;
|
use crate::ui::profile_editor::ProfileEditorInit;
|
||||||
|
use crate::ui::stardust::stardust_view::StardustViewInit;
|
||||||
use crate::ui::util::{limit_dropdown_width, warning_heading};
|
use crate::ui::util::{limit_dropdown_width, warning_heading};
|
||||||
use crate::xr_devices::XRDevice;
|
use crate::xr_devices::XRDevice;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
@ -49,7 +50,7 @@ pub struct MainView {
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
root_win: gtk::Window,
|
root_win: gtk::Window,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
stardust_view: Controller<StardustView>
|
stardust_view: Controller<StardustView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -382,7 +383,7 @@ impl SimpleComponent for MainView {
|
||||||
set_title: Some("XR"),
|
set_title: Some("XR"),
|
||||||
set_icon_name: Some("org.gabmus.envision-symbolic"),
|
set_icon_name: Some("org.gabmus.envision-symbolic"),
|
||||||
},
|
},
|
||||||
add_titled_with_icon: (model.stardust_view.widget(), Some("stardust_view"), "Stardust", "starred-symbolic"),
|
add_titled_with_icon: (model.stardust_view.widget(), Some("stardust_view"), "Stardust XR", "starred-symbolic"),
|
||||||
},
|
},
|
||||||
add_bottom_bar: bottom_bar = >k::Box {
|
add_bottom_bar: bottom_bar = >k::Box {
|
||||||
set_orientation: gtk::Orientation::Horizontal,
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
@ -661,7 +662,7 @@ impl SimpleComponent for MainView {
|
||||||
profile_delete_confirm_dialog,
|
profile_delete_confirm_dialog,
|
||||||
root_win: init.root_win.clone(),
|
root_win: init.root_win.clone(),
|
||||||
profile_editor: None,
|
profile_editor: None,
|
||||||
stardust_view: StardustView::builder().launch(()).detach(),
|
stardust_view: StardustView::builder().launch(StardustViewInit {}).detach(),
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
|
@ -1,34 +1,211 @@
|
||||||
use relm4::prelude::*;
|
use crate::{stateless_action, withclones};
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use relm4::{
|
||||||
|
actions::{ActionGroupName, RelmAction, RelmActionGroup},
|
||||||
|
new_action_group, new_stateless_action,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum StardustViewMsg {}
|
pub enum StardustViewMsg {
|
||||||
|
BuildStardust,
|
||||||
|
UpdateStardust,
|
||||||
|
StartClicked,
|
||||||
|
StopClicked,
|
||||||
|
RestartClicked,
|
||||||
|
|
||||||
|
AutostartChanged(bool),
|
||||||
|
StartAsOvelayChanged(bool),
|
||||||
|
OverlayPriorityChanged(u32),
|
||||||
|
DisableControllerChanged(bool),
|
||||||
|
RepoChanged(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum StardustViewOutMsg {}
|
pub enum StardustViewOutMsg {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StardustViewInit {}
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct StardustView {}
|
pub struct StardustView {
|
||||||
|
stardust_service_active: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for StardustView {
|
impl SimpleComponent for StardustView {
|
||||||
type Init = ();
|
type Init = StardustViewInit;
|
||||||
type Input = StardustViewMsg;
|
type Input = StardustViewMsg;
|
||||||
type Output = StardustViewOutMsg;
|
type Output = StardustViewOutMsg;
|
||||||
|
|
||||||
|
menu! {
|
||||||
|
stardust_menu: {
|
||||||
|
section! {
|
||||||
|
"_Build" => BuildStardustAction,
|
||||||
|
"_Update" => UpdateStardustAction,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
#[root]
|
||||||
|
gtk::ScrolledWindow {
|
||||||
|
set_hscrollbar_policy: gtk::PolicyType::Never,
|
||||||
|
set_hexpand: true,
|
||||||
|
set_vexpand: true,
|
||||||
|
adw::Clamp {
|
||||||
|
set_maximum_size: 600,
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
gtk::Label {
|
set_spacing: 12,
|
||||||
set_label: "Stardust",
|
set_margin_all: 12,
|
||||||
|
// service inactive
|
||||||
|
gtk::Box {
|
||||||
|
add_css_class: "linked",
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_hexpand: true,
|
||||||
|
set_vexpand: false,
|
||||||
|
#[track = "model.changed(Self::stardust_service_active())"]
|
||||||
|
set_visible: !model.stardust_service_active,
|
||||||
|
gtk::Button {
|
||||||
|
add_css_class: "suggested-action",
|
||||||
|
set_label: "Start",
|
||||||
|
set_hexpand: true,
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.input(Self::Input::StartClicked);
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
gtk::MenuButton {
|
||||||
|
set_icon_name: "view-more-symbolic",
|
||||||
|
set_menu_model: Some(&stardust_menu),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// service active
|
||||||
|
gtk::Box {
|
||||||
|
add_css_class: "linked",
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_hexpand: true,
|
||||||
|
set_vexpand: false,
|
||||||
|
#[track = "model.changed(Self::stardust_service_active())"]
|
||||||
|
set_visible: model.stardust_service_active,
|
||||||
|
gtk::Button {
|
||||||
|
add_css_class: "destructive-action",
|
||||||
|
set_label: "Stop",
|
||||||
|
set_hexpand: true,
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.input(Self::Input::StopClicked);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gtk::Button {
|
||||||
|
set_icon_name: "view-refresh-symbolic",
|
||||||
|
set_tooltip_text: Some("Restart"),
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.input(Self::Input::RestartClicked);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gtk::ListBox {
|
||||||
|
add_css_class: "boxed-list",
|
||||||
|
set_selection_mode: gtk::SelectionMode::None,
|
||||||
|
adw::SwitchRow {
|
||||||
|
set_title: "Autostart with XR Service",
|
||||||
|
// TODO: settings
|
||||||
|
// set_active: model.settings.autostart,
|
||||||
|
connect_active_notify[sender] => move |row| {
|
||||||
|
sender.input(Self::Input::AutostartChanged(row.is_active()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
adw::SwitchRow {
|
||||||
|
set_title: "Start as an overlay",
|
||||||
|
// TODO: settings
|
||||||
|
// set_active: model.settings.overlay,
|
||||||
|
connect_active_notify[sender] => move |row| {
|
||||||
|
sender.input(Self::Input::StartAsOvelayChanged(row.is_active()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
adw::SpinRow {
|
||||||
|
set_title: "Overlay priority",
|
||||||
|
set_digits: 0,
|
||||||
|
set_snap_to_ticks: true,
|
||||||
|
// TODO: settings -- here or in adj?
|
||||||
|
// set_value: model.settings.priority,
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_adjustment: overlay_priority_adj = >k::Adjustment {
|
||||||
|
set_lower: 0.0,
|
||||||
|
set_upper: f64::from(u32::MAX),
|
||||||
|
set_value: 0.0,
|
||||||
|
set_page_increment: 10.0,
|
||||||
|
set_step_increment: 1.0,
|
||||||
|
// TODO: settings
|
||||||
|
// set_value: model.settings.priority,
|
||||||
|
},
|
||||||
|
set_range: (0.0, f64::from(u32::MAX)),
|
||||||
|
connect_value_notify[sender] => move |row| {
|
||||||
|
sender.input(Self::Input::OverlayPriorityChanged(row.value() as u32));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// WARN: negative logic, maybe switch it to positive instead?
|
||||||
|
adw::SwitchRow {
|
||||||
|
set_title: "Disable controller",
|
||||||
|
set_subtitle_lines: 0,
|
||||||
|
set_subtitle: "Necessary if you plan on using hand tracking",
|
||||||
|
// TODO: settings
|
||||||
|
// set_active: model.settings.autostart,
|
||||||
|
connect_active_notify[sender] => move |row| {
|
||||||
|
sender.input(Self::Input::DisableControllerChanged(row.is_active()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
adw::EntryRow {
|
||||||
|
set_title: "Repository#git ref",
|
||||||
|
// TODO: settings
|
||||||
|
// set_text: model.settings.repo,
|
||||||
|
set_text: "https://github.com/StardustXR/server#main",
|
||||||
|
connect_changed[sender] => move |row| {
|
||||||
|
sender.input(Self::Input::RepoChanged(row.text().into()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
Self::Input::BuildStardust => {
|
||||||
|
println!("Build");
|
||||||
|
},
|
||||||
|
Self::Input::UpdateStardust => {
|
||||||
|
println!("Update");
|
||||||
|
},
|
||||||
|
Self::Input::StartClicked => {
|
||||||
|
println!("Start");
|
||||||
|
},
|
||||||
|
Self::Input::StopClicked => {
|
||||||
|
println!("Stop");
|
||||||
|
},
|
||||||
|
Self::Input::RestartClicked => {
|
||||||
|
println!("Restart");
|
||||||
|
},
|
||||||
|
Self::Input::AutostartChanged(val) => {
|
||||||
|
println!("Autostart: {}", val);
|
||||||
|
}
|
||||||
|
Self::Input::StartAsOvelayChanged(val) => {
|
||||||
|
println!("StartAsOvelayChanged: {}", val);
|
||||||
|
}
|
||||||
|
Self::Input::OverlayPriorityChanged(val) => {
|
||||||
|
println!("OverlayPriorityChanged: {}", val);
|
||||||
|
}
|
||||||
|
Self::Input::DisableControllerChanged(val) => {
|
||||||
|
println!("DisableControllerChanged: {}", val);
|
||||||
|
}
|
||||||
|
Self::Input::RepoChanged(val) => {
|
||||||
|
println!("RepoChanged: {}", val);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
|
@ -37,11 +214,33 @@ impl SimpleComponent for StardustView {
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let model = Self {
|
let model = Self {
|
||||||
|
stardust_service_active: false,
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
let mut actions = RelmActionGroup::<StardustActionGroup>::new();
|
||||||
|
|
||||||
|
{
|
||||||
|
withclones![sender];
|
||||||
|
stateless_action!(actions, BuildStardustAction, {
|
||||||
|
sender.input_sender().emit(Self::Input::BuildStardust);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
|
withclones![sender];
|
||||||
|
stateless_action!(actions, UpdateStardustAction, {
|
||||||
|
sender.input_sender().emit(Self::Input::UpdateStardust);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
root.insert_action_group(StardustActionGroup::NAME, Some(&actions.into_action_group()));
|
||||||
|
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_action_group!(StardustActionGroup, "stardust");
|
||||||
|
new_stateless_action!(BuildStardustAction, StardustActionGroup, "build");
|
||||||
|
new_stateless_action!(UpdateStardustAction, StardustActionGroup, "update");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue