wayvr/wlx-overlay-s/src/overlays/edit/lock.rs

112 lines
3.4 KiB
Rust

use glam::FloatExt;
use wgui::{
animation::{Animation, AnimationEasing},
event::CallbackDataCommon,
layout::WidgetID,
parser::Fetchable,
widget::rectangle::WidgetRectangle,
};
use crate::{backend::task::OverlayTask, overlays::edit::EditModeWrapPanel, state::AppState};
#[derive(Default)]
pub(super) struct InteractLockHandler {
id: WidgetID,
color: wgui::drawing::Color,
interactable: bool,
}
impl InteractLockHandler {
pub fn new(panel: &mut EditModeWrapPanel) -> anyhow::Result<Self> {
let id = panel.parser_state.get_widget_id("shadow")?;
let shadow_rect = panel
.layout
.state
.widgets
.get_as::<WidgetRectangle>(id)
.ok_or_else(|| anyhow::anyhow!("Element with id=\"shadow\" must be a <rectangle>"))?;
Ok(Self {
id,
color: shadow_rect.params.color,
interactable: true,
})
}
pub fn reset(&mut self, common: &mut CallbackDataCommon, interactable: bool) {
self.interactable = interactable;
let mut rect = common
.state
.widgets
.get_as::<WidgetRectangle>(self.id)
.unwrap(); // can only fail if set_up_rect has issues
let globals = common.state.globals.get();
if interactable {
set_anim_color(&mut rect, 0.0, self.color, globals.defaults.danger_color);
} else {
set_anim_color(&mut rect, 0.2, self.color, globals.defaults.danger_color);
}
}
pub fn toggle(
&mut self,
common: &mut CallbackDataCommon,
app: &mut AppState,
) -> Box<OverlayTask> {
let defaults = app.wgui_globals.get().defaults.clone();
let rect_color = self.color;
self.interactable = !self.interactable;
let anim = if self.interactable {
Animation::new(
self.id,
10,
AnimationEasing::OutQuad,
Box::new(move |common, data| {
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
set_anim_color(
rect,
0.2 - (data.pos * 0.2),
rect_color,
defaults.danger_color,
);
common.alterables.mark_redraw();
}),
)
} else {
Animation::new(
self.id,
10,
AnimationEasing::OutBack,
Box::new(move |common, data| {
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
set_anim_color(rect, data.pos * 0.2, rect_color, defaults.danger_color);
common.alterables.mark_redraw();
}),
)
};
common.alterables.animate(anim);
let interactable = self.interactable;
Box::new(move |_app, owc| {
let state = owc.active_state.as_mut().unwrap(); //want panic
state.interactable = interactable;
})
}
}
fn set_anim_color(
rect: &mut WidgetRectangle,
pos: f32,
rect_color: wgui::drawing::Color,
target_color: wgui::drawing::Color,
) {
// rect to target_color
rect.params.color.r = rect_color.r.lerp(target_color.r, pos);
rect.params.color.g = rect_color.g.lerp(target_color.g, pos);
rect.params.color.b = rect_color.b.lerp(target_color.b, pos);
}