Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
resize_arranger_objects_command.h
1// SPDX-FileCopyrightText: © 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <algorithm>
7#include <ranges>
8#include <vector>
9
10#include "structure/arrangement/arranger_object_all.h"
11
12#include <QUndoCommand>
13
14namespace zrythm::commands
15{
16Q_NAMESPACE
17
19enum class ResizeType : int
20{
21 Bounds = 0,
22 LoopPoints = 1,
23 Fades = 2
24};
25Q_ENUM_NS (ResizeType)
26
27
28enum class ResizeDirection : int
29{
30 FromStart = 0,
31 FromEnd = 1
32};
33Q_ENUM_NS (ResizeDirection)
34
35class ResizeArrangerObjectsCommand : public QUndoCommand
36{
37 static constexpr int ID = 1762503480;
38
39public:
42 {
43 units::precise_tick_t position = units::ticks (0);
44 units::precise_tick_t length = units::ticks (0);
45 units::precise_tick_t clipStart = units::ticks (0);
46 units::precise_tick_t loopStart = units::ticks (0);
47 units::precise_tick_t loopEnd = units::ticks (0);
48 bool boundsTracked{};
49 units::precise_tick_t fadeInOffset = units::ticks (0);
50 units::precise_tick_t fadeOutOffset = units::ticks (0);
51 units::precise_tick_t firstChildTicks = units::ticks (0);
52 };
53
54 ResizeArrangerObjectsCommand (
55 std::vector<structure::arrangement::ArrangerObjectUuidReference> objects,
56 ResizeType type,
57 ResizeDirection direction,
58 double delta);
59
60 int id () const override { return ID; }
61
62 bool mergeWith (const QUndoCommand * other) override
63 {
64 if (other->id () != id ())
65 return false;
66
67 // Only merge if other command was made in quick succession of this
68 // command's redo() and operates on the same objects
69 const auto * other_cmd =
70 dynamic_cast<const ResizeArrangerObjectsCommand *> (other);
71 const auto cur_time = std::chrono::steady_clock::now ();
72 const auto duration = cur_time - last_redo_timestamp_;
73 if (
74 std::chrono::duration_cast<std::chrono::milliseconds> (duration).count ()
75 > 1'000)
76 {
77 return false;
78 }
79
80 // Check if we're operating on the same set of objects, type, and direction
81 if (type_ != other_cmd->type_ || direction_ != other_cmd->direction_)
82 return false;
83
84 if (objects_.size () != other_cmd->objects_.size ())
85 return false;
86
87 if (
88 !std::ranges::equal (
89 objects_, other_cmd->objects_, {},
90 &structure::arrangement::ArrangerObjectUuidReference::id,
91 &structure::arrangement::ArrangerObjectUuidReference::id))
92 {
93 return false;
94 }
95
96 last_redo_timestamp_ = cur_time;
97 delta_ += other_cmd->delta_;
98 return true;
99 }
100
101 void undo () override;
102 void redo () override;
103
104private:
105 std::vector<structure::arrangement::ArrangerObjectUuidReference> objects_;
106 ResizeType type_;
107 ResizeDirection direction_;
108 double delta_;
109
110 // Original state storage for undo
111 std::vector<OriginalState> original_states_;
112
113 std::chrono::time_point<std::chrono::steady_clock> last_redo_timestamp_;
114};
115
116} // namespace zrythm::commands
Structure to hold original state of an arranger object for undo.