#[derive(Clone, Copy)]
struct SizeSync {
last_seen: [u16; 2],
was_resizing: bool,
}
#[derive(Clone, Copy)]
pub(crate) struct Decisions {
pub resizing: bool,
pub push_external: bool,
pub drag_released: bool,
}
pub(crate) fn begin(
ui: &egui::Ui,
sync_id: egui::Id,
resize_id: egui::Id,
size: [u16; 2],
) -> Decisions {
let corner_id = resize_id.with("__resize_corner");
let resizing = ui
.ctx()
.read_response(corner_id)
.is_some_and(|r| r.dragged());
if resizing {
ui.ctx().request_repaint();
}
let prev: Option<SizeSync> = ui.memory_mut(|m| m.data.get_temp(sync_id));
let (push_external, drag_released) = size_sync_frame(prev, size, resizing);
Decisions {
resizing,
push_external,
drag_released,
}
}
pub(crate) fn store(
ui: &egui::Ui,
sync_id: egui::Id,
size: [u16; 2],
push_external: bool,
resizing: bool,
) {
ui.memory_mut(|m| {
m.data.insert_temp(
sync_id,
SizeSync {
last_seen: size,
was_resizing: if push_external { false } else { resizing },
},
)
});
}
fn size_sync_frame(prev: Option<SizeSync>, size: [u16; 2], resizing: bool) -> (bool, bool) {
match prev {
None => (true, false),
Some(prev) => {
let push = prev.last_seen != size;
let released = !push && prev.was_resizing && !resizing;
(push, released)
}
}
}
pub(crate) fn fitted_size(width: f32, height: f32) -> [u16; 2] {
[width.round() as u16, height.round() as u16]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn size_sync_frame_decisions() {
let sync = |last_seen, was_resizing| {
Some(SizeSync {
last_seen,
was_resizing,
})
};
assert_eq!(size_sync_frame(None, [100, 40], false), (true, false));
assert_eq!(
size_sync_frame(sync([100, 40], false), [100, 40], false),
(false, false)
);
assert_eq!(
size_sync_frame(sync([100, 40], true), [120, 40], true),
(true, false)
);
assert_eq!(
size_sync_frame(sync([100, 40], false), [100, 40], true),
(false, false)
);
assert_eq!(
size_sync_frame(sync([100, 40], true), [100, 40], true),
(false, false)
);
assert_eq!(
size_sync_frame(sync([100, 40], true), [100, 40], false),
(false, true)
);
}
#[test]
fn fitted_size_rounds() {
assert_eq!(fitted_size(100.6, 40.4), [101, 40]);
assert_eq!(fitted_size(100.4, 40.5), [100, 41]);
}
}