watch: highlight current set
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{self, Component, ComponentBase, ComponentTrait, RefreshData, tooltip::ComponentTooltip},
|
components::{self, tooltip::ComponentTooltip, Component, ComponentBase, ComponentTrait, RefreshData},
|
||||||
drawing::{self, Boundary, Color},
|
drawing::{self, Boundary, Color},
|
||||||
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
@@ -10,15 +10,15 @@ use crate::{
|
|||||||
util::centered_matrix,
|
util::centered_matrix,
|
||||||
},
|
},
|
||||||
widget::{
|
widget::{
|
||||||
ConstructEssentials, EventResult, WidgetData,
|
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
|
ConstructEssentials, EventResult, WidgetData,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use glam::{Mat4, Vec3};
|
use glam::{Mat4, Vec3};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
use taffy::{AlignItems, JustifyContent, prelude::length};
|
use taffy::{prelude::length, AlignItems, JustifyContent};
|
||||||
|
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
pub text: Option<Translation>, // if unset, label will not be populated
|
pub text: Option<Translation>, // if unset, label will not be populated
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="Set">
|
<template name="Set">
|
||||||
<Button macro="button_style" _press="::SetToggle ${handle}" tooltip="Switch to set" tooltip_side="top">
|
<Button macro="button_style" id="set_${handle}" _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" />
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::f32::consts::PI;
|
|||||||
use std::process::{Child, Command};
|
use std::process::{Child, Command};
|
||||||
use std::{collections::VecDeque, time::Instant};
|
use std::{collections::VecDeque, time::Instant};
|
||||||
|
|
||||||
use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
|
use glam::{Affine3A, Vec2, Vec3A, Vec3Swizzles};
|
||||||
|
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ use crate::windowing::manager::OverlayWindowManager;
|
|||||||
use crate::windowing::window::{realign, OverlayWindowData, OverlayWindowState, Positioning};
|
use crate::windowing::window::{realign, OverlayWindowData, OverlayWindowState, Positioning};
|
||||||
use crate::windowing::{OverlayID, OverlaySelector};
|
use crate::windowing::{OverlayID, OverlaySelector};
|
||||||
|
|
||||||
use super::task::{TaskContainer, TaskType};
|
use super::task::TaskType;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct HoverResult {
|
pub struct HoverResult {
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ use wgui::gfx::WGfx;
|
|||||||
use crate::backend::input::{HoverResult, PointerHit};
|
use crate::backend::input::{HoverResult, PointerHit};
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
use crate::subsystem::hid::WheelDelta;
|
use crate::subsystem::hid::WheelDelta;
|
||||||
use crate::windowing::backend::{FrameMeta, OverlayBackend, RenderResources, ShouldRender};
|
use crate::windowing::backend::{
|
||||||
|
FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
|
||||||
|
};
|
||||||
use crate::windowing::window::{OverlayWindowConfig, OverlayWindowData};
|
use crate::windowing::window::{OverlayWindowConfig, OverlayWindowData};
|
||||||
use crate::windowing::Z_ORDER_LINES;
|
use crate::windowing::Z_ORDER_LINES;
|
||||||
|
|
||||||
@@ -198,6 +200,10 @@ impl OverlayBackend for LineBackend {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn notify(&mut self, _: &mut AppState, _: OverlayEventData) -> anyhow::Result<()> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
fn on_hover(&mut self, _: &mut AppState, _: &PointerHit) -> HoverResult {
|
fn on_hover(&mut self, _: &mut AppState, _: &PointerHit) -> HoverResult {
|
||||||
HoverResult::default()
|
HoverResult::default()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ use crate::{
|
|||||||
backend::input::{Haptics, HoverResult, PointerHit, PointerMode},
|
backend::input::{Haptics, HoverResult, PointerHit, PointerMode},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::WheelDelta,
|
subsystem::hid::WheelDelta,
|
||||||
windowing::backend::{ui_transform, FrameMeta, OverlayBackend, RenderResources, ShouldRender},
|
windowing::backend::{
|
||||||
|
ui_transform, FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{timer::GuiTimer, timestep::Timestep};
|
use super::{timer::GuiTimer, timestep::Timestep};
|
||||||
@@ -35,6 +37,9 @@ const DEFAULT_MAX_SIZE: f32 = 2048.0;
|
|||||||
|
|
||||||
const COLOR_ERR: drawing::Color = drawing::Color::new(1., 0., 1., 1.);
|
const COLOR_ERR: drawing::Color = drawing::Color::new(1., 0., 1., 1.);
|
||||||
|
|
||||||
|
pub type OnNotifyFunc<S> =
|
||||||
|
Box<dyn Fn(&mut GuiPanel<S>, &mut AppState, OverlayEventData) -> anyhow::Result<()>>;
|
||||||
|
|
||||||
pub struct GuiPanel<S> {
|
pub struct GuiPanel<S> {
|
||||||
pub layout: Layout,
|
pub layout: Layout,
|
||||||
pub state: S,
|
pub state: S,
|
||||||
@@ -42,31 +47,33 @@ pub struct GuiPanel<S> {
|
|||||||
pub parser_state: ParserState,
|
pub parser_state: ParserState,
|
||||||
pub max_size: Vec2,
|
pub max_size: Vec2,
|
||||||
pub gui_scale: f32,
|
pub gui_scale: f32,
|
||||||
|
pub on_notify: Option<OnNotifyFunc<S>>,
|
||||||
interaction_transform: Option<Affine2>,
|
interaction_transform: Option<Affine2>,
|
||||||
context: WguiContext,
|
context: WguiContext,
|
||||||
timestep: Timestep,
|
timestep: Timestep,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type OnCustomIdFunc = Box<
|
pub type OnCustomIdFunc<S> = Box<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
Rc<str>,
|
Rc<str>,
|
||||||
WidgetID,
|
WidgetID,
|
||||||
&wgui::parser::ParseDocumentParams,
|
&wgui::parser::ParseDocumentParams,
|
||||||
&mut Layout,
|
&mut Layout,
|
||||||
&mut ParserState,
|
&mut ParserState,
|
||||||
|
&mut S,
|
||||||
) -> anyhow::Result<()>,
|
) -> anyhow::Result<()>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub type OnCustomAttribFunc = Box<dyn Fn(&mut Layout, &CustomAttribsInfoOwned, &AppState)>;
|
pub type OnCustomAttribFunc = Box<dyn Fn(&mut Layout, &CustomAttribsInfoOwned, &AppState)>;
|
||||||
|
|
||||||
pub struct NewGuiPanelParams {
|
pub struct NewGuiPanelParams<S> {
|
||||||
pub on_custom_id: Option<OnCustomIdFunc>, // used only in `new_from_template`
|
pub on_custom_id: Option<OnCustomIdFunc<S>>, // used only in `new_from_template`
|
||||||
pub on_custom_attrib: Option<OnCustomAttribFunc>, // used only in `new_from_template`
|
pub on_custom_attrib: Option<OnCustomAttribFunc>, // used only in `new_from_template`
|
||||||
pub resize_to_parent: bool,
|
pub resize_to_parent: bool,
|
||||||
pub gui_scale: f32,
|
pub gui_scale: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for NewGuiPanelParams {
|
impl<S> Default for NewGuiPanelParams<S> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
on_custom_id: None,
|
on_custom_id: None,
|
||||||
@@ -81,8 +88,8 @@ impl<S: 'static> GuiPanel<S> {
|
|||||||
pub fn new_from_template(
|
pub fn new_from_template(
|
||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
path: &str,
|
path: &str,
|
||||||
state: S,
|
mut state: S,
|
||||||
params: NewGuiPanelParams,
|
params: NewGuiPanelParams<S>,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let custom_elems = Rc::new(RefCell::new(vec![]));
|
let custom_elems = Rc::new(RefCell::new(vec![]));
|
||||||
|
|
||||||
@@ -117,6 +124,7 @@ impl<S: 'static> GuiPanel<S> {
|
|||||||
&doc_params,
|
&doc_params,
|
||||||
&mut layout,
|
&mut layout,
|
||||||
&mut parser_state,
|
&mut parser_state,
|
||||||
|
&mut state,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,6 +164,7 @@ impl<S: 'static> GuiPanel<S> {
|
|||||||
max_size: vec2(DEFAULT_MAX_SIZE as _, DEFAULT_MAX_SIZE as _),
|
max_size: vec2(DEFAULT_MAX_SIZE as _, DEFAULT_MAX_SIZE as _),
|
||||||
timers: vec![],
|
timers: vec![],
|
||||||
interaction_transform: None,
|
interaction_transform: None,
|
||||||
|
on_notify: None,
|
||||||
gui_scale: params.gui_scale,
|
gui_scale: params.gui_scale,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -163,7 +172,7 @@ impl<S: 'static> GuiPanel<S> {
|
|||||||
pub fn new_blank(
|
pub fn new_blank(
|
||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
state: S,
|
state: S,
|
||||||
params: NewGuiPanelParams,
|
params: NewGuiPanelParams<S>,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let layout = Layout::new(
|
let layout = Layout::new(
|
||||||
app.wgui_globals.clone(),
|
app.wgui_globals.clone(),
|
||||||
@@ -183,6 +192,7 @@ impl<S: 'static> GuiPanel<S> {
|
|||||||
parser_state: ParserState::default(),
|
parser_state: ParserState::default(),
|
||||||
max_size: vec2(DEFAULT_MAX_SIZE as _, DEFAULT_MAX_SIZE as _),
|
max_size: vec2(DEFAULT_MAX_SIZE as _, DEFAULT_MAX_SIZE as _),
|
||||||
timers: vec![],
|
timers: vec![],
|
||||||
|
on_notify: None,
|
||||||
interaction_transform: None,
|
interaction_transform: None,
|
||||||
gui_scale: params.gui_scale,
|
gui_scale: params.gui_scale,
|
||||||
})
|
})
|
||||||
@@ -295,6 +305,15 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn notify(&mut self, app: &mut AppState, data: OverlayEventData) -> anyhow::Result<()> {
|
||||||
|
let Some(on_notify) = self.on_notify.take() else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
on_notify(self, app, data)?;
|
||||||
|
self.on_notify = Some(on_notify);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) {
|
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) {
|
||||||
let e = WguiEvent::MouseWheel(MouseWheelEvent {
|
let e = WguiEvent::MouseWheel(MouseWheelEvent {
|
||||||
delta: vec2(delta.x, delta.y),
|
delta: vec2(delta.x, delta.y),
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use crate::{
|
|||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::WheelDelta,
|
subsystem::hid::WheelDelta,
|
||||||
windowing::{
|
windowing::{
|
||||||
backend::{DummyBackend, OverlayBackend, RenderResources, ShouldRender},
|
backend::{DummyBackend, OverlayBackend, OverlayEventData, RenderResources, ShouldRender},
|
||||||
window::OverlayWindowConfig,
|
window::OverlayWindowConfig,
|
||||||
OverlayID,
|
OverlayID,
|
||||||
},
|
},
|
||||||
@@ -204,6 +204,9 @@ impl OverlayBackend for EditModeBackendWrapper {
|
|||||||
) {
|
) {
|
||||||
self.panel.on_scroll(app, hit, delta);
|
self.panel.on_scroll(app, hit, delta);
|
||||||
}
|
}
|
||||||
|
fn notify(&mut self, app: &mut AppState, event_data: OverlayEventData) -> anyhow::Result<()> {
|
||||||
|
self.panel.notify(app, event_data)
|
||||||
|
}
|
||||||
fn get_interaction_transform(&mut self) -> Option<glam::Affine2> {
|
fn get_interaction_transform(&mut self) -> Option<glam::Affine2> {
|
||||||
self.inner.get_interaction_transform()
|
self.inner.get_interaction_transform()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ use crate::{
|
|||||||
backend::input::{HoverResult, PointerHit},
|
backend::input::{HoverResult, PointerHit},
|
||||||
gui::panel::GuiPanel,
|
gui::panel::GuiPanel,
|
||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::{ALT, CTRL, KeyModifier, META, SHIFT, SUPER, VirtualKey, WheelDelta},
|
subsystem::hid::{KeyModifier, VirtualKey, WheelDelta, ALT, CTRL, META, SHIFT, SUPER},
|
||||||
windowing::backend::{FrameMeta, OverlayBackend, RenderResources, ShouldRender},
|
windowing::backend::{
|
||||||
|
FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
@@ -53,6 +55,10 @@ impl OverlayBackend for KeyboardBackend {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn notify(&mut self, app: &mut AppState, event_data: OverlayEventData) -> anyhow::Result<()> {
|
||||||
|
self.panel.notify(app, event_data)
|
||||||
|
}
|
||||||
|
|
||||||
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) {
|
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) {
|
||||||
self.panel.on_pointer(app, hit, pressed);
|
self.panel.on_pointer(app, hit, pressed);
|
||||||
self.panel.push_event(
|
self.panel.push_event(
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ use crate::{
|
|||||||
state::{AppSession, AppState},
|
state::{AppSession, AppState},
|
||||||
subsystem::hid::WheelDelta,
|
subsystem::hid::WheelDelta,
|
||||||
windowing::{
|
windowing::{
|
||||||
backend::{ui_transform, FrameMeta, OverlayBackend, RenderResources, ShouldRender},
|
backend::{
|
||||||
|
ui_transform, FrameMeta, OverlayBackend, OverlayEventData, RenderResources,
|
||||||
|
ShouldRender,
|
||||||
|
},
|
||||||
window::{OverlayWindowConfig, OverlayWindowState},
|
window::{OverlayWindowConfig, OverlayWindowState},
|
||||||
OverlaySelector,
|
OverlaySelector,
|
||||||
},
|
},
|
||||||
@@ -124,6 +127,13 @@ impl OverlayBackend for MirrorBackend {
|
|||||||
self.renderer.as_mut().and_then(ScreenBackend::frame_meta)
|
self.renderer.as_mut().and_then(ScreenBackend::frame_meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn notify(&mut self, app: &mut AppState, event_data: OverlayEventData) -> anyhow::Result<()> {
|
||||||
|
let Some(renderer) = self.renderer.as_mut() else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
renderer.notify(app, event_data)
|
||||||
|
}
|
||||||
|
|
||||||
fn on_hover(&mut self, _: &mut AppState, _: &PointerHit) -> HoverResult {
|
fn on_hover(&mut self, _: &mut AppState, _: &PointerHit) -> HoverResult {
|
||||||
HoverResult {
|
HoverResult {
|
||||||
consume: true,
|
consume: true,
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ use crate::{
|
|||||||
graphics::ExtentExt,
|
graphics::ExtentExt,
|
||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::{WheelDelta, MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
|
subsystem::hid::{WheelDelta, MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
|
||||||
windowing::backend::{FrameMeta, OverlayBackend, RenderResources, ShouldRender},
|
windowing::backend::{
|
||||||
|
FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::capture::{receive_callback, ScreenPipeline, WlxCaptureIn, WlxCaptureOut};
|
use super::capture::{receive_callback, ScreenPipeline, WlxCaptureIn, WlxCaptureOut};
|
||||||
@@ -199,6 +201,10 @@ impl OverlayBackend for ScreenBackend {
|
|||||||
self.meta
|
self.meta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn notify(&mut self, _app: &mut AppState, _event_data: OverlayEventData) -> anyhow::Result<()> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult {
|
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
log::trace!("Hover: {:?}", hit.uv);
|
log::trace!("Hover: {:?}", hit.uv);
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
use std::{collections::HashMap, rc::Rc, time::Duration};
|
use std::{collections::HashMap, rc::Rc, time::Duration};
|
||||||
|
|
||||||
use glam::{Affine3A, Vec3, Vec3A};
|
use glam::{Affine3A, Vec3, Vec3A};
|
||||||
|
use wgui::{
|
||||||
|
components::button::ComponentButton,
|
||||||
|
event::{CallbackDataCommon, EventAlterables},
|
||||||
|
parser::Fetchable,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gui::{
|
gui::{
|
||||||
@@ -9,6 +14,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
windowing::{
|
windowing::{
|
||||||
|
backend::OverlayEventData,
|
||||||
window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState, Positioning},
|
window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState, Positioning},
|
||||||
Z_ORDER_WATCH,
|
Z_ORDER_WATCH,
|
||||||
},
|
},
|
||||||
@@ -16,18 +22,22 @@ use crate::{
|
|||||||
|
|
||||||
pub const WATCH_NAME: &str = "watch";
|
pub const WATCH_NAME: &str = "watch";
|
||||||
|
|
||||||
struct WatchState {}
|
#[derive(Default)]
|
||||||
|
struct WatchState {
|
||||||
|
current_set: Option<usize>,
|
||||||
|
set_buttons: Vec<Rc<ComponentButton>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::significant_drop_tightening)]
|
#[allow(clippy::significant_drop_tightening)]
|
||||||
pub fn create_watch(app: &mut AppState, num_sets: usize) -> anyhow::Result<OverlayWindowConfig> {
|
pub fn create_watch(app: &mut AppState, num_sets: usize) -> anyhow::Result<OverlayWindowConfig> {
|
||||||
let state = WatchState {};
|
let state = WatchState::default();
|
||||||
let mut panel = GuiPanel::new_from_template(
|
let mut panel = GuiPanel::new_from_template(
|
||||||
app,
|
app,
|
||||||
"gui/watch.xml",
|
"gui/watch.xml",
|
||||||
state,
|
state,
|
||||||
NewGuiPanelParams {
|
NewGuiPanelParams {
|
||||||
on_custom_id: Some(Box::new(
|
on_custom_id: Some(Box::new(
|
||||||
move |id, widget, doc_params, layout, parser_state| {
|
move |id, widget, doc_params, layout, parser_state, state| {
|
||||||
if &*id != "sets" {
|
if &*id != "sets" {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -38,6 +48,11 @@ pub fn create_watch(app: &mut AppState, num_sets: usize) -> anyhow::Result<Overl
|
|||||||
params.insert("handle".into(), idx.to_string().into());
|
params.insert("handle".into(), idx.to_string().into());
|
||||||
parser_state
|
parser_state
|
||||||
.instantiate_template(doc_params, "Set", layout, widget, params)?;
|
.instantiate_template(doc_params, "Set", layout, widget, params)?;
|
||||||
|
|
||||||
|
let button_id = format!("set_{idx}");
|
||||||
|
let component =
|
||||||
|
parser_state.fetch_component_as::<ComponentButton>(&button_id)?;
|
||||||
|
state.set_buttons.push(component);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
@@ -46,6 +61,27 @@ pub fn create_watch(app: &mut AppState, num_sets: usize) -> anyhow::Result<Overl
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
panel.on_notify = Some(Box::new(|panel, _app, event_data| {
|
||||||
|
match event_data {
|
||||||
|
OverlayEventData::SetChanged(current_set) => {
|
||||||
|
let mut alterables = EventAlterables::default();
|
||||||
|
let mut common = CallbackDataCommon {
|
||||||
|
alterables: &mut alterables,
|
||||||
|
state: &panel.layout.state,
|
||||||
|
};
|
||||||
|
if let Some(old_set) = panel.state.current_set.take() {
|
||||||
|
panel.state.set_buttons[old_set].set_sticky_state(&mut common, false);
|
||||||
|
}
|
||||||
|
if let Some(new_set) = current_set {
|
||||||
|
panel.state.set_buttons[new_set].set_sticky_state(&mut common, true);
|
||||||
|
}
|
||||||
|
panel.state.current_set = current_set;
|
||||||
|
panel.layout.process_alterables(alterables)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}));
|
||||||
|
|
||||||
panel
|
panel
|
||||||
.timers
|
.timers
|
||||||
.push(GuiTimer::new(Duration::from_millis(100), 0));
|
.push(GuiTimer::new(Duration::from_millis(100), 0));
|
||||||
|
|||||||
@@ -30,7 +30,10 @@ use crate::{
|
|||||||
state::{self, AppState},
|
state::{self, AppState},
|
||||||
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
||||||
windowing::{
|
windowing::{
|
||||||
backend::{ui_transform, FrameMeta, OverlayBackend, RenderResources, ShouldRender},
|
backend::{
|
||||||
|
ui_transform, FrameMeta, OverlayBackend, OverlayEventData, RenderResources,
|
||||||
|
ShouldRender,
|
||||||
|
},
|
||||||
manager::OverlayWindowManager,
|
manager::OverlayWindowManager,
|
||||||
window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState},
|
window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState},
|
||||||
OverlayID, OverlaySelector, Z_ORDER_DASHBOARD,
|
OverlayID, OverlaySelector, Z_ORDER_DASHBOARD,
|
||||||
@@ -703,6 +706,14 @@ impl OverlayBackend for WayVRBackend {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn notify(
|
||||||
|
&mut self,
|
||||||
|
_app: &mut state::AppState,
|
||||||
|
_event_data: OverlayEventData,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn on_hover(&mut self, _app: &mut state::AppState, hit: &input::PointerHit) -> HoverResult {
|
fn on_hover(&mut self, _app: &mut state::AppState, hit: &input::PointerHit) -> HoverResult {
|
||||||
let ctx = self.context.borrow();
|
let ctx = self.context.borrow();
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ impl RenderResources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum OverlayEventData {
|
||||||
|
SetChanged(Option<usize>),
|
||||||
|
}
|
||||||
|
|
||||||
pub trait OverlayBackend: Any {
|
pub trait OverlayBackend: Any {
|
||||||
/// Called once, before the first frame is rendered
|
/// Called once, before the first frame is rendered
|
||||||
fn init(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
fn init(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
||||||
@@ -82,6 +86,8 @@ pub trait OverlayBackend: Any {
|
|||||||
/// Must be Some if should_render was Should or Can on the same frame.
|
/// Must be Some if should_render was Should or Can on the same frame.
|
||||||
fn frame_meta(&mut self) -> Option<FrameMeta>;
|
fn frame_meta(&mut self) -> Option<FrameMeta>;
|
||||||
|
|
||||||
|
fn notify(&mut self, app: &mut AppState, event_data: OverlayEventData) -> anyhow::Result<()>;
|
||||||
|
|
||||||
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult;
|
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult;
|
||||||
fn on_left(&mut self, app: &mut AppState, pointer: usize);
|
fn on_left(&mut self, app: &mut AppState, pointer: usize);
|
||||||
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool);
|
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool);
|
||||||
@@ -125,6 +131,10 @@ impl OverlayBackend for DummyBackend {
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn notify(&mut self, _: &mut AppState, _event_data: OverlayEventData) -> anyhow::Result<()> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
fn on_hover(&mut self, _: &mut AppState, _: &PointerHit) -> HoverResult {
|
fn on_hover(&mut self, _: &mut AppState, _: &PointerHit) -> HoverResult {
|
||||||
HoverResult::default()
|
HoverResult::default()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
windowing::{
|
windowing::{
|
||||||
|
backend::OverlayEventData,
|
||||||
set::{OverlayWindowSet, SerializedWindowSet},
|
set::{OverlayWindowSet, SerializedWindowSet},
|
||||||
snap_upright,
|
snap_upright,
|
||||||
window::OverlayWindowData,
|
window::OverlayWindowData,
|
||||||
@@ -320,6 +321,14 @@ impl<T> OverlayWindowManager<T> {
|
|||||||
self.restore_set = new_set;
|
self.restore_set = new_set;
|
||||||
}
|
}
|
||||||
self.current_set = new_set;
|
self.current_set = new_set;
|
||||||
|
|
||||||
|
if let Some(watch) = self.mut_by_id(self.watch_id) {
|
||||||
|
watch
|
||||||
|
.config
|
||||||
|
.backend
|
||||||
|
.notify(app, OverlayEventData::SetChanged(new_set))
|
||||||
|
.unwrap(); // TODO: handle this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_hide(&mut self, app: &mut AppState) {
|
pub fn show_hide(&mut self, app: &mut AppState) {
|
||||||
|
|||||||
Reference in New Issue
Block a user