diff --git a/dash-frontend/assets/gui/view/display_options.xml b/dash-frontend/assets/gui/view/display_options.xml new file mode 100644 index 0000000..6d5edb1 --- /dev/null +++ b/dash-frontend/assets/gui/view/display_options.xml @@ -0,0 +1,15 @@ + + + + +
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/dash-frontend/assets/lang/de.json b/dash-frontend/assets/lang/de.json index 9da3b9e..0574d78 100644 --- a/dash-frontend/assets/lang/de.json +++ b/dash-frontend/assets/lang/de.json @@ -55,5 +55,9 @@ }, "WIDTH": "Breite", "HEIGHT": "Höhe", - "DISPLAY_PORTRAIT_MODE": "Porträtmodus" + "DISPLAY_PORTRAIT_MODE": "Porträtmodus", + "HIDE": "Verbergen", + "REMOVE": "Entfernen", + "SHOW": "Anzeigen", + "DISPLAY_OPTIONS": "Anzeigeeinstellungen" } \ No newline at end of file diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json index 1b9fb2a..deff9fd 100644 --- a/dash-frontend/assets/lang/en.json +++ b/dash-frontend/assets/lang/en.json @@ -3,7 +3,6 @@ "RECENTER_PLAYSPACE": "Re-center playspace" }, "ADD_DISPLAY": "Add display", - "DISPLAY_PORTRAIT_MODE": "Portrait mode", "APP_SETTINGS": { "BRIGHTNESS": "Brightness", "HEADSET_SETTINGS": "Headset settings", @@ -40,11 +39,14 @@ "SPEAKERS_SET_SUCCESSFULLY": "Speakers set successfully", "VOLUME": "Volume" }, + "DISPLAY_OPTIONS": "Display options", + "DISPLAY_PORTRAIT_MODE": "Portrait mode", "GAMES": "Games", "GENERAL_SETTINGS": "General settings", "HEIGHT": "Height", "HELLO": "Hello!", "HELLO_USER": "Hello, {USER}!", + "HIDE": "Hide", "HOME_SCREEN": "Home", "LIST_OF_DISPLAYS": "Display list", "LIST_OF_PROCESSES": "Process list", @@ -54,6 +56,8 @@ "RESOLUTION": "Resolution" }, "PROCESSES": "Processes", + "REMOVE": "Remove", "SETTINGS": "Settings", + "SHOW": "Show", "WIDTH": "Width" } diff --git a/dash-frontend/assets/lang/es.json b/dash-frontend/assets/lang/es.json index e786599..090c9ff 100644 --- a/dash-frontend/assets/lang/es.json +++ b/dash-frontend/assets/lang/es.json @@ -55,5 +55,9 @@ }, "WIDTH": "Ancho", "HEIGHT": "Altura", - "DISPLAY_PORTRAIT_MODE": "Modo retrato" + "DISPLAY_PORTRAIT_MODE": "Modo retrato", + "HIDE": "Ocultar", + "REMOVE": "Eliminar", + "SHOW": "Mostrar", + "DISPLAY_OPTIONS": "Opciones de pantalla" } \ No newline at end of file diff --git a/dash-frontend/assets/lang/ja.json b/dash-frontend/assets/lang/ja.json index 6648001..20ae809 100644 --- a/dash-frontend/assets/lang/ja.json +++ b/dash-frontend/assets/lang/ja.json @@ -55,5 +55,9 @@ }, "WIDTH": "幅", "HEIGHT": "高さ", - "DISPLAY_PORTRAIT_MODE": "縦向きモード" + "DISPLAY_PORTRAIT_MODE": "縦向きモード", + "HIDE": "隠す", + "REMOVE": "削除", + "SHOW": "表示", + "DISPLAY_OPTIONS": "表示オプション" } \ No newline at end of file diff --git a/dash-frontend/assets/lang/pl.json b/dash-frontend/assets/lang/pl.json index ef08762..1a05a86 100644 --- a/dash-frontend/assets/lang/pl.json +++ b/dash-frontend/assets/lang/pl.json @@ -1,59 +1,63 @@ { - "HOME_SCREEN": "Ekran główny", - "MONADO_RUNTIME": "Środowisko Monado", - "APPLICATIONS": "Aplikacje", - "GAMES": "Gry", - "SETTINGS": "Ustawienia", - "PROCESSES": "Procesy", - "HELLO_USER": "Witaj, {USER}!", - "GENERAL_SETTINGS": "Ustawienia ogólne", - "APPLICATION_LAUNCHER": "Uruchamiacz aplikacji", - "APP_SETTINGS": { - "HIDE_USERNAME": "Ukryj nazwę użytkownika", - "OPAQUE_BACKGROUND": "Nieprzezroczyste tło", - "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Uruchom domyślnie w trybie XWayland", - "WLX_OVERLAY_S_SETTINGS": "Ustawienia wlx-overlay-s", - "HEADSET_SETTINGS": "Ustawienia HMD", - "BRIGHTNESS": "Jasność", - "WLX": { - "NOTIFICATIONS_ENABLED": "Powiadomienia", - "NOTIFICATIONS_SOUND_ENABLED": "Dźwięk powiadomień", - "KEYBOARD_SOUND_ENABLED": "Dźwięki klawiatury", - "BLOCK_GAME_INPUT": "Zablokuj sterowanie grą podczas używania Wlx", - "SPACE_DRAG_MULTIPLIER": "Mnożnik space-drag", - "SPACE_DRAG_ROTATION_ENABLED": "Włącz rotację w space-drag", - "SHOW_SKYBOX": "Pokaż skybox", - "ENABLE_PASSTHROUGH": "Włącz passthrough" - }, - "RESTART_SOFTWARE": "Uruchom ponownie oprogramowanie" - }, - "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", - "SELECT_AUDIO_CARD_PROFILE": "Wybierz profil karty dźwiękowej", - "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "Brak głośników VR. Włącz je ręcznie.", - "NO_VR_MICROPHONE_SWITCH_MANUALLY": "Brak mikrofonu VR. Włącz go ręcznie.", - "FAILED_TO_SWITCH_MICROPHONE": "Nie udało się przełączyć mikrofon", - "MICROPHONE_SET_SUCCESSFULLY": "Mikrofon ustawiono pomyślnie", - "SPEAKERS_SET_SUCCESSFULLY": "Głośniki ustawiono pomyślnie", - "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Urządzenie znalezione i zainicjalizowane, ale nie przełączone" - }, "ACTIONS": { "RECENTER_PLAYSPACE": "Wycentruj przestrzeń" }, + "ADD_DISPLAY": "Dodaj monitor", + "APP_SETTINGS": { + "BRIGHTNESS": "Jasność", + "HEADSET_SETTINGS": "Ustawienia HMD", + "HIDE_USERNAME": "Ukryj nazwę użytkownika", + "OPAQUE_BACKGROUND": "Nieprzezroczyste tło", + "RESTART_SOFTWARE": "Uruchom ponownie oprogramowanie", + "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Uruchom domyślnie w trybie XWayland", + "WLX": { + "BLOCK_GAME_INPUT": "Zablokuj sterowanie grą podczas używania Wlx", + "ENABLE_PASSTHROUGH": "Włącz passthrough", + "KEYBOARD_SOUND_ENABLED": "Dźwięki klawiatury", + "NOTIFICATIONS_ENABLED": "Powiadomienia", + "NOTIFICATIONS_SOUND_ENABLED": "Dźwięk powiadomień", + "SHOW_SKYBOX": "Pokaż skybox", + "SPACE_DRAG_MULTIPLIER": "Mnożnik space-drag", + "SPACE_DRAG_ROTATION_ENABLED": "Włącz rotację w space-drag" + }, + "WLX_OVERLAY_S_SETTINGS": "Ustawienia wlx-overlay-s" + }, + "APPLICATION_LAUNCHER": "Uruchamiacz aplikacji", + "APPLICATIONS": "Aplikacje", + "AUDIO": { + "AUTO_SWITCH_TO_VR_AUDIO": "Automatyczne przełączanie na dźwięk VR", + "CARDS": "Karty", + "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Urządzenie znalezione i zainicjalizowane, ale nie przełączone", + "FAILED_TO_SWITCH_MICROPHONE": "Nie udało się przełączyć mikrofon", + "MICROPHONE_SET_SUCCESSFULLY": "Mikrofon ustawiono pomyślnie", + "MICROPHONES": "Mikrofony", + "NO_VR_MICROPHONE_SWITCH_MANUALLY": "Brak mikrofonu VR. Włącz go ręcznie.", + "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "Brak głośników VR. Włącz je ręcznie.", + "SELECT_AUDIO_CARD_PROFILE": "Wybierz profil karty dźwiękowej", + "SETTINGS": "Ustawienia dźwięku", + "SPEAKERS": "Głośniki", + "SPEAKERS_SET_SUCCESSFULLY": "Głośniki ustawiono pomyślnie", + "VOLUME": "Głośność" + }, + "DISPLAY_OPTIONS": "Opcje monitora", + "DISPLAY_PORTRAIT_MODE": "Tryb pionowy", + "GAMES": "Gry", + "GENERAL_SETTINGS": "Ustawienia ogólne", + "HEIGHT": "Wysokość", + "HELLO": "Witaj!", + "HELLO_USER": "Witaj, {USER}!", + "HIDE": "Ukryj", + "HOME_SCREEN": "Ekran główny", "LIST_OF_DISPLAYS": "Lista monitorów", "LIST_OF_PROCESSES": "Lista procesów", + "MONADO_RUNTIME": "Środowisko Monado", "NO_DISPLAYS_FOUND": "Brak monitorów", - "ADD_DISPLAY": "Dodaj monitor", "POPUP_ADD_DISPLAY": { "RESOLUTION": "Rozdzielczość" }, + "REMOVE": "Usuń", + "SETTINGS": "Ustawienia", + "SHOW": "Pokaż", "WIDTH": "Szerokość", - "HEIGHT": "Wysokość", - "DISPLAY_PORTRAIT_MODE": "Tryb pionowy" + "PROCESSES": "Procesy" } \ No newline at end of file diff --git a/dash-frontend/src/frontend.rs b/dash-frontend/src/frontend.rs index 6f2d19c..14c762c 100644 --- a/dash-frontend/src/frontend.rs +++ b/dash-frontend/src/frontend.rs @@ -13,7 +13,10 @@ use wgui::{ widget::{label::WidgetLabel, rectangle::WidgetRectangle}, windowing::{WguiWindow, WguiWindowParams, WguiWindowParamsExtra, WguiWindowPlacement}, }; -use wlx_common::{dash_interface, timestep::Timestep}; +use wlx_common::{ + dash_interface::{self, BoxDashInterface}, + timestep::Timestep, +}; use crate::{ assets, settings, @@ -41,7 +44,7 @@ pub struct Frontend { globals: WguiGlobals, pub settings: Box, - pub interface: Box, + pub interface: BoxDashInterface, #[allow(dead_code)] state: ParserState, @@ -63,7 +66,7 @@ pub struct Frontend { pub struct InitParams { pub settings: Box, - pub interface: Box, + pub interface: BoxDashInterface, } pub type RcFrontend = Rc>; diff --git a/dash-frontend/src/tab/mod.rs b/dash-frontend/src/tab/mod.rs index f0f3a60..fa34c91 100644 --- a/dash-frontend/src/tab/mod.rs +++ b/dash-frontend/src/tab/mod.rs @@ -2,7 +2,7 @@ use wgui::{ globals::WguiGlobals, layout::{Layout, WidgetID}, }; -use wlx_common::dash_interface; +use wlx_common::dash_interface::BoxDashInterface; use crate::frontend::{FrontendTasks, RcFrontend}; @@ -36,7 +36,7 @@ pub struct TabUpdateParams<'a> { pub globals: &'a WguiGlobals, pub frontend_tasks: &'a FrontendTasks, pub layout: &'a mut Layout, - pub interface: &'a mut Box, + pub interface: &'a mut BoxDashInterface, } pub trait Tab { diff --git a/dash-frontend/src/views/add_display.rs b/dash-frontend/src/views/add_display.rs index 98114b8..ea60c8f 100644 --- a/dash-frontend/src/views/add_display.rs +++ b/dash-frontend/src/views/add_display.rs @@ -10,10 +10,10 @@ use wgui::{ layout::{Layout, WidgetID}, parser::{Fetchable, ParseDocumentParams, ParserState}, taffy::prelude::length, - widget::{label::WidgetLabel, rectangle::WidgetRectangle}, + widget::label::WidgetLabel, }; -use crate::{frontend::FrontendTasks, task::Tasks}; +use crate::task::Tasks; #[derive(Clone)] enum Task { @@ -27,7 +27,6 @@ pub struct View { #[allow(dead_code)] pub state: ParserState, tasks: Tasks, - frontend_tasks: FrontendTasks, on_submit: Rc, cur_raw_width: u16, @@ -51,7 +50,6 @@ pub struct Result { pub struct Params<'a> { pub globals: WguiGlobals, - pub frontend_tasks: FrontendTasks, pub layout: &'a mut Layout, pub parent_id: WidgetID, pub on_submit: Rc, @@ -114,7 +112,6 @@ impl View { let mut res = Self { state, tasks, - frontend_tasks: params.frontend_tasks, on_submit: params.on_submit, cur_raw_width: RES_WIDTHS[2], cur_raw_height: RES_HEIGHTS[2], diff --git a/dash-frontend/src/views/display_list.rs b/dash-frontend/src/views/display_list.rs index 851c535..9f00aa3 100644 --- a/dash-frontend/src/views/display_list.rs +++ b/dash-frontend/src/views/display_list.rs @@ -1,40 +1,38 @@ -use std::{cell::RefCell, collections::HashMap, rc::Rc}; +use std::{cell::RefCell, rc::Rc}; use wayvr_ipc::{ - packet_client::{AttachTo, WvrDisplayCreateParams}, - packet_server::WvrDisplay, + packet_client::{self}, + packet_server::{self}, }; use wgui::{ assets::AssetPath, components::{self, button::ComponentButton}, - drawing::Color, globals::WguiGlobals, i18n::Translation, - layout::{Layout, WidgetID}, + layout::{Layout, WidgetID, WidgetPair}, parser::{Fetchable, ParseDocumentParams, ParserState}, renderer_vk::text::{FontWeight, HorizontalAlign, TextStyle}, taffy::{self, prelude::length}, widget::{ ConstructEssentials, label::{WidgetLabel, WidgetLabelParams}, - rectangle::{WidgetRectangle, WidgetRectangleParams}, - util::WLength, }, }; -use wlx_common::dash_interface; +use wlx_common::dash_interface::BoxDashInterface; use crate::{ frontend::{FrontendTask, FrontendTasks}, - tab::TabUpdateParams, task::Tasks, util::popup_manager::{MountPopupParams, PopupHandle}, - views::add_display, + views::{add_display, display_options}, }; #[derive(Clone)] enum Task { AddDisplay, AddDisplayFinish(add_display::Result), + DisplayOptions(packet_server::WvrDisplay), + DisplayOptionsFinish, Refresh, } @@ -47,6 +45,7 @@ pub struct Params<'a> { struct State { view_add_display: Option<(PopupHandle, add_display::View)>, + view_display_options: Option<(PopupHandle, display_options::View)>, } pub struct View { @@ -76,7 +75,10 @@ impl View { tasks.handle_button(btn_add, Task::AddDisplay); tasks.push(Task::Refresh); - let state = Rc::new(RefCell::new(State { view_add_display: None })); + let state = Rc::new(RefCell::new(State { + view_add_display: None, + view_display_options: None, + })); Ok(Self { parser_state, @@ -88,11 +90,7 @@ impl View { }) } - pub fn update( - &mut self, - layout: &mut Layout, - interface: &mut Box, - ) -> anyhow::Result<()> { + pub fn update(&mut self, layout: &mut Layout, interface: &mut BoxDashInterface) -> anyhow::Result<()> { loop { let tasks = self.tasks.drain(); if tasks.is_empty() { @@ -102,7 +100,9 @@ impl View { match task { Task::AddDisplay => self.add_display(), Task::AddDisplayFinish(result) => self.add_display_finish(interface, result)?, + Task::DisplayOptionsFinish => self.display_options_finish(), Task::Refresh => self.refresh(layout, interface)?, + Task::DisplayOptions(display) => self.display_options(display)?, } } } @@ -112,71 +112,87 @@ impl View { view.update(layout)?; } + if let Some((_, view)) = &mut state.view_display_options { + view.update(layout, interface)?; + } + Ok(()) } } +pub fn construct_display_button( + ess: &mut ConstructEssentials, + globals: &WguiGlobals, + display: &packet_server::WvrDisplay, +) -> anyhow::Result<(WidgetPair, Rc)> { + let aspect = display.width as f32 / display.height as f32; + let height = 96.0; + let width = height * aspect; + let accent_color = globals.defaults().accent_color; + + let (widget_button, button) = components::button::construct( + ess, + components::button::Params { + color: Some(accent_color.with_alpha(0.2)), + border_color: Some(accent_color), + style: taffy::Style { + align_items: Some(taffy::AlignItems::Center), + justify_content: Some(taffy::JustifyContent::Center), + size: taffy::Size { + width: length(width), + height: length(height), + }, + ..Default::default() + }, + ..Default::default() + }, + )?; + + let label_name = WidgetLabel::create( + &mut globals.get(), + WidgetLabelParams { + content: Translation::from_raw_text(&display.name), + style: TextStyle { + weight: Some(FontWeight::Bold), + wrap: true, + align: Some(HorizontalAlign::Center), + ..Default::default() + }, + }, + ); + + let label_resolution = WidgetLabel::create( + &mut globals.get(), + WidgetLabelParams { + content: Translation::from_raw_text(""), + ..Default::default() + }, + ); + + ess.layout.add_child(widget_button.id, label_name, Default::default())?; + ess + .layout + .add_child(widget_button.id, label_resolution, Default::default())?; + + Ok((widget_button, button)) +} + fn fill_display_list( globals: &WguiGlobals, ess: &mut ConstructEssentials, - list: Vec, + list: Vec, + tasks: &Tasks, ) -> anyhow::Result<()> { - let accent_color = globals.defaults().accent_color; - for entry in list { - let aspect = entry.width as f32 / entry.height as f32; + let (_, button) = construct_display_button(ess, globals, &entry)?; - let height = 96.0; - let width = height * aspect; - - let (widget_button, button) = components::button::construct( - ess, - components::button::Params { - color: Some(accent_color.with_alpha(0.2)), - border_color: Some(accent_color), - style: taffy::Style { - align_items: Some(taffy::AlignItems::Center), - justify_content: Some(taffy::JustifyContent::Center), - size: taffy::Size { - width: length(width), - height: length(height), - }, - ..Default::default() - }, - ..Default::default() - }, - )?; - - button.on_click(Box::new(move |_, _| { - log::error!("display options todo"); - Ok(()) - })); - - let label_name = WidgetLabel::create( - &mut globals.get(), - WidgetLabelParams { - content: Translation::from_raw_text(&entry.name), - style: TextStyle { - weight: Some(FontWeight::Bold), - wrap: true, - align: Some(HorizontalAlign::Center), - ..Default::default() - }, - }, - ); - - let label_resolution = WidgetLabel::create( - &mut globals.get(), - WidgetLabelParams { - content: Translation::from_raw_text(""), - ..Default::default() - }, - ); - - ess.layout.add_child(widget_button.id, label_name, Default::default())?; - ess - .layout - .add_child(widget_button.id, label_resolution, Default::default())?; + button.on_click({ + let tasks = tasks.clone(); + Box::new(move |_, _| { + tasks.push(Task::DisplayOptions(entry.clone())); + Ok(()) + }) + }); } Ok(()) @@ -187,7 +203,6 @@ impl View { self.frontend_tasks.push(FrontendTask::MountPopup(MountPopupParams { title: Translation::from_translation_key("ADD_DISPLAY"), on_content: { - let frontend_tasks = self.frontend_tasks.clone(); let globals = self.globals.clone(); let state = self.state.clone(); @@ -203,7 +218,6 @@ impl View { state.borrow_mut().view_add_display = Some(( data.handle, add_display::View::new(add_display::Params { - frontend_tasks: frontend_tasks.clone(), globals: globals.clone(), layout: data.layout, parent_id: data.id_content, @@ -218,25 +232,26 @@ impl View { fn add_display_finish( &mut self, - interface: &mut Box, + interface: &mut BoxDashInterface, result: add_display::Result, ) -> anyhow::Result<()> { - interface.display_create(WvrDisplayCreateParams { + interface.display_create(packet_client::WvrDisplayCreateParams { width: result.width, height: result.height, name: result.display_name, - attach_to: AttachTo::None, + attach_to: packet_client::AttachTo::None, scale: None, })?; self.state.borrow_mut().view_add_display = None; Ok(()) } - fn refresh( - &mut self, - layout: &mut Layout, - interface: &mut Box, - ) -> anyhow::Result<()> { + fn display_options_finish(&mut self) { + self.state.borrow_mut().view_display_options = None; + self.tasks.push(Task::Refresh); + } + + fn refresh(&mut self, layout: &mut Layout, interface: &mut BoxDashInterface) -> anyhow::Result<()> { layout.remove_children(self.id_list_parent); let mut text: Option = None; @@ -252,6 +267,7 @@ impl View { parent: self.id_list_parent, }, list, + &self.tasks, )? } } @@ -274,4 +290,33 @@ impl View { Ok(()) } + + fn display_options(&mut self, display: packet_server::WvrDisplay) -> anyhow::Result<()> { + self.frontend_tasks.push(FrontendTask::MountPopup(MountPopupParams { + title: Translation::from_translation_key("DISPLAY_OPTIONS"), + on_content: { + let frontend_tasks = self.frontend_tasks.clone(); + let globals = self.globals.clone(); + let state = self.state.clone(); + let tasks = self.tasks.clone(); + + Rc::new(move |data| { + state.borrow_mut().view_display_options = Some(( + data.handle, + display_options::View::new(display_options::Params { + globals: globals.clone(), + layout: data.layout, + parent_id: data.id_content, + on_submit: tasks.make_callback(Task::DisplayOptionsFinish), + display: display.clone(), + frontend_tasks: frontend_tasks.clone(), + })?, + )); + Ok(()) + }) + }, + })); + + Ok(()) + } } diff --git a/dash-frontend/src/views/display_options.rs b/dash-frontend/src/views/display_options.rs new file mode 100644 index 0000000..4b0a9ce --- /dev/null +++ b/dash-frontend/src/views/display_options.rs @@ -0,0 +1,131 @@ +use std::rc::Rc; + +use anyhow::Context; +use wayvr_ipc::packet_server; +use wgui::{ + assets::AssetPath, + components::{button::ComponentButton, checkbox::ComponentCheckbox, slider::ComponentSlider}, + event::StyleSetRequest, + globals::WguiGlobals, + i18n::Translation, + layout::{Layout, WidgetID}, + parser::{Fetchable, ParseDocumentParams, ParserState}, + taffy::prelude::length, + widget::{ConstructEssentials, label::WidgetLabel, rectangle::WidgetRectangle}, +}; +use wlx_common::dash_interface::{self, BoxDashInterface}; + +use crate::{ + frontend::{FrontendTask, FrontendTasks}, + task::Tasks, + views::display_list::construct_display_button, +}; + +#[derive(Clone)] +enum Task { + SetVisible(bool), + Remove, +} + +pub struct View { + #[allow(dead_code)] + pub state: ParserState, + tasks: Tasks, + frontend_tasks: FrontendTasks, + display: packet_server::WvrDisplay, + on_submit: Rc, +} + +pub struct Params<'a> { + pub globals: WguiGlobals, + pub frontend_tasks: FrontendTasks, + pub layout: &'a mut Layout, + pub parent_id: WidgetID, + pub on_submit: Rc, + pub display: packet_server::WvrDisplay, +} + +impl View { + pub fn new(params: Params) -> anyhow::Result { + let doc_params = &ParseDocumentParams { + globals: params.globals.clone(), + path: AssetPath::BuiltIn("gui/view/display_options.xml"), + extra: Default::default(), + }; + + let state = wgui::parser::parse_from_assets(doc_params, params.layout, params.parent_id)?; + + let tasks = Tasks::new(); + + let display_parent = state.get_widget_id("display_parent")?; + let btn_remove = state.fetch_component_as::("btn_remove")?; + let btn_show_hide = state.fetch_component_as::("btn_show_hide")?; + + construct_display_button( + &mut ConstructEssentials { + layout: params.layout, + parent: display_parent, + }, + ¶ms.globals, + ¶ms.display, + )?; + + { + let mut c = params.layout.start_common(); + btn_show_hide.set_text( + &mut c.common(), + Translation::from_translation_key(if params.display.visible { "HIDE" } else { "SHOW" }), + ); + c.finish()?; + } + + tasks.handle_button(btn_remove, Task::Remove); + tasks.handle_button(btn_show_hide, Task::SetVisible(!params.display.visible)); + + Ok(Self { + state, + tasks, + display: params.display, + frontend_tasks: params.frontend_tasks, + on_submit: params.on_submit, + }) + } + + pub fn update(&mut self, layout: &mut Layout, interface: &mut BoxDashInterface) -> anyhow::Result<()> { + for task in self.tasks.drain() { + match task { + Task::SetVisible(v) => self.action_set_visible(interface, v), + Task::Remove => self.action_remove(interface), + } + } + Ok(()) + } +} + +impl View { + fn action_set_visible(&mut self, interface: &mut BoxDashInterface, visible: bool) { + if let Err(e) = interface.display_set_visible(self.display.handle.clone(), visible) { + self + .frontend_tasks + .push(FrontendTask::PushToast(Translation::from_raw_text_string(format!( + "Failed to remove display: {:?}", + e + )))); + }; + + (*self.on_submit)(); + } + + fn action_remove(&mut self, interface: &mut BoxDashInterface) { + if let Err(e) = interface.display_remove(self.display.handle.clone()) { + self + .frontend_tasks + .push(FrontendTask::PushToast(Translation::from_raw_text_string(format!( + "Failed to remove display: {:?}", + e + )))); + }; + + (*self.on_submit)(); + } +} diff --git a/dash-frontend/src/views/mod.rs b/dash-frontend/src/views/mod.rs index ec19001..631d1f2 100644 --- a/dash-frontend/src/views/mod.rs +++ b/dash-frontend/src/views/mod.rs @@ -2,3 +2,4 @@ pub mod add_display; pub mod app_launcher; pub mod audio_settings; pub mod display_list; +pub mod display_options; diff --git a/scripts/translator/description.txt b/scripts/translator/description.txt index 1774ac5..49159bb 100644 --- a/scripts/translator/description.txt +++ b/scripts/translator/description.txt @@ -11,6 +11,7 @@ Glossary: - Playspace: A designated real area where users can interact with the virtual environment - 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; +- Display: A virtual monitor located in WayVR environment. It has a specific resolution and it contains virtual windows. +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. diff --git a/wgui/src/components/button.rs b/wgui/src/components/button.rs index 2f66cdc..79a425b 100644 --- a/wgui/src/components/button.rs +++ b/wgui/src/components/button.rs @@ -383,7 +383,6 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul style.justify_content = Some(JustifyContent::Center); style.overflow.x = taffy::Overflow::Hidden; style.overflow.y = taffy::Overflow::Hidden; - style.gap = length(8.0); // update colors to default ones if they are not specified let color = if let Some(color) = params.color { @@ -434,6 +433,13 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul (color.r + color.g + color.b) * mult < 1.5 }; + let default_margin = taffy::Rect { + top: length(4.0), + bottom: length(4.0), + left: length(4.0), + right: length(4.0), + }; + if let Some(sprite_path) = params.sprite_src { let sprite = WidgetSprite::create(WidgetSpriteParams { glyph_data: Some(CustomGlyphData::new(CustomGlyphContent::from_assets( @@ -451,12 +457,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul width: length(20.0), height: length(20.0), }, - margin: taffy::Rect { - top: length(4.0), - bottom: length(4.0), - left: length(0.0), - right: length(0.0), - }, + margin: default_margin.clone(), ..Default::default() }, )?; @@ -480,7 +481,10 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul }, }, ), - Default::default(), + taffy::Style { + margin: default_margin, + ..Default::default() + }, )?; label.id } else { diff --git a/wlx-common/src/dash_interface.rs b/wlx-common/src/dash_interface.rs index 1cd79c3..e2a0f82 100644 --- a/wlx-common/src/dash_interface.rs +++ b/wlx-common/src/dash_interface.rs @@ -23,3 +23,5 @@ pub trait DashInterface { fn process_terminate(&mut self, handle: WvrProcessHandle) -> anyhow::Result<()>; fn window_set_visible(&mut self, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>; } + +pub type BoxDashInterface = Box;