Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
arranger_view.hpp
Go to the documentation of this file.
1#pragma once
2
6
11#include <pulp/view/view.hpp>
12
13#include <cstddef>
14#include <functional>
15#include <optional>
16
18
22
37 double px_per_tick = 0.0;
39 float track_height_px = 64.0f;
41 float lane_left_px = 0.0f;
43 float ruler_height_px = 24.0f;
44
48 float x_for_tick(timebase::TickPosition tick) const noexcept;
51 timebase::TickPosition tick_for_x(float x) const noexcept;
53 float y_for_track_index(std::size_t index) const noexcept;
54};
55
59enum class ArrangerRefusal : std::uint8_t {
63};
64
71class ArrangerView : public view::View {
72 public:
78 using ClipFactory = std::function<std::optional<timeline::Clip>(timebase::TickPosition start)>;
83 using TrackFactory = std::function<std::optional<timeline::Track>()>;
84
86
89 void set_project(const timeline::Project* project, timeline::ItemId sequence_id);
111
112 const ArrangerLayout& layout() const noexcept { return layout_; }
113
116 std::optional<view::Rect> clip_rect(timeline::ItemId track_id,
117 timeline::ItemId clip_id) const;
118
120 const std::vector<ArrangerRefusal>& refusals() const noexcept { return refusals_; }
121 void clear_refusals() { refusals_.clear(); }
122
125 bool gesture_open() const noexcept {
126 return drag_.has_value() || header_drag_.has_value() || track_create_press_.has_value();
127 }
128
129 // ── View ─────────────────────────────────────────────────────────────
130
131 void paint(canvas::Canvas& canvas) override;
132 bool wants_mouse_input() const override { return true; }
137
138 private:
140 struct Drag {
141 timeline::ItemId track_id;
142 timeline::ItemId clip_id;
145 std::int64_t grab_offset_ticks = 0;
146 timebase::TickDuration duration{};
155 bool opened = false;
156 };
157
159 struct HeaderDrag {
160 timeline::ItemId track_id;
161 float pointer_down_y = 0.0f;
162 float grab_offset_y = 0.0f;
163 bool moved = false;
166 std::optional<timeline::ItemId> expected_before_track_id;
167 };
168
170 struct TrackCreatePress {
171 view::Point pointer_down{};
172 bool moved = false;
173 };
174
175 const timeline::Sequence* sequence() const;
176 const timeline::Track* track_at(view::Point position, std::size_t& index_out) const;
178 const timeline::Clip* clip_at(const timeline::Track& track, view::Point position) const;
179
180 void emit_move(const Drag& drag, timeline::GesturePhase phase,
181 timeline::MusicalTimeRange replacement);
182 void submit(const timeline_editor::EditIntent& intent);
183 void submit(const timeline_editor::TrackEditIntent& intent);
184 void submit(const timeline_editor::TrackCreateIntent& intent);
185
186 const timeline::Project* project_ = nullptr;
187 timeline::ItemId sequence_id_{};
188 ArrangerLayout layout_{};
189 timeline_editor::EditIntentHost* host_ = nullptr;
190 timeline_editor::TrackEditIntentHost* track_edit_host_ = nullptr;
191 timeline_editor::TrackArrangementIntentHost* track_arrangement_host_ = nullptr;
192 view::HitMetrics metrics_ = view::HitMetrics::for_pointer(view::PointerType::mouse);
193 ClipFactory clip_factory_;
194 TrackFactory track_factory_;
195 std::optional<Drag> drag_;
196 std::optional<HeaderDrag> header_drag_;
197 std::optional<TrackCreatePress> track_create_press_;
198 std::vector<ArrangerRefusal> refusals_;
199};
200
202
203} // namespace pulp::timeline_view
Definition canvas.hpp:240
Immutable root of a Timeline document and its monotonic identity domain.
Definition model.hpp:1079
void set_host(timeline_editor::EditIntentHost *host)
Where emitted intents go.
void paint(canvas::Canvas &canvas) override
void set_track_arrangement_host(timeline_editor::TrackArrangementIntentHost *host)
Where reorder and create-track intents go.
void set_hit_metrics(const view::HitMetrics &metrics)
Pointer geometry, resolved once per gesture rather than per hit test.
void on_mouse_cancel(view::Point position) override
Pointer / touch cancellation (iOS touchesCancelled, etc.).
const std::vector< ArrangerRefusal > & refusals() const noexcept
Refusals recorded since the last clear_refusals(), in order.
Definition arranger_view.hpp:120
void set_clip_factory(ClipFactory factory)
Enables the create-clip gesture.
void set_layout(const ArrangerLayout &layout)
bool wants_mouse_input() const override
True if this widget handles mouse down/drag through virtual methods even when it does not expose JS p...
Definition arranger_view.hpp:132
void on_mouse_drag(view::Point position) override
const ArrangerLayout & layout() const noexcept
Definition arranger_view.hpp:112
std::function< std::optional< timeline::Track >()> TrackFactory
Builds the complete value for a create-track gesture.
Definition arranger_view.hpp:83
bool gesture_open() const noexcept
Whether a drag is mid-flight.
Definition arranger_view.hpp:125
void set_track_edit_host(timeline_editor::TrackEditIntentHost *host)
Where track-header reorder intents go.
void set_track_factory(TrackFactory factory)
Enables track creation from the first empty header row.
void on_mouse_up(view::Point position) override
void set_project(const timeline::Project *project, timeline::ItemId sequence_id)
Borrows the project to paint and hit-test.
void clear_refusals()
Definition arranger_view.hpp:121
std::function< std::optional< timeline::Clip >(timebase::TickPosition start)> ClipFactory
Builds the payload for a create-clip gesture at a lane position.
Definition arranger_view.hpp:78
std::optional< view::Rect > clip_rect(timeline::ItemId track_id, timeline::ItemId clip_id) const
Rectangle a clip occupies, in this view's local coordinates, or nullopt when the identity is not in t...
void on_mouse_down(view::Point position) override
Definition view.hpp:73
Position position() const
Definition view.hpp:1767
const std::shared_ptr< WidgetMetrics > & metrics() const
Definition view.hpp:251
Pointer-neutral editing intents and their lowering to ordinary transactions.
GesturePhase
Lifecycle position of a transaction within an interactive gesture.
Definition command.hpp:79
SequencerUiHostT< EditIntent > EditIntentHost
The host an editor submits its intents to.
Definition edit_intent.hpp:523
SequencerUiHostT< TrackEditIntent > TrackEditIntentHost
The host an arranger submits track intents to.
Definition track_edit_intent.hpp:78
SequencerUiHostT< TrackArrangementIntent > TrackArrangementIntentHost
The host an arranger offering reorder and creation submits intents to.
Definition track_edit_intent.hpp:81
@ Sequence
Sequence existence and cloning.
Definition document_session.hpp:65
@ Clip
Clip placement, timing, and playback properties on a track.
Definition document_session.hpp:44
@ Track
Track existence, order, naming, mix, arm, and freeze.
Definition document_session.hpp:59
@ Project
Definition model.hpp:945
ArrangerRefusal
Why the arranger declined to emit an intent a gesture would otherwise have produced.
Definition arranger_view.hpp:59
@ NestedSequenceContent
A clip factory returned content the arranger will not author.
Definition arranger_view.hpp:62
Device-appropriate target sizing shared by pointer-driven hit tests.
Definition affine_transform.hpp:24
Bounded event contracts shared by host ingress and graph-authored nodes.
Definition anticipation_eligibility.hpp:9
Definition arranger_view.hpp:17
@ mouse
Mouse cursor (default).
Definition input_events.hpp:76
Definition tick.hpp:56
Definition tick.hpp:61
Nonzero monotonic identity for a Timeline-owned object.
Definition item_id.hpp:19
Musical clip placement in canonical ticks.
Definition clip.hpp:182
A resolved tick/pixel mapping, supplied by whoever owns the viewport.
Definition arranger_view.hpp:31
float track_height_px
Row pitch, and the height of a clip rectangle within its row.
Definition arranger_view.hpp:39
float lane_left_px
Clip lanes begin here; [0, lane_left_px) is the track-header column.
Definition arranger_view.hpp:41
float y_for_track_index(std::size_t index) const noexcept
Top edge of the row at an authored track index.
float x_for_tick(timebase::TickPosition tick) const noexcept
Lane-space x of a document tick.
double px_per_tick
Horizontal scale.
Definition arranger_view.hpp:37
timebase::TickPosition tick_for_x(float x) const noexcept
Document tick at a lane-space x.
float ruler_height_px
Height reserved above the track rows for the musical ruler.
Definition arranger_view.hpp:43
timebase::TickPosition origin_tick
Document tick drawn at the left edge of the clip lanes.
Definition arranger_view.hpp:33
Minimum hit-target sizing for one pointer type.
Definition hit_metrics.hpp:24
static constexpr HitMetrics for_pointer(PointerType type) noexcept
Metrics carrying this pointer type's default target extent.
Definition hit_metrics.hpp:43
Definition geometry.hpp:20
Pointer-neutral track-arrangement intents and their lowering to transactions.