listener handles, auto-clean destroyed listeners, minor refactor
This commit is contained in:
@@ -4,11 +4,12 @@ use glam::{Affine2, Vec2, vec2};
|
||||
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
||||
use wgui::{
|
||||
event::{
|
||||
Event as WguiEvent, EventListenerCollection, InternalStateChangeEvent, MouseButton,
|
||||
MouseDownEvent, MouseLeaveEvent, MouseMotionEvent, MouseUpEvent, MouseWheelEvent,
|
||||
Event as WguiEvent, EventListenerCollection, InternalStateChangeEvent, ListenerHandleVec,
|
||||
MouseButton, MouseDownEvent, MouseLeaveEvent, MouseMotionEvent, MouseUpEvent,
|
||||
MouseWheelEvent,
|
||||
},
|
||||
layout::Layout,
|
||||
parser::ParserResult,
|
||||
parser::ParserState,
|
||||
renderer_vk::context::Context as WguiContext,
|
||||
};
|
||||
|
||||
@@ -32,20 +33,18 @@ pub struct GuiPanel<S> {
|
||||
pub state: S,
|
||||
pub timers: Vec<GuiTimer>,
|
||||
pub listeners: EventListenerCollection<AppState, S>,
|
||||
pub listener_handles: ListenerHandleVec,
|
||||
pub parser_state: ParserState,
|
||||
interaction_transform: Option<Affine2>,
|
||||
context: WguiContext,
|
||||
timestep: Timestep,
|
||||
}
|
||||
|
||||
impl<S> GuiPanel<S> {
|
||||
pub fn new_from_template(
|
||||
app: &mut AppState,
|
||||
path: &str,
|
||||
state: S,
|
||||
) -> anyhow::Result<(Self, ParserResult)> {
|
||||
pub fn new_from_template(app: &mut AppState, path: &str, state: S) -> anyhow::Result<Self> {
|
||||
let mut listeners = EventListenerCollection::<AppState, S>::default();
|
||||
|
||||
let (layout, parser_result) = wgui::parser::new_layout_from_assets(
|
||||
let (layout, parser_state) = wgui::parser::new_layout_from_assets(
|
||||
Box::new(gui::asset::GuiAsset {}),
|
||||
&mut listeners,
|
||||
path,
|
||||
@@ -55,18 +54,17 @@ impl<S> GuiPanel<S> {
|
||||
let mut timestep = Timestep::new();
|
||||
timestep.set_tps(60.0);
|
||||
|
||||
Ok((
|
||||
Self {
|
||||
layout,
|
||||
context,
|
||||
timestep,
|
||||
state,
|
||||
timers: vec![],
|
||||
listeners,
|
||||
interaction_transform: None,
|
||||
},
|
||||
parser_result,
|
||||
))
|
||||
Ok(Self {
|
||||
layout,
|
||||
context,
|
||||
timestep,
|
||||
state,
|
||||
listener_handles: ListenerHandleVec::default(),
|
||||
parser_state,
|
||||
timers: vec![],
|
||||
listeners,
|
||||
interaction_transform: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new_blank(app: &mut AppState, state: S) -> anyhow::Result<Self> {
|
||||
@@ -80,6 +78,8 @@ impl<S> GuiPanel<S> {
|
||||
context,
|
||||
timestep,
|
||||
state,
|
||||
parser_state: ParserState::default(),
|
||||
listener_handles: ListenerHandleVec::default(),
|
||||
timers: vec![],
|
||||
listeners: EventListenerCollection::default(),
|
||||
interaction_transform: None,
|
||||
@@ -93,7 +93,7 @@ impl<S> GuiPanel<S> {
|
||||
pub fn push_event(&mut self, app: &mut AppState, event: &WguiEvent) {
|
||||
if let Err(e) = self
|
||||
.layout
|
||||
.push_event(&self.listeners, event, (app, &mut self.state))
|
||||
.push_event(&mut self.listeners, event, (app, &mut self.state))
|
||||
{
|
||||
log::error!("Failed to push event: {e:?}");
|
||||
}
|
||||
@@ -186,7 +186,7 @@ impl<S> OverlayBackend for GuiPanel<S> {
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) {
|
||||
self.layout
|
||||
.push_event(
|
||||
&self.listeners,
|
||||
&mut self.listeners,
|
||||
&WguiEvent::MouseWheel(MouseWheelEvent {
|
||||
shift: vec2(delta_x, delta_y),
|
||||
pos: hit.uv * self.layout.content_size,
|
||||
|
||||
@@ -11,7 +11,7 @@ pub fn create_anchor<O>(app: &mut AppState) -> anyhow::Result<OverlayData<O>>
|
||||
where
|
||||
O: Default,
|
||||
{
|
||||
let (panel, _) = GuiPanel::new_from_template(app, "gui/anchor.xml", ())?;
|
||||
let panel = GuiPanel::new_from_template(app, "gui/anchor.xml", ())?;
|
||||
|
||||
Ok(OverlayData {
|
||||
state: OverlayState {
|
||||
|
||||
@@ -14,9 +14,9 @@ where
|
||||
O: Default,
|
||||
{
|
||||
let state = BarState {};
|
||||
let (mut panel, parser) = GuiPanel::new_from_template(app, "gui/bar.xml", state)?;
|
||||
let mut panel = GuiPanel::new_from_template(app, "gui/bar.xml", state)?;
|
||||
|
||||
for (id, widget_id) in parser.ids {
|
||||
for (id, _widget_id) in &panel.parser_state.ids {
|
||||
match id.as_ref() {
|
||||
"lock" => {}
|
||||
"anchor" => {}
|
||||
|
||||
@@ -186,7 +186,8 @@ where
|
||||
})
|
||||
};
|
||||
|
||||
panel.listeners.add(
|
||||
panel.listeners.register(
|
||||
&mut panel.listener_handles,
|
||||
*widget_id,
|
||||
EventListenerKind::MouseEnter,
|
||||
Box::new({
|
||||
@@ -197,7 +198,8 @@ where
|
||||
}
|
||||
}),
|
||||
);
|
||||
panel.listeners.add(
|
||||
panel.listeners.register(
|
||||
&mut panel.listener_handles,
|
||||
*widget_id,
|
||||
EventListenerKind::MouseLeave,
|
||||
Box::new({
|
||||
@@ -208,7 +210,8 @@ where
|
||||
}
|
||||
}),
|
||||
);
|
||||
panel.listeners.add(
|
||||
panel.listeners.register(
|
||||
&mut panel.listener_handles,
|
||||
*widget_id,
|
||||
EventListenerKind::MousePress,
|
||||
Box::new({
|
||||
@@ -223,7 +226,8 @@ where
|
||||
}
|
||||
}),
|
||||
);
|
||||
panel.listeners.add(
|
||||
panel.listeners.register(
|
||||
&mut panel.listener_handles,
|
||||
*widget_id,
|
||||
EventListenerKind::MouseRelease,
|
||||
Box::new({
|
||||
@@ -237,7 +241,8 @@ where
|
||||
);
|
||||
|
||||
if let Some(modifier) = my_modifier {
|
||||
panel.listeners.add(
|
||||
panel.listeners.register(
|
||||
&mut panel.listener_handles,
|
||||
*widget_id,
|
||||
EventListenerKind::InternalStateChange,
|
||||
Box::new({
|
||||
@@ -259,6 +264,7 @@ where
|
||||
}
|
||||
|
||||
panel.layout.update(vec2(2048., 2048.), 0.0)?;
|
||||
panel.parser_state = gui_state_key;
|
||||
|
||||
let width = layout.row_size * 0.05 * app.session.config.keyboard_scale;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ where
|
||||
O: Default,
|
||||
{
|
||||
let state = WatchState {};
|
||||
let (mut panel, parser) = GuiPanel::new_from_template(app, "gui/watch.xml", state)?;
|
||||
let mut panel = GuiPanel::new_from_template(app, "gui/watch.xml", state)?;
|
||||
|
||||
panel
|
||||
.timers
|
||||
@@ -33,8 +33,8 @@ where
|
||||
|
||||
let clock_regex = Regex::new(r"^clock([0-9])_([a-z]+)$").unwrap();
|
||||
|
||||
for (id, widget_id) in parser.ids {
|
||||
if let Some(cap) = clock_regex.captures(&id) {
|
||||
for (id, widget_id) in &panel.parser_state.ids {
|
||||
if let Some(cap) = clock_regex.captures(id) {
|
||||
let tz_idx: usize = cap.get(1).unwrap().as_str().parse().unwrap(); // safe due to regex
|
||||
let tz_str = (tz_idx > 0)
|
||||
.then(|| app.session.config.timezones.get(tz_idx - 1))
|
||||
@@ -44,7 +44,7 @@ where
|
||||
let mut widget = panel
|
||||
.layout
|
||||
.widget_map
|
||||
.get_mut(widget_id)
|
||||
.get_mut(*widget_id)
|
||||
.unwrap() // want panic
|
||||
.lock()
|
||||
.unwrap(); // want panic
|
||||
@@ -87,8 +87,9 @@ where
|
||||
format: format.into(),
|
||||
};
|
||||
|
||||
panel.listeners.add(
|
||||
widget_id,
|
||||
panel.listeners.register(
|
||||
&mut panel.listener_handles,
|
||||
*widget_id,
|
||||
EventListenerKind::InternalStateChange,
|
||||
Box::new(move |_common, data, _, _| {
|
||||
clock_on_tick(&clock, data);
|
||||
|
||||
Reference in New Issue
Block a user