Even more code comments and reformatting.
This commit is contained in:
parent
3f320e4d68
commit
6b74b5771a
|
@ -31,36 +31,36 @@
|
|||
|
||||
typedef VECTOR2I::extended_type ecoord;
|
||||
|
||||
static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance,
|
||||
bool needMTV, VECTOR2I& aMTV )
|
||||
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_CIRCLE& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
ecoord min_dist = clearance + a.GetRadius() + b.GetRadius();
|
||||
ecoord min_dist = aClearance + aA.GetRadius() + aB.GetRadius();
|
||||
ecoord min_dist_sq = min_dist * min_dist;
|
||||
|
||||
const VECTOR2I delta = b.GetCenter() - a.GetCenter();
|
||||
const VECTOR2I delta = aB.GetCenter() - aA.GetCenter();
|
||||
|
||||
ecoord dist_sq = delta.SquaredEuclideanNorm();
|
||||
|
||||
if ( dist_sq >= min_dist_sq )
|
||||
return false;
|
||||
|
||||
if ( needMTV )
|
||||
if ( aNeedMTV )
|
||||
aMTV = delta.Resize( sqrt ( abs( min_dist_sq - dist_sq ) ) + 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance,
|
||||
bool needMTV, VECTOR2I& aMTV )
|
||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CIRCLE& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
const VECTOR2I c = b.GetCenter();
|
||||
const VECTOR2I p0 = a.GetPosition();
|
||||
const VECTOR2I size = a.GetSize();
|
||||
const ecoord r = b.GetRadius();
|
||||
const ecoord min_dist = clearance + r;
|
||||
const VECTOR2I c = aB.GetCenter();
|
||||
const VECTOR2I p0 = aA.GetPosition();
|
||||
const VECTOR2I size = aA.GetSize();
|
||||
const ecoord r = aB.GetRadius();
|
||||
const ecoord min_dist = aClearance + r;
|
||||
const ecoord min_dist_sq = min_dist * min_dist;
|
||||
|
||||
if ( a.BBox( 0 ).Contains( c ) )
|
||||
if ( aA.BBox( 0 ).Contains( c ) )
|
||||
return true;
|
||||
|
||||
const VECTOR2I vts[] = {
|
||||
|
@ -86,7 +86,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
|
|||
|
||||
if( dist_sq < min_dist_sq )
|
||||
{
|
||||
if( !needMTV )
|
||||
if( !aNeedMTV )
|
||||
return true;
|
||||
else
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
|
|||
|
||||
VECTOR2I delta = c - nearest;
|
||||
|
||||
if( !needMTV )
|
||||
if( !aNeedMTV )
|
||||
return true;
|
||||
|
||||
if( inside )
|
||||
|
@ -114,12 +114,12 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
|
|||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance,
|
||||
bool needMTV, VECTOR2I& aMTV )
|
||||
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
for( int s = 0; s < b.SegmentCount(); s++ )
|
||||
for( int s = 0; s < aB.SegmentCount(); s++ )
|
||||
{
|
||||
if ( a.Collide( b.CSegment( s ), clearance ) )
|
||||
if ( aA.Collide( aB.CSegment( s ), aClearance ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -127,23 +127,23 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, in
|
|||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance,
|
||||
bool needMTV, VECTOR2I& aMTV )
|
||||
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
for( int i = 0; i < b.SegmentCount(); i++ )
|
||||
if( a.Collide( b.CSegment(i), clearance ) )
|
||||
for( int i = 0; i < aB.SegmentCount(); i++ )
|
||||
if( aA.Collide( aB.CSegment(i), aClearance ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance,
|
||||
bool needMTV, VECTOR2I& aMTV )
|
||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
for( int s = 0; s < b.SegmentCount(); s++ )
|
||||
for( int s = 0; s < aB.SegmentCount(); s++ )
|
||||
{
|
||||
SEG seg = b.CSegment( s );
|
||||
if( a.Collide( seg, clearance ) )
|
||||
SEG seg = aB.CSegment( s );
|
||||
if( aA.Collide( seg, aClearance ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -151,58 +151,58 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int
|
|||
}
|
||||
|
||||
|
||||
bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV )
|
||||
bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
switch( a->Type() )
|
||||
switch( aA->Type() )
|
||||
{
|
||||
case SH_RECT:
|
||||
switch( b->Type() )
|
||||
switch( aB->Type() )
|
||||
{
|
||||
case SH_CIRCLE:
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( a ),
|
||||
*static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( aA ),
|
||||
*static_cast<const SHAPE_CIRCLE*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_LINE_CHAIN:
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( a ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( aA ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_CIRCLE:
|
||||
switch( b->Type() )
|
||||
switch( aB->Type() )
|
||||
{
|
||||
case SH_RECT:
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( b ),
|
||||
*static_cast<const SHAPE_CIRCLE*>( a ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( aB ),
|
||||
*static_cast<const SHAPE_CIRCLE*>( aA ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CIRCLE:
|
||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( a ),
|
||||
*static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( aA ),
|
||||
*static_cast<const SHAPE_CIRCLE*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_LINE_CHAIN:
|
||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( a ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN *>( b ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( aA ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN *>( aB ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_LINE_CHAIN:
|
||||
switch( b->Type() )
|
||||
switch( aB->Type() )
|
||||
{
|
||||
case SH_RECT:
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( b ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_RECT*>( aB ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( aA ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CIRCLE:
|
||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( b ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( aB ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( aA ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_LINE_CHAIN:
|
||||
return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( a ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV );
|
||||
return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( aA ),
|
||||
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -99,6 +99,7 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
|
|||
|
||||
void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const
|
||||
{
|
||||
TOOL_EVENT event = aAction->GetEvent();
|
||||
TOOL_EVENT event = aAction->MakeEvent();
|
||||
|
||||
m_toolMgr->ProcessEvent( event );
|
||||
}
|
||||
|
|
|
@ -151,24 +151,28 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
|
|||
TOOL_EVENT evt;
|
||||
wxEventType type = aEvent.GetEventType();
|
||||
|
||||
// When the currently chosen item in the menu is changed, an update event is issued.
|
||||
// For example, the selection tool can use this to dynamically highlight the current item
|
||||
// from selection clarification popup.
|
||||
if( type == wxEVT_MENU_HIGHLIGHT )
|
||||
evt = TOOL_EVENT( TC_Command, TA_ContextMenuUpdate, aEvent.GetId() );
|
||||
|
||||
// One of menu entries was selected..
|
||||
else if( type == wxEVT_COMMAND_MENU_SELECTED )
|
||||
{
|
||||
if( aEvent.GetId() > m_actionId )
|
||||
// Check if there is a TOOL_ACTION for the given ID
|
||||
if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 )
|
||||
{
|
||||
// Handling TOOL_ACTIONs
|
||||
if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 )
|
||||
evt = m_menu->m_toolActions[aEvent.GetId()]->GetEvent();
|
||||
evt = m_menu->m_toolActions[aEvent.GetId()]->MakeEvent();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handling common menu entries
|
||||
// Handling non-action menu entries (e.g. items in clarification list)
|
||||
evt = TOOL_EVENT( TC_Command, TA_ContextMenuChoice, aEvent.GetId() );
|
||||
}
|
||||
}
|
||||
|
||||
// forward the action/update event to the TOOL_MANAGER
|
||||
if( m_menu->m_tool )
|
||||
m_menu->m_tool->GetManager()->ProcessEvent( evt );
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
using boost::optional;
|
||||
|
||||
///> Stores information about a mouse button state
|
||||
struct TOOL_DISPATCHER::ButtonState
|
||||
{
|
||||
ButtonState( TOOL_MouseButtons aButton, const wxEventType& aDownEvent,
|
||||
|
@ -217,6 +218,8 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
|
|||
type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_UP ||
|
||||
type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP ||
|
||||
type == wxEVT_RIGHT_DOWN || type == wxEVT_RIGHT_UP ||
|
||||
// Event issued whem mouse retains position in screen coordinates,
|
||||
// but changes in world coordinates (eg. autopanning)
|
||||
type == KiGfx::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
|
||||
{
|
||||
VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition();
|
||||
|
@ -247,7 +250,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
|
|||
|
||||
if( type == wxEVT_KEY_UP )
|
||||
{
|
||||
if( key == WXK_ESCAPE )
|
||||
if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools
|
||||
evt = TOOL_EVENT( TC_Command, TA_CancelTool );
|
||||
else
|
||||
evt = TOOL_EVENT( TC_Keyboard, TA_KeyUp, key | mods );
|
||||
|
@ -261,6 +264,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
|
|||
if( evt )
|
||||
m_toolMgr->ProcessEvent( *evt );
|
||||
|
||||
// pass the event to the GUI, it might still be interested in it
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
@ -270,6 +274,7 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
|
|||
bool activateTool = false;
|
||||
std::string toolName;
|
||||
|
||||
// fixme: use TOOL_ACTIONs here
|
||||
switch( aEvent.GetId() )
|
||||
{
|
||||
case ID_PNS_ROUTER_TOOL:
|
||||
|
@ -282,6 +287,7 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
|
|||
break;
|
||||
}
|
||||
|
||||
// do nothing if the legacy view is active
|
||||
if( activateTool && m_editFrame->IsGalCanvasActive() )
|
||||
m_toolMgr->InvokeTool( toolName );
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
//#include <base_struct.h>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_action.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -55,6 +54,12 @@ static const std::string flag2string( int flag, const FlagString* exps )
|
|||
}
|
||||
|
||||
|
||||
bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const
|
||||
{
|
||||
return Matches( aAction->MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
const std::string TOOL_EVENT::Format() const
|
||||
{
|
||||
std::string ev;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -39,6 +40,7 @@
|
|||
#include <tool/tool_manager.h>
|
||||
#include <tool/context_menu.h>
|
||||
#include <tool/coroutine.h>
|
||||
#include <tool/action_manager.h>
|
||||
|
||||
#include <wxPcbStruct.h>
|
||||
#include <class_drawpanel_gal.h>
|
||||
|
@ -46,37 +48,38 @@
|
|||
using boost::optional;
|
||||
using namespace std;
|
||||
|
||||
/// Struct describing the current state of a TOOL
|
||||
/// Struct describing the current execution state of a TOOL
|
||||
struct TOOL_MANAGER::TOOL_STATE
|
||||
{
|
||||
/// The tool itself
|
||||
TOOL_BASE* theTool;
|
||||
|
||||
/// Is the tool active or idle at the moment
|
||||
/// Is the tool active (pending execution) or disabled at the moment
|
||||
bool idle;
|
||||
|
||||
/// Flag defining if the tool is waiting for any event
|
||||
/// Flag defining if the tool is waiting for any event (i.e. if it
|
||||
/// issued a Wait() call).
|
||||
bool pendingWait;
|
||||
|
||||
/// Is there a context menu to be displayed
|
||||
/// Is there a context menu being displayed
|
||||
bool pendingContextMenu;
|
||||
|
||||
/// Context menu used by the tool
|
||||
/// Context menu currently used by the tool
|
||||
CONTEXT_MENU* contextMenu;
|
||||
|
||||
/// Defines when a context menu is opened
|
||||
/// Defines when the context menu is opened
|
||||
CONTEXT_MENU_TRIGGER contextMenuTrigger;
|
||||
|
||||
/// Coroutine launched upon an event trigger
|
||||
/// Tool execution context
|
||||
COROUTINE<int, TOOL_EVENT&>* cofunc;
|
||||
|
||||
/// The event that triggered the coroutine
|
||||
/// The event that triggered the execution/wakeup of the tool after Wait() call
|
||||
TOOL_EVENT wakeupEvent;
|
||||
|
||||
/// List of events that are triggering the coroutine
|
||||
/// List of events the tool is currently waiting for
|
||||
TOOL_EVENT_LIST waitEvents;
|
||||
|
||||
/// List of possible transitions (ie. association of events and functions that are executed
|
||||
/// List of possible transitions (ie. association of events and state handlers that are executed
|
||||
/// upon the event reception
|
||||
std::vector<TRANSITION> transitions;
|
||||
|
||||
|
@ -93,8 +96,9 @@ struct TOOL_MANAGER::TOOL_STATE
|
|||
|
||||
|
||||
TOOL_MANAGER::TOOL_MANAGER() :
|
||||
m_actionMgr( this ), m_model( NULL ), m_view( NULL )
|
||||
m_model( NULL ), m_view( NULL )
|
||||
{
|
||||
m_actionMgr = new ACTION_MANAGER( this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,6 +112,8 @@ TOOL_MANAGER::~TOOL_MANAGER()
|
|||
delete it->second; // delete TOOL_STATE
|
||||
delete it->first; // delete the tool itself
|
||||
}
|
||||
|
||||
delete m_actionMgr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -154,7 +160,7 @@ bool TOOL_MANAGER::InvokeTool( TOOL_ID aToolId )
|
|||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
return invokeTool( tool );
|
||||
|
||||
return false;
|
||||
return false; // there is no tool with the given id
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,7 +171,19 @@ bool TOOL_MANAGER::InvokeTool( const std::string& aToolName )
|
|||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
return invokeTool( tool );
|
||||
|
||||
return false;
|
||||
return false; // there is no tool with the given name
|
||||
}
|
||||
|
||||
|
||||
void TOOL_MANAGER::RegisterAction( TOOL_ACTION* aAction )
|
||||
{
|
||||
m_actionMgr->RegisterAction( aAction );
|
||||
}
|
||||
|
||||
|
||||
void TOOL_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
|
||||
{
|
||||
m_actionMgr->UnregisterAction( aAction );
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,7 +205,7 @@ bool TOOL_MANAGER::runTool( TOOL_ID aToolId )
|
|||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
return runTool( tool );
|
||||
|
||||
return false;
|
||||
return false; // there is no tool with the given id
|
||||
}
|
||||
|
||||
|
||||
|
@ -198,7 +216,7 @@ bool TOOL_MANAGER::runTool( const std::string& aToolName )
|
|||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
return runTool( tool );
|
||||
|
||||
return false;
|
||||
return false; // there is no tool with the given name
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,8 +278,12 @@ optional<TOOL_EVENT> TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool,
|
|||
{
|
||||
TOOL_STATE* st = m_toolState[aTool];
|
||||
|
||||
// indicate to the manager that we are going to sleep and we shall be
|
||||
// woken up when an event matching aConditions arrive
|
||||
st->pendingWait = true;
|
||||
st->waitEvents = aConditions;
|
||||
|
||||
// switch context back to event dispatcher loop
|
||||
st->cofunc->Yield();
|
||||
|
||||
return st->wakeupEvent;
|
||||
|
@ -300,7 +322,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
|||
|
||||
BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values )
|
||||
{
|
||||
// the tool state handler is waiting for events (i.e. called Wait() method)
|
||||
// the tool scheduled next state(s) by calling Go()
|
||||
if( !st->pendingWait )
|
||||
{
|
||||
// no state handler in progress - check if there are any transitions (defined by
|
||||
|
@ -313,6 +335,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
|||
{
|
||||
st->transitions.clear();
|
||||
|
||||
// no tool context allocated yet? Create one.
|
||||
if( !st->cofunc )
|
||||
st->cofunc = new COROUTINE<int, TOOL_EVENT&>( tr.second );
|
||||
else
|
||||
|
@ -322,7 +345,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
|||
st->cofunc->Call( aEvent );
|
||||
|
||||
if( !st->cofunc->Running() )
|
||||
finishTool( st ); // The couroutine has finished
|
||||
finishTool( st ); // The couroutine has finished immediately?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -331,8 +354,27 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( aEvent.Action() == TA_KeyUp )
|
||||
{
|
||||
// Check if there is a hotkey associated
|
||||
if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) )
|
||||
return false; // hotkey event was handled so it does not go any further
|
||||
}
|
||||
else if( aEvent.Category() == TC_Command ) // it may be a tool activation event
|
||||
{
|
||||
dispatchActivation( aEvent );
|
||||
// do not return false, as the event has to go on to the destined tool
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Look for the tool that has the same name as parameter in the processed command TOOL_EVENT
|
||||
BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values )
|
||||
{
|
||||
if( st->theTool->GetName() == aEvent.m_commandStr )
|
||||
|
@ -359,7 +401,7 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
|
|||
if( it != m_activeTools.end() )
|
||||
m_activeTools.erase( it );
|
||||
else
|
||||
wxLogWarning( wxT( "Tried to finish not active tool" ) );
|
||||
wxLogWarning( wxT( "Tried to finish inactive tool" ) );
|
||||
|
||||
aState->idle = true;
|
||||
delete aState->cofunc;
|
||||
|
@ -371,22 +413,19 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
|
|||
{
|
||||
// wxLogDebug( "event: %s", aEvent.Format().c_str() );
|
||||
|
||||
if( aEvent.Action() == TA_KeyUp )
|
||||
{
|
||||
// Check if there is a hotkey associated
|
||||
if( m_actionMgr.RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) )
|
||||
return false; // hotkey event was handled so it does not go any further
|
||||
} else if( aEvent.Category() == TC_Command ) // it may be a tool activation event
|
||||
{
|
||||
dispatchActivation( aEvent );
|
||||
}
|
||||
// Early dispatch of events destined for the TOOL_MANAGER
|
||||
if( !dispatchStandardEvents( aEvent ) )
|
||||
return false;
|
||||
|
||||
dispatchInternal( aEvent );
|
||||
|
||||
// popup menu handling
|
||||
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
|
||||
{
|
||||
TOOL_STATE* st = m_toolIdIndex[toolId];
|
||||
|
||||
// the tool requested a context menu. The menu is activated on RMB click (CMENU_BUTTON mode)
|
||||
// or immediately (CMENU_NOW) mode. The latter is used for clarification lists.
|
||||
if( st->contextMenuTrigger != CMENU_OFF )
|
||||
{
|
||||
if( st->contextMenuTrigger == CMENU_BUTTON && !aEvent.IsClick( MB_Right ) )
|
||||
|
@ -401,6 +440,7 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
|
|||
boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *st->contextMenu ) );
|
||||
GetEditFrame()->PopupMenu( menu->GetMenu() );
|
||||
|
||||
//
|
||||
TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice );
|
||||
dispatchInternal( evt );
|
||||
|
||||
|
@ -426,6 +466,7 @@ void TOOL_MANAGER::ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu,
|
|||
st->contextMenu = aMenu;
|
||||
st->contextMenuTrigger = aTrigger;
|
||||
|
||||
// the tool wants the menu immediately? Preempt it and do so :)
|
||||
if( aTrigger == CMENU_NOW )
|
||||
st->cofunc->Yield();
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
|
||||
typedef boost::optional<VECTOR2I> OPT_VECTOR2I;
|
||||
|
||||
class SEG {
|
||||
|
||||
class SEG
|
||||
{
|
||||
private:
|
||||
typedef VECTOR2I::extended_type ecoord;
|
||||
|
||||
|
@ -52,7 +52,7 @@ class SEG {
|
|||
/** Default constructor
|
||||
* Creates an empty (0, 0) segment, locally-referenced
|
||||
*/
|
||||
SEG(): a(m_a), b(m_b)
|
||||
SEG() : a( m_a ), b( m_b )
|
||||
{
|
||||
a = m_a;
|
||||
b = m_b;
|
||||
|
@ -62,12 +62,12 @@ class SEG {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a segment between (x1, y1) and (x2, y2), locally referenced
|
||||
* Creates a segment between (aX1, aY1) and (aX2, aY2), locally referenced
|
||||
*/
|
||||
SEG ( int x1, int y1, int x2, int y2 ) : a(m_a), b(m_b)
|
||||
SEG( int aX1, int aY1, int aX2, int aY2 ) : a( m_a ), b( m_b )
|
||||
{
|
||||
m_a = VECTOR2I(x1, y1);
|
||||
m_b = VECTOR2I(x2, y2);
|
||||
m_a = VECTOR2I( aX1, aY1 );
|
||||
m_b = VECTOR2I( aX2, aY2 );
|
||||
a = m_a;
|
||||
b = m_b;
|
||||
m_is_local = true;
|
||||
|
@ -78,7 +78,7 @@ class SEG {
|
|||
* Constructor
|
||||
* Creates a segment between (aA) and (aB), locally referenced
|
||||
*/
|
||||
SEG ( const VECTOR2I& aA, const VECTOR2I& aB ): a(m_a), b(m_b), m_a(aA), m_b(aB)
|
||||
SEG( const VECTOR2I& aA, const VECTOR2I& aB ) : a( m_a ), b( m_b ), m_a( aA ), m_b( aB )
|
||||
{
|
||||
a = m_a;
|
||||
b = m_b;
|
||||
|
@ -93,7 +93,7 @@ class SEG {
|
|||
* @param aB reference to the end point in the parent shape
|
||||
* @param aIndex index of the segment within the parent shape
|
||||
*/
|
||||
SEG ( VECTOR2I& aA, VECTOR2I& aB, int aIndex ): a(aA), b(aB)
|
||||
SEG ( VECTOR2I& aA, VECTOR2I& aB, int aIndex ) : a( aA ), b( aB )
|
||||
{
|
||||
m_is_local = false;
|
||||
m_index = aIndex;
|
||||
|
@ -102,32 +102,32 @@ class SEG {
|
|||
/**
|
||||
* Copy constructor
|
||||
*/
|
||||
SEG ( const SEG& seg ): a(m_a), b(m_b)
|
||||
SEG ( const SEG& aSeg ) : a( m_a ), b( m_b )
|
||||
{
|
||||
if (seg.m_is_local)
|
||||
if (aSeg.m_is_local)
|
||||
{
|
||||
m_a = seg.m_a;
|
||||
m_b = seg.m_b;
|
||||
m_a = aSeg.m_a;
|
||||
m_b = aSeg.m_b;
|
||||
a = m_a;
|
||||
b = m_b;
|
||||
m_is_local = true;
|
||||
m_index = -1;
|
||||
} else {
|
||||
a = seg.a;
|
||||
b = seg.b;
|
||||
m_index = seg.m_index;
|
||||
a = aSeg.a;
|
||||
b = aSeg.b;
|
||||
m_index = aSeg.m_index;
|
||||
m_is_local = false;
|
||||
}
|
||||
}
|
||||
|
||||
SEG& operator=(const SEG& seg)
|
||||
SEG& operator=( const SEG& aSeg )
|
||||
{
|
||||
a = seg.a;
|
||||
b = seg.b;
|
||||
m_a = seg.m_a;
|
||||
m_b = seg.m_b;
|
||||
m_index = seg.m_index;
|
||||
m_is_local = seg.m_is_local;
|
||||
a = aSeg.a;
|
||||
b = aSeg.b;
|
||||
m_a = aSeg.m_a;
|
||||
m_b = aSeg.m_b;
|
||||
m_index = aSeg.m_index;
|
||||
m_is_local = aSeg.m_is_local;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -150,8 +150,9 @@ class SEG {
|
|||
*/
|
||||
int Side( const VECTOR2I& aP ) const
|
||||
{
|
||||
const ecoord det = (b - a).Cross(aP - a);
|
||||
return det < 0 ? -1 : (det > 0 ? 1 : 0);
|
||||
const ecoord det = ( b - a ).Cross( aP - a );
|
||||
|
||||
return det < 0 ? -1 : ( det > 0 ? 1 : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,7 +174,6 @@ class SEG {
|
|||
*/
|
||||
const VECTOR2I NearestPoint( const VECTOR2I &aP ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Function Intersect()
|
||||
*
|
||||
|
@ -186,8 +186,6 @@ class SEG {
|
|||
*/
|
||||
OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false ) const;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function IntersectLines()
|
||||
*
|
||||
|
@ -195,9 +193,9 @@ class SEG {
|
|||
* @param aSeg segment defining the line to intersect with
|
||||
* @return intersection point, if exists
|
||||
*/
|
||||
OPT_VECTOR2I IntersectLines( const SEG& aSeg ) const
|
||||
OPT_VECTOR2I IntersectLines( const SEG& aSeg ) const
|
||||
{
|
||||
return Intersect ( aSeg, false, true );
|
||||
return Intersect( aSeg, false, true );
|
||||
}
|
||||
|
||||
bool Collide( const SEG& aSeg, int aClearance ) const;
|
||||
|
@ -210,14 +208,13 @@ class SEG {
|
|||
* @return minimum distance
|
||||
*/
|
||||
|
||||
ecoord SquaredDistance( const SEG& aSeg ) const ;
|
||||
ecoord SquaredDistance( const SEG& aSeg ) const;
|
||||
|
||||
int Distance( const SEG& aSeg ) const
|
||||
{
|
||||
return sqrt ( SquaredDistance(aSeg) );
|
||||
return sqrt( SquaredDistance( aSeg ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Distance()
|
||||
*
|
||||
|
@ -225,18 +222,16 @@ class SEG {
|
|||
* @param aP the point
|
||||
* @return minimum distance
|
||||
*/
|
||||
|
||||
ecoord SquaredDistance( const VECTOR2I& aP ) const
|
||||
{
|
||||
return (NearestPoint(aP) - aP).SquaredEuclideanNorm();
|
||||
return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
|
||||
}
|
||||
|
||||
int Distance( const VECTOR2I& aP ) const
|
||||
{
|
||||
return sqrt ( SquaredDistance( aP) );
|
||||
return sqrt( SquaredDistance( aP ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Collinear()
|
||||
*
|
||||
|
@ -244,7 +239,6 @@ class SEG {
|
|||
* @param aSeg the segment to chech colinearity with
|
||||
* @return true, when segments are collinear.
|
||||
*/
|
||||
|
||||
bool Collinear( const SEG& aSeg ) const
|
||||
{
|
||||
ecoord qa1 = a.y - b.y;
|
||||
|
@ -254,7 +248,7 @@ class SEG {
|
|||
ecoord qb2 = aSeg.b.x - aSeg.a.x;
|
||||
ecoord qc2 = -qa2 * aSeg.a.x - qb2 * aSeg.a.y;
|
||||
|
||||
return (qa1 == qa2) && (qb1 == qb2) && (qc1 == qc2);
|
||||
return ( qa1 == qa2 ) && ( qb1 == qb2 ) && ( qc1 == qc2 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -265,15 +259,14 @@ class SEG {
|
|||
*/
|
||||
int Length() const
|
||||
{
|
||||
return (a - b).EuclideanNorm();
|
||||
return ( a - b ).EuclideanNorm();
|
||||
}
|
||||
|
||||
ecoord SquaredLength() const
|
||||
ecoord SquaredLength() const
|
||||
{
|
||||
return (a - b).SquaredEuclideanNorm();
|
||||
return ( a - b ).SquaredEuclideanNorm();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Index()
|
||||
*
|
||||
|
@ -285,20 +278,20 @@ class SEG {
|
|||
return m_index;
|
||||
}
|
||||
|
||||
bool Contains( const VECTOR2I& aP ) const;
|
||||
|
||||
bool Contains(const VECTOR2I& aP) const;
|
||||
|
||||
bool PointCloserThan ( const VECTOR2I& aP, int dist) const;
|
||||
bool PointCloserThan( const VECTOR2I& aP, int aDist ) const;
|
||||
|
||||
// friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
|
||||
private:
|
||||
|
||||
bool ccw ( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I &c ) const;
|
||||
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
|
||||
|
||||
///> locally stored start/end coordinates (used when m_is_local == true)
|
||||
VECTOR2I m_a, m_b;
|
||||
|
||||
///> index withing the parent shape (used when m_is_local == false)
|
||||
int m_index;
|
||||
|
||||
///> locality flag
|
||||
bool m_is_local;
|
||||
};
|
||||
|
@ -306,49 +299,47 @@ class SEG {
|
|||
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
||||
{
|
||||
// fixme: numerical errors for large integers
|
||||
assert(false);
|
||||
return VECTOR2I(0, 0);
|
||||
assert( false );
|
||||
return VECTOR2I( 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
||||
{
|
||||
ecoord p = a.y - b.y;
|
||||
ecoord q = b.x - a.x;
|
||||
ecoord r = -p * a.x - q * a.y;
|
||||
ecoord p = a.y - b.y;
|
||||
ecoord q = b.x - a.x;
|
||||
ecoord r = -p * a.x - q * a.y;
|
||||
|
||||
ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q );
|
||||
return aDetermineSide ? dist : abs(dist);
|
||||
ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q );
|
||||
|
||||
return aDetermineSide ? dist : abs( dist );
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline const VECTOR2I SEG::NearestPoint(const VECTOR2I& aP) const
|
||||
inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
|
||||
{
|
||||
VECTOR2I d = b - a;
|
||||
ecoord l_squared = d.Dot(d);
|
||||
VECTOR2I d = b - a;
|
||||
ecoord l_squared = d.Dot( d );
|
||||
|
||||
if( l_squared == 0 )
|
||||
return a;
|
||||
|
||||
ecoord t = d.Dot(aP - a);
|
||||
ecoord t = d.Dot( aP - a );
|
||||
|
||||
if( t < 0 )
|
||||
return a;
|
||||
else if( t > l_squared )
|
||||
return b;
|
||||
|
||||
int xp = rescale(t, (ecoord)d.x, l_squared);
|
||||
int yp = rescale(t, (ecoord)d.y, l_squared);
|
||||
int xp = rescale( t, (ecoord)d.x, l_squared );
|
||||
int yp = rescale( t, (ecoord)d.y, l_squared );
|
||||
|
||||
return a + VECTOR2I(xp, yp);
|
||||
return a + VECTOR2I( xp, yp );
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg )
|
||||
{
|
||||
if(aSeg.m_is_local)
|
||||
if( aSeg.m_is_local )
|
||||
aStream << "[ local " << aSeg.a << " - " << aSeg.b << " ]";
|
||||
|
||||
return aStream;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ enum ShapeType {
|
|||
/**
|
||||
* Class SHAPE
|
||||
*
|
||||
* Represents an abstract shape on 2D plane. All SHAPEs implement SHAPE interface.
|
||||
* Represents an abstract shape on 2D plane.
|
||||
*/
|
||||
class SHAPE {
|
||||
protected:
|
||||
|
@ -58,7 +58,7 @@ class SHAPE {
|
|||
* Creates an empty shape of type aType
|
||||
*/
|
||||
|
||||
SHAPE ( ShapeType aType ): m_type( aType ) { };
|
||||
SHAPE ( ShapeType aType ) : m_type( aType ) { };
|
||||
|
||||
// Destructor
|
||||
virtual ~SHAPE() {};
|
||||
|
@ -78,7 +78,7 @@ class SHAPE {
|
|||
* @retval copy of the shape
|
||||
*/
|
||||
virtual SHAPE* Clone() const {
|
||||
assert(false);
|
||||
assert( false );
|
||||
return NULL;
|
||||
};
|
||||
|
||||
|
@ -89,9 +89,9 @@ class SHAPE {
|
|||
* a collision.
|
||||
* @return true, if there is a collision.
|
||||
*/
|
||||
virtual bool Collide ( const VECTOR2I& aP, int aClearance = 0 ) const
|
||||
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0 ) const
|
||||
{
|
||||
return Collide(SEG(aP, aP), aClearance);
|
||||
return Collide( SEG( aP, aP ), aClearance );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,10 +99,13 @@ class SHAPE {
|
|||
*
|
||||
* Checks if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating
|
||||
* a collision.
|
||||
* @param aShape shape to check collision against
|
||||
* @param aClearance minimum clearance
|
||||
* @param aMTV minimum translation vector
|
||||
* @return true, if there is a collision.
|
||||
*/
|
||||
virtual bool Collide ( const SHAPE *aShape, int aClerance, VECTOR2I& aMTV ) const;
|
||||
virtual bool Collide ( const SHAPE *aShape, int aClerance = 0 ) const;
|
||||
virtual bool Collide( const SHAPE* aShape, int aClerance, VECTOR2I& aMTV ) const;
|
||||
virtual bool Collide( const SHAPE* aShape, int aClerance = 0 ) const;
|
||||
/**
|
||||
* Function Collide()
|
||||
*
|
||||
|
@ -110,7 +113,7 @@ class SHAPE {
|
|||
* a collision.
|
||||
* @return true, if there is a collision.
|
||||
*/
|
||||
virtual bool Collide ( const SEG& aSeg, int aClearance = 0) const = 0;
|
||||
virtual bool Collide( const SEG& aSeg, int aClearance = 0 ) const = 0;
|
||||
|
||||
/**
|
||||
* Function Collide()
|
||||
|
@ -120,7 +123,7 @@ class SHAPE {
|
|||
* @aClearance how much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape.
|
||||
* @return the bounding box.
|
||||
*/
|
||||
virtual const BOX2I BBox ( int aClearance = 0 ) const = 0;
|
||||
virtual const BOX2I BBox( int aClearance = 0 ) const = 0;
|
||||
|
||||
/**
|
||||
* Function Centre()
|
||||
|
@ -130,7 +133,7 @@ class SHAPE {
|
|||
*/
|
||||
virtual VECTOR2I Centre() const
|
||||
{
|
||||
return BBox(0).Centre(); // if nothing better is available....
|
||||
return BBox( 0 ).Centre(); // if nothing better is available....
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -139,6 +142,6 @@ class SHAPE {
|
|||
|
||||
};
|
||||
|
||||
bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV, VECTOR2I& aMTV );
|
||||
bool CollideShapes( const SHAPE *aA, const SHAPE *aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV );
|
||||
|
||||
#endif // __SHAPE_H
|
||||
|
|
|
@ -31,32 +31,31 @@ class SHAPE_CIRCLE : public SHAPE {
|
|||
|
||||
public:
|
||||
SHAPE_CIRCLE():
|
||||
SHAPE( SH_CIRCLE ), m_radius (0) {};
|
||||
SHAPE( SH_CIRCLE ), m_radius( 0 ) {};
|
||||
|
||||
SHAPE_CIRCLE( const VECTOR2I& aCenter, int aRadius ):
|
||||
SHAPE( SH_CIRCLE ), m_radius (aRadius), m_center(aCenter) {};
|
||||
SHAPE( SH_CIRCLE ), m_radius( aRadius ), m_center( aCenter ) {};
|
||||
|
||||
~SHAPE_CIRCLE() {};
|
||||
|
||||
const BOX2I BBox(int aClearance = 0) const
|
||||
const BOX2I BBox( int aClearance = 0 ) const
|
||||
{
|
||||
const VECTOR2I rc (m_radius + aClearance, m_radius + aClearance);
|
||||
return BOX2I (m_center - rc, rc * 2);
|
||||
const VECTOR2I rc( m_radius + aClearance, m_radius + aClearance );
|
||||
return BOX2I( m_center - rc, rc * 2 );
|
||||
}
|
||||
|
||||
|
||||
bool Collide(const SEG& aSeg, int aClearance = 0) const
|
||||
bool Collide( const SEG& aSeg, int aClearance = 0 ) const
|
||||
{
|
||||
int rc = aClearance + m_radius;
|
||||
return aSeg.Distance(m_center) <= rc;
|
||||
return aSeg.Distance( m_center ) <= rc;
|
||||
}
|
||||
|
||||
void SetRadius(int aRadius)
|
||||
void SetRadius( int aRadius )
|
||||
{
|
||||
m_radius = aRadius;
|
||||
}
|
||||
|
||||
void SetCenter (const VECTOR2I& aCenter)
|
||||
void SetCenter( const VECTOR2I& aCenter )
|
||||
{
|
||||
m_center = aCenter;
|
||||
}
|
||||
|
|
|
@ -62,9 +62,9 @@ const SHAPE* shapeFunctor( SHAPE* aItem );
|
|||
* @return a BOX2I object containing the bounding box of the T object.
|
||||
*/
|
||||
template <class T>
|
||||
BOX2I boundingBox( T object )
|
||||
BOX2I boundingBox( T aObject )
|
||||
{
|
||||
return shapeFunctor(object)->BBox();
|
||||
return shapeFunctor( aObject )->BBox();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,9 +77,9 @@ BOX2I boundingBox( T object )
|
|||
* @param visitor V visitor object
|
||||
*/
|
||||
template <class T, class V>
|
||||
void acceptVisitor( T object, V visitor )
|
||||
void acceptVisitor( T aObject, V aVisitor )
|
||||
{
|
||||
visitor(object);
|
||||
aVisitor( aObject );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,22 +94,23 @@ void acceptVisitor( T object, V visitor )
|
|||
* @return if object and anotherObject collide
|
||||
*/
|
||||
template<class T, class U>
|
||||
bool collide( T object, U anotherObject, int minDistance )
|
||||
bool collide( T aObject, U aAnotherObject, int aMinDistance )
|
||||
{
|
||||
return shapeFunctor( object )->Collide( anotherObject, minDistance );
|
||||
return shapeFunctor( aObject )->Collide( aAnotherObject, aMinDistance );
|
||||
}
|
||||
|
||||
template<class T, class V>
|
||||
bool queryCallback(T shape, void* context)
|
||||
bool queryCallback( T aShape, void* aContext )
|
||||
{
|
||||
V* visitor = (V*) context;
|
||||
acceptVisitor<T,V>( shape, *visitor );
|
||||
V* visitor = (V*) aContext;
|
||||
acceptVisitor<T,V>( aShape, *visitor );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T = SHAPE*>
|
||||
class SHAPE_INDEX {
|
||||
class SHAPE_INDEX
|
||||
{
|
||||
public:
|
||||
class Iterator
|
||||
{
|
||||
|
@ -123,9 +124,9 @@ class SHAPE_INDEX {
|
|||
* Setup the internal tree iterator.
|
||||
* @param tree pointer to a RTREE object
|
||||
*/
|
||||
void Init( RTree<T, int, 2, float>* tree )
|
||||
void Init( RTree<T, int, 2, float>* aTree )
|
||||
{
|
||||
tree->GetFirst( iterator );
|
||||
aTree->GetFirst( iterator );
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -135,9 +136,9 @@ class SHAPE_INDEX {
|
|||
* Creates an iterator for the index object
|
||||
* @param index SHAPE_INDEX object to iterate
|
||||
*/
|
||||
Iterator( SHAPE_INDEX* index )
|
||||
Iterator( SHAPE_INDEX* aIndex )
|
||||
{
|
||||
Init( index->m_tree );
|
||||
Init( aIndex->m_tree );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -321,7 +322,7 @@ void SHAPE_INDEX<T>::Add( T aShape )
|
|||
}
|
||||
|
||||
template<class T>
|
||||
void SHAPE_INDEX<T>::Remove(T aShape)
|
||||
void SHAPE_INDEX<T>::Remove( T aShape )
|
||||
{
|
||||
BOX2I box = boundingBox( aShape );
|
||||
int min[2] = { box.GetX(), box.GetY() };
|
||||
|
|
|
@ -27,30 +27,29 @@
|
|||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
template <class T> const SHAPE *defaultShapeFunctor( const T aItem )
|
||||
template <class T> const SHAPE* defaultShapeFunctor( const T aItem )
|
||||
{
|
||||
return aItem->GetShape();
|
||||
}
|
||||
|
||||
template <class T, const SHAPE *(ShapeFunctor)(const T) = defaultShapeFunctor<T> >
|
||||
template <class T, const SHAPE* (ShapeFunctor)(const T) = defaultShapeFunctor<T> >
|
||||
|
||||
class SHAPE_INDEX_LIST {
|
||||
|
||||
struct ShapeEntry {
|
||||
ShapeEntry(T aParent)
|
||||
ShapeEntry( T aParent )
|
||||
{
|
||||
shape = ShapeFunctor(aParent);
|
||||
bbox = shape->BBox(0);
|
||||
shape = ShapeFunctor( aParent );
|
||||
bbox = shape->BBox( 0 );
|
||||
parent = aParent;
|
||||
}
|
||||
|
||||
~ShapeEntry()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
T parent;
|
||||
const SHAPE *shape;
|
||||
const SHAPE* shape;
|
||||
BOX2I bbox;
|
||||
};
|
||||
|
||||
|
@ -58,18 +57,16 @@ class SHAPE_INDEX_LIST {
|
|||
typedef typename std::vector<ShapeEntry>::iterator ShapeVecIter;
|
||||
|
||||
public:
|
||||
|
||||
// "Normal" iterator interface, for STL algorithms.
|
||||
// "Normal" iterator interface, for STL algorithms.
|
||||
class iterator {
|
||||
|
||||
public:
|
||||
iterator() {};
|
||||
|
||||
iterator( ShapeVecIter aCurrent)
|
||||
: m_current(aCurrent) {};
|
||||
iterator( ShapeVecIter aCurrent )
|
||||
: m_current( aCurrent ) {};
|
||||
|
||||
iterator(const iterator &b) :
|
||||
m_current(b.m_current) {};
|
||||
iterator( const iterator &aB ) :
|
||||
m_current( aB.m_current ) {};
|
||||
|
||||
T operator*() const
|
||||
{
|
||||
|
@ -81,25 +78,25 @@ public:
|
|||
++m_current;
|
||||
}
|
||||
|
||||
iterator& operator++(int dummy)
|
||||
iterator& operator++( int aDummy )
|
||||
{
|
||||
++m_current;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator ==( const iterator& rhs ) const
|
||||
bool operator==( const iterator& aRhs ) const
|
||||
{
|
||||
return m_current == rhs.m_current;
|
||||
return m_current == aRhs.m_current;
|
||||
}
|
||||
|
||||
bool operator !=( const iterator& rhs ) const
|
||||
bool operator!=( const iterator& aRhs ) const
|
||||
{
|
||||
return m_current != rhs.m_current;
|
||||
return m_current != aRhs.m_current;
|
||||
}
|
||||
|
||||
const iterator& operator=(const iterator& rhs)
|
||||
const iterator& operator=( const iterator& aRhs )
|
||||
{
|
||||
m_current = rhs.m_current;
|
||||
m_current = aRhs.m_current;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -107,40 +104,37 @@ public:
|
|||
ShapeVecIter m_current;
|
||||
};
|
||||
|
||||
// "Query" iterator, for iterating over a set of spatially matching shapes.
|
||||
// "Query" iterator, for iterating over a set of spatially matching shapes.
|
||||
class query_iterator {
|
||||
public:
|
||||
|
||||
query_iterator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
query_iterator( ShapeVecIter aCurrent, ShapeVecIter aEnd, SHAPE *aShape, int aMinDistance, bool aExact)
|
||||
: m_end(aEnd),
|
||||
m_current(aCurrent),
|
||||
m_shape(aShape),
|
||||
m_minDistance(aMinDistance),
|
||||
m_exact(aExact)
|
||||
query_iterator( ShapeVecIter aCurrent, ShapeVecIter aEnd, SHAPE* aShape,
|
||||
int aMinDistance, bool aExact ) :
|
||||
m_end( aEnd ),
|
||||
m_current( aCurrent ),
|
||||
m_shape( aShape ),
|
||||
m_minDistance( aMinDistance ),
|
||||
m_exact( aExact )
|
||||
{
|
||||
if(aShape)
|
||||
if( aShape )
|
||||
{
|
||||
m_refBBox = aShape->BBox();
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
query_iterator(const query_iterator &b)
|
||||
: m_end(b.m_end),
|
||||
m_current(b.m_current),
|
||||
m_shape(b.m_shape),
|
||||
m_minDistance(b.m_minDistance),
|
||||
m_exact(b.m_exact),
|
||||
m_refBBox(b.m_refBBox)
|
||||
query_iterator( const query_iterator &aB ) :
|
||||
m_end( aB.m_end ),
|
||||
m_current( aB.m_current ),
|
||||
m_shape( aB.m_shape ),
|
||||
m_minDistance( aB.m_minDistance ),
|
||||
m_exact( aB.m_exact ),
|
||||
m_refBBox( aB.m_refBBox )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
T operator*() const
|
||||
{
|
||||
|
@ -154,45 +148,45 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
query_iterator& operator++(int dummy)
|
||||
query_iterator& operator++( int aDummy )
|
||||
{
|
||||
++m_current;
|
||||
next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator ==( const query_iterator& rhs ) const
|
||||
bool operator==( const query_iterator& aRhs ) const
|
||||
{
|
||||
return m_current == rhs.m_current;
|
||||
return m_current == aRhs.m_current;
|
||||
}
|
||||
|
||||
bool operator !=( const query_iterator& rhs ) const
|
||||
bool operator!=( const query_iterator& aRhs ) const
|
||||
{
|
||||
return m_current != rhs.m_current;
|
||||
return m_current != aRhs.m_current;
|
||||
}
|
||||
|
||||
const query_iterator& operator=(const query_iterator& rhs)
|
||||
const query_iterator& operator=( const query_iterator& aRhs )
|
||||
{
|
||||
m_end = rhs.m_end;
|
||||
m_current = rhs.m_current;
|
||||
m_shape = rhs.m_shape;
|
||||
m_minDistance = rhs.m_minDistance;
|
||||
m_exact = rhs.m_exact;
|
||||
m_refBBox = rhs.m_refBBox;
|
||||
m_end = aRhs.m_end;
|
||||
m_current = aRhs.m_current;
|
||||
m_shape = aRhs.m_shape;
|
||||
m_minDistance = aRhs.m_minDistance;
|
||||
m_exact = aRhs.m_exact;
|
||||
m_refBBox = aRhs.m_refBBox;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void next()
|
||||
{
|
||||
while(m_current != m_end)
|
||||
while( m_current != m_end )
|
||||
{
|
||||
if (m_refBBox.Distance(m_current->bbox) <= m_minDistance)
|
||||
if( m_refBBox.Distance( m_current->bbox ) <= m_minDistance )
|
||||
{
|
||||
if(!m_exact || m_current->shape->Collide(m_shape, m_minDistance))
|
||||
if( !m_exact || m_current->shape->Collide( m_shape, m_minDistance ) )
|
||||
return;
|
||||
}
|
||||
|
||||
++m_current;
|
||||
}
|
||||
}
|
||||
|
@ -205,27 +199,27 @@ public:
|
|||
int m_minDistance;
|
||||
};
|
||||
|
||||
void Add(T aItem)
|
||||
void Add( T aItem )
|
||||
{
|
||||
ShapeEntry s (aItem);
|
||||
ShapeEntry s( aItem );
|
||||
|
||||
m_shapes.push_back(s);
|
||||
}
|
||||
|
||||
void Remove(const T aItem)
|
||||
void Remove( const T aItem )
|
||||
{
|
||||
ShapeVecIter i;
|
||||
|
||||
for(i=m_shapes.begin(); i!=m_shapes.end();++i)
|
||||
for( i = m_shapes.begin(); i != m_shapes.end(); ++i )
|
||||
{
|
||||
if(i->parent == aItem)
|
||||
if( i->parent == aItem )
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == m_shapes.end())
|
||||
if( i == m_shapes.end() )
|
||||
return;
|
||||
|
||||
m_shapes.erase(i);
|
||||
m_shapes.erase( i );
|
||||
}
|
||||
|
||||
int Size() const
|
||||
|
@ -234,37 +228,37 @@ public:
|
|||
}
|
||||
|
||||
template<class Visitor>
|
||||
int Query( const SHAPE *aShape, int aMinDistance, Visitor &v, bool aExact = true) //const
|
||||
{
|
||||
ShapeVecIter i;
|
||||
int n = 0;
|
||||
VECTOR2I::extended_type minDistSq = (VECTOR2I::extended_type) aMinDistance * aMinDistance;
|
||||
int Query( const SHAPE *aShape, int aMinDistance, Visitor &aV, bool aExact = true ) //const
|
||||
{
|
||||
ShapeVecIter i;
|
||||
int n = 0;
|
||||
VECTOR2I::extended_type minDistSq = (VECTOR2I::extended_type) aMinDistance * aMinDistance;
|
||||
|
||||
BOX2I refBBox = aShape->BBox();
|
||||
BOX2I refBBox = aShape->BBox();
|
||||
|
||||
for(i = m_shapes.begin(); i!=m_shapes.end(); ++i)
|
||||
{
|
||||
if (refBBox.SquaredDistance(i->bbox) <= minDistSq)
|
||||
{
|
||||
if(!aExact || i->shape->Collide(aShape, aMinDistance))
|
||||
{
|
||||
n++;
|
||||
if(!v( i->parent ))
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
for( i = m_shapes.begin(); i != m_shapes.end(); ++i )
|
||||
{
|
||||
if( refBBox.SquaredDistance( i->bbox ) <= minDistSq )
|
||||
{
|
||||
if( !aExact || i->shape->Collide( aShape, aMinDistance ) )
|
||||
{
|
||||
n++;
|
||||
if( !aV( i->parent ) )
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_shapes.clear();
|
||||
}
|
||||
|
||||
query_iterator qbegin( SHAPE *aShape, int aMinDistance, bool aExact )
|
||||
query_iterator qbegin( SHAPE* aShape, int aMinDistance, bool aExact )
|
||||
{
|
||||
return query_iterator( m_shapes.begin(), m_shapes.end(), aShape, aMinDistance, aExact);
|
||||
return query_iterator( m_shapes.begin(), m_shapes.end(), aShape, aMinDistance, aExact );
|
||||
}
|
||||
|
||||
const query_iterator qend()
|
||||
|
@ -283,7 +277,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
ShapeVec m_shapes;
|
||||
};
|
||||
|
||||
|
|
|
@ -36,28 +36,28 @@ class SHAPE_RECT : public SHAPE {
|
|||
* Constructor
|
||||
* Creates an empty (0-sized) rectangle
|
||||
*/
|
||||
SHAPE_RECT():
|
||||
SHAPE( SH_RECT ), m_w (0), m_h(0) {};
|
||||
SHAPE_RECT() :
|
||||
SHAPE( SH_RECT ), m_w( 0 ), m_h( 0 ) {};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a rectangle defined by top-left corner (x0, y0), width w and height h.
|
||||
* Creates a rectangle defined by top-left corner (aX0, aY0), width aW and height aH.
|
||||
*/
|
||||
SHAPE_RECT( int x0, int y0, int w, int h ):
|
||||
SHAPE(SH_RECT), m_p0(x0, y0), m_w(w), m_h(h) {};
|
||||
SHAPE_RECT( int aX0, int aY0, int aW, int aH ) :
|
||||
SHAPE( SH_RECT ), m_p0( aX0, aY0 ), m_w( aW ), m_h( aH ) {};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a rectangle defined by top-left corner p0, width w and height h.
|
||||
* Creates a rectangle defined by top-left corner aP0, width aW and height aH.
|
||||
*/
|
||||
SHAPE_RECT( const VECTOR2I &p0, int w, int h ):
|
||||
SHAPE(SH_RECT), m_p0(p0), m_w(w), m_h(h) {};
|
||||
SHAPE_RECT( const VECTOR2I &aP0, int aW, int aH ) :
|
||||
SHAPE( SH_RECT ), m_p0( aP0 ), m_w( aW ), m_h( aH ) {};
|
||||
|
||||
/// @copydoc SHAPE::BBox()
|
||||
const BOX2I BBox(int aClearance = 0) const
|
||||
{
|
||||
BOX2I bbox( VECTOR2I (m_p0.x - aClearance, m_p0.y - aClearance ),
|
||||
VECTOR2I (m_w + 2 * aClearance, m_h + 2 * aClearance ));
|
||||
BOX2I bbox( VECTOR2I( m_p0.x - aClearance, m_p0.y - aClearance ),
|
||||
VECTOR2I( m_w + 2 * aClearance, m_h + 2 * aClearance ) );
|
||||
//printf("bb : %s\n",bbox.Format().c_str());
|
||||
return bbox;
|
||||
}
|
||||
|
@ -70,11 +70,11 @@ class SHAPE_RECT : public SHAPE {
|
|||
*/
|
||||
int Diagonal() const
|
||||
{
|
||||
return VECTOR2I(m_w, m_h).EuclideanNorm();
|
||||
return VECTOR2I( m_w, m_h ).EuclideanNorm();
|
||||
}
|
||||
|
||||
/// @copydoc SHAPE::Collide()
|
||||
bool Collide(const SEG& aSeg, int aClearance = 0) const
|
||||
bool Collide( const SEG& aSeg, int aClearance = 0 ) const
|
||||
{
|
||||
//VECTOR2I pmin = VECTOR2I(std::min(aSeg.a.x, aSeg.b.x), std::min(aSeg.a.y, aSeg.b.y));
|
||||
//VECTOR2I pmax = VECTOR2I(std::max(aSeg.a.x, aSeg.b.x), std::max(aSeg.a.y, aSeg.b.y));
|
||||
|
@ -83,19 +83,19 @@ class SHAPE_RECT : public SHAPE {
|
|||
//if (BBox(0).SquaredDistance(r) > aClearance * aClearance)
|
||||
// return false;
|
||||
|
||||
if(BBox(0).Contains(aSeg.a) || BBox(0).Contains(aSeg.b))
|
||||
if( BBox( 0 ).Contains( aSeg.a ) || BBox( 0 ).Contains( aSeg.b ) )
|
||||
return true;
|
||||
|
||||
VECTOR2I vts[] = { VECTOR2I(m_p0.x, m_p0.y),
|
||||
VECTOR2I(m_p0.x, m_p0.y + m_h),
|
||||
VECTOR2I(m_p0.x + m_w, m_p0.y + m_h),
|
||||
VECTOR2I(m_p0.x + m_w, m_p0.y),
|
||||
VECTOR2I(m_p0.x, m_p0.y) };
|
||||
VECTOR2I vts[] = { VECTOR2I( m_p0.x, m_p0.y ),
|
||||
VECTOR2I( m_p0.x, m_p0.y + m_h ),
|
||||
VECTOR2I( m_p0.x + m_w, m_p0.y + m_h ),
|
||||
VECTOR2I( m_p0.x + m_w, m_p0.y ),
|
||||
VECTOR2I( m_p0.x, m_p0.y ) };
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
SEG s(vts[i], vts[i+1], i);
|
||||
if(s.Distance(aSeg) <= aClearance)
|
||||
SEG s( vts[i], vts[i + 1], i );
|
||||
if( s.Distance( aSeg ) <= aClearance )
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ class SHAPE_RECT : public SHAPE {
|
|||
*
|
||||
* @return size of the rectangle
|
||||
*/
|
||||
const VECTOR2I GetSize() const { return VECTOR2I(m_w, m_h); }
|
||||
const VECTOR2I GetSize() const { return VECTOR2I( m_w, m_h ); }
|
||||
|
||||
/**
|
||||
* Function GetWidth()
|
||||
|
@ -133,8 +133,10 @@ class SHAPE_RECT : public SHAPE {
|
|||
private:
|
||||
///> Top-left corner
|
||||
VECTOR2I m_p0;
|
||||
|
||||
///> Width
|
||||
int m_w;
|
||||
|
||||
///> Height
|
||||
int m_h;
|
||||
};
|
||||
|
|
|
@ -32,6 +32,12 @@ class TOOL_BASE;
|
|||
class TOOL_MANAGER;
|
||||
class TOOL_ACTION;
|
||||
|
||||
/**
|
||||
* Class ACTION_MANAGER
|
||||
*
|
||||
* Takes care of TOOL_ACTION objects. Registers them and allows to run them using associated
|
||||
* hot keys, names or ids.
|
||||
*/
|
||||
class ACTION_MANAGER
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -140,7 +140,7 @@ private:
|
|||
/// Menu items with ID higher than that are considered TOOL_ACTIONs
|
||||
static const int m_actionId = 10000;
|
||||
|
||||
/// Stores tool actions that are choosable from the menu. Does not take the ownership.
|
||||
/// Associates tool actions with menu item IDs. Non-owning.
|
||||
std::map<int, const TOOL_ACTION*> m_toolActions;
|
||||
};
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
static const int c_defaultStackSize = 2000000;
|
||||
static const int c_defaultStackSize = 2000000; // fixme: make configurable
|
||||
|
||||
/* real entry point of the coroutine */
|
||||
static void callerStub( intptr_t data )
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -31,10 +32,16 @@
|
|||
#include <tool/tool_base.h>
|
||||
#include <tool/action_manager.h>
|
||||
|
||||
// TOOL_ACTION - represents a single action. For instance:
|
||||
// - changing layer to top by pressing PgUp
|
||||
// - running the DRC from the menu
|
||||
// and so on, and so forth....
|
||||
/**
|
||||
* Class TOOL_ACTION
|
||||
*
|
||||
* Represents a single user action. For instance:
|
||||
* - changing layer to top by pressing PgUp
|
||||
* - running the DRC from the menu
|
||||
* and so on, and so forth....
|
||||
* Action class groups all necessary properties of an action, including explanation,
|
||||
* icons, hotkeys,.menu items, etc.
|
||||
*/
|
||||
class TOOL_ACTION
|
||||
{
|
||||
public:
|
||||
|
@ -133,13 +140,13 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Function GetEvent()
|
||||
* Function MakeEvent()
|
||||
* Returns the event associated with the action (ie. the event that will be sent after
|
||||
* activating the action).
|
||||
*
|
||||
* @return The event associated with the action.
|
||||
*/
|
||||
TOOL_EVENT GetEvent() const
|
||||
TOOL_EVENT MakeEvent() const
|
||||
{
|
||||
return TOOL_EVENT( TC_Command, TA_Action, m_name, m_scope );
|
||||
}
|
||||
|
|
|
@ -42,10 +42,10 @@ namespace KiGfx {
|
|||
* Class TOOL_DISPATCHER
|
||||
*
|
||||
* - takes wx events,
|
||||
* - fixes all wx quirks (mouse warping, etc)
|
||||
* - fixes all wx quirks (mouse warping, panning, ordering problems, etc)
|
||||
* - translates coordinates to world space
|
||||
* - low-level input conditioning (drag/click threshold), updating mouse position during view auto-scroll/pan.
|
||||
* - issues TOOL_EVENTS to the manager
|
||||
* - issues TOOL_EVENTS to the tool manager
|
||||
*/
|
||||
|
||||
class TOOL_DISPATCHER
|
||||
|
@ -100,6 +100,7 @@ private:
|
|||
///> Saves the state of key modifiers (Alt, Ctrl and so on).
|
||||
int decodeModifiers( const wxKeyboardState* aState ) const;
|
||||
|
||||
|
||||
///> Stores all the informations regarding a mouse button state.
|
||||
struct ButtonState;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
class TOOL_ACTION;
|
||||
class TOOL_MANAGER;
|
||||
|
||||
/**
|
||||
|
@ -313,6 +314,14 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IsAction()
|
||||
* Tests if the event contains an action issued upon activation of the given TOOL_ACTION.
|
||||
* @param aAction is the TOOL_ACTION to be checked against.
|
||||
* @return True if it matches the given TOOL_ACTION.
|
||||
*/
|
||||
bool IsAction( const TOOL_ACTION* aAction ) const;
|
||||
|
||||
boost::optional<int> GetCommandId()
|
||||
{
|
||||
return m_commandId;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -30,11 +31,10 @@
|
|||
|
||||
#include <math/vector2d.h>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_base.h>
|
||||
#include <tool/action_manager.h>
|
||||
|
||||
class TOOL_BASE;
|
||||
class ACTION_MANAGER;
|
||||
class CONTEXT_MENU;
|
||||
class wxWindow;
|
||||
|
||||
|
@ -89,10 +89,7 @@ public:
|
|||
*
|
||||
* @param aAction is the action to be registered.
|
||||
*/
|
||||
void RegisterAction( TOOL_ACTION* aAction )
|
||||
{
|
||||
m_actionMgr.RegisterAction( aAction );
|
||||
}
|
||||
void RegisterAction( TOOL_ACTION* aAction );
|
||||
|
||||
/**
|
||||
* Function UnregisterAction()
|
||||
|
@ -100,10 +97,7 @@ public:
|
|||
*
|
||||
* @param aAction is the action to be unregistered.
|
||||
*/
|
||||
void UnregisterAction( TOOL_ACTION* aAction )
|
||||
{
|
||||
m_actionMgr.UnregisterAction( aAction );
|
||||
}
|
||||
void UnregisterAction( TOOL_ACTION* aAction );
|
||||
|
||||
/**
|
||||
* Function FindTool()
|
||||
|
@ -205,6 +199,14 @@ private:
|
|||
|
||||
void dispatchInternal( TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function dispatchStandardEvents()
|
||||
* Handles specific events, that are intended for TOOL_MANAGER rather than tools.
|
||||
* @aEvent is the event to be processed.
|
||||
* @return False if the event was processed and should not go any further.
|
||||
*/
|
||||
bool dispatchStandardEvents( TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function dispatchActivation()
|
||||
* Checks if it is a valid activation event and invokes a proper tool.
|
||||
|
@ -215,7 +217,8 @@ private:
|
|||
|
||||
/**
|
||||
* Function invokeTool()
|
||||
* Invokes a tool by sending a proper event.
|
||||
* Invokes a tool by sending a proper event (in contrary to runTool, which makes the tool run
|
||||
* for real).
|
||||
* @param aTool is the tool to be invoked.
|
||||
*/
|
||||
bool invokeTool( TOOL_BASE* aTool );
|
||||
|
@ -291,7 +294,9 @@ private:
|
|||
/// Stack of the active tools
|
||||
std::deque<TOOL_ID> m_activeTools;
|
||||
|
||||
ACTION_MANAGER m_actionMgr;
|
||||
/// Instance of ACTION_MANAGER that handles TOOL_ACTIONs
|
||||
ACTION_MANAGER* m_actionMgr;
|
||||
|
||||
EDA_ITEM* m_model;
|
||||
KiGfx::VIEW* m_view;
|
||||
KiGfx::VIEW_CONTROLS* m_viewControls;
|
||||
|
|
|
@ -84,15 +84,16 @@ public:
|
|||
/// @copydoc VIEW_CONTROLS::GetCursorPosition()
|
||||
virtual const VECTOR2D GetCursorPosition() const;
|
||||
|
||||
/// Event that forces mouse move event in the dispatcher
|
||||
/// Event that forces mouse move event in the dispatcher (eg. used in autopanning, when mouse
|
||||
/// cursor does not move in screen coordinates, but does in world coordinates)
|
||||
static const wxEventType EVT_REFRESH_MOUSE;
|
||||
|
||||
private:
|
||||
/// Possible states for WX_VIEW_CONTROLS
|
||||
enum State {
|
||||
IDLE = 1,
|
||||
DRAG_PANNING,
|
||||
AUTO_PANNING,
|
||||
IDLE = 1, /// Nothing is happening
|
||||
DRAG_PANNING, /// Panning with mouse button pressed
|
||||
AUTO_PANNING, /// Panning on approaching borders of the frame
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef ITEM_STATE_H_
|
||||
#define ITEM_STATE_H_
|
||||
|
||||
#include <deque>
|
||||
#include <class_board_item.h>
|
||||
|
||||
/**
|
||||
* Class ITEM_STATE
|
||||
*
|
||||
|
@ -29,13 +35,6 @@
|
|||
* the introduced changes. Does not take ownership of modified items, neither takes care of
|
||||
* refreshing.
|
||||
*/
|
||||
|
||||
#ifndef ITEM_STATE_H_
|
||||
#define ITEM_STATE_H_
|
||||
|
||||
#include <deque>
|
||||
#include <class_board_item.h>
|
||||
|
||||
class ITEM_STATE
|
||||
{
|
||||
public:
|
||||
|
@ -278,4 +277,3 @@ private:
|
|||
};
|
||||
|
||||
#endif /* ITEM_STATE_H_ */
|
||||
|
|
@ -53,7 +53,7 @@ MOVE_TOOL::~MOVE_TOOL()
|
|||
void MOVE_TOOL::Reset()
|
||||
{
|
||||
// The tool launches upon reception of action event ("pcbnew.InteractiveMove")
|
||||
Go( &MOVE_TOOL::Main, m_activate.GetEvent() );
|
||||
Go( &MOVE_TOOL::Main, m_activate.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,12 +115,12 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
|
|||
{
|
||||
VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() );
|
||||
|
||||
if( evt->Matches( m_rotate.GetEvent() ) ) // got rotation event?
|
||||
if( evt->IsAction( &m_rotate ) ) // got rotation event?
|
||||
{
|
||||
m_state.Rotate( cursorPos, 900.0 );
|
||||
m_items.ViewUpdate( VIEW_ITEM::GEOMETRY );
|
||||
}
|
||||
else if( evt->Matches( m_flip.GetEvent() ) ) // got flip event?
|
||||
else if( evt->IsAction( &m_flip ) ) // got flip event?
|
||||
{
|
||||
m_state.Flip( cursorPos );
|
||||
m_items.ViewUpdate( VIEW_ITEM::GEOMETRY );
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
#include <math/vector2d.h>
|
||||
#include <tool/tool_interactive.h>
|
||||
#include <tool/item_state.h>
|
||||
#include <view/view_group.h>
|
||||
#include "item_state.h"
|
||||
|
||||
class BOARD_ITEM;
|
||||
class SELECTION_TOOL;
|
||||
|
|
|
@ -68,7 +68,7 @@ void SELECTION_TOOL::Reset()
|
|||
m_selectedItems.clear();
|
||||
|
||||
// The tool launches upon reception of action event ("pcbnew.InteractiveSelection")
|
||||
Go( &SELECTION_TOOL::Main, m_activate.GetEvent() );
|
||||
Go( &SELECTION_TOOL::Main, m_activate.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,7 +266,7 @@ bool SELECTION_TOOL::selectMultiple()
|
|||
VIEW* view = getView();
|
||||
getViewControls()->SetAutoPan( true );
|
||||
|
||||
// Those 2 lines remove the blink-in-the-random-place effect
|
||||
// These 2 lines remove the blink-in-the-random-place effect
|
||||
m_selArea->SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
m_selArea->SetEnd( VECTOR2I( 0, 0 ) );
|
||||
view->Add( m_selArea );
|
||||
|
@ -467,7 +467,6 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
// All other items are selected only if the layer on which they exist is visible
|
||||
return board->IsLayerVisible( aItem->GetLayer() );
|
||||
}
|
||||
|
@ -475,12 +474,14 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
|||
|
||||
bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const
|
||||
{
|
||||
const unsigned GRIP_MARGIN = 500000;
|
||||
|
||||
// Check if the point is located within any of the currently selected items bounding boxes
|
||||
std::set<BOARD_ITEM*>::iterator it, it_end;
|
||||
for( it = m_selectedItems.begin(), it_end = m_selectedItems.end(); it != it_end; ++it )
|
||||
{
|
||||
BOX2I itemBox = (*it)->ViewBBox();
|
||||
itemBox.Inflate( 500000 ); // Give some margin for gripping an item
|
||||
itemBox.Inflate( GRIP_MARGIN ); // Give some margin for gripping an item
|
||||
|
||||
if( itemBox.Contains( aPoint ) )
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue