Loading...
Searching...
No Matches
QGraphicsGridChooser.hpp
1#pragma once
2#include <score/graphics/widgets/Constants.hpp>
3#include <score/graphics/widgets/NoteValues.hpp>
4
5#include <ossia/network/value/vec.hpp>
6
7#include <QGraphicsItem>
8#include <QObject>
9#include <QString>
10
11#include <score_lib_base_export.h>
12
13#include <array>
14#include <verdigris>
15
16class QMenu;
17namespace score
18{
19// A quantization grid: free seconds, a note value, a number of bars or a
20// multiple of the process's own period (e.g. its loop). The same knob and
21// readout as the time chooser: dragging the knob steps through the values of
22// the current unit, clicking the readout opens a menu of the units the
23// control allows (and, for note values, of the feels), a right-click on a free
24// time types it in, a double-click on the knob goes back to the default.
25//
26// The value is vec2f{value, unit}, see halp::grid_value: unit 0 is seconds (0
27// is no grid, "None"), 1 a fraction of a whole note, 2 bars, 3 a multiple of
28// the period, -1 the parent's grid.
29class SCORE_LIB_BASE_EXPORT QGraphicsGridChooser final
30 : public QObject
31 , public QGraphicsItem
32{
33 W_OBJECT(QGraphicsGridChooser)
34 SCORE_GRAPHICS_ITEM_TYPE(330)
35 friend struct DefaultControlImpl;
36 friend struct DefaultGraphicsKnobImpl;
37
38public:
39 enum Unit : int8_t
40 {
41 Parent = -1,
42 Free = 0,
43 Note = 1,
44 Bars = 2,
45 Period = 3
46 };
48 static constexpr uint32_t flag(Unit u) noexcept
49 {
50 return u == Parent ? (1u << 4) : (1u << int(u));
51 }
52
53 using Feel = note_values::Feel;
54
56 static constexpr std::array<float, 7> periodDetents{0.25f, 0.5f, 1.f, 2.f,
57 3.f, 4.f, 8.f};
58
61 double min{0.}, max{8.};
63 ossia::vec2f init{0.25f, float(Note)};
64 bool moving{};
65
66 explicit QGraphicsGridChooser(QGraphicsItem* parent);
67 ~QGraphicsGridChooser();
68
70 void setUnits(uint32_t units);
71 [[nodiscard]] uint32_t units() const noexcept { return m_units; }
72 void setMaxBars(int bars);
73 [[nodiscard]] int maxBars() const noexcept { return m_maxBars; }
75 void setPeriodName(const QString& name);
76 [[nodiscard]] const QString& periodName() const noexcept { return m_periodName; }
77 void setMaxSeconds(double seconds);
78
79 void setRect(const QRectF& r);
80 void setValue(ossia::vec2f v);
81 [[nodiscard]] ossia::vec2f value() const noexcept;
82 void setExecutionValue(ossia::vec2f v);
83 void resetExecution();
84
85 [[nodiscard]] Unit unit() const noexcept { return m_unit; }
86 [[nodiscard]] Feel feel() const noexcept { return m_feel; }
87
89 void chooseUnit(Unit u);
91 void chooseFeel(Feel f);
92
94 [[nodiscard]] QString text() const;
96 [[nodiscard]] static QString
97 label(ossia::vec2f v, const QString& periodName = QStringLiteral("loop"));
99 [[nodiscard]] static QString
100 unitName(Unit u, const QString& periodName = QStringLiteral("loop"));
101
103 [[nodiscard]] QMenu* makeUnitMenu();
104
105 QRectF boundingRect() const override;
106
107 void sliderMoved() E_SIGNAL(SCORE_LIB_BASE_EXPORT, sliderMoved)
108 void sliderReleased() E_SIGNAL(SCORE_LIB_BASE_EXPORT, sliderReleased)
109
110private:
111 void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
112 override;
113 void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
114 void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
115 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
116 bool sceneEvent(QEvent* event) override;
117 void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) override;
118 void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;
119 void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
120 void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
121
124 double map(double position) const noexcept;
125 double unmap(double seconds) const noexcept;
126 bool onReadout(QPointF pos) const noexcept;
127
129 double positionOf(Unit u, double value) const noexcept;
130 double valueAt(Unit u, double position) const noexcept;
132 double snap(double position, bool allNoteValues) const noexcept;
133 void dragTo(double position, bool allNoteValues);
134 void popupUnitMenu(QPoint screenPos);
135 void edited();
136
137 QRectF m_rect{0., 0., 35., 35.};
138
139 double m_value{}; // knob position, 0..1, in the current unit
140 double m_execValue{};
143 std::array<double, 4> m_values{0., 0.25, 1., 1.};
144 QString m_periodName{QStringLiteral("loop")};
145 uint32_t m_units{flag(Free) | flag(Note) | flag(Bars)};
146 int m_maxBars{16};
147 Unit m_unit{Note};
148 Feel m_feel{Feel::Straight};
149 bool m_grab{};
150 bool m_hasExec{};
151 bool m_hover{};
152};
153}
Definition QGraphicsGridChooser.hpp:32
static constexpr uint32_t flag(Unit u) noexcept
The bit of a unit in a set of allowed units, as halp::grid_units.
Definition QGraphicsGridChooser.hpp:48
Base toolkit upon which the software is built.
Definition Application.cpp:83
Definition DefaultControlImpl.hpp:10
Definition DefaultGraphicsKnobImpl.hpp:27