Converted tabs to spaces. Removed trailing whitespaces.

This commit is contained in:
Maciej Suminski 2013-10-14 13:43:57 +02:00
parent ac489ece7b
commit 22045b61ea
55 changed files with 2739 additions and 2740 deletions

View File

@ -78,17 +78,17 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
/* Generic events for the Tool Dispatcher */
Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) );
Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_KEY_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) );
Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_KEY_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this );
Connect( KiGfx::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE,
wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
@ -223,13 +223,13 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
void EDA_DRAW_PANEL_GAL::onEvent( wxEvent& aEvent )
{
if( !m_eventDispatcher )
{
aEvent.Skip();
return;
}
else
{
if( !m_eventDispatcher )
{
aEvent.Skip();
return;
}
else
{
m_eventDispatcher->DispatchWxEvent( aEvent );
}

View File

@ -159,7 +159,6 @@ void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
b = q;
break;
}
}

View File

@ -32,38 +32,38 @@ template<typename T> int sgn( T val ) {
bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const
{
VECTOR2I d = b - a;
ecoord dist_sq = (ecoord) dist * dist;
VECTOR2I d = b - a;
ecoord dist_sq = (ecoord) dist * dist;
SEG::ecoord l_squared = d.Dot( d );
SEG::ecoord l_squared = d.Dot( d );
SEG::ecoord t = d.Dot( aP - a );
if( t <= 0 || !l_squared )
return ( aP - a ).SquaredEuclideanNorm() < dist_sq;
return ( aP - a ).SquaredEuclideanNorm() < dist_sq;
else if( t >= l_squared )
return ( aP - b ).SquaredEuclideanNorm() < dist_sq;
return ( aP - b ).SquaredEuclideanNorm() < dist_sq;
int dxdy = abs( d.x ) - abs( d.y );
int dxdy = abs( d.x ) - abs( d.y );
if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 )
{
int ca = -sgn( d.y );
int cb = sgn( d.x );
int cc = -ca * a.x - cb * a.y;
int ca = -sgn( d.y );
int cb = sgn( d.x );
int cc = -ca * a.x - cb * a.y;
ecoord num = ca * aP.x + cb * aP.y + cc;
num *= num;
ecoord num = ca * aP.x + cb * aP.y + cc;
num *= num;
if( ca && cb )
num >>= 1;
if( ca && cb )
num >>= 1;
if( num > ( dist_sq + 100 ) )
return false;
else if( num < ( dist_sq - 100 ) )
return true;
if( num > ( dist_sq + 100 ) )
return false;
else if( num < ( dist_sq - 100 ) )
return true;
}
VECTOR2I nearest;
VECTOR2I nearest;
nearest.x = a.x + rescale( t, (ecoord)d.x, l_squared );
nearest.y = a.y + rescale( t, (ecoord)d.y, l_squared );
@ -95,58 +95,58 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const
OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const
{
const VECTOR2I e ( b - a );
const VECTOR2I f ( aSeg.b - aSeg.a );
const VECTOR2I ac ( aSeg.a - a );
const VECTOR2I e ( b - a );
const VECTOR2I f ( aSeg.b - aSeg.a );
const VECTOR2I ac ( aSeg.a - a );
ecoord d = f.Cross( e );
ecoord p = f.Cross( ac );
ecoord q = e.Cross( ac );
ecoord d = f.Cross( e );
ecoord p = f.Cross( ac );
ecoord q = e.Cross( ac );
if( d == 0 )
return OPT_VECTOR2I();
if ( !aLines && d > 0 && ( q < 0 || q > d || p < 0 || p > d ) )
return OPT_VECTOR2I();
if ( !aLines && d < 0 && ( q < d || p < d || p > 0 || q > 0 ) )
return OPT_VECTOR2I();
if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) )
return OPT_VECTOR2I();
if( d == 0 )
return OPT_VECTOR2I();
if ( !aLines && d > 0 && ( q < 0 || q > d || p < 0 || p > d ) )
return OPT_VECTOR2I();
if ( !aLines && d < 0 && ( q < d || p < d || p > 0 || q > 0 ) )
return OPT_VECTOR2I();
if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) )
return OPT_VECTOR2I();
VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ),
aSeg.a.y + rescale( q, (ecoord)f.y, d ) );
VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ),
aSeg.a.y + rescale( q, (ecoord)f.y, d ) );
return ip;
return ip;
}
bool SEG::ccw( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I& c ) const
{
return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x );
return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x );
}
bool SEG::Collide( const SEG& aSeg, int aClearance ) const
{
// check for intersection
// fixme: move to a method
if( ccw( a, aSeg.a, aSeg.b ) != ccw( b, aSeg.a, aSeg.b ) &&
ccw( a, b, aSeg.a ) != ccw( a, b, aSeg.b ) )
return true;
// check for intersection
// fixme: move to a method
if( ccw( a, aSeg.a, aSeg.b ) != ccw( b, aSeg.a, aSeg.b ) &&
ccw( a, b, aSeg.a ) != ccw( a, b, aSeg.b ) )
return true;
#define CHK(_seg, _pt) \
if( (_seg).PointCloserThan (_pt, aClearance ) ) return true;
if( (_seg).PointCloserThan (_pt, aClearance ) ) return true;
CHK( *this, aSeg.a );
CHK( *this, aSeg.b );
CHK( aSeg, a );
CHK( aSeg, b );
CHK( *this, aSeg.a );
CHK( *this, aSeg.b );
CHK( aSeg, a );
CHK( aSeg, b );
#undef CHK
return false;
return false;
}
bool SEG::Contains( const VECTOR2I& aP ) const
{
return PointCloserThan( aP, 1 );
return PointCloserThan( aP, 1 );
}

View File

@ -34,200 +34,200 @@ typedef VECTOR2I::extended_type ecoord;
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_CIRCLE& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
ecoord min_dist = aClearance + aA.GetRadius() + aB.GetRadius();
ecoord min_dist_sq = min_dist * min_dist;
ecoord min_dist = aClearance + aA.GetRadius() + aB.GetRadius();
ecoord min_dist_sq = min_dist * min_dist;
const VECTOR2I delta = aB.GetCenter() - aA.GetCenter();
const VECTOR2I delta = aB.GetCenter() - aA.GetCenter();
ecoord dist_sq = delta.SquaredEuclideanNorm();
ecoord dist_sq = delta.SquaredEuclideanNorm();
if ( dist_sq >= min_dist_sq )
return false;
if ( dist_sq >= min_dist_sq )
return false;
if ( aNeedMTV )
aMTV = delta.Resize( sqrt ( abs( min_dist_sq - dist_sq ) ) + 1 );
if ( aNeedMTV )
aMTV = delta.Resize( sqrt ( abs( min_dist_sq - dist_sq ) ) + 1 );
return true;
return true;
}
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CIRCLE& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
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;
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 ( aA.BBox( 0 ).Contains( c ) )
return true;
if ( aA.BBox( 0 ).Contains( c ) )
return true;
const VECTOR2I vts[] = {
VECTOR2I(p0.x, p0.y),
VECTOR2I(p0.x, p0.y + size.y),
VECTOR2I(p0.x + size.x, p0.y + size.y),
VECTOR2I(p0.x + size.x, p0.y),
VECTOR2I(p0.x, p0.y) };
const VECTOR2I vts[] = {
VECTOR2I(p0.x, p0.y),
VECTOR2I(p0.x, p0.y + size.y),
VECTOR2I(p0.x + size.x, p0.y + size.y),
VECTOR2I(p0.x + size.x, p0.y),
VECTOR2I(p0.x, p0.y) };
ecoord nearest_seg_dist_sq = VECTOR2I::ECOORD_MAX;
VECTOR2I nearest;
ecoord nearest_seg_dist_sq = VECTOR2I::ECOORD_MAX;
VECTOR2I nearest;
bool inside = c.x >= p0.x && c.x <= ( p0.x + size.x )
&& c.y >= p0.y && c.y <= ( p0.y + size.y );
bool inside = c.x >= p0.x && c.x <= ( p0.x + size.x )
&& c.y >= p0.y && c.y <= ( p0.y + size.y );
if( !inside )
{
if( !inside )
{
for( int i = 0; i < 4; i++ )
{
const SEG seg( vts[i], vts[i+1] );
ecoord dist_sq = seg.SquaredDistance( c );
for( int i = 0; i < 4; i++ )
{
const SEG seg( vts[i], vts[i+1] );
ecoord dist_sq = seg.SquaredDistance( c );
if( dist_sq < min_dist_sq )
{
if( !aNeedMTV )
return true;
else
{
nearest = seg.NearestPoint( c );
nearest_seg_dist_sq = dist_sq;
}
}
}
}
if( dist_sq < min_dist_sq )
{
if( !aNeedMTV )
return true;
else
{
nearest = seg.NearestPoint( c );
nearest_seg_dist_sq = dist_sq;
}
}
}
}
if( nearest_seg_dist_sq >= min_dist_sq && !inside )
return false;
if( nearest_seg_dist_sq >= min_dist_sq && !inside )
return false;
VECTOR2I delta = c - nearest;
VECTOR2I delta = c - nearest;
if( !aNeedMTV )
return true;
if( !aNeedMTV )
return true;
if( inside )
aMTV = -delta.Resize( sqrt( abs( r * r + nearest_seg_dist_sq ) + 1 ) );
else
aMTV = delta.Resize( sqrt( abs( r * r - nearest_seg_dist_sq ) + 1 ) );
if( inside )
aMTV = -delta.Resize( sqrt( abs( r * r + nearest_seg_dist_sq ) + 1 ) );
else
aMTV = delta.Resize( sqrt( abs( r * r - nearest_seg_dist_sq ) + 1 ) );
return true;
return true;
}
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
for( int s = 0; s < aB.SegmentCount(); s++ )
{
if ( aA.Collide( aB.CSegment( s ), aClearance ) )
return true;
}
for( int s = 0; s < aB.SegmentCount(); s++ )
{
if ( aA.Collide( aB.CSegment( s ), aClearance ) )
return true;
}
return false;
return false;
}
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 < aB.SegmentCount(); i++ )
if( aA.Collide( aB.CSegment(i), aClearance ) )
return true;
return false;
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& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
for( int s = 0; s < aB.SegmentCount(); s++ )
{
SEG seg = aB.CSegment( s );
if( aA.Collide( seg, aClearance ) )
return true;
}
for( int s = 0; s < aB.SegmentCount(); s++ )
{
SEG seg = aB.CSegment( s );
if( aA.Collide( seg, aClearance ) )
return true;
}
return false;
return false;
}
bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV )
{
switch( aA->Type() )
{
case SH_RECT:
switch( aB->Type() )
{
case SH_CIRCLE:
return Collide( *static_cast<const SHAPE_RECT*>( aA ),
*static_cast<const SHAPE_CIRCLE*>( aB ), aClearance, aNeedMTV, aMTV );
switch( aA->Type() )
{
case SH_RECT:
switch( aB->Type() )
{
case SH_CIRCLE:
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*>( aA ),
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
case SH_LINE_CHAIN:
return Collide( *static_cast<const SHAPE_RECT*>( aA ),
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
default:
break;
}
default:
break;
}
case SH_CIRCLE:
switch( aB->Type() )
{
case SH_RECT:
return Collide( *static_cast<const SHAPE_RECT*>( aB ),
*static_cast<const SHAPE_CIRCLE*>( aA ), aClearance, aNeedMTV, aMTV );
case SH_CIRCLE:
switch( aB->Type() )
{
case SH_RECT:
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*>( aA ),
*static_cast<const SHAPE_CIRCLE*>( aB ), aClearance, aNeedMTV, aMTV );
case SH_CIRCLE:
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*>( aA ),
*static_cast<const SHAPE_LINE_CHAIN *>( aB ), aClearance, aNeedMTV, aMTV );
case SH_LINE_CHAIN:
return Collide( *static_cast<const SHAPE_CIRCLE*>( aA ),
*static_cast<const SHAPE_LINE_CHAIN *>( aB ), aClearance, aNeedMTV, aMTV );
default:
break;
}
default:
break;
}
case SH_LINE_CHAIN:
switch( aB->Type() )
{
case SH_RECT:
return Collide( *static_cast<const SHAPE_RECT*>( aB ),
*static_cast<const SHAPE_LINE_CHAIN*>( aA ), aClearance, aNeedMTV, aMTV );
case SH_LINE_CHAIN:
switch( aB->Type() )
{
case SH_RECT:
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*>( aB ),
*static_cast<const SHAPE_LINE_CHAIN*>( aA ), aClearance, aNeedMTV, aMTV );
case SH_CIRCLE:
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*>( aA ),
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
case SH_LINE_CHAIN:
return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( aA ),
*static_cast<const SHAPE_LINE_CHAIN*>( aB ), aClearance, aNeedMTV, aMTV );
default:
break;
}
default:
break;
}
default:
break;
}
default:
break;
}
bool unsupported_collision = true;
bool unsupported_collision = true;
assert( unsupported_collision == false );
assert( unsupported_collision == false );
return false;
return false;
}
bool SHAPE::Collide( const SHAPE* aShape, int aClerance, VECTOR2I& aMTV ) const
{
return CollideShapes( this, aShape, aClerance, true, aMTV);
return CollideShapes( this, aShape, aClerance, true, aMTV);
}
bool SHAPE::Collide ( const SHAPE* aShape, int aClerance ) const
{
VECTOR2I dummy;
return CollideShapes( this, aShape, aClerance, false, dummy );
VECTOR2I dummy;
return CollideShapes( this, aShape, aClerance, false, dummy );
}

View File

@ -30,205 +30,205 @@ using boost::optional;
bool SHAPE_LINE_CHAIN::Collide( const VECTOR2I& aP, int aClearance ) const
{
assert( false );
return false;
assert( false );
return false;
}
bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const
{
assert( false );
return false;
assert( false );
return false;
}
bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const
{
BOX2I box_a( aSeg.a, aSeg.b - aSeg.a );
BOX2I::ecoord_type dist_sq = (BOX2I::ecoord_type) aClearance * aClearance;
BOX2I box_a( aSeg.a, aSeg.b - aSeg.a );
BOX2I::ecoord_type dist_sq = (BOX2I::ecoord_type) aClearance * aClearance;
for( int i = 0; i < SegmentCount() ;i++ )
{
const SEG& s = CSegment( i );
BOX2I box_b( s.a, s.b - s.a );
for( int i = 0; i < SegmentCount() ;i++ )
{
const SEG& s = CSegment( i );
BOX2I box_b( s.a, s.b - s.a );
BOX2I::ecoord_type d = box_a.SquaredDistance ( box_b );
BOX2I::ecoord_type d = box_a.SquaredDistance ( box_b );
if( d < dist_sq )
{
if( s.Collide( aSeg, aClearance ) )
return true;
}
}
if( d < dist_sq )
{
if( s.Collide( aSeg, aClearance ) )
return true;
}
}
return false;
return false;
}
const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse() const
{
SHAPE_LINE_CHAIN a( *this );
reverse( a.m_points.begin(), a.m_points.end() );
a.m_closed = m_closed;
SHAPE_LINE_CHAIN a( *this );
reverse( a.m_points.begin(), a.m_points.end() );
a.m_closed = m_closed;
return a;
return a;
}
int SHAPE_LINE_CHAIN::Length() const
{
int l = 0;
for( int i = 0; i < SegmentCount(); i++ )
l += CSegment( i ).Length();
int l = 0;
for( int i = 0; i < SegmentCount(); i++ )
l += CSegment( i ).Length();
return l;
return l;
}
void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP )
{
if( aEndIndex < 0 )
aEndIndex += PointCount();
if( aStartIndex < 0 )
aStartIndex += PointCount();
if( aEndIndex < 0 )
aEndIndex += PointCount();
if( aStartIndex < 0 )
aStartIndex += PointCount();
if( aStartIndex == aEndIndex )
m_points [aStartIndex] = aP;
else
{
m_points.erase( m_points.begin() + aStartIndex + 1, m_points.begin() + aEndIndex + 1 );
m_points[aStartIndex] = aP;
}
if( aStartIndex == aEndIndex )
m_points [aStartIndex] = aP;
else
{
m_points.erase( m_points.begin() + aStartIndex + 1, m_points.begin() + aEndIndex + 1 );
m_points[aStartIndex] = aP;
}
}
void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine )
{
if( aEndIndex < 0 )
aEndIndex += PointCount();
if( aStartIndex < 0 )
aStartIndex += PointCount();
if( aEndIndex < 0 )
aEndIndex += PointCount();
if( aStartIndex < 0 )
aStartIndex += PointCount();
m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 );
m_points.insert( m_points.begin() + aStartIndex, aLine.m_points.begin(), aLine.m_points.end() );
m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 );
m_points.insert( m_points.begin() + aStartIndex, aLine.m_points.begin(), aLine.m_points.end() );
}
void SHAPE_LINE_CHAIN::Remove( int aStartIndex, int aEndIndex )
{
if(aEndIndex < 0)
aEndIndex += PointCount();
if(aStartIndex < 0)
aStartIndex += PointCount();
if(aEndIndex < 0)
aEndIndex += PointCount();
if(aStartIndex < 0)
aStartIndex += PointCount();
m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 );
m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 );
}
int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP ) const
{
int d = INT_MAX;
for( int s = 0; s < SegmentCount(); s++ )
d = min( d, CSegment( s ).Distance( aP ) );
int d = INT_MAX;
for( int s = 0; s < SegmentCount(); s++ )
d = min( d, CSegment( s ).Distance( aP ) );
return d;
return d;
}
int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP )
{
int ii = -1;
int min_dist = 2;
int ii = -1;
int min_dist = 2;
ii = Find( aP );
ii = Find( aP );
if( ii >= 0 )
return ii;
if( ii >= 0 )
return ii;
for( int s = 0; s < SegmentCount(); s++ )
{
const SEG seg = CSegment( s );
int dist = seg.Distance( aP );
for( int s = 0; s < SegmentCount(); s++ )
{
const SEG seg = CSegment( s );
int dist = seg.Distance( aP );
// make sure we are not producing a 'slightly concave' primitive. This might happen
// if aP lies very close to one of already existing points.
if( dist < min_dist && seg.a != aP && seg.b != aP )
{
min_dist = dist;
ii = s;
}
}
// make sure we are not producing a 'slightly concave' primitive. This might happen
// if aP lies very close to one of already existing points.
if( dist < min_dist && seg.a != aP && seg.b != aP )
{
min_dist = dist;
ii = s;
}
}
if( ii >= 0 )
{
m_points.insert( m_points.begin() + ii + 1, aP );
if( ii >= 0 )
{
m_points.insert( m_points.begin() + ii + 1, aP );
return ii + 1;
}
return ii + 1;
}
return -1;
return -1;
}
int SHAPE_LINE_CHAIN::Find( const VECTOR2I& aP ) const
{
for( int s = 0; s< PointCount(); s++ )
if( CPoint( s ) == aP )
return s;
for( int s = 0; s< PointCount(); s++ )
if( CPoint( s ) == aP )
return s;
return -1;
return -1;
}
const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex ) const
{
SHAPE_LINE_CHAIN rv;
SHAPE_LINE_CHAIN rv;
if( aEndIndex < 0 )
aEndIndex += PointCount();
if( aStartIndex < 0 )
aStartIndex += PointCount();
if( aEndIndex < 0 )
aEndIndex += PointCount();
if( aStartIndex < 0 )
aStartIndex += PointCount();
for( int i = aStartIndex; i <= aEndIndex; i++ )
rv.Append( m_points[i] );
for( int i = aStartIndex; i <= aEndIndex; i++ )
rv.Append( m_points[i] );
return rv;
return rv;
}
struct compareOriginDistance
{
compareOriginDistance( VECTOR2I& aOrigin ):
m_origin( aOrigin ) {};
compareOriginDistance( VECTOR2I& aOrigin ):
m_origin( aOrigin ) {};
bool operator()( const SHAPE_LINE_CHAIN::Intersection& aA,
const SHAPE_LINE_CHAIN::Intersection& aB )
{
return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
}
bool operator()( const SHAPE_LINE_CHAIN::Intersection& aA,
const SHAPE_LINE_CHAIN::Intersection& aB )
{
return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
}
VECTOR2I m_origin;
VECTOR2I m_origin;
};
int SHAPE_LINE_CHAIN::Intersect( const SEG& aSeg, Intersections& aIp ) const
{
for( int s = 0; s < SegmentCount(); s++ )
{
OPT_VECTOR2I p = CSegment( s ).Intersect( aSeg );
if( p )
{
Intersection is;
is.our = CSegment( s );
is.their = aSeg;
is.p = *p;
aIp.push_back( is );
}
}
for( int s = 0; s < SegmentCount(); s++ )
{
OPT_VECTOR2I p = CSegment( s ).Intersect( aSeg );
if( p )
{
Intersection is;
is.our = CSegment( s );
is.their = aSeg;
is.p = *p;
aIp.push_back( is );
}
}
compareOriginDistance comp( aSeg.a );
sort( aIp.begin(), aIp.end(), comp );
compareOriginDistance comp( aSeg.a );
sort( aIp.begin(), aIp.end(), comp );
return aIp.size();
return aIp.size();
}
@ -236,285 +236,285 @@ int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, Intersections&
{
BOX2I bb_other = aChain.BBox();
for ( int s1 = 0; s1 < SegmentCount(); s1++ )
{
const SEG& a = CSegment( s1 );
const BOX2I bb_cur( a.a, a.b - a.a );
for ( int s1 = 0; s1 < SegmentCount(); s1++ )
{
const SEG& a = CSegment( s1 );
const BOX2I bb_cur( a.a, a.b - a.a );
if( !bb_other.Intersects( bb_cur ) )
continue;
if( !bb_other.Intersects( bb_cur ) )
continue;
for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ )
{
const SEG& b = aChain.CSegment( s2 );
Intersection is;
for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ )
{
const SEG& b = aChain.CSegment( s2 );
Intersection is;
if( a.Collinear( b ) )
{
if( a.Contains( b.a ) ) { is.p = b.a; aIp.push_back( is ); }
if( a.Contains( b.b ) ) { is.p = b.b; aIp.push_back( is ); }
if( b.Contains( a.a ) ) { is.p = a.a; aIp.push_back( is ); }
if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); }
}
else
{
OPT_VECTOR2I p = a.Intersect( b );
if( a.Collinear( b ) )
{
if( a.Contains( b.a ) ) { is.p = b.a; aIp.push_back( is ); }
if( a.Contains( b.b ) ) { is.p = b.b; aIp.push_back( is ); }
if( b.Contains( a.a ) ) { is.p = a.a; aIp.push_back( is ); }
if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); }
}
else
{
OPT_VECTOR2I p = a.Intersect( b );
if( p )
{
is.p = *p;
is.our = a;
is.their = b;
aIp.push_back( is );
}
}
}
}
if( p )
{
is.p = *p;
is.our = a;
is.their = b;
aIp.push_back( is );
}
}
}
}
return aIp.size();
return aIp.size();
for( int s1 = 0; s1 < SegmentCount(); s1++ )
{
for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ )
{
const SEG& a = CSegment( s1 );
const SEG& b = aChain.CSegment( s2 );
OPT_VECTOR2I p = a.Intersect( b );
Intersection is;
for( int s1 = 0; s1 < SegmentCount(); s1++ )
{
for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ )
{
const SEG& a = CSegment( s1 );
const SEG& b = aChain.CSegment( s2 );
OPT_VECTOR2I p = a.Intersect( b );
Intersection is;
if( p )
{
is.p = *p;
is.our = a;
is.their = b;
aIp.push_back( is );
}
else if( a.Collinear( b ) )
{
if( a.a != b.a && a.a != b.b && b.Contains( a.a ) )
{
is.p = a.a;
is.our = a;
is.their = b;
aIp.push_back( is );
}
else if( a.b != b.a && a.b != b.b && b.Contains( a.b ) )
{
is.p = a.b;
is.our = a;
is.their = b;
aIp.push_back( is );
}
if( p )
{
is.p = *p;
is.our = a;
is.their = b;
aIp.push_back( is );
}
else if( a.Collinear( b ) )
{
if( a.a != b.a && a.a != b.b && b.Contains( a.a ) )
{
is.p = a.a;
is.our = a;
is.their = b;
aIp.push_back( is );
}
else if( a.b != b.a && a.b != b.b && b.Contains( a.b ) )
{
is.p = a.b;
is.our = a;
is.their = b;
aIp.push_back( is );
}
}
}
}
}
}
}
return aIp.size();
return aIp.size();
}
int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const
{
int sum = 0;
for( int i = 0; i < SegmentCount(); i++ )
{
const SEG seg = CSegment( i );
int d = seg.Distance( aP );
int sum = 0;
for( int i = 0; i < SegmentCount(); i++ )
{
const SEG seg = CSegment( i );
int d = seg.Distance( aP );
if( d <= 1 )
{
sum += ( aP - seg.a ).EuclideanNorm();
return sum;
}
else
sum += seg.Length();
}
if( d <= 1 )
{
sum += ( aP - seg.a ).EuclideanNorm();
return sum;
}
else
sum += seg.Length();
}
return -1;
return -1;
}
bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const
{
if( !m_closed || SegmentCount() < 3 )
return false;
if( !m_closed || SegmentCount() < 3 )
return false;
int cur = CSegment(0).Side( aP );
int cur = CSegment(0).Side( aP );
if( cur == 0 )
return false;
if( cur == 0 )
return false;
for( int i = 1; i < SegmentCount(); i++ )
{
const SEG s = CSegment( i );
for( int i = 1; i < SegmentCount(); i++ )
{
const SEG s = CSegment( i );
if( aP == s.a || aP == s.b ) // edge does not belong to the interior!
return false;
if( aP == s.a || aP == s.b ) // edge does not belong to the interior!
return false;
if( s.Side(aP) != cur )
return false;
if( s.Side(aP) != cur )
return false;
}
return true;
return true;
}
bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const
{
if( SegmentCount() < 1 )
return m_points[0] == aP;
if( SegmentCount() < 1 )
return m_points[0] == aP;
for( int i = 1; i < SegmentCount(); i++ )
{
const SEG s = CSegment( i );
for( int i = 1; i < SegmentCount(); i++ )
{
const SEG s = CSegment( i );
if( s.a == aP || s.b == aP )
return true;
if( s.a == aP || s.b == aP )
return true;
if( s.Distance(aP) <= 1 )
return true;
}
if( s.Distance(aP) <= 1 )
return true;
}
return false;
return false;
}
const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersecting() const
{
for( int s1 = 0; s1 < SegmentCount(); s1++ )
{
for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ )
{
const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b;
if( s1 + 1 != s2 && CSegment( s1 ).Contains( s2a ) )
{
Intersection is;
is.our = CSegment( s1 );
is.their = CSegment( s2 );
is.p = s2a;
return is;
}
else if( CSegment( s1 ).Contains(s2b ) )
{
Intersection is;
is.our = CSegment( s1 );
is.their = CSegment( s2 );
is.p = s2b;
return is;
}
else
{
OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true );
for( int s1 = 0; s1 < SegmentCount(); s1++ )
{
for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ )
{
const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b;
if( s1 + 1 != s2 && CSegment( s1 ).Contains( s2a ) )
{
Intersection is;
is.our = CSegment( s1 );
is.their = CSegment( s2 );
is.p = s2a;
return is;
}
else if( CSegment( s1 ).Contains(s2b ) )
{
Intersection is;
is.our = CSegment( s1 );
is.their = CSegment( s2 );
is.p = s2b;
return is;
}
else
{
OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true );
if( p )
{
Intersection is;
is.our = CSegment( s1 );
is.their = CSegment( s2 );
is.p = *p;
return is;
}
}
}
}
if( p )
{
Intersection is;
is.our = CSegment( s1 );
is.their = CSegment( s2 );
is.p = *p;
return is;
}
}
}
}
return optional<Intersection>();
return optional<Intersection>();
}
SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
{
vector<VECTOR2I> pts_unique;
vector<VECTOR2I> pts_unique;
if( PointCount() < 2 )
{
return *this;
}
else if( PointCount() == 2 )
{
if( m_points[0] == m_points[1] )
m_points.erase( m_points.end() );
if( PointCount() < 2 )
{
return *this;
}
else if( PointCount() == 2 )
{
if( m_points[0] == m_points[1] )
m_points.erase( m_points.end() );
return *this;
}
return *this;
}
int i = 0;
int np = PointCount();
int i = 0;
int np = PointCount();
// stage 1: eliminate duplicate vertices
while ( i < np )
{
int j = i + 1;
while( j < np && CPoint(i) == CPoint( j ) )
j++;
// stage 1: eliminate duplicate vertices
while ( i < np )
{
int j = i + 1;
while( j < np && CPoint(i) == CPoint( j ) )
j++;
pts_unique.push_back( CPoint( i ) );
i = j;
}
pts_unique.push_back( CPoint( i ) );
i = j;
}
m_points.clear();
np = pts_unique.size();
m_points.clear();
np = pts_unique.size();
i = 0;
// stage 1: eliminate collinear segments
while( i < np - 2 )
{
const VECTOR2I p0 = pts_unique[i];
const VECTOR2I p1 = pts_unique[i+1];
int n = i;
i = 0;
// stage 1: eliminate collinear segments
while( i < np - 2 )
{
const VECTOR2I p0 = pts_unique[i];
const VECTOR2I p1 = pts_unique[i+1];
int n = i;
while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 )
n++;
while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 )
n++;
m_points.push_back( p0 );
if( n > i )
i = n;
m_points.push_back( p0 );
if( n > i )
i = n;
if( n == np )
{
m_points.push_back( pts_unique[n - 1] );
return *this;
}
if( n == np )
{
m_points.push_back( pts_unique[n - 1] );
return *this;
}
i++;
}
i++;
}
if( np > 1 )
m_points.push_back( pts_unique[np - 2] );
if( np > 1 )
m_points.push_back( pts_unique[np - 2] );
m_points.push_back( pts_unique[np - 1] );
m_points.push_back( pts_unique[np - 1] );
return *this;
return *this;
}
const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const
{
int min_d = INT_MAX;
int nearest = 0;
for ( int i = 0; i < SegmentCount(); i++ )
{
int d = CSegment( i ).Distance( aP );
if( d < min_d )
{
min_d = d;
nearest = i;
}
}
int min_d = INT_MAX;
int nearest = 0;
for ( int i = 0; i < SegmentCount(); i++ )
{
int d = CSegment( i ).Distance( aP );
if( d < min_d )
{
min_d = d;
nearest = i;
}
}
return CSegment( nearest ).NearestPoint( aP );
return CSegment( nearest ).NearestPoint( aP );
}
const string SHAPE_LINE_CHAIN::Format() const
{
stringstream ss;
stringstream ss;
ss << m_points.size() << " " << ( m_closed ? 1 : 0 ) << " " ;
ss << m_points.size() << " " << ( m_closed ? 1 : 0 ) << " " ;
for( int i = 0; i < PointCount(); i++ )
ss << m_points[i].x << " " << m_points[i].y << " ";// Format() << " ";
for( int i = 0; i < PointCount(); i++ )
ss << m_points[i].x << " " << m_points[i].y << " ";// Format() << " ";
return ss.str();
return ss.str();
}

View File

@ -1,7 +1,7 @@
/*
Boost::Context assembly wrapper - done to avoid compiling the whole boost binary library
which may be unpleasant, in particular under Windows (we don't support VC++, while boost::context
does not support mingw */
Boost::Context assembly wrapper - done to avoid compiling the whole boost binary library
which may be unpleasant, in particular under Windows (we don't support VC++, while boost::context
does not support mingw */
#ifdef __APPLE__

View File

@ -9,39 +9,39 @@
.align 2
_make_fcontext:
mov 0x4(%esp),%eax
lea -0x34(%eax),%eax
and $0xfffffff0,%eax
mov 0x4(%esp),%ecx
mov %ecx,0x18(%eax)
mov 0x8(%esp),%edx
mov %edx,0x1c(%eax)
neg %edx
lea (%edx,%ecx,1),%ecx
mov %ecx,0x20(%eax)
mov 0xc(%esp),%ecx
mov %ecx,0x14(%eax)
stmxcsr 0x2c(%eax)
fnstcw 0x30(%eax)
lea -0x1c(%eax),%edx
mov %edx,0x10(%eax)
mov $0x0,%ecx
mov %ecx,(%edx)
mov %fs:0x18,%ecx
mov (%ecx),%edx
inc %edx
je _make_fcontext+0x4c // <_make_fcontext+0x4c>
dec %edx
xchg %edx,%ecx
jmp _make_fcontext+0x42 // <_make_fcontext+0x42>
mov 0x4(%ecx),%ecx
mov 0x10(%eax),%edx
mov %ecx,0x18(%edx)
mov $0xffffffff,%ecx
mov %ecx,0x14(%edx)
lea 0x14(%edx),%ecx
mov %ecx,0x24(%eax)
ret
mov 0x4(%esp),%eax
lea -0x34(%eax),%eax
and $0xfffffff0,%eax
mov 0x4(%esp),%ecx
mov %ecx,0x18(%eax)
mov 0x8(%esp),%edx
mov %edx,0x1c(%eax)
neg %edx
lea (%edx,%ecx,1),%ecx
mov %ecx,0x20(%eax)
mov 0xc(%esp),%ecx
mov %ecx,0x14(%eax)
stmxcsr 0x2c(%eax)
fnstcw 0x30(%eax)
lea -0x1c(%eax),%edx
mov %edx,0x10(%eax)
mov $0x0,%ecx
mov %ecx,(%edx)
mov %fs:0x18,%ecx
mov (%ecx),%edx
inc %edx
je _make_fcontext+0x4c // <_make_fcontext+0x4c>
dec %edx
xchg %edx,%ecx
jmp _make_fcontext+0x42 // <_make_fcontext+0x42>
mov 0x4(%ecx),%ecx
mov 0x10(%eax),%edx
mov %ecx,0x18(%edx)
mov $0xffffffff,%ecx
mov %ecx,0x14(%edx)
lea 0x14(%edx),%ecx
mov %ecx,0x24(%eax)
ret
finish:
xor %eax,%eax

View File

@ -31,14 +31,14 @@
CONTEXT_MENU::CONTEXT_MENU() :
m_titleSet( false ), m_handler( this ), m_tool( NULL )
{
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler );
m_menu.Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler );
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler );
m_menu.Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler );
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
wxMenuEvent menuEvent( wxEVT_MENU_HIGHLIGHT, -1, &m_menu );
m_menu.AddPendingEvent( menuEvent );
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
wxMenuEvent menuEvent( wxEVT_MENU_HIGHLIGHT, -1, &m_menu );
m_menu.AddPendingEvent( menuEvent );
}
@ -72,16 +72,16 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
// TODO handle an empty string (remove title and separator)
// Unfortunately wxMenu::SetTitle() does nothing..
if( m_titleSet )
{
if( m_titleSet )
{
m_menu.FindItemByPosition( 0 )->SetItemLabel( aTitle );
}
else
{
}
else
{
m_menu.InsertSeparator( 0 );
m_menu.Insert( 0, new wxMenuItem( &m_menu, -1, aTitle, wxEmptyString, wxITEM_NORMAL ) );
m_titleSet = true;
}
}
}
@ -92,7 +92,7 @@ void CONTEXT_MENU::Add( const wxString& aLabel, int aId )
wxLogWarning( wxT( "Adding more than one menu entry with the same ID may result in"
"undefined behaviour" ) );
#endif
m_menu.Append( new wxMenuItem( &m_menu, aId, aLabel, wxEmptyString, wxITEM_NORMAL ) );
m_menu.Append( new wxMenuItem( &m_menu, aId, aLabel, wxEmptyString, wxITEM_NORMAL ) );
}
@ -104,7 +104,7 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
if( aAction.HasHotKey() )
menuEntry = wxString( ( aAction.GetMenuItem() + '\t' + getHotKeyDescription( aAction ) ).c_str(),
wxConvUTF8 );
wxConvUTF8 );
else
menuEntry = wxString( aAction.GetMenuItem().c_str(), wxConvUTF8 );
@ -117,13 +117,13 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
void CONTEXT_MENU::Clear()
{
m_titleSet = false;
m_titleSet = false;
// Remove all the entries from context menu
for( unsigned i = 0; i < m_menu.GetMenuItemCount(); ++i )
m_menu.Destroy( m_menu.FindItemByPosition( 0 ) );
// Remove all the entries from context menu
for( unsigned i = 0; i < m_menu.GetMenuItemCount(); ++i )
m_menu.Destroy( m_menu.FindItemByPosition( 0 ) );
m_toolActions.clear();
m_toolActions.clear();
}

View File

@ -27,23 +27,23 @@
KiGfx::VIEW* TOOL_BASE::getView() const
{
return m_toolMgr->GetView();
return m_toolMgr->GetView();
}
KiGfx::VIEW_CONTROLS* TOOL_BASE::getViewControls() const
{
return m_toolMgr->GetViewControls();
return m_toolMgr->GetViewControls();
}
wxWindow* TOOL_BASE::getEditFrameInt() const
{
return m_toolMgr->GetEditFrame();
return m_toolMgr->GetEditFrame();
}
EDA_ITEM* TOOL_BASE::getModelInt() const
{
return m_toolMgr->GetModel();
return m_toolMgr->GetModel();
}

View File

@ -42,52 +42,52 @@ using boost::optional;
///> Stores information about a mouse button state
struct TOOL_DISPATCHER::ButtonState
{
ButtonState( TOOL_MouseButtons aButton, const wxEventType& aDownEvent,
const wxEventType& aUpEvent ) :
button( aButton ),
downEvent( aDownEvent ),
upEvent( aUpEvent )
{};
ButtonState( TOOL_MouseButtons aButton, const wxEventType& aDownEvent,
const wxEventType& aUpEvent ) :
button( aButton ),
downEvent( aDownEvent ),
upEvent( aUpEvent )
{};
///> Flag indicating that dragging is active for the given button.
bool dragging;
///> Flag indicating that dragging is active for the given button.
bool dragging;
///> Flag indicating that the given button is pressed.
bool pressed;
///> Flag indicating that the given button is pressed.
bool pressed;
///> Point where dragging has started (in world coordinates).
VECTOR2D dragOrigin;
///> Point where dragging has started (in world coordinates).
VECTOR2D dragOrigin;
///> Point where click event has occurred.
VECTOR2D downPosition;
///> Point where click event has occurred.
VECTOR2D downPosition;
///> Difference between drag origin point and current mouse position (expressed as distance in
///> pixels).
double dragMaxDelta;
///> Difference between drag origin point and current mouse position (expressed as distance in
///> pixels).
double dragMaxDelta;
///> Determines the mouse button for which information are stored.
TOOL_MouseButtons button;
///> Determines the mouse button for which information are stored.
TOOL_MouseButtons button;
///> The type of wxEvent that determines mouse button press.
wxEventType downEvent;
///> The type of wxEvent that determines mouse button press.
wxEventType downEvent;
///> The type of wxEvent that determines mouse button release.
wxEventType upEvent;
///> The type of wxEvent that determines mouse button release.
wxEventType upEvent;
///> Time stamp for the last mouse button press event.
wxLongLong downTimestamp;
///> Time stamp for the last mouse button press event.
wxLongLong downTimestamp;
///> Restores initial state.
void Reset()
{
dragging = false;
pressed = false;
}
///> Restores initial state.
void Reset()
{
dragging = false;
pressed = false;
}
};
TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditFrame ) :
m_toolMgr( aToolMgr ), m_editFrame( aEditFrame )
m_toolMgr( aToolMgr ), m_editFrame( aEditFrame )
{
m_buttons.push_back( new ButtonState( MB_Left, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP ) );
m_buttons.push_back( new ButtonState( MB_Right, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_UP ) );
@ -99,135 +99,135 @@ TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditF
TOOL_DISPATCHER::~TOOL_DISPATCHER()
{
BOOST_FOREACH( ButtonState* st, m_buttons )
delete st;
BOOST_FOREACH( ButtonState* st, m_buttons )
delete st;
}
void TOOL_DISPATCHER::ResetState()
{
BOOST_FOREACH( ButtonState* st, m_buttons )
st->Reset();
BOOST_FOREACH( ButtonState* st, m_buttons )
st->Reset();
}
KiGfx::VIEW* TOOL_DISPATCHER::getView()
{
return m_editFrame->GetGalCanvas()->GetView();
return m_editFrame->GetGalCanvas()->GetView();
}
bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMotion )
{
ButtonState* st = m_buttons[aIndex];
wxEventType type = aEvent.GetEventType();
optional<TOOL_EVENT> evt;
bool isClick = false;
ButtonState* st = m_buttons[aIndex];
wxEventType type = aEvent.GetEventType();
optional<TOOL_EVENT> evt;
bool isClick = false;
bool up = type == st->upEvent;
bool down = type == st->downEvent;
bool up = type == st->upEvent;
bool down = type == st->downEvent;
int mods = decodeModifiers<wxMouseEvent>( static_cast<wxMouseEvent*>( &aEvent ) );
int args = st->button | mods;
int mods = decodeModifiers<wxMouseEvent>( static_cast<wxMouseEvent*>( &aEvent ) );
int args = st->button | mods;
if( down ) // Handle mouse button press
{
st->downTimestamp = wxGetLocalTimeMillis();
st->dragOrigin = m_lastMousePos;
st->downPosition = m_lastMousePos;
st->dragMaxDelta = 0;
st->pressed = true;
evt = TOOL_EVENT( TC_Mouse, TA_MouseDown, args );
}
else if( up ) // Handle mouse button release
{
st->pressed = false;
if( down ) // Handle mouse button press
{
st->downTimestamp = wxGetLocalTimeMillis();
st->dragOrigin = m_lastMousePos;
st->downPosition = m_lastMousePos;
st->dragMaxDelta = 0;
st->pressed = true;
evt = TOOL_EVENT( TC_Mouse, TA_MouseDown, args );
}
else if( up ) // Handle mouse button release
{
st->pressed = false;
if( st->dragging )
{
wxLongLong t = wxGetLocalTimeMillis();
if( st->dragging )
{
wxLongLong t = wxGetLocalTimeMillis();
// Determine if it was just a single click or beginning of dragging
if( t - st->downTimestamp < DragTimeThreshold &&
st->dragMaxDelta < DragDistanceThreshold )
isClick = true;
else
evt = TOOL_EVENT( TC_Mouse, TA_MouseUp, args );
}
else
isClick = true;
// Determine if it was just a single click or beginning of dragging
if( t - st->downTimestamp < DragTimeThreshold &&
st->dragMaxDelta < DragDistanceThreshold )
isClick = true;
else
evt = TOOL_EVENT( TC_Mouse, TA_MouseUp, args );
}
else
isClick = true;
if( isClick )
evt = TOOL_EVENT( TC_Mouse, TA_MouseClick, args );
if( isClick )
evt = TOOL_EVENT( TC_Mouse, TA_MouseClick, args );
st->dragging = false;
}
st->dragging = false;
}
if( st->pressed && aMotion )
{
st->dragging = true;
double dragPixelDistance = getView()->ToScreen( m_lastMousePos - st->dragOrigin, false ).EuclideanNorm();
st->dragMaxDelta = std::max( st->dragMaxDelta, dragPixelDistance );
if( st->pressed && aMotion )
{
st->dragging = true;
double dragPixelDistance = getView()->ToScreen( m_lastMousePos - st->dragOrigin, false ).EuclideanNorm();
st->dragMaxDelta = std::max( st->dragMaxDelta, dragPixelDistance );
wxLongLong t = wxGetLocalTimeMillis();
wxLongLong t = wxGetLocalTimeMillis();
if( t - st->downTimestamp > DragTimeThreshold || st->dragMaxDelta > DragDistanceThreshold )
{
evt = TOOL_EVENT( TC_Mouse, TA_MouseDrag, args );
evt->SetMouseDragOrigin( st->dragOrigin );
evt->SetMouseDelta( m_lastMousePos - st->dragOrigin );
}
}
if( t - st->downTimestamp > DragTimeThreshold || st->dragMaxDelta > DragDistanceThreshold )
{
evt = TOOL_EVENT( TC_Mouse, TA_MouseDrag, args );
evt->SetMouseDragOrigin( st->dragOrigin );
evt->SetMouseDelta( m_lastMousePos - st->dragOrigin );
}
}
if( evt )
{
evt->SetMousePosition( isClick ? st->downPosition : m_lastMousePos );
m_toolMgr->ProcessEvent( *evt );
if( evt )
{
evt->SetMousePosition( isClick ? st->downPosition : m_lastMousePos );
m_toolMgr->ProcessEvent( *evt );
return true;
}
return true;
}
return false;
return false;
}
void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
{
bool motion = false, buttonEvents = false;
optional<TOOL_EVENT> evt;
bool motion = false, buttonEvents = false;
optional<TOOL_EVENT> evt;
int type = aEvent.GetEventType();
int type = aEvent.GetEventType();
// Mouse handling
if( type == wxEVT_MOTION || type == wxEVT_MOUSEWHEEL ||
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 )
{
// Mouse handling
if( type == wxEVT_MOTION || type == wxEVT_MOUSEWHEEL ||
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();
VECTOR2D pos = getView()->ToWorld( screenPos );
if( pos != m_lastMousePos || type == KiGfx::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
{
motion = true;
m_lastMousePos = pos;
}
if( pos != m_lastMousePos || type == KiGfx::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
{
motion = true;
m_lastMousePos = pos;
}
for( unsigned int i = 0; i < m_buttons.size(); i++ )
buttonEvents |= handleMouseButton( aEvent, i, motion );
for( unsigned int i = 0; i < m_buttons.size(); i++ )
buttonEvents |= handleMouseButton( aEvent, i, motion );
if( !buttonEvents && motion )
{
evt = TOOL_EVENT( TC_Mouse, TA_MouseMotion );
evt->SetMousePosition( pos );
}
}
if( !buttonEvents && motion )
{
evt = TOOL_EVENT( TC_Mouse, TA_MouseMotion );
evt->SetMousePosition( pos );
}
}
// Keyboard handling
else if( type == wxEVT_KEY_UP || type == wxEVT_KEY_DOWN )
// Keyboard handling
else if( type == wxEVT_KEY_UP || type == wxEVT_KEY_DOWN )
{
wxKeyEvent* ke = static_cast<wxKeyEvent*>( &aEvent );
int key = ke->GetKeyCode();
@ -246,33 +246,33 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
}
}
if( evt )
m_toolMgr->ProcessEvent( *evt );
if( evt )
m_toolMgr->ProcessEvent( *evt );
// pass the event to the GUI, it might still be interested in it
aEvent.Skip();
// pass the event to the GUI, it might still be interested in it
aEvent.Skip();
}
void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
{
bool activateTool = false;
std::string toolName;
bool activateTool = false;
std::string toolName;
// fixme: use TOOL_ACTIONs here
switch( aEvent.GetId() )
{
case ID_PNS_ROUTER_TOOL:
toolName = "pcbnew.InteractiveRouter";
activateTool = true;
break;
case ID_SELECTION_TOOL:
toolName = "pcbnew.InteractiveSelection";
activateTool = true;
break;
}
// fixme: use TOOL_ACTIONs here
switch( aEvent.GetId() )
{
case ID_PNS_ROUTER_TOOL:
toolName = "pcbnew.InteractiveRouter";
activateTool = true;
break;
case ID_SELECTION_TOOL:
toolName = "pcbnew.InteractiveSelection";
activateTool = true;
break;
}
// do nothing if the legacy view is active
if( activateTool && m_editFrame->IsGalCanvasActive() )
m_toolMgr->InvokeTool( toolName );
// do nothing if the legacy view is active
if( activateTool && m_editFrame->IsGalCanvasActive() )
m_toolMgr->InvokeTool( toolName );
}

View File

@ -35,22 +35,22 @@ using namespace std;
struct FlagString
{
int flag;
std::string str;
int flag;
std::string str;
};
static const std::string flag2string( int flag, const FlagString* exps )
{
std::string rv;
std::string rv;
for( int i = 0; exps[i].str.length(); i++ )
{
if( exps[i].flag & flag )
rv += exps[i].str + " ";
}
for( int i = 0; exps[i].str.length(); i++ )
{
if( exps[i].flag & flag )
rv += exps[i].str + " ";
}
return rv;
return rv;
}
@ -62,97 +62,97 @@ bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const
const std::string TOOL_EVENT::Format() const
{
std::string ev;
std::string ev;
const FlagString categories[] = {
{ TC_Mouse, "mouse" },
{ TC_Keyboard, "keyboard" },
{ TC_Command, "command" },
{ TC_Message, "message" },
{ TC_View, "view" },
{ 0, "" }
};
const FlagString categories[] = {
{ TC_Mouse, "mouse" },
{ TC_Keyboard, "keyboard" },
{ TC_Command, "command" },
{ TC_Message, "message" },
{ TC_View, "view" },
{ 0, "" }
};
const FlagString actions[] = {
{ TA_MouseClick, "click" },
{ TA_MouseUp, "button-up" },
{ TA_MouseDown, "button-down" },
{ TA_MouseDrag, "drag" },
{ TA_MouseMotion, "motion" },
{ TA_MouseWheel, "wheel" },
{ TA_KeyUp, "key-up" },
{ TA_KeyDown, "key-down" },
{ TA_ViewRefresh, "view-refresh" },
{ TA_ViewZoom, "view-zoom" },
{ TA_ViewPan, "view-pan" },
{ TA_ViewDirty, "view-dirty" },
{ TA_ChangeLayer, "change-layer" },
{ TA_CancelTool, "cancel-tool" },
{ TA_ContextMenuUpdate, "context-menu-update" },
{ TA_ContextMenuChoice, "context-menu-choice" },
{ TA_Action, "action" },
{ 0, "" }
};
const FlagString actions[] = {
{ TA_MouseClick, "click" },
{ TA_MouseUp, "button-up" },
{ TA_MouseDown, "button-down" },
{ TA_MouseDrag, "drag" },
{ TA_MouseMotion, "motion" },
{ TA_MouseWheel, "wheel" },
{ TA_KeyUp, "key-up" },
{ TA_KeyDown, "key-down" },
{ TA_ViewRefresh, "view-refresh" },
{ TA_ViewZoom, "view-zoom" },
{ TA_ViewPan, "view-pan" },
{ TA_ViewDirty, "view-dirty" },
{ TA_ChangeLayer, "change-layer" },
{ TA_CancelTool, "cancel-tool" },
{ TA_ContextMenuUpdate, "context-menu-update" },
{ TA_ContextMenuChoice, "context-menu-choice" },
{ TA_Action, "action" },
{ 0, "" }
};
const FlagString buttons[] = {
{ MB_None, "none" },
{ MB_Left, "left" },
{ MB_Right, "right" },
{ MB_Middle, "middle" },
{ 0, "" }
};
const FlagString buttons[] = {
{ MB_None, "none" },
{ MB_Left, "left" },
{ MB_Right, "right" },
{ MB_Middle, "middle" },
{ 0, "" }
};
const FlagString modifiers[] = {
const FlagString modifiers[] = {
{ MD_ModShift, "shift" },
{ MD_ModCtrl, "ctrl" },
{ MD_ModAlt, "alt" },
{ 0, "" }
};
};
ev = "category: ";
ev += flag2string( m_category, categories );
ev += " action: ";
ev += flag2string( m_actions, actions );
ev = "category: ";
ev += flag2string( m_category, categories );
ev += " action: ";
ev += flag2string( m_actions, actions );
if( m_actions & TA_Mouse )
{
ev += " btns: ";
ev += flag2string( m_mouseButtons, buttons );
}
if( m_actions & TA_Mouse )
{
ev += " btns: ";
ev += flag2string( m_mouseButtons, buttons );
}
if( m_actions & TA_Keyboard )
{
if( m_actions & TA_Keyboard )
{
char tmp[128];
sprintf( tmp, "key: %d", m_keyCode );
ev += tmp;
}
}
if( m_actions & ( TA_Mouse | TA_Keyboard ) )
{
ev += " mods: ";
ev += flag2string( m_modifiers, modifiers );
}
if( m_actions & ( TA_Mouse | TA_Keyboard ) )
{
ev += " mods: ";
ev += flag2string( m_modifiers, modifiers );
}
if( m_commandId )
{
char tmp[128];
sprintf( tmp, "cmd-id: %d", *m_commandId );
ev += tmp;
}
if( m_commandId )
{
char tmp[128];
sprintf( tmp, "cmd-id: %d", *m_commandId );
ev += tmp;
}
if( m_commandStr )
ev += "cmd-str: " + ( *m_commandStr );
if( m_commandStr )
ev += "cmd-str: " + ( *m_commandStr );
return ev;
return ev;
}
const std::string TOOL_EVENT_LIST::Format() const
{
string s;
string s;
BOOST_FOREACH( TOOL_EVENT e, m_events )
s += e.Format() + " ";
BOOST_FOREACH( TOOL_EVENT e, m_events )
s += e.Format() + " ";
return s;
return s;
}

View File

@ -30,13 +30,13 @@
#include <tool/context_menu.h>
TOOL_INTERACTIVE::TOOL_INTERACTIVE( TOOL_ID aId, const std::string& aName ) :
TOOL_BASE( TOOL_Interactive, aId, aName )
{};
TOOL_BASE( TOOL_Interactive, aId, aName )
{};
TOOL_INTERACTIVE::TOOL_INTERACTIVE( const std::string& aName ) :
TOOL_BASE( TOOL_Interactive, TOOL_MANAGER::MakeToolId( aName ), aName )
{};
TOOL_BASE( TOOL_Interactive, TOOL_MANAGER::MakeToolId( aName ), aName )
{};
TOOL_INTERACTIVE::~TOOL_INTERACTIVE()
@ -46,18 +46,18 @@ TOOL_INTERACTIVE::~TOOL_INTERACTIVE()
OPT_TOOL_EVENT TOOL_INTERACTIVE::Wait( const TOOL_EVENT_LIST& aEventList )
{
return m_toolMgr->ScheduleWait( this, aEventList );
return m_toolMgr->ScheduleWait( this, aEventList );
}
void TOOL_INTERACTIVE::goInternal( TOOL_STATE_FUNC& aState, const TOOL_EVENT_LIST& aConditions )
{
m_toolMgr->ScheduleNextState( this, aState, aConditions );
m_toolMgr->ScheduleNextState( this, aState, aConditions );
}
void TOOL_INTERACTIVE::SetContextMenu( CONTEXT_MENU* aMenu, CONTEXT_MENU_TRIGGER aTrigger )
{
aMenu->setTool( this );
m_toolMgr->ScheduleContextMenu( this, aMenu, aTrigger );
aMenu->setTool( this );
m_toolMgr->ScheduleContextMenu( this, aMenu, aTrigger );
}

View File

@ -52,45 +52,45 @@ using namespace std;
struct TOOL_MANAGER::TOOL_STATE
{
/// The tool itself
TOOL_BASE* theTool;
TOOL_BASE* theTool;
/// Is the tool active (pending execution) or disabled at the moment
bool idle;
/// Is the tool active (pending execution) or disabled at the moment
bool idle;
/// Flag defining if the tool is waiting for any event (i.e. if it
/// issued a Wait() call).
bool pendingWait;
/// 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 being displayed
bool pendingContextMenu;
/// Is there a context menu being displayed
bool pendingContextMenu;
/// Context menu currently used by the tool
CONTEXT_MENU* contextMenu;
/// Context menu currently used by the tool
CONTEXT_MENU* contextMenu;
/// Defines when the context menu is opened
CONTEXT_MENU_TRIGGER contextMenuTrigger;
/// Defines when the context menu is opened
CONTEXT_MENU_TRIGGER contextMenuTrigger;
/// Tool execution context
COROUTINE<int, TOOL_EVENT&>* cofunc;
/// Tool execution context
COROUTINE<int, TOOL_EVENT&>* cofunc;
/// The event that triggered the execution/wakeup of the tool after Wait() call
TOOL_EVENT wakeupEvent;
/// The event that triggered the execution/wakeup of the tool after Wait() call
TOOL_EVENT wakeupEvent;
/// List of events the tool is currently waiting for
TOOL_EVENT_LIST waitEvents;
/// List of events the tool is currently waiting for
TOOL_EVENT_LIST waitEvents;
/// List of possible transitions (ie. association of events and state handlers that are executed
/// upon the event reception
std::vector<TRANSITION> transitions;
/// List of possible transitions (ie. association of events and state handlers that are executed
/// upon the event reception
std::vector<TRANSITION> transitions;
bool operator==( const TOOL_MANAGER::TOOL_STATE& aRhs ) const
bool operator==( const TOOL_MANAGER::TOOL_STATE& aRhs ) const
{
return ( aRhs.theTool == this->theTool );
return ( aRhs.theTool == this->theTool );
}
bool operator!=( const TOOL_MANAGER::TOOL_STATE& aRhs ) const
bool operator!=( const TOOL_MANAGER::TOOL_STATE& aRhs ) const
{
return ( aRhs.theTool != this->theTool );
return ( aRhs.theTool != this->theTool );
}
};
@ -119,37 +119,37 @@ TOOL_MANAGER::~TOOL_MANAGER()
void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool )
{
TOOL_STATE* st = new TOOL_STATE;
TOOL_STATE* st = new TOOL_STATE;
st->theTool = aTool;
st->idle = true;
st->pendingWait = false;
st->pendingContextMenu = false;
st->cofunc = NULL;
st->contextMenuTrigger = CMENU_OFF;
st->theTool = aTool;
st->idle = true;
st->pendingWait = false;
st->pendingContextMenu = false;
st->cofunc = NULL;
st->contextMenuTrigger = CMENU_OFF;
m_toolState[aTool] = st;
m_toolNameIndex[aTool->GetName()] = st;
m_toolIdIndex[aTool->GetId()] = st;
m_toolState[aTool] = st;
m_toolNameIndex[aTool->GetName()] = st;
m_toolIdIndex[aTool->GetId()] = st;
aTool->m_toolMgr = this;
aTool->m_toolMgr = this;
if( aTool->GetType() == TOOL_Interactive )
{
bool initState = static_cast<TOOL_INTERACTIVE*>( aTool )->Init();
if( !initState )
{
wxLogError( wxT( "Initialization of the %s tool failed" ), aTool->GetName().c_str() );
if( aTool->GetType() == TOOL_Interactive )
{
bool initState = static_cast<TOOL_INTERACTIVE*>( aTool )->Init();
if( !initState )
{
wxLogError( wxT( "Initialization of the %s tool failed" ), aTool->GetName().c_str() );
// Unregister the tool
m_toolState.erase( aTool );
m_toolNameIndex.erase( aTool->GetName() );
m_toolIdIndex.erase( aTool->GetId() );
// Unregister the tool
m_toolState.erase( aTool );
m_toolNameIndex.erase( aTool->GetName() );
m_toolIdIndex.erase( aTool->GetId() );
delete st;
delete aTool;
}
}
delete st;
delete aTool;
}
}
}
@ -268,89 +268,89 @@ TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const
void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler,
const TOOL_EVENT_LIST& aConditions )
{
TOOL_STATE* st = m_toolState[aTool];
st->transitions.push_back( TRANSITION( aConditions, aHandler ) );
TOOL_STATE* st = m_toolState[aTool];
st->transitions.push_back( TRANSITION( aConditions, aHandler ) );
}
optional<TOOL_EVENT> TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool,
const TOOL_EVENT_LIST& aConditions )
{
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->waitEvents = aConditions;
// 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();
// switch context back to event dispatcher loop
st->cofunc->Yield();
return st->wakeupEvent;
return st->wakeupEvent;
}
void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
{
// iterate over all registered tools
// iterate over all registered tools
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
{
TOOL_STATE* st = m_toolIdIndex[toolId];
// the tool state handler is waiting for events (i.e. called Wait() method)
if( st->pendingWait )
{
if( st->waitEvents.Matches( aEvent ) )
{
// By default, already processed events are not passed further
m_passEvent = false;
// the tool state handler is waiting for events (i.e. called Wait() method)
if( st->pendingWait )
{
if( st->waitEvents.Matches( aEvent ) )
{
// By default, already processed events are not passed further
m_passEvent = false;
// got matching event? clear wait list and wake up the coroutine
st->wakeupEvent = aEvent;
st->pendingWait = false;
st->waitEvents.clear();
if( st->cofunc && !st->cofunc->Resume() )
finishTool( st ); // The couroutine has finished
// got matching event? clear wait list and wake up the coroutine
st->wakeupEvent = aEvent;
st->pendingWait = false;
st->waitEvents.clear();
if( st->cofunc && !st->cofunc->Resume() )
finishTool( st ); // The couroutine has finished
// If the tool did not request to propagate
// the event to other tools, we should stop it now
if( !m_passEvent )
break;
}
}
// If the tool did not request to propagate
// the event to other tools, we should stop it now
if( !m_passEvent )
break;
}
}
}
BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values )
{
// 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
// Go() method that match the event.
if( st->transitions.size() )
{
BOOST_FOREACH( TRANSITION tr, st->transitions )
{
if( tr.first.Matches( aEvent ) )
{
st->transitions.clear();
if( !st->pendingWait )
{
// no state handler in progress - check if there are any transitions (defined by
// Go() method that match the event.
if( st->transitions.size() )
{
BOOST_FOREACH( TRANSITION tr, st->transitions )
{
if( tr.first.Matches( aEvent ) )
{
st->transitions.clear();
// no tool context allocated yet? Create one.
if( !st->cofunc )
st->cofunc = new COROUTINE<int, TOOL_EVENT&>( tr.second );
else
st->cofunc->SetEntry( tr.second );
// no tool context allocated yet? Create one.
if( !st->cofunc )
st->cofunc = new COROUTINE<int, TOOL_EVENT&>( tr.second );
else
st->cofunc->SetEntry( tr.second );
// got match? Run the handler.
st->cofunc->Call( aEvent );
// got match? Run the handler.
st->cofunc->Call( aEvent );
if( !st->cofunc->Running() )
finishTool( st ); // The couroutine has finished immediately?
}
}
}
}
}
if( !st->cofunc->Running() )
finishTool( st ); // The couroutine has finished immediately?
}
}
}
}
}
}
@ -411,90 +411,90 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
{
// wxLogDebug( "event: %s", aEvent.Format().c_str() );
// wxLogDebug( "event: %s", aEvent.Format().c_str() );
// Early dispatch of events destined for the TOOL_MANAGER
if( !dispatchStandardEvents( aEvent ) )
return false;
dispatchInternal( aEvent );
dispatchInternal( aEvent );
// popup menu handling
// 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 ) )
break;
if( st->contextMenuTrigger != CMENU_OFF )
{
if( st->contextMenuTrigger == CMENU_BUTTON && !aEvent.IsClick( MB_Right ) )
break;
st->pendingWait = true;
st->waitEvents = TOOL_EVENT( TC_Any, TA_Any );
st->pendingWait = true;
st->waitEvents = TOOL_EVENT( TC_Any, TA_Any );
if( st->contextMenuTrigger == CMENU_NOW )
st->contextMenuTrigger = CMENU_OFF;
if( st->contextMenuTrigger == CMENU_NOW )
st->contextMenuTrigger = CMENU_OFF;
boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *st->contextMenu ) );
GetEditFrame()->PopupMenu( menu->GetMenu() );
//
TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice );
dispatchInternal( evt );
TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice );
dispatchInternal( evt );
break;
}
}
break;
}
}
if( m_view->IsDirty() )
{
PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() );
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
}
if( m_view->IsDirty() )
{
PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() );
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
}
return false;
return false;
}
void TOOL_MANAGER::ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu,
CONTEXT_MENU_TRIGGER aTrigger )
{
TOOL_STATE* st = m_toolState[aTool];
TOOL_STATE* st = m_toolState[aTool];
st->contextMenu = aMenu;
st->contextMenuTrigger = aTrigger;
st->contextMenu = aMenu;
st->contextMenuTrigger = aTrigger;
// the tool wants the menu immediately? Preempt it and do so :)
if( aTrigger == CMENU_NOW )
st->cofunc->Yield();
// the tool wants the menu immediately? Preempt it and do so :)
if( aTrigger == CMENU_NOW )
st->cofunc->Yield();
}
TOOL_ID TOOL_MANAGER::MakeToolId( const std::string& aToolName )
{
static int currentId;
return currentId++;
static int currentId;
return currentId++;
}
void TOOL_MANAGER::SetEnvironment( EDA_ITEM* aModel, KiGfx::VIEW* aView,
KiGfx::VIEW_CONTROLS* aViewControls, wxWindow* aFrame )
{
m_model = aModel;
m_view = aView;
m_viewControls = aViewControls;
m_editFrame = aFrame;
m_model = aModel;
m_view = aView;
m_viewControls = aViewControls;
m_editFrame = aFrame;
// Reset state of the registered tools
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
{
TOOL_BASE* tool = m_toolIdIndex[toolId]->theTool;
// Reset state of the registered tools
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
{
TOOL_BASE* tool = m_toolIdIndex[toolId]->theTool;
if( tool->GetType() == TOOL_Interactive )
static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
}
if( tool->GetType() == TOOL_Interactive )
static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
}
}

View File

@ -172,11 +172,11 @@ private:
void programInfo( GLuint aProgram );
/**
* @brief Get the shader information.
*
* @param aShader is the shader number.
*/
void shaderInfo( GLuint aShader );
* @brief Get the shader information.
*
* @param aShader is the shader number.
*/
void shaderInfo( GLuint aShader );
/**
* @brief Read the shader source file

View File

@ -36,278 +36,278 @@ typedef boost::optional<VECTOR2I> OPT_VECTOR2I;
class SEG
{
private:
typedef VECTOR2I::extended_type ecoord;
private:
typedef VECTOR2I::extended_type ecoord;
public:
public:
friend inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg );
friend inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg );
/* Start and the of the segment. Public, to make access simpler. These are references
* to an object the segment belongs to (e.g. a line chain) or references to locally stored points
* (m_a, m_b).
*/
VECTOR2I& a, b;
/* Start and the of the segment. Public, to make access simpler. These are references
* to an object the segment belongs to (e.g. a line chain) or references to locally stored points
* (m_a, m_b).
*/
VECTOR2I& a, b;
/** Default constructor
* Creates an empty (0, 0) segment, locally-referenced
*/
SEG() : a( m_a ), b( m_b )
{
a = m_a;
b = m_b;
m_is_local = true;
m_index = -1;
}
/** Default constructor
* Creates an empty (0, 0) segment, locally-referenced
*/
SEG() : a( m_a ), b( m_b )
{
a = m_a;
b = m_b;
m_is_local = true;
m_index = -1;
}
/**
* Constructor
* Creates a segment between (aX1, aY1) and (aX2, aY2), locally referenced
*/
SEG( int aX1, int aY1, int aX2, int aY2 ) : a( m_a ), b( m_b )
{
m_a = VECTOR2I( aX1, aY1 );
m_b = VECTOR2I( aX2, aY2 );
a = m_a;
b = m_b;
m_is_local = true;
m_index = -1;
}
/**
* Constructor
* Creates a segment between (aX1, aY1) and (aX2, aY2), locally referenced
*/
SEG( int aX1, int aY1, int aX2, int aY2 ) : a( m_a ), b( m_b )
{
m_a = VECTOR2I( aX1, aY1 );
m_b = VECTOR2I( aX2, aY2 );
a = m_a;
b = m_b;
m_is_local = true;
m_index = -1;
}
/**
* 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 )
{
a = m_a;
b = m_b;
m_is_local = true;
m_index = -1;
}
/**
* 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 )
{
a = m_a;
b = m_b;
m_is_local = true;
m_index = -1;
}
/**
* Constructor
* Creates a segment between (aA) and (aB), referenced to a multi-segment shape
* @param aA reference to the start 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
*/
SEG ( VECTOR2I& aA, VECTOR2I& aB, int aIndex ) : a( aA ), b( aB )
{
m_is_local = false;
m_index = aIndex;
}
/**
* Constructor
* Creates a segment between (aA) and (aB), referenced to a multi-segment shape
* @param aA reference to the start 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
*/
SEG ( VECTOR2I& aA, VECTOR2I& aB, int aIndex ) : a( aA ), b( aB )
{
m_is_local = false;
m_index = aIndex;
}
/**
* Copy constructor
*/
SEG ( const SEG& aSeg ) : a( m_a ), b( m_b )
{
if (aSeg.m_is_local)
{
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 = aSeg.a;
b = aSeg.b;
m_index = aSeg.m_index;
m_is_local = false;
}
}
/**
* Copy constructor
*/
SEG ( const SEG& aSeg ) : a( m_a ), b( m_b )
{
if (aSeg.m_is_local)
{
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 = aSeg.a;
b = aSeg.b;
m_index = aSeg.m_index;
m_is_local = false;
}
}
SEG& operator=( const SEG& aSeg )
{
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;
}
SEG& operator=( const SEG& aSeg )
{
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;
}
/**
* Function LineProject()
*
* Computes the perpendicular projection point of aP on a line passing through
* ends of the segment.
* @param aP point to project
* @return projected point
*/
VECTOR2I LineProject( const VECTOR2I& aP ) const;
/**
* Function LineProject()
*
* Computes the perpendicular projection point of aP on a line passing through
* ends of the segment.
* @param aP point to project
* @return projected point
*/
VECTOR2I LineProject( const VECTOR2I& aP ) const;
/**
* Function Side()
*
* Determines on which side of directed line passing via segment ends point aP lies.
* @param aP point to determine the orientation wrs to self
* @return: < 0: left, 0 : on the line, > 0 : right
*/
int Side( const VECTOR2I& aP ) const
{
const ecoord det = ( b - a ).Cross( aP - a );
/**
* Function Side()
*
* Determines on which side of directed line passing via segment ends point aP lies.
* @param aP point to determine the orientation wrs to self
* @return: < 0: left, 0 : on the line, > 0 : right
*/
int Side( const VECTOR2I& aP ) const
{
const ecoord det = ( b - a ).Cross( aP - a );
return det < 0 ? -1 : ( det > 0 ? 1 : 0 );
}
return det < 0 ? -1 : ( det > 0 ? 1 : 0 );
}
/**
* Function LineDistance()
*
* Returns the closest Euclidean distance between point aP and the line defined by
* the ends of segment (this).
* @param aDetermineSide: when true, the sign of the returned value indicates
* the side of the line at which we are (negative = left)
* @return the distance
*/
int LineDistance( const VECTOR2I& aP, bool aDetermineSide = false ) const;
/**
* Function LineDistance()
*
* Returns the closest Euclidean distance between point aP and the line defined by
* the ends of segment (this).
* @param aDetermineSide: when true, the sign of the returned value indicates
* the side of the line at which we are (negative = left)
* @return the distance
*/
int LineDistance( const VECTOR2I& aP, bool aDetermineSide = false ) const;
/**
* Function NearestPoint()
*
* Computes a point on the segment (this) that is closest to point aP.
* @return: nearest point
*/
const VECTOR2I NearestPoint( const VECTOR2I &aP ) const;
/**
* Function NearestPoint()
*
* Computes a point on the segment (this) that is closest to point aP.
* @return: nearest point
*/
const VECTOR2I NearestPoint( const VECTOR2I &aP ) const;
/**
* Function Intersect()
*
* Computes intersection point of segment (this) with segment aSeg.
* @param aSeg: segment to intersect with
* @param aIgnoreEndpoints: don't treat corner cases (i.e. end of one segment touching the other)
* as intersections.
* @param aLines: treat segments as infinite lines
* @return intersection point, if exists
*/
OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false ) const;
/**
* Function Intersect()
*
* Computes intersection point of segment (this) with segment aSeg.
* @param aSeg: segment to intersect with
* @param aIgnoreEndpoints: don't treat corner cases (i.e. end of one segment touching the other)
* as intersections.
* @param aLines: treat segments as infinite lines
* @return intersection point, if exists
*/
OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false ) const;
/**
* Function IntersectLines()
*
* Computes the intersection point of lines passing through ends of (this) and aSeg
* @param aSeg segment defining the line to intersect with
* @return intersection point, if exists
*/
OPT_VECTOR2I IntersectLines( const SEG& aSeg ) const
{
return Intersect( aSeg, false, true );
}
/**
* Function IntersectLines()
*
* Computes the intersection point of lines passing through ends of (this) and aSeg
* @param aSeg segment defining the line to intersect with
* @return intersection point, if exists
*/
OPT_VECTOR2I IntersectLines( const SEG& aSeg ) const
{
return Intersect( aSeg, false, true );
}
bool Collide( const SEG& aSeg, int aClearance ) const;
bool Collide( const SEG& aSeg, int aClearance ) const;
/**
* Function Distance()
*
* Computes minimum Euclidean distance to segment aSeg.
* @param aSeg other segment
* @return minimum distance
*/
/**
* Function Distance()
*
* Computes minimum Euclidean distance to segment aSeg.
* @param aSeg other segment
* @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 ) );
}
int Distance( const SEG& aSeg ) const
{
return sqrt( SquaredDistance( aSeg ) );
}
/**
* Function Distance()
*
* Computes minimum Euclidean distance to point aP.
* @param aP the point
* @return minimum distance
*/
ecoord SquaredDistance( const VECTOR2I& aP ) const
{
return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
}
/**
* Function Distance()
*
* Computes minimum Euclidean distance to point aP.
* @param aP the point
* @return minimum distance
*/
ecoord SquaredDistance( const VECTOR2I& aP ) const
{
return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
}
int Distance( const VECTOR2I& aP ) const
{
return sqrt( SquaredDistance( aP ) );
}
int Distance( const VECTOR2I& aP ) const
{
return sqrt( SquaredDistance( aP ) );
}
/**
* Function Collinear()
*
* Checks if segment aSeg lies on the same line as (this).
* @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;
ecoord qb1 = b.x - a.x;
ecoord qc1 = -qa1 * a.x - qb1 * a.y;
ecoord qa2 = aSeg.a.y - aSeg.b.y;
ecoord qb2 = aSeg.b.x - aSeg.a.x;
ecoord qc2 = -qa2 * aSeg.a.x - qb2 * aSeg.a.y;
/**
* Function Collinear()
*
* Checks if segment aSeg lies on the same line as (this).
* @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;
ecoord qb1 = b.x - a.x;
ecoord qc1 = -qa1 * a.x - qb1 * a.y;
ecoord qa2 = aSeg.a.y - aSeg.b.y;
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 );
}
/**
* Function Length()
*
* Returns the length (this)
* @return length
*/
int Length() const
{
return ( a - b ).EuclideanNorm();
}
/**
* Function Length()
*
* Returns the length (this)
* @return length
*/
int Length() const
{
return ( a - b ).EuclideanNorm();
}
ecoord SquaredLength() const
{
return ( a - b ).SquaredEuclideanNorm();
}
ecoord SquaredLength() const
{
return ( a - b ).SquaredEuclideanNorm();
}
/**
* Function Index()
*
* Return the index of this segment in its parent shape (applicable only to non-local segments)
* @return index value
*/
int Index() const
{
return m_index;
}
/**
* Function Index()
*
* Return the index of this segment in its parent shape (applicable only to non-local segments)
* @return index value
*/
int Index() const
{
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 aDist ) const;
// friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
private:
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
// friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
private:
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;
///> 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;
///> index withing the parent shape (used when m_is_local == false)
int m_index;
///> locality flag
bool m_is_local;
///> locality flag
bool m_is_local;
};
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
{
// fixme: numerical errors for large integers
assert( false );
return VECTOR2I( 0, 0 );
// fixme: numerical errors for large integers
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 r = -p * a.x - q * a.y;
ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q );
@ -338,7 +338,7 @@ inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg )
{
if( aSeg.m_is_local )
aStream << "[ local " << aSeg.a << " - " << aSeg.b << " ]";
aStream << "[ local " << aSeg.a << " - " << aSeg.b << " ]";
return aStream;
}

View File

@ -36,10 +36,10 @@
*/
enum ShapeType {
SH_RECT = 0, ///> axis-aligned rectangle
SH_SEGMENT, ///> line segment
SH_LINE_CHAIN, ///> line chain (polyline)
SH_CIRCLE ///> circle
SH_RECT = 0, ///> axis-aligned rectangle
SH_SEGMENT, ///> line segment
SH_LINE_CHAIN, ///> line chain (polyline)
SH_CIRCLE ///> circle
};
/**
@ -48,97 +48,97 @@ enum ShapeType {
* Represents an abstract shape on 2D plane.
*/
class SHAPE {
protected:
typedef VECTOR2I::extended_type ecoord;
protected:
typedef VECTOR2I::extended_type ecoord;
public:
/**
* Constructor
*
* Creates an empty shape of type aType
*/
public:
/**
* Constructor
*
* Creates an empty shape of type aType
*/
SHAPE ( ShapeType aType ) : m_type( aType ) { };
SHAPE ( ShapeType aType ) : m_type( aType ) { };
// Destructor
virtual ~SHAPE() {};
// Destructor
virtual ~SHAPE() {};
/**
* Function Type()
*
* Returns the type of the shape.
* @retval the type
*/
ShapeType Type() const { return m_type; }
/**
* Function Type()
*
* Returns the type of the shape.
* @retval the type
*/
ShapeType Type() const { return m_type; }
/**
* Function Clone()
*
* Returns a dynamically allocated copy of the shape
* @retval copy of the shape
*/
virtual SHAPE* Clone() const {
assert( false );
return NULL;
};
/**
* Function Clone()
*
* Returns a dynamically allocated copy of the shape
* @retval copy of the shape
*/
virtual SHAPE* Clone() const {
assert( false );
return NULL;
};
/**
* Function Collide()
*
* Checks if the boundary of shape (this) lies closer to the point aP than aClearance, indicating
* a collision.
* @return true, if there is a collision.
*/
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0 ) const
{
return Collide( SEG( aP, aP ), aClearance );
}
/**
* Function Collide()
*
* Checks if the boundary of shape (this) lies closer to the point aP than aClearance, indicating
* a collision.
* @return true, if there is a collision.
*/
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0 ) const
{
return Collide( SEG( aP, aP ), aClearance );
}
/**
* Function Collide()
*
* 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;
/**
* Function Collide()
*
* Checks if the boundary of shape (this) lies closer to the segment aSeg than aClearance, indicating
* a collision.
* @return true, if there is a collision.
*/
virtual bool Collide( const SEG& aSeg, int aClearance = 0 ) const = 0;
/**
* Function Collide()
*
* 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;
/**
* Function Collide()
*
* Checks if the boundary of shape (this) lies closer to the segment aSeg than aClearance, indicating
* a collision.
* @return true, if there is a collision.
*/
virtual bool Collide( const SEG& aSeg, int aClearance = 0 ) const = 0;
/**
* Function Collide()
*
* Computes a bounding box of the shape, with a margin of aClearance
* a collision.
* @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;
/**
* Function Collide()
*
* Computes a bounding box of the shape, with a margin of aClearance
* a collision.
* @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;
/**
* Function Centre()
*
* Computes a center-of-mass of the shape
* @return the center-of-mass point
*/
virtual VECTOR2I Centre() const
{
return BBox( 0 ).Centre(); // if nothing better is available....
}
/**
* Function Centre()
*
* Computes a center-of-mass of the shape
* @return the center-of-mass point
*/
virtual VECTOR2I Centre() const
{
return BBox( 0 ).Centre(); // if nothing better is available....
}
private:
///> type of our shape
ShapeType m_type;
private:
///> type of our shape
ShapeType m_type;
};

View File

@ -30,48 +30,48 @@
class SHAPE_CIRCLE : public SHAPE {
public:
SHAPE_CIRCLE():
SHAPE( SH_CIRCLE ), m_radius( 0 ) {};
SHAPE_CIRCLE():
SHAPE( SH_CIRCLE ), m_radius( 0 ) {};
SHAPE_CIRCLE( const VECTOR2I& aCenter, int aRadius ):
SHAPE( SH_CIRCLE ), m_radius( aRadius ), m_center( aCenter ) {};
SHAPE_CIRCLE( const VECTOR2I& aCenter, int aRadius ):
SHAPE( SH_CIRCLE ), m_radius( aRadius ), m_center( aCenter ) {};
~SHAPE_CIRCLE() {};
~SHAPE_CIRCLE() {};
const BOX2I BBox( int aClearance = 0 ) const
{
const VECTOR2I rc( m_radius + aClearance, m_radius + aClearance );
return BOX2I( m_center - rc, rc * 2 );
}
const BOX2I BBox( int aClearance = 0 ) const
{
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
{
int rc = aClearance + m_radius;
return aSeg.Distance( m_center ) <= rc;
}
bool Collide( const SEG& aSeg, int aClearance = 0 ) const
{
int rc = aClearance + m_radius;
return aSeg.Distance( m_center ) <= rc;
}
void SetRadius( int aRadius )
{
m_radius = aRadius;
}
void SetRadius( int aRadius )
{
m_radius = aRadius;
}
void SetCenter( const VECTOR2I& aCenter )
{
m_center = aCenter;
}
void SetCenter( const VECTOR2I& aCenter )
{
m_center = aCenter;
}
int GetRadius() const
{
return m_radius;
}
int GetRadius() const
{
return m_radius;
}
const VECTOR2I GetCenter() const
{
return m_center;
}
const VECTOR2I GetCenter() const
{
return m_center;
}
private:
int m_radius;
VECTOR2I m_center;
int m_radius;
VECTOR2I m_center;
};
#endif

View File

@ -277,10 +277,10 @@ class SHAPE_INDEX
BOX2I box = aShape->BBox();
box.Inflate( aMinDistance );
int min[2] = { box.GetX(), box.GetY() };
int max[2] = { box.GetRight(), box.GetBottom() };
int min[2] = { box.GetX(), box.GetY() };
int max[2] = { box.GetRight(), box.GetBottom() };
return this->m_tree->Search( min, max, aVisitor );
return this->m_tree->Search( min, max, aVisitor );
}
/**

View File

@ -29,205 +29,205 @@
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> >
class SHAPE_INDEX_LIST {
struct ShapeEntry {
ShapeEntry( T aParent )
{
shape = ShapeFunctor( aParent );
bbox = shape->BBox( 0 );
parent = aParent;
}
struct ShapeEntry {
ShapeEntry( T aParent )
{
shape = ShapeFunctor( aParent );
bbox = shape->BBox( 0 );
parent = aParent;
}
~ShapeEntry()
{
}
~ShapeEntry()
{
}
T parent;
const SHAPE* shape;
BOX2I bbox;
};
T parent;
const SHAPE* shape;
BOX2I bbox;
};
typedef std::vector<ShapeEntry> ShapeVec;
typedef typename std::vector<ShapeEntry>::iterator ShapeVecIter;
typedef std::vector<ShapeEntry> ShapeVec;
typedef typename std::vector<ShapeEntry>::iterator ShapeVecIter;
public:
// "Normal" iterator interface, for STL algorithms.
class iterator {
public:
iterator() {};
// "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 &aB ) :
m_current( aB.m_current ) {};
iterator( const iterator &aB ) :
m_current( aB.m_current ) {};
T operator*() const
{
return (*m_current).parent;
}
T operator*() const
{
return (*m_current).parent;
}
void operator++()
{
++m_current;
}
void operator++()
{
++m_current;
}
iterator& operator++( int aDummy )
{
++m_current;
return *this;
}
iterator& operator++( int aDummy )
{
++m_current;
return *this;
}
bool operator==( const iterator& aRhs ) const
{
return m_current == aRhs.m_current;
}
bool operator==( const iterator& aRhs ) const
{
return m_current == aRhs.m_current;
}
bool operator!=( const iterator& aRhs ) const
{
return m_current != aRhs.m_current;
}
bool operator!=( const iterator& aRhs ) const
{
return m_current != aRhs.m_current;
}
const iterator& operator=( const iterator& aRhs )
{
m_current = aRhs.m_current;
return *this;
}
const iterator& operator=( const iterator& aRhs )
{
m_current = aRhs.m_current;
return *this;
}
private:
ShapeVecIter m_current;
};
private:
ShapeVecIter m_current;
};
// "Query" iterator, for iterating over a set of spatially matching shapes.
class query_iterator {
public:
query_iterator()
{
}
// "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 )
{
if( aShape )
{
m_refBBox = aShape->BBox();
next();
}
}
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 )
{
m_refBBox = aShape->BBox();
next();
}
}
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 )
{
}
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
{
return (*m_current).parent;
}
T operator*() const
{
return (*m_current).parent;
}
query_iterator& operator++()
{
++m_current;
next();
return *this;
}
query_iterator& operator++()
{
++m_current;
next();
return *this;
}
query_iterator& operator++( int aDummy )
{
++m_current;
next();
return *this;
}
query_iterator& operator++( int aDummy )
{
++m_current;
next();
return *this;
}
bool operator==( const query_iterator& aRhs ) const
{
return m_current == aRhs.m_current;
}
bool operator==( const query_iterator& aRhs ) const
{
return m_current == aRhs.m_current;
}
bool operator!=( const query_iterator& aRhs ) const
{
return m_current != aRhs.m_current;
}
bool operator!=( const query_iterator& aRhs ) const
{
return m_current != aRhs.m_current;
}
const query_iterator& operator=( const query_iterator& aRhs )
{
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;
}
const query_iterator& operator=( const query_iterator& aRhs )
{
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 )
{
if( m_refBBox.Distance( m_current->bbox ) <= m_minDistance )
{
if( !m_exact || m_current->shape->Collide( m_shape, m_minDistance ) )
return;
}
private:
void next()
{
while( m_current != m_end )
{
if( m_refBBox.Distance( m_current->bbox ) <= m_minDistance )
{
if( !m_exact || m_current->shape->Collide( m_shape, m_minDistance ) )
return;
}
++m_current;
}
}
++m_current;
}
}
ShapeVecIter m_end;
ShapeVecIter m_current;
BOX2I m_refBBox;
bool m_exact;
SHAPE *m_shape;
int m_minDistance;
};
ShapeVecIter m_end;
ShapeVecIter m_current;
BOX2I m_refBBox;
bool m_exact;
SHAPE *m_shape;
int m_minDistance;
};
void Add( T aItem )
{
ShapeEntry s( aItem );
void Add( T aItem )
{
ShapeEntry s( aItem );
m_shapes.push_back(s);
}
m_shapes.push_back(s);
}
void Remove( const T aItem )
{
ShapeVecIter i;
void Remove( const T aItem )
{
ShapeVecIter i;
for( i = m_shapes.begin(); i != m_shapes.end(); ++i )
{
if( i->parent == aItem )
break;
}
for( i = m_shapes.begin(); i != m_shapes.end(); ++i )
{
if( i->parent == aItem )
break;
}
if( i == m_shapes.end() )
return;
if( i == m_shapes.end() )
return;
m_shapes.erase( i );
}
m_shapes.erase( i );
}
int Size() const
{
return m_shapes.size();
}
int Size() const
{
return m_shapes.size();
}
template<class Visitor>
template<class Visitor>
int Query( const SHAPE *aShape, int aMinDistance, Visitor &aV, bool aExact = true ) //const
{
ShapeVecIter i;
@ -251,33 +251,33 @@ public:
return n;
}
void Clear()
{
m_shapes.clear();
}
void Clear()
{
m_shapes.clear();
}
query_iterator qbegin( SHAPE* aShape, int aMinDistance, bool aExact )
{
return query_iterator( m_shapes.begin(), m_shapes.end(), aShape, aMinDistance, aExact );
}
query_iterator qbegin( SHAPE* aShape, int aMinDistance, bool aExact )
{
return query_iterator( m_shapes.begin(), m_shapes.end(), aShape, aMinDistance, aExact );
}
const query_iterator qend()
{
return query_iterator( m_shapes.end(), m_shapes.end(), NULL, 0, false );
}
const query_iterator qend()
{
return query_iterator( m_shapes.end(), m_shapes.end(), NULL, 0, false );
}
iterator begin()
{
return iterator( m_shapes.begin() );
}
iterator begin()
{
return iterator( m_shapes.begin() );
}
iterator end()
{
return iterator( m_shapes.end() );
}
iterator end()
{
return iterator( m_shapes.end() );
}
private:
ShapeVec m_shapes;
ShapeVec m_shapes;
};
#endif

View File

@ -43,499 +43,499 @@
* SHAPE_LINE_CHAIN class shall not be used for polygons!
*/
class SHAPE_LINE_CHAIN : public SHAPE {
private:
typedef std::vector<VECTOR2I>::iterator point_iter;
typedef std::vector<VECTOR2I>::const_iterator point_citer;
private:
typedef std::vector<VECTOR2I>::iterator point_iter;
typedef std::vector<VECTOR2I>::const_iterator point_citer;
public:
public:
/**
* Struct Intersection
*
* Represents an intersection between two line segments
*/
struct Intersection
{
/// segment belonging from the (this) argument of Intersect()
SEG our;
/// segment belonging from the aOther argument of Intersect()
SEG their;
/// point of intersection between our and their.
VECTOR2I p;
};
/**
* Struct Intersection
*
* Represents an intersection between two line segments
*/
struct Intersection
{
/// segment belonging from the (this) argument of Intersect()
SEG our;
/// segment belonging from the aOther argument of Intersect()
SEG their;
/// point of intersection between our and their.
VECTOR2I p;
};
typedef std::vector<Intersection> Intersections;
typedef std::vector<Intersection> Intersections;
/**
* Constructor
* Initializes an empty line chain.
*/
SHAPE_LINE_CHAIN():
SHAPE( SH_LINE_CHAIN ), m_closed( false ) {};
/**
* Constructor
* Initializes an empty line chain.
*/
SHAPE_LINE_CHAIN():
SHAPE( SH_LINE_CHAIN ), m_closed( false ) {};
/**
* Copy Constructor
*/
SHAPE_LINE_CHAIN( const SHAPE_LINE_CHAIN& aShape ) :
SHAPE( SH_LINE_CHAIN ), m_points( aShape.m_points ), m_closed( aShape.m_closed ) {};
/**
* Copy Constructor
*/
SHAPE_LINE_CHAIN( const SHAPE_LINE_CHAIN& aShape ) :
SHAPE( SH_LINE_CHAIN ), m_points( aShape.m_points ), m_closed( aShape.m_closed ) {};
/**
* Constructor
* Initializes a 2-point line chain (a single segment)
*/
SHAPE_LINE_CHAIN( const VECTOR2I& aA, const VECTOR2I& aB ) :
SHAPE( SH_LINE_CHAIN ),
m_closed( false )
{
m_points.resize( 2 );
m_points[0] = aA;
m_points[1] = aB;
}
/**
* Constructor
* Initializes a 2-point line chain (a single segment)
*/
SHAPE_LINE_CHAIN( const VECTOR2I& aA, const VECTOR2I& aB ) :
SHAPE( SH_LINE_CHAIN ),
m_closed( false )
{
m_points.resize( 2 );
m_points[0] = aA;
m_points[1] = aB;
}
SHAPE_LINE_CHAIN( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I& aC ):
SHAPE( SH_LINE_CHAIN ),
m_closed( false )
{
m_points.resize( 3 );
m_points[0] = aA;
m_points[1] = aB;
m_points[2] = aC;
}
SHAPE_LINE_CHAIN( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I& aC ):
SHAPE( SH_LINE_CHAIN ),
m_closed( false )
{
m_points.resize( 3 );
m_points[0] = aA;
m_points[1] = aB;
m_points[2] = aC;
}
SHAPE_LINE_CHAIN(const VECTOR2I* aV, int aCount ) :
SHAPE( SH_LINE_CHAIN ),
m_closed( false )
{
m_points.resize( aCount );
SHAPE_LINE_CHAIN(const VECTOR2I* aV, int aCount ) :
SHAPE( SH_LINE_CHAIN ),
m_closed( false )
{
m_points.resize( aCount );
for( int i = 0; i < aCount; i++ )
m_points[i] = *aV++;
}
for( int i = 0; i < aCount; i++ )
m_points[i] = *aV++;
}
~SHAPE_LINE_CHAIN() {};
~SHAPE_LINE_CHAIN() {};
/**
* Function Clear()
* Removes all points from the line chain.
*/
void Clear()
{
m_points.clear();
m_closed = false;
}
/**
* Function Clear()
* Removes all points from the line chain.
*/
void Clear()
{
m_points.clear();
m_closed = false;
}
/**
* Function SetClosed()
*
* Marks the line chain as closed (i.e. with a segment connecting the last point with the first point).
* @param aClosed: whether the line chain is to be closed or not.
*/
void SetClosed( bool aClosed )
{
m_closed = aClosed;
}
/**
* Function SetClosed()
*
* Marks the line chain as closed (i.e. with a segment connecting the last point with the first point).
* @param aClosed: whether the line chain is to be closed or not.
*/
void SetClosed( bool aClosed )
{
m_closed = aClosed;
}
/**
* Function IsClosed()
*
* @return aClosed: true, when our line is closed.
*/
bool IsClosed() const
{
return m_closed;
}
/**
* Function IsClosed()
*
* @return aClosed: true, when our line is closed.
*/
bool IsClosed() const
{
return m_closed;
}
/**
* Function SegmentCount()
*
* Returns number of segments in this line chain.
* @return number of segments
*/
int SegmentCount() const
{
int c = m_points.size() - 1;
if( m_closed )
c++;
/**
* Function SegmentCount()
*
* Returns number of segments in this line chain.
* @return number of segments
*/
int SegmentCount() const
{
int c = m_points.size() - 1;
if( m_closed )
c++;
return std::max( 0, c );
}
return std::max( 0, c );
}
/**
* Function PointCount()
*
* Returns the number of points (vertices) in this line chain
* @return number of points
*/
int PointCount() const
{
return m_points.size();
}
/**
* Function PointCount()
*
* Returns the number of points (vertices) in this line chain
* @return number of points
*/
int PointCount() const
{
return m_points.size();
}
/**
* Function Segment()
*
* Returns a segment referencing to the segment (index) in the line chain.
* Modifying ends of the returned segment will modify corresponding points in the line chain.
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* the last segment in the line chain)
* @return SEG referenced to given segment in the line chain
*/
SEG Segment( int aIndex )
{
if( aIndex < 0 )
aIndex += SegmentCount();
/**
* Function Segment()
*
* Returns a segment referencing to the segment (index) in the line chain.
* Modifying ends of the returned segment will modify corresponding points in the line chain.
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* the last segment in the line chain)
* @return SEG referenced to given segment in the line chain
*/
SEG Segment( int aIndex )
{
if( aIndex < 0 )
aIndex += SegmentCount();
if( aIndex == ( m_points.size() - 1 ) && m_closed )
return SEG( m_points[aIndex], m_points[0], aIndex );
else
return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
}
if( aIndex == ( m_points.size() - 1 ) && m_closed )
return SEG( m_points[aIndex], m_points[0], aIndex );
else
return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
}
/**
* Function CSegment()
*
* Returns a read-only segment referencing to the segment (index) in the line chain.
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* the last segment in the line chain)
* @return SEG referenced to given segment in the line chain
*/
const SEG CSegment( int aIndex ) const
{
if( aIndex < 0 )
aIndex += SegmentCount();
/**
* Function CSegment()
*
* Returns a read-only segment referencing to the segment (index) in the line chain.
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* the last segment in the line chain)
* @return SEG referenced to given segment in the line chain
*/
const SEG CSegment( int aIndex ) const
{
if( aIndex < 0 )
aIndex += SegmentCount();
if( aIndex == ( m_points.size() - 1 ) && m_closed )
return SEG( const_cast<VECTOR2I&>( m_points[aIndex] ),
const_cast<VECTOR2I&>( m_points[0] ), aIndex );
else
return SEG( const_cast<VECTOR2I&>( m_points[aIndex] ),
const_cast<VECTOR2I&>( m_points[aIndex + 1] ), aIndex );
}
if( aIndex == ( m_points.size() - 1 ) && m_closed )
return SEG( const_cast<VECTOR2I&>( m_points[aIndex] ),
const_cast<VECTOR2I&>( m_points[0] ), aIndex );
else
return SEG( const_cast<VECTOR2I&>( m_points[aIndex] ),
const_cast<VECTOR2I&>( m_points[aIndex + 1] ), aIndex );
}
/**
* Function Point()
*
* Returns a reference to a given point in the line chain.
* @param aIndex index of the point
* @return reference to the point
*/
VECTOR2I& Point( int aIndex )
{
if( aIndex < 0 )
aIndex += PointCount();
/**
* Function Point()
*
* Returns a reference to a given point in the line chain.
* @param aIndex index of the point
* @return reference to the point
*/
VECTOR2I& Point( int aIndex )
{
if( aIndex < 0 )
aIndex += PointCount();
return m_points[aIndex];
}
return m_points[aIndex];
}
/**
* Function CPoint()
*
* Returns a const reference to a given point in the line chain.
* @param aIndex index of the point
* @return const reference to the point
*/
const VECTOR2I& CPoint( int aIndex ) const
{
if( aIndex < 0 )
aIndex += PointCount();
/**
* Function CPoint()
*
* Returns a const reference to a given point in the line chain.
* @param aIndex index of the point
* @return const reference to the point
*/
const VECTOR2I& CPoint( int aIndex ) const
{
if( aIndex < 0 )
aIndex += PointCount();
return m_points[aIndex];
}
return m_points[aIndex];
}
/// @copydoc SHAPE::BBox()
const BOX2I BBox( int aClearance = 0 ) const
{
BOX2I bbox;
bbox.Compute( m_points );
/// @copydoc SHAPE::BBox()
const BOX2I BBox( int aClearance = 0 ) const
{
BOX2I bbox;
bbox.Compute( m_points );
return bbox;
}
return bbox;
}
/**
* Function Collide()
*
* Checks if point aP lies closer to us than aClearance.
* @param aP the point to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
*/
bool Collide( const VECTOR2I& aP, int aClearance = 0 ) const;
/**
* Function Collide()
*
* Checks if point aP lies closer to us than aClearance.
* @param aP the point to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
*/
bool Collide( const VECTOR2I& aP, int aClearance = 0 ) const;
/**
* Function Collide()
*
* Checks if box aBox lies closer to us than aClearance.
* @param aP the box to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
*/
bool Collide( const BOX2I& aBox, int aClearance = 0 ) const;
/**
* Function Collide()
*
* Checks if box aBox lies closer to us than aClearance.
* @param aP the box to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
*/
bool Collide( const BOX2I& aBox, int aClearance = 0 ) const;
/**
* Function Collide()
*
* Checks if segment aSeg lies closer to us than aClearance.
* @param aSeg the segment to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
*/
bool Collide( const SEG& aSeg, int aClearance = 0 ) const;
/**
* Function Collide()
*
* Checks if segment aSeg lies closer to us than aClearance.
* @param aSeg the segment to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
*/
bool Collide( const SEG& aSeg, int aClearance = 0 ) const;
/**
* Function Distance()
*
* Computes the minimum distance between the line chain and a point aP.
* @param aP the point
* @return minimum distance.
*/
int Distance( const VECTOR2I& aP ) const;
/**
* Function Distance()
*
* Computes the minimum distance between the line chain and a point aP.
* @param aP the point
* @return minimum distance.
*/
int Distance( const VECTOR2I& aP ) const;
/**
* Function Reverse()
*
* Reverses point order in the line chain.
* @return line chain with reversed point order (original A-B-C-D: returned D-C-B-A)
*/
const SHAPE_LINE_CHAIN Reverse() const;
/**
* Function Reverse()
*
* Reverses point order in the line chain.
* @return line chain with reversed point order (original A-B-C-D: returned D-C-B-A)
*/
const SHAPE_LINE_CHAIN Reverse() const;
/**
* Function Length()
*
* Returns length of the line chain in Euclidean metric.
* @return length of the line chain
*/
int Length() const;
/**
* Function Length()
*
* Returns length of the line chain in Euclidean metric.
* @return length of the line chain
*/
int Length() const;
/**
* Function Append()
*
* Appends a new point at the end of the line chain.
* @param aX is X coordinate of the new point
* @param aY is Y coordinate of the new point
*/
void Append( int aX, int aY )
{
VECTOR2I v( aX, aY );
Append( v );
}
/**
* Function Append()
*
* Appends a new point at the end of the line chain.
* @param aX is X coordinate of the new point
* @param aY is Y coordinate of the new point
*/
void Append( int aX, int aY )
{
VECTOR2I v( aX, aY );
Append( v );
}
/**
* Function Append()
*
* Appends a new point at the end of the line chain.
* @param aP the new point
*/
void Append( const VECTOR2I& aP )
{
if( m_points.size() == 0 )
m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
/**
* Function Append()
*
* Appends a new point at the end of the line chain.
* @param aP the new point
*/
void Append( const VECTOR2I& aP )
{
if( m_points.size() == 0 )
m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
if( m_points.size() == 0 || CPoint( -1 ) != aP )
{
m_points.push_back( aP );
m_bbox.Merge( aP );
}
}
if( m_points.size() == 0 || CPoint( -1 ) != aP )
{
m_points.push_back( aP );
m_bbox.Merge( aP );
}
}
/**
* Function Append()
*
* Appends another line chain at the end.
* @param aOtherLine the line chain to be appended.
*/
void Append( const SHAPE_LINE_CHAIN& aOtherLine )
{
if( aOtherLine.PointCount() == 0 )
return;
/**
* Function Append()
*
* Appends another line chain at the end.
* @param aOtherLine the line chain to be appended.
*/
void Append( const SHAPE_LINE_CHAIN& aOtherLine )
{
if( aOtherLine.PointCount() == 0 )
return;
else if( PointCount() == 0 || aOtherLine.CPoint( 0 ) != CPoint( -1 ) )
{
const VECTOR2I p = aOtherLine.CPoint( 0 );
m_points.push_back( p );
m_bbox.Merge( p );
}
else if( PointCount() == 0 || aOtherLine.CPoint( 0 ) != CPoint( -1 ) )
{
const VECTOR2I p = aOtherLine.CPoint( 0 );
m_points.push_back( p );
m_bbox.Merge( p );
}
for( int i = 1; i < aOtherLine.PointCount(); i++ )
{
const VECTOR2I p = aOtherLine.CPoint( i );
m_points.push_back( p );
m_bbox.Merge( p );
}
}
for( int i = 1; i < aOtherLine.PointCount(); i++ )
{
const VECTOR2I p = aOtherLine.CPoint( i );
m_points.push_back( p );
m_bbox.Merge( p );
}
}
/**
* Function Replace()
*
* Replaces points with indices in range [start_index, end_index] with a single
* point aP.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aP replacement point
*/
void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
/**
* Function Replace()
*
* Replaces points with indices in range [start_index, end_index] with a single
* point aP.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aP replacement point
*/
void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
/**
* Function Replace()
*
* Replaces points with indices in range [start_index, end_index] with the points from
* line chain aLine.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aLine replacement line chain.
*/
void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
/**
* Function Replace()
*
* Replaces points with indices in range [start_index, end_index] with the points from
* line chain aLine.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aLine replacement line chain.
*/
void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
/**
* Function Remove()
*
* Removes the range of points [start_index, end_index] from the line chain.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
*/
void Remove( int aStartIndex, int aEndIndex );
/**
* Function Remove()
*
* Removes the range of points [start_index, end_index] from the line chain.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
*/
void Remove( int aStartIndex, int aEndIndex );
/**
* Function Split()
*
* Inserts the point aP belonging to one of the our segments, splitting the adjacent
* segment in two.
* @param aP the point to be inserted
* @return index of the newly inserted point (or a negative value if aP does not lie on our line)
*/
int Split( const VECTOR2I& aP );
/**
* Function Split()
*
* Inserts the point aP belonging to one of the our segments, splitting the adjacent
* segment in two.
* @param aP the point to be inserted
* @return index of the newly inserted point (or a negative value if aP does not lie on our line)
*/
int Split( const VECTOR2I& aP );
/**
* Function Find()
*
* Searches for point aP.
* @param aP the point to be looked for
* @return index of the correspoinding point in the line chain or negative when not found.
*/
int Find ( const VECTOR2I& aP ) const;
/**
* Function Find()
*
* Searches for point aP.
* @param aP the point to be looked for
* @return index of the correspoinding point in the line chain or negative when not found.
*/
int Find ( const VECTOR2I& aP ) const;
/**
* Function Slice()
*
* Returns a subset of this line chain containing the [start_index, end_index] range of points.
* @param aStartIndex start of the point range to be returned (inclusive)
* @param aEndIndex end of the point range to be returned (inclusive)
* @return cut line chain.
*/
const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex = -1) const;
/**
* Function Slice()
*
* Returns a subset of this line chain containing the [start_index, end_index] range of points.
* @param aStartIndex start of the point range to be returned (inclusive)
* @param aEndIndex end of the point range to be returned (inclusive)
* @return cut line chain.
*/
const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex = -1) const;
struct compareOriginDistance
{
compareOriginDistance( VECTOR2I& aOrigin ):
m_origin( aOrigin ) {};
struct compareOriginDistance
{
compareOriginDistance( VECTOR2I& aOrigin ):
m_origin( aOrigin ) {};
bool operator()( const Intersection& aA, const Intersection& aB )
{
return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
}
bool operator()( const Intersection& aA, const Intersection& aB )
{
return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
}
VECTOR2I m_origin;
};
VECTOR2I m_origin;
};
/**
* Function Intersect()
*
* Finds all intersection points between our line chain and the segment aSeg.
* @param aSeg the segment chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing distances from point aSeg.a.
* @return number of intersections found
*/
int Intersect ( const SEG& aSeg, Intersections& aIp ) const;
/**
* Function Intersect()
*
* Finds all intersection points between our line chain and the segment aSeg.
* @param aSeg the segment chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing distances from point aSeg.a.
* @return number of intersections found
*/
int Intersect ( const SEG& aSeg, Intersections& aIp ) const;
/**
* Function Intersect()
*
* Finds all intersection points between our line chain and the line chain aChain.
* @param aChain the line chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing path lengths from the starting point of aChain.
* @return number of intersections found
*/
int Intersect( const SHAPE_LINE_CHAIN& aChain, Intersections& aIp ) const;
/**
* Function Intersect()
*
* Finds all intersection points between our line chain and the line chain aChain.
* @param aChain the line chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing path lengths from the starting point of aChain.
* @return number of intersections found
*/
int Intersect( const SHAPE_LINE_CHAIN& aChain, Intersections& aIp ) const;
/**
* Function PathLength()
*
* Computes the walk path length from the beginning of the line chain and
* the point aP belonging to our line.
* @return: path length in Euclidean metric or negative if aP does not belong to the line chain.
*/
int PathLength( const VECTOR2I& aP ) const;
/**
* Function PathLength()
*
* Computes the walk path length from the beginning of the line chain and
* the point aP belonging to our line.
* @return: path length in Euclidean metric or negative if aP does not belong to the line chain.
*/
int PathLength( const VECTOR2I& aP ) const;
/**
* Function PointInside()
*
* Checks if point aP lies inside a convex polygon defined by the line chain. For closed
* shapes only.
* @param aP point to check
* @return true if the point is inside the shape (edge is not treated as being inside).
*/
bool PointInside( const VECTOR2I& aP ) const;
/**
* Function PointInside()
*
* Checks if point aP lies inside a convex polygon defined by the line chain. For closed
* shapes only.
* @param aP point to check
* @return true if the point is inside the shape (edge is not treated as being inside).
*/
bool PointInside( const VECTOR2I& aP ) const;
/**
* Function PointOnEdge()
*
* Checks if point aP lies on an edge or vertex of the line chain.
* @param aP point to check
* @return true if the point lies on the edge.
*/
bool PointOnEdge( const VECTOR2I& aP ) const;
/**
* Function PointOnEdge()
*
* Checks if point aP lies on an edge or vertex of the line chain.
* @param aP point to check
* @return true if the point lies on the edge.
*/
bool PointOnEdge( const VECTOR2I& aP ) const;
/**
* Function SelfIntersecting()
*
* Checks if the line chain is self-intersecting.
* @return (optional) first found self-intersection point.
*/
const boost::optional<Intersection> SelfIntersecting() const;
/**
* Function SelfIntersecting()
*
* Checks if the line chain is self-intersecting.
* @return (optional) first found self-intersection point.
*/
const boost::optional<Intersection> SelfIntersecting() const;
/**
* Function Simplify()
*
* Simplifies the line chain by removing colinear adjacent segments and duplicate vertices.
* @return reference to self.
*/
SHAPE_LINE_CHAIN& Simplify();
/**
* Function Simplify()
*
* Simplifies the line chain by removing colinear adjacent segments and duplicate vertices.
* @return reference to self.
*/
SHAPE_LINE_CHAIN& Simplify();
/**
* Function NearestPoint()
*
* Finds a point on the line chain that is closest to point aP.
* @return the nearest point.
*/
const VECTOR2I NearestPoint( const VECTOR2I& aP ) const;
/**
* Function NearestPoint()
*
* Finds a point on the line chain that is closest to point aP.
* @return the nearest point.
*/
const VECTOR2I NearestPoint( const VECTOR2I& aP ) const;
/// @copydoc SHAPE::Format()
const std::string Format() const;
/// @copydoc SHAPE::Format()
const std::string Format() const;
bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
{
if( PointCount() != aRhs.PointCount() )
return true;
bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
{
if( PointCount() != aRhs.PointCount() )
return true;
for( int i = 0; i < PointCount(); i++ )
{
if( CPoint( i ) != aRhs.CPoint( i ) )
return true;
}
for( int i = 0; i < PointCount(); i++ )
{
if( CPoint( i ) != aRhs.CPoint( i ) )
return true;
}
return false;
}
return false;
}
private:
/// array of vertices
std::vector<VECTOR2I> m_points;
private:
/// array of vertices
std::vector<VECTOR2I> m_points;
/// is the line chain closed?
bool m_closed;
/// is the line chain closed?
bool m_closed;
/// cached bounding box
BOX2I m_bbox;
/// cached bounding box
BOX2I m_bbox;
};
#endif // __SHAPE_LINE_CHAIN

View File

@ -31,114 +31,114 @@
#include <geometry/seg.h>
class SHAPE_RECT : public SHAPE {
public:
/**
* Constructor
* Creates an empty (0-sized) rectangle
*/
SHAPE_RECT() :
SHAPE( SH_RECT ), m_w( 0 ), m_h( 0 ) {};
public:
/**
* Constructor
* Creates an empty (0-sized) rectangle
*/
SHAPE_RECT() :
SHAPE( SH_RECT ), m_w( 0 ), m_h( 0 ) {};
/**
* Constructor
* Creates a rectangle defined by top-left corner (aX0, aY0), width aW and height aH.
*/
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 (aX0, aY0), width aW and height aH.
*/
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 aP0, width aW and height aH.
*/
SHAPE_RECT( const VECTOR2I &aP0, int aW, int aH ) :
SHAPE( SH_RECT ), m_p0( aP0 ), m_w( aW ), m_h( aH ) {};
/**
* Constructor
* Creates a rectangle defined by top-left corner aP0, width aW and height aH.
*/
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 ) );
//printf("bb : %s\n",bbox.Format().c_str());
return bbox;
}
/// @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 ) );
//printf("bb : %s\n",bbox.Format().c_str());
return bbox;
}
/**
* Function Diagonal()
*
* Returns length of the diagonal of the rectangle
* @return diagonal length
*/
int Diagonal() const
{
return VECTOR2I( m_w, m_h ).EuclideanNorm();
}
/**
* Function Diagonal()
*
* Returns length of the diagonal of the rectangle
* @return diagonal length
*/
int Diagonal() const
{
return VECTOR2I( m_w, m_h ).EuclideanNorm();
}
/// @copydoc SHAPE::Collide()
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));
//BOX2I r(pmin, VECTOR2I(pmax.x - pmin.x, pmax.y - pmin.y));
/// @copydoc SHAPE::Collide()
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));
//BOX2I r(pmin, VECTOR2I(pmax.x - pmin.x, pmax.y - pmin.y));
//if (BBox(0).SquaredDistance(r) > aClearance * aClearance)
// return false;
//if (BBox(0).SquaredDistance(r) > aClearance * aClearance)
// return false;
if( BBox( 0 ).Contains( aSeg.a ) || BBox( 0 ).Contains( aSeg.b ) )
return true;
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++ )
{
SEG s( vts[i], vts[i + 1], i );
if( s.Distance( aSeg ) <= aClearance )
return true;
}
for( int i = 0; i < 4; i++ )
{
SEG s( vts[i], vts[i + 1], i );
if( s.Distance( aSeg ) <= aClearance )
return true;
}
return false;
};
return false;
};
/**
* Function GetPosition()
*
* @return top-left corner of the rectangle
*/
const VECTOR2I& GetPosition() const { return m_p0; }
/**
* Function GetPosition()
*
* @return top-left corner of the rectangle
*/
const VECTOR2I& GetPosition() const { return m_p0; }
/**
* Function GetSize()
*
* @return size of the rectangle
*/
const VECTOR2I GetSize() const { return VECTOR2I( m_w, m_h ); }
/**
* Function GetSize()
*
* @return size of the rectangle
*/
const VECTOR2I GetSize() const { return VECTOR2I( m_w, m_h ); }
/**
* Function GetWidth()
*
* @return width of the rectangle
*/
const int GetWidth() const { return m_w; }
/**
* Function GetWidth()
*
* @return width of the rectangle
*/
const int GetWidth() const { return m_w; }
/**
* Function GetHeight()
*
* @return height of the rectangle
*/
const int GetHeight() const { return m_h; }
/**
* Function GetHeight()
*
* @return height of the rectangle
*/
const int GetHeight() const { return m_h; }
private:
///> Top-left corner
VECTOR2I m_p0;
private:
///> Top-left corner
VECTOR2I m_p0;
///> Width
int m_w;
///> Width
int m_w;
///> Height
int m_h;
};
///> Height
int m_h;
};
#endif // __SHAPE_RECT_H

View File

@ -41,101 +41,101 @@ class CONTEXT_MENU
{
public:
///> Default constructor
CONTEXT_MENU();
CONTEXT_MENU();
///> Copy constructor
CONTEXT_MENU( const CONTEXT_MENU& aMenu );
///> Copy constructor
CONTEXT_MENU( const CONTEXT_MENU& aMenu );
/**
* Function SetTitle()
* Sets title for the context menu. The title is shown as a text label shown on the top of
* the menu.
* @param aTitle is the new title.
*/
void SetTitle( const wxString& aTitle );
/**
* Function SetTitle()
* Sets title for the context menu. The title is shown as a text label shown on the top of
* the menu.
* @param aTitle is the new title.
*/
void SetTitle( const wxString& aTitle );
/**
* Function Add()
* Adds an entry to the menu. After highlighting/selecting the entry, a TOOL_EVENT command is
* sent that contains ID of the entry.
* @param aLabel is the text label show in the menu.
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
*/
void Add( const wxString& aLabel, int aId );
/**
* Function Add()
* Adds an entry to the menu. After highlighting/selecting the entry, a TOOL_EVENT command is
* sent that contains ID of the entry.
* @param aLabel is the text label show in the menu.
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
*/
void Add( const wxString& aLabel, int aId );
/**
* Function Add()
* Adds an entry to the menu, basing on the TOOL_ACTION object. After selecting the entry,
* a TOOL_EVENT command containing name of the action is sent.
* @param aAction is the action to be added to menu entry.
*/
void Add( const TOOL_ACTION& aAction );
/**
* Function Add()
* Adds an entry to the menu, basing on the TOOL_ACTION object. After selecting the entry,
* a TOOL_EVENT command containing name of the action is sent.
* @param aAction is the action to be added to menu entry.
*/
void Add( const TOOL_ACTION& aAction );
/**
* Function Clear()
* Removes all the entries from the menu (as well as its title). It leaves the menu in the
* initial state.
*/
void Clear();
/**
* Function Clear()
* Removes all the entries from the menu (as well as its title). It leaves the menu in the
* initial state.
*/
void Clear();
/**
* Function GetMenu()
* Returns the instance of wxMenu object used to display the menu.
*/
wxMenu* GetMenu() const
{
return const_cast<wxMenu*>( &m_menu );
}
/**
* Function GetMenu()
* Returns the instance of wxMenu object used to display the menu.
*/
wxMenu* GetMenu() const
{
return const_cast<wxMenu*>( &m_menu );
}
private:
///> Class CMEventHandler takes care of handling menu events. After reception of particular
///> events, it translates them to TOOL_EVENTs that may control tools.
class CMEventHandler : public wxEvtHandler
{
public:
///> Default constructor
///> aMenu is the CONTEXT_MENU instance for which it handles events.
CMEventHandler( CONTEXT_MENU* aMenu ) : m_menu( aMenu ) {};
///> Class CMEventHandler takes care of handling menu events. After reception of particular
///> events, it translates them to TOOL_EVENTs that may control tools.
class CMEventHandler : public wxEvtHandler
{
public:
///> Default constructor
///> aMenu is the CONTEXT_MENU instance for which it handles events.
CMEventHandler( CONTEXT_MENU* aMenu ) : m_menu( aMenu ) {};
///> Handler for menu events.
void onEvent( wxEvent& aEvent );
///> Handler for menu events.
void onEvent( wxEvent& aEvent );
private:
///> CONTEXT_MENU instance for which it handles events.
CONTEXT_MENU* m_menu;
};
private:
///> CONTEXT_MENU instance for which it handles events.
CONTEXT_MENU* m_menu;
};
friend class TOOL_INTERACTIVE;
friend class TOOL_INTERACTIVE;
/**
* Function setTool()
* Sets a tool that is the creator of the menu.
* @param aTool is the tool that created the menu.
*/
void setTool( TOOL_INTERACTIVE* aTool )
{
m_tool = aTool;
}
/**
* Function setTool()
* Sets a tool that is the creator of the menu.
* @param aTool is the tool that created the menu.
*/
void setTool( TOOL_INTERACTIVE* aTool )
{
m_tool = aTool;
}
/**
* Function getHotKeyDescription()
* Returns a hot key in the string format accepted by wxMenu.
* @param aAction is the action with hot key to be translated..
* @return Hot key in the string format compatible with wxMenu.
*/
std::string getHotKeyDescription( const TOOL_ACTION& aAction ) const;
/**
* Function getHotKeyDescription()
* Returns a hot key in the string format accepted by wxMenu.
* @param aAction is the action with hot key to be translated..
* @return Hot key in the string format compatible with wxMenu.
*/
std::string getHotKeyDescription( const TOOL_ACTION& aAction ) const;
///> Flag indicating that the menu title was set up.
bool m_titleSet;
///> Flag indicating that the menu title was set up.
bool m_titleSet;
///> Instance of wxMenu used for display of the context menu.
wxMenu m_menu;
///> Instance of wxMenu used for display of the context menu.
wxMenu m_menu;
///> Instance of menu event handler.
CMEventHandler m_handler;
///> Instance of menu event handler.
CMEventHandler m_handler;
///> Creator of the menu
TOOL_INTERACTIVE* m_tool;
///> Creator of the menu
TOOL_INTERACTIVE* m_tool;
/// Menu items with ID higher than that are considered TOOL_ACTIONs
static const int m_actionId = 10000;

View File

@ -56,82 +56,82 @@ template<class ReturnType, class ArgType>
class COROUTINE
{
public:
COROUTINE()
{
m_stackSize = c_defaultStackSize;
m_stack = NULL;
m_saved = NULL;
}
COROUTINE()
{
m_stackSize = c_defaultStackSize;
m_stack = NULL;
m_saved = NULL;
}
/**
* Constructor
* Creates a coroutine from a member method of an object
*/
template<class T>
COROUTINE( T* object, ReturnType (T::*ptr)( ArgType ) ) :
m_func( object, ptr ), m_saved( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize )
{
}
/**
* Constructor
* Creates a coroutine from a member method of an object
*/
template<class T>
COROUTINE( T* object, ReturnType (T::*ptr)( ArgType ) ) :
m_func( object, ptr ), m_saved( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize )
{
}
/**
* Constructor
* Creates a coroutine from a delegate object
*/
COROUTINE( DELEGATE<ReturnType, ArgType> aEntry ) :
/**
* Constructor
* Creates a coroutine from a delegate object
*/
COROUTINE( DELEGATE<ReturnType, ArgType> aEntry ) :
m_func( aEntry ), m_saved( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize )
{};
{};
~COROUTINE()
{
~COROUTINE()
{
if( m_saved )
delete m_saved;
if( m_stack )
free( m_stack );
}
}
/**
* Function Yield()
*
* Stops execution of the coroutine and returns control to the caller.
* After a yield, Call() or Resume() methods invoked by the caller will
* immediately return true, indicating that we are not done yet, just asleep.
*/
void Yield()
{
boost::context::jump_fcontext( m_self, m_saved, 0 );
}
/**
* Function Yield()
*
* Stops execution of the coroutine and returns control to the caller.
* After a yield, Call() or Resume() methods invoked by the caller will
* immediately return true, indicating that we are not done yet, just asleep.
*/
void Yield()
{
boost::context::jump_fcontext( m_self, m_saved, 0 );
}
/**
* Function Yield()
*
* Yield with a value - passes a value of given type to the caller.
* Useful for implementing generator objects.
*/
void Yield( ReturnType& retVal )
{
m_retVal = retVal;
boost::context::jump_fcontext( m_self, m_saved, 0 );
}
/**
* Function Yield()
*
* Yield with a value - passes a value of given type to the caller.
* Useful for implementing generator objects.
*/
void Yield( ReturnType& retVal )
{
m_retVal = retVal;
boost::context::jump_fcontext( m_self, m_saved, 0 );
}
/**
<F11>* Function SetEntry()
*
* Defines the entry point for the coroutine, if not set in the constructor.
*/
void SetEntry( DELEGATE<ReturnType, ArgType> aEntry )
{
m_func = aEntry;
}
/**
<F11>* Function SetEntry()
*
* Defines the entry point for the coroutine, if not set in the constructor.
*/
void SetEntry( DELEGATE<ReturnType, ArgType> aEntry )
{
m_func = aEntry;
}
/* Function Call()
*
* Starts execution of a coroutine, passing args as its arguments.
* @return true, if the coroutine has yielded and false if it has finished its
* execution (returned).
*/
bool Call( ArgType args )
{
// fixme: Clean up stack stuff. Add a guard
/* Function Call()
*
* Starts execution of a coroutine, passing args as its arguments.
* @return true, if the coroutine has yielded and false if it has finished its
* execution (returned).
*/
bool Call( ArgType args )
{
// fixme: Clean up stack stuff. Add a guard
m_stack = malloc( c_defaultStackSize );
// align to 16 bytes
@ -145,87 +145,87 @@ public:
// off we go!
boost::context::jump_fcontext( m_saved, m_self, reinterpret_cast<intptr_t>( this ) );
return m_running;
}
}
/**
* Function Resume()
*
* Resumes execution of a previously yielded coroutine.
* @return true, if the coroutine has yielded again and false if it has finished its
* execution (returned).
*/
bool Resume()
{
/**
* Function Resume()
*
* Resumes execution of a previously yielded coroutine.
* @return true, if the coroutine has yielded again and false if it has finished its
* execution (returned).
*/
bool Resume()
{
boost::context::jump_fcontext( m_saved, m_self, 0 );
return m_running;
}
}
/**
* Function ReturnValue()
*
* Returns the yielded value (the argument Yield() was called with)
*/
const ReturnType& ReturnValue() const
{
return m_retVal;
}
/**
* Function ReturnValue()
*
* Returns the yielded value (the argument Yield() was called with)
*/
const ReturnType& ReturnValue() const
{
return m_retVal;
}
/**
* Function Running()
*
* @return true, if the coroutine is active
*/
bool Running() const
{
return m_running;
}
/**
* Function Running()
*
* @return true, if the coroutine is active
*/
bool Running() const
{
return m_running;
}
private:
static const int c_defaultStackSize = 2000000; // fixme: make configurable
static const int c_defaultStackSize = 2000000; // fixme: make configurable
/* real entry point of the coroutine */
static void callerStub( intptr_t data )
{
// get pointer to self
COROUTINE<ReturnType, ArgType>* cor = reinterpret_cast<COROUTINE<ReturnType, ArgType>*>( data );
/* real entry point of the coroutine */
static void callerStub( intptr_t data )
{
// get pointer to self
COROUTINE<ReturnType, ArgType>* cor = reinterpret_cast<COROUTINE<ReturnType, ArgType>*>( data );
// call the coroutine method
cor->m_retVal = cor->m_func( *cor->m_args );
cor->m_running = false;
// call the coroutine method
cor->m_retVal = cor->m_func( *cor->m_args );
cor->m_running = false;
// go back to wherever we came from.
boost::context::jump_fcontext( cor->m_self, cor->m_saved, 0 ); //reinterpret_cast<intptr_t>( this ));
}
// go back to wherever we came from.
boost::context::jump_fcontext( cor->m_self, cor->m_saved, 0 ); //reinterpret_cast<intptr_t>( this ));
}
template <typename T> struct strip_ref
{
typedef T result;
};
template <typename T> struct strip_ref
{
typedef T result;
};
template <typename T> struct strip_ref<T&>
{
typedef T result;
};
template <typename T> struct strip_ref<T&>
{
typedef T result;
};
DELEGATE<ReturnType, ArgType> m_func;
DELEGATE<ReturnType, ArgType> m_func;
///< pointer to coroutine entry arguments. Stripped of references
///< to avoid compiler errors.
typename strip_ref<ArgType>::result* m_args;
ReturnType m_retVal;
///< pointer to coroutine entry arguments. Stripped of references
///< to avoid compiler errors.
typename strip_ref<ArgType>::result* m_args;
ReturnType m_retVal;
///< saved caller context
boost::context::fcontext_t* m_saved;
///< saved caller context
boost::context::fcontext_t* m_saved;
///< saved coroutine context
boost::context::fcontext_t* m_self;
///< saved coroutine context
boost::context::fcontext_t* m_self;
///< coroutine stack
void* m_stack;
///< coroutine stack
void* m_stack;
size_t m_stackSize;
size_t m_stackSize;
bool m_running;
bool m_running;
};
#endif

View File

@ -33,33 +33,33 @@
*/
template<class ReturnType, class Arg>
class DELEGATE {
public:
typedef ReturnType (DELEGATE<ReturnType, Arg>::*MemberPointer)( Arg );
typedef ReturnType _ReturnType;
typedef Arg _ArgType;
class DELEGATE {
public:
typedef ReturnType (DELEGATE<ReturnType, Arg>::*MemberPointer)( Arg );
typedef ReturnType _ReturnType;
typedef Arg _ArgType;
DELEGATE ()
{
}
DELEGATE ()
{
}
template<class T>
DELEGATE ( T* object, ReturnType (T::*ptr)( Arg ) )
{
m_ptr = reinterpret_cast<MemberPointer>( ptr );
m_object = reinterpret_cast<void *>( object );
};
template<class T>
DELEGATE ( T* object, ReturnType (T::*ptr)( Arg ) )
{
m_ptr = reinterpret_cast<MemberPointer>( ptr );
m_object = reinterpret_cast<void *>( object );
};
ReturnType operator()( Arg a ) const
{
DELEGATE<ReturnType, Arg> *casted = reinterpret_cast<DELEGATE<ReturnType, Arg>*>( m_object );
return (casted->*m_ptr)(a);
}
ReturnType operator()( Arg a ) const
{
DELEGATE<ReturnType, Arg> *casted = reinterpret_cast<DELEGATE<ReturnType, Arg>*>( m_object );
return (casted->*m_ptr)(a);
}
private:
MemberPointer m_ptr;
void *m_object;
MemberPointer m_ptr;
void *m_object;
};
/**
@ -67,32 +67,32 @@ private:
* Same as DELEGATE, but with no arguments.
*/
template<class ReturnType>
class DELEGATE0 {
public:
typedef ReturnType ( DELEGATE0<ReturnType>::*MemberPointer )();
typedef ReturnType _ReturnType;
class DELEGATE0 {
public:
typedef ReturnType ( DELEGATE0<ReturnType>::*MemberPointer )();
typedef ReturnType _ReturnType;
DELEGATE0 ()
{
}
DELEGATE0 ()
{
}
template<class T>
DELEGATE0 ( T* object, ReturnType (T::*ptr)( ) )
{
m_ptr = reinterpret_cast<MemberPointer>( ptr );
m_object = reinterpret_cast<void*>( object );
};
template<class T>
DELEGATE0 ( T* object, ReturnType (T::*ptr)( ) )
{
m_ptr = reinterpret_cast<MemberPointer>( ptr );
m_object = reinterpret_cast<void*>( object );
};
ReturnType operator()( ) const
{
DELEGATE0<ReturnType>* casted = reinterpret_cast<DELEGATE0<ReturnType>*>( m_object );
return ( casted->*m_ptr )();
}
ReturnType operator()( ) const
{
DELEGATE0<ReturnType>* casted = reinterpret_cast<DELEGATE0<ReturnType>*>( m_object );
return ( casted->*m_ptr )();
}
private:
MemberPointer m_ptr;
void *m_object;
MemberPointer m_ptr;
void *m_object;
};
#endif

View File

@ -9,40 +9,40 @@ typedef COROUTINE<int, int> MyCoroutine;
class MyClass {
public:
int CountTo(int n)
{
printf("%s: Coroutine says hi. I will count from 1 to %d and yield each value.\n", __FUNCTION__, n);
for(int i = 1; i <= n; i++)
{
printf("%s: Yielding %d\n", __FUNCTION__, i);
cofunc.Yield(i);
}
}
public:
int CountTo(int n)
{
printf("%s: Coroutine says hi. I will count from 1 to %d and yield each value.\n", __FUNCTION__, n);
for(int i = 1; i <= n; i++)
{
printf("%s: Yielding %d\n", __FUNCTION__, i);
cofunc.Yield(i);
}
}
void Run()
{
cofunc = MyCoroutine (this, &MyClass::CountTo);
printf("%s: Calling coroutine that will count from 1 to 5.\n", __FUNCTION__);
cofunc.Call(5);
while (cofunc.Running())
{
printf("%s: Got value: %d\n", __FUNCTION__, cofunc.ReturnValue());
cofunc.Resume();
}
void Run()
{
cofunc = MyCoroutine (this, &MyClass::CountTo);
printf("%s: Calling coroutine that will count from 1 to 5.\n", __FUNCTION__);
cofunc.Call(5);
while (cofunc.Running())
{
printf("%s: Got value: %d\n", __FUNCTION__, cofunc.ReturnValue());
cofunc.Resume();
}
printf("%s: Done!\n", __FUNCTION__);
}
printf("%s: Done!\n", __FUNCTION__);
}
MyCoroutine cofunc;
MyCoroutine cofunc;
};
main()
{
MyClass obj;
MyClass obj;
obj.Run();
obj.Run();
return 0;
return 0;
}

View File

@ -7,29 +7,29 @@ using namespace std;
class MyClass {
public:
int MyMethod(const string &arg)
{
printf("MyClass(this = %p)::MyMethod() called with string '%s', length %d\n", this, arg.c_str(), arg.length());
return arg.length();
}
public:
int MyMethod(const string &arg)
{
printf("MyClass(this = %p)::MyMethod() called with string '%s', length %d\n", this, arg.c_str(), arg.length());
return arg.length();
}
};
typedef DELEGATE<int, const string&> MyDelegate;
main()
{
MyClass t1;
MyClass t2;
MyClass t1;
MyClass t2;
MyDelegate ptr1 (&t1, &MyClass::MyMethod);
MyDelegate ptr2 (&t2, &MyClass::MyMethod);
MyDelegate ptr1 (&t1, &MyClass::MyMethod);
MyDelegate ptr2 (&t2, &MyClass::MyMethod);
int retval1, retval2;
int retval1, retval2;
retval1 = ptr1("apples");
retval2 = ptr2("cherries");
printf("Object 1 returned %d, object 2 returned %d\n", retval1, retval2);
return 0;
printf("Object 1 returned %d, object 2 returned %d\n", retval1, retval2);
return 0;
}

View File

@ -62,125 +62,125 @@ typedef DELEGATE<int, TOOL_EVENT&> TOOL_STATE_FUNC;
class TOOL_BASE
{
public:
TOOL_BASE( TOOL_Type aType, TOOL_ID aId, const std::string& aName = std::string( "" ) ) :
m_type( aType ),
m_toolId( aId ),
m_toolName( aName ),
m_toolMgr( NULL ){};
TOOL_BASE( TOOL_Type aType, TOOL_ID aId, const std::string& aName = std::string( "" ) ) :
m_type( aType ),
m_toolId( aId ),
m_toolName( aName ),
m_toolMgr( NULL ){};
virtual ~TOOL_BASE() {};
virtual ~TOOL_BASE() {};
/**
* Function GetType()
* Returns the type of the tool.
* @return The type of the tool.
*/
TOOL_Type GetType() const
{
return m_type;
}
/**
* Function GetType()
* Returns the type of the tool.
* @return The type of the tool.
*/
TOOL_Type GetType() const
{
return m_type;
}
/**
* Function GetId()
* Returns the unique identifier of the tool. The identifier is set by an instance of
* TOOL_MANAGER.
* @return Identifier of the tool.
*/
TOOL_ID GetId() const
{
return m_toolId;
}
/**
* Function GetId()
* Returns the unique identifier of the tool. The identifier is set by an instance of
* TOOL_MANAGER.
* @return Identifier of the tool.
*/
TOOL_ID GetId() const
{
return m_toolId;
}
/**
* Function GetName()
* Returns the name of the tool. Tool names are expected to obey the format:
* application.ToolName (eg. pcbnew.InteractiveSelection).
* @return The name of the tool.
*/
const std::string& GetName() const
{
return m_toolName;
}
/**
* Function GetName()
* Returns the name of the tool. Tool names are expected to obey the format:
* application.ToolName (eg. pcbnew.InteractiveSelection).
* @return The name of the tool.
*/
const std::string& GetName() const
{
return m_toolName;
}
/**
* Function GetManager()
* Returns the instance of TOOL_MANAGER that takes care of the tool.
* @return Instance of the TOOL_MANAGER. If there is no TOOL_MANAGER associated, it returns
* NULL.
*/
TOOL_MANAGER* GetManager() const
{
return m_toolMgr;
}
/**
* Function GetManager()
* Returns the instance of TOOL_MANAGER that takes care of the tool.
* @return Instance of the TOOL_MANAGER. If there is no TOOL_MANAGER associated, it returns
* NULL.
*/
TOOL_MANAGER* GetManager() const
{
return m_toolMgr;
}
protected:
friend class TOOL_MANAGER;
friend class TOOL_MANAGER;
/**
* Function attachManager()
*
* Sets the TOOL_MANAGER the tool will belong to.
* Called by TOOL_MANAGER::RegisterTool()
*/
void attachManager( TOOL_MANAGER* aManager );
/**
* Function attachManager()
*
* Sets the TOOL_MANAGER the tool will belong to.
* Called by TOOL_MANAGER::RegisterTool()
*/
void attachManager( TOOL_MANAGER* aManager );
/**
* Function getView()
*
* Returns the instance of VIEW object used in the application. It allows tools to draw.
* @return The instance of VIEW.
*/
KiGfx::VIEW* getView() const;
/**
* Function getView()
*
* Returns the instance of VIEW object used in the application. It allows tools to draw.
* @return The instance of VIEW.
*/
KiGfx::VIEW* getView() const;
/**
* Function getViewControls()
*
* Returns the instance of VIEW_CONTROLS object used in the application. It allows tools to
* read & modify user input and its settings (eg. show cursor, enable snapping to grid, etc.)
* @return The instance of VIEW_CONTROLS.
*/
KiGfx::VIEW_CONTROLS* getViewControls() const;
/**
* Function getViewControls()
*
* Returns the instance of VIEW_CONTROLS object used in the application. It allows tools to
* read & modify user input and its settings (eg. show cursor, enable snapping to grid, etc.)
* @return The instance of VIEW_CONTROLS.
*/
KiGfx::VIEW_CONTROLS* getViewControls() const;
/**
* Function getEditFrame()
*
* Returns the application window object, casted to requested user type.
*/
template<typename T>
T* getEditFrame() const
{
return static_cast<T*>( getEditFrameInt() );
}
/**
* Function getEditFrame()
*
* Returns the application window object, casted to requested user type.
*/
template<typename T>
T* getEditFrame() const
{
return static_cast<T*>( getEditFrameInt() );
}
/**
* Function getModel()
*
* Returns the model object if it matches the requested type.
*/
template<typename T>
T* getModel( KICAD_T modelType ) const
{
EDA_ITEM* m = getModelInt();
/**
* Function getModel()
*
* Returns the model object if it matches the requested type.
*/
template<typename T>
T* getModel( KICAD_T modelType ) const
{
EDA_ITEM* m = getModelInt();
return static_cast<T*>( m );
}
return static_cast<T*>( m );
}
///> Stores the type of the tool.
TOOL_Type m_type;
///> Stores the type of the tool.
TOOL_Type m_type;
///> Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
TOOL_ID m_toolId;
///> Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
TOOL_ID m_toolId;
///> Name of the tool. Names are expected to obey the format application.ToolName
///> (eg. pcbnew.InteractiveSelection).
std::string m_toolName;
TOOL_MANAGER* m_toolMgr;
///> Name of the tool. Names are expected to obey the format application.ToolName
///> (eg. pcbnew.InteractiveSelection).
std::string m_toolName;
TOOL_MANAGER* m_toolMgr;
private:
// hide the implementation to avoid spreading half of
// kicad and wxWidgets headers to the tools that may not need them at all!
EDA_ITEM* getModelInt() const;
wxWindow* getEditFrameInt() const;
// hide the implementation to avoid spreading half of
// kicad and wxWidgets headers to the tools that may not need them at all!
EDA_ITEM* getModelInt() const;
wxWindow* getEditFrameInt() const;
};
#endif

View File

@ -33,7 +33,7 @@ class TOOL_MANAGER;
class PCB_BASE_FRAME;
namespace KiGfx {
class VIEW;
class VIEW;
};
/**

View File

@ -42,63 +42,63 @@ class TOOL_MANAGER;
*/
enum TOOL_EventCategory
{
TC_None = 0x00,
TC_Mouse = 0x01,
TC_Keyboard = 0x02,
TC_Command = 0x04,
TC_Message = 0x08,
TC_View = 0x10,
TC_Any = 0xffffffff
TC_None = 0x00,
TC_Mouse = 0x01,
TC_Keyboard = 0x02,
TC_Command = 0x04,
TC_Message = 0x08,
TC_View = 0x10,
TC_Any = 0xffffffff
};
enum TOOL_Actions
{
// UI input events
TA_None = 0x0000,
TA_MouseClick = 0x0001,
TA_MouseUp = 0x0002,
TA_MouseDown = 0x0004,
TA_MouseDrag = 0x0008,
TA_MouseMotion = 0x0010,
TA_MouseWheel = 0x0020,
TA_Mouse = 0x003f,
TA_KeyUp = 0x0040,
TA_None = 0x0000,
TA_MouseClick = 0x0001,
TA_MouseUp = 0x0002,
TA_MouseDown = 0x0004,
TA_MouseDrag = 0x0008,
TA_MouseMotion = 0x0010,
TA_MouseWheel = 0x0020,
TA_Mouse = 0x003f,
TA_KeyUp = 0x0040,
TA_KeyDown = 0x0080,
TA_Keyboard = TA_KeyUp | TA_KeyDown,
// View related events
TA_ViewRefresh = 0x0100,
TA_ViewZoom = 0x0200,
TA_ViewPan = 0x0400,
TA_ViewDirty = 0x0800,
TA_ChangeLayer = 0x1000,
TA_ViewRefresh = 0x0100,
TA_ViewZoom = 0x0200,
TA_ViewPan = 0x0400,
TA_ViewDirty = 0x0800,
TA_ChangeLayer = 0x1000,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu.
TA_CancelTool = 0x2000,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu.
TA_CancelTool = 0x2000,
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
// over one of choices. Used in dynamic highligting in disambiguation menu
TA_ContextMenuUpdate = 0x4000,
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
// over one of choices. Used in dynamic highligting in disambiguation menu
TA_ContextMenuUpdate = 0x4000,
// Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything.
TA_ContextMenuChoice = 0x8000,
// Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything.
TA_ContextMenuChoice = 0x8000,
// Tool action (allows to control tools)
TA_Action = 0x10000,
// Tool action (allows to control tools)
TA_Action = 0x10000,
TA_Any = 0xffffffff
TA_Any = 0xffffffff
};
enum TOOL_MouseButtons
{
MB_None = 0x0,
MB_Left = 0x1,
MB_Right = 0x2,
MB_Middle = 0x4,
MB_ButtonMask = MB_Left | MB_Right | MB_Middle,
MB_Any = 0xffffffff
MB_None = 0x0,
MB_Left = 0x1,
MB_Right = 0x2,
MB_Middle = 0x4,
MB_ButtonMask = MB_Left | MB_Right | MB_Middle,
MB_Any = 0xffffffff
};
enum TOOL_Modifiers
@ -120,9 +120,9 @@ enum TOOL_ActionScope
/// Defines when a context menu is opened.
enum CONTEXT_MENU_TRIGGER
{
CMENU_BUTTON = 0, // On the right button
CMENU_NOW, // Right now (after TOOL_INTERACTIVE::SetContextMenu)
CMENU_OFF // Never
CMENU_BUTTON = 0, // On the right button
CMENU_NOW, // Right now (after TOOL_INTERACTIVE::SetContextMenu)
CMENU_OFF // Never
};
/**
@ -473,20 +473,20 @@ private:
inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& a, const TOOL_EVENT& b )
{
TOOL_EVENT_LIST l;
TOOL_EVENT_LIST l;
l.Add( a );
l.Add( b );
l.Add( a );
l.Add( b );
return l;
return l;
}
inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& a, const TOOL_EVENT_LIST& b )
{
TOOL_EVENT_LIST l( b );
TOOL_EVENT_LIST l( b );
l.Add( a );
return l;
l.Add( a );
return l;
}
#endif

View File

@ -39,23 +39,23 @@ public:
* Constructor
*
* Creates a tool with given id & name. The name must be unique. */
TOOL_INTERACTIVE( TOOL_ID aId, const std::string& aName );
TOOL_INTERACTIVE( TOOL_ID aId, const std::string& aName );
/**
* Constructor
*
* Creates a tool with given name. The name must be unique. */
TOOL_INTERACTIVE( const std::string& aName );
virtual ~TOOL_INTERACTIVE();
/**
* Constructor
*
* Creates a tool with given name. The name must be unique. */
TOOL_INTERACTIVE( const std::string& aName );
virtual ~TOOL_INTERACTIVE();
/**
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
* the model or the view, it must release it when its reset.
*/
virtual void Reset() = 0;
/**
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
* the model or the view, it must release it when its reset.
*/
virtual void Reset() = 0;
/**
/**
* Function Init()
* Init() is called once upon a registration of the tool.
*
@ -66,58 +66,58 @@ public:
return true;
}
/**
* Function SetContextMenu()
*
* Assigns a context menu and tells when it should be activated.
* @param aMenu is the menu to be assigned.
* @param aTrigger determines conditions upon which the context menu is activated.
*/
void SetContextMenu( CONTEXT_MENU* aMenu, CONTEXT_MENU_TRIGGER aTrigger = CMENU_BUTTON );
/**
* Function SetContextMenu()
*
* Assigns a context menu and tells when it should be activated.
* @param aMenu is the menu to be assigned.
* @param aTrigger determines conditions upon which the context menu is activated.
*/
void SetContextMenu( CONTEXT_MENU* aMenu, CONTEXT_MENU_TRIGGER aTrigger = CMENU_BUTTON );
/**
* Function Go()
*
* Defines which state (aStateFunc) to go when a certain event arrives (aConditions).
* No conditions means any event.
*/
template<class T>
void Go( int (T::*aStateFunc)( TOOL_EVENT& ),
const TOOL_EVENT_LIST& aConditions = TOOL_EVENT( TC_Any, TA_Any ) );
/**
* Function Go()
*
* Defines which state (aStateFunc) to go when a certain event arrives (aConditions).
* No conditions means any event.
*/
template<class T>
void Go( int (T::*aStateFunc)( TOOL_EVENT& ),
const TOOL_EVENT_LIST& aConditions = TOOL_EVENT( TC_Any, TA_Any ) );
/**
* Function Wait()
*
* Suspends execution of the tool until an event specified in aEventList arrives.
* No parameters means waiting for any event.
*/
OPT_TOOL_EVENT Wait( const TOOL_EVENT_LIST& aEventList = TOOL_EVENT ( TC_Any, TA_Any ) );
/**
* Function Wait()
*
* Suspends execution of the tool until an event specified in aEventList arrives.
* No parameters means waiting for any event.
*/
OPT_TOOL_EVENT Wait( const TOOL_EVENT_LIST& aEventList = TOOL_EVENT ( TC_Any, TA_Any ) );
/** functions below are not yet implemented - their interface may change */
/*template<class Parameters, class ReturnValue>
bool InvokeTool( const std::string& aToolName, const Parameters& parameters,
ReturnValue& returnValue );
/** functions below are not yet implemented - their interface may change */
/*template<class Parameters, class ReturnValue>
bool InvokeTool( const std::string& aToolName, const Parameters& parameters,
ReturnValue& returnValue );
template<class Parameters, class ReturnValue>
bool InvokeWindow( const std::string& aWindowName, const Parameters& parameters,
ReturnValue& returnValue );
template<class Parameters, class ReturnValue>
bool InvokeWindow( const std::string& aWindowName, const Parameters& parameters,
ReturnValue& returnValue );
template<class T>
void Yield( const T& returnValue );*/
template<class T>
void Yield( const T& returnValue );*/
protected:
/* helper functions for constructing events for Wait() and Go() with less typing */
const TOOL_EVENT evActivate( std::string aToolName = "" );
const TOOL_EVENT evCommand( int aCommandId = -1 );
const TOOL_EVENT evCommand( std::string aCommandStr = "" );
const TOOL_EVENT evMotion();
const TOOL_EVENT evClick( int aButton = MB_Any );
const TOOL_EVENT evDrag( int aButton = MB_Any );
const TOOL_EVENT evButtonUp( int aButton = MB_Any );
const TOOL_EVENT evButtonDown(int aButton = MB_Any );
/* helper functions for constructing events for Wait() and Go() with less typing */
const TOOL_EVENT evActivate( std::string aToolName = "" );
const TOOL_EVENT evCommand( int aCommandId = -1 );
const TOOL_EVENT evCommand( std::string aCommandStr = "" );
const TOOL_EVENT evMotion();
const TOOL_EVENT evClick( int aButton = MB_Any );
const TOOL_EVENT evDrag( int aButton = MB_Any );
const TOOL_EVENT evButtonUp( int aButton = MB_Any );
const TOOL_EVENT evButtonDown(int aButton = MB_Any );
private:
void goInternal( TOOL_STATE_FUNC& aState, const TOOL_EVENT_LIST& aConditions );
void goInternal( TOOL_STATE_FUNC& aState, const TOOL_EVENT_LIST& aConditions );
};
// hide TOOL_MANAGER implementation
@ -125,8 +125,8 @@ template<class T>
void TOOL_INTERACTIVE::Go( int (T::*aStateFunc)( TOOL_EVENT& ),
const TOOL_EVENT_LIST& aConditions )
{
TOOL_STATE_FUNC sptr( static_cast<T*>( this ), aStateFunc );
goInternal( sptr, aConditions );
TOOL_STATE_FUNC sptr( static_cast<T*>( this ), aStateFunc );
goInternal( sptr, aConditions );
}
#endif

0
pcbnew/edit.cpp Executable file → Normal file
View File

View File

@ -691,7 +691,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
if( !checkColliding( &tmp ) )
{
/* if(aEnd)
/* if(aEnd)
* PNSDisplayDebugLine (l_best, 6);
* else
* PNSDisplayDebugLine (l_best, 5);*/

View File

@ -429,7 +429,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( PNS_LINE* aCurrentHead )
break;
}
/* if(lastWalkSolid == nearest->item)
/* if(lastWalkSolid == nearest->item)
* {
* fail = true;
* break;