CG::InteractionResult Dropdown::mouseButtonEvent(const MouseButtonEvent &ev) { CG::InteractionResult result; if (ev.eventType != MouseButtonEvent::PRESSED || ev.button != 0) { return result; } if (isActive()) { setActiveState(false); result.contolStateChanged = true; int currentSelection = _getSelectionLineAtLocation(ev.x, ev.y); if (currentSelection != NOTHING_SELECTED) { result.newDataAvailable = true; result.newControlState = _selectionOptions.at(currentSelection).id; result.newStateLabel = _selectionOptions.at(currentSelection).label; setSelectedOption(currentSelection); notifyCallback(); } } else { if (boundingBox.inside(ev.x, ev.y)) { setActiveState(true); result.contolStateChanged = true; } } return result; }
void TOOL_MANAGER::InitTools() { for( auto it = m_toolState.begin(); it != m_toolState.end(); /* iteration in the loop */ ) { TOOL_BASE* tool = it->first; TOOL_STATE* state = it->second; setActiveState( state ); ++it; // keep the iterator valid if the element is going to be erased if( !tool->Init() ) { wxMessageBox( wxString::Format( "Initialization of tool \"%s\" failed", tool->GetName() ) ); // Unregister the tool setActiveState( nullptr ); m_toolState.erase( tool ); m_toolNameIndex.erase( tool->GetName() ); m_toolIdIndex.erase( tool->GetId() ); m_toolTypes.erase( typeid( *tool ).name() ); delete state; delete tool; } } ResetTools( TOOL_BASE::RUN ); }
bool TOOL_MANAGER::runTool( TOOL_BASE* aTool ) { wxASSERT( aTool != NULL ); if( !isRegistered( aTool ) ) { wxASSERT_MSG( false, wxT( "You cannot run unregistered tools" ) ); return false; } TOOL_ID id = aTool->GetId(); if( aTool->GetType() == INTERACTIVE ) static_cast<TOOL_INTERACTIVE*>( aTool )->resetTransitions(); // If the tool is already active, bring it to the top of the active tools stack if( isActive( aTool ) ) { m_activeTools.erase( std::find( m_activeTools.begin(), m_activeTools.end(), id ) ); m_activeTools.push_front( id ); return false; } setActiveState( m_toolIdIndex[id] ); aTool->Reset( TOOL_INTERACTIVE::RUN ); // Add the tool on the front of the processing queue (it gets events first) m_activeTools.push_front( id ); return true; }
bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool ) { wxASSERT( aTool != NULL ); TOOL_EVENT evt( TC_COMMAND, TA_ACTIVATE, aTool->GetName() ); processEvent( evt ); if( TOOL_STATE* active = GetCurrentToolState() ) setActiveState( active ); return true; }
void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason ) { DeactivateTool(); for( auto& state : m_toolState ) { TOOL_BASE* tool = state.first; setActiveState( state.second ); tool->Reset( aReason ); if( tool->GetType() == INTERACTIVE ) static_cast<TOOL_INTERACTIVE*>( tool )->resetTransitions(); } }
/*! Removes \a state from this group. If \a state is the default state, the default state will be reset to 0. If \a state is the active state, the state will first be deactivated, and then removed from this group. The group will then revert to the default state, or 0 if there is no default state. The ownership of \a state is transferred to the caller (i.e., this function does not delete \a state). \sa defaultState(), activeState(), QtState::isActive() */ void QtStateGroup::removeState(QtState *state) { Q_D(QtStateGroup); if (state->group() != this) { qWarning("QtStateGroup::removeState: cannot remove state %p," " which is not part of this group %p", state, this); return; } d->states.removeAll(state); state->d_func()->group = 0; state->setParent(0); if (state == d->defaultState) d->defaultState = 0; if (state == d->activeState) setActiveState(0); }
/*! Adds \a state to this group. If \a state is already active, it will become this group's active state. The ownership of \a state is transferred to this group. \sa QtState::isActive(), activeState() */ void QtStateGroup::addState(QtState *state) { Q_D(QtStateGroup); if (!state) { qWarning("QtStateGroup::addState: cannot add null state"); return; } if (state->group() == this) return; if (QtStateGroup *other = state->group()) other->removeState(state); d->states << state; state->d_func()->group = this; state->setParent(this); if (state->isActive()) setActiveState(state); }
void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction, bool aNow, void* aParam ) { TOOL_EVENT event = aAction.MakeEvent(); // Allow to override the action parameter if( aParam ) event.SetParameter( aParam ); if( aNow ) { TOOL_STATE* current = m_activeState; processEvent( event ); setActiveState( current ); } else { PostEvent( event ); } }
bool TOOL_MANAGER::ProcessEvent( const TOOL_EVENT& aEvent ) { bool hotkey_handled = processEvent( aEvent ); if( TOOL_STATE* active = GetCurrentToolState() ) setActiveState( active ); if( m_view->IsDirty() ) { auto f = dynamic_cast<EDA_DRAW_FRAME*>( GetEditFrame() ); if( f ) f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER. #if defined( __WXMAC__ ) || defined( __WINDOWS__ ) wxTheApp->ProcessPendingEvents(); // required for updating brightening behind a popup menu #endif } return hotkey_handled; }
TOOL_MANAGER::ID_LIST::iterator TOOL_MANAGER::finishTool( TOOL_STATE* aState ) { auto it = std::find( m_activeTools.begin(), m_activeTools.end(), aState->theTool->GetId() ); if( !aState->Pop() ) { // Deactivate the tool if there are no other contexts saved on the stack if( it != m_activeTools.end() ) it = m_activeTools.erase( it ); aState->idle = true; } if( aState == m_activeState ) setActiveState( nullptr ); // Set transitions to be ready for future TOOL_EVENTs TOOL_BASE* tool = aState->theTool; if( tool->GetType() == INTERACTIVE ) static_cast<TOOL_INTERACTIVE*>( tool )->resetTransitions(); return it; }
void Application::initializeStates() { states["INTRO"] = new Intro(); setActiveState("INTRO"); }
void TOOL_MANAGER::dispatchInternal( const TOOL_EVENT& aEvent ) { // iterate over all registered tools for( auto it = m_activeTools.begin(); it != m_activeTools.end(); ++it ) { TOOL_STATE* st = m_toolIdIndex[*it]; // forward context menu events to the tool that created the menu if( aEvent.IsMenu() ) { if( *it != m_menuOwner ) continue; } // the tool state handler is waiting for events (i.e. called Wait() method) if( st->pendingWait ) { if( st->waitEvents.Matches( aEvent ) ) { // By default only messages are passed further m_passEvent = ( aEvent.Category() == TC_MESSAGE ); // got matching event? clear wait list and wake up the coroutine st->wakeupEvent = aEvent; st->pendingWait = false; st->waitEvents.clear(); if( st->cofunc ) { setActiveState( st ); bool end = !st->cofunc->Resume(); if( end ) it = finishTool( st ); } // If the tool did not request to propagate // the event to other tools, we should stop it now if( !m_passEvent ) break; } } } for( auto& state : m_toolState ) { TOOL_STATE* st = state.second; bool finished = false; // no state handler in progress - check if there are any transitions (defined by // Go() method that match the event. if( !st->transitions.empty() ) { for( TRANSITION& tr : st->transitions ) { if( tr.first.Matches( aEvent ) ) { auto func_copy = tr.second; // if there is already a context, then push it on the stack // and transfer the previous view control settings to the new context if( st->cofunc ) { auto vc = st->vcSettings; st->Push(); st->vcSettings = vc; } st->cofunc = new COROUTINE<int, const TOOL_EVENT&>( std::move( func_copy ) ); // as the state changes, the transition table has to be set up again st->transitions.clear(); // got match? Run the handler. setActiveState( st ); st->idle = false; st->cofunc->Call( aEvent ); if( !st->cofunc->Running() ) finishTool( st ); // The couroutine has finished immediately? // if it is a message, continue processing finished = !( aEvent.Category() == TC_MESSAGE ); // there is no point in further checking, as transitions got cleared break; } } } if( finished ) break; // only the first tool gets the event } }
void TOOL_MANAGER::RunMainStack( TOOL_BASE* aTool, std::function<void()> aFunc ) { TOOL_STATE* st = m_toolState[aTool]; setActiveState( st ); st->cofunc->RunMainStack( std::move( aFunc ) ); }
Dropdown::Dropdown(void) : _currentSelectionIndex(NOTHING_SELECTED), _highlightedSelectionIndex(NOTHING_SELECTED) { setActiveState(false); }