16class MoveArrangerObjectsCommand :
public QUndoCommand
19 MoveArrangerObjectsCommand (
20 std::vector<structure::arrangement::ArrangerObjectUuidReference> objects,
21 units::precise_tick_t tick_delta,
22 double vertical_delta = 0.0)
23 : QUndoCommand (QObject::tr (
"Move Objects")),
24 objects_ (std::move (objects)), tick_delta_ (tick_delta),
25 vertical_delta_ (vertical_delta)
28 original_positions_.reserve (objects_.size ());
29 for (
const auto &obj_ref : objects_)
33 using ObjectT = base_type<
decltype (obj)>;
34 original_positions_.push_back (
35 units::ticks (obj->position ()->ticks ()));
37 std::is_same_v<ObjectT, structure::arrangement::MidiNote>)
39 original_vertical_positions_.push_back (obj->pitch ());
42 std::is_same_v<ObjectT, structure::arrangement::AutomationPoint>)
44 original_vertical_positions_.push_back (obj->value ());
48 original_vertical_positions_.push_back (0);
51 obj_ref.get_object ());
55 int id ()
const override {
return 894553188; }
56 bool mergeWith (
const QUndoCommand * other)
override
58 if (other->id () != id ())
63 const auto * other_cmd =
64 dynamic_cast<const MoveArrangerObjectsCommand *
> (other);
65 const auto cur_time = std::chrono::steady_clock::now ();
66 const auto duration = cur_time - last_redo_timestamp_;
68 std::chrono::duration_cast<std::chrono::milliseconds> (duration).count ()
75 if (objects_.size () != other_cmd->objects_.size ())
80 objects_, other_cmd->objects_, {},
81 &structure::arrangement::ArrangerObjectUuidReference::id,
82 &structure::arrangement::ArrangerObjectUuidReference::id))
87 last_redo_timestamp_ = cur_time;
88 tick_delta_ += other_cmd->tick_delta_;
95 const auto &[obj_ref, original_pos, original_vertical_pos] :
97 objects_, original_positions_, original_vertical_positions_))
101 using ObjectT = base_type<
decltype (obj)>;
102 obj->position ()->setTicks (original_pos.in (units::ticks));
103 if (vertical_delta_ != 0)
106 std::is_same_v<ObjectT, structure::arrangement::MidiNote>)
108 obj->setPitch (
static_cast<int> (original_vertical_pos));
111 std::is_same_v<ObjectT, structure::arrangement::AutomationPoint>)
113 obj->setValue (
static_cast<float> (original_vertical_pos));
117 obj_ref.get_object ());
121 void redo ()
override
124 const auto &[obj_ref, original_pos, original_vertical_pos] :
126 objects_, original_positions_, original_vertical_positions_))
130 using ObjectT = base_type<
decltype (obj)>;
131 obj->position ()->setTicks (
132 (original_pos + tick_delta_).in (units::ticks));
133 if (vertical_delta_ != 0)
136 std::is_same_v<ObjectT, structure::arrangement::MidiNote>)
139 static_cast<int> (original_vertical_pos + vertical_delta_));
142 std::is_same_v<ObjectT, structure::arrangement::AutomationPoint>)
146 original_vertical_pos + vertical_delta_));
150 obj_ref.get_object ());
152 last_redo_timestamp_ = std::chrono::steady_clock::now ();
156 std::vector<structure::arrangement::ArrangerObjectUuidReference> objects_;
157 std::vector<units::precise_tick_t> original_positions_;
158 std::vector<double> original_vertical_positions_;
159 units::precise_tick_t tick_delta_;
160 double vertical_delta_{};
161 std::chrono::time_point<std::chrono::steady_clock> last_redo_timestamp_;