Loading...
Searching...
No Matches
score-plugin-scenario/Scenario/Palette/Tools/SmartTool.hpp
1#pragma once
2#include <Scenario/Palette/Tools/ScenarioToolState.hpp>
3#include <Scenario/Palette/Tools/StateSelection.hpp>
4#include <Scenario/Palette/Tools/States/ResizeSlotState.hpp>
5#include <Scenario/Palette/Tools/States/ScenarioSelectionState.hpp>
6#include <Scenario/Palette/Transitions/IntervalTransitions.hpp>
7#include <Scenario/Palette/Transitions/SlotTransitions.hpp>
8#include <Scenario/Palette/Transitions/StateTransitions.hpp>
9#include <Scenario/Process/Algorithms/StandardDisplacementPolicy.hpp>
10
11#include <score/selection/SelectionDispatcher.hpp>
12
13namespace Scenario
14{
15class ToolPalette;
16
17// TODO Generic smart tool with variadic...
18template <
19 typename Scenario_T, typename ToolPalette_T, typename View_T,
20 typename MoveIntervalWrapper_T, typename MoveLeftBraceWrapper_T,
21 typename MoveRightBraceWrapper_T, typename MoveEventWrapper_T,
22 typename MoveTimeSyncWrapper_T>
23class SmartTool final : public ToolBase<ToolPalette_T>
24{
25public:
26 SmartTool(ToolPalette_T& sm)
27 : ToolBase<ToolPalette_T>{sm}
28 {
29 auto sub = new QState{&this->localSM()};
30 sub->setChildMode(QState::ParallelStates);
31
32 // Selection
33 m_state = new SelectionState<ToolPalette_T, View_T>{
34 this->m_palette.context().context.selectionStack, this->m_palette,
35 this->m_palette.presenter().view(), sub};
36
37 this->localSM().setInitialState(sub);
38
39 // Other actions; they are in //.
40 auto actionsState = new QState(sub);
41 {
42 auto waitState = new QState(actionsState);
43 actionsState->setInitialState(waitState);
44
45 auto mov_i = MoveIntervalWrapper_T::template make<Scenario_T, ToolPalette_T>(
46 this->m_palette, waitState, *actionsState);
47 auto mov_lb = MoveLeftBraceWrapper_T::template make<Scenario_T, ToolPalette_T>(
48 this->m_palette, waitState, *actionsState);
49 auto mov_rb = MoveRightBraceWrapper_T::template make<Scenario_T, ToolPalette_T>(
50 this->m_palette, waitState, *actionsState);
51 auto mov_e = MoveEventWrapper_T::template make<Scenario_T, ToolPalette_T>(
52 this->m_palette, waitState, *actionsState);
53 auto mov_ts = MoveTimeSyncWrapper_T::template make<Scenario_T, ToolPalette_T>(
54 this->m_palette, waitState, *actionsState);
55
56 if constexpr(!std::is_same_v<decltype(mov_i), std::nullptr_t>)
57 {
58 score::make_transition<ClickOnState_Transition<Scenario_T>>(
59 mov_i, mov_e, *mov_e);
60 score::make_transition<ClickOnState_Transition<Scenario_T>>(
61 mov_ts, mov_e, *mov_e);
62 score::make_transition<ClickOnState_Transition<Scenario_T>>(
63 mov_lb, mov_e, *mov_e);
64 score::make_transition<ClickOnState_Transition<Scenario_T>>(
65 mov_rb, mov_e, *mov_e);
66
67 score::make_transition<ClickOnInterval_Transition<Scenario_T>>(
68 mov_ts, mov_i, *mov_i);
69 score::make_transition<ClickOnInterval_Transition<Scenario_T>>(
70 mov_e, mov_i, *mov_i);
71 score::make_transition<ClickOnInterval_Transition<Scenario_T>>(
72 mov_lb, mov_i, *mov_i);
73 score::make_transition<ClickOnInterval_Transition<Scenario_T>>(
74 mov_rb, mov_i, *mov_i);
75 }
77 auto resizeSlot = new ResizeSlotState<Scenario_T, ToolPalette_T>{
78 this->m_palette.context().context.commandStack, this->m_palette, actionsState};
79
80 score::make_transition<ClickOnSlotHandle_Transition>(
81 waitState, resizeSlot, *resizeSlot);
82
83 resizeSlot->addTransition(resizeSlot, finishedState(), waitState);
84 }
85
86 this->localSM().start();
87 }
88
89 void on_pressed(QPointF scene, Scenario::Point sp)
90 {
91 using namespace std;
92
93 this->mapTopItem(
94 this->itemUnderMouse(scene),
95 [&](const Id<StateModel>& id) // State
96 {
97 const auto& elt = this->m_palette.presenter().state(id);
98
99 Selection sel;
100 doStateSelection(sel, elt.model(), this->m_palette.model());
101
102 m_state->dispatcher.select(filterSelections(
103 sel, this->m_palette.model().selectedChildren(), m_state->multiSelection()));
104
105 this->localSM().postEvent(new ClickOnState_Event{id, sp});
106 m_nothingPressed = false;
107 },
108 [&](const Id<EventModel>& id) // Event
109 {
110 const auto& elt = this->m_palette.presenter().event(id);
111
112 m_state->dispatcher.select(filterSelections(
113 &elt.model(), this->m_palette.model().selectedChildren(),
114 m_state->multiSelection()));
115
116 this->localSM().postEvent(new ClickOnEvent_Event{id, sp});
117 m_nothingPressed = false;
118 },
119 [&](const Id<TimeSyncModel>& id) // TimeSync
120 {
121 const auto& elt = this->m_palette.presenter().timeSync(id);
122
123 m_state->dispatcher.select(filterSelections(
124 &elt.model(), this->m_palette.model().selectedChildren(),
125 m_state->multiSelection()));
126 this->localSM().postEvent(new ClickOnTimeSync_Event{id, sp});
127 m_nothingPressed = false;
128 },
129 [&](const Id<IntervalModel>& id) // Interval
130 {
131 const auto& model = this->m_palette.model().interval(id);
132
133 if(!model.selection.get())
134 {
135 m_state->dispatcher.select(filterSelections(
136 &model, this->m_palette.model().selectedChildren(),
137 m_state->multiSelection()));
138 }
139 this->localSM().postEvent(new ClickOnInterval_Event{id, sp});
140 m_nothingPressed = false;
141 },
142 [&](const Id<IntervalModel>& id) // LeftBrace
143 {
144 const auto& elt = this->m_palette.presenter().interval(id);
145
146 if(!elt.isSelected())
147 {
148 m_state->dispatcher.select(filterSelections(
149 &elt.model(), this->m_palette.model().selectedChildren(),
150 m_state->multiSelection()));
151 }
152
153 this->localSM().postEvent((new ClickOnLeftBrace_Event{id, sp}));
154 m_nothingPressed = false;
155 },
156 [&](const Id<IntervalModel>& id) // RightBrace
157 {
158 const auto& elt = this->m_palette.presenter().interval(id);
159
160 if(!elt.isSelected())
161 {
162 m_state->dispatcher.select(filterSelections(
163 &elt.model(), this->m_palette.model().selectedChildren(),
164 m_state->multiSelection()));
165 }
166
167 this->localSM().postEvent((new ClickOnRightBrace_Event{id, sp}));
168 m_nothingPressed = false;
169 },
170 [&](const SlotPath& slot) // Slot handle
171 {
172 this->localSM().postEvent(new ClickOnSlotHandle_Event{slot});
173 m_nothingPressed = false;
174 },
175 [&]() {
176 this->localSM().postEvent(new score::Press_Event);
177 m_nothingPressed = true;
178 });
179
180 m_moved = false;
181 }
182
183 void on_moved(QPointF scene, Scenario::Point sp)
184 {
185 if(m_nothingPressed)
186 {
187 this->localSM().postEvent(new score::Move_Event);
188 }
189 else
190 {
191 m_moved = true;
192 this->mapTopItem(
193 this->itemUnderMouse(scene),
194 [&](const Id<StateModel>& id) {
195 this->localSM().postEvent(new MoveOnState_Event{id, sp});
196 }, // state
197 [&](const Id<EventModel>& id) {
198 this->localSM().postEvent(new MoveOnEvent_Event{id, sp});
199 }, // event
200 [&](const Id<TimeSyncModel>& id) {
201 this->localSM().postEvent(new MoveOnTimeSync_Event{id, sp});
202 }, // timesync
203 [&](const Id<IntervalModel>& id) {
204 this->localSM().postEvent(new MoveOnInterval_Event{id, sp});
205 }, // interval
206 [&](const Id<IntervalModel>& id) {
207 this->localSM().postEvent(new MoveOnLeftBrace_Event{id, sp});
208 }, // LeftBrace
209 [&](const Id<IntervalModel>& id) {
210 this->localSM().postEvent(new MoveOnRightBrace_Event{id, sp});
211 }, // RightBrace
212 [&](const SlotPath& slot) {
213 this->localSM().postEvent(new MoveOnSlotHandle_Event{slot});
214 }, // Slot handle
215 [&]() { this->localSM().postEvent(new MoveOnNothing_Event{sp}); });
216 }
217 }
218
219 void on_released(QPointF scene, Scenario::Point sp)
220 {
221 if(m_nothingPressed)
222 {
223 this->localSM().postEvent(new score::Release_Event); // select
224 m_nothingPressed = false;
225
226 return;
227 }
228 if(m_moved) // then don't change selection
229 {
230 this->localSM().postEvent(new ReleaseOnNothing_Event{sp});
231 m_nothingPressed = false;
232
233 return;
234 }
235
236 this->mapTopItem(
237 this->itemUnderMouse(scene),
238 [&](const Id<StateModel>& id) // State
239 {
240 this->localSM().postEvent(new ReleaseOnState_Event{id, sp});
241 },
242 [&](const Id<EventModel>& id) // Event
243 {
244 this->localSM().postEvent(new ReleaseOnEvent_Event{id, sp});
245 },
246 [&](const Id<TimeSyncModel>& id) // TimeSync
247 {
248 this->localSM().postEvent(new ReleaseOnTimeSync_Event{id, sp});
249 },
250 [&](const Id<IntervalModel>& id) // Interval
251 {
252 this->localSM().postEvent(new ReleaseOnInterval_Event{id, sp});
253 },
254 [&](const Id<IntervalModel>& id) // LeftBrace
255 {
256 this->localSM().postEvent(new ReleaseOnLeftBrace_Event{id, sp});
257 },
258 [&](const Id<IntervalModel>& id) // RightBrace
259 {
260 this->localSM().postEvent(new ReleaseOnRightBrace_Event{id, sp});
261 },
262 [&](const SlotPath& slot) // Slot handle
263 { this->localSM().postEvent(new ReleaseOnSlotHandle_Event{slot}); },
264 [&]() {
265 this->localSM().postEvent(new ReleaseOnNothing_Event{sp}); // end of move
266 });
267 }
268
269 void on_cancel() override { GraphicsSceneTool<Point>::on_cancel(); }
270
271 auto& selectionState() const { return *m_state; }
272
273private:
274 SelectionState<ToolPalette_T, View_T>* m_state{};
275
276 bool m_nothingPressed{true};
277 bool m_moved{false};
278};
279}
Definition GraphicsSceneTool.hpp:11
Definition score-plugin-scenario/Scenario/Palette/Tools/SmartTool.hpp:24
SmartTool(ToolPalette_T &sm)
Definition score-plugin-scenario/Scenario/Palette/Tools/SmartTool.hpp:26
Definition ScenarioToolState.hpp:49
Definition Selection.hpp:12
The id_base_t class.
Definition Identifier.hpp:57
Main plug-in of score.
Definition score-plugin-dataflow/Dataflow/PortItem.hpp:13
STL namespace.
Definition ScenarioPoint.hpp:13
Definition StateMachineUtils.hpp:18