display_list, add_display views (wip)
[skip ci]
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1479,6 +1479,7 @@ dependencies = [
|
|||||||
"rust-embed",
|
"rust-embed",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"wayvr_ipc",
|
||||||
"wgui",
|
"wgui",
|
||||||
"wlx-common",
|
"wlx-common",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,3 +15,4 @@ gtk = "0.18.2"
|
|||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
serde_json = "1.0.145"
|
serde_json = "1.0.145"
|
||||||
wlx-common = { path = "../wlx-common" }
|
wlx-common = { path = "../wlx-common" }
|
||||||
|
wayvr_ipc = { workspace = true }
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<include src="t_tab_title.xml" />
|
<include src="t_tab_title.xml" />
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<TabTitle translation="PROCESSES" icon="dashboard/window.svg" />
|
<TabTitle translation="LIST_OF_DISPLAYS" icon="dashboard/window.svg" />
|
||||||
|
<div id="display_list_parent" />
|
||||||
|
<TabTitle translation="LIST_OF_PROCESSES" icon="dashboard/cpu.svg" />
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
21
dash-frontend/assets/gui/view/add_display.xml
Normal file
21
dash-frontend/assets/gui/view/add_display.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<layout>
|
||||||
|
<include src="../t_group_box.xml" />
|
||||||
|
|
||||||
|
<elements>
|
||||||
|
<div gap="8" flex_direction="column" width="100%" justify_self="center" align_items="center" justify_content="center">
|
||||||
|
<rectangle macro="group_box">
|
||||||
|
<label translation="POPUP_ADD_DISPLAY.RESOLUTION" weight="bold" size="20" />
|
||||||
|
<Slider id="slider_width" min_value="0" max_value="10" width="250" height="24" />
|
||||||
|
<Slider id="slider_height" min_value="0" max_value="10" width="250" height="24" />
|
||||||
|
<rectangle macro="group_box" id="rect_display">
|
||||||
|
<label id="label_display" />
|
||||||
|
</rectangle>
|
||||||
|
</rectangle>
|
||||||
|
<Button id="btn_confirm" color="#44ce22FF" padding_top="4" padding_bottom="4" round="8" padding_left="12" padding_right="12">
|
||||||
|
<sprite src_builtin="dashboard/display.svg" width="32" height="32" />
|
||||||
|
<label translation="ADD_DISPLAY" weight="bold" size="17" shadow="#00000099" />
|
||||||
|
</Button>
|
||||||
|
<label id="label_display_name" weight="bold" size="20" />
|
||||||
|
</div>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<CheckBox text="Run in Wayland mode" checked="1" />
|
<CheckBox text="Run in Wayland mode" checked="1" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<Button color="#44ce22FF" padding_top="4" padding_bottom="4" round="8" padding_right="12">
|
<Button color="#44ce22FF" padding_top="4" padding_bottom="4" round="8" padding_right="12">
|
||||||
<sprite src="dashboard/play.svg" width="32" height="32" />
|
<sprite src_builtin="dashboard/play.svg" width="32" height="32" />
|
||||||
<label text="Launch embedded" weight="bold" size="17" shadow="#00000099" />
|
<label text="Launch embedded" weight="bold" size="17" shadow="#00000099" />
|
||||||
</Button>
|
</Button>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
10
dash-frontend/assets/gui/view/display_list.xml
Normal file
10
dash-frontend/assets/gui/view/display_list.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<layout>
|
||||||
|
<include src="../t_group_box.xml" />
|
||||||
|
|
||||||
|
<elements>
|
||||||
|
<rectangle macro="group_box" flex_direction="row">
|
||||||
|
<div id="list_parent" />
|
||||||
|
<Button id="btn_add" sprite_src_builtin="dashboard/add.svg" tooltip="ADD_DISPLAY" height="100%" width="32" />
|
||||||
|
</rectangle>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<div gap="16" align_items="center">
|
<div gap="16" align_items="center">
|
||||||
<!-- Back button -->
|
<!-- Back button -->
|
||||||
<Button id="but_back" width="48" height="48" color="#ffffff00" border_color="#ffffff00">
|
<Button id="but_back" width="48" height="48" color="#ffffff00" border_color="#ffffff00">
|
||||||
<sprite src="dashboard/back.svg" width="24" height="24" />
|
<sprite src_builtin="dashboard/back.svg" width="24" height="24" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
|
|||||||
@@ -45,5 +45,12 @@
|
|||||||
},
|
},
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"RECENTER_PLAYSPACE": "Playspace neu zentrieren"
|
"RECENTER_PLAYSPACE": "Playspace neu zentrieren"
|
||||||
|
},
|
||||||
|
"LIST_OF_DISPLAYS": "Anzeigeliste",
|
||||||
|
"LIST_OF_PROCESSES": "Prozessliste",
|
||||||
|
"NO_DISPLAYS_FOUND": "Keine Displays gefunden",
|
||||||
|
"ADD_DISPLAY": "Bildschirm hinzufügen",
|
||||||
|
"POPUP_ADD_DISPLAY": {
|
||||||
|
"RESOLUTION": "Auflösung"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,56 @@
|
|||||||
{
|
{
|
||||||
"HOME_SCREEN": "Home",
|
|
||||||
"MONADO_RUNTIME": "„Monado” runtime",
|
|
||||||
"APPLICATIONS": "Applications",
|
|
||||||
"GAMES": "Games",
|
|
||||||
"SETTINGS": "Settings",
|
|
||||||
"PROCESSES": "Processes",
|
|
||||||
"HELLO_USER": "Hello, {USER}!",
|
|
||||||
"HELLO": "Hello!",
|
|
||||||
"GENERAL_SETTINGS": "General settings",
|
|
||||||
"APPLICATION_LAUNCHER": "Application launcher",
|
|
||||||
"APP_SETTINGS": {
|
|
||||||
"RESTART_SOFTWARE": "Restart software",
|
|
||||||
"HIDE_USERNAME": "Hide username",
|
|
||||||
"OPAQUE_BACKGROUND": "Opaque background",
|
|
||||||
"RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Run in XWayland mode by default",
|
|
||||||
"WLX_OVERLAY_S_SETTINGS": "WlxOverlay-S settings",
|
|
||||||
"HEADSET_SETTINGS": "Headset settings",
|
|
||||||
"BRIGHTNESS": "Brightness",
|
|
||||||
"WLX": {
|
|
||||||
"NOTIFICATIONS_ENABLED": "Notifications enabled",
|
|
||||||
"NOTIFICATIONS_SOUND_ENABLED": "Notifications sound enabled",
|
|
||||||
"KEYBOARD_SOUND_ENABLED": "Keyboard sound enabled",
|
|
||||||
"BLOCK_GAME_INPUT": "Block game input",
|
|
||||||
"SPACE_DRAG_MULTIPLIER": "Space-drag multiplier",
|
|
||||||
"SPACE_DRAG_ROTATION_ENABLED": "Enable rotation in space-drag",
|
|
||||||
"SHOW_SKYBOX": "Show skybox",
|
|
||||||
"ENABLE_PASSTHROUGH": "Enable passthrough"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AUDIO": {
|
|
||||||
"SELECT_AUDIO_CARD_PROFILE": "Select audio card profile",
|
|
||||||
"SETTINGS": "Audio settings",
|
|
||||||
"VOLUME": "Volume",
|
|
||||||
"AUTO_SWITCH_TO_VR_AUDIO": "Auto-switch to VR audio",
|
|
||||||
"SPEAKERS": "Speakers",
|
|
||||||
"MICROPHONES": "Microphones",
|
|
||||||
"CARDS": "Cards",
|
|
||||||
"NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "No VR speakers found. Switch them manually.",
|
|
||||||
"NO_VR_MICROPHONE_SWITCH_MANUALLY": "No VR microphone found. Switch it manually.",
|
|
||||||
"FAILED_TO_SWITCH_MICROPHONE": "Failed to switch microphone",
|
|
||||||
"MICROPHONE_SET_SUCCESSFULLY": "Microphone set successfully",
|
|
||||||
"SPEAKERS_SET_SUCCESSFULLY": "Speakers set successfully",
|
|
||||||
"DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Device found and initialized, but not switched"
|
|
||||||
},
|
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"RECENTER_PLAYSPACE": "Re-center playspace"
|
"RECENTER_PLAYSPACE": "Re-center playspace"
|
||||||
}
|
},
|
||||||
|
"POPUP_ADD_DISPLAY": {
|
||||||
|
"RESOLUTION": "Resolution"
|
||||||
|
},
|
||||||
|
"ADD_DISPLAY": "Add display",
|
||||||
|
"APP_SETTINGS": {
|
||||||
|
"BRIGHTNESS": "Brightness",
|
||||||
|
"HEADSET_SETTINGS": "Headset settings",
|
||||||
|
"HIDE_USERNAME": "Hide username",
|
||||||
|
"OPAQUE_BACKGROUND": "Opaque background",
|
||||||
|
"RESTART_SOFTWARE": "Restart software",
|
||||||
|
"RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Run in XWayland mode by default",
|
||||||
|
"WLX": {
|
||||||
|
"BLOCK_GAME_INPUT": "Block game input",
|
||||||
|
"ENABLE_PASSTHROUGH": "Enable passthrough",
|
||||||
|
"KEYBOARD_SOUND_ENABLED": "Keyboard sound enabled",
|
||||||
|
"NOTIFICATIONS_ENABLED": "Notifications enabled",
|
||||||
|
"NOTIFICATIONS_SOUND_ENABLED": "Notifications sound enabled",
|
||||||
|
"SHOW_SKYBOX": "Show skybox",
|
||||||
|
"SPACE_DRAG_MULTIPLIER": "Space-drag multiplier",
|
||||||
|
"SPACE_DRAG_ROTATION_ENABLED": "Enable rotation in space-drag"
|
||||||
|
},
|
||||||
|
"WLX_OVERLAY_S_SETTINGS": "WlxOverlay-S settings"
|
||||||
|
},
|
||||||
|
"APPLICATION_LAUNCHER": "Application launcher",
|
||||||
|
"APPLICATIONS": "Applications",
|
||||||
|
"AUDIO": {
|
||||||
|
"AUTO_SWITCH_TO_VR_AUDIO": "Auto-switch to VR audio",
|
||||||
|
"CARDS": "Cards",
|
||||||
|
"DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Device found and initialized, but not switched",
|
||||||
|
"FAILED_TO_SWITCH_MICROPHONE": "Failed to switch microphone",
|
||||||
|
"MICROPHONE_SET_SUCCESSFULLY": "Microphone set successfully",
|
||||||
|
"MICROPHONES": "Microphones",
|
||||||
|
"NO_VR_MICROPHONE_SWITCH_MANUALLY": "No VR microphone found. Switch it manually.",
|
||||||
|
"NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "No VR speakers found. Switch them manually.",
|
||||||
|
"SELECT_AUDIO_CARD_PROFILE": "Select audio card profile",
|
||||||
|
"SETTINGS": "Audio settings",
|
||||||
|
"SPEAKERS": "Speakers",
|
||||||
|
"SPEAKERS_SET_SUCCESSFULLY": "Speakers set successfully",
|
||||||
|
"VOLUME": "Volume"
|
||||||
|
},
|
||||||
|
"GAMES": "Games",
|
||||||
|
"GENERAL_SETTINGS": "General settings",
|
||||||
|
"HELLO": "Hello!",
|
||||||
|
"HELLO_USER": "Hello, {USER}!",
|
||||||
|
"HOME_SCREEN": "Home",
|
||||||
|
"LIST_OF_DISPLAYS": "Display list",
|
||||||
|
"LIST_OF_PROCESSES": "Process list",
|
||||||
|
"MONADO_RUNTIME": "„Monado” runtime",
|
||||||
|
"NO_DISPLAYS_FOUND": "No displays found",
|
||||||
|
"PROCESSES": "Processes",
|
||||||
|
"SETTINGS": "Settings"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,5 +45,12 @@
|
|||||||
},
|
},
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"RECENTER_PLAYSPACE": "Re-centrar espacio de juego"
|
"RECENTER_PLAYSPACE": "Re-centrar espacio de juego"
|
||||||
|
},
|
||||||
|
"LIST_OF_DISPLAYS": "Lista de pantallas",
|
||||||
|
"LIST_OF_PROCESSES": "Lista de procesos",
|
||||||
|
"NO_DISPLAYS_FOUND": "No se encontraron pantallas",
|
||||||
|
"ADD_DISPLAY": "Agregar pantalla",
|
||||||
|
"POPUP_ADD_DISPLAY": {
|
||||||
|
"RESOLUTION": "Resolución"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,5 +45,12 @@
|
|||||||
},
|
},
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"RECENTER_PLAYSPACE": "プレイスペースを再中央"
|
"RECENTER_PLAYSPACE": "プレイスペースを再中央"
|
||||||
|
},
|
||||||
|
"LIST_OF_DISPLAYS": "ディスプレイリスト",
|
||||||
|
"LIST_OF_PROCESSES": "プロセスのリスト",
|
||||||
|
"NO_DISPLAYS_FOUND": "ディスプレイが見つかりません",
|
||||||
|
"ADD_DISPLAY": "ディスプレイを追加",
|
||||||
|
"POPUP_ADD_DISPLAY": {
|
||||||
|
"RESOLUTION": "解像度"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,5 +45,12 @@
|
|||||||
},
|
},
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"RECENTER_PLAYSPACE": "Wycentruj przestrzeń"
|
"RECENTER_PLAYSPACE": "Wycentruj przestrzeń"
|
||||||
|
},
|
||||||
|
"LIST_OF_DISPLAYS": "Lista wyświetlaczy",
|
||||||
|
"LIST_OF_PROCESSES": "Lista procesów",
|
||||||
|
"NO_DISPLAYS_FOUND": "Brak monitorów",
|
||||||
|
"ADD_DISPLAY": "Dodaj monitor",
|
||||||
|
"POPUP_ADD_DISPLAY": {
|
||||||
|
"RESOLUTION": "Rozdzielczość"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,8 +18,8 @@ use wlx_common::{dash_interface, timestep::Timestep};
|
|||||||
use crate::{
|
use crate::{
|
||||||
assets, settings,
|
assets, settings,
|
||||||
tab::{
|
tab::{
|
||||||
Tab, TabParams, TabType, apps::TabApps, games::TabGames, home::TabHome, monado::TabMonado, processes::TabProcesses,
|
Tab, TabParams, TabType, TabUpdateParams, apps::TabApps, games::TabGames, home::TabHome, monado::TabMonado,
|
||||||
settings::TabSettings,
|
processes::TabProcesses, settings::TabSettings,
|
||||||
},
|
},
|
||||||
task::Tasks,
|
task::Tasks,
|
||||||
util::{
|
util::{
|
||||||
@@ -166,6 +166,17 @@ impl Frontend {
|
|||||||
self.process_task(rc_this, task)?;
|
self.process_task(rc_this, task)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(tab) = &mut self.current_tab {
|
||||||
|
let mut layout = self.layout.borrow_mut();
|
||||||
|
|
||||||
|
tab.update(TabUpdateParams {
|
||||||
|
globals: &self.globals,
|
||||||
|
frontend_tasks: &self.tasks,
|
||||||
|
layout: &mut layout,
|
||||||
|
interface: &mut self.interface,
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
self.tick(width, height, timestep_alpha)?;
|
self.tick(width, height, timestep_alpha)?;
|
||||||
self.ticks += 1;
|
self.ticks += 1;
|
||||||
|
|
||||||
@@ -292,6 +303,7 @@ impl Frontend {
|
|||||||
frontend: rc_this,
|
frontend: rc_this,
|
||||||
//frontend_widgets: &self.widgets,
|
//frontend_widgets: &self.widgets,
|
||||||
settings: self.settings.get_mut(),
|
settings: self.settings.get_mut(),
|
||||||
|
frontend_tasks: &self.tasks,
|
||||||
};
|
};
|
||||||
|
|
||||||
let tab: Box<dyn Tab> = match tab_type {
|
let tab: Box<dyn Tab> = match tab_type {
|
||||||
@@ -308,15 +320,6 @@ 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();
|
||||||
|
|
||||||
@@ -325,44 +328,38 @@ impl Frontend {
|
|||||||
// ################################
|
// ################################
|
||||||
|
|
||||||
// "Home" side button
|
// "Home" side button
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_side_home")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_side_home")?,
|
|
||||||
FrontendTask::SetTab(TabType::Home),
|
FrontendTask::SetTab(TabType::Home),
|
||||||
);
|
);
|
||||||
|
|
||||||
// "Apps" side button
|
// "Apps" side button
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_side_apps")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_side_apps")?,
|
|
||||||
FrontendTask::SetTab(TabType::Apps),
|
FrontendTask::SetTab(TabType::Apps),
|
||||||
);
|
);
|
||||||
|
|
||||||
// "Games" side button
|
// "Games" side button
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_side_games")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_side_games")?,
|
|
||||||
FrontendTask::SetTab(TabType::Games),
|
FrontendTask::SetTab(TabType::Games),
|
||||||
);
|
);
|
||||||
|
|
||||||
// "Monado side button"
|
// "Monado side button"
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_side_monado")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_side_monado")?,
|
|
||||||
FrontendTask::SetTab(TabType::Monado),
|
FrontendTask::SetTab(TabType::Monado),
|
||||||
);
|
);
|
||||||
|
|
||||||
// "Processes" side button
|
// "Processes" side button
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_side_processes")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_side_processes")?,
|
|
||||||
FrontendTask::SetTab(TabType::Processes),
|
FrontendTask::SetTab(TabType::Processes),
|
||||||
);
|
);
|
||||||
|
|
||||||
// "Settings" side button
|
// "Settings" side button
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_side_settings")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_side_settings")?,
|
|
||||||
FrontendTask::SetTab(TabType::Settings),
|
FrontendTask::SetTab(TabType::Settings),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -371,16 +368,14 @@ impl Frontend {
|
|||||||
// ################################
|
// ################################
|
||||||
|
|
||||||
// "Audio" bottom bar button
|
// "Audio" bottom bar button
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_audio")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_audio")?,
|
|
||||||
FrontendTask::ShowAudioSettings,
|
FrontendTask::ShowAudioSettings,
|
||||||
);
|
);
|
||||||
|
|
||||||
// "Recenter playspace" bottom bar button
|
// "Recenter playspace" bottom bar button
|
||||||
Frontend::register_button_task(
|
this.tasks.handle_button(
|
||||||
rc_this.clone(),
|
this.state.fetch_component_as::<ComponentButton>("btn_recenter")?,
|
||||||
&this.state.fetch_component_as::<ComponentButton>("btn_recenter")?,
|
|
||||||
FrontendTask::RecenterPlayspace,
|
FrontendTask::RecenterPlayspace,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -66,16 +66,12 @@ impl TabHome {
|
|||||||
let btn_processes = state.fetch_component_as::<ComponentButton>("btn_processes")?;
|
let btn_processes = state.fetch_component_as::<ComponentButton>("btn_processes")?;
|
||||||
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 tasks = params.frontend_tasks;
|
||||||
Frontend::register_button_task(frontend.clone(), &btn_apps, FrontendTask::SetTab(TabType::Apps));
|
tasks.handle_button(btn_apps, FrontendTask::SetTab(TabType::Apps));
|
||||||
Frontend::register_button_task(frontend.clone(), &btn_games, FrontendTask::SetTab(TabType::Games));
|
tasks.handle_button(btn_games, FrontendTask::SetTab(TabType::Games));
|
||||||
Frontend::register_button_task(frontend.clone(), &btn_monado, FrontendTask::SetTab(TabType::Monado));
|
tasks.handle_button(btn_monado, FrontendTask::SetTab(TabType::Monado));
|
||||||
Frontend::register_button_task(
|
tasks.handle_button(btn_processes, FrontendTask::SetTab(TabType::Processes));
|
||||||
frontend.clone(),
|
tasks.handle_button(btn_settings, FrontendTask::SetTab(TabType::Settings));
|
||||||
&btn_processes,
|
|
||||||
FrontendTask::SetTab(TabType::Processes),
|
|
||||||
);
|
|
||||||
Frontend::register_button_task(frontend.clone(), &btn_settings, FrontendTask::SetTab(TabType::Settings));
|
|
||||||
|
|
||||||
Ok(Self { state })
|
Ok(Self { state })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ use wgui::{
|
|||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
};
|
};
|
||||||
|
use wlx_common::dash_interface;
|
||||||
|
|
||||||
use crate::frontend::RcFrontend;
|
use crate::frontend::{FrontendTasks, RcFrontend};
|
||||||
|
|
||||||
pub mod apps;
|
pub mod apps;
|
||||||
pub mod games;
|
pub mod games;
|
||||||
@@ -28,9 +29,21 @@ pub struct TabParams<'a> {
|
|||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
pub frontend: &'a RcFrontend,
|
pub frontend: &'a RcFrontend,
|
||||||
pub settings: &'a mut crate::settings::Settings,
|
pub settings: &'a mut crate::settings::Settings,
|
||||||
|
pub frontend_tasks: &'a FrontendTasks,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TabUpdateParams<'a> {
|
||||||
|
pub globals: &'a WguiGlobals,
|
||||||
|
pub frontend_tasks: &'a FrontendTasks,
|
||||||
|
pub layout: &'a mut Layout,
|
||||||
|
pub interface: &'a mut Box<dyn dash_interface::DashInterface>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Tab {
|
pub trait Tab {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn get_type(&self) -> TabType;
|
fn get_type(&self) -> TabType;
|
||||||
|
|
||||||
|
fn update(&mut self, _params: TabUpdateParams) -> anyhow::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,29 @@
|
|||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
parser::{ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::tab::{Tab, TabParams, TabType};
|
use crate::{
|
||||||
|
tab::{Tab, TabParams, TabType, TabUpdateParams},
|
||||||
|
views::display_list,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct TabProcesses {
|
pub struct TabProcesses {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub state: ParserState,
|
pub state: ParserState,
|
||||||
|
|
||||||
|
view_display_list: display_list::View,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tab for TabProcesses {
|
impl Tab for TabProcesses {
|
||||||
fn get_type(&self) -> TabType {
|
fn get_type(&self) -> TabType {
|
||||||
TabType::Games
|
TabType::Games
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, params: TabUpdateParams) -> anyhow::Result<()> {
|
||||||
|
self.view_display_list.update(params.layout, params.interface)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TabProcesses {
|
impl TabProcesses {
|
||||||
@@ -28,6 +38,14 @@ impl TabProcesses {
|
|||||||
params.parent_id,
|
params.parent_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self { state })
|
Ok(Self {
|
||||||
|
view_display_list: display_list::View::new(display_list::Params {
|
||||||
|
layout: params.layout,
|
||||||
|
parent_id: state.get_widget_id("display_list_parent")?,
|
||||||
|
globals: params.globals.clone(),
|
||||||
|
frontend_tasks: params.frontend_tasks.clone(),
|
||||||
|
})?,
|
||||||
|
state,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
use std::{cell::RefCell, collections::VecDeque, rc::Rc};
|
use std::{cell::RefCell, collections::VecDeque, rc::Rc};
|
||||||
|
|
||||||
#[derive(Clone)]
|
use wgui::components::button::ComponentButton;
|
||||||
pub struct Tasks<TaskType>(Rc<RefCell<VecDeque<TaskType>>>)
|
|
||||||
where
|
|
||||||
TaskType: Clone;
|
|
||||||
|
|
||||||
impl<TaskType: Clone + 'static> Tasks<TaskType> {
|
pub struct Tasks<TaskType>(Rc<RefCell<VecDeque<TaskType>>>);
|
||||||
|
|
||||||
|
impl<T> Clone for Tasks<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self(self.0.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<TaskType: 'static> Tasks<TaskType> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(Rc::new(RefCell::new(VecDeque::new())))
|
Self(Rc::new(RefCell::new(VecDeque::new())))
|
||||||
}
|
}
|
||||||
@@ -20,8 +25,27 @@ impl<TaskType: Clone + 'static> Tasks<TaskType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TaskType: Clone + 'static> Default for Tasks<TaskType> {
|
impl<TaskType: 'static> Default for Tasks<TaskType> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<TaskType: Clone + 'static> Tasks<TaskType> {
|
||||||
|
pub fn handle_button(&self, button: Rc<ComponentButton>, task: TaskType) {
|
||||||
|
button.on_click({
|
||||||
|
let this = self.clone();
|
||||||
|
Box::new(move |_, _| {
|
||||||
|
this.push(task.clone());
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_callback(&self, task: TaskType) -> Rc<dyn Fn()> {
|
||||||
|
let this = self.clone();
|
||||||
|
Rc::new(move || {
|
||||||
|
this.push(task.clone());
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
79
dash-frontend/src/views/add_display.rs
Normal file
79
dash-frontend/src/views/add_display.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
|
use wgui::{
|
||||||
|
assets::AssetPath,
|
||||||
|
components::{button::ComponentButton, slider::ComponentSlider},
|
||||||
|
globals::WguiGlobals,
|
||||||
|
layout::{Layout, WidgetID},
|
||||||
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{frontend::FrontendTasks, tab::TabUpdateParams, task::Tasks};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Task {
|
||||||
|
Confirm,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct View {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub state: ParserState,
|
||||||
|
tasks: Tasks<Task>,
|
||||||
|
frontend_tasks: FrontendTasks,
|
||||||
|
on_submit: Rc<dyn Fn()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Params<'a> {
|
||||||
|
pub globals: WguiGlobals,
|
||||||
|
pub frontend_tasks: FrontendTasks,
|
||||||
|
pub layout: &'a mut Layout,
|
||||||
|
pub parent_id: WidgetID,
|
||||||
|
pub on_submit: Rc<dyn Fn()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View {
|
||||||
|
pub fn new(params: Params) -> anyhow::Result<Self> {
|
||||||
|
let doc_params = &ParseDocumentParams {
|
||||||
|
globals: params.globals.clone(),
|
||||||
|
path: AssetPath::BuiltIn("gui/view/add_display.xml"),
|
||||||
|
extra: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = wgui::parser::parse_from_assets(doc_params, params.layout, params.parent_id)?;
|
||||||
|
|
||||||
|
let tasks = Tasks::new();
|
||||||
|
|
||||||
|
let slider_width = state.fetch_component_as::<ComponentSlider>("slider_width")?;
|
||||||
|
let slider_height = state.fetch_component_as::<ComponentSlider>("slider_height")?;
|
||||||
|
let label_display_name = state.fetch_widget_as::<WidgetLabel>(¶ms.layout.state, "label_display_name")?;
|
||||||
|
let rect_display = state.fetch_widget_as::<WidgetRectangle>(¶ms.layout.state, "rect_display");
|
||||||
|
let label_display = state.fetch_widget_as::<WidgetLabel>(¶ms.layout.state, "label_display");
|
||||||
|
let btn_confirm = state.fetch_component_as::<ComponentButton>("btn_confirm")?;
|
||||||
|
|
||||||
|
tasks.handle_button(btn_confirm, Task::Confirm);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
state,
|
||||||
|
tasks,
|
||||||
|
frontend_tasks: params.frontend_tasks,
|
||||||
|
on_submit: params.on_submit,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self) -> anyhow::Result<()> {
|
||||||
|
for task in self.tasks.drain() {
|
||||||
|
match task {
|
||||||
|
Task::Confirm => self.confirm(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View {
|
||||||
|
fn confirm(&mut self) {
|
||||||
|
log::info!("confirm");
|
||||||
|
(*self.on_submit)();
|
||||||
|
}
|
||||||
|
}
|
||||||
224
dash-frontend/src/views/display_list.rs
Normal file
224
dash-frontend/src/views/display_list.rs
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
|
use wayvr_ipc::packet_server::WvrDisplay;
|
||||||
|
use wgui::{
|
||||||
|
assets::AssetPath,
|
||||||
|
components::button::ComponentButton,
|
||||||
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
|
layout::{Layout, WidgetID},
|
||||||
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
|
taffy,
|
||||||
|
widget::{
|
||||||
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use wlx_common::dash_interface;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
frontend::{FrontendTask, FrontendTasks},
|
||||||
|
tab::TabUpdateParams,
|
||||||
|
task::Tasks,
|
||||||
|
util::popup_manager::{MountPopupParams, PopupHandle},
|
||||||
|
views::add_display,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Task {
|
||||||
|
AddDisplay,
|
||||||
|
AddDisplayFinish,
|
||||||
|
Refresh,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Params<'a> {
|
||||||
|
pub globals: WguiGlobals,
|
||||||
|
pub frontend_tasks: FrontendTasks,
|
||||||
|
pub layout: &'a mut Layout,
|
||||||
|
pub parent_id: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
view_add_display: Option<(PopupHandle, add_display::View)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct View {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub parser_state: ParserState,
|
||||||
|
tasks: Tasks<Task>,
|
||||||
|
frontend_tasks: FrontendTasks,
|
||||||
|
globals: WguiGlobals,
|
||||||
|
state: Rc<RefCell<State>>,
|
||||||
|
id_list_parent: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View {
|
||||||
|
pub fn new(params: Params) -> anyhow::Result<Self> {
|
||||||
|
let doc_params = &ParseDocumentParams {
|
||||||
|
globals: params.globals.clone(),
|
||||||
|
path: AssetPath::BuiltIn("gui/view/display_list.xml"),
|
||||||
|
extra: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let parser_state = wgui::parser::parse_from_assets(doc_params, params.layout, params.parent_id)?;
|
||||||
|
let list_parent = parser_state.fetch_widget(¶ms.layout.state, "list_parent")?;
|
||||||
|
|
||||||
|
let tasks = Tasks::new();
|
||||||
|
|
||||||
|
let btn_add = parser_state.fetch_component_as::<ComponentButton>("btn_add")?;
|
||||||
|
tasks.handle_button(btn_add, Task::AddDisplay);
|
||||||
|
|
||||||
|
tasks.push(Task::Refresh);
|
||||||
|
|
||||||
|
let state = Rc::new(RefCell::new(State { view_add_display: None }));
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
parser_state,
|
||||||
|
tasks,
|
||||||
|
frontend_tasks: params.frontend_tasks,
|
||||||
|
globals: params.globals,
|
||||||
|
state,
|
||||||
|
id_list_parent: list_parent.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
layout: &mut Layout,
|
||||||
|
interface: &mut Box<dyn dash_interface::DashInterface>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
loop {
|
||||||
|
let tasks = self.tasks.drain();
|
||||||
|
if tasks.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for task in tasks {
|
||||||
|
match task {
|
||||||
|
Task::AddDisplay => self.add_display(),
|
||||||
|
Task::AddDisplayFinish => self.add_display_finish()?,
|
||||||
|
Task::Refresh => self.refresh(layout, interface)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
if let Some((_, view)) = &mut state.view_add_display {
|
||||||
|
view.update()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill_display_list(
|
||||||
|
globals: &WguiGlobals,
|
||||||
|
parent: WidgetID,
|
||||||
|
layout: &mut Layout,
|
||||||
|
list: Vec<WvrDisplay>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
for entry in list {
|
||||||
|
let (rect, _) = layout.add_child(
|
||||||
|
parent,
|
||||||
|
WidgetRectangle::create(WidgetRectangleParams { ..Default::default() }),
|
||||||
|
taffy::Style {
|
||||||
|
align_items: Some(taffy::AlignItems::Center),
|
||||||
|
justify_content: Some(taffy::JustifyContent::Center),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let label_name = WidgetLabel::create(
|
||||||
|
&mut globals.get(),
|
||||||
|
WidgetLabelParams {
|
||||||
|
content: Translation::from_raw_text(&entry.name),
|
||||||
|
style: TextStyle {
|
||||||
|
weight: Some(FontWeight::Bold),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let label_resolution = WidgetLabel::create(
|
||||||
|
&mut globals.get(),
|
||||||
|
WidgetLabelParams {
|
||||||
|
content: Translation::from_raw_text(""),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
layout.add_child(rect.id, label_name, Default::default())?;
|
||||||
|
layout.add_child(rect.id, label_resolution, Default::default())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View {
|
||||||
|
fn add_display(&mut self) {
|
||||||
|
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();
|
||||||
|
let tasks = self.tasks.clone();
|
||||||
|
|
||||||
|
Rc::new(move |data| {
|
||||||
|
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,
|
||||||
|
on_submit: tasks.make_callback(Task::AddDisplayFinish),
|
||||||
|
})?,
|
||||||
|
));
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_display_finish(&mut self) -> anyhow::Result<()> {
|
||||||
|
self.state.borrow_mut().view_add_display = None;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refresh(
|
||||||
|
&mut self,
|
||||||
|
layout: &mut Layout,
|
||||||
|
interface: &mut Box<dyn dash_interface::DashInterface>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
layout.remove_children(self.id_list_parent);
|
||||||
|
|
||||||
|
let mut text: Option<Translation> = None;
|
||||||
|
match interface.display_list() {
|
||||||
|
Ok(list) => {
|
||||||
|
if list.is_empty() {
|
||||||
|
text = Some(Translation::from_translation_key("NO_DISPLAYS_FOUND"))
|
||||||
|
} else {
|
||||||
|
fill_display_list(&self.globals, self.id_list_parent, layout, list)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => text = Some(Translation::from_raw_text(&format!("Error: {:?}", e))),
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(text) = text.take() {
|
||||||
|
layout.add_child(
|
||||||
|
self.id_list_parent,
|
||||||
|
WidgetLabel::create(
|
||||||
|
&mut self.globals.get(),
|
||||||
|
WidgetLabelParams {
|
||||||
|
content: text,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Default::default(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
|
pub mod add_display;
|
||||||
pub mod app_launcher;
|
pub mod app_launcher;
|
||||||
pub mod audio_settings;
|
pub mod audio_settings;
|
||||||
|
pub mod display_list;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ impl Default for Params<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ButtonClickEvent {}
|
pub struct ButtonClickEvent {}
|
||||||
pub type ButtonClickCallback = Box<dyn Fn(&mut CallbackDataCommon, ButtonClickEvent) -> anyhow::Result<()>>;
|
pub type ButtonClickCallback = Box<dyn FnMut(&mut CallbackDataCommon, ButtonClickEvent) -> anyhow::Result<()>>;
|
||||||
|
|
||||||
pub struct Colors {
|
pub struct Colors {
|
||||||
pub color: drawing::Color,
|
pub color: drawing::Color,
|
||||||
@@ -351,7 +351,7 @@ fn register_event_mouse_release(
|
|||||||
state.down = false;
|
state.down = false;
|
||||||
|
|
||||||
if state.hovered
|
if state.hovered
|
||||||
&& let Some(on_click) = &state.on_click
|
&& let Some(on_click) = &mut state.on_click
|
||||||
{
|
{
|
||||||
anim_hover(
|
anim_hover(
|
||||||
rect,
|
rect,
|
||||||
|
|||||||
Reference in New Issue
Block a user