View affine worlds

This commit is contained in:
2025-02-17 21:19:34 -05:00
parent 3cdc0583a6
commit 802da8f93e
4 changed files with 218 additions and 17 deletions
+20 -6
View File
@@ -9,7 +9,7 @@ use egui::{
Response, RichText, Rounding, Sense, Shape, Stroke, TextEdit, Ui, UiBuilder, Vec2, Widget,
WidgetText,
};
use num_traits::PrimInt;
use num_traits::{CheckedAdd, CheckedSub, One};
pub trait UiExt {
fn section(&mut self, title: impl Into<String>, add_contents: impl FnOnce(&mut Ui));
@@ -97,12 +97,20 @@ enum Direction {
Down,
}
pub trait Number: PrimInt + Display + FromStr + Send + Sync + 'static {}
impl<T: PrimInt + Display + FromStr + Send + Sync + 'static> Number for T {}
pub trait Number:
Copy + One + CheckedAdd + CheckedSub + Eq + Ord + Display + FromStr + Send + Sync + 'static
{
}
impl<
T: Copy + One + CheckedAdd + CheckedSub + Eq + Ord + Display + FromStr + Send + Sync + 'static,
> Number for T
{
}
pub struct NumberEdit<'a, T: Number> {
value: &'a mut T,
increment: T,
precision: usize,
min: Option<T>,
max: Option<T>,
}
@@ -112,11 +120,16 @@ impl<'a, T: Number> NumberEdit<'a, T> {
Self {
value,
increment: T::one(),
precision: 3,
min: None,
max: None,
}
}
pub fn precision(self, precision: usize) -> Self {
Self { precision, ..self }
}
pub fn range(self, range: impl RangeBounds<T>) -> Self {
let min = match range.start_bound() {
Bound::Unbounded => None,
@@ -135,18 +148,19 @@ impl<'a, T: Number> NumberEdit<'a, T> {
impl<T: Number> Widget for NumberEdit<'_, T> {
fn ui(self, ui: &mut Ui) -> Response {
let id = ui.id();
let to_string = |val: &T| format!("{val:.0$}", self.precision);
let (last_value, mut str, focus) = ui.memory(|m| {
let (lv, s) = m
.data
.get_temp(id)
.unwrap_or((*self.value, self.value.to_string()));
.unwrap_or((*self.value, to_string(self.value)));
let focus = m.has_focus(id);
(lv, s, focus)
});
let mut stale = false;
if *self.value != last_value {
str = self.value.to_string();
str = to_string(self.value);
stale = true;
}
let valid = str.parse().is_ok_and(|v: T| v == *self.value);
@@ -236,7 +250,7 @@ impl<T: Number> Widget for NumberEdit<'_, T> {
if let Some(new_value) = value.filter(in_range) {
*self.value = new_value;
}
str = self.value.to_string();
str = to_string(self.value);
stale = true;
} else if res.changed {
if let Some(new_value) = str.parse().ok().filter(in_range) {