list helpers
This commit is contained in:
@@ -8,7 +8,7 @@ use std::{
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
backend::{input, wayvr::process::KillSignal},
|
||||
backend::input,
|
||||
state::AppState,
|
||||
windowing::{OverlaySelector, window::OverlayWindowConfig},
|
||||
};
|
||||
|
||||
@@ -36,6 +36,8 @@ use super::timer::GuiTimer;
|
||||
|
||||
pub mod button;
|
||||
mod label;
|
||||
pub mod overlay_list;
|
||||
pub mod set_list;
|
||||
|
||||
const DEFAULT_MAX_SIZE: f32 = 2048.0;
|
||||
|
||||
|
||||
143
wlx-overlay-s/src/gui/panel/overlay_list.rs
Normal file
143
wlx-overlay-s/src/gui/panel/overlay_list.rs
Normal file
@@ -0,0 +1,143 @@
|
||||
use std::{collections::HashMap, rc::Rc};
|
||||
|
||||
use slotmap::{Key, SecondaryMap};
|
||||
use wgui::{
|
||||
components::button::ComponentButton,
|
||||
event::{CallbackDataCommon, EventAlterables},
|
||||
layout::Layout,
|
||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||
};
|
||||
|
||||
use crate::windowing::{OverlayID, backend::OverlayEventData, window::OverlayCategory};
|
||||
|
||||
#[derive(Default)]
|
||||
/// Helper for managing a list of overlays
|
||||
/// Populates `id="panels_root"` with `<Screen>`, `<Mirror>`, `<Panel>` templates
|
||||
/// Populates `id="apps_root"` with `<App>` templates (optional)
|
||||
/// Uses the following parameters: `name` (All), `display` (Screen, Mirror), `icon` (App)
|
||||
pub struct OverlayList {
|
||||
overlay_buttons: SecondaryMap<OverlayID, Rc<ComponentButton>>,
|
||||
}
|
||||
|
||||
impl OverlayList {
|
||||
pub fn on_notify(
|
||||
&mut self,
|
||||
layout: &mut Layout,
|
||||
parser_state: &mut ParserState,
|
||||
event_data: &OverlayEventData,
|
||||
alterables: &mut EventAlterables,
|
||||
doc_params: &ParseDocumentParams,
|
||||
) -> anyhow::Result<bool> {
|
||||
let mut elements_changed = false;
|
||||
match event_data {
|
||||
OverlayEventData::OverlaysChanged(metas) => {
|
||||
let panels_root = parser_state
|
||||
.get_widget_id("panels_root")
|
||||
.unwrap_or_default();
|
||||
let apps_root = parser_state.get_widget_id("apps_root").unwrap_or_default();
|
||||
|
||||
layout.remove_children(panels_root);
|
||||
layout.remove_children(apps_root);
|
||||
self.overlay_buttons.clear();
|
||||
|
||||
for (i, meta) in metas.iter().enumerate() {
|
||||
let mut params = HashMap::new();
|
||||
|
||||
let (template, root) = match meta.category {
|
||||
OverlayCategory::Screen => {
|
||||
params.insert(
|
||||
"display".into(),
|
||||
format!(
|
||||
"{}{}",
|
||||
(*meta.name).chars().next().unwrap_or_default(),
|
||||
(*meta.name).chars().last().unwrap_or_default()
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
("Screen", panels_root)
|
||||
}
|
||||
OverlayCategory::Mirror => {
|
||||
params.insert(
|
||||
"display".into(),
|
||||
(*meta.name).chars().last().unwrap().to_string().into(),
|
||||
);
|
||||
("Mirror", panels_root)
|
||||
}
|
||||
OverlayCategory::Panel => ("Panel", panels_root),
|
||||
OverlayCategory::WayVR => {
|
||||
params.insert(
|
||||
"icon".into(),
|
||||
meta.icon
|
||||
.as_ref()
|
||||
.expect("WayVR overlay without Icon attribute!")
|
||||
.as_ref()
|
||||
.into(),
|
||||
);
|
||||
("App", apps_root)
|
||||
}
|
||||
OverlayCategory::Dashboard => {
|
||||
let overlay_button = parser_state
|
||||
.fetch_component_as::<ComponentButton>("btn_dashboard")?;
|
||||
|
||||
if meta.visible {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: alterables,
|
||||
state: &layout.state,
|
||||
};
|
||||
overlay_button.set_sticky_state(&mut com, true);
|
||||
}
|
||||
self.overlay_buttons.insert(meta.id, overlay_button);
|
||||
continue;
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
if root.is_null() {
|
||||
continue;
|
||||
}
|
||||
|
||||
params.insert("idx".into(), i.to_string().into());
|
||||
params.insert("name".into(), meta.name.as_ref().into());
|
||||
parser_state.instantiate_template(
|
||||
&doc_params,
|
||||
template,
|
||||
layout,
|
||||
root,
|
||||
params,
|
||||
)?;
|
||||
let overlay_button = parser_state
|
||||
.fetch_component_as::<ComponentButton>(&format!("overlay_{i}"))?;
|
||||
if meta.visible {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: alterables,
|
||||
state: &layout.state,
|
||||
};
|
||||
overlay_button.set_sticky_state(&mut com, true);
|
||||
}
|
||||
self.overlay_buttons.insert(meta.id, overlay_button);
|
||||
}
|
||||
elements_changed = true;
|
||||
}
|
||||
OverlayEventData::VisibleOverlaysChanged(overlays) => {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: alterables,
|
||||
state: &layout.state,
|
||||
};
|
||||
let mut overlay_buttons = self.overlay_buttons.clone();
|
||||
|
||||
for visible in overlays.as_ref() {
|
||||
if let Some(btn) = overlay_buttons.remove(*visible) {
|
||||
btn.set_sticky_state(&mut com, true);
|
||||
}
|
||||
}
|
||||
|
||||
for btn in overlay_buttons.values() {
|
||||
btn.set_sticky_state(&mut com, false);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(elements_changed)
|
||||
}
|
||||
}
|
||||
76
wlx-overlay-s/src/gui/panel/set_list.rs
Normal file
76
wlx-overlay-s/src/gui/panel/set_list.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use std::{collections::HashMap, rc::Rc};
|
||||
|
||||
use wgui::{
|
||||
components::button::ComponentButton,
|
||||
event::{CallbackDataCommon, EventAlterables},
|
||||
layout::Layout,
|
||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||
};
|
||||
|
||||
use crate::windowing::backend::OverlayEventData;
|
||||
|
||||
#[derive(Default)]
|
||||
/// Populates `id="sets_root"` by instantiating the `<Set>` template.
|
||||
/// Passes `idx`, `display` parameters.
|
||||
pub struct SetList {
|
||||
set_buttons: Vec<Rc<ComponentButton>>,
|
||||
current_set: Option<usize>,
|
||||
}
|
||||
|
||||
impl SetList {
|
||||
pub fn on_notify(
|
||||
&mut self,
|
||||
layout: &mut Layout,
|
||||
parser_state: &mut ParserState,
|
||||
event_data: &OverlayEventData,
|
||||
alterables: &mut EventAlterables,
|
||||
doc_params: &ParseDocumentParams,
|
||||
) -> anyhow::Result<bool> {
|
||||
let mut elements_changed = false;
|
||||
match event_data {
|
||||
OverlayEventData::ActiveSetChanged(current_set) => {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: alterables,
|
||||
state: &layout.state,
|
||||
};
|
||||
if let Some(old_set) = self.current_set.take()
|
||||
&& let Some(old_set) = self.set_buttons.get_mut(old_set)
|
||||
{
|
||||
old_set.set_sticky_state(&mut com, false);
|
||||
}
|
||||
if let Some(new_set) = current_set
|
||||
&& let Some(new_set) = self.set_buttons.get_mut(*new_set)
|
||||
{
|
||||
new_set.set_sticky_state(&mut com, true);
|
||||
}
|
||||
self.current_set = *current_set;
|
||||
}
|
||||
OverlayEventData::NumSetsChanged(num_sets) => {
|
||||
let sets_root = parser_state.get_widget_id("sets_root")?;
|
||||
layout.remove_children(sets_root);
|
||||
self.set_buttons.clear();
|
||||
|
||||
for i in 0..*num_sets {
|
||||
let mut params = HashMap::new();
|
||||
params.insert("idx".into(), i.to_string().into());
|
||||
params.insert("display".into(), (i + 1).to_string().into());
|
||||
parser_state
|
||||
.instantiate_template(doc_params, "Set", layout, sets_root, params)?;
|
||||
let set_button =
|
||||
parser_state.fetch_component_as::<ComponentButton>(&format!("set_{i}"))?;
|
||||
if self.current_set == Some(i) {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: alterables,
|
||||
state: &layout.state,
|
||||
};
|
||||
set_button.set_sticky_state(&mut com, true);
|
||||
}
|
||||
self.set_buttons.push(set_button);
|
||||
}
|
||||
elements_changed = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(elements_changed)
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,14 @@ use crate::{
|
||||
},
|
||||
state::AppState,
|
||||
subsystem::hid::XkbKeymap,
|
||||
windowing::{backend::OverlayEventData, window::OverlayCategory},
|
||||
};
|
||||
use anyhow::Context;
|
||||
use glam::{FloatExt, Mat4, Vec2, vec2, vec3};
|
||||
use wgui::{
|
||||
animation::{Animation, AnimationEasing},
|
||||
assets::AssetPath,
|
||||
components::button::ComponentButton,
|
||||
drawing::{self, Color},
|
||||
event::{self, CallbackDataCommon, CallbackMetadata, EventAlterables, EventListenerKind},
|
||||
event::{self, CallbackMetadata, EventAlterables, EventListenerKind},
|
||||
layout::LayoutUpdateParams,
|
||||
parser::{Fetchable, ParseDocumentParams},
|
||||
renderer_vk::util,
|
||||
@@ -263,158 +261,25 @@ pub(super) fn create_keyboard_panel(
|
||||
panel.on_notify = Some(Box::new(move |panel, app, event_data| {
|
||||
let mut alterables = EventAlterables::default();
|
||||
|
||||
match event_data {
|
||||
OverlayEventData::ActiveSetChanged(current_set) => {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: &mut alterables,
|
||||
state: &panel.layout.state,
|
||||
};
|
||||
if let Some(old_set) = panel.state.current_set.take()
|
||||
&& let Some(old_set) = panel.state.set_buttons.get_mut(old_set)
|
||||
{
|
||||
old_set.set_sticky_state(&mut com, false);
|
||||
}
|
||||
if let Some(new_set) = current_set
|
||||
&& let Some(new_set) = panel.state.set_buttons.get_mut(new_set)
|
||||
{
|
||||
new_set.set_sticky_state(&mut com, true);
|
||||
}
|
||||
panel.state.current_set = current_set;
|
||||
}
|
||||
OverlayEventData::NumSetsChanged(num_sets) => {
|
||||
let sets_root = panel.parser_state.get_widget_id("sets_root")?;
|
||||
panel.layout.remove_children(sets_root);
|
||||
panel.state.set_buttons.clear();
|
||||
|
||||
for i in 0..num_sets {
|
||||
let mut params = HashMap::new();
|
||||
params.insert("idx".into(), i.to_string().into());
|
||||
params.insert("display".into(), (i + 1).to_string().into());
|
||||
panel.parser_state.instantiate_template(
|
||||
&doc_params,
|
||||
"Set",
|
||||
let mut elems_changed = panel.state.overlay_list.on_notify(
|
||||
&mut panel.layout,
|
||||
sets_root,
|
||||
params,
|
||||
)?;
|
||||
let set_button = panel
|
||||
.parser_state
|
||||
.fetch_component_as::<ComponentButton>(&format!("set_{i}"))?;
|
||||
if panel.state.current_set == Some(i) {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: &mut alterables,
|
||||
state: &panel.layout.state,
|
||||
};
|
||||
set_button.set_sticky_state(&mut com, true);
|
||||
}
|
||||
panel.state.set_buttons.push(set_button);
|
||||
}
|
||||
panel.process_custom_elems(app);
|
||||
}
|
||||
OverlayEventData::OverlaysChanged(metas) => {
|
||||
let panels_root = panel.parser_state.get_widget_id("panels_root")?;
|
||||
let apps_root = panel.parser_state.get_widget_id("apps_root")?;
|
||||
panel.layout.remove_children(panels_root);
|
||||
panel.layout.remove_children(apps_root);
|
||||
panel.state.overlay_buttons.clear();
|
||||
|
||||
for (i, meta) in metas.iter().enumerate() {
|
||||
let mut params = HashMap::new();
|
||||
|
||||
let (template, root) = match meta.category {
|
||||
OverlayCategory::Screen => {
|
||||
params.insert(
|
||||
"display".into(),
|
||||
format!(
|
||||
"{}{}",
|
||||
(*meta.name).chars().next().unwrap_or_default(),
|
||||
(*meta.name).chars().last().unwrap_or_default()
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
("Screen", panels_root)
|
||||
}
|
||||
OverlayCategory::Mirror => {
|
||||
params.insert(
|
||||
"display".into(),
|
||||
(*meta.name).chars().last().unwrap().to_string().into(),
|
||||
);
|
||||
("Mirror", panels_root)
|
||||
}
|
||||
OverlayCategory::Panel => ("Panel", panels_root),
|
||||
OverlayCategory::WayVR => {
|
||||
params.insert(
|
||||
"icon".into(),
|
||||
meta.icon
|
||||
.as_ref()
|
||||
.expect("WayVR overlay without Icon attribute!")
|
||||
.as_ref()
|
||||
.into(),
|
||||
);
|
||||
("App", apps_root)
|
||||
}
|
||||
OverlayCategory::Dashboard => {
|
||||
let overlay_button = panel
|
||||
.parser_state
|
||||
.fetch_component_as::<ComponentButton>("btn_dashboard")?;
|
||||
|
||||
log::error!("Found dashboard at: {:?}", meta.id);
|
||||
|
||||
if meta.visible {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: &mut alterables,
|
||||
state: &panel.layout.state,
|
||||
};
|
||||
overlay_button.set_sticky_state(&mut com, true);
|
||||
}
|
||||
panel.state.overlay_buttons.insert(meta.id, overlay_button);
|
||||
continue;
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
params.insert("idx".into(), i.to_string().into());
|
||||
params.insert("name".into(), meta.name.as_ref().into());
|
||||
panel.parser_state.instantiate_template(
|
||||
&mut panel.parser_state,
|
||||
&event_data,
|
||||
&mut alterables,
|
||||
&doc_params,
|
||||
template,
|
||||
&mut panel.layout,
|
||||
root,
|
||||
params,
|
||||
)?;
|
||||
let overlay_button = panel
|
||||
.parser_state
|
||||
.fetch_component_as::<ComponentButton>(&format!("overlay_{i}"))?;
|
||||
if meta.visible {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: &mut alterables,
|
||||
state: &panel.layout.state,
|
||||
};
|
||||
overlay_button.set_sticky_state(&mut com, true);
|
||||
}
|
||||
panel.state.overlay_buttons.insert(meta.id, overlay_button);
|
||||
}
|
||||
|
||||
elems_changed |= panel.state.set_list.on_notify(
|
||||
&mut panel.layout,
|
||||
&mut panel.parser_state,
|
||||
&event_data,
|
||||
&mut alterables,
|
||||
&doc_params,
|
||||
)?;
|
||||
|
||||
if elems_changed {
|
||||
panel.process_custom_elems(app);
|
||||
}
|
||||
OverlayEventData::VisibleOverlaysChanged(overlays) => {
|
||||
let mut com = CallbackDataCommon {
|
||||
alterables: &mut alterables,
|
||||
state: &panel.layout.state,
|
||||
};
|
||||
let mut overlay_buttons = panel.state.overlay_buttons.clone();
|
||||
|
||||
for visible in &*overlays {
|
||||
if let Some(btn) = overlay_buttons.remove(*visible) {
|
||||
btn.set_sticky_state(&mut com, true);
|
||||
}
|
||||
}
|
||||
|
||||
for btn in overlay_buttons.values() {
|
||||
btn.set_sticky_state(&mut com, false);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
panel.layout.process_alterables(alterables)?;
|
||||
Ok(())
|
||||
|
||||
@@ -2,14 +2,13 @@ use std::{
|
||||
cell::Cell,
|
||||
collections::HashMap,
|
||||
process::{Child, Command},
|
||||
rc::Rc,
|
||||
sync::atomic::Ordering,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
KEYMAP_CHANGE,
|
||||
backend::input::{HoverResult, PointerHit},
|
||||
gui::panel::GuiPanel,
|
||||
gui::panel::{GuiPanel, overlay_list::OverlayList, set_list::SetList},
|
||||
overlays::keyboard::{builder::create_keyboard_panel, layout::AltModifier},
|
||||
state::AppState,
|
||||
subsystem::{
|
||||
@@ -20,19 +19,15 @@ use crate::{
|
||||
},
|
||||
},
|
||||
windowing::{
|
||||
OverlayID,
|
||||
backend::{
|
||||
FrameMeta, OverlayBackend, OverlayEventData, OverlayMeta, RenderResources, ShouldRender,
|
||||
},
|
||||
backend::{FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender},
|
||||
window::{OverlayCategory, OverlayWindowConfig},
|
||||
},
|
||||
};
|
||||
use anyhow::Context;
|
||||
use glam::{Affine3A, Quat, Vec3, vec3};
|
||||
use regex::Regex;
|
||||
use slotmap::{SecondaryMap, SlotMap, new_key_type};
|
||||
use slotmap::{SlotMap, new_key_type};
|
||||
use wgui::{
|
||||
components::button::ComponentButton,
|
||||
drawing,
|
||||
event::{InternalStateChangeEvent, MouseButton, MouseButtonIndex},
|
||||
};
|
||||
@@ -59,10 +54,8 @@ pub fn create_keyboard(app: &mut AppState, wayland: bool) -> anyhow::Result<Over
|
||||
_ => 0,
|
||||
},
|
||||
processes: vec![],
|
||||
set_buttons: vec![],
|
||||
overlay_buttons: SecondaryMap::new(),
|
||||
overlay_metas: SecondaryMap::new(),
|
||||
current_set: None,
|
||||
overlay_list: OverlayList::default(),
|
||||
set_list: SetList::default(),
|
||||
};
|
||||
|
||||
let auto_labels = layout.auto_labels.unwrap_or(true);
|
||||
@@ -318,10 +311,16 @@ struct KeyboardState {
|
||||
modifiers: KeyModifier,
|
||||
alt_modifier: KeyModifier,
|
||||
processes: Vec<Child>,
|
||||
set_buttons: Vec<Rc<ComponentButton>>,
|
||||
overlay_buttons: SecondaryMap<OverlayID, Rc<ComponentButton>>,
|
||||
overlay_metas: SecondaryMap<OverlayID, OverlayMeta>,
|
||||
current_set: Option<usize>,
|
||||
overlay_list: OverlayList,
|
||||
set_list: SetList,
|
||||
}
|
||||
|
||||
macro_rules! take_and_leave_default {
|
||||
($what:expr) => {{
|
||||
let mut x = Default::default();
|
||||
std::mem::swap(&mut x, $what);
|
||||
x
|
||||
}};
|
||||
}
|
||||
|
||||
impl KeyboardState {
|
||||
@@ -329,27 +328,9 @@ impl KeyboardState {
|
||||
Self {
|
||||
modifiers: self.modifiers,
|
||||
alt_modifier: self.alt_modifier,
|
||||
processes: {
|
||||
let mut processes = vec![];
|
||||
std::mem::swap(&mut processes, &mut self.processes);
|
||||
processes
|
||||
},
|
||||
set_buttons: {
|
||||
let mut set_buttons = vec![];
|
||||
std::mem::swap(&mut set_buttons, &mut self.set_buttons);
|
||||
set_buttons
|
||||
},
|
||||
overlay_buttons: {
|
||||
let mut overlay_buttons = SecondaryMap::new();
|
||||
std::mem::swap(&mut overlay_buttons, &mut self.overlay_buttons);
|
||||
overlay_buttons
|
||||
},
|
||||
overlay_metas: {
|
||||
let mut overlay_metas = SecondaryMap::new();
|
||||
std::mem::swap(&mut overlay_metas, &mut self.overlay_metas);
|
||||
overlay_metas
|
||||
},
|
||||
current_set: self.current_set.take(),
|
||||
processes: take_and_leave_default!(&mut self.processes),
|
||||
overlay_list: take_and_leave_default!(&mut self.overlay_list),
|
||||
set_list: take_and_leave_default!(&mut self.set_list),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user