events with user data to also trigger internal listeners + toast fix

This commit is contained in:
galister
2025-10-29 19:56:33 +09:00
parent bf1d02ed00
commit 01d11e8485
7 changed files with 51 additions and 54 deletions

View File

@@ -219,8 +219,8 @@ new_key_type! {
pub struct EventListener { pub struct EventListener {
kind: EventListenerKind, kind: EventListenerKind,
callback: EventCallbackInternal, callback: EventCallbackInternal,
tid1: TypeId, tid1: Option<TypeId>,
tid2: TypeId, tid2: Option<TypeId>,
} }
impl EventListener { impl EventListener {
@@ -230,7 +230,9 @@ impl EventListener {
data: &mut CallbackData, data: &mut CallbackData,
user_data: &mut (&mut U1, &mut U2), user_data: &mut (&mut U1, &mut U2),
) -> anyhow::Result<EventResult> { ) -> anyhow::Result<EventResult> {
(self.callback)(common, data, user_data.0, user_data.1) let a1: &mut (dyn Any + 'static) = if self.tid1.is_none() { &mut () } else { user_data.0 };
let a2: &mut (dyn Any + 'static) = if self.tid2.is_none() { &mut () } else { user_data.1 };
(self.callback)(common, data, a1, a2)
} }
} }
@@ -250,7 +252,7 @@ impl EventListenerCollection {
self self
.inner .inner
.values() .values()
.filter(move |p| p.tid1 == tid1 && p.tid2 == tid2 && p.kind == kind) .filter(move |p| p.tid1.is_none_or(|a| a == tid1) && p.tid2.is_none_or(|a| a == tid2) && p.kind == kind)
} }
pub fn register<U1: 'static, U2: 'static>( pub fn register<U1: 'static, U2: 'static>(
@@ -258,6 +260,8 @@ impl EventListenerCollection {
kind: EventListenerKind, kind: EventListenerKind,
callback: EventCallback<U1, U2>, callback: EventCallback<U1, U2>,
) -> EventListenerID { ) -> EventListenerID {
let tid_unit = TypeId::of::<()>();
let tid1 = TypeId::of::<U1>(); let tid1 = TypeId::of::<U1>();
let tid2 = TypeId::of::<U2>(); let tid2 = TypeId::of::<U2>();
@@ -274,8 +278,8 @@ impl EventListenerCollection {
let new_item = EventListener { let new_item = EventListener {
kind, kind,
callback: callback_inner, callback: callback_inner,
tid1, tid1: (tid1 != tid_unit).then_some(tid1),
tid2, tid2: (tid2 != tid_unit).then_some(tid2),
}; };
self.inner.insert(new_item) self.inner.insert(new_item)

View File

@@ -26,7 +26,7 @@
</template> </template>
<template name="Set"> <template name="Set">
<Button macro="button_style" _press="::SetToggle ${handle}"> <Button macro="button_style" _press="::SetToggle ${handle}" tooltip="Switch to set" tooltip_side="top">
<sprite width="40" height="40" color="~set_color" src="watch/set2.svg" /> <sprite width="40" height="40" color="~set_color" src="watch/set2.svg" />
<div position="absolute" margin_top="9"> <div position="absolute" margin_top="9">
<label text="${display}" size="24" color="#00050F" weight="bold" /> <label text="${display}" size="24" color="#00050F" weight="bold" />
@@ -64,13 +64,13 @@
</div> </div>
</div> </div>
<div width="100%" flex_direction="row"> <div width="100%" flex_direction="row">
<Button macro="button_style" _press="::DashToggle"> <Button macro="button_style" _press="::DashToggle" tooltip="Toggle dashboard" tooltip_side="top">
<sprite color="~set_color" width="40" height="40" src="watch/home.svg" /> <sprite color="~set_color" width="40" height="40" src="watch/home.svg" />
</Button> </Button>
<div id="sets"> <div id="sets">
<!-- Will populate <Set> tags at runtime --> <!-- Will populate <Set> tags at runtime -->
</div> </div>
<Button macro="button_style" _press="::EditToggle"> <Button macro="button_style" _press="::EditToggle" tooltip="Edit sets" tooltip_side="top">
<sprite color="~set_color" width="40" height="40" src="watch/edit.svg" /> <sprite color="~set_color" width="40" height="40" src="watch/edit.svg" />
</Button> </Button>
</div> </div>

View File

@@ -240,7 +240,9 @@ pub fn openxr_run(
continue 'main_loop; continue 'main_loop;
} }
log::trace!("xrWaitFrame");
let xr_frame_state = frame_wait.wait()?; let xr_frame_state = frame_wait.wait()?;
log::trace!("xrBeginFrame");
frame_stream.begin()?; frame_stream.begin()?;
xr_state.predicted_display_time = xr_frame_state.predicted_display_time; xr_state.predicted_display_time = xr_frame_state.predicted_display_time;
@@ -263,6 +265,7 @@ pub fn openxr_run(
}; };
if !xr_frame_state.should_render { if !xr_frame_state.should_render {
log::trace!("xrEndFrame");
frame_stream.end( frame_stream.end(
xr_frame_state.predicted_display_time, xr_frame_state.predicted_display_time,
environment_blend_mode, environment_blend_mode,
@@ -478,6 +481,7 @@ pub fn openxr_run(
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
log::trace!("xrEndFrame");
frame_stream.end( frame_stream.end(
xr_state.predicted_display_time, xr_state.predicted_display_time,
environment_blend_mode, environment_blend_mode,

View File

@@ -258,27 +258,20 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
} }
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) { fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) {
self.layout let e = WguiEvent::MouseWheel(MouseWheelEvent {
.push_event(
&WguiEvent::MouseWheel(MouseWheelEvent {
shift: vec2(delta_x, delta_y), shift: vec2(delta_x, delta_y),
pos: hit.uv * self.layout.content_size, pos: hit.uv * self.layout.content_size,
device: hit.pointer, device: hit.pointer,
}), });
app, self.push_event(app, &e);
&mut self.state,
)
.unwrap(); // want panic
} }
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics> { fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics> {
self.push_event( let e = &WguiEvent::MouseMotion(MouseMotionEvent {
app,
&WguiEvent::MouseMotion(MouseMotionEvent {
pos: hit.uv * self.layout.content_size, pos: hit.uv * self.layout.content_size,
device: hit.pointer, device: hit.pointer,
}), });
); self.push_event(app, &e);
self.layout self.layout
.check_toggle_haptics_triggered() .check_toggle_haptics_triggered()
@@ -290,10 +283,8 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
} }
fn on_left(&mut self, app: &mut AppState, pointer: usize) { fn on_left(&mut self, app: &mut AppState, pointer: usize) {
self.push_event( let e = WguiEvent::MouseLeave(MouseLeaveEvent { device: pointer });
app, self.push_event(app, &e);
&WguiEvent::MouseLeave(MouseLeaveEvent { device: pointer }),
);
} }
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) { fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) {
@@ -304,25 +295,21 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
_ => return, _ => return,
}; };
if pressed { let e = if pressed {
self.push_event( WguiEvent::MouseDown(MouseDownEvent {
app,
&WguiEvent::MouseDown(MouseDownEvent {
pos: hit.uv * self.layout.content_size, pos: hit.uv * self.layout.content_size,
index, index,
device: hit.pointer, device: hit.pointer,
}), })
);
} else { } else {
self.push_event( WguiEvent::MouseUp(MouseUpEvent {
app,
&WguiEvent::MouseUp(MouseUpEvent {
pos: hit.uv * self.layout.content_size, pos: hit.uv * self.layout.content_size,
index, index,
device: hit.pointer, device: hit.pointer,
}), })
); };
}
self.push_event(app, &e);
} }
fn get_interaction_transform(&mut self) -> Option<Affine2> { fn get_interaction_transform(&mut self) -> Option<Affine2> {

View File

@@ -1,6 +1,7 @@
pub mod anchor; pub mod anchor;
pub mod bar; pub mod bar;
pub mod custom; pub mod custom;
//pub mod edit;
pub mod keyboard; pub mod keyboard;
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
pub mod mirror; pub mod mirror;

View File

@@ -5,7 +5,7 @@ use std::{
time::Instant, time::Instant,
}; };
use glam::{Affine3A, Quat, Vec3, vec3}; use glam::{vec3, Affine3A, Quat, Vec3};
use idmap_derive::IntegerId; use idmap_derive::IntegerId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use wgui::{ use wgui::{
@@ -28,8 +28,8 @@ use crate::{
gui::panel::GuiPanel, gui::panel::GuiPanel,
state::{AppState, LeftRight}, state::{AppState, LeftRight},
windowing::{ windowing::{
OverlaySelector, Z_ORDER_TOAST,
window::{OverlayWindowConfig, OverlayWindowState, Positioning}, window::{OverlayWindowConfig, OverlayWindowState, Positioning},
OverlaySelector, Z_ORDER_TOAST,
}, },
}; };
@@ -249,6 +249,7 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option<OverlayWindowConfig> {
}, },
global: true, global: true,
z_order: Z_ORDER_TOAST, z_order: Z_ORDER_TOAST,
show_on_spawn: true,
..OverlayWindowConfig::from_backend(Box::new(panel)) ..OverlayWindowConfig::from_backend(Box::new(panel))
}) })
} }

View File

@@ -129,14 +129,14 @@ impl OverlayWindowConfig {
} }
pub fn activate(&mut self, app: &mut AppState) { pub fn activate(&mut self, app: &mut AppState) {
log::warn!("activate {}", self.name.as_ref()); log::debug!("activate {}", self.name.as_ref());
self.dirty = true; self.dirty = true;
self.active_state = Some(self.default_state.clone()); self.active_state = Some(self.default_state.clone());
self.reset(app, true); self.reset(app, true);
} }
pub fn deactivate(&mut self) { pub fn deactivate(&mut self) {
log::warn!("deactivate {}", self.name.as_ref()); log::debug!("deactivate {}", self.name.as_ref());
self.active_state = None; self.active_state = None;
} }
@@ -144,7 +144,7 @@ impl OverlayWindowConfig {
if self.active_state.take().is_none() { if self.active_state.take().is_none() {
self.activate(app); self.activate(app);
} else { } else {
log::warn!("deactivate {}", self.name.as_ref()); log::debug!("deactivate {}", self.name.as_ref());
} }
} }