feat(render): logical style metrics with a UI scale, so chrome has a consistent physical size
This commit is contained in:
1 parent
1f03631e98
commit
7500fc90d2
21 files changed
+708
-82
No files matched your search
@@ -358,3 +358,75 @@ PLOT_TEST(key_f_auto_fits_traces) {
|
||||
PLOT_CHECK(p.x_axis(ax).auto_scale); // a fit re-arms auto scale
|
||||
PLOT_CHECK(p.y_axis(ay).auto_scale);
|
||||
}
|
||||
|
||||
// --- tolerances are logical, coordinates are device pixels -------------------
|
||||
|
||||
/// The grab radius is a distance the user aims with, so it must be the same
|
||||
/// *physical* distance at any DPI: the controller compares device-pixel coordinates
|
||||
/// against `logical * Plot::ui_scale()`. The press positions below are the same
|
||||
/// logical distance (0.9 and 1.1 of the 5 px radius) from the cursor at both scales,
|
||||
/// so the same press grabs -- and the same press just outside does not.
|
||||
PLOT_TEST(grab_radius_scales_with_dpi) {
|
||||
for (const f32 scale : {1.0f, 2.0f}) {
|
||||
plot::Plot p;
|
||||
p.set_ui_scale(scale);
|
||||
p.set_viewport({0, 0, 800.0f * scale, 400.0f * scale});
|
||||
const u32 ax = p.add_x_axis({"t", {0.0, 100.0}, false, plot::AxisPlace::Bottom, false});
|
||||
const u32 cid = p.add_cursor(50.0, plot::Color::hex(0xFF0000));
|
||||
plot::input::Controller c(p);
|
||||
c.set_viewport({0, 0, 800.0f * scale, 400.0f * scale});
|
||||
PLOT_CHECK_NEAR(p.ui_scale(), scale, 1e-6);
|
||||
|
||||
const f32 sx = screen_x_of(p, ax, 50.0);
|
||||
const f32 inside = 0.9f * 5.0f * scale; // logical: within the grab radius
|
||||
const f32 outside = 1.1f * 5.0f * scale; // logical: just past it
|
||||
c.on_pointer({sx + inside, 200.0f * scale, 0, 0, plot::input::Button::Left, 0, false, false,
|
||||
false});
|
||||
PLOT_CHECK(c.hovered_cursor() == cid);
|
||||
c.on_pointer({sx + outside, 200.0f * scale, 0, 0, plot::input::Button::Left, 0, false, false,
|
||||
false});
|
||||
PLOT_CHECK(c.hovered_cursor() == plot::kInvalid);
|
||||
// ...and a ctrl-drag at that same logical distance opens a cursor move, which is
|
||||
// the gesture the radius actually gates.
|
||||
c.on_pointer({sx + inside, 200.0f * scale, 0, 0, plot::input::Button::Left, kCtrl, true, true,
|
||||
false});
|
||||
PLOT_CHECK(c.drag_mode() == plot::input::DragMode::MoveCursor);
|
||||
}
|
||||
}
|
||||
|
||||
/// The box-zoom click threshold is a hand movement too: a selection the user
|
||||
/// perceives as a few pixels is a click at any DPI, so both dimensions are compared
|
||||
/// against `logical * Plot::ui_scale()`.
|
||||
PLOT_TEST(box_zoom_click_threshold_scales_with_dpi) {
|
||||
for (const f32 scale : {1.0f, 2.0f}) {
|
||||
plot::Plot p;
|
||||
p.set_ui_scale(scale);
|
||||
p.set_viewport({0, 0, 800.0f * scale, 400.0f * scale});
|
||||
const u32 ax = p.add_x_axis({"t", {0.0, 800.0}, true, plot::AxisPlace::Bottom, false});
|
||||
plot::input::Controller c(p);
|
||||
c.set_viewport({0, 0, 800.0f * scale, 400.0f * scale});
|
||||
const plot::Range before = p.x_range(ax);
|
||||
|
||||
// 3 logical px on each side: a click, at both scales.
|
||||
const f32 x0 = 100.0f * scale;
|
||||
const f32 y0 = 50.0f * scale;
|
||||
const f32 small = 3.0f * scale;
|
||||
c.on_pointer({x0, y0, 0, 0, plot::input::Button::Left, kShift, true, true, false});
|
||||
c.on_pointer({x0 + small, y0 + small, small, small, plot::input::Button::Left, kShift, true,
|
||||
false, false});
|
||||
c.on_pointer({x0 + small, y0 + small, 0, 0, plot::input::Button::Left, kShift, false, false,
|
||||
true});
|
||||
PLOT_CHECK_NEAR(p.x_range(ax).min, before.min, 1e-9);
|
||||
PLOT_CHECK_NEAR(p.x_range(ax).max, before.max, 1e-9);
|
||||
|
||||
// 5 logical px on each side: a box, at both scales.
|
||||
const f32 large = 5.0f * scale;
|
||||
c.on_pointer({x0, y0, 0, 0, plot::input::Button::Left, kShift, true, true, false});
|
||||
c.on_pointer({x0 + large, y0 + large, large, large, plot::input::Button::Left, kShift, true,
|
||||
false, false});
|
||||
c.on_pointer({x0 + large, y0 + large, 0, 0, plot::input::Button::Left, kShift, false, false,
|
||||
true});
|
||||
PLOT_CHECK(p.x_range(ax).min > before.min);
|
||||
PLOT_CHECK(p.x_range(ax).max < before.max);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user