Added stacking for tools.
This commit is contained in:
parent
424aa28e1f
commit
fb9a4c2bfc
|
@ -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 );
|
||||||
|
|
|
@ -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,8 +228,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
if( !st->cofunc->Running() )
|
if( !st->cofunc->Running() )
|
||||||
{
|
{
|
||||||
delete st->cofunc;
|
finishTool( st );
|
||||||
st->cofunc = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,14 +238,28 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
|
bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
wxLogDebug( "event: %s", aEvent.Format().c_str() );
|
wxLogDebug( "event: %s", aEvent.Format().c_str() );
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue