Interface on the pixel grid: a virtual screen of whole multiples of the world's rows, sharp-scaled to every device; compact title menu on short screens
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa39e66da9
commit
e7fc0a4751
5 files changed
+142
-66
No files matched your search
+14
-9
@@ -7,6 +7,11 @@ use macroquad::prelude::*;
|
||||
|
||||
const LONG_PRESS: f64 = 0.5; // seconds without moving
|
||||
const DOUBLE_TAP: f64 = 0.3; // max. time between two taps
|
||||
// touches come in device pixels; everything here works in interface units (see ui::dpr)
|
||||
fn ui_pos(p: Vec2) -> Vec2 {
|
||||
p * crate::ui::dpr() / crate::ui::device_dpr()
|
||||
}
|
||||
|
||||
const DRAG_CSS: f32 = 10.0; // movement (CSS pixels) that turns a press into a drag
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -92,13 +97,13 @@ impl TouchInput {
|
||||
if active.len() >= 2 {
|
||||
self.start_two(active[0], active[1]);
|
||||
} else if let Some(t) = active.first() {
|
||||
out.push(Gesture::Press(t.position));
|
||||
self.st = St::One { id: t.id, start: t.position, pos: t.position, t0: now, drag: false, long: false };
|
||||
out.push(Gesture::Press(ui_pos(t.position)));
|
||||
self.st = St::One { id: t.id, start: ui_pos(t.position), pos: ui_pos(t.position), t0: now, drag: false, long: false };
|
||||
} else if let Some(t) = ts.iter().find(|t| ended(t.phase)) {
|
||||
// started and ended between two frames
|
||||
out.push(Gesture::Press(t.position));
|
||||
self.tap(t.position, now, want_double, &mut out);
|
||||
out.push(Gesture::Release(t.position));
|
||||
out.push(Gesture::Press(ui_pos(t.position)));
|
||||
self.tap(ui_pos(t.position), now, want_double, &mut out);
|
||||
out.push(Gesture::Release(ui_pos(t.position)));
|
||||
}
|
||||
}
|
||||
St::One { id, start, t0, mut drag, mut long, .. } => {
|
||||
@@ -108,7 +113,7 @@ impl TouchInput {
|
||||
} else {
|
||||
match find(id) {
|
||||
Some(t) if !ended(t.phase) => {
|
||||
let pos = t.position;
|
||||
let pos = ui_pos(t.position);
|
||||
if !drag && pos.distance(start) > drag_px {
|
||||
drag = true;
|
||||
out.push(Gesture::DragStart(start));
|
||||
@@ -122,7 +127,7 @@ impl TouchInput {
|
||||
self.st = St::One { id, start, pos, t0, drag, long };
|
||||
}
|
||||
other => {
|
||||
let pos = other.map(|t| t.position).unwrap_or(start);
|
||||
let pos = other.map(|t| ui_pos(t.position)).unwrap_or(start);
|
||||
if drag {
|
||||
out.push(Gesture::DragEnd);
|
||||
} else if !long {
|
||||
@@ -136,7 +141,7 @@ impl TouchInput {
|
||||
}
|
||||
St::Two { a, b, center, dist, angle } => match (find(a).filter(|t| !ended(t.phase)), find(b).filter(|t| !ended(t.phase))) {
|
||||
(Some(ta), Some(tb)) => {
|
||||
let (c, d, an) = Self::geometry(ta.position, tb.position);
|
||||
let (c, d, an) = Self::geometry(ui_pos(ta.position), ui_pos(tb.position));
|
||||
let mut rot = an - angle;
|
||||
if rot > std::f32::consts::PI {
|
||||
rot -= std::f32::consts::TAU;
|
||||
@@ -169,7 +174,7 @@ impl TouchInput {
|
||||
}
|
||||
|
||||
fn start_two(&mut self, a: &Touch, b: &Touch) {
|
||||
let (center, dist, angle) = Self::geometry(a.position, b.position);
|
||||
let (center, dist, angle) = Self::geometry(ui_pos(a.position), ui_pos(b.position));
|
||||
self.pending_tap = None;
|
||||
self.st = St::Two { a: a.id, b: b.id, center, dist, angle };
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user