Files
plotter/adapters/qt6/qt_pointer.hpp
T
Martino Ferrari ed3a8ce645 licence: MIT LICENSE and SPDX identifiers in every first-party file
The repository had no licence at all, so every source was all-rights-reserved
by default. Add the verbatim MIT text at LICENSE (Copyright (c) 2026 Martino
Ferrari) and a two-line SPDX header to each of the 113 first-party sources --
48 include/plot, 26 src, 10 adapters, 5 examples, 21 tests, 3 tools -- so the
grant travels with each file rather than relying on the root document alone.

Scripts keep their shebang on line 1; the SPDX lines follow it. Genuinely
vendored code is untouched: third_party/stb_truetype.h carries no header of
ours. src/render/embedded_mono_font.cpp is generated, so tools/fonts/gen_atlas.py
emit() now writes the two lines into its header comment and the file was
regenerated -- gen_atlas.py --check passes and the regeneration adds only those
comment lines to the previously committed file.

README's provenance section now states MIT and links LICENSE.

No code, test or public API change.
2026-09-28 22:13:40 +02:00

53 lines
2.2 KiB
C++

// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2026 Martino Ferrari
#pragma once
#include <plot/core/types.hpp>
#include <plot/math/vec2.hpp>
namespace plot::qt {
/// The cached pointer position a move event's movement is measured from, in
/// **logical** widget pixels.
///
/// Logical, not device, pixels on purpose. Qt reports every widget position in
/// logical pixels, and the device-pixel ratio can change between two move events
/// -- the window being dragged onto a monitor with another scale factor is the
/// case -- so an anchor cached in device pixels would compare a position computed
/// at the old ratio with one computed at the new one. At 1.0 -> 1.25 a logical
/// position of 500 would then look like a jump of 125 device pixels, and
/// `Controller::pan` applies a delta as a fraction of the range span (and clears
/// auto scale), so a scale change mid-drag would pan the plot by 125 pixels' worth
/// of data. Keeping the anchor logical and scaling the *difference* by the ratio
/// in effect now makes the same gesture map to the same device distance whatever
/// the window's scale is.
///
/// A plain value with no toolkit dependency: the widget owns one, and this is the
/// part of the adapter's translation a test can drive directly (see
/// tests/test_qt_pointer.cpp).
struct PointerAnchor {
bool have = false; ///< false until the first sample, which has no movement
f32 x = 0.0f; ///< last logical position, widget pixels
f32 y = 0.0f;
/// Movement from the cached position to `logical`, in device pixels at `dpr`.
/// Zero before the first sample, so the first motion of a drag never includes
/// the jump to where the drag began.
Vec2 device_delta(Vec2 logical, f64 dpr) const noexcept {
if (!have) return Vec2{0.0f, 0.0f};
return Vec2{static_cast<f32>((static_cast<f64>(logical.x) - static_cast<f64>(x)) * dpr),
static_cast<f32>((static_cast<f64>(logical.y) - static_cast<f64>(y)) * dpr)};
}
/// Caches `logical` as the position the next movement is measured from. Always
/// logical pixels, whatever the ratio is: see the type's comment.
void set(Vec2 logical) noexcept {
x = logical.x;
y = logical.y;
have = true;
}
};
} // namespace plot::qt