Loading...
Searching...
No Matches
BarsDrag.hpp
1#pragma once
2#include <QPointF>
3
4#include <algorithm>
5#include <cmath>
6#include <vector>
7
8namespace score
9{
22{
23 enum class Kind
24 {
25 None,
26 Offset,
27 Random
28 };
29
30 Kind kind{Kind::None};
31 QPointF origin;
32 std::vector<float> base;
34 std::vector<float> target;
35 std::vector<int> steps;
36
37 explicit operator bool() const noexcept { return kind != Kind::None; }
38
39 void start(
40 Kind k, QPointF pos, std::vector<float> values, std::vector<float> targets,
41 std::vector<int> affected)
42 {
43 kind = k;
44 origin = pos;
45 base = std::move(values);
46 target = std::move(targets);
47 target.resize(base.size());
48 steps = std::move(affected);
49 }
50
51 void stop() noexcept { kind = Kind::None; }
52
54 std::vector<float> values(QPointF pos, double height, float bottom, float top) const
55 {
56 std::vector<float> res = base;
57 if(height <= 0.)
58 return res;
59 const float lo = std::min(bottom, top);
60 const float hi = std::max(bottom, top);
61 if(kind == Kind::Offset)
62 {
63 const float delta = float((origin.y() - pos.y()) / height) * (top - bottom);
64 for(int i : steps)
65 if(i >= 0 && i < std::ssize(res))
66 res[i] = std::clamp(base[i] + delta, lo, hi);
67 }
68 else if(kind == Kind::Random)
69 {
70 const QPointF d = pos - origin;
71 const float t = std::clamp(
72 float(std::hypot(d.x(), d.y()) / std::max(80., height)), 0.f, 1.f);
73 for(int i : steps)
74 if(i >= 0 && i < std::ssize(res))
75 res[i] = base[i] + t * (target[i] - base[i]);
76 }
77 return res;
78 }
79};
80}
Base toolkit upon which the software is built.
Definition Application.cpp:83
A modifier drag over a row of bars, each the value of a step.
Definition BarsDrag.hpp:22
std::vector< float > values(QPointF pos, double height, float bottom, float top) const
The values with the mouse at pos, over bars height high.
Definition BarsDrag.hpp:54
std::vector< float > target
For Random: where each bar ends up when dragged all the way.
Definition BarsDrag.hpp:34