custom panel icons

This commit is contained in:
galister
2026-01-10 04:10:39 +09:00
parent e5f0131730
commit 6cf4c1fe8f
5 changed files with 52 additions and 11 deletions

View File

@@ -141,7 +141,7 @@
<template name="Panel">
<Button macro="button_style" id="overlay_${idx}" tooltip_str="${name}" _context_name="${name}" _press="::ContextMenuOpen menu_panel">
<sprite width="38" height="38" color="~color_text" src_builtin="edit/panel.svg" />
<sprite width="38" height="38" color="~color_text" src="${icon}" />
</Button>
</template>

View File

@@ -1,8 +1,9 @@
use std::{cell::RefCell, rc::Rc};
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use anyhow::Context;
use button::setup_custom_button;
use glam::{Affine2, Vec2, vec2};
use idmap::IdMap;
use label::setup_custom_label;
use wgui::{
assets::AssetPath,
@@ -67,6 +68,7 @@ pub struct GuiPanel<S> {
pub on_notify: Option<OnNotifyFunc<S>>,
pub initialized: bool,
pub doc_extra: Option<ParseDocumentExtra>,
pub extra_attribs: IdMap<BackendAttrib, BackendAttribValue>,
interaction_transform: Option<Affine2>,
context: WguiContext,
timestep: Timestep,
@@ -182,6 +184,7 @@ impl<S: 'static> GuiPanel<S> {
last_content_size: Vec2::ZERO,
doc_extra: Some(doc_params.extra),
custom_elems,
extra_attribs: Default::default(),
context_menu: Default::default(),
on_custom_attrib: params.on_custom_attrib,
on_custom_attrib_inner,
@@ -443,8 +446,8 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
fn get_interaction_transform(&mut self) -> Option<Affine2> {
self.interaction_transform
}
fn get_attrib(&self, _attrib: BackendAttrib) -> Option<BackendAttribValue> {
None
fn get_attrib(&self, attrib: BackendAttrib) -> Option<BackendAttribValue> {
self.extra_attribs.get(&attrib).cloned()
}
fn set_attrib(&mut self, _app: &mut AppState, _value: BackendAttribValue) -> bool {
false

View File

@@ -14,7 +14,7 @@ use crate::windowing::{OverlayID, backend::OverlayEventData, window::OverlayCate
/// 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)
/// Uses the following parameters: `name` (All), `display` (Screen, Mirror), `icon` (App, Panel)
pub struct OverlayList {
overlay_buttons: SecondaryMap<OverlayID, Rc<ComponentButton>>,
}
@@ -63,7 +63,16 @@ impl OverlayList {
);
("Mirror", panels_root)
}
OverlayCategory::Panel => ("Panel", panels_root),
OverlayCategory::Panel => {
let icon: Rc<str> = if let Some(icon) = meta.icon.as_ref() {
icon.to_string().into()
} else {
"edit/panel.svg".into()
};
params.insert("icon".into(), icon);
("Panel", panels_root)
}
OverlayCategory::WayVR => {
params.insert(
"icon".into(),

View File

@@ -1,7 +1,14 @@
use std::{sync::Arc, time::Duration};
use std::{
sync::{Arc, LazyLock},
time::Duration,
};
use glam::{Affine3A, Quat, Vec3, vec3};
use wlx_common::windowing::OverlayWindowState;
use regex::Regex;
use wlx_common::{
overlays::{BackendAttrib, BackendAttribValue},
windowing::OverlayWindowState,
};
use crate::{
gui::{
@@ -15,7 +22,22 @@ use crate::{
},
};
struct CustomPanelState {}
static ENV_VAR_REGEX: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"\$\{([A-Z_][A-Z0-9_]*)}|\$([A-Z_][A-Z0-9_]*)").unwrap() // want panic
});
pub(super) fn expand_env_vars(template: &str) -> String {
ENV_VAR_REGEX
.replace_all(template, |caps: &regex::Captures| {
let var_name = caps.get(1).or_else(|| caps.get(2)).unwrap().as_str();
std::env::var(var_name)
.inspect_err(|e| log::warn!("Unable to substitute env var {var_name}: {e:?}"))
.unwrap_or_default()
})
.into_owned()
}
struct CustomPanelState;
pub fn create_custom(app: &mut AppState, name: Arc<str>) -> Option<OverlayWindowConfig> {
let params = NewGuiPanelParams {
@@ -24,10 +46,17 @@ pub fn create_custom(app: &mut AppState, name: Arc<str>) -> Option<OverlayWindow
};
let mut panel =
GuiPanel::new_from_template(app, &format!("gui/{name}.xml"), CustomPanelState {}, params)
GuiPanel::new_from_template(app, &format!("gui/{name}.xml"), CustomPanelState, params)
.inspect_err(|e| log::warn!("Error creating '{name}': {e:?}"))
.ok()?;
if let Some(icon) = panel.parser_state.data.var_map.get("_panel_icon") {
let icon = expand_env_vars(&icon);
panel
.extra_attribs
.insert(BackendAttrib::Icon, BackendAttribValue::Icon(icon.into()));
}
panel
.update_layout(app)
.inspect_err(|e| log::warn!("Error layouting '{name}': {e:?}"))

View File

@@ -19,7 +19,7 @@ pub enum ToastDisplayMethod {
Watch,
}
#[derive(Clone, Copy)]
#[derive(Debug, Clone, Copy, IntegerId, PartialEq)]
pub enum BackendAttrib {
Stereo,
MouseTransform,