27template <FinalArrangerObjectSub
class ChildT>
class ArrangerObjectOwner
30 using ArrangerObjectChildType = ChildT;
33 requires std::derived_from<T, QObject>
34 : registry_ (registry)
36 if constexpr (std::derived_from<T, ArrangerObject>)
38 list_model_ = utils::make_qobject_unique<ArrangerObjectListModel> (
43 list_model_ = utils::make_qobject_unique<ArrangerObjectListModel> (
47 virtual ~ArrangerObjectOwner () =
default;
48 Q_DISABLE_COPY_MOVE (ArrangerObjectOwner)
50 auto &get_children_vector ()
const
55 auto get_children_view ()
const
59 | std::views::transform (
60 &ArrangerObjectUuidReference::get_object_as<ChildT>);
63 auto get_sorted_children_view ()
const
67 | std::views::transform (
68 &ArrangerObjectUuidReference::get_object_as<ChildT>);
71 void add_ticks_to_children (
double ticks)
73 for (
auto * child : get_children_view ())
75 child->position ()->setTicks (child->position ()->ticks () + ticks);
89 ArrangerObjectUuidReference remove_object (
const ArrangerObject::Uuid &
id)
91 auto &container = ArrangerObjectOwner<ChildT>::children_;
92 auto &random_access_idx = container.template get<random_access_index> ();
93 auto it_to_remove = std::ranges::find (
94 random_access_idx,
id, &ArrangerObjectUuidReference::id);
95 if (it_to_remove == random_access_idx.end ())
97 throw std::runtime_error (
98 fmt::format (
"object to remove not found: {}",
id));
100 z_trace (
"removing object: {}",
id);
102 auto obj_ref = *it_to_remove;
103 const auto remove_idx =
104 std::distance (random_access_idx.begin (), it_to_remove);
107 ArrangerObjectOwner<ChildT>::list_model_->removeRows (
108 static_cast<int> (remove_idx), 1);
113 void insert_object (
const ArrangerObjectUuidReference &obj_ref,
int idx)
115 ArrangerObjectOwner<ChildT>::list_model_->insertObject (obj_ref, idx);
118 void add_object (
const ArrangerObjectUuidReference &obj_ref)
120 ArrangerObjectOwner<ChildT>::insert_object (
122 static_cast<int> (ArrangerObjectOwner<ChildT>::children_.size ()));
125 void clear_objects () { list_model_->clear (); }
139 friend void init_from (
140 ArrangerObjectOwner &obj,
141 const ArrangerObjectOwner &other,
146 obj.children_.reserve (other.children_.size ());
147 for (
const auto &child : other.get_children_view ())
150 std::optional<ArrangerObjectUuidReference> clone_ref;
151 if constexpr (std::is_same_v<ChildT, AudioSourceObject>)
153 clone_ref = utils::clone_object (
155 child->get_tempo_map (), obj.registry_,
156 child->audio_source_ref ());
160 z_warning (
"RegionObject clone not implemented - skipping");
163 else if constexpr (std::is_same_v<ChildT, Marker>)
165 clone_ref = utils::clone_object (
167 child->get_tempo_map (), child->markerType ());
171 clone_ref = utils::clone_object (
173 child->get_tempo_map ());
178 obj.add_object (*clone_ref);
187 const auto children_field_name =
189 j[children_field_name] = obj.children_;
191 friend void from_json (
const nlohmann::json &j, ArrangerObjectOwner &obj)
193 const auto children_field_name =
194 obj.get_field_name_for_serialization (
static_cast<ChildT *
> (
nullptr));
195 for (
const auto &child_json : j.at (children_field_name))
197 const auto uuid = child_json.template get<ArrangerObjectUuid> ();
198 ArrangerObjectUuidReference obj_ref{ uuid, obj.registry_ };
199 obj.add_object (obj_ref);
204 utils::IObjectRegistry ®istry_;
205 ArrangerObjectRefMultiIndexContainer children_;
206 utils::QObjectUniquePtr<ArrangerObjectListModel> list_model_;
208 BOOST_DESCRIBE_CLASS (ArrangerObjectOwner<ChildT>, (), (), (), (children_))