Audio settings pop-up
This commit is contained in:
@@ -130,8 +130,12 @@
|
|||||||
|
|
||||||
<!-- Left bottom side -->
|
<!-- Left bottom side -->
|
||||||
<div margin_left="8">
|
<div margin_left="8">
|
||||||
<sprite src="dashboard/volume.svg" width="24" height="24" margin="8" />
|
<Button id="btn_audio" color="#FFFFFF00" border_color="#FFFFFF00" tooltip="AUDIO.VOLUME" tooltip_side="top">
|
||||||
<sprite src="dashboard/recenter.svg" width="24" height="24" margin="8" />
|
<sprite src="dashboard/volume.svg" width="24" height="24" margin="8" />
|
||||||
|
</Button>
|
||||||
|
<Button id="btn_recenter" color="#FFFFFF00" border_color="#FFFFFF00" tooltip="ACTIONS.RECENTER_PLAYSPACE" tooltip_side="top">
|
||||||
|
<sprite src="dashboard/recenter.svg" width="24" height="24" margin="8" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right bottom side -->
|
<!-- Right bottom side -->
|
||||||
|
|||||||
47
dash-frontend/assets/gui/view/audio_settings.xml
Normal file
47
dash-frontend/assets/gui/view/audio_settings.xml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<layout>
|
||||||
|
<include src="../t_group_box.xml" />
|
||||||
|
|
||||||
|
<!-- device_name, device_icon -->
|
||||||
|
<template name="AudioDevice">
|
||||||
|
<rectangle macro="group_box">
|
||||||
|
<div width="100%" align_items="center" justify_content="center" gap="8">
|
||||||
|
<sprite src="${device_icon}" width="16" height="16" />
|
||||||
|
<label translation="${device_name}" margin_right="8" size="12" weight="bold" />
|
||||||
|
</div>
|
||||||
|
<div width="100%" align_items="center">
|
||||||
|
<CheckBox />
|
||||||
|
<Button>
|
||||||
|
<sprite src="dashboard/volume.svg" width="20" height="20" margin="4" margin_left="8" margin_right="8" />
|
||||||
|
</Button>
|
||||||
|
<Slider flex_grow="1" height="16" min_value="0" max_value="150" margin_left="8" />
|
||||||
|
</div>
|
||||||
|
</rectangle>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- src, translation -->
|
||||||
|
<template name="BottomButton">
|
||||||
|
<Button flex_grow="1">
|
||||||
|
<sprite src="${src}"
|
||||||
|
min_width="24" min_height="24" width="24" height="24" margin="4" margin_left="16" />
|
||||||
|
<label translation="${translation}" weight="bold" margin_right="16" />
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<elements>
|
||||||
|
<AudioDevice device_name="Analog Stereo Output" device_icon="dashboard/minijack.svg" />
|
||||||
|
<AudioDevice device_name="My spectacular display" device_icon="dashboard/displayport.svg" />
|
||||||
|
<AudioDevice device_name="Foobar device" device_icon="dashboard/minijack.svg" />
|
||||||
|
|
||||||
|
<!-- bottom buttons -->
|
||||||
|
<div flex_direction="row" gap="4">
|
||||||
|
<Button tooltip="AUDIO.AUTO_SWITCH_TO_VR_AUDIO" color="#00CCFF" tooltip_side="right">
|
||||||
|
<sprite src="dashboard/magic_wand.svg"
|
||||||
|
min_width="24" width="24" height="24" margin="4" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<BottomButton src="dashboard/volume.svg" translation="AUDIO.SPEAKERS" />
|
||||||
|
<BottomButton src="dashboard/microphone.svg" translation="AUDIO.MICROPHONES" />
|
||||||
|
<BottomButton src="dashboard/cpu.svg" translation="AUDIO.CARDS" />
|
||||||
|
</div>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
@@ -27,5 +27,16 @@
|
|||||||
},
|
},
|
||||||
"RESTART_SOFTWARE": "Software neu starten"
|
"RESTART_SOFTWARE": "Software neu starten"
|
||||||
},
|
},
|
||||||
"HELLO": "Hallo!"
|
"HELLO": "Hallo!",
|
||||||
|
"AUDIO": {
|
||||||
|
"VOLUME": "Lautstärke",
|
||||||
|
"SETTINGS": "Audioeinstellungen",
|
||||||
|
"AUTO_SWITCH_TO_VR_AUDIO": "Automatisch auf VR-Audio umschalten",
|
||||||
|
"SPEAKERS": "Lautsprecher",
|
||||||
|
"MICROPHONES": "Mikrofone",
|
||||||
|
"CARDS": "Karten"
|
||||||
|
},
|
||||||
|
"ACTIONS": {
|
||||||
|
"RECENTER_PLAYSPACE": "Playspace neu zentrieren"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,5 +27,16 @@
|
|||||||
"SHOW_SKYBOX": "Show skybox",
|
"SHOW_SKYBOX": "Show skybox",
|
||||||
"ENABLE_PASSTHROUGH": "Enable passthrough"
|
"ENABLE_PASSTHROUGH": "Enable passthrough"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"AUDIO": {
|
||||||
|
"SETTINGS": "Audio settings",
|
||||||
|
"VOLUME": "Volume",
|
||||||
|
"AUTO_SWITCH_TO_VR_AUDIO": "Auto-switch to VR audio",
|
||||||
|
"SPEAKERS": "Speakers",
|
||||||
|
"MICROPHONES": "Microphones",
|
||||||
|
"CARDS": "Cards"
|
||||||
|
},
|
||||||
|
"ACTIONS": {
|
||||||
|
"RECENTER_PLAYSPACE": "Re-center playspace"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,5 +27,16 @@
|
|||||||
},
|
},
|
||||||
"RESTART_SOFTWARE": "Reiniciar software"
|
"RESTART_SOFTWARE": "Reiniciar software"
|
||||||
},
|
},
|
||||||
"HELLO": "¡Hola!"
|
"HELLO": "¡Hola!",
|
||||||
|
"AUDIO": {
|
||||||
|
"VOLUME": "Volumen",
|
||||||
|
"SETTINGS": "Configuración de audio",
|
||||||
|
"AUTO_SWITCH_TO_VR_AUDIO": "Conmutar automáticamente al audio VR",
|
||||||
|
"SPEAKERS": "Altavoces",
|
||||||
|
"MICROPHONES": "Micrófonos",
|
||||||
|
"CARDS": "Tarjetas"
|
||||||
|
},
|
||||||
|
"ACTIONS": {
|
||||||
|
"RECENTER_PLAYSPACE": "Re-centrar espacio de juego"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,5 +27,16 @@
|
|||||||
},
|
},
|
||||||
"RESTART_SOFTWARE": "ソフトウェアを再起動"
|
"RESTART_SOFTWARE": "ソフトウェアを再起動"
|
||||||
},
|
},
|
||||||
"HELLO": "こんにちは!"
|
"HELLO": "こんにちは!",
|
||||||
|
"AUDIO": {
|
||||||
|
"VOLUME": "音量",
|
||||||
|
"SETTINGS": "オーディオ設定",
|
||||||
|
"AUTO_SWITCH_TO_VR_AUDIO": "VRオーディオに自動切り替え",
|
||||||
|
"SPEAKERS": "スピーカー",
|
||||||
|
"MICROPHONES": "マイク",
|
||||||
|
"CARDS": "カード"
|
||||||
|
},
|
||||||
|
"ACTIONS": {
|
||||||
|
"RECENTER_PLAYSPACE": "プレイスペースを再中央"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,31 +1,42 @@
|
|||||||
{
|
{
|
||||||
"HOME_SCREEN": "Ekran główny",
|
"HOME_SCREEN": "Ekran główny",
|
||||||
"MONADO_RUNTIME": "„Monado” środowisko uruchomieniowe",
|
"MONADO_RUNTIME": "„Monado” środowisko uruchomieniowe",
|
||||||
"APPLICATIONS": "Aplikacje",
|
"APPLICATIONS": "Aplikacje",
|
||||||
"GAMES": "Gry",
|
"GAMES": "Gry",
|
||||||
"SETTINGS": "Ustawienia",
|
"SETTINGS": "Ustawienia",
|
||||||
"PROCESSES": "Procesy",
|
"PROCESSES": "Procesy",
|
||||||
"HELLO_USER": "Witaj, {USER}!",
|
"HELLO_USER": "Witaj, {USER}!",
|
||||||
"GENERAL_SETTINGS": "Ustawienia ogólne",
|
"GENERAL_SETTINGS": "Ustawienia ogólne",
|
||||||
"APPLICATION_LAUNCHER": "Uruchamiacz aplikacji",
|
"APPLICATION_LAUNCHER": "Uruchamiacz aplikacji",
|
||||||
"APP_SETTINGS": {
|
"APP_SETTINGS": {
|
||||||
"HIDE_USERNAME": "Ukryj nazwę użytkownika",
|
"HIDE_USERNAME": "Ukryj nazwę użytkownika",
|
||||||
"OPAQUE_BACKGROUND": "Nieprzezroczysty tło",
|
"OPAQUE_BACKGROUND": "Nieprzezroczyste tło",
|
||||||
"RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Uruchom domyślnie w trybie XWayland",
|
"RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Uruchom domyślnie w trybie XWayland",
|
||||||
"WLX_OVERLAY_S_SETTINGS": "Ustawienia wlx-overlay-s",
|
"WLX_OVERLAY_S_SETTINGS": "Ustawienia wlx-overlay-s",
|
||||||
"HEADSET_SETTINGS": "Ustawienia głośności",
|
"HEADSET_SETTINGS": "Ustawienia HMD",
|
||||||
"BRIGHTNESS": "Jasność",
|
"BRIGHTNESS": "Jasność",
|
||||||
"WLX": {
|
"WLX": {
|
||||||
"NOTIFICATIONS_ENABLED": "Powiadomienia",
|
"NOTIFICATIONS_ENABLED": "Powiadomienia",
|
||||||
"NOTIFICATIONS_SOUND_ENABLED": "Dźwięk powiadomień",
|
"NOTIFICATIONS_SOUND_ENABLED": "Dźwięk powiadomień",
|
||||||
"KEYBOARD_SOUND_ENABLED": "Dźwięki klawiatury",
|
"KEYBOARD_SOUND_ENABLED": "Dźwięki klawiatury",
|
||||||
"BLOCK_GAME_INPUT": "Zablokuj sterowanie grą podczas używania Wlx",
|
"BLOCK_GAME_INPUT": "Zablokuj sterowanie grą podczas używania Wlx",
|
||||||
"SPACE_DRAG_MULTIPLIER": "Mnożnik space-drag",
|
"SPACE_DRAG_MULTIPLIER": "Mnożnik space-drag",
|
||||||
"SPACE_DRAG_ROTATION_ENABLED": "Włącz rotację w space-drag",
|
"SPACE_DRAG_ROTATION_ENABLED": "Włącz rotację w space-drag",
|
||||||
"SHOW_SKYBOX": "Pokaż skybox",
|
"SHOW_SKYBOX": "Pokaż skybox",
|
||||||
"ENABLE_PASSTHROUGH": "Włącz passthrough"
|
"ENABLE_PASSTHROUGH": "Włącz passthrough"
|
||||||
},
|
},
|
||||||
"RESTART_SOFTWARE": "Uruchom ponownie oprogramowanie"
|
"RESTART_SOFTWARE": "Uruchom ponownie oprogramowanie"
|
||||||
},
|
},
|
||||||
"HELLO": "Witaj!"
|
"HELLO": "Witaj!",
|
||||||
|
"AUDIO": {
|
||||||
|
"VOLUME": "Głośność",
|
||||||
|
"SETTINGS": "Ustawienia dźwięku",
|
||||||
|
"AUTO_SWITCH_TO_VR_AUDIO": "Automatyczne przełączanie na dźwięk VR",
|
||||||
|
"SPEAKERS": "Głośniki",
|
||||||
|
"MICROPHONES": "Mikrofony",
|
||||||
|
"CARDS": "Karty"
|
||||||
|
},
|
||||||
|
"ACTIONS": {
|
||||||
|
"RECENTER_PLAYSPACE": "Wycentruj przestrzeń"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,10 @@ use wgui::{
|
|||||||
font_config::WguiFontConfig,
|
font_config::WguiFontConfig,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{LayoutParams, RcLayout, WidgetID},
|
layout::{Layout, LayoutParams, RcLayout, WidgetID},
|
||||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
||||||
|
windowing::{WguiWindow, WguiWindowParams, WguiWindowParamsExtra, WguiWindowPlacement},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -20,6 +21,7 @@ use crate::{
|
|||||||
settings::TabSettings,
|
settings::TabSettings,
|
||||||
},
|
},
|
||||||
util::popup_manager::{MountPopupParams, PopupManager, PopupManagerParams},
|
util::popup_manager::{MountPopupParams, PopupManager, PopupManagerParams},
|
||||||
|
views,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct FrontendWidgets {
|
pub struct FrontendWidgets {
|
||||||
@@ -57,6 +59,8 @@ pub struct Frontend {
|
|||||||
|
|
||||||
widgets: FrontendWidgets,
|
widgets: FrontendWidgets,
|
||||||
popup_manager: PopupManager,
|
popup_manager: PopupManager,
|
||||||
|
|
||||||
|
window_audio_settings: WguiWindow,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InitParams {
|
pub struct InitParams {
|
||||||
@@ -65,12 +69,15 @@ pub struct InitParams {
|
|||||||
|
|
||||||
pub type RcFrontend = Rc<RefCell<Frontend>>;
|
pub type RcFrontend = Rc<RefCell<Frontend>>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum FrontendTask {
|
pub enum FrontendTask {
|
||||||
SetTab(TabType),
|
SetTab(TabType),
|
||||||
RefreshClock,
|
RefreshClock,
|
||||||
RefreshBackground,
|
RefreshBackground,
|
||||||
MountPopup(MountPopupParams),
|
MountPopup(MountPopupParams),
|
||||||
RefreshPopupManager,
|
RefreshPopupManager,
|
||||||
|
ShowAudioSettings,
|
||||||
|
RecenterPlayspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frontend {
|
impl Frontend {
|
||||||
@@ -129,6 +136,7 @@ impl Frontend {
|
|||||||
},
|
},
|
||||||
settings: params.settings,
|
settings: params.settings,
|
||||||
popup_manager,
|
popup_manager,
|
||||||
|
window_audio_settings: WguiWindow::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// init some things first
|
// init some things first
|
||||||
@@ -251,6 +259,8 @@ impl Frontend {
|
|||||||
FrontendTask::RefreshBackground => self.update_background()?,
|
FrontendTask::RefreshBackground => self.update_background()?,
|
||||||
FrontendTask::MountPopup(params) => self.mount_popup(params)?,
|
FrontendTask::MountPopup(params) => self.mount_popup(params)?,
|
||||||
FrontendTask::RefreshPopupManager => self.refresh_popup_manager()?,
|
FrontendTask::RefreshPopupManager => self.refresh_popup_manager()?,
|
||||||
|
FrontendTask::ShowAudioSettings => self.action_show_audio_settings()?,
|
||||||
|
FrontendTask::RecenterPlayspace => self.action_recenter_playspace()?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -284,21 +294,112 @@ impl Frontend {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_button_task(this_rc: RcFrontend, btn: &Rc<ComponentButton>, task: FrontendTask) {
|
||||||
|
btn.on_click({
|
||||||
|
Box::new(move |_common, _evt| {
|
||||||
|
this_rc.borrow_mut().tasks.push(task.clone());
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn register_widgets(rc_this: &RcFrontend) -> anyhow::Result<()> {
|
fn register_widgets(rc_this: &RcFrontend) -> anyhow::Result<()> {
|
||||||
let this = rc_this.borrow_mut();
|
let this = rc_this.borrow_mut();
|
||||||
let btn_home = this.state.fetch_component_as::<ComponentButton>("btn_side_home")?;
|
|
||||||
let btn_apps = this.state.fetch_component_as::<ComponentButton>("btn_side_apps")?;
|
|
||||||
let btn_games = this.state.fetch_component_as::<ComponentButton>("btn_side_games")?;
|
|
||||||
let btn_monado = this.state.fetch_component_as::<ComponentButton>("btn_side_monado")?;
|
|
||||||
let btn_processes = this.state.fetch_component_as::<ComponentButton>("btn_side_processes")?;
|
|
||||||
let btn_settings = this.state.fetch_component_as::<ComponentButton>("btn_side_settings")?;
|
|
||||||
|
|
||||||
TabType::register_button(rc_this.clone(), &btn_home, TabType::Home);
|
// ################################
|
||||||
TabType::register_button(rc_this.clone(), &btn_apps, TabType::Apps);
|
// SIDE BUTTONS
|
||||||
TabType::register_button(rc_this.clone(), &btn_games, TabType::Games);
|
// ################################
|
||||||
TabType::register_button(rc_this.clone(), &btn_monado, TabType::Monado);
|
|
||||||
TabType::register_button(rc_this.clone(), &btn_processes, TabType::Processes);
|
// "Home" side button
|
||||||
TabType::register_button(rc_this.clone(), &btn_settings, TabType::Settings);
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_side_home")?,
|
||||||
|
FrontendTask::SetTab(TabType::Home),
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Apps" side button
|
||||||
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_side_apps")?,
|
||||||
|
FrontendTask::SetTab(TabType::Apps),
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Games" side button
|
||||||
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_side_games")?,
|
||||||
|
FrontendTask::SetTab(TabType::Games),
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Monado side button"
|
||||||
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_side_monado")?,
|
||||||
|
FrontendTask::SetTab(TabType::Monado),
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Processes" side button
|
||||||
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_side_processes")?,
|
||||||
|
FrontendTask::SetTab(TabType::Processes),
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Settings" side button
|
||||||
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_side_settings")?,
|
||||||
|
FrontendTask::SetTab(TabType::Settings),
|
||||||
|
);
|
||||||
|
|
||||||
|
// ################################
|
||||||
|
// BOTTOM BAR BUTTONS
|
||||||
|
// ################################
|
||||||
|
|
||||||
|
// "Audio" bottom bar button
|
||||||
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_audio")?,
|
||||||
|
FrontendTask::ShowAudioSettings,
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Recenter playspace" bottom bar button
|
||||||
|
Frontend::register_button_task(
|
||||||
|
rc_this.clone(),
|
||||||
|
&this.state.fetch_component_as::<ComponentButton>("btn_recenter")?,
|
||||||
|
FrontendTask::RecenterPlayspace,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_show_audio_settings(&mut self) -> anyhow::Result<()> {
|
||||||
|
let mut layout = self.layout.borrow_mut();
|
||||||
|
|
||||||
|
self.window_audio_settings.open(&mut WguiWindowParams {
|
||||||
|
globals: self.globals.clone(),
|
||||||
|
position: Vec2::new(64.0, 64.0),
|
||||||
|
layout: &mut layout,
|
||||||
|
title: Translation::from_translation_key("AUDIO.SETTINGS"),
|
||||||
|
extra: WguiWindowParamsExtra {
|
||||||
|
fixed_width: Some(400.0),
|
||||||
|
placement: WguiWindowPlacement::BottomLeft,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let content = self.window_audio_settings.get_content();
|
||||||
|
|
||||||
|
views::audio_settings::View::new(views::audio_settings::Params {
|
||||||
|
globals: self.globals.clone(),
|
||||||
|
layout: &mut layout,
|
||||||
|
parent_id: content.id,
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_recenter_playspace(&mut self) -> anyhow::Result<()> {
|
||||||
|
log::info!("todo");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ fn on_app_click(
|
|||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
let entry = entry.clone();
|
let entry = entry.clone();
|
||||||
let globals = globals.clone();
|
let globals = globals.clone();
|
||||||
Box::new(move |data| {
|
Rc::new(move |data| {
|
||||||
let view = app_launcher::View::new(app_launcher::Params {
|
let view = app_launcher::View::new(app_launcher::Params {
|
||||||
entry: entry.clone(),
|
entry: entry.clone(),
|
||||||
globals: globals.clone(),
|
globals: globals.clone(),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use wgui::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
frontend::{Frontend, FrontendTask},
|
||||||
settings,
|
settings,
|
||||||
tab::{Tab, TabParams, TabType},
|
tab::{Tab, TabParams, TabType},
|
||||||
various,
|
various,
|
||||||
@@ -66,11 +67,15 @@ impl TabHome {
|
|||||||
let btn_settings = state.fetch_component_as::<ComponentButton>("btn_settings")?;
|
let btn_settings = state.fetch_component_as::<ComponentButton>("btn_settings")?;
|
||||||
|
|
||||||
let frontend = params.frontend;
|
let frontend = params.frontend;
|
||||||
TabType::register_button(frontend.clone(), &btn_apps, TabType::Apps);
|
Frontend::register_button_task(frontend.clone(), &btn_apps, FrontendTask::SetTab(TabType::Apps));
|
||||||
TabType::register_button(frontend.clone(), &btn_games, TabType::Games);
|
Frontend::register_button_task(frontend.clone(), &btn_games, FrontendTask::SetTab(TabType::Games));
|
||||||
TabType::register_button(frontend.clone(), &btn_monado, TabType::Monado);
|
Frontend::register_button_task(frontend.clone(), &btn_monado, FrontendTask::SetTab(TabType::Monado));
|
||||||
TabType::register_button(frontend.clone(), &btn_processes, TabType::Processes);
|
Frontend::register_button_task(
|
||||||
TabType::register_button(frontend.clone(), &btn_settings, TabType::Settings);
|
frontend.clone(),
|
||||||
|
&btn_processes,
|
||||||
|
FrontendTask::SetTab(TabType::Processes),
|
||||||
|
);
|
||||||
|
Frontend::register_button_task(frontend.clone(), &btn_settings, FrontendTask::SetTab(TabType::Settings));
|
||||||
|
|
||||||
Ok(Self { state })
|
Ok(Self { state })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,14 +38,3 @@ pub trait Tab {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn get_type(&self) -> TabType;
|
fn get_type(&self) -> TabType;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TabType {
|
|
||||||
pub fn register_button(this_rc: RcFrontend, btn: &Rc<ComponentButton>, tab: TabType) {
|
|
||||||
btn.on_click({
|
|
||||||
Box::new(move |_common, _evt| {
|
|
||||||
this_rc.borrow_mut().tasks.push(FrontendTask::SetTab(tab));
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -63,9 +63,10 @@ pub struct PopupContentFuncData<'a> {
|
|||||||
pub id_content: WidgetID,
|
pub id_content: WidgetID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct MountPopupParams {
|
pub struct MountPopupParams {
|
||||||
pub title: Translation,
|
pub title: Translation,
|
||||||
pub on_content: Box<dyn Fn(PopupContentFuncData) -> anyhow::Result<()>>,
|
pub on_content: Rc<dyn Fn(PopupContentFuncData) -> anyhow::Result<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for MountedPopup {
|
impl Drop for MountedPopup {
|
||||||
|
|||||||
36
dash-frontend/src/views/audio_settings.rs
Normal file
36
dash-frontend/src/views/audio_settings.rs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
|
use wgui::{
|
||||||
|
assets::AssetPath,
|
||||||
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
|
layout::{Layout, WidgetID},
|
||||||
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
widget::label::WidgetLabel,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct View {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub state: ParserState,
|
||||||
|
//entry: DesktopEntry,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Params<'a> {
|
||||||
|
pub globals: WguiGlobals,
|
||||||
|
pub layout: &'a mut Layout,
|
||||||
|
pub parent_id: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View {
|
||||||
|
pub fn new(params: Params) -> anyhow::Result<Self> {
|
||||||
|
let doc_params = &ParseDocumentParams {
|
||||||
|
globals: params.globals.clone(),
|
||||||
|
path: AssetPath::BuiltIn("gui/view/audio_settings.xml"),
|
||||||
|
extra: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = wgui::parser::parse_from_assets(doc_params, params.layout, params.parent_id)?;
|
||||||
|
|
||||||
|
Ok(Self { state })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
pub mod app_launcher;
|
pub mod app_launcher;
|
||||||
|
pub mod audio_settings;
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ You are a translator for the VR application which translates strings from Englis
|
|||||||
Info: This program is intended to be used as an utility to easily access your desktop display from within VR.
|
Info: This program is intended to be used as an utility to easily access your desktop display from within VR.
|
||||||
|
|
||||||
Glossary:
|
Glossary:
|
||||||
wlx-overlay-s: The name of this software (also called WlxOverlay-S)
|
- wlx-overlay-s: The name of this software (also called WlxOverlay-S)
|
||||||
WayVR: A Wayland compositor intended to be used in VR
|
- WayVR: A Wayland compositor intended to be used in VR
|
||||||
WayVR Dashboard: An application (and game) launcher which is displayed in front of the user
|
- WayVR Dashboard: An application (and game) launcher which is displayed in front of the user
|
||||||
OpenVR: API made by Valve
|
- OpenVR: API made by Valve
|
||||||
OpenXR: API made by Khronos
|
- OpenXR: API made by Khronos
|
||||||
OSC: OpenSoundControl
|
- OSC: OpenSoundControl
|
||||||
Space-drag: A feature which allows the user to move their HMD origin position via a controller
|
- Playspace: A designated real area where users can interact with the virtual environment
|
||||||
Passthrough: Some headsets have built-in cameras for displaying image on the HMD screen
|
- Space-drag: A feature which allows the user to move their HMD origin position via a controller
|
||||||
|
- Passthrough: Some headsets have built-in cameras for displaying image on the HMD screen
|
||||||
|
End of glossary;
|
||||||
|
|
||||||
You will be given the input in the code blocks which needs to be translated to {TARGET_LANG} language. Write only the result in codeblocks, do not explain. Keep any newlines and other important formatting-required identifiers as-is.
|
You will be given the input in the code blocks which needs to be translated to {TARGET_LANG} language. Write only the result in codeblocks, do not explain. Keep any newlines and other important formatting-required identifiers as-is.
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use wgui::{
|
|||||||
parser::{Fetchable, ParseDocumentExtra, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentExtra, ParseDocumentParams, ParserState},
|
||||||
taffy,
|
taffy,
|
||||||
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
||||||
windowing::{WguiWindow, WguiWindowParams},
|
windowing::{WguiWindow, WguiWindowParams, WguiWindowParamsExtra},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum TestbedTask {
|
pub enum TestbedTask {
|
||||||
@@ -215,6 +215,8 @@ impl TestbedGeneric {
|
|||||||
globals: self.globals.clone(),
|
globals: self.globals.clone(),
|
||||||
position: Vec2::new(128.0, 128.0),
|
position: Vec2::new(128.0, 128.0),
|
||||||
layout,
|
layout,
|
||||||
|
title: Translation::from_raw_text("foo"),
|
||||||
|
extra: Default::default(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
<layout>
|
<layout>
|
||||||
<elements>
|
<elements>
|
||||||
|
<!--
|
||||||
|
Window decoration
|
||||||
|
Make sure to modify WINDOW_DECORATION_PADDING
|
||||||
|
and WINDOW_DECORATION_HEADER_HEIGHT in the source code accordingly
|
||||||
|
-->
|
||||||
<rectangle
|
<rectangle
|
||||||
flex_direction="column"
|
flex_direction="column"
|
||||||
round="8"
|
round="16"
|
||||||
border="2"
|
border="2"
|
||||||
border_color="#778899"
|
border_color="#ffffff33"
|
||||||
color="#001122ee"
|
color="#081020ee"
|
||||||
padding="2">
|
padding="2">
|
||||||
<!-- window title -->
|
<!-- window title -->
|
||||||
<rectangle width="100%" height="100%" round="4" align_items="center" justify_content="space_between"
|
<div width="100%" height="32" align_items="center" position="relative" justify_content="end">
|
||||||
gradient="vertical" color="#224466" color2="#113355">
|
<div width="100%" justify_content="center">
|
||||||
<label margin_left="8" text="Window title" weight="bold" />
|
<label id="text_window_title" weight="bold" />
|
||||||
<Button id="but_close" border="0" round="0">
|
</div>
|
||||||
<sprite src_internal="wgui/close.svg" width="24" height="24" />
|
<Button id="but_close" border="0" round="16" color="#FFFFFF00" position="absolute">
|
||||||
|
<sprite src_internal="wgui/close.svg" width="32" height="32" />
|
||||||
</Button>
|
</Button>
|
||||||
</rectangle>
|
</div>
|
||||||
|
|
||||||
<!-- content itself -->
|
<!-- content itself -->
|
||||||
<div id="content" width="100%" height="100%" padding="8" gap="4" flex_direction="column">
|
<div id="content" padding="8" padding_top="0" gap="4" flex_direction="column">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</rectangle>
|
</rectangle>
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
|
|
||||||
let transform = Mat4::from_translation(Vec3::new(-0.5, 0.0, 0.0));
|
let transform = Mat4::from_translation(Vec3::new(-0.5, 0.0, 0.0));
|
||||||
|
|
||||||
let (pin_left, pin_top, pin_align_items, pin_justify_content) = match params.info.side {
|
let (mut pin_left, mut pin_top, pin_align_items, pin_justify_content) = match params.info.side {
|
||||||
TooltipSide::Left => (
|
TooltipSide::Left => (
|
||||||
absolute_boundary.left() - spacing,
|
absolute_boundary.left() - spacing,
|
||||||
absolute_boundary.top() + absolute_boundary.size.y / 2.0,
|
absolute_boundary.top() + absolute_boundary.size.y / 2.0,
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ impl Event {
|
|||||||
pub enum StyleSetRequest {
|
pub enum StyleSetRequest {
|
||||||
Display(taffy::Display),
|
Display(taffy::Display),
|
||||||
Margin(taffy::Rect<taffy::LengthPercentageAuto>),
|
Margin(taffy::Rect<taffy::LengthPercentageAuto>),
|
||||||
|
Width(taffy::Dimension),
|
||||||
|
Height(taffy::Dimension),
|
||||||
}
|
}
|
||||||
|
|
||||||
// alterables which will be dispatched in the next loop iteration phase
|
// alterables which will be dispatched in the next loop iteration phase
|
||||||
|
|||||||
@@ -744,6 +744,12 @@ impl Layout {
|
|||||||
event::StyleSetRequest::Margin(margin) => {
|
event::StyleSetRequest::Margin(margin) => {
|
||||||
cur_style.margin = margin;
|
cur_style.margin = margin;
|
||||||
}
|
}
|
||||||
|
event::StyleSetRequest::Width(val) => {
|
||||||
|
cur_style.size.width = val;
|
||||||
|
}
|
||||||
|
event::StyleSetRequest::Height(val) => {
|
||||||
|
cur_style.size.height = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = self.state.tree.set_style(*node_id, cur_style) {
|
if let Err(e) = self.state.tree.set_style(*node_id, cur_style) {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
components::{button, tooltip, Component},
|
components::{Component, button, tooltip},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
parse_check_f32, parse_check_i32, parse_children, print_invalid_attrib, process_component,
|
AttribPair, ParserContext, ParserFile, parse_check_f32, parse_check_i32, parse_children, print_invalid_attrib,
|
||||||
|
process_component,
|
||||||
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
||||||
AttribPair, ParserContext, ParserFile,
|
|
||||||
},
|
},
|
||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
};
|
};
|
||||||
@@ -94,7 +94,7 @@ pub fn parse_component_button<'a>(
|
|||||||
text_style,
|
text_style,
|
||||||
round,
|
round,
|
||||||
tooltip: tooltip.map(|t| tooltip::TooltipInfo {
|
tooltip: tooltip.map(|t| tooltip::TooltipInfo {
|
||||||
side: tooltip_side.map_or(tooltip::TooltipSide::Bottom, |f| f),
|
side: tooltip_side.map_or(tooltip::TooltipSide::Top, |f| f),
|
||||||
text: Translation::from_translation_key(&t),
|
text: Translation::from_translation_key(&t),
|
||||||
}),
|
}),
|
||||||
sticky,
|
sticky,
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use taffy::prelude::length;
|
use taffy::prelude::{length, percent};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::button::ComponentButton,
|
components::button::ComponentButton,
|
||||||
|
event::StyleSetRequest,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
layout::{Layout, LayoutTask, LayoutTasks, WidgetPair},
|
layout::{Layout, LayoutTask, LayoutTasks, WidgetPair},
|
||||||
parser::{self, Fetchable, ParserState},
|
parser::{self, Fetchable, ParserState},
|
||||||
widget::div::WidgetDiv,
|
widget::{div::WidgetDiv, label::WidgetLabel},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OpenedWindow {
|
struct OpenedWindow {
|
||||||
@@ -38,10 +40,28 @@ pub struct OnContentData {
|
|||||||
pub widget: WidgetPair,
|
pub widget: WidgetPair,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub enum WguiWindowPlacement {
|
||||||
|
#[default]
|
||||||
|
TopLeft,
|
||||||
|
BottomLeft,
|
||||||
|
TopRight,
|
||||||
|
BottomRight,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WguiWindowParamsExtra {
|
||||||
|
pub fixed_width: Option<f32>,
|
||||||
|
pub fixed_height: Option<f32>,
|
||||||
|
pub placement: WguiWindowPlacement,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WguiWindowParams<'a> {
|
pub struct WguiWindowParams<'a> {
|
||||||
pub position: Vec2,
|
pub position: Vec2,
|
||||||
pub globals: WguiGlobals,
|
pub globals: WguiGlobals,
|
||||||
pub layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
|
pub title: Translation,
|
||||||
|
pub extra: WguiWindowParamsExtra,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WguiWindow {
|
impl Default for WguiWindow {
|
||||||
@@ -50,6 +70,9 @@ impl Default for WguiWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WINDOW_DECORATION_HEADER_HEIGHT: f32 = 32.0;
|
||||||
|
const WINDOW_DECORATION_PADDING: f32 = 2.0;
|
||||||
|
|
||||||
impl WguiWindow {
|
impl WguiWindow {
|
||||||
pub fn close(&self) {
|
pub fn close(&self) {
|
||||||
self.0.borrow_mut().opened_window = None;
|
self.0.borrow_mut().opened_window = None;
|
||||||
@@ -61,15 +84,59 @@ impl WguiWindow {
|
|||||||
|
|
||||||
const XML_PATH: AssetPath = AssetPath::WguiInternal("wgui/window_frame.xml");
|
const XML_PATH: AssetPath = AssetPath::WguiInternal("wgui/window_frame.xml");
|
||||||
|
|
||||||
|
let (padding, justify_content, align_items) = match params.extra.placement {
|
||||||
|
WguiWindowPlacement::TopLeft => (
|
||||||
|
taffy::Rect {
|
||||||
|
left: length(params.position.x - WINDOW_DECORATION_PADDING),
|
||||||
|
top: length(params.position.y - WINDOW_DECORATION_HEADER_HEIGHT - WINDOW_DECORATION_PADDING),
|
||||||
|
bottom: length(0.0),
|
||||||
|
right: length(0.0),
|
||||||
|
},
|
||||||
|
taffy::JustifyContent::Start, // x start
|
||||||
|
taffy::AlignItems::Start, // y start
|
||||||
|
),
|
||||||
|
WguiWindowPlacement::BottomLeft => (
|
||||||
|
taffy::Rect {
|
||||||
|
left: length(params.position.x - WINDOW_DECORATION_PADDING),
|
||||||
|
top: length(0.0),
|
||||||
|
bottom: length(params.position.y - WINDOW_DECORATION_PADDING),
|
||||||
|
right: length(0.0),
|
||||||
|
},
|
||||||
|
taffy::JustifyContent::Start, // x start
|
||||||
|
taffy::AlignItems::End, // y end
|
||||||
|
),
|
||||||
|
WguiWindowPlacement::TopRight => (
|
||||||
|
taffy::Rect {
|
||||||
|
left: length(0.0),
|
||||||
|
top: length(params.position.y - WINDOW_DECORATION_HEADER_HEIGHT - WINDOW_DECORATION_PADDING),
|
||||||
|
bottom: length(0.0),
|
||||||
|
right: length(params.position.x - WINDOW_DECORATION_PADDING),
|
||||||
|
},
|
||||||
|
taffy::JustifyContent::End, // x end
|
||||||
|
taffy::AlignItems::Start, // y start
|
||||||
|
),
|
||||||
|
WguiWindowPlacement::BottomRight => (
|
||||||
|
taffy::Rect {
|
||||||
|
left: length(0.0),
|
||||||
|
top: length(0.0),
|
||||||
|
bottom: length(params.position.y - WINDOW_DECORATION_PADDING),
|
||||||
|
right: length(params.position.x - WINDOW_DECORATION_PADDING),
|
||||||
|
},
|
||||||
|
taffy::JustifyContent::End, // x end
|
||||||
|
taffy::AlignItems::End, // y end
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
let (widget, _) = params.layout.add_topmost_child(
|
let (widget, _) = params.layout.add_topmost_child(
|
||||||
WidgetDiv::create(),
|
WidgetDiv::create(),
|
||||||
taffy::Style {
|
taffy::Style {
|
||||||
position: taffy::Position::Absolute,
|
position: taffy::Position::Absolute,
|
||||||
margin: taffy::Rect {
|
align_items: Some(align_items),
|
||||||
left: length(params.position.x),
|
justify_content: Some(justify_content),
|
||||||
right: length(0.0),
|
padding,
|
||||||
top: length(params.position.y),
|
size: taffy::Size {
|
||||||
bottom: length(0.0),
|
width: percent(1.0),
|
||||||
|
height: percent(1.0),
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -94,15 +161,35 @@ impl WguiWindow {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut text_title = state.fetch_widget_as::<WidgetLabel>(¶ms.layout.state, "text_window_title")?;
|
||||||
|
text_title.set_text_simple(&mut params.globals.get(), params.title.clone());
|
||||||
|
}
|
||||||
|
|
||||||
let content = state.fetch_widget(¶ms.layout.state, "content")?;
|
let content = state.fetch_widget(¶ms.layout.state, "content")?;
|
||||||
|
|
||||||
self.0.borrow_mut().opened_window = Some(OpenedWindow {
|
self.0.borrow_mut().opened_window = Some(OpenedWindow {
|
||||||
widget,
|
widget,
|
||||||
state,
|
state,
|
||||||
layout_tasks: params.layout.tasks.clone(),
|
layout_tasks: params.layout.tasks.clone(),
|
||||||
content,
|
content: content.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut c = params.layout.start_common();
|
||||||
|
if let Some(width) = params.extra.fixed_width {
|
||||||
|
c.common()
|
||||||
|
.alterables
|
||||||
|
.set_style(content.id, StyleSetRequest::Width(length(width)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(height) = params.extra.fixed_height {
|
||||||
|
c.common()
|
||||||
|
.alterables
|
||||||
|
.set_style(content.id, StyleSetRequest::Height(length(height)));
|
||||||
|
}
|
||||||
|
|
||||||
|
c.finish()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user