ToolPaletteInputDispatcher( const Input_T& input, ToolPalette_T& palette, Context_T& context): m_palette{palette}, m_context{context}, m_currentTool{palette.editionSettings().tool()} { auto screens = QApplication::screens(); if(!screens.empty()) { m_frameTime = 1000000. / screens.front()->refreshRate(); } using EditionSettings_T = std::remove_reference_t<decltype(palette.editionSettings())>; con(palette.editionSettings(), &EditionSettings_T::toolChanged, this, &ToolPaletteInputDispatcher::on_toolChanged); con(input, &Input_T::pressed, this, &ToolPaletteInputDispatcher::on_pressed); con(input, &Input_T::moved, this, &ToolPaletteInputDispatcher::on_moved); con(input, &Input_T::released, this, &ToolPaletteInputDispatcher::on_released); con(input, &Input_T::escPressed, this, &ToolPaletteInputDispatcher::on_cancel); con(m_elapsedTimer, &QTimer::timeout, this, &ToolPaletteInputDispatcher::on_moved_from_timer); }
static void make(const ToolPalette_T& palette, QState* waitState, QState& parent) { auto moveBrace = new MoveConstraintBraceState<Scenario::Command::SetMaxDuration, Scenario_T, ToolPalette_T>{ palette, palette.model(), palette.context().commandStack, palette.context().objectLocker, &parent}; iscore::make_transition<ClickOnRightBrace_Transition<Scenario_T>>(waitState, moveBrace, *moveBrace); moveBrace->addTransition(moveBrace, finishedState(), waitState); }
static void make(const ToolPalette_T& palette, QState* waitState, QState& parent) { /// TimeNode auto moveTimeNode = new MoveTimeNodeState<Scenario::Command::MoveEventMeta, Scenario_T, ToolPalette_T>{ palette, palette.model(), palette.context().commandStack, palette.context().objectLocker, &parent}; iscore::make_transition<ClickOnTimeNode_Transition<Scenario_T>>(waitState, moveTimeNode, *moveTimeNode); moveTimeNode->addTransition(moveTimeNode, finishedState(), waitState); }
static void make(const ToolPalette_T& palette, QState* waitState, QState& parent) { /// Constraint /// //TODO remove useless arguments to ctor auto moveConstraint = new MoveConstraintState<Scenario::Command::MoveConstraint, Scenario_T, ToolPalette_T>{ palette, palette.model(), palette.context().commandStack, palette.context().objectLocker, &parent}; iscore::make_transition<ClickOnConstraint_Transition<Scenario_T>>(waitState, moveConstraint, *moveConstraint); moveConstraint->addTransition(moveConstraint, finishedState(), waitState); }
Creation_FromTimeSync( const ToolPalette_T& stateMachine, const Scenario_T& scenarioPath, const score::CommandStackFacade& stack, QState* parent) : CreationState<Scenario_T, ToolPalette_T>{stateMachine, stack, std::move(scenarioPath), parent} { using namespace Scenario::Command; auto finalState = new QFinalState{this}; QObject::connect( finalState, &QState::entered, [&]() { this->clearCreatedIds(); }); auto mainState = new QState{this}; { auto pressed = new QState{mainState}; auto released = new QState{mainState}; auto move_nothing = new StrongQState<MoveOnNothing>{mainState}; auto move_state = new StrongQState<MoveOnState>{mainState}; auto move_event = new StrongQState<MoveOnEvent>{mainState}; auto move_timesync = new StrongQState<MoveOnTimeSync>{mainState}; // General setup mainState->setInitialState(pressed); released->addTransition(finalState); // Release score::make_transition<ReleaseOnAnything_Transition>( mainState, released); // Pressed -> ... auto t_pressed_moving_nothing = score::make_transition<MoveOnNothing_Transition<Scenario_T>>( pressed, move_nothing, *this); QObject::connect( t_pressed_moving_nothing, &QAbstractTransition::triggered, [&]() { this->rollback(); createToNothing(); }); /// MoveOnNothing -> ... // MoveOnNothing -> MoveOnNothing. score::make_transition<MoveOnNothing_Transition<Scenario_T>>( move_nothing, move_nothing, *this); // MoveOnNothing -> MoveOnState. this->add_transition(move_nothing, move_state, [&]() { this->rollback(); SCORE_TODO; }); // MoveOnNothing -> MoveOnEvent. this->add_transition(move_nothing, move_event, [&]() { if (this->hoveredEvent && this->createdEvents.contains(*this->hoveredEvent)) { return; } this->rollback(); createToEvent(); }); // MoveOnNothing -> MoveOnTimeSync this->add_transition(move_nothing, move_timesync, [&]() { if (this->hoveredTimeSync && this->createdTimeSyncs.contains(*this->hoveredTimeSync)) { return; } this->rollback(); createToTimeSync(); }); /// MoveOnState -> ... // MoveOnState -> MoveOnNothing this->add_transition(move_state, move_nothing, [&]() { this->rollback(); SCORE_TODO; }); // MoveOnState -> MoveOnState // We don't do anything, the interval should not move. // MoveOnState -> MoveOnEvent this->add_transition(move_state, move_event, [&]() { this->rollback(); SCORE_TODO; }); // MoveOnState -> MoveOnTimeSync this->add_transition(move_state, move_timesync, [&]() { this->rollback(); SCORE_TODO; }); /// MoveOnEvent -> ... // MoveOnEvent -> MoveOnNothing this->add_transition(move_event, move_nothing, [&]() { this->rollback(); createToNothing(); }); // MoveOnEvent -> MoveOnState this->add_transition(move_event, move_state, [&]() { this->rollback(); SCORE_TODO; }); // MoveOnEvent -> MoveOnEvent score::make_transition<MoveOnEvent_Transition<Scenario_T>>( move_event, move_event, *this); // MoveOnEvent -> MoveOnTimeSync this->add_transition(move_event, move_timesync, [&]() { if (this->hoveredTimeSync && this->createdTimeSyncs.contains(*this->hoveredTimeSync)) { return; } this->rollback(); createToTimeSync(); }); /// MoveOnTimeSync -> ... // MoveOnTimeSync -> MoveOnNothing this->add_transition(move_timesync, move_nothing, [&]() { this->rollback(); createToNothing(); }); // MoveOnTimeSync -> MoveOnState this->add_transition(move_timesync, move_state, [&]() { this->rollback(); SCORE_TODO; }); // MoveOnTimeSync -> MoveOnEvent this->add_transition(move_timesync, move_event, [&]() { if (this->hoveredEvent && this->createdEvents.contains(*this->hoveredEvent)) { this->rollback(); return; } this->rollback(); createToEvent(); }); // MoveOnTimeSync -> MoveOnTimeSync score::make_transition<MoveOnTimeSync_Transition<Scenario_T>>( move_timesync, move_timesync, *this); // What happens in each state. QObject::connect(pressed, &QState::entered, [&]() { this->m_clickedPoint = this->currentPoint; createInitialEventAndState(); }); QObject::connect(move_nothing, &QState::entered, [&]() { if (this->createdEvents.empty() || this->createdIntervals.empty()) { this->rollback(); return; } if (this->currentPoint.date <= this->m_clickedPoint.date) { this->currentPoint.date = this->m_clickedPoint.date + TimeVal::fromMsecs(10); ; } // Move the timesync this->m_dispatcher.template submit<MoveNewEvent>( this->m_scenario, this->createdIntervals.last(), this->createdEvents.last(), this->currentPoint.date, this->currentPoint.y, stateMachine.editionSettings().sequence()); }); QObject::connect(move_timesync, &QState::entered, [&]() { if (this->createdEvents.empty()) { this->rollback(); return; } if (this->currentPoint.date <= this->m_clickedPoint.date) { return; } this->m_dispatcher.template submit<MoveEventMeta>( this->m_scenario, this->createdEvents.last(), TimeVal::zero(), 0., stateMachine.editionSettings().expandMode(), LockMode::Free); }); QObject::connect( released, &QState::entered, this, &Creation_FromTimeSync::commit); } auto rollbackState = new QState{this}; score::make_transition<score::Cancel_Transition>(mainState, rollbackState); rollbackState->addTransition(finalState); QObject::connect( rollbackState, &QState::entered, this, &Creation_FromTimeSync::rollback); this->setInitialState(mainState); }
ToolBase(const ToolPalette_T& palette) : GraphicsSceneTool<Scenario::Point>{palette.scene()}, m_palette{palette} { }
MoveEventState(const ToolPalette_T& stateMachine, const Path<Scenario_T>& scenarioPath, const iscore::CommandStackFacade& stack, iscore::ObjectLocker& locker, QState* parent): StateBase<Scenario_T>{scenarioPath, parent}, m_movingDispatcher{stack} { this->setObjectName("MoveEventState"); using namespace Scenario::Command ; auto finalState = new QFinalState{this}; auto mainState = new QState{this}; { auto pressed = new QState{mainState}; auto released = new QState{mainState}; auto onlyMoving = new QState{mainState}; // General setup mainState->setInitialState(pressed); released->addTransition(finalState); // *************************************** // transitions // press iscore::make_transition<MoveOnAnything_Transition<Scenario_T>>( pressed, onlyMoving, *this); iscore::make_transition<ReleaseOnAnything_Transition>( pressed, finalState); // update commands iscore::make_transition<MoveOnAnything_Transition<Scenario_T>>( onlyMoving, onlyMoving, *this); // commit merging iscore::make_transition<ReleaseOnAnything_Transition>( onlyMoving, released); // ******************************************** // What happens in each state. QObject::connect(onlyMoving, &QState::entered, [&] () { auto& scenar = stateMachine.model(); // If we came here through a state. Id<EventModel> evId{this->clickedEvent}; if(!bool(evId) && bool(this->clickedState)) { evId = scenar.state(this->clickedState).eventId(); } TimeValue date = this->m_pressedPrevious ? max(this->currentPoint.date, *this->m_pressedPrevious) : this->currentPoint.date; this->m_movingDispatcher.submitCommand( Path<Scenario_T>{this->m_scenarioPath}, evId, date, this->currentPoint.y, stateMachine.editionSettings().expandMode() ); }); QObject::connect(pressed, &QState::entered, [&] () { auto& scenar = stateMachine.model(); Id<EventModel> evId{this->clickedEvent}; if(!bool(evId) && bool(this->clickedState)) { evId = scenar.state(this->clickedState).eventId(); } auto prev_csts = previousConstraints(scenar.event(evId), scenar); if(!prev_csts.empty()) { // We find the one that starts the latest. TimeValue t = TimeValue::zero(); for(const auto& cst_id : prev_csts) { const auto& other_date = scenar.constraint(cst_id).startDate(); if(other_date > t) t = other_date; } // These 10 milliseconds are here to prevent "squashing" // processes to zero, which leads to problem (they can't scale back!) this->m_pressedPrevious = t + TimeValue::fromMsecs(10); } else { this->m_pressedPrevious = iscore::none; } }); QObject::connect(released, &QState::entered, [&] () { m_movingDispatcher.commit(); }); } auto rollbackState = new QState{this}; iscore::make_transition<iscore::Cancel_Transition>(mainState, rollbackState); rollbackState->addTransition(finalState); QObject::connect(rollbackState, &QState::entered, [&] () { m_movingDispatcher.rollback(); }); this->setInitialState(mainState); }