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.
53 lines
2.2 KiB
C++
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
|