3 #include <Scenario/Commands/Scenario/Displacement/MoveEventMeta.hpp>
4 #include <Scenario/Commands/Scenario/Merge/MergeEvents.hpp>
5 #include <Scenario/Commands/Scenario/Merge/MergeTimeSyncs.hpp>
6 #include <Scenario/Document/Event/EventPresenter.hpp>
7 #include <Scenario/Document/Event/EventView.hpp>
8 #include <Scenario/Document/State/StatePresenter.hpp>
9 #include <Scenario/Document/State/StateView.hpp>
10 #include <Scenario/Document/TimeSync/TimeSyncPresenter.hpp>
11 #include <Scenario/Document/TimeSync/TimeSyncView.hpp>
12 #include <Scenario/Document/TimeSync/TriggerView.hpp>
13 #include <Scenario/Palette/ScenarioPaletteBaseStates.hpp>
14 #include <Scenario/Palette/Tools/ScenarioRollbackStrategy.hpp>
15 #include <Scenario/Palette/Transitions/AnythingTransitions.hpp>
16 #include <Scenario/Palette/Transitions/EventTransitions.hpp>
17 #include <Scenario/Palette/Transitions/NothingTransitions.hpp>
18 #include <Scenario/Palette/Transitions/StateTransitions.hpp>
19 #include <Scenario/Palette/Transitions/TimeSyncTransitions.hpp>
20 #include <Scenario/Process/Algorithms/Accessors.hpp>
22 #include <Magnetism/MagnetismAdjuster.hpp>
24 #include <score/command/Dispatchers/MultiOngoingCommandDispatcher.hpp>
25 #include <score/locking/ObjectLocker.hpp>
27 #include <QFinalState>
92 typename MoveEventCommand_T,
93 typename Scenario_T,
typename ToolPalette_T>
98 const ToolPalette_T& stateMachine,
const Scenario_T& scenarioPath,
103 , m_movingDispatcher{stack}
105 this->setObjectName(
"MoveEventState");
106 using namespace Scenario::Command;
107 auto finalState =
new QFinalState{
this};
109 auto mainState =
new QState{
this};
111 auto pressed =
new QState{mainState};
112 auto released =
new QState{mainState};
114 auto onlyMoving =
new QState{mainState};
117 mainState->setInitialState(pressed);
118 released->addTransition(finalState);
124 score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
125 pressed, onlyMoving, *
this);
126 score::make_transition<ReleaseOnAnything_Transition>(pressed, finalState);
129 score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
130 onlyMoving, onlyMoving, *
this);
133 score::make_transition<ReleaseOnAnything_Transition>(onlyMoving, released);
138 QObject::connect(pressed, &QState::entered, [&]() {
139 auto& scenar = stateMachine.model();
140 auto evId{this->clickedEvent};
141 if(!
bool(evId) &&
bool(this->clickedState))
145 m_origPos.y = st.heightPercentage();
152 m_origPos.date = ev.date();
154 auto prev_csts = previousNonGraphIntervals(ev, scenar);
155 if(!prev_csts.empty())
159 for(
const auto& cst_id : prev_csts)
161 const auto& other_date = scenar.interval(cst_id).date();
168 this->m_pressedPrevious = t + TimeVal::fromMsecs(10);
172 this->m_pressedPrevious = std::nullopt;
175 this->m_pressPos = this->currentPoint;
178 QObject::connect(onlyMoving, &QState::entered, [&]() {
179 auto& scenar = stateMachine.model();
181 auto evId = this->clickedEvent;
182 if(!
bool(evId) &&
bool(this->clickedState))
184 evId = scenar.state(*this->clickedState).eventId();
191 = this->m_origPos.date + (this->currentPoint.date - this->m_pressPos.date);
192 m_lastDate = this->m_pressedPrevious
193 ? std::max(adjDate, *this->m_pressedPrevious)
196 auto [magPos, snap] = stateMachine.magnetic().getPosition(
197 &Scenario::parentTimeSync(*evId, stateMachine.model()), m_lastDate);
199 stateMachine.presenter().setSnapLine(magPos, snap);
201 m_lastDate = std::max(m_lastDate,
TimeVal{});
203 if(this->clickedState)
205 auto new_y = m_origPos.y + (this->currentPoint.y - this->m_pressPos.y);
206 this->m_movingDispatcher.template submit<MoveEventCommand_T>(
207 this->m_scenario, *evId, m_lastDate, new_y,
208 stateMachine.editionSettings().expandMode(),
209 stateMachine.editionSettings().lockMode(), *this->clickedState);
213 this->m_movingDispatcher.template submit<MoveEventCommand_T>(
214 this->m_scenario, *evId, m_lastDate, this->currentPoint.y,
215 stateMachine.editionSettings().expandMode(),
216 stateMachine.editionSettings().lockMode());
220 QObject::connect(released, &QState::entered, [&] {
221 if constexpr(std::is_same_v<Scenario::ToolPalette, ToolPalette_T>)
223 if(this->clickedState)
225 auto& st = this->m_scenario.state(*this->clickedState);
226 merge(st, this->m_lastDate);
230 m_movingDispatcher.template commit<Command::MoveStateMacro>();
231 this->m_pressPos = {};
232 this->m_pressedPrevious = {};
233 stateMachine.presenter().setSnapLine({},
false);
237 auto rollbackState =
new QState{
this};
238 score::make_transition<score::Cancel_Transition>(mainState, rollbackState);
239 rollbackState->addTransition(finalState);
240 QObject::connect(rollbackState, &QState::entered, [&] {
242 this->m_pressPos = {};
243 this->m_pressedPrevious = {};
244 stateMachine.presenter().setSnapLine({},
false);
247 this->setInitialState(mainState);
250 void rollback() { m_movingDispatcher.template rollback<DefaultRollbackStrategy>(); }
254 auto& ev = Scenario::parentEvent(st, this->m_scenario);
255 auto& ts = Scenario::parentTimeSync(ev, this->m_scenario);
259 std::vector<QGraphicsItem*> toIgnore;
260 toIgnore.push_back(sts_pres.view());
261 toIgnore.push_back(&sts_pres.trigger());
262 for(
auto& ev_id : sts_pres.model().events())
264 auto& ev = m_sm.presenter().event(ev_id);
265 toIgnore.push_back(ev.view());
266 for(
auto& st_id : ev.model().states())
268 auto& st = m_sm.presenter().state(st_id);
269 toIgnore.push_back(st.view());
273 for(
auto& itv : Scenario::previousIntervals(sts_pres.model(), this->m_scenario))
276 = m_sm.presenter().state(this->m_scenario.interval(itv).startState());
277 auto& sev_pres = m_sm.presenter().event(sst_pres.model().eventId());
279 = m_sm.presenter().timeSync(sev_pres.model().timeSync());
281 toIgnore.push_back(sts_pres.view());
282 for(
auto& ev : sts_pres.events())
284 toIgnore.push_back(ev->view());
285 for(
auto& st : ev->states())
287 toIgnore.push_back(st->view());
291 toIgnore.push_back(&sts_pres.trigger());
294 for(
auto& itv : Scenario::nextIntervals(sts_pres.model(), this->m_scenario))
296 auto& sst_pres = m_sm.presenter().state(this->m_scenario.interval(itv).endState());
297 auto& sev_pres = m_sm.presenter().event(sst_pres.model().eventId());
298 auto& sts_pres = m_sm.presenter().timeSync(sev_pres.model().timeSync());
300 toIgnore.push_back(sts_pres.view());
301 for(
auto& ev : sts_pres.events())
303 toIgnore.push_back(ev->view());
304 for(
auto& st : ev->states())
306 toIgnore.push_back(st->view());
310 toIgnore.push_back(&sts_pres.trigger());
313 QGraphicsItem* item = m_sm.itemAt({date, st.heightPercentage()}, toIgnore);
315 if(
auto stateToMerge = qgraphicsitem_cast<Scenario::StateView*>(item))
318 this->m_movingDispatcher.template submit<Command::MergeEvents>(
319 this->m_scenario, ev.id(),
320 Scenario::parentEvent(stateToMerge->presenter().model().id(), this->m_scenario)
323 else if(
auto eventToMerge = qgraphicsitem_cast<Scenario::EventView*>(item))
326 this->m_movingDispatcher.template submit<Command::MergeEvents>(
327 this->m_scenario, ev.id(), eventToMerge->presenter().model().id());
329 else if(
auto syncToMerge = qgraphicsitem_cast<Scenario::TimeSyncView*>(item))
332 this->m_movingDispatcher.template submit<Command::MergeTimeSyncs>(
333 this->m_scenario, ts.id(), syncToMerge->presenter().model().id());
337 const ToolPalette_T& m_sm;
341 std::optional<TimeVal> m_pressedPrevious;
343 bool m_startEventCanBeMerged{};
344 bool m_endEventCanBeMerged{};
The MultiOngoingCommandDispatcher class.
Definition: MultiOngoingCommandDispatcher.hpp:33
Definition: EventModel.hpp:36
Definition: MoveAndMergeState.hpp:95
Definition: ScenarioPaletteBaseStates.hpp:20
Definition: StateModel.hpp:63
Definition: TimeSyncPresenter.hpp:29
A small abstraction layer over the score::CommandStack.
Definition: CommandStackFacade.hpp:20
The ObjectLocker class.
Definition: ObjectLocker.hpp:21
Main plug-in of score.
Definition: score-plugin-dataflow/Dataflow/PortItem.hpp:14
Definition: ScenarioPoint.hpp:13
Definition: TimeValue.hpp:21