add universal _long_release and variants

This commit is contained in:
galister
2025-12-22 17:47:46 +09:00
parent a0bc4001c0
commit b90b7336e0
13 changed files with 223 additions and 104 deletions

View File

@@ -47,21 +47,9 @@ mod sprite_tab;
mod stereo;
pub mod tab;
pub(super) struct LongPressButtonState {
pub(super) pressed: Instant,
}
impl Default for LongPressButtonState {
fn default() -> Self {
Self {
pressed: Instant::now(),
}
}
}
struct EditModeState {
tasks: Rc<RefCell<TaskContainer>>,
id: Rc<RefCell<OverlayID>>,
delete: LongPressButtonState,
tabs: ButtonPaneTabSwitcher,
lock: InteractLockHandler,
pos: SpriteTabHandler<PosTabState>,
@@ -272,9 +260,6 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
let state = EditModeState {
id: Rc::new(RefCell::new(OverlayID::null())),
tasks: Rc::new(RefCell::new(TaskContainer::new())),
delete: LongPressButtonState {
pressed: Instant::now(),
},
tabs: ButtonPaneTabSwitcher::default(),
lock: InteractLockHandler::default(),
pos: SpriteTabHandler::default(),
@@ -284,8 +269,14 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
let anim_mult = app.wgui_globals.defaults().animation_mult;
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, attribs, _app| {
for (name, kind, test_btn) in &BUTTON_EVENTS {
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| {
let Ok(button) =
parser.fetch_component_from_widget_id_as::<ComponentButton>(attribs.widget_id)
else {
return;
};
for (name, kind, test_button, test_duration) in &BUTTON_EVENTS {
let Some(action) = attribs.get_value(name) else {
continue;
};
@@ -295,9 +286,11 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
continue;
};
let button = button.clone();
let callback: EventCallback<AppState, EditModeState> = match command {
"::EditModeToggleLock" => Box::new(move |common, data, app, state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -308,7 +301,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
Ok(EventResult::Consumed)
}),
"::EditModeToggleGrab" => Box::new(move |_common, data, app, state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -324,8 +317,8 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
}),
"::EditModeTab" => {
let tab_name = args.next().unwrap().to_owned();
Box::new(move |common, data, _app, state| {
if !test_btn(data) {
Box::new(move |common, data, app, state| {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -336,7 +329,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
"::EditModeSetPos" => {
let key = args.next().unwrap().to_owned();
Box::new(move |common, data, app, state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -350,7 +343,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
"::EditModeSetStereo" => {
let key = args.next().unwrap().to_owned();
Box::new(move |common, data, app, state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -364,7 +357,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
"::EditModeSetMouse" => {
let key = args.next().unwrap().to_owned();
Box::new(move |common, data, app, state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -375,23 +368,11 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
Ok(EventResult::Consumed)
})
}
"::EditModeDeletePress" => Box::new(move |_common, data, _app, state| {
if !test_btn(data) {
"::EditModeDelete" => Box::new(move |_common, data, app, state| {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
state.delete.pressed = Instant::now();
// TODO: animate to light up button after 2s
Ok(EventResult::Consumed)
}),
"::EditModeDeleteRelease" => Box::new(move |_common, data, app, state| {
if !test_btn(data) {
return Ok(EventResult::Pass);
}
if state.delete.pressed.elapsed() < Duration::from_secs(1) {
return Ok(EventResult::Pass);
}
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Id(*state.id.borrow()),
Box::new(move |_app, owc| {

View File

@@ -1,8 +1,4 @@
use std::{
collections::HashMap,
rc::Rc,
time::{Duration, Instant},
};
use std::{collections::HashMap, rc::Rc, time::Duration};
use glam::{Affine3A, Quat, Vec3, Vec3A, vec3};
use idmap::DirectIdMap;
@@ -31,7 +27,6 @@ use crate::{
panel::{GuiPanel, NewGuiPanelParams, OnCustomAttribFunc, button::BUTTON_EVENTS},
timer::GuiTimer,
},
overlays::edit::LongPressButtonState,
state::AppState,
windowing::{
OverlayID, OverlaySelector, Z_ORDER_WATCH,
@@ -70,7 +65,6 @@ struct WatchState {
keyboard_oid: OverlayID,
dashboard_oid: OverlayID,
num_sets: usize,
delete: LongPressButtonState,
}
#[allow(clippy::significant_drop_tightening)]
@@ -78,8 +72,14 @@ struct WatchState {
pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
let state = WatchState::default();
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, attribs, _app| {
for (name, kind, test_btn) in &BUTTON_EVENTS {
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| {
let Ok(button) =
parser.fetch_component_from_widget_id_as::<ComponentButton>(attribs.widget_id)
else {
return;
};
for (name, kind, test_button, test_duration) in &BUTTON_EVENTS {
let Some(action) = attribs.get_value(name) else {
continue;
};
@@ -89,29 +89,20 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
continue;
};
let button = button.clone();
let callback: EventCallback<AppState, WatchState> = match command {
"::EditModeDeleteDown" => Box::new(move |_common, data, _app, state| {
if !test_btn(data) {
"::EditModeDeleteSet" => Box::new(move |_common, data, app, _state| {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
state.delete.pressed = Instant::now();
Ok(EventResult::Consumed)
}),
"::EditModeDeleteUp" => Box::new(move |_common, data, app, state| {
if !test_btn(data) {
return Ok(EventResult::Pass);
}
if state.delete.pressed.elapsed() < Duration::from_secs(1) {
return Ok(EventResult::Consumed);
}
app.tasks
.enqueue(TaskType::Overlay(OverlayTask::DeleteActiveSet));
Ok(EventResult::Consumed)
}),
"::EditModeAddSet" => Box::new(move |_common, data, app, _state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -125,7 +116,7 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
return;
};
Box::new(move |_common, data, app, state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -154,7 +145,7 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
return;
};
Box::new(move |_common, data, app, state| {
if !test_btn(data) {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
@@ -170,6 +161,29 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
Ok(EventResult::Consumed)
})
}
"::SingleSetOverlayReset" => {
let arg = args.next().unwrap_or_default();
let Ok(idx) = arg.parse::<usize>() else {
log::error!("{command} has invalid argument: \"{arg}\"");
return;
};
Box::new(move |_common, data, app, state| {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
let Some(overlay) = state.overlay_metas.get(idx) else {
log::error!("No overlay at index {idx}.");
return Ok(EventResult::Consumed);
};
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Id(overlay.id),
Box::new(|app, owc| owc.activate(app)),
)));
Ok(EventResult::Consumed)
})
}
_ => return,
};