Even more code comments and reformatting.
This commit is contained in:
parent
3f320e4d68
commit
6b74b5771a
|
@ -31,36 +31,36 @@
|
||||||
|
|
||||||
typedef VECTOR2I::extended_type ecoord;
|
typedef VECTOR2I::extended_type ecoord;
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance,
|
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_CIRCLE& aB, int aClearance,
|
||||||
bool needMTV, VECTOR2I& aMTV )
|
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;
|
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();
|
ecoord dist_sq = delta.SquaredEuclideanNorm();
|
||||||
|
|
||||||
if ( dist_sq >= min_dist_sq )
|
if ( dist_sq >= min_dist_sq )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( needMTV )
|
if ( aNeedMTV )
|
||||||
aMTV = delta.Resize( sqrt ( abs( min_dist_sq - dist_sq ) ) + 1 );
|
aMTV = delta.Resize( sqrt ( abs( min_dist_sq - dist_sq ) ) + 1 );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance,
|
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CIRCLE& aB, int aClearance,
|
||||||
bool needMTV, VECTOR2I& aMTV )
|
bool aNeedMTV, VECTOR2I& aMTV )
|
||||||
{
|
{
|
||||||
const VECTOR2I c = b.GetCenter();
|
const VECTOR2I c = aB.GetCenter();
|
||||||
const VECTOR2I p0 = a.GetPosition();
|
const VECTOR2I p0 = aA.GetPosition();
|
||||||
const VECTOR2I size = a.GetSize();
|
const VECTOR2I size = aA.GetSize();
|
||||||
const ecoord r = b.GetRadius();
|
const ecoord r = aB.GetRadius();
|
||||||
const ecoord min_dist = clearance + r;
|
const ecoord min_dist = aClearance + r;
|
||||||
const ecoord min_dist_sq = min_dist * min_dist;
|
const ecoord min_dist_sq = min_dist * min_dist;
|
||||||
|
|
||||||
if ( a.BBox( 0 ).Contains( c ) )
|
if ( aA.BBox( 0 ).Contains( c ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const VECTOR2I vts[] = {
|
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( dist_sq < min_dist_sq )
|
||||||
{
|
{
|
||||||
if( !needMTV )
|
if( !aNeedMTV )
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -102,7 +102,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
|
||||||
|
|
||||||
VECTOR2I delta = c - nearest;
|
VECTOR2I delta = c - nearest;
|
||||||
|
|
||||||
if( !needMTV )
|
if( !aNeedMTV )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( inside )
|
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,
|
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
||||||
bool needMTV, VECTOR2I& aMTV )
|
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;
|
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,
|
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
||||||
bool needMTV, VECTOR2I& aMTV )
|
bool aNeedMTV, VECTOR2I& aMTV )
|
||||||
{
|
{
|
||||||
for( int i = 0; i < b.SegmentCount(); i++ )
|
for( int i = 0; i < aB.SegmentCount(); i++ )
|
||||||
if( a.Collide( b.CSegment(i), clearance ) )
|
if( aA.Collide( aB.CSegment(i), aClearance ) )
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance,
|
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
||||||
bool needMTV, VECTOR2I& aMTV )
|
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 );
|
SEG seg = aB.CSegment( s );
|
||||||
if( a.Collide( seg, clearance ) )
|
if( aA.Collide( seg, aClearance ) )
|
||||||
return true;
|
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:
|
case SH_RECT:
|
||||||
switch( b->Type() )
|
switch( aB->Type() )
|
||||||
{
|
{
|
||||||
case SH_CIRCLE:
|
case SH_CIRCLE:
|
||||||
return Collide( *static_cast<const SHAPE_RECT*>( a ),
|
return Collide( *static_cast<const SHAPE_RECT*>( aA ),
|
||||||
*static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_CIRCLE*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
case SH_LINE_CHAIN:
|
case SH_LINE_CHAIN:
|
||||||
return Collide( *static_cast<const SHAPE_RECT*>( a ),
|
return Collide( *static_cast<const SHAPE_RECT*>( aA ),
|
||||||
*static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SH_CIRCLE:
|
case SH_CIRCLE:
|
||||||
switch( b->Type() )
|
switch( aB->Type() )
|
||||||
{
|
{
|
||||||
case SH_RECT:
|
case SH_RECT:
|
||||||
return Collide( *static_cast<const SHAPE_RECT*>( b ),
|
return Collide( *static_cast<const SHAPE_RECT*>( aB ),
|
||||||
*static_cast<const SHAPE_CIRCLE*>( a ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_CIRCLE*>( aA ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
case SH_CIRCLE:
|
case SH_CIRCLE:
|
||||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( a ),
|
return Collide( *static_cast<const SHAPE_CIRCLE*>( aA ),
|
||||||
*static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_CIRCLE*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
case SH_LINE_CHAIN:
|
case SH_LINE_CHAIN:
|
||||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( a ),
|
return Collide( *static_cast<const SHAPE_CIRCLE*>( aA ),
|
||||||
*static_cast<const SHAPE_LINE_CHAIN *>( b ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_LINE_CHAIN *>( aB ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SH_LINE_CHAIN:
|
case SH_LINE_CHAIN:
|
||||||
switch( b->Type() )
|
switch( aB->Type() )
|
||||||
{
|
{
|
||||||
case SH_RECT:
|
case SH_RECT:
|
||||||
return Collide( *static_cast<const SHAPE_RECT*>( b ),
|
return Collide( *static_cast<const SHAPE_RECT*>( aB ),
|
||||||
*static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_LINE_CHAIN*>( aA ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
case SH_CIRCLE:
|
case SH_CIRCLE:
|
||||||
return Collide( *static_cast<const SHAPE_CIRCLE*>( b ),
|
return Collide( *static_cast<const SHAPE_CIRCLE*>( aB ),
|
||||||
*static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_LINE_CHAIN*>( aA ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
case SH_LINE_CHAIN:
|
case SH_LINE_CHAIN:
|
||||||
return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( a ),
|
return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( aA ),
|
||||||
*static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV );
|
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -99,6 +99,7 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
|
||||||
|
|
||||||
void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const
|
void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const
|
||||||
{
|
{
|
||||||
TOOL_EVENT event = aAction->GetEvent();
|
TOOL_EVENT event = aAction->MakeEvent();
|
||||||
|
|
||||||
m_toolMgr->ProcessEvent( event );
|
m_toolMgr->ProcessEvent( event );
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,24 +151,28 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
|
||||||
TOOL_EVENT evt;
|
TOOL_EVENT evt;
|
||||||
wxEventType type = aEvent.GetEventType();
|
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 )
|
if( type == wxEVT_MENU_HIGHLIGHT )
|
||||||
evt = TOOL_EVENT( TC_Command, TA_ContextMenuUpdate, aEvent.GetId() );
|
evt = TOOL_EVENT( TC_Command, TA_ContextMenuUpdate, aEvent.GetId() );
|
||||||
|
|
||||||
|
// One of menu entries was selected..
|
||||||
else if( type == wxEVT_COMMAND_MENU_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
|
evt = m_menu->m_toolActions[aEvent.GetId()]->MakeEvent();
|
||||||
if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 )
|
|
||||||
evt = m_menu->m_toolActions[aEvent.GetId()]->GetEvent();
|
|
||||||
}
|
}
|
||||||
else
|
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() );
|
evt = TOOL_EVENT( TC_Command, TA_ContextMenuChoice, aEvent.GetId() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// forward the action/update event to the TOOL_MANAGER
|
||||||
if( m_menu->m_tool )
|
if( m_menu->m_tool )
|
||||||
m_menu->m_tool->GetManager()->ProcessEvent( evt );
|
m_menu->m_tool->GetManager()->ProcessEvent( evt );
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
|
|
||||||
|
///> Stores information about a mouse button state
|
||||||
struct TOOL_DISPATCHER::ButtonState
|
struct TOOL_DISPATCHER::ButtonState
|
||||||
{
|
{
|
||||||
ButtonState( TOOL_MouseButtons aButton, const wxEventType& aDownEvent,
|
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_LEFT_DOWN || type == wxEVT_LEFT_UP ||
|
||||||
type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP ||
|
type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP ||
|
||||||
type == wxEVT_RIGHT_DOWN || type == wxEVT_RIGHT_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 )
|
type == KiGfx::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
|
||||||
{
|
{
|
||||||
VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition();
|
VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition();
|
||||||
|
@ -247,7 +250,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
|
||||||
|
|
||||||
if( type == wxEVT_KEY_UP )
|
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 );
|
evt = TOOL_EVENT( TC_Command, TA_CancelTool );
|
||||||
else
|
else
|
||||||
evt = TOOL_EVENT( TC_Keyboard, TA_KeyUp, key | mods );
|
evt = TOOL_EVENT( TC_Keyboard, TA_KeyUp, key | mods );
|
||||||
|
@ -261,6 +264,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
|
||||||
if( evt )
|
if( evt )
|
||||||
m_toolMgr->ProcessEvent( *evt );
|
m_toolMgr->ProcessEvent( *evt );
|
||||||
|
|
||||||
|
// pass the event to the GUI, it might still be interested in it
|
||||||
aEvent.Skip();
|
aEvent.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +274,7 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
|
||||||
bool activateTool = false;
|
bool activateTool = false;
|
||||||
std::string toolName;
|
std::string toolName;
|
||||||
|
|
||||||
|
// fixme: use TOOL_ACTIONs here
|
||||||
switch( aEvent.GetId() )
|
switch( aEvent.GetId() )
|
||||||
{
|
{
|
||||||
case ID_PNS_ROUTER_TOOL:
|
case ID_PNS_ROUTER_TOOL:
|
||||||
|
@ -282,6 +287,7 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do nothing if the legacy view is active
|
||||||
if( activateTool && m_editFrame->IsGalCanvasActive() )
|
if( activateTool && m_editFrame->IsGalCanvasActive() )
|
||||||
m_toolMgr->InvokeTool( toolName );
|
m_toolMgr->InvokeTool( toolName );
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,8 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
//#include <base_struct.h>
|
|
||||||
|
|
||||||
#include <tool/tool_event.h>
|
#include <tool/tool_event.h>
|
||||||
|
#include <tool/tool_action.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#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
|
const std::string TOOL_EVENT::Format() const
|
||||||
{
|
{
|
||||||
std::string ev;
|
std::string ev;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tool/context_menu.h>
|
#include <tool/context_menu.h>
|
||||||
#include <tool/coroutine.h>
|
#include <tool/coroutine.h>
|
||||||
|
#include <tool/action_manager.h>
|
||||||
|
|
||||||
#include <wxPcbStruct.h>
|
#include <wxPcbStruct.h>
|
||||||
#include <class_drawpanel_gal.h>
|
#include <class_drawpanel_gal.h>
|
||||||
|
@ -46,37 +48,38 @@
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
using namespace std;
|
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
|
struct TOOL_MANAGER::TOOL_STATE
|
||||||
{
|
{
|
||||||
/// The tool itself
|
/// The tool itself
|
||||||
TOOL_BASE* theTool;
|
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;
|
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;
|
bool pendingWait;
|
||||||
|
|
||||||
/// Is there a context menu to be displayed
|
/// Is there a context menu being displayed
|
||||||
bool pendingContextMenu;
|
bool pendingContextMenu;
|
||||||
|
|
||||||
/// Context menu used by the tool
|
/// Context menu currently used by the tool
|
||||||
CONTEXT_MENU* contextMenu;
|
CONTEXT_MENU* contextMenu;
|
||||||
|
|
||||||
/// Defines when a context menu is opened
|
/// Defines when the context menu is opened
|
||||||
CONTEXT_MENU_TRIGGER contextMenuTrigger;
|
CONTEXT_MENU_TRIGGER contextMenuTrigger;
|
||||||
|
|
||||||
/// Coroutine launched upon an event trigger
|
/// Tool execution context
|
||||||
COROUTINE<int, TOOL_EVENT&>* cofunc;
|
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;
|
TOOL_EVENT wakeupEvent;
|
||||||
|
|
||||||
/// List of events that are triggering the coroutine
|
/// List of events the tool is currently waiting for
|
||||||
TOOL_EVENT_LIST waitEvents;
|
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
|
/// upon the event reception
|
||||||
std::vector<TRANSITION> transitions;
|
std::vector<TRANSITION> transitions;
|
||||||
|
|
||||||
|
@ -93,8 +96,9 @@ struct TOOL_MANAGER::TOOL_STATE
|
||||||
|
|
||||||
|
|
||||||
TOOL_MANAGER::TOOL_MANAGER() :
|
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->second; // delete TOOL_STATE
|
||||||
delete it->first; // delete the tool itself
|
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 )
|
if( tool && tool->GetType() == TOOL_Interactive )
|
||||||
return invokeTool( tool );
|
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 )
|
if( tool && tool->GetType() == TOOL_Interactive )
|
||||||
return invokeTool( tool );
|
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 )
|
if( tool && tool->GetType() == TOOL_Interactive )
|
||||||
return runTool( tool );
|
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 )
|
if( tool && tool->GetType() == TOOL_Interactive )
|
||||||
return runTool( tool );
|
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];
|
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->pendingWait = true;
|
||||||
st->waitEvents = aConditions;
|
st->waitEvents = aConditions;
|
||||||
|
|
||||||
|
// switch context back to event dispatcher loop
|
||||||
st->cofunc->Yield();
|
st->cofunc->Yield();
|
||||||
|
|
||||||
return st->wakeupEvent;
|
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 )
|
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 )
|
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
|
||||||
|
@ -313,6 +335,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
st->transitions.clear();
|
st->transitions.clear();
|
||||||
|
|
||||||
|
// no tool context allocated yet? Create one.
|
||||||
if( !st->cofunc )
|
if( !st->cofunc )
|
||||||
st->cofunc = new COROUTINE<int, TOOL_EVENT&>( tr.second );
|
st->cofunc = new COROUTINE<int, TOOL_EVENT&>( tr.second );
|
||||||
else
|
else
|
||||||
|
@ -322,7 +345,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
||||||
st->cofunc->Call( aEvent );
|
st->cofunc->Call( aEvent );
|
||||||
|
|
||||||
if( !st->cofunc->Running() )
|
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 )
|
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 )
|
BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values )
|
||||||
{
|
{
|
||||||
if( st->theTool->GetName() == aEvent.m_commandStr )
|
if( st->theTool->GetName() == aEvent.m_commandStr )
|
||||||
|
@ -359,7 +401,7 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
|
||||||
if( it != m_activeTools.end() )
|
if( it != m_activeTools.end() )
|
||||||
m_activeTools.erase( it );
|
m_activeTools.erase( it );
|
||||||
else
|
else
|
||||||
wxLogWarning( wxT( "Tried to finish not active tool" ) );
|
wxLogWarning( wxT( "Tried to finish inactive tool" ) );
|
||||||
|
|
||||||
aState->idle = true;
|
aState->idle = true;
|
||||||
delete aState->cofunc;
|
delete aState->cofunc;
|
||||||
|
@ -371,22 +413,19 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
// wxLogDebug( "event: %s", aEvent.Format().c_str() );
|
// wxLogDebug( "event: %s", aEvent.Format().c_str() );
|
||||||
|
|
||||||
if( aEvent.Action() == TA_KeyUp )
|
// Early dispatch of events destined for the TOOL_MANAGER
|
||||||
{
|
if( !dispatchStandardEvents( aEvent ) )
|
||||||
// Check if there is a hotkey associated
|
return false;
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatchInternal( aEvent );
|
dispatchInternal( aEvent );
|
||||||
|
|
||||||
|
// popup menu handling
|
||||||
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
|
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
|
||||||
{
|
{
|
||||||
TOOL_STATE* st = m_toolIdIndex[toolId];
|
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_OFF )
|
||||||
{
|
{
|
||||||
if( st->contextMenuTrigger == CMENU_BUTTON && !aEvent.IsClick( MB_Right ) )
|
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 ) );
|
boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *st->contextMenu ) );
|
||||||
GetEditFrame()->PopupMenu( menu->GetMenu() );
|
GetEditFrame()->PopupMenu( menu->GetMenu() );
|
||||||
|
|
||||||
|
//
|
||||||
TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice );
|
TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice );
|
||||||
dispatchInternal( evt );
|
dispatchInternal( evt );
|
||||||
|
|
||||||
|
@ -426,6 +466,7 @@ void TOOL_MANAGER::ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu,
|
||||||
st->contextMenu = aMenu;
|
st->contextMenu = aMenu;
|
||||||
st->contextMenuTrigger = aTrigger;
|
st->contextMenuTrigger = aTrigger;
|
||||||
|
|
||||||
|
// the tool wants the menu immediately? Preempt it and do so :)
|
||||||
if( aTrigger == CMENU_NOW )
|
if( aTrigger == CMENU_NOW )
|
||||||
st->cofunc->Yield();
|
st->cofunc->Yield();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
|
|
||||||
typedef boost::optional<VECTOR2I> OPT_VECTOR2I;
|
typedef boost::optional<VECTOR2I> OPT_VECTOR2I;
|
||||||
|
|
||||||
class SEG {
|
class SEG
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
typedef VECTOR2I::extended_type ecoord;
|
typedef VECTOR2I::extended_type ecoord;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class SEG {
|
||||||
/** Default constructor
|
/** Default constructor
|
||||||
* Creates an empty (0, 0) segment, locally-referenced
|
* 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;
|
a = m_a;
|
||||||
b = m_b;
|
b = m_b;
|
||||||
|
@ -62,12 +62,12 @@ class SEG {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* 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_a = VECTOR2I( aX1, aY1 );
|
||||||
m_b = VECTOR2I(x2, y2);
|
m_b = VECTOR2I( aX2, aY2 );
|
||||||
a = m_a;
|
a = m_a;
|
||||||
b = m_b;
|
b = m_b;
|
||||||
m_is_local = true;
|
m_is_local = true;
|
||||||
|
@ -78,7 +78,7 @@ class SEG {
|
||||||
* Constructor
|
* Constructor
|
||||||
* Creates a segment between (aA) and (aB), locally referenced
|
* 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;
|
a = m_a;
|
||||||
b = m_b;
|
b = m_b;
|
||||||
|
@ -93,7 +93,7 @@ class SEG {
|
||||||
* @param aB reference to the end point in the parent shape
|
* @param aB reference to the end point in the parent shape
|
||||||
* @param aIndex index of the segment within 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_is_local = false;
|
||||||
m_index = aIndex;
|
m_index = aIndex;
|
||||||
|
@ -102,32 +102,32 @@ class SEG {
|
||||||
/**
|
/**
|
||||||
* Copy constructor
|
* 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_a = aSeg.m_a;
|
||||||
m_b = seg.m_b;
|
m_b = aSeg.m_b;
|
||||||
a = m_a;
|
a = m_a;
|
||||||
b = m_b;
|
b = m_b;
|
||||||
m_is_local = true;
|
m_is_local = true;
|
||||||
m_index = -1;
|
m_index = -1;
|
||||||
} else {
|
} else {
|
||||||
a = seg.a;
|
a = aSeg.a;
|
||||||
b = seg.b;
|
b = aSeg.b;
|
||||||
m_index = seg.m_index;
|
m_index = aSeg.m_index;
|
||||||
m_is_local = false;
|
m_is_local = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SEG& operator=(const SEG& seg)
|
SEG& operator=( const SEG& aSeg )
|
||||||
{
|
{
|
||||||
a = seg.a;
|
a = aSeg.a;
|
||||||
b = seg.b;
|
b = aSeg.b;
|
||||||
m_a = seg.m_a;
|
m_a = aSeg.m_a;
|
||||||
m_b = seg.m_b;
|
m_b = aSeg.m_b;
|
||||||
m_index = seg.m_index;
|
m_index = aSeg.m_index;
|
||||||
m_is_local = seg.m_is_local;
|
m_is_local = aSeg.m_is_local;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,8 +150,9 @@ class SEG {
|
||||||
*/
|
*/
|
||||||
int Side( const VECTOR2I& aP ) const
|
int Side( const VECTOR2I& aP ) const
|
||||||
{
|
{
|
||||||
const ecoord det = (b - a).Cross(aP - a);
|
const ecoord det = ( b - a ).Cross( aP - a );
|
||||||
return det < 0 ? -1 : (det > 0 ? 1 : 0);
|
|
||||||
|
return det < 0 ? -1 : ( det > 0 ? 1 : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,7 +174,6 @@ class SEG {
|
||||||
*/
|
*/
|
||||||
const VECTOR2I NearestPoint( const VECTOR2I &aP ) const;
|
const VECTOR2I NearestPoint( const VECTOR2I &aP ) const;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Intersect()
|
* Function Intersect()
|
||||||
*
|
*
|
||||||
|
@ -186,8 +186,6 @@ class SEG {
|
||||||
*/
|
*/
|
||||||
OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false ) const;
|
OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false ) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function IntersectLines()
|
* Function IntersectLines()
|
||||||
*
|
*
|
||||||
|
@ -195,9 +193,9 @@ class SEG {
|
||||||
* @param aSeg segment defining the line to intersect with
|
* @param aSeg segment defining the line to intersect with
|
||||||
* @return intersection point, if exists
|
* @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;
|
bool Collide( const SEG& aSeg, int aClearance ) const;
|
||||||
|
@ -210,14 +208,13 @@ class SEG {
|
||||||
* @return minimum distance
|
* @return minimum distance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ecoord SquaredDistance( const SEG& aSeg ) const ;
|
ecoord SquaredDistance( const SEG& aSeg ) const;
|
||||||
|
|
||||||
int Distance( const SEG& aSeg ) const
|
int Distance( const SEG& aSeg ) const
|
||||||
{
|
{
|
||||||
return sqrt ( SquaredDistance(aSeg) );
|
return sqrt( SquaredDistance( aSeg ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Distance()
|
* Function Distance()
|
||||||
*
|
*
|
||||||
|
@ -225,18 +222,16 @@ class SEG {
|
||||||
* @param aP the point
|
* @param aP the point
|
||||||
* @return minimum distance
|
* @return minimum distance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ecoord SquaredDistance( const VECTOR2I& aP ) const
|
ecoord SquaredDistance( const VECTOR2I& aP ) const
|
||||||
{
|
{
|
||||||
return (NearestPoint(aP) - aP).SquaredEuclideanNorm();
|
return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Distance( const VECTOR2I& aP ) const
|
int Distance( const VECTOR2I& aP ) const
|
||||||
{
|
{
|
||||||
return sqrt ( SquaredDistance( aP) );
|
return sqrt( SquaredDistance( aP ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Collinear()
|
* Function Collinear()
|
||||||
*
|
*
|
||||||
|
@ -244,7 +239,6 @@ class SEG {
|
||||||
* @param aSeg the segment to chech colinearity with
|
* @param aSeg the segment to chech colinearity with
|
||||||
* @return true, when segments are collinear.
|
* @return true, when segments are collinear.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Collinear( const SEG& aSeg ) const
|
bool Collinear( const SEG& aSeg ) const
|
||||||
{
|
{
|
||||||
ecoord qa1 = a.y - b.y;
|
ecoord qa1 = a.y - b.y;
|
||||||
|
@ -254,7 +248,7 @@ class SEG {
|
||||||
ecoord qb2 = aSeg.b.x - aSeg.a.x;
|
ecoord qb2 = aSeg.b.x - aSeg.a.x;
|
||||||
ecoord qc2 = -qa2 * aSeg.a.x - qb2 * aSeg.a.y;
|
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
|
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()
|
* Function Index()
|
||||||
*
|
*
|
||||||
|
@ -285,20 +278,20 @@ class SEG {
|
||||||
return m_index;
|
return m_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Contains( const VECTOR2I& aP ) const;
|
||||||
|
|
||||||
bool Contains(const VECTOR2I& aP) const;
|
bool PointCloserThan( const VECTOR2I& aP, int aDist ) const;
|
||||||
|
|
||||||
bool PointCloserThan ( const VECTOR2I& aP, int dist) const;
|
|
||||||
|
|
||||||
// friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
|
// friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
|
||||||
private:
|
private:
|
||||||
|
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
|
||||||
bool ccw ( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I &c ) const;
|
|
||||||
|
|
||||||
///> locally stored start/end coordinates (used when m_is_local == true)
|
///> locally stored start/end coordinates (used when m_is_local == true)
|
||||||
VECTOR2I m_a, m_b;
|
VECTOR2I m_a, m_b;
|
||||||
|
|
||||||
///> index withing the parent shape (used when m_is_local == false)
|
///> index withing the parent shape (used when m_is_local == false)
|
||||||
int m_index;
|
int m_index;
|
||||||
|
|
||||||
///> locality flag
|
///> locality flag
|
||||||
bool m_is_local;
|
bool m_is_local;
|
||||||
};
|
};
|
||||||
|
@ -306,49 +299,47 @@ class SEG {
|
||||||
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
||||||
{
|
{
|
||||||
// fixme: numerical errors for large integers
|
// fixme: numerical errors for large integers
|
||||||
assert(false);
|
assert( false );
|
||||||
return VECTOR2I(0, 0);
|
return VECTOR2I( 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
||||||
{
|
{
|
||||||
ecoord p = a.y - b.y;
|
ecoord p = a.y - b.y;
|
||||||
ecoord q = b.x - a.x;
|
ecoord q = b.x - a.x;
|
||||||
ecoord r = -p * a.x - q * a.y;
|
ecoord r = -p * a.x - q * a.y;
|
||||||
|
|
||||||
ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q );
|
ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q );
|
||||||
return aDetermineSide ? dist : abs(dist);
|
|
||||||
|
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;
|
VECTOR2I d = b - a;
|
||||||
ecoord l_squared = d.Dot(d);
|
ecoord l_squared = d.Dot( d );
|
||||||
|
|
||||||
if( l_squared == 0 )
|
if( l_squared == 0 )
|
||||||
return a;
|
return a;
|
||||||
|
|
||||||
ecoord t = d.Dot(aP - a);
|
ecoord t = d.Dot( aP - a );
|
||||||
|
|
||||||
if( t < 0 )
|
if( t < 0 )
|
||||||
return a;
|
return a;
|
||||||
else if( t > l_squared )
|
else if( t > l_squared )
|
||||||
return b;
|
return b;
|
||||||
|
|
||||||
int xp = rescale(t, (ecoord)d.x, l_squared);
|
int xp = rescale( t, (ecoord)d.x, l_squared );
|
||||||
int yp = rescale(t, (ecoord)d.y, 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 )
|
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 << " ]";
|
aStream << "[ local " << aSeg.a << " - " << aSeg.b << " ]";
|
||||||
|
|
||||||
return aStream;
|
return aStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ enum ShapeType {
|
||||||
/**
|
/**
|
||||||
* Class SHAPE
|
* Class SHAPE
|
||||||
*
|
*
|
||||||
* Represents an abstract shape on 2D plane. All SHAPEs implement SHAPE interface.
|
* Represents an abstract shape on 2D plane.
|
||||||
*/
|
*/
|
||||||
class SHAPE {
|
class SHAPE {
|
||||||
protected:
|
protected:
|
||||||
|
@ -58,7 +58,7 @@ class SHAPE {
|
||||||
* Creates an empty shape of type aType
|
* Creates an empty shape of type aType
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SHAPE ( ShapeType aType ): m_type( aType ) { };
|
SHAPE ( ShapeType aType ) : m_type( aType ) { };
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
virtual ~SHAPE() {};
|
virtual ~SHAPE() {};
|
||||||
|
@ -78,7 +78,7 @@ class SHAPE {
|
||||||
* @retval copy of the shape
|
* @retval copy of the shape
|
||||||
*/
|
*/
|
||||||
virtual SHAPE* Clone() const {
|
virtual SHAPE* Clone() const {
|
||||||
assert(false);
|
assert( false );
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -89,9 +89,9 @@ class SHAPE {
|
||||||
* a collision.
|
* a collision.
|
||||||
* @return true, if there is 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
|
* Checks if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating
|
||||||
* a collision.
|
* 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.
|
* @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, VECTOR2I& aMTV ) const;
|
||||||
virtual bool Collide ( const SHAPE *aShape, int aClerance = 0 ) const;
|
virtual bool Collide( const SHAPE* aShape, int aClerance = 0 ) const;
|
||||||
/**
|
/**
|
||||||
* Function Collide()
|
* Function Collide()
|
||||||
*
|
*
|
||||||
|
@ -110,7 +113,7 @@ class SHAPE {
|
||||||
* a collision.
|
* a collision.
|
||||||
* @return true, if there is 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()
|
* 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.
|
* @aClearance how much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape.
|
||||||
* @return the bounding box.
|
* @return the bounding box.
|
||||||
*/
|
*/
|
||||||
virtual const BOX2I BBox ( int aClearance = 0 ) const = 0;
|
virtual const BOX2I BBox( int aClearance = 0 ) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Centre()
|
* Function Centre()
|
||||||
|
@ -130,7 +133,7 @@ class SHAPE {
|
||||||
*/
|
*/
|
||||||
virtual VECTOR2I Centre() const
|
virtual VECTOR2I Centre() const
|
||||||
{
|
{
|
||||||
return BBox(0).Centre(); // if nothing better is available....
|
return BBox( 0 ).Centre(); // if nothing better is available....
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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
|
#endif // __SHAPE_H
|
||||||
|
|
|
@ -31,32 +31,31 @@ class SHAPE_CIRCLE : public SHAPE {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHAPE_CIRCLE():
|
SHAPE_CIRCLE():
|
||||||
SHAPE( SH_CIRCLE ), m_radius (0) {};
|
SHAPE( SH_CIRCLE ), m_radius( 0 ) {};
|
||||||
|
|
||||||
SHAPE_CIRCLE( const VECTOR2I& aCenter, int aRadius ):
|
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() {};
|
~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);
|
const VECTOR2I rc( m_radius + aClearance, m_radius + aClearance );
|
||||||
return BOX2I (m_center - rc, rc * 2);
|
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;
|
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;
|
m_radius = aRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCenter (const VECTOR2I& aCenter)
|
void SetCenter( const VECTOR2I& aCenter )
|
||||||
{
|
{
|
||||||
m_center = 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.
|
* @return a BOX2I object containing the bounding box of the T object.
|
||||||
*/
|
*/
|
||||||
template <class T>
|
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
|
* @param visitor V visitor object
|
||||||
*/
|
*/
|
||||||
template <class T, class V>
|
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
|
* @return if object and anotherObject collide
|
||||||
*/
|
*/
|
||||||
template<class T, class U>
|
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>
|
template<class T, class V>
|
||||||
bool queryCallback(T shape, void* context)
|
bool queryCallback( T aShape, void* aContext )
|
||||||
{
|
{
|
||||||
V* visitor = (V*) context;
|
V* visitor = (V*) aContext;
|
||||||
acceptVisitor<T,V>( shape, *visitor );
|
acceptVisitor<T,V>( aShape, *visitor );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T = SHAPE*>
|
template<class T = SHAPE*>
|
||||||
class SHAPE_INDEX {
|
class SHAPE_INDEX
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
class Iterator
|
class Iterator
|
||||||
{
|
{
|
||||||
|
@ -123,9 +124,9 @@ class SHAPE_INDEX {
|
||||||
* Setup the internal tree iterator.
|
* Setup the internal tree iterator.
|
||||||
* @param tree pointer to a RTREE object
|
* @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:
|
public:
|
||||||
|
@ -135,9 +136,9 @@ class SHAPE_INDEX {
|
||||||
* Creates an iterator for the index object
|
* Creates an iterator for the index object
|
||||||
* @param index SHAPE_INDEX object to iterate
|
* @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>
|
template<class T>
|
||||||
void SHAPE_INDEX<T>::Remove(T aShape)
|
void SHAPE_INDEX<T>::Remove( T aShape )
|
||||||
{
|
{
|
||||||
BOX2I box = boundingBox( aShape );
|
BOX2I box = boundingBox( aShape );
|
||||||
int min[2] = { box.GetX(), box.GetY() };
|
int min[2] = { box.GetX(), box.GetY() };
|
||||||
|
|
|
@ -27,30 +27,29 @@
|
||||||
|
|
||||||
#include <boost/unordered_map.hpp>
|
#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();
|
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 {
|
class SHAPE_INDEX_LIST {
|
||||||
|
|
||||||
struct ShapeEntry {
|
struct ShapeEntry {
|
||||||
ShapeEntry(T aParent)
|
ShapeEntry( T aParent )
|
||||||
{
|
{
|
||||||
shape = ShapeFunctor(aParent);
|
shape = ShapeFunctor( aParent );
|
||||||
bbox = shape->BBox(0);
|
bbox = shape->BBox( 0 );
|
||||||
parent = aParent;
|
parent = aParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ShapeEntry()
|
~ShapeEntry()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T parent;
|
T parent;
|
||||||
const SHAPE *shape;
|
const SHAPE* shape;
|
||||||
BOX2I bbox;
|
BOX2I bbox;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,18 +57,16 @@ class SHAPE_INDEX_LIST {
|
||||||
typedef typename std::vector<ShapeEntry>::iterator ShapeVecIter;
|
typedef typename std::vector<ShapeEntry>::iterator ShapeVecIter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// "Normal" iterator interface, for STL algorithms.
|
||||||
// "Normal" iterator interface, for STL algorithms.
|
|
||||||
class iterator {
|
class iterator {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
iterator() {};
|
iterator() {};
|
||||||
|
|
||||||
iterator( ShapeVecIter aCurrent)
|
iterator( ShapeVecIter aCurrent )
|
||||||
: m_current(aCurrent) {};
|
: m_current( aCurrent ) {};
|
||||||
|
|
||||||
iterator(const iterator &b) :
|
iterator( const iterator &aB ) :
|
||||||
m_current(b.m_current) {};
|
m_current( aB.m_current ) {};
|
||||||
|
|
||||||
T operator*() const
|
T operator*() const
|
||||||
{
|
{
|
||||||
|
@ -81,25 +78,25 @@ public:
|
||||||
++m_current;
|
++m_current;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator& operator++(int dummy)
|
iterator& operator++( int aDummy )
|
||||||
{
|
{
|
||||||
++m_current;
|
++m_current;
|
||||||
return *this;
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,40 +104,37 @@ public:
|
||||||
ShapeVecIter m_current;
|
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 {
|
class query_iterator {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
query_iterator()
|
query_iterator()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query_iterator( ShapeVecIter aCurrent, ShapeVecIter aEnd, SHAPE *aShape, int aMinDistance, bool aExact)
|
query_iterator( ShapeVecIter aCurrent, ShapeVecIter aEnd, SHAPE* aShape,
|
||||||
: m_end(aEnd),
|
int aMinDistance, bool aExact ) :
|
||||||
m_current(aCurrent),
|
m_end( aEnd ),
|
||||||
m_shape(aShape),
|
m_current( aCurrent ),
|
||||||
m_minDistance(aMinDistance),
|
m_shape( aShape ),
|
||||||
m_exact(aExact)
|
m_minDistance( aMinDistance ),
|
||||||
|
m_exact( aExact )
|
||||||
{
|
{
|
||||||
if(aShape)
|
if( aShape )
|
||||||
{
|
{
|
||||||
m_refBBox = aShape->BBox();
|
m_refBBox = aShape->BBox();
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query_iterator(const query_iterator &b)
|
query_iterator( const query_iterator &aB ) :
|
||||||
: m_end(b.m_end),
|
m_end( aB.m_end ),
|
||||||
m_current(b.m_current),
|
m_current( aB.m_current ),
|
||||||
m_shape(b.m_shape),
|
m_shape( aB.m_shape ),
|
||||||
m_minDistance(b.m_minDistance),
|
m_minDistance( aB.m_minDistance ),
|
||||||
m_exact(b.m_exact),
|
m_exact( aB.m_exact ),
|
||||||
m_refBBox(b.m_refBBox)
|
m_refBBox( aB.m_refBBox )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
T operator*() const
|
T operator*() const
|
||||||
{
|
{
|
||||||
|
@ -154,45 +148,45 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
query_iterator& operator++(int dummy)
|
query_iterator& operator++( int aDummy )
|
||||||
{
|
{
|
||||||
++m_current;
|
++m_current;
|
||||||
next();
|
next();
|
||||||
return *this;
|
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_end = aRhs.m_end;
|
||||||
m_current = rhs.m_current;
|
m_current = aRhs.m_current;
|
||||||
m_shape = rhs.m_shape;
|
m_shape = aRhs.m_shape;
|
||||||
m_minDistance = rhs.m_minDistance;
|
m_minDistance = aRhs.m_minDistance;
|
||||||
m_exact = rhs.m_exact;
|
m_exact = aRhs.m_exact;
|
||||||
m_refBBox = rhs.m_refBBox;
|
m_refBBox = aRhs.m_refBBox;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void next()
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
++m_current;
|
++m_current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,27 +199,27 @@ public:
|
||||||
int m_minDistance;
|
int m_minDistance;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Add(T aItem)
|
void Add( T aItem )
|
||||||
{
|
{
|
||||||
ShapeEntry s (aItem);
|
ShapeEntry s( aItem );
|
||||||
|
|
||||||
m_shapes.push_back(s);
|
m_shapes.push_back(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Remove(const T aItem)
|
void Remove( const T aItem )
|
||||||
{
|
{
|
||||||
ShapeVecIter i;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i == m_shapes.end())
|
if( i == m_shapes.end() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_shapes.erase(i);
|
m_shapes.erase( i );
|
||||||
}
|
}
|
||||||
|
|
||||||
int Size() const
|
int Size() const
|
||||||
|
@ -234,37 +228,37 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Visitor>
|
template<class Visitor>
|
||||||
int Query( const SHAPE *aShape, int aMinDistance, Visitor &v, bool aExact = true) //const
|
int Query( const SHAPE *aShape, int aMinDistance, Visitor &aV, bool aExact = true ) //const
|
||||||
{
|
{
|
||||||
ShapeVecIter i;
|
ShapeVecIter i;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
VECTOR2I::extended_type minDistSq = (VECTOR2I::extended_type) aMinDistance * aMinDistance;
|
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)
|
for( i = m_shapes.begin(); i != m_shapes.end(); ++i )
|
||||||
{
|
{
|
||||||
if (refBBox.SquaredDistance(i->bbox) <= minDistSq)
|
if( refBBox.SquaredDistance( i->bbox ) <= minDistSq )
|
||||||
{
|
{
|
||||||
if(!aExact || i->shape->Collide(aShape, aMinDistance))
|
if( !aExact || i->shape->Collide( aShape, aMinDistance ) )
|
||||||
{
|
{
|
||||||
n++;
|
n++;
|
||||||
if(!v( i->parent ))
|
if( !aV( i->parent ) )
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
m_shapes.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()
|
const query_iterator qend()
|
||||||
|
@ -283,7 +277,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ShapeVec m_shapes;
|
ShapeVec m_shapes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,28 +36,28 @@ class SHAPE_RECT : public SHAPE {
|
||||||
* Constructor
|
* Constructor
|
||||||
* Creates an empty (0-sized) rectangle
|
* Creates an empty (0-sized) rectangle
|
||||||
*/
|
*/
|
||||||
SHAPE_RECT():
|
SHAPE_RECT() :
|
||||||
SHAPE( SH_RECT ), m_w (0), m_h(0) {};
|
SHAPE( SH_RECT ), m_w( 0 ), m_h( 0 ) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* 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_RECT( int aX0, int aY0, int aW, int aH ) :
|
||||||
SHAPE(SH_RECT), m_p0(x0, y0), m_w(w), m_h(h) {};
|
SHAPE( SH_RECT ), m_p0( aX0, aY0 ), m_w( aW ), m_h( aH ) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* 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_RECT( const VECTOR2I &aP0, int aW, int aH ) :
|
||||||
SHAPE(SH_RECT), m_p0(p0), m_w(w), m_h(h) {};
|
SHAPE( SH_RECT ), m_p0( aP0 ), m_w( aW ), m_h( aH ) {};
|
||||||
|
|
||||||
/// @copydoc SHAPE::BBox()
|
/// @copydoc SHAPE::BBox()
|
||||||
const BOX2I BBox(int aClearance = 0) const
|
const BOX2I BBox(int aClearance = 0) const
|
||||||
{
|
{
|
||||||
BOX2I bbox( VECTOR2I (m_p0.x - aClearance, m_p0.y - aClearance ),
|
BOX2I bbox( VECTOR2I( m_p0.x - aClearance, m_p0.y - aClearance ),
|
||||||
VECTOR2I (m_w + 2 * aClearance, m_h + 2 * aClearance ));
|
VECTOR2I( m_w + 2 * aClearance, m_h + 2 * aClearance ) );
|
||||||
//printf("bb : %s\n",bbox.Format().c_str());
|
//printf("bb : %s\n",bbox.Format().c_str());
|
||||||
return bbox;
|
return bbox;
|
||||||
}
|
}
|
||||||
|
@ -70,11 +70,11 @@ class SHAPE_RECT : public SHAPE {
|
||||||
*/
|
*/
|
||||||
int Diagonal() const
|
int Diagonal() const
|
||||||
{
|
{
|
||||||
return VECTOR2I(m_w, m_h).EuclideanNorm();
|
return VECTOR2I( m_w, m_h ).EuclideanNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @copydoc SHAPE::Collide()
|
/// @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 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));
|
//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)
|
//if (BBox(0).SquaredDistance(r) > aClearance * aClearance)
|
||||||
// return false;
|
// 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;
|
return true;
|
||||||
|
|
||||||
VECTOR2I vts[] = { 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_p0.y + m_h ),
|
||||||
VECTOR2I(m_p0.x + m_w, 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_w, m_p0.y ),
|
||||||
VECTOR2I(m_p0.x, 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);
|
SEG s( vts[i], vts[i + 1], i );
|
||||||
if(s.Distance(aSeg) <= aClearance)
|
if( s.Distance( aSeg ) <= aClearance )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ class SHAPE_RECT : public SHAPE {
|
||||||
*
|
*
|
||||||
* @return size of the rectangle
|
* @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()
|
* Function GetWidth()
|
||||||
|
@ -133,8 +133,10 @@ class SHAPE_RECT : public SHAPE {
|
||||||
private:
|
private:
|
||||||
///> Top-left corner
|
///> Top-left corner
|
||||||
VECTOR2I m_p0;
|
VECTOR2I m_p0;
|
||||||
|
|
||||||
///> Width
|
///> Width
|
||||||
int m_w;
|
int m_w;
|
||||||
|
|
||||||
///> Height
|
///> Height
|
||||||
int m_h;
|
int m_h;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,12 @@ class TOOL_BASE;
|
||||||
class TOOL_MANAGER;
|
class TOOL_MANAGER;
|
||||||
class TOOL_ACTION;
|
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
|
class ACTION_MANAGER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -140,7 +140,7 @@ private:
|
||||||
/// Menu items with ID higher than that are considered TOOL_ACTIONs
|
/// Menu items with ID higher than that are considered TOOL_ACTIONs
|
||||||
static const int m_actionId = 10000;
|
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;
|
std::map<int, const TOOL_ACTION*> m_toolActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int c_defaultStackSize = 2000000;
|
static const int c_defaultStackSize = 2000000; // fixme: make configurable
|
||||||
|
|
||||||
/* real entry point of the coroutine */
|
/* real entry point of the coroutine */
|
||||||
static void callerStub( intptr_t data )
|
static void callerStub( intptr_t data )
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -31,10 +32,16 @@
|
||||||
#include <tool/tool_base.h>
|
#include <tool/tool_base.h>
|
||||||
#include <tool/action_manager.h>
|
#include <tool/action_manager.h>
|
||||||
|
|
||||||
// TOOL_ACTION - represents a single action. For instance:
|
/**
|
||||||
// - changing layer to top by pressing PgUp
|
* Class TOOL_ACTION
|
||||||
// - running the DRC from the menu
|
*
|
||||||
// and so on, and so forth....
|
* 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
|
class TOOL_ACTION
|
||||||
{
|
{
|
||||||
public:
|
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
|
* Returns the event associated with the action (ie. the event that will be sent after
|
||||||
* activating the action).
|
* activating the action).
|
||||||
*
|
*
|
||||||
* @return The event associated with 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 );
|
return TOOL_EVENT( TC_Command, TA_Action, m_name, m_scope );
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,10 @@ namespace KiGfx {
|
||||||
* Class TOOL_DISPATCHER
|
* Class TOOL_DISPATCHER
|
||||||
*
|
*
|
||||||
* - takes wx events,
|
* - 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
|
* - translates coordinates to world space
|
||||||
* - low-level input conditioning (drag/click threshold), updating mouse position during view auto-scroll/pan.
|
* - 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
|
class TOOL_DISPATCHER
|
||||||
|
@ -100,6 +100,7 @@ private:
|
||||||
///> Saves the state of key modifiers (Alt, Ctrl and so on).
|
///> Saves the state of key modifiers (Alt, Ctrl and so on).
|
||||||
int decodeModifiers( const wxKeyboardState* aState ) const;
|
int decodeModifiers( const wxKeyboardState* aState ) const;
|
||||||
|
|
||||||
|
|
||||||
///> Stores all the informations regarding a mouse button state.
|
///> Stores all the informations regarding a mouse button state.
|
||||||
struct ButtonState;
|
struct ButtonState;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
class TOOL_ACTION;
|
||||||
class TOOL_MANAGER;
|
class TOOL_MANAGER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -313,6 +314,14 @@ public:
|
||||||
return true;
|
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()
|
boost::optional<int> GetCommandId()
|
||||||
{
|
{
|
||||||
return m_commandId;
|
return m_commandId;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -30,11 +31,10 @@
|
||||||
|
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
#include <tool/tool_event.h>
|
|
||||||
#include <tool/tool_base.h>
|
#include <tool/tool_base.h>
|
||||||
#include <tool/action_manager.h>
|
|
||||||
|
|
||||||
class TOOL_BASE;
|
class TOOL_BASE;
|
||||||
|
class ACTION_MANAGER;
|
||||||
class CONTEXT_MENU;
|
class CONTEXT_MENU;
|
||||||
class wxWindow;
|
class wxWindow;
|
||||||
|
|
||||||
|
@ -89,10 +89,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param aAction is the action to be registered.
|
* @param aAction is the action to be registered.
|
||||||
*/
|
*/
|
||||||
void RegisterAction( TOOL_ACTION* aAction )
|
void RegisterAction( TOOL_ACTION* aAction );
|
||||||
{
|
|
||||||
m_actionMgr.RegisterAction( aAction );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function UnregisterAction()
|
* Function UnregisterAction()
|
||||||
|
@ -100,10 +97,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param aAction is the action to be unregistered.
|
* @param aAction is the action to be unregistered.
|
||||||
*/
|
*/
|
||||||
void UnregisterAction( TOOL_ACTION* aAction )
|
void UnregisterAction( TOOL_ACTION* aAction );
|
||||||
{
|
|
||||||
m_actionMgr.UnregisterAction( aAction );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function FindTool()
|
* Function FindTool()
|
||||||
|
@ -205,6 +199,14 @@ private:
|
||||||
|
|
||||||
void dispatchInternal( TOOL_EVENT& aEvent );
|
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()
|
* Function dispatchActivation()
|
||||||
* Checks if it is a valid activation event and invokes a proper tool.
|
* Checks if it is a valid activation event and invokes a proper tool.
|
||||||
|
@ -215,7 +217,8 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function invokeTool()
|
* 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.
|
* @param aTool is the tool to be invoked.
|
||||||
*/
|
*/
|
||||||
bool invokeTool( TOOL_BASE* aTool );
|
bool invokeTool( TOOL_BASE* aTool );
|
||||||
|
@ -291,7 +294,9 @@ private:
|
||||||
/// Stack of the active tools
|
/// Stack of the active tools
|
||||||
std::deque<TOOL_ID> m_activeTools;
|
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;
|
EDA_ITEM* m_model;
|
||||||
KiGfx::VIEW* m_view;
|
KiGfx::VIEW* m_view;
|
||||||
KiGfx::VIEW_CONTROLS* m_viewControls;
|
KiGfx::VIEW_CONTROLS* m_viewControls;
|
||||||
|
|
|
@ -84,15 +84,16 @@ public:
|
||||||
/// @copydoc VIEW_CONTROLS::GetCursorPosition()
|
/// @copydoc VIEW_CONTROLS::GetCursorPosition()
|
||||||
virtual const VECTOR2D GetCursorPosition() const;
|
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;
|
static const wxEventType EVT_REFRESH_MOUSE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Possible states for WX_VIEW_CONTROLS
|
/// Possible states for WX_VIEW_CONTROLS
|
||||||
enum State {
|
enum State {
|
||||||
IDLE = 1,
|
IDLE = 1, /// Nothing is happening
|
||||||
DRAG_PANNING,
|
DRAG_PANNING, /// Panning with mouse button pressed
|
||||||
AUTO_PANNING,
|
AUTO_PANNING, /// Panning on approaching borders of the frame
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 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
|
* Class ITEM_STATE
|
||||||
*
|
*
|
||||||
|
@ -29,13 +35,6 @@
|
||||||
* the introduced changes. Does not take ownership of modified items, neither takes care of
|
* the introduced changes. Does not take ownership of modified items, neither takes care of
|
||||||
* refreshing.
|
* refreshing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ITEM_STATE_H_
|
|
||||||
#define ITEM_STATE_H_
|
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <class_board_item.h>
|
|
||||||
|
|
||||||
class ITEM_STATE
|
class ITEM_STATE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -278,4 +277,3 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ITEM_STATE_H_ */
|
#endif /* ITEM_STATE_H_ */
|
||||||
|
|
|
@ -53,7 +53,7 @@ MOVE_TOOL::~MOVE_TOOL()
|
||||||
void MOVE_TOOL::Reset()
|
void MOVE_TOOL::Reset()
|
||||||
{
|
{
|
||||||
// The tool launches upon reception of action event ("pcbnew.InteractiveMove")
|
// 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() );
|
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_state.Rotate( cursorPos, 900.0 );
|
||||||
m_items.ViewUpdate( VIEW_ITEM::GEOMETRY );
|
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_state.Flip( cursorPos );
|
||||||
m_items.ViewUpdate( VIEW_ITEM::GEOMETRY );
|
m_items.ViewUpdate( VIEW_ITEM::GEOMETRY );
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
#include <tool/tool_interactive.h>
|
#include <tool/tool_interactive.h>
|
||||||
#include <tool/item_state.h>
|
|
||||||
#include <view/view_group.h>
|
#include <view/view_group.h>
|
||||||
|
#include "item_state.h"
|
||||||
|
|
||||||
class BOARD_ITEM;
|
class BOARD_ITEM;
|
||||||
class SELECTION_TOOL;
|
class SELECTION_TOOL;
|
||||||
|
|
|
@ -68,7 +68,7 @@ void SELECTION_TOOL::Reset()
|
||||||
m_selectedItems.clear();
|
m_selectedItems.clear();
|
||||||
|
|
||||||
// The tool launches upon reception of action event ("pcbnew.InteractiveSelection")
|
// 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();
|
VIEW* view = getView();
|
||||||
getViewControls()->SetAutoPan( true );
|
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->SetOrigin( VECTOR2I( 0, 0 ) );
|
||||||
m_selArea->SetEnd( VECTOR2I( 0, 0 ) );
|
m_selArea->SetEnd( VECTOR2I( 0, 0 ) );
|
||||||
view->Add( m_selArea );
|
view->Add( m_selArea );
|
||||||
|
@ -467,7 +467,6 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// All other items are selected only if the layer on which they exist is visible
|
// All other items are selected only if the layer on which they exist is visible
|
||||||
return board->IsLayerVisible( aItem->GetLayer() );
|
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
|
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
|
// Check if the point is located within any of the currently selected items bounding boxes
|
||||||
std::set<BOARD_ITEM*>::iterator it, it_end;
|
std::set<BOARD_ITEM*>::iterator it, it_end;
|
||||||
for( it = m_selectedItems.begin(), it_end = m_selectedItems.end(); it != it_end; ++it )
|
for( it = m_selectedItems.begin(), it_end = m_selectedItems.end(); it != it_end; ++it )
|
||||||
{
|
{
|
||||||
BOX2I itemBox = (*it)->ViewBBox();
|
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 ) )
|
if( itemBox.Contains( aPoint ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue