Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
arranger_object_list_model.h
1// SPDX-FileCopyrightText: © 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <unordered_map>
7
8#include "structure/arrangement/arranger_object.h"
9#include "utils/expandable_tick_range.h"
10#include "utils/units.h"
11
12#include <QAbstractListModel>
13
14#include <boost/multi_index/global_fun.hpp>
15#include <boost/multi_index/hashed_index.hpp>
16#include <boost/multi_index/mem_fun.hpp>
17#include <boost/multi_index/ordered_index.hpp>
18#include <boost/multi_index/random_access_index.hpp>
19#include <boost/multi_index/ranked_index.hpp>
20#include <boost/multi_index/sequenced_index.hpp>
21#include <boost/multi_index_container.hpp>
22
23namespace zrythm::structure::arrangement
24{
25
26// Vector-like index for fast iteration
28{
29};
30
31// Random-access index for fast lookups by index
33{
34};
35
36// HashTable-like index for fast lookups by ID
38{
39};
40
41// Sorted by position
43{
44};
45
46inline double
47get_ticks_from_arranger_object_uuid_ref (const ArrangerObjectUuidReference &ref)
48{
49 return ref.get_object_base ()->position ()->ticks ();
50}
51
52// Multi-index container for both quick iteration and quick lookups
53using ArrangerObjectRefMultiIndexContainer = boost::multi_index_container<
54 ArrangerObjectUuidReference,
55 boost::multi_index::indexed_by<
56 boost::multi_index::hashed_unique<
57 boost::multi_index::tag<uuid_hash_index>,
58 boost::multi_index::const_mem_fun<
59 ArrangerObjectUuidReference,
60 ArrangerObject::Uuid,
61 &ArrangerObjectUuidReference::id>>,
62 boost::multi_index::random_access<boost::multi_index::tag<random_access_index>>,
63 boost::multi_index::ranked_non_unique<
64 boost::multi_index::tag<sorted_index>,
65 boost::multi_index::global_fun<
66 const ArrangerObjectUuidReference &,
67 double,
68 &get_ticks_from_arranger_object_uuid_ref>>,
69 boost::multi_index::sequenced<boost::multi_index::tag<sequenced_index>>>>;
70
77class ArrangerObjectListModel : public QAbstractListModel
78{
79 Q_OBJECT
80 QML_ELEMENT
81 QML_UNCREATABLE ("")
82
83public:
84 enum ArrangerObjectListModelRoles
85 {
86 ArrangerObjectPtrRole = Qt::UserRole + 1,
87 ArrangerObjectUuidReferenceRole
88 };
89 Q_ENUM (ArrangerObjectListModelRoles)
90
91 ArrangerObjectListModel (
92 ArrangerObjectRefMultiIndexContainer &objects,
93 QObject * parent = nullptr);
94
102 ArrangerObjectRefMultiIndexContainer &objects,
103 ArrangerObject &parent_arranger_object);
104
105 QHash<int, QByteArray> roleNames () const override;
106
107 int rowCount (const QModelIndex &parent = QModelIndex ()) const override
108 {
109 if (parent.isValid ())
110 return 0;
111 return static_cast<int> (objects_.size ());
112 }
113
114 QVariant
115 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
116
117 void clear ();
118
119 bool insertObject (const ArrangerObjectUuidReference &object, int index);
120
121 bool
122 removeRows (int row, int count, const QModelIndex &parent = QModelIndex ())
123 override;
124
125 Q_SIGNAL void contentChanged (utils::ExpandableTickRange affectedRange);
126
127private:
136 void connect_object_signals (int index);
137
145 void disconnect_object_signals (int index);
146
155 void setup_signals (bool is_parent_arranger_object);
156
166 void handle_object_change (const ArrangerObject * object);
167
177 std::pair<units::precise_tick_t, units::precise_tick_t>
178 get_and_update_previous_range (const ArrangerObject * object);
179
180private:
181 ArrangerObjectRefMultiIndexContainer &objects_;
182
185 std::unordered_map<
187 std::pair<units::precise_tick_t, units::precise_tick_t>>
188 previous_object_ranges_;
189};
190}
ArrangerObjectListModel(ArrangerObjectRefMultiIndexContainer &objects, ArrangerObject &parent_arranger_object)
To be used when the parent is also an arranger object.
Base class for all objects in the arranger.