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 : QAbstractListModel (parent), objects_ (objects)
95 {
96 setup_signals (false);
97 }
98
106 ArrangerObjectRefMultiIndexContainer &objects,
107 ArrangerObject &parent_arranger_object)
108 : QAbstractListModel (&parent_arranger_object), objects_ (objects)
109 {
110 setup_signals (true);
111 }
112
113 QHash<int, QByteArray> roleNames () const override;
114
115 int rowCount (const QModelIndex &parent = QModelIndex ()) const override
116 {
117 if (parent.isValid ())
118 return 0;
119 return static_cast<int> (objects_.size ());
120 }
121
122 QVariant
123 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
124
125 void clear ();
126
127 bool insertObject (const ArrangerObjectUuidReference &object, int index);
128
129 bool
130 removeRows (int row, int count, const QModelIndex &parent = QModelIndex ())
131 override;
132
133 Q_SIGNAL void contentChanged (utils::ExpandableTickRange affectedRange);
134
135private:
144 void connect_object_signals (int index);
145
153 void disconnect_object_signals (int index);
154
163 void setup_signals (bool is_parent_arranger_object);
164
174 void handle_object_change (const ArrangerObject * object);
175
185 std::pair<units::precise_tick_t, units::precise_tick_t>
186 get_and_update_previous_range (const ArrangerObject * object);
187
188private:
189 ArrangerObjectRefMultiIndexContainer &objects_;
190
193 std::unordered_map<
194 ArrangerObject::Uuid,
195 std::pair<units::precise_tick_t, units::precise_tick_t>>
196 previous_object_ranges_;
197};
198}
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.