CreationToolState.hpp
1 #pragma once
2 #include "ScenarioToolState.hpp"
3 
4 #include <Scenario/Document/Event/EventModel.hpp>
5 #include <Scenario/Document/Event/EventPresenter.hpp>
6 #include <Scenario/Document/Event/EventView.hpp>
7 #include <Scenario/Document/TimeSync/TimeSyncModel.hpp>
8 #include <Scenario/Document/TimeSync/TimeSyncPresenter.hpp>
9 #include <Scenario/Document/TimeSync/TimeSyncView.hpp>
10 #include <Scenario/Palette/ScenarioPaletteBaseStates.hpp>
11 #include <Scenario/Palette/Tools/ScenarioToolState.hpp>
12 #include <Scenario/Palette/Tools/States/ScenarioCreation_FromEvent.hpp>
13 #include <Scenario/Palette/Tools/States/ScenarioCreation_FromNothing.hpp>
14 #include <Scenario/Palette/Tools/States/ScenarioCreation_FromState.hpp>
15 #include <Scenario/Palette/Tools/States/ScenarioCreation_FromTimeSync.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 
21 #include <score/document/DocumentInterface.hpp>
22 #include <score/statemachine/StateMachineTools.hpp>
23 
24 namespace Scenario
25 {
26 
27 template <typename Scenario_T, typename ToolPalette_T>
28 class CreationTool final : public ToolBase<ToolPalette_T>
29 {
30 public:
31  CreationTool(ToolPalette_T& sm)
33  {
34  m_waitState = new QState;
35  this->localSM().addState(m_waitState);
36  this->localSM().setInitialState(m_waitState);
37 
39  m_createFromNothingState = new Creation_FromNothing<Scenario_T, ToolPalette_T>{
40  this->m_palette, this->m_palette.model(),
41  this->m_palette.context().context.commandStack, nullptr};
42 
43  score::make_transition<ClickOnNothing_Transition<Scenario_T>>(
44  m_waitState, m_createFromNothingState, *m_createFromNothingState);
45  m_createFromNothingState->addTransition(
46  m_createFromNothingState, finishedState(), m_waitState);
47 
48  this->localSM().addState(m_createFromNothingState);
49 
51  m_createFromEventState = new Creation_FromEvent<Scenario_T, ToolPalette_T>{
52  this->m_palette, this->m_palette.model(),
53  this->m_palette.context().context.commandStack, nullptr};
54 
55  score::make_transition<ClickOnEvent_Transition<Scenario_T>>(
56  m_waitState, m_createFromEventState, *m_createFromEventState);
57  m_createFromEventState->addTransition(
58  m_createFromEventState, finishedState(), m_waitState);
59 
60  this->localSM().addState(m_createFromEventState);
61 
63  m_createFromTimeSyncState = new Creation_FromTimeSync<Scenario_T, ToolPalette_T>{
64  this->m_palette, this->m_palette.model(),
65  this->m_palette.context().context.commandStack, nullptr};
66 
67  score::make_transition<ClickOnTimeSync_Transition<Scenario_T>>(
68  m_waitState, m_createFromTimeSyncState, *m_createFromTimeSyncState);
69  m_createFromTimeSyncState->addTransition(
70  m_createFromTimeSyncState, finishedState(), m_waitState);
71 
72  this->localSM().addState(m_createFromTimeSyncState);
73 
75  m_createFromStateState = new Creation_FromState<Scenario_T, ToolPalette_T>{
76  this->m_palette, this->m_palette.model(),
77  this->m_palette.context().context.commandStack, nullptr};
78 
79  score::make_transition<ClickOnState_Transition<Scenario_T>>(
80  m_waitState, m_createFromStateState, *m_createFromStateState);
81 
82  m_createFromStateState->addTransition(
83  m_createFromStateState, finishedState(), m_waitState);
84 
85  this->localSM().addState(m_createFromStateState);
86 
87  this->localSM().start();
88  }
89 
90  void on_pressed(QPointF scene, Scenario::Point sp)
91  {
92  this->mapTopItem(
93  this->itemUnderMouse(scene),
94 
95  // Press a state
96  [&](const Id<StateModel>& id) {
97  this->localSM().postEvent(new ClickOnState_Event{id, sp});
98  },
99 
100  // Press an event
101  [&](const Id<EventModel>& id) {
102  this->localSM().postEvent(new ClickOnEvent_Event{id, sp});
103  },
104 
105  // Press a TimeSync
106  [&](const Id<TimeSyncModel>& id) {
107  this->localSM().postEvent(new ClickOnTimeSync_Event{id, sp});
108  },
109 
110  // Press a Interval
111  [&](const Id<IntervalModel>&) {},
112  // Press a Brace (left)
113  [&](const Id<IntervalModel>&) {},
114  // (right)
115  [&](const Id<IntervalModel>&) {},
116 
117  // Press a slot handle
118  [&](const SlotPath&) {},
119 
120  // Click on the background
121  [&]() {
122  // Here we have the logic for the creation in nothing
123  // where we instead choose the latest state if selected
124  if(auto state = furthestSelectedState(this->m_palette.model()))
125  {
126  if(this->m_palette.model().events.at(state->eventId()).date() < sp.date)
127  {
128  this->localSM().postEvent(new ClickOnState_Event{state->id(), sp});
129  return;
130  }
131  }
132 
133  this->localSM().postEvent(new ClickOnNothing_Event{sp});
134  });
135  }
136  void on_moved(QPointF scene, Scenario::Point sp)
137  {
138  if(auto cs = currentState())
139  {
140  mapWithCollision(
141  scene,
142  [&](const Id<StateModel>& id) {
143  this->localSM().postEvent(new MoveOnState_Event{id, sp});
144  },
145  [&](const Id<EventModel>& id) {
146  this->localSM().postEvent(new MoveOnEvent_Event{id, sp});
147  },
148  [&](const Id<TimeSyncModel>& id) {
149  this->localSM().postEvent(new MoveOnTimeSync_Event{id, sp});
150  }, [&]() { this->localSM().postEvent(new MoveOnNothing_Event{sp}); },
151  cs->createdStates, cs->createdEvents, cs->createdTimeSyncs);
152  }
153  }
154  void on_released(QPointF scene, Scenario::Point sp)
155  {
156  if(auto cs = currentState())
157  {
158  mapWithCollision(
159  scene,
160  [&](const Id<StateModel>& id) {
161  this->localSM().postEvent(new ReleaseOnState_Event{id, sp});
162  },
163  [&](const Id<EventModel>& id) {
164  this->localSM().postEvent(new ReleaseOnEvent_Event{id, sp});
165  },
166  [&](const Id<TimeSyncModel>& id) {
167  this->localSM().postEvent(new ReleaseOnTimeSync_Event{id, sp});
168  }, [&]() { this->localSM().postEvent(new ReleaseOnNothing_Event{sp}); },
169  cs->createdStates, cs->createdEvents, cs->createdTimeSyncs);
170  }
171  }
172 
173 private:
174  // Return the colliding elements that were not created in the current
175  // commands
176  QList<Id<StateModel>>
177  getCollidingStates(QPointF point, const QVector<Id<StateModel>>& createdStates)
178  {
179  return getCollidingModels(
180  this->m_palette.presenter().getStates(), createdStates, point);
181  }
182  QList<Id<EventModel>>
183  getCollidingEvents(QPointF point, const QVector<Id<EventModel>>& createdEvents)
184  {
185  return getCollidingModels(
186  this->m_palette.presenter().getEvents(), createdEvents, point);
187  }
188  QList<Id<TimeSyncModel>> getCollidingTimeSyncs(
189  QPointF point, const QVector<Id<TimeSyncModel>>& createdTimeSyncs)
190  {
191  return getCollidingModels(
192  this->m_palette.presenter().getTimeSyncs(), createdTimeSyncs, point);
193  }
194 
195  CreationState<Scenario_T, ToolPalette_T>* currentState() const
196  {
197  if(isStateActive(m_createFromEventState))
198  return m_createFromEventState;
199  else if(isStateActive(m_createFromNothingState))
200  return m_createFromNothingState;
201  else if(isStateActive(m_createFromStateState))
202  return m_createFromStateState;
203  else if(isStateActive(m_createFromTimeSyncState))
204  return m_createFromTimeSyncState;
205  else
206  return nullptr;
207  }
208 
209  template <
210  typename StateFun, typename EventFun, typename TimeSyncFun, typename NothingFun>
211  void mapWithCollision(
212  QPointF point, StateFun st_fun, EventFun ev_fun, TimeSyncFun tn_fun,
213  NothingFun nothing_fun, const QVector<Id<StateModel>>& createdStates,
214  const QVector<Id<EventModel>>& createdEvents,
215  const QVector<Id<TimeSyncModel>>& createdTimeSyncs)
216  {
217  auto collidingStates = getCollidingStates(point, createdStates);
218  if(!collidingStates.empty())
219  {
220  st_fun(collidingStates.first());
221  return;
222  }
223 
224  auto collidingEvents = getCollidingEvents(point, createdEvents);
225  if(!collidingEvents.empty())
226  {
227  ev_fun(collidingEvents.first());
228  return;
229  }
230 
231  auto collidingTimeSyncs = getCollidingTimeSyncs(point, createdTimeSyncs);
232  if(!collidingTimeSyncs.empty())
233  {
234  tn_fun(collidingTimeSyncs.first());
235  return;
236  }
237 
238  nothing_fun();
239  }
240 
241  Creation_FromNothing<Scenario_T, ToolPalette_T>* m_createFromNothingState{};
242  Creation_FromEvent<Scenario_T, ToolPalette_T>* m_createFromEventState{};
243  Creation_FromTimeSync<Scenario_T, ToolPalette_T>* m_createFromTimeSyncState{};
244  Creation_FromState<Scenario_T, ToolPalette_T>* m_createFromStateState{};
245  QState* m_waitState{};
246 };
247 }
Definition: ScenarioCreation_FromEvent.hpp:22
Definition: ScenarioCreation_FromNothing.hpp:23
Definition: ScenarioCreation_FromState.hpp:26
Definition: ScenarioCreation_FromTimeSync.hpp:22
Definition: ScenarioCreationState.hpp:66
Definition: CreationToolState.hpp:29
Definition: ScenarioToolState.hpp:49
The id_base_t class.
Definition: Identifier.hpp:57
Main plug-in of score.
Definition: score-plugin-dataflow/Dataflow/PortItem.hpp:14
Definition: ScenarioPoint.hpp:13
Definition: ScenarioPaletteBaseEvents.hpp:43
Definition: ScenarioPaletteBaseEvents.hpp:53
Definition: Slot.hpp:54