Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
track_header_projection.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5#include <cstdint>
6#include <optional>
7#include <span>
8#include <utility>
9#include <vector>
10
13
14namespace pulp::timeline_editor {
15
26
31class TrackHeaderProjection {
32 public:
34 using DropTarget = std::optional<timeline::ItemId>;
35
38 create(std::span<const timeline::ItemId> track_order, float origin_y, float row_height) {
39 if (!std::isfinite(origin_y) || !std::isfinite(row_height)) {
41 }
42 if (row_height <= 0.0f) {
44 }
45 if (track_order.empty()) {
47 }
48
49 std::vector<timeline::ItemId> order(track_order.begin(), track_order.end());
50 for (const auto id : order) {
51 if (!id.valid()) {
53 }
54 }
55 auto sorted = order;
56 std::sort(sorted.begin(), sorted.end());
57 if (std::adjacent_find(sorted.begin(), sorted.end()) != sorted.end()) {
59 }
60
61 const auto bottom = origin_y + row_height * static_cast<float>(order.size());
62 if (!std::isfinite(bottom)) {
64 }
65 return runtime::Ok(TrackHeaderProjection(std::move(order), origin_y, row_height));
66 }
67
69 [[nodiscard]] std::optional<timeline::ItemId> track_at(float y) const noexcept {
70 if (!std::isfinite(y) || y < origin_y_ || y >= bottom_y()) {
71 return std::nullopt;
72 }
73 const auto index =
74 std::min(static_cast<std::size_t>((y - origin_y_) / row_height_), order_.size() - 1);
75 return order_[index];
76 }
77
80 before_track_for_drop(float y, timeline::ItemId moving_track) const {
81 if (!std::isfinite(y)) {
83 }
84 if (std::find(order_.begin(), order_.end(), moving_track) == order_.end()) {
86 }
87
88 std::size_t candidate_index = 0;
89 for (const auto candidate : order_) {
90 if (candidate == moving_track) {
91 continue;
92 }
93 const auto center =
94 origin_y_ + (static_cast<float>(candidate_index) + 0.5f) * row_height_;
95 if (y < center) {
96 return runtime::Ok(DropTarget{candidate});
97 }
98 ++candidate_index;
99 }
100 return runtime::Ok(DropTarget{});
101 }
102
104 [[nodiscard]] constexpr float origin_y() const noexcept {
105 return origin_y_;
106 }
107
108 [[nodiscard]] constexpr float row_height() const noexcept {
109 return row_height_;
110 }
111
112 [[nodiscard]] float bottom_y() const noexcept {
113 return origin_y_ + row_height_ * static_cast<float>(order_.size());
114 }
115
116 [[nodiscard]] std::span<const timeline::ItemId> track_order() const noexcept {
117 return order_;
118 }
119
120 private:
121 TrackHeaderProjection(std::vector<timeline::ItemId> order, float origin_y, float row_height)
122 : order_(std::move(order)), origin_y_(origin_y), row_height_(row_height) {}
123
124 std::vector<timeline::ItemId> order_;
125 float origin_y_ = 0.0f;
126 float row_height_ = 0.0f;
127};
128
129} // namespace pulp::timeline_editor
Result<T, E> — either holds a T or an E, never both.
Definition result.hpp:76
Maps authored track order to header rows and reorder insertion neighbors.
Definition track_header_projection.hpp:31
constexpr float origin_y() const noexcept
Returns the leading y coordinate of the first row.
Definition track_header_projection.hpp:104
static runtime::Result< TrackHeaderProjection, TrackHeaderProjectionError > create(std::span< const timeline::ItemId > track_order, float origin_y, float row_height)
Validates and captures the complete authored order and row geometry.
Definition track_header_projection.hpp:38
constexpr float row_height() const noexcept
Returns the positive height shared by every row.
Definition track_header_projection.hpp:108
float bottom_y() const noexcept
Returns the exclusive y coordinate following the final row.
Definition track_header_projection.hpp:112
std::span< const timeline::ItemId > track_order() const noexcept
Returns the immutable authored order captured at construction.
Definition track_header_projection.hpp:116
std::optional< timeline::ItemId > DropTarget
Empty means append after every remaining track.
Definition track_header_projection.hpp:34
runtime::Result< DropTarget, TrackHeaderProjectionError > before_track_for_drop(float y, timeline::ItemId moving_track) const
Resolves y to a reorder neighbor after removing moving_track logically.
Definition track_header_projection.hpp:80
std::optional< timeline::ItemId > track_at(float y) const noexcept
Returns the track owning y, or empty outside the half-open row range.
Definition track_header_projection.hpp:69
Err(E) -> Err< E >
@ Ok
No error; bytes is authoritative.
Definition stream.hpp:32
ScriptedUiHost is a SequencerUiHost whose playhead is written by the caller instead of an engine,...
Definition edit_intent.hpp:14
TrackHeaderProjectionError
Construction and query failures for track-header projection.
Definition track_header_projection.hpp:17
@ NonPositiveRowHeight
Definition track_header_projection.hpp:22
@ NonFiniteGeometry
Definition track_header_projection.hpp:21
@ MissingMovingTrack
Definition track_header_projection.hpp:24
@ EmptyTrackOrder
Definition track_header_projection.hpp:18
@ InvalidTrackId
Definition track_header_projection.hpp:19
@ NonFiniteCoordinate
Definition track_header_projection.hpp:23
@ DuplicateTrackId
Definition track_header_projection.hpp:20
STL namespace.
Result<T, E> — success / failure union for fallible operations.
Nonzero monotonic identity for a Timeline-owned object.
Definition item_id.hpp:19