From 3aee4d68a331036e204a60db4d494becada55178 Mon Sep 17 00:00:00 2001 From: Aleksander Date: Wed, 12 Nov 2025 19:57:38 +0100 Subject: [PATCH] edit: dynamic gui scale --- wlx-overlay-s/src/gui/panel/mod.rs | 56 +++++++++++++++---- wlx-overlay-s/src/overlays/anchor.rs | 4 +- wlx-overlay-s/src/overlays/bar.rs | 2 +- wlx-overlay-s/src/overlays/custom.rs | 4 +- wlx-overlay-s/src/overlays/edit.rs | 42 ++++++++++++-- .../src/overlays/keyboard/builder.rs | 2 +- wlx-overlay-s/src/overlays/toast.rs | 6 +- wlx-overlay-s/src/overlays/watch.rs | 40 +++++++------ 8 files changed, 112 insertions(+), 44 deletions(-) diff --git a/wlx-overlay-s/src/gui/panel/mod.rs b/wlx-overlay-s/src/gui/panel/mod.rs index a6f0c8a..bdf0d43 100644 --- a/wlx-overlay-s/src/gui/panel/mod.rs +++ b/wlx-overlay-s/src/gui/panel/mod.rs @@ -1,7 +1,7 @@ use std::{cell::RefCell, rc::Rc}; use button::setup_custom_button; -use glam::{vec2, Affine2, Vec2}; +use glam::{Affine2, Vec2, vec2}; use label::setup_custom_label; use wgui::{ assets::AssetPath, @@ -15,14 +15,14 @@ use wgui::{ layout::{Layout, LayoutParams, WidgetID}, parser::ParserState, renderer_vk::context::Context as WguiContext, - widget::{label::WidgetLabel, rectangle::WidgetRectangle, EventResult}, + widget::{EventResult, label::WidgetLabel, rectangle::WidgetRectangle}, }; use crate::{ backend::input::{Haptics, HoverResult, PointerHit, PointerMode}, state::AppState, subsystem::hid::WheelDelta, - windowing::backend::{ui_transform, FrameMeta, OverlayBackend, RenderResources, ShouldRender}, + windowing::backend::{FrameMeta, OverlayBackend, RenderResources, ShouldRender, ui_transform}, }; use super::{timer::GuiTimer, timestep::Timestep}; @@ -41,6 +41,7 @@ pub struct GuiPanel { pub timers: Vec, pub parser_state: ParserState, pub max_size: Vec2, + pub gui_scale: f32, interaction_transform: Option, context: WguiContext, timestep: Timestep, @@ -56,13 +57,28 @@ pub type OnCustomIdFunc = Box< ) -> anyhow::Result<()>, >; +pub struct NewGuiPanelParams { + pub on_custom_id: Option, // used only in `new_from_template` + pub resize_to_parent: bool, + pub gui_scale: f32, +} + +impl Default for NewGuiPanelParams { + fn default() -> Self { + Self { + on_custom_id: None, + resize_to_parent: false, + gui_scale: 1.0, + } + } +} + impl GuiPanel { pub fn new_from_template( app: &mut AppState, path: &str, state: S, - on_custom_id: Option, - resize_to_parent: bool, + params: NewGuiPanelParams, ) -> anyhow::Result { let custom_elems = Rc::new(RefCell::new(vec![])); @@ -80,10 +96,14 @@ impl GuiPanel { }, }; - let (mut layout, mut parser_state) = - wgui::parser::new_layout_from_assets(&doc_params, &LayoutParams { resize_to_parent })?; + let (mut layout, mut parser_state) = wgui::parser::new_layout_from_assets( + &doc_params, + &LayoutParams { + resize_to_parent: params.resize_to_parent, + }, + )?; - if let Some(on_element_id) = on_custom_id { + if let Some(on_element_id) = params.on_custom_id { let ids = parser_state.data.ids.clone(); // FIXME: copying all ids? for (id, widget) in ids { @@ -128,11 +148,21 @@ impl GuiPanel { max_size: vec2(DEFAULT_MAX_SIZE as _, DEFAULT_MAX_SIZE as _), timers: vec![], interaction_transform: None, + gui_scale: params.gui_scale, }) } - pub fn new_blank(app: &mut AppState, state: S, resize_to_parent: bool) -> anyhow::Result { - let layout = Layout::new(app.wgui_globals.clone(), &LayoutParams { resize_to_parent })?; + pub fn new_blank( + app: &mut AppState, + state: S, + params: NewGuiPanelParams, + ) -> anyhow::Result { + let layout = Layout::new( + app.wgui_globals.clone(), + &LayoutParams { + resize_to_parent: params.resize_to_parent, + }, + )?; let context = WguiContext::new(&mut app.wgui_shared, 1.0)?; let mut timestep = Timestep::new(); timestep.set_tps(60.0); @@ -146,6 +176,7 @@ impl GuiPanel { max_size: vec2(DEFAULT_MAX_SIZE as _, DEFAULT_MAX_SIZE as _), timers: vec![], interaction_transform: None, + gui_scale: params.gui_scale, }) } @@ -222,8 +253,9 @@ impl OverlayBackend for GuiPanel { fn render(&mut self, app: &mut AppState, rdr: &mut RenderResources) -> anyhow::Result<()> { self.context - .update_viewport(&mut app.wgui_shared, rdr.extent, 1.0)?; - self.layout.update(self.max_size, self.timestep.alpha)?; + .update_viewport(&mut app.wgui_shared, rdr.extent, self.gui_scale)?; + self.layout + .update(self.max_size / self.gui_scale, self.timestep.alpha)?; let globals = self.layout.state.globals.clone(); // sorry let mut globals = globals.get(); diff --git a/wlx-overlay-s/src/overlays/anchor.rs b/wlx-overlay-s/src/overlays/anchor.rs index 90d0f98..9f8bc09 100644 --- a/wlx-overlay-s/src/overlays/anchor.rs +++ b/wlx-overlay-s/src/overlays/anchor.rs @@ -3,13 +3,13 @@ use std::sync::{Arc, LazyLock}; use crate::gui::panel::GuiPanel; use crate::state::AppState; -use crate::windowing::window::{OverlayWindowConfig, OverlayWindowState, Positioning}; use crate::windowing::Z_ORDER_ANCHOR; +use crate::windowing::window::{OverlayWindowConfig, OverlayWindowState, Positioning}; pub static ANCHOR_NAME: LazyLock> = LazyLock::new(|| Arc::from("anchor")); pub fn create_anchor(app: &mut AppState) -> anyhow::Result { - let mut panel = GuiPanel::new_from_template(app, "gui/anchor.xml", (), None, false)?; + let mut panel = GuiPanel::new_from_template(app, "gui/anchor.xml", (), Default::default())?; panel.update_layout()?; Ok(OverlayWindowConfig { diff --git a/wlx-overlay-s/src/overlays/bar.rs b/wlx-overlay-s/src/overlays/bar.rs index fa61351..986dabf 100644 --- a/wlx-overlay-s/src/overlays/bar.rs +++ b/wlx-overlay-s/src/overlays/bar.rs @@ -15,7 +15,7 @@ struct BarState {} #[allow(clippy::match_same_arms)] // TODO: remove later pub fn create_bar(app: &mut AppState) -> anyhow::Result { let state = BarState {}; - let mut panel = GuiPanel::new_from_template(app, "gui/bar.xml", state, None, false)?; + let mut panel = GuiPanel::new_from_template(app, "gui/bar.xml", state, Default::default())?; for (id, _widget_id) in &panel.parser_state.data.ids { match id.as_ref() { diff --git a/wlx-overlay-s/src/overlays/custom.rs b/wlx-overlay-s/src/overlays/custom.rs index 79bc183..a8cdf58 100644 --- a/wlx-overlay-s/src/overlays/custom.rs +++ b/wlx-overlay-s/src/overlays/custom.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use glam::{vec3, Affine3A, Quat, Vec3}; +use glam::{Affine3A, Quat, Vec3, vec3}; use crate::{ gui::panel::GuiPanel, @@ -18,7 +18,7 @@ pub fn create_custom(app: &mut AppState, name: Arc) -> Option anyhow::Result { - let panel = GuiPanel::new_from_template(app, "gui/edit.xml", "".into(), None, true)?; +fn make_edit_panel( + app: &mut AppState, + overlay_resolution: UVec2, +) -> anyhow::Result { + log::error!( + "overlay res {} {}", + overlay_resolution.x, + overlay_resolution.y + ); + + let panel = GuiPanel::new_from_template( + app, + "gui/edit.xml", + "".into(), + NewGuiPanelParams { + resize_to_parent: true, + ..Default::default() + }, + )?; Ok(panel) } diff --git a/wlx-overlay-s/src/overlays/keyboard/builder.rs b/wlx-overlay-s/src/overlays/keyboard/builder.rs index b599cc8..0e3bdbc 100644 --- a/wlx-overlay-s/src/overlays/keyboard/builder.rs +++ b/wlx-overlay-s/src/overlays/keyboard/builder.rs @@ -53,7 +53,7 @@ pub fn create_keyboard( processes: vec![], }; - let mut panel = GuiPanel::new_blank(app, state, false)?; + let mut panel = GuiPanel::new_blank(app, state, Default::default())?; let globals = app.wgui_globals.clone(); let accent_color = globals.get().defaults.accent_color; diff --git a/wlx-overlay-s/src/overlays/toast.rs b/wlx-overlay-s/src/overlays/toast.rs index 36bb962..048d081 100644 --- a/wlx-overlay-s/src/overlays/toast.rs +++ b/wlx-overlay-s/src/overlays/toast.rs @@ -5,7 +5,7 @@ use std::{ time::Instant, }; -use glam::{vec3, Affine3A, Quat, Vec3}; +use glam::{Affine3A, Quat, Vec3, vec3}; use idmap_derive::IntegerId; use serde::{Deserialize, Serialize}; use wgui::{ @@ -28,8 +28,8 @@ use crate::{ gui::panel::GuiPanel, state::{AppState, LeftRight}, windowing::{ - window::{OverlayWindowConfig, OverlayWindowState, Positioning}, OverlaySelector, Z_ORDER_TOAST, + window::{OverlayWindowConfig, OverlayWindowState, Positioning}, }, }; @@ -170,7 +170,7 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option { toast.title }; - let mut panel = GuiPanel::new_blank(app, (), false).ok()?; + let mut panel = GuiPanel::new_blank(app, (), Default::default()).ok()?; let globals = panel.layout.state.globals.clone(); diff --git a/wlx-overlay-s/src/overlays/watch.rs b/wlx-overlay-s/src/overlays/watch.rs index 3c4f076..cf95abc 100644 --- a/wlx-overlay-s/src/overlays/watch.rs +++ b/wlx-overlay-s/src/overlays/watch.rs @@ -3,11 +3,14 @@ use std::{collections::HashMap, rc::Rc, time::Duration}; use glam::{Affine3A, Vec3, Vec3A}; use crate::{ - gui::{panel::GuiPanel, timer::GuiTimer}, + gui::{ + panel::{GuiPanel, NewGuiPanelParams}, + timer::GuiTimer, + }, state::AppState, windowing::{ - window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState, Positioning}, Z_ORDER_WATCH, + window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState, Positioning}, }, }; @@ -22,22 +25,25 @@ pub fn create_watch(app: &mut AppState, num_sets: usize) -> anyhow::Result, Rc> = HashMap::new(); - params.insert("display".into(), (idx + 1).to_string().into()); - params.insert("handle".into(), idx.to_string().into()); - parser_state.instantiate_template(doc_params, "Set", layout, widget, params)?; - } - Ok(()) - }, - )), - false, + for idx in 0..num_sets { + let mut params: HashMap, Rc> = HashMap::new(); + params.insert("display".into(), (idx + 1).to_string().into()); + params.insert("handle".into(), idx.to_string().into()); + parser_state + .instantiate_template(doc_params, "Set", layout, widget, params)?; + } + Ok(()) + }, + )), + ..Default::default() + }, )?; panel