mirror of https://github.com/wayvr-org/wayvr.git
Merge 7d9af16b20 into cb3aa42bd9
This commit is contained in:
commit
fc2c71e72c
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="currentColor" d="M2 21v-2h20v2zm1-3v-7h3v7zm5 0V6h3v12zm5 0V9h3v9zm5 0V3h3v15z"/></svg>
|
||||
|
After Width: | Height: | Size: 297 B |
|
|
@ -31,6 +31,13 @@
|
|||
<RadioBox text="${text}" translation="${translation}" value="${value}" tooltip="${tooltip}" />
|
||||
</template>
|
||||
|
||||
<template name="StatRow">
|
||||
<div flex_direction="row" justify_content="space_between" align_items="center" gap="12" width="100%">
|
||||
<label weight="bold" translation="${translation}" />
|
||||
<label id="${id}" weight="bold" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="ButtonText">
|
||||
<Button id="${id}" height="32" tooltip="${translation}_HELP" padding="4" gap="8">
|
||||
<sprite src_builtin="${icon}" height="24" width="24" />
|
||||
|
|
@ -69,6 +76,7 @@
|
|||
<Tab macro="tab_style" name="space_drag" translation="APP_SETTINGS.SPACE_DRAG" sprite_src_builtin="dashboard/drag.svg" />
|
||||
<Tab macro="tab_style" name="misc" translation="APP_SETTINGS.MISC" sprite_src_builtin="dashboard/blocks.svg" />
|
||||
<Tab macro="tab_style" name="autostart_apps" translation="APP_SETTINGS.AUTOSTART_APPS" sprite_src_builtin="dashboard/apps.svg" />
|
||||
<Tab macro="tab_style" name="statistics" translation="APP_SETTINGS.STATISTICS" sprite_src_builtin="dashboard/barchart.svg" />
|
||||
<Tab macro="tab_style" name="troubleshooting" translation="APP_SETTINGS.TROUBLESHOOTING" sprite_src_builtin="dashboard/cpu.svg" />
|
||||
</Tabs>
|
||||
<div flex_wrap="wrap" justify_content="stretch" gap="4" id="settings_root" width="100%">
|
||||
|
|
|
|||
|
|
@ -243,7 +243,11 @@
|
|||
"GRID_OPACITY_HELP": "Deckkraft des Bodengitters, wenn die Skymap aktiviert ist",
|
||||
"XWAYLAND_BY_DEFAULT": "Apps standardmäßig im Kompatibilitätsmodus starten",
|
||||
"SAVE": "Speichern",
|
||||
"CANCEL": "Abbrechen"
|
||||
"CANCEL": "Abbrechen",
|
||||
"STATISTICS": "Statistiken",
|
||||
"ROTATIONS": "HMD-Rotationen",
|
||||
"SESSION_TIME": "Sitzungszeit",
|
||||
"IPD_MM": "Pupillenabstand (mm)"
|
||||
},
|
||||
"APPLICATION_LAUNCHER": "Programmstarter",
|
||||
"APPLICATION_STARTED": "Anwendung gestartet",
|
||||
|
|
@ -346,4 +350,4 @@
|
|||
"ADD_TO_FAVOURITES_HINT": "Voreinstellung speichern und an die App-Schublade anheften",
|
||||
"REMOVE_FROM_FAVOURITES": "Aus angehefteten Anwendungen entfernen",
|
||||
"EMPTY": "Leer"
|
||||
}
|
||||
}
|
||||
|
|
@ -132,6 +132,7 @@ APP_SETTINGS.INPUT_PROFILES,Change Input Bindings,Button label in Settings > Con
|
|||
APP_SETTINGS.INPUT_PROFILES_HELP,OpenXR controller input bindings,Tooltip for the Change Input Bindings button.
|
||||
APP_SETTINGS.INVERT_SCROLL_DIRECTION_X,Invert horizontal scroll direction,Checkbox label in Settings > Features tab. Inverts the horizontal scroll direction.
|
||||
APP_SETTINGS.INVERT_SCROLL_DIRECTION_Y,Invert vertical scroll direction,Checkbox label in Settings > Features tab. Inverts the vertical scroll direction.
|
||||
APP_SETTINGS.IPD_MM,Interpupilary distance (mm),Distance between eyes (IPD), in milimeters.
|
||||
APP_SETTINGS.KEYBOARD_MIDDLE_CLICK,Keyboard middle click,Dropdown label in Settings > Features tab. Selects the modifier key used for middle-click when typing with the laser pointer.
|
||||
APP_SETTINGS.KEYBOARD_MIDDLE_CLICK_HELP,"Modifier to use when typing
|
||||
with purple laser",Tooltip for the keyboard middle-click setting.
|
||||
|
|
@ -225,6 +226,9 @@ APP_SETTINGS.SPACE_GRAVITY_GROUND_FRICTION_HELP,"Amount of friction slowing you
|
|||
APP_SETTINGS.SPACE_GRAVITY_FLOOR_HEIGHT,Floor height,Setting in the space gravity physics panel. The Y position where the virtual floor is.
|
||||
APP_SETTINGS.SPACE_GRAVITY_FLOOR_HEIGHT_HELP,The Y position where the floor is. Gravity stops when you reach this height.,Tooltip for the floor height setting.
|
||||
APP_SETTINGS.SPACE_ROTATE_UNLOCKED,Allow space rotate on all axes,"Checkbox in Settings > Space Drag tab. Unlocks space rotate to work on all axes. ""Space"" in this context refers to ""Playspace"" which was translated as ""${DEFINITIONS.PLAYSPACE}""."
|
||||
APP_SETTINGS.ROTATIONS,HMD rotations,Number of full 360-degree rotations of the HMD since startup. Shown in Settings > Statistics.
|
||||
APP_SETTINGS.SESSION_TIME,Session time,Time since WayVR started. Shown in Settings > Statistics.
|
||||
APP_SETTINGS.STATISTICS,Statistics,Category header in Settings.
|
||||
APP_SETTINGS.TROUBLESHOOTING,Troubleshooting,"Category header in Settings. Groups diagnostic/reset actions like clearing tokens, wiping config, and restarting."
|
||||
APP_SETTINGS.UI_GRADIENT_INTENSITY,UI Gradient intensity,Slider in Settings > Look & Feel tab. Controls the intensity of gradient effects on the UI (range 0.0-1.0).
|
||||
APP_SETTINGS.UPRIGHT_SCREEN_FIX,Upright screen fix,Checkbox in Settings > Miscellaneous tab. Fixes upright screen orientation on some desktop environments.
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 135.
|
|
|
@ -146,6 +146,7 @@
|
|||
"INPUT_PROFILES_HELP": "OpenXR controller input bindings",
|
||||
"INVERT_SCROLL_DIRECTION_X": "Invert horizontal scroll direction",
|
||||
"INVERT_SCROLL_DIRECTION_Y": "Invert vertical scroll direction",
|
||||
"IPD_MM": "Interpupilary distance (mm)",
|
||||
"KEYBOARD_MIDDLE_CLICK": "Keyboard middle click",
|
||||
"KEYBOARD_MIDDLE_CLICK_HELP": "Modifier to use when typing\nwith purple laser",
|
||||
"KEYBOARD_SOUND_ENABLED": "Keyboard sounds",
|
||||
|
|
@ -223,6 +224,9 @@
|
|||
"SPACE_GRAVITY_FLOOR_HEIGHT": "Floor height",
|
||||
"SPACE_GRAVITY_FLOOR_HEIGHT_HELP": "The Y position where the floor is. Gravity stops when you reach this height.",
|
||||
"SPACE_ROTATE_UNLOCKED": "Allow space rotate on all axes",
|
||||
"ROTATIONS": "HMD rotations",
|
||||
"SESSION_TIME": "Session time",
|
||||
"STATISTICS": "Statistics",
|
||||
"TROUBLESHOOTING": "Troubleshooting",
|
||||
"UI_GRADIENT_INTENSITY": "UI Gradient intensity",
|
||||
"UPRIGHT_SCREEN_FIX": "Upright screen fix",
|
||||
|
|
@ -346,4 +350,4 @@
|
|||
"ADD_TO_FAVOURITES_HINT": "Save preset and pin it to the app drawer",
|
||||
"REMOVE_FROM_FAVOURITES": "Remove from pinned apps",
|
||||
"EMPTY": "Empty"
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,11 @@
|
|||
"GRID_OPACITY_HELP": "Opacidad de la rejilla del suelo cuando el skymap está activado",
|
||||
"XWAYLAND_BY_DEFAULT": "Ejecutar apps en modo de compatibilidad por defecto",
|
||||
"SAVE": "Guardar",
|
||||
"CANCEL": "Cancelar"
|
||||
"CANCEL": "Cancelar",
|
||||
"STATISTICS": "Estadísticas",
|
||||
"ROTATIONS": "Rotaciones del HMD",
|
||||
"SESSION_TIME": "Tiempo de sesión",
|
||||
"IPD_MM": "Distancia interpupilar (mm)"
|
||||
},
|
||||
"APPLICATION_LAUNCHER": "Lanzador de aplicaciones",
|
||||
"APPLICATION_STARTED": "Aplicación iniciada",
|
||||
|
|
@ -346,4 +350,4 @@
|
|||
"ADD_TO_FAVOURITES_HINT": "Guardar ajuste y fijarlo al cajón de aplicaciones",
|
||||
"REMOVE_FROM_FAVOURITES": "Quitar de aplicaciones fijadas",
|
||||
"EMPTY": "Vacío"
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,11 @@
|
|||
"GRID_OPACITY_HELP": "Opacità della griglia del pavimento quando lo skymap è attivo",
|
||||
"XWAYLAND_BY_DEFAULT": "Avvia le app in modalità compatibilità per impostazione predefinita",
|
||||
"SAVE": "Salva",
|
||||
"CANCEL": "Annulla"
|
||||
"CANCEL": "Annulla",
|
||||
"STATISTICS": "Statistiche",
|
||||
"ROTATIONS": "Rotazioni HMD",
|
||||
"SESSION_TIME": "Tempo sessione",
|
||||
"IPD_MM": "Distanza interpupillare (mm)"
|
||||
},
|
||||
"APPLICATION_LAUNCHER": "Avvio applicazioni",
|
||||
"APPLICATION_STARTED": "Applicazione avviata",
|
||||
|
|
@ -346,4 +350,4 @@
|
|||
"ADD_TO_FAVOURITES_HINT": "Salva il preset e fissalo al cassetto delle app",
|
||||
"REMOVE_FROM_FAVOURITES": "Rimuovi dalle app fissate",
|
||||
"EMPTY": "Vuoto"
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,11 @@
|
|||
"GRID_OPACITY_HELP": "スカイマップ有効時のフロアグリッドの不透明度",
|
||||
"XWAYLAND_BY_DEFAULT": "デフォルトで互換モードでアプリを起動",
|
||||
"SAVE": "保存",
|
||||
"CANCEL": "キャンセル"
|
||||
"CANCEL": "キャンセル",
|
||||
"STATISTICS": "統計",
|
||||
"ROTATIONS": "HMD回転数",
|
||||
"SESSION_TIME": "セッション時間",
|
||||
"IPD_MM": "瞳孔間距離 (mm)"
|
||||
},
|
||||
"APPLICATION_LAUNCHER": "アプリランチャー",
|
||||
"APPLICATION_STARTED": "アプリが起動しました",
|
||||
|
|
@ -346,4 +350,4 @@
|
|||
"ADD_TO_FAVOURITES_HINT": "プリセットを保存し、アプリドロワーに固定する",
|
||||
"REMOVE_FROM_FAVOURITES": "固定済みアプリから外す",
|
||||
"EMPTY": "なし"
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,11 @@
|
|||
"GRID_OPACITY_HELP": "Przezroczystość siatki podłogi przy włączonym Skymapie",
|
||||
"XWAYLAND_BY_DEFAULT": "Uruchamiaj aplikacje domyślnie w trybie kompatybilności",
|
||||
"SAVE": "Zapisz",
|
||||
"CANCEL": "Anuluj"
|
||||
"CANCEL": "Anuluj",
|
||||
"STATISTICS": "Statystyki",
|
||||
"ROTATIONS": "Obroty HMD",
|
||||
"SESSION_TIME": "Czas sesji",
|
||||
"IPD_MM": "Rozstaw źrenic (mm)"
|
||||
},
|
||||
"APPLICATION_LAUNCHER": "Launcher aplikacji",
|
||||
"APPLICATION_STARTED": "Uruchomiono aplikację",
|
||||
|
|
@ -346,4 +350,4 @@
|
|||
"ADD_TO_FAVOURITES_HINT": "Zapisz preset i przypnij go do szuflady aplikacji",
|
||||
"REMOVE_FROM_FAVOURITES": "Usuń z przypiętych aplikacji",
|
||||
"EMPTY": "Puste"
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,11 @@
|
|||
"GRID_OPACITY_HELP": "启用天空盒时地面网格的不透明度",
|
||||
"XWAYLAND_BY_DEFAULT": "默认以兼容模式运行应用程序",
|
||||
"SAVE": "保存",
|
||||
"CANCEL": "取消"
|
||||
"CANCEL": "取消",
|
||||
"STATISTICS": "统计数据",
|
||||
"ROTATIONS": "HMD 旋转次数",
|
||||
"SESSION_TIME": "会话时间",
|
||||
"IPD_MM": "瞳距 (mm)"
|
||||
},
|
||||
"APPLICATION_LAUNCHER": "应用启动器",
|
||||
"APPLICATION_STARTED": "应用程序已启动",
|
||||
|
|
@ -346,4 +350,4 @@
|
|||
"ADD_TO_FAVOURITES_HINT": "保存预设并将其固定到应用抽屉",
|
||||
"REMOVE_FROM_FAVOURITES": "从固定应用中移除",
|
||||
"EMPTY": "暂无"
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,20 @@ pub fn options_category(
|
|||
mp.parser_state.get_widget_id(&id)
|
||||
}
|
||||
|
||||
pub fn options_stat_row(mp: &mut MacroParams, parent: WidgetID, translation: &str) -> anyhow::Result<WidgetID> {
|
||||
let id = mp.idx.to_string();
|
||||
mp.idx += 1;
|
||||
|
||||
let mut params = TemplateParams::new();
|
||||
params.insert("id", &id);
|
||||
params.insert("translation", translation);
|
||||
|
||||
mp.parser_state
|
||||
.instantiate_template(mp.doc_params, "StatRow", mp.layout, parent, params)?;
|
||||
|
||||
mp.parser_state.get_widget_id(&id)
|
||||
}
|
||||
|
||||
pub fn options_checkbox(mp: &mut MacroParams, parent: WidgetID, setting: SettingType) -> anyhow::Result<()> {
|
||||
let id = mp.idx.to_string();
|
||||
mp.idx += 1;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use wgui::{
|
|||
use wlx_common::{
|
||||
config::GeneralConfig,
|
||||
config_io::ConfigRoot,
|
||||
dash_interface::{ConfigChangeKind, DashPlayspaceTask, InterfaceFeats},
|
||||
dash_interface::{ConfigChangeKind, DashPlayspaceTask, HmdStats, InterfaceFeats},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -40,6 +40,7 @@ mod tab_look_and_feel;
|
|||
mod tab_misc;
|
||||
mod tab_skybox;
|
||||
mod tab_space_drag;
|
||||
mod tab_statistics;
|
||||
mod tab_troubleshooting;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -51,6 +52,7 @@ pub(crate) enum TabNameEnum {
|
|||
Misc,
|
||||
Skybox,
|
||||
SpaceDrag,
|
||||
Statistics,
|
||||
Troubleshooting,
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +66,7 @@ impl TabNameEnum {
|
|||
"misc" => Some(TabNameEnum::Misc),
|
||||
"skybox" => Some(TabNameEnum::Skybox),
|
||||
"space_drag" => Some(TabNameEnum::SpaceDrag),
|
||||
"statistics" => Some(TabNameEnum::Statistics),
|
||||
"troubleshooting" => Some(TabNameEnum::Troubleshooting),
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -101,8 +104,12 @@ struct SettingUpdatedParams<'a> {
|
|||
setting_type: SettingType,
|
||||
}
|
||||
|
||||
struct UpdateExtra {
|
||||
hmd_stats: HmdStats,
|
||||
}
|
||||
|
||||
trait SettingsTab {
|
||||
fn update(&mut self, _par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||
fn update(&mut self, _par: &mut ViewUpdateParams, _extra: &UpdateExtra) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -144,12 +151,17 @@ impl<T> Tab<T> for TabSettings<T> {
|
|||
if let Some(tab) = &mut self.current_tab {
|
||||
let mut config_change_kind = None;
|
||||
|
||||
tab.update(&mut ViewUpdateParams {
|
||||
layout: &mut frontend.layout,
|
||||
executor: &frontend.executor,
|
||||
general_config: frontend.interface.general_config(data),
|
||||
config_change_kind: &mut config_change_kind,
|
||||
})?;
|
||||
let hmd_stats = frontend.interface.hmd_stats(data);
|
||||
|
||||
tab.update(
|
||||
&mut ViewUpdateParams {
|
||||
layout: &mut frontend.layout,
|
||||
executor: &frontend.executor,
|
||||
general_config: frontend.interface.general_config(data),
|
||||
config_change_kind: &mut config_change_kind,
|
||||
},
|
||||
&UpdateExtra { hmd_stats },
|
||||
)?;
|
||||
|
||||
if let Some(kind) = config_change_kind {
|
||||
frontend.interface.config_changed(data, kind);
|
||||
|
|
@ -734,6 +746,9 @@ impl<T> TabSettings<T> {
|
|||
TabNameEnum::Skybox => {
|
||||
self.current_tab = Some(Box::new(tab_skybox::State::mount(settings_mount_params)?));
|
||||
}
|
||||
TabNameEnum::Statistics => {
|
||||
self.current_tab = Some(Box::new(tab_statistics::State::mount(settings_mount_params)?));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use wgui::{
|
|||
components::button::ComponentButton, globals::WguiGlobals, layout::WidgetID, parser::Fetchable, task::Tasks,
|
||||
};
|
||||
|
||||
use crate::tab::settings::{horiz_cell, mount_requires_restart};
|
||||
use crate::tab::settings::{UpdateExtra, horiz_cell, mount_requires_restart};
|
||||
use crate::util::popup_manager::PopupHolder;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -29,7 +29,7 @@ pub struct State {
|
|||
}
|
||||
|
||||
impl SettingsTab for State {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams, _extra: &UpdateExtra) -> anyhow::Result<()> {
|
||||
self.popup_input_profiles.update(par)?;
|
||||
|
||||
for task in self.tasks.drain() {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use wlx_common::{async_executor::AsyncExecutor, config::GeneralConfig, dash_inte
|
|||
use crate::{
|
||||
frontend::FrontendTasks,
|
||||
tab::settings::{
|
||||
SettingType, SettingsMountParams, SettingsTab, TabNameEnum, Task as ParentTask, horiz_cell,
|
||||
SettingType, SettingsMountParams, SettingsTab, TabNameEnum, Task as ParentTask, UpdateExtra, horiz_cell,
|
||||
macros::{MacroParams, options_category, options_checkbox, options_range_f32},
|
||||
},
|
||||
util::{
|
||||
|
|
@ -50,7 +50,7 @@ pub struct State {
|
|||
}
|
||||
|
||||
impl SettingsTab for State {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams, _extra: &UpdateExtra) -> anyhow::Result<()> {
|
||||
self.popup_download.update(par)?;
|
||||
self.popup_dialog.update(par)?;
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ impl SettingsTab for State {
|
|||
par.general_config.whisper_model = model.file_name.into();
|
||||
par.config_change_kind.replace(ConfigChangeKind::Other);
|
||||
|
||||
// reload tab so that the downloaded checkmarks get populated
|
||||
// reload tab so that the downloaded check marks get populated
|
||||
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use wgui::{
|
|||
use crate::{
|
||||
frontend::FrontendTasks,
|
||||
tab::settings::{
|
||||
SettingType, SettingsMountParams, SettingsTab, horiz_cell,
|
||||
SettingType, SettingsMountParams, SettingsTab, UpdateExtra, horiz_cell,
|
||||
macros::{options_category, options_checkbox, options_dropdown, options_slider_f32},
|
||||
mount_requires_restart,
|
||||
},
|
||||
|
|
@ -32,7 +32,7 @@ pub struct State {
|
|||
}
|
||||
|
||||
impl SettingsTab for State {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams, _extra: &UpdateExtra) -> anyhow::Result<()> {
|
||||
self.popup_color_palettes.update(par)?;
|
||||
|
||||
for task in self.tasks.drain() {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use wgui::{assets::AssetPath, i18n::Translation, layout::Layout, task::Tasks};
|
|||
use crate::{
|
||||
frontend::FrontendTasks,
|
||||
tab::settings::{
|
||||
SettingType, SettingsMountParams, SettingsTab,
|
||||
SettingType, SettingsMountParams, SettingsTab, UpdateExtra,
|
||||
macros::{options_category, options_checkbox, options_slider_f32},
|
||||
},
|
||||
util::{popup_manager::PopupHolder, wgui_simple},
|
||||
|
|
@ -22,7 +22,7 @@ pub struct State {
|
|||
}
|
||||
|
||||
impl SettingsTab for State {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams, _extra: &UpdateExtra) -> anyhow::Result<()> {
|
||||
self.popup_skymap_list.update(par)?;
|
||||
|
||||
for task in self.tasks.drain() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
use crate::{
|
||||
tab::settings::{
|
||||
SettingsMountParams, SettingsTab, UpdateExtra,
|
||||
macros::{options_category, options_stat_row},
|
||||
},
|
||||
views::ViewUpdateParams,
|
||||
};
|
||||
use std::f32::consts::TAU;
|
||||
use wgui::{i18n::Translation, layout::WidgetID, widget::label::WidgetLabel};
|
||||
|
||||
pub struct State {
|
||||
id_label_rotations: WidgetID,
|
||||
id_label_session_time: WidgetID,
|
||||
id_label_ipd: WidgetID,
|
||||
last_rotations: f32,
|
||||
last_session_time_ms: u64,
|
||||
last_ipd: f32,
|
||||
}
|
||||
|
||||
impl SettingsTab for State {
|
||||
fn update(&mut self, par: &mut ViewUpdateParams, extra: &UpdateExtra) -> anyhow::Result<()> {
|
||||
let hmd_stats = &extra.hmd_stats;
|
||||
|
||||
let mut common = par.layout.common();
|
||||
|
||||
// 1 - one rotation, 2 - two rotations
|
||||
// accuracy up to 0.01 rotations
|
||||
let rotations = (hmd_stats.rotations_rad / TAU * 100.0).round() / 100.0;
|
||||
|
||||
if rotations != self.last_rotations {
|
||||
self.last_rotations = rotations;
|
||||
|
||||
let mut label = common.state.widgets.cast_as::<WidgetLabel>(self.id_label_rotations)?;
|
||||
label.set_text(&mut common, Translation::from_raw_text_string(rotations.to_string()));
|
||||
}
|
||||
|
||||
if hmd_stats.session_time_ms != self.last_session_time_ms {
|
||||
self.last_session_time_ms = hmd_stats.session_time_ms;
|
||||
|
||||
let mut label = common
|
||||
.state
|
||||
.widgets
|
||||
.cast_as::<WidgetLabel>(self.id_label_session_time)?;
|
||||
label.set_text(
|
||||
&mut common,
|
||||
Translation::from_raw_text_string(format_duration(hmd_stats.session_time_ms)),
|
||||
);
|
||||
}
|
||||
|
||||
if hmd_stats.ipd != self.last_ipd {
|
||||
self.last_ipd = hmd_stats.ipd;
|
||||
|
||||
let mut label = common.state.widgets.cast_as::<WidgetLabel>(self.id_label_ipd)?;
|
||||
label.set_text(
|
||||
&mut common,
|
||||
Translation::from_raw_text_string(format!("{:.2}", hmd_stats.ipd)),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn format_duration(ms: u64) -> String {
|
||||
let total_secs = ms / 1000;
|
||||
let h = total_secs / 3600;
|
||||
let m = (total_secs % 3600) / 60;
|
||||
let s = total_secs % 60;
|
||||
|
||||
if h > 0 {
|
||||
format!("{h}:{m:02}:{s:02}")
|
||||
} else {
|
||||
format!("{m}:{s:02}")
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn mount(par: SettingsMountParams) -> anyhow::Result<State> {
|
||||
let c = options_category(
|
||||
par.mp,
|
||||
par.id_parent,
|
||||
"APP_SETTINGS.STATISTICS",
|
||||
"dashboard/barchart.svg",
|
||||
)?;
|
||||
|
||||
let id_label_rotations = options_stat_row(par.mp, c, "APP_SETTINGS.ROTATIONS")?;
|
||||
let id_label_session_time = options_stat_row(par.mp, c, "APP_SETTINGS.SESSION_TIME")?;
|
||||
let id_label_ipd = options_stat_row(par.mp, c, "APP_SETTINGS.IPD_MM")?;
|
||||
|
||||
Ok(State {
|
||||
id_label_rotations,
|
||||
id_label_session_time,
|
||||
id_label_ipd,
|
||||
last_rotations: f32::MIN,
|
||||
last_session_time_ms: u64::MAX,
|
||||
last_ipd: f32::MIN,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -15,10 +15,10 @@ cd "$(dirname "$0")"
|
|||
bun install
|
||||
|
||||
# model URL:
|
||||
# https://huggingface.co/unsloth/gemma-4-26B-A4B-it-GGUF
|
||||
# https://huggingface.co/unsloth/gemma-4-31B-it-GGUF
|
||||
# you can specify your own if you want to.
|
||||
if [ -z "${MODEL}" ]; then
|
||||
export MODEL="gemma-4-26B-A4B-it-UD-Q3_K_M"
|
||||
export MODEL="gemma-4-31B-it-Q4_K_M"
|
||||
fi
|
||||
|
||||
if [ -z "${LLAMA_BASE_URL}" ]; then
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::f32::consts::PI;
|
||||
use std::f32::consts::{PI, TAU};
|
||||
use std::process::{Child, Command};
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
|
@ -75,6 +75,8 @@ pub struct InputState {
|
|||
pub picking_focus: FocusPickState,
|
||||
processes: Vec<Child>,
|
||||
disable_lerp_until: Instant,
|
||||
pub head_yaw_total: f64,
|
||||
head_last_yaw: Option<f32>,
|
||||
}
|
||||
|
||||
impl InputState {
|
||||
|
|
@ -88,6 +90,8 @@ impl InputState {
|
|||
handsfree_state: PointerState::default(),
|
||||
picking_focus: FocusPickState::None,
|
||||
disable_lerp_until: Instant::now(),
|
||||
head_yaw_total: 0.0,
|
||||
head_last_yaw: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,6 +106,34 @@ impl InputState {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_head_yaw(&mut self) {
|
||||
let fwd = self.hmd.transform_vector3a(Vec3A::NEG_Z);
|
||||
if fwd.x * fwd.x + fwd.z * fwd.z < 0.01 {
|
||||
return;
|
||||
}
|
||||
|
||||
let yaw = (-fwd.x).atan2(-fwd.z) as f64;
|
||||
if !yaw.is_finite() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(last) = self.head_last_yaw else {
|
||||
self.head_last_yaw = Some(yaw as f32);
|
||||
return;
|
||||
};
|
||||
|
||||
let mut delta = (yaw - last as f64).rem_euclid(TAU as f64);
|
||||
if delta > PI as f64 {
|
||||
delta -= TAU as f64;
|
||||
}
|
||||
|
||||
if delta.abs() <= (PI / 4.0) as f64 {
|
||||
self.head_yaw_total -= delta;
|
||||
}
|
||||
|
||||
self.head_last_yaw = Some(yaw as f32);
|
||||
}
|
||||
|
||||
pub fn apply_handsfree_action(&mut self, params: HandsfreeParams) {
|
||||
const fn set_true(v: &mut bool) {
|
||||
*v = true;
|
||||
|
|
@ -154,6 +186,8 @@ impl InputState {
|
|||
}
|
||||
|
||||
pub fn post_update(&mut self, session: &AppSession) {
|
||||
self.update_head_yaw();
|
||||
|
||||
for hand in &mut self.pointers {
|
||||
#[cfg(debug_assertions)]
|
||||
debug_print_hand(hand);
|
||||
|
|
|
|||
|
|
@ -185,7 +185,9 @@ impl OpenVrInputSource {
|
|||
let _ = input.update_actions(&mut [aas_left, aas_right]);
|
||||
|
||||
let devices = system.get_device_to_absolute_tracking_pose(universe.clone(), 0.005);
|
||||
app.input_state.hmd = devices[0].mDeviceToAbsoluteTracking.to_affine();
|
||||
if devices[0].bPoseIsValid {
|
||||
app.input_state.hmd = devices[0].mDeviceToAbsoluteTracking.to_affine();
|
||||
}
|
||||
|
||||
for i in 0..2 {
|
||||
let hand = &mut self.hands[i];
|
||||
|
|
|
|||
|
|
@ -928,7 +928,7 @@ impl WvrServerState {
|
|||
if !self.grab_toast_sent {
|
||||
self.grab_toast_sent = true;
|
||||
let text = &globals.i18n().translate("NOTIFICATION.WE_ARE_GRABBING");
|
||||
let _ = DbusConnector::notify_send("WayVR", &text, 1, 5000, 0, true);
|
||||
let _ = DbusConnector::notify_send("WayVR", text, 1, 5000, 0, true);
|
||||
}
|
||||
}
|
||||
input_capture::CapturedEvent::Ungrabbed => {
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ impl Connection {
|
|||
pos: to_arr(¶ms.input_state.pointers[0].raw_pose.translation),
|
||||
},
|
||||
right: WlxInputStatePointer {
|
||||
pos: to_arr(¶ms.input_state.pointers[0].raw_pose.translation),
|
||||
pos: to_arr(¶ms.input_state.pointers[1].raw_pose.translation),
|
||||
},
|
||||
},
|
||||
)),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use wlx_common::{
|
|||
overlays::{BackendAttrib, BackendAttribValue},
|
||||
};
|
||||
use wlx_common::{
|
||||
timestep::Timestep,
|
||||
timestep::{self, Timestep},
|
||||
windowing::{OverlayWindowState, Positioning},
|
||||
};
|
||||
|
||||
|
|
@ -579,6 +579,14 @@ impl DashInterface<AppState> for DashInterfaceLive {
|
|||
data.feats
|
||||
}
|
||||
|
||||
fn hmd_stats(&mut self, data: &mut AppState) -> dash_interface::HmdStats {
|
||||
dash_interface::HmdStats {
|
||||
rotations_rad: data.input_state.head_yaw_total as f32,
|
||||
session_time_ms: timestep::get_micros() / 1000,
|
||||
ipd: data.input_state.ipd,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "openxr")]
|
||||
fn monado_client_list(
|
||||
&mut self,
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ impl InterfaceFeats {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct HmdStats {
|
||||
pub rotations_rad: f32, // total raw in radians
|
||||
pub session_time_ms: u64,
|
||||
pub ipd: f32,
|
||||
}
|
||||
|
||||
pub trait DashInterface<T> {
|
||||
fn window_list(&mut self, data: &mut T) -> anyhow::Result<Vec<WvrWindow>>;
|
||||
fn window_set_visible(&mut self, data: &mut T, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>;
|
||||
|
|
@ -92,6 +99,7 @@ pub trait DashInterface<T> {
|
|||
fn restart(&mut self, data: &mut T);
|
||||
fn toggle_dashboard(&mut self, data: &mut T);
|
||||
fn get_feats(&mut self, data: &mut T) -> InterfaceFeats;
|
||||
fn hmd_stats(&mut self, data: &mut T) -> HmdStats;
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
|
|
|
|||
|
|
@ -243,6 +243,14 @@ impl DashInterface<()> for DashInterfaceEmulated {
|
|||
}
|
||||
}
|
||||
|
||||
fn hmd_stats(&mut self, _data: &mut ()) -> dash_interface::HmdStats {
|
||||
dash_interface::HmdStats {
|
||||
rotations_rad: 0.42,
|
||||
session_time_ms: crate::timestep::get_micros() / 1000,
|
||||
ipd: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
fn monado_client_list(
|
||||
&mut self,
|
||||
_data: &mut (),
|
||||
|
|
|
|||
Loading…
Reference in New Issue