Commit fb9a4c2b authored by Maciej Suminski's avatar Maciej Suminski
Browse files

Added stacking for tools.

parent 424aa28e
Loading
Loading
Loading
Loading
+0 −5
Original line number Original line Diff line number Diff line
@@ -56,11 +56,6 @@ void TOOL_INTERACTIVE::goInternal( TOOL_STATE_FUNC& aState, const TOOL_EVENT_LIS
}
}




void TOOL_INTERACTIVE::Reset()
{
}


void TOOL_INTERACTIVE::SetContextMenu( CONTEXT_MENU* aMenu, TOOL_ContextMenuTrigger aTrigger )
void TOOL_INTERACTIVE::SetContextMenu( CONTEXT_MENU* aMenu, TOOL_ContextMenuTrigger aTrigger )
{
{
	aMenu->setTool( this );
	aMenu->setTool( this );
+58 −16
Original line number Original line Diff line number Diff line
@@ -92,24 +92,40 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool )
}
}




void TOOL_MANAGER::InvokeTool( TOOL_ID aToolId )
bool TOOL_MANAGER::InvokeTool( TOOL_ID aToolId )
{
{
    TOOL_BASE* tool = FindTool( aToolId );
    TOOL_BASE* tool = FindTool( aToolId );


    if( tool && tool->GetType() == TOOL_Interactive )
    if( tool && tool->GetType() == TOOL_Interactive )
    {
        // If the tool is already active, do not invoke it again
        if( m_toolIdIndex[aToolId]->idle == false )
            return false;

        m_toolIdIndex[aToolId]->idle = false;
        static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
        static_cast<TOOL_INTERACTIVE*>( tool )->Reset();


        TOOL_EVENT evt( TC_Command, TA_ActivateTool, tool->GetName() );
        TOOL_EVENT evt( TC_Command, TA_ActivateTool, tool->GetName() );
        ProcessEvent( evt );
        ProcessEvent( evt );

        // Save the tool on the front of the processing queue
        m_activeTools.push_front( aToolId );

        return true;
    }

    return false;
}
}




void TOOL_MANAGER::InvokeTool( const std::string& aName )
bool TOOL_MANAGER::InvokeTool( const std::string& aName )
{
{
    TOOL_BASE* tool = FindTool( aName );
    TOOL_BASE* tool = FindTool( aName );


    if( tool )
    if( tool )
        InvokeTool( tool->GetId() );
        return InvokeTool( tool->GetId() );

    return false;
}
}




@@ -159,13 +175,18 @@ optional<TOOL_EVENT> TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool,
void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
{
{
	// iterate over all registered tools
	// iterate over all registered tools
	BOOST_FOREACH( ToolState* st, m_toolState | boost::adaptors::map_values )
    BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
    {
    {
        ToolState* st = m_toolIdIndex[toolId];

		// the tool state handler is waiting for events (i.e. called Wait() method)
		// the tool state handler is waiting for events (i.e. called Wait() method)
		if( st->pendingWait )
		if( st->pendingWait )
		{
		{
			if( st->waitEvents.Matches( aEvent ) )
			if( st->waitEvents.Matches( aEvent ) )
			{
			{
			    // By default, already processed events are not passed further
			    m_passEvent = false;

				// got matching event? clear wait list and wake up the coroutine
				// got matching event? clear wait list and wake up the coroutine
				st->wakeupEvent = aEvent;
				st->wakeupEvent = aEvent;
				st->pendingWait = false;
				st->pendingWait = false;
@@ -173,16 +194,22 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
				st->cofunc->Resume();
				st->cofunc->Resume();
				if( !st->cofunc->Running() )
				if( !st->cofunc->Running() )
				{
				{
					delete st->cofunc;
				    finishTool( st );
					st->cofunc = NULL;
				}

				// The tool requested to stop propagating event to other tools
				if( !m_passEvent )
				    break;
			}
			}
		}
		}
    }
    }
		else

    BOOST_FOREACH( ToolState* st, m_toolState | boost::adaptors::map_values )
    {
		if( !st->pendingWait )
		{
		{
			// no state handler in progress - check if there are any transitions (defined by
			// no state handler in progress - check if there are any transitions (defined by
			// Go() method that match the event.
			// Go() method that match the event.

			if( st->transitions.size() )
			if( st->transitions.size() )
			{
			{
				BOOST_FOREACH( Transition tr, st->transitions )
				BOOST_FOREACH( Transition tr, st->transitions )
@@ -201,14 +228,25 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
						
						
						if( !st->cofunc->Running() )
						if( !st->cofunc->Running() )
						{
						{
							delete st->cofunc;
						    finishTool( st );
							st->cofunc = NULL;
						}
					}
					}
				}
				}
			}
			}
		}
		}
	}	
	}	
}
}


void TOOL_MANAGER::finishTool( ToolState* aState )
{
    wxASSERT( m_activeTools.front() == aState->theTool->GetId() );

    aState->idle = true;
    m_activeTools.erase( m_activeTools.begin() );

    delete aState->cofunc;
    aState->cofunc = NULL;
}
}




@@ -218,8 +256,10 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )


	dispatchInternal( aEvent );
	dispatchInternal( aEvent );
	
	
	BOOST_FOREACH( ToolState* st, m_toolState | boost::adaptors::map_values )
    BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
    {
    {
        ToolState* st = m_toolIdIndex[toolId];

		if( st->contextMenuTrigger == CMENU_NOW )
		if( st->contextMenuTrigger == CMENU_NOW )
		{
		{
			st->pendingWait = true;
			st->pendingWait = true;
@@ -273,8 +313,10 @@ void TOOL_MANAGER::SetEnvironment( EDA_ITEM* aModel, KiGfx::VIEW* aView,
	m_editFrame = aFrame;
	m_editFrame = aFrame;


	// Reset state of the registered tools
	// Reset state of the registered tools
	BOOST_FOREACH( TOOL_BASE* tool, m_toolState | boost::adaptors::map_keys )
	BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
	{
	{
	    TOOL_BASE* tool = m_toolIdIndex[toolId]->theTool;

	    if( tool->GetType() == TOOL_Interactive )
	    if( tool->GetType() == TOOL_Interactive )
	        static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
	        static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
	}
	}
+15 −4
Original line number Original line Diff line number Diff line
@@ -72,8 +72,8 @@ public:
     * Calls a tool by sending a tool activation event to tool of given ID or name.
     * Calls a tool by sending a tool activation event to tool of given ID or name.
     * An user-defined parameter object can be also passed
     * An user-defined parameter object can be also passed
     */
     */
    void InvokeTool( TOOL_ID aToolId );
    bool InvokeTool( TOOL_ID aToolId );
    void InvokeTool( const std::string& aName );
    bool InvokeTool( const std::string& aName );


    template <class Parameters>
    template <class Parameters>
        void InvokeTool( const std::string& aName, const Parameters& aToolParams );
        void InvokeTool( const std::string& aName, const Parameters& aToolParams );
@@ -153,20 +153,31 @@ public:
    void ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu,
    void ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu,
                              TOOL_ContextMenuTrigger aTrigger );
                              TOOL_ContextMenuTrigger aTrigger );


private:
    /**
    void dispatchInternal( TOOL_EVENT& aEvent );
     * Allows a tool pass the already handled event to be passed to the next tool on the stack.
     */
    void PassEvent()
    {
        m_passEvent = true;
    }


private:
    struct ToolState;
    struct ToolState;
    typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> Transition;
    typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> Transition;


    void dispatchInternal( TOOL_EVENT& aEvent );
    void finishTool( ToolState* aState );

    std::map<TOOL_BASE*, ToolState*> m_toolState;
    std::map<TOOL_BASE*, ToolState*> m_toolState;
    std::map<std::string, ToolState*> m_toolNameIndex;
    std::map<std::string, ToolState*> m_toolNameIndex;
    std::map<TOOL_ID, ToolState*> m_toolIdIndex;
    std::map<TOOL_ID, ToolState*> m_toolIdIndex;
    std::deque<TOOL_ID> m_activeTools;


    EDA_ITEM* m_model;
    EDA_ITEM* m_model;
    KiGfx::VIEW* m_view;
    KiGfx::VIEW* m_view;
    KiGfx::VIEW_CONTROLS* m_viewControls;
    KiGfx::VIEW_CONTROLS* m_viewControls;
    wxWindow* m_editFrame;
    wxWindow* m_editFrame;
    bool m_passEvent;


    ToolState* m_currentTool;
    ToolState* m_currentTool;
};
};