Homogenize hit testing and selection return types.

Prep work for sharing SCH_SELECTION_TOOL with LibEdit.
This commit is contained in:
Jeff Young 2019-05-05 11:33:34 +01:00
parent 9adf012c20
commit fd546da640
76 changed files with 380 additions and 549 deletions

View File

@ -26,6 +26,7 @@
#include <geometry/shape_line_chain.h>
#include <geometry/shape_circle.h>
#include <trigo.h>
#include "clipper.hpp"
@ -348,9 +349,12 @@ int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const
}
bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const
bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy ) const
{
if( !m_closed || PointCount() < 3 || !BBox().Contains( aP ) )
BOX2I bbox = BBox();
bbox.Inflate( aAccuracy );
if( !m_closed || PointCount() < 3 || !BBox().Contains( aPt ) )
return false;
bool inside = false;
@ -371,37 +375,40 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const
if( diff.y != 0 )
{
const int d = rescale( diff.x, ( aP.y - p1.y ), diff.y );
const int d = rescale( diff.x, ( aPt.y - p1.y ), diff.y );
if( ( ( p1.y > aP.y ) != ( p2.y > aP.y ) ) && ( aP.x - p1.x < d ) )
if( ( ( p1.y > aPt.y ) != ( p2.y > aPt.y ) ) && ( aPt.x - p1.x < d ) )
inside = !inside;
}
}
return inside && !PointOnEdge( aP );
return inside && !PointOnEdge( aPt, aAccuracy );
}
bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const
bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aPt, int aAccuracy ) const
{
return EdgeContainingPoint( aP ) >= 0;
return EdgeContainingPoint( aPt, aAccuracy ) >= 0;
}
int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aP ) const
int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aPt, int aAccuracy ) const
{
if( !PointCount() )
return -1;
else if( PointCount() == 1 )
return m_points[0] == aP ? 0 : -1;
{
VECTOR2I dist = m_points[0] - aPt;
return ( hypot( dist.x, dist.y ) <= aAccuracy + 1 ) ? 0 : -1;
}
for( int i = 0; i < SegmentCount(); i++ )
{
const SEG s = CSegment( i );
if( s.A == aP || s.B == aP )
if( s.A == aPt || s.B == aPt )
return i;
if( s.Distance( aP ) <= 1 )
if( s.Distance( aPt ) <= aAccuracy + 1 )
return i;
}

View File

@ -160,9 +160,10 @@ void MARKER_BASE::SetData( int aErrorCode, const wxPoint& aMarkerPos,
}
bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition ) const
bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition, int aAccuracy ) const
{
EDA_RECT bbox = GetBoundingBoxMarker();
bbox.Inflate( aAccuracy );
// Fast hit test using boundary box. A finer test will be made if requested
bool hit = bbox.Contains( aHitPosition );
@ -172,7 +173,7 @@ bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition ) const
SHAPE_LINE_CHAIN polygon;
ShapeToPolygon( polygon );
VECTOR2I rel_pos( aHitPosition - m_Pos );
hit = polygon.PointInside( rel_pos );
hit = polygon.PointInside( rel_pos, aAccuracy );
}
return hit;

View File

@ -99,32 +99,16 @@ LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent )
}
bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) const
bool LIB_ARC::HitTest( const wxPoint& aRefPoint, int aAccuracy ) const
{
int mindist = GetPenSize() / 2;
// Have a minimal tolerance for hit test
if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPoint, mindist, DefaultTransform );
}
bool LIB_ARC::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
{
if( aThreshold < 0 )
aThreshold = GetPenSize() / 2;
// TODO: use aTransMat to calculates parameters
wxPoint relativePosition = aPosition;
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint relativePosition = aRefPoint;
relativePosition.y = -relativePosition.y; // reverse Y axis
int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) );
if( abs( distance - m_Radius ) > aThreshold )
if( abs( distance - m_Radius ) > mindist )
return false;
// We are on the circle, ensure we are only on the arc, i.e. between
@ -151,8 +135,26 @@ bool LIB_ARC::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM
// When the cross products have a different sign, the point lies in sector
// also check, if the reference is near start or end point
return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
( crossProductStart <= 0 && crossProductEnd >= 0 );
HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
( crossProductStart <= 0 && crossProductEnd >= 0 );
}
bool LIB_ARC::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
return false;
EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect );
if ( aAccuracy )
rect.Inflate( aAccuracy );
if( aContained )
return rect.Contains( GetBoundingBox() );
return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse for filled arcs,
// egregiously coarse for unfilled...
}

View File

@ -90,9 +90,8 @@ public:
return _( "Arc" );
}
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
const EDA_RECT GetBoundingBox() const override;
@ -101,9 +100,7 @@ public:
int GetPenSize() const override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) override;
@ -115,7 +112,6 @@ public:
wxPoint GetPosition() const override { return m_Pos; }
void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -124,27 +120,21 @@ public:
const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; }
void SetRadius( int aRadius ) { m_Radius = aRadius; }
int GetRadius() const { return m_Radius; }
void SetFirstRadiusAngle( int aAngle ) { m_t1 = aAngle; }
int GetFirstRadiusAngle() const { return m_t1; }
void SetSecondRadiusAngle( int aAngle ) { m_t2 = aAngle; }
int GetSecondRadiusAngle() const { return m_t2; }
wxPoint GetStart() const { return m_ArcStart; }
void SetStart( const wxPoint& aPoint ) { m_ArcStart = aPoint; }
wxPoint GetEnd() const { return m_ArcEnd; }
void SetEnd( const wxPoint& aPoint ) { m_ArcEnd = aPoint; }
/**

View File

@ -266,31 +266,17 @@ void LIB_BEZIER::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint&
}
bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) const
{
int mindist = GetPenSize() / 2;
// Have a minimal tolerance for hit test
if ( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPos, mindist, DefaultTransform );
}
bool LIB_BEZIER::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const
bool LIB_BEZIER::HitTest( const wxPoint& aRefPos, int aAccuracy ) const
{
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint start, end;
if( aThreshold < 0 )
aThreshold = GetPenSize() / 2;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{
start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
start = DefaultTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = DefaultTransform.TransformCoordinate( m_PolyPoints[ii] );
if ( TestSegmentHit( aPosRef, start, end, aThreshold ) )
if ( TestSegmentHit( aRefPos, start, end, mindist ) )
return true;
}
@ -298,6 +284,24 @@ bool LIB_BEZIER::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFOR
}
bool LIB_BEZIER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
return false;
EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect );
if ( aAccuracy )
rect.Inflate( aAccuracy );
if( aContained )
return rect.Contains( GetBoundingBox() );
return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse for filled beziers,
// egregiously coarse for unfilled...
}
const EDA_RECT LIB_BEZIER::GetBoundingBox() const
{
EDA_RECT rect;

View File

@ -78,9 +78,8 @@ public:
return m_BezierPoints;
}
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
const EDA_RECT GetBoundingBox() const override;
@ -91,7 +90,6 @@ public:
wxPoint GetPosition() const override;
void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -100,7 +98,6 @@ public:
const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; }
int GetPenSize( ) const override;

View File

@ -52,28 +52,32 @@ LIB_CIRCLE::LIB_CIRCLE( LIB_PART* aParent ) :
}
bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) const
bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef, int aAccuracy ) const
{
int mindist = GetPenSize() / 2;
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
int dist = KiROUND( GetLineLength( aPosRef, DefaultTransform.TransformCoordinate( m_Pos ) ) );
// Have a minimal tolerance for hit test
if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE;
if( abs( dist - m_Radius ) <= mindist )
return true;
return HitTest( aPosRef, mindist, DefaultTransform );
return false;
}
bool LIB_CIRCLE::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const
bool LIB_CIRCLE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
if( aThreshold < 0 )
aThreshold = GetPenSize() / 2;
if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
return false;
int dist = KiROUND( GetLineLength( aPosRef, aTransform.TransformCoordinate( m_Pos ) ) );
EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect );
if( abs( dist - m_Radius ) <= aThreshold )
return true;
return false;
if ( aAccuracy )
rect.Inflate( aAccuracy );
if( aContained )
return rect.Contains( GetBoundingBox() );
return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse...
}

View File

@ -60,9 +60,8 @@ public:
return _( "Circle" );
}
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
int GetPenSize( ) const override;
@ -71,9 +70,7 @@ public:
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) override;
@ -85,7 +82,6 @@ public:
wxPoint GetPosition() const override { return m_Pos; }
void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -94,11 +90,9 @@ public:
const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; }
void SetRadius( int aRadius ) { m_Radius = aRadius; }
int GetRadius() const { return m_Radius; }
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;

View File

@ -114,7 +114,7 @@ SEARCH_RESULT LIB_COLLECTOR::Inspect( EDA_ITEM* aItem, void* testData )
if( ( m_data.m_unit && item->GetUnit() && ( m_data.m_unit != item->GetUnit() ) )
|| ( m_data.m_convert && item->GetConvert() && ( m_data.m_convert != item->GetConvert() ) )
|| !item->HitTest( m_RefPos, -1, DefaultTransform ) )
|| !item->HitTest( m_RefPos ) )
return SEARCH_CONTINUE;
Append( aItem );

View File

@ -107,6 +107,23 @@ bool LIB_ITEM::operator<( const LIB_ITEM& aOther ) const
}
bool LIB_ITEM::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
return false;
EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect );
if ( aAccuracy )
rect.Inflate( aAccuracy );
if( aContained )
return rect.Contains( GetBoundingBox() );
return rect.Intersects( GetBoundingBox() );
}
void LIB_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, void* aData,
const TRANSFORM& aTransform )
{

View File

@ -201,27 +201,21 @@ public:
*/
virtual int GetPenSize() const = 0;
LIB_PART* GetParent() const
LIB_PART* GetParent() const
{
return (LIB_PART *)m_Parent;
return (LIB_PART*) m_Parent;
}
void ViewGetLayers( int aLayers[], int& aCount ) const override;
virtual bool HitTest( const wxPoint& aPosition ) const override
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override
{
return EDA_ITEM::HitTest( aPosition );
// This is just here to prevent annoying compiler warnings about hidden overloaded
// virtual functions
return EDA_ITEM::HitTest( aPosition, aAccuracy );
}
/**
* @param aPosition A wxPoint to test.
* @param aThreshold Maximum distance to this object (usually the half thickness of a line)
* if < 0, it will be automatically set to half pen size when locating
* lines or arcs and set to 0 for other items.
* @param aTransform The transform matrix.
* @return True if the point \a aPosition is near this object
*/
virtual bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const = 0;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
/**
* @return the boundary box for this, in library coordinates

View File

@ -156,22 +156,12 @@ void LIB_FIELD::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& a
}
bool LIB_FIELD::HitTest( const wxPoint& aPosition ) const
bool LIB_FIELD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
// Because HitTest is mainly used to select the field
// return always false if this field is void
// Because HitTest is mainly used to select the field return false if it is void
if( IsVoid() )
return false;
return HitTest( aPosition, 0, DefaultTransform );
}
bool LIB_FIELD::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
{
if( aThreshold < 0 )
aThreshold = 0;
// Build a temporary copy of the text for hit testing
EDA_TEXT tmp_text( *this );
@ -188,16 +178,16 @@ bool LIB_FIELD::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFO
tmp_text.SetText( extended_text );
}
tmp_text.SetTextPos( aTransform.TransformCoordinate( GetTextPos() ) );
tmp_text.SetTextPos( DefaultTransform.TransformCoordinate( GetTextPos() ) );
/* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped.
* this simple algo works only for schematic matrix (rot 90 or/and mirror)
*/
bool t1 = ( aTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 );
bool t1 = ( DefaultTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 );
tmp_text.SetTextAngle( t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT );
return tmp_text.TextHitTest( aPosition );
return tmp_text.TextHitTest( aPosition, aAccuracy );
}

View File

@ -168,9 +168,7 @@ public:
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
void operator=( const LIB_FIELD& field );
@ -191,9 +189,7 @@ public:
COLOR4D GetDefaultColor() override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void Rotate() override;
@ -220,7 +216,6 @@ public:
wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); }
void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -229,7 +224,6 @@ public:
const TRANSFORM& aTransform ) override;
int GetWidth() const override { return GetThickness(); }
void SetWidth( int aWidth ) override { SetThickness( aWidth ); }
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;

View File

@ -538,27 +538,11 @@ void LIB_PIN::EnableEditMode( bool aEnable, bool aEditPinByPin )
}
bool LIB_PIN::HitTest( const wxPoint& aPosition ) const
bool LIB_PIN::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
return HitTest( aPosition, 0, DefaultTransform );
}
bool LIB_PIN::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
{
if( aThreshold < 0 )
aThreshold = 0;
TRANSFORM transform = DefaultTransform;
DefaultTransform = aTransform;
EDA_RECT rect = GetBoundingBox();
rect.Inflate( aThreshold );
//Restore matrix
DefaultTransform = transform;
return rect.Contains( aPosition );
return rect.Inflate( aAccuracy ).Contains( aPosition );
}

View File

@ -110,9 +110,7 @@ public:
void Show( int nestLevel, std::ostream& os ) const override;
#endif
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;

View File

@ -214,31 +214,17 @@ void LIB_POLYLINE::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint
}
bool LIB_POLYLINE::HitTest( const wxPoint& aPosition ) const
{
int mindist = GetPenSize() / 2;
// Have a minimal tolerance for hit test
if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aPosition, mindist, DefaultTransform );
}
bool LIB_POLYLINE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
bool LIB_POLYLINE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint start, end;
if( aThreshold < 0 )
aThreshold = GetPenSize() / 2;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{
start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
start = DefaultTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = DefaultTransform.TransformCoordinate( m_PolyPoints[ii] );
if( TestSegmentHit( aPosition, start, end, aThreshold ) )
if( TestSegmentHit( aPosition, start, end, mindist ) )
return true;
}
@ -246,6 +232,24 @@ bool LIB_POLYLINE::HitTest( const wxPoint &aPosition, int aThreshold, const TRAN
}
bool LIB_POLYLINE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
return false;
EDA_RECT rect = aRect;
if ( aAccuracy )
rect.Inflate( aAccuracy );
if( aContained )
return rect.Contains( GetBoundingBox() );
return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse for filled polylines,
// egregiously coarse for unfilled...
}
const EDA_RECT LIB_POLYLINE::GetBoundingBox() const
{
EDA_RECT rect;

View File

@ -76,9 +76,8 @@ public:
*/
unsigned GetCornerCount() const { return m_PolyPoints.size(); }
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
const EDA_RECT GetBoundingBox() const override;
@ -87,9 +86,7 @@ public:
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) override;
@ -101,7 +98,6 @@ public:
wxPoint GetPosition() const override { return m_PolyPoints[0]; }
void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -110,7 +106,6 @@ public:
const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; }
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;

View File

@ -219,25 +219,11 @@ const EDA_RECT LIB_RECTANGLE::GetBoundingBox() const
}
bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition ) const
bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
int mindist = ( GetPenSize() / 2 ) + 1;
// Have a minimal tolerance for hit test
if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aPosition, mindist, DefaultTransform );
}
bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
{
if( aThreshold < 0 )
aThreshold = GetPenSize() / 2;
wxPoint actualStart = aTransform.TransformCoordinate( m_Pos );
wxPoint actualEnd = aTransform.TransformCoordinate( m_End );
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint actualStart = DefaultTransform.TransformCoordinate( m_Pos );
wxPoint actualEnd = DefaultTransform.TransformCoordinate( m_End );
// locate lower segment
wxPoint start, end;
@ -246,21 +232,21 @@ bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRA
end.x = actualEnd.x;
end.y = actualStart.y;
if( TestSegmentHit( aPosition, start, end, aThreshold ) )
if( TestSegmentHit( aPosition, start, end, mindist ) )
return true;
// locate right segment
start.x = actualEnd.x;
end.y = actualEnd.y;
if( TestSegmentHit( aPosition, start, end, aThreshold ) )
if( TestSegmentHit( aPosition, start, end, mindist ) )
return true;
// locate upper segment
start.y = actualEnd.y;
end.x = actualStart.x;
if( TestSegmentHit( aPosition, start, end, aThreshold ) )
if( TestSegmentHit( aPosition, start, end, mindist ) )
return true;
// locate left segment
@ -268,7 +254,7 @@ bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRA
end.x = actualStart.x;
end.y = actualEnd.y;
if( TestSegmentHit( aPosition, start, end, aThreshold ) )
if( TestSegmentHit( aPosition, start, end, mindist ) )
return true;
return false;

View File

@ -65,9 +65,7 @@ public:
void SetEndPosition( const wxPoint& aPosition ) { m_End = aPosition; }
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
int GetPenSize( ) const override;
@ -76,9 +74,7 @@ public:
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) override;

View File

@ -59,25 +59,19 @@ void LIB_TEXT::ViewGetLayers( int aLayers[], int& aCount ) const
}
bool LIB_TEXT::HitTest( const wxPoint& aPosition ) const
{
return HitTest( aPosition, 0, DefaultTransform );
}
bool LIB_TEXT::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
bool LIB_TEXT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
EDA_TEXT tmp_text( *this );
tmp_text.SetTextPos( aTransform.TransformCoordinate( GetTextPos() ) );
tmp_text.SetTextPos( DefaultTransform.TransformCoordinate( GetTextPos() ) );
/* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped.
* this simple algo works only for schematic matrix (rot 90 or/and mirror)
*/
bool t1 = ( aTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 );
bool t1 = ( DefaultTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 );
tmp_text.SetTextAngle( t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT );
return tmp_text.TextHitTest( aPosition );
return tmp_text.TextHitTest( aPosition, aAccuracy );
}

View File

@ -83,13 +83,11 @@ public:
*/
void SetText( const wxString& aText ) override;
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
bool HitTest( const EDA_RECT& aRect ) const
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override
{
return TextHitTest( aRect );
return TextHitTest( aRect, aContained, aAccuracy );
}

View File

@ -152,8 +152,8 @@ public:
wxPoint GetPosition() const override { return m_pos; }
void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -105,12 +105,10 @@ public:
void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const override;
wxPoint GetPosition() const override { return m_pos; }
void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -611,8 +611,8 @@ public:
wxPoint GetPosition() const override { return m_Pos; }
void SetPosition( const wxPoint& aPosition ) override { Move( aPosition - m_Pos ); }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -195,12 +195,10 @@ public:
wxPoint GetLibPosition() const { return EDA_TEXT::GetTextPos(); }
wxPoint GetPosition() const override;
void SetPosition( const wxPoint& aPosition ) override;
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -363,35 +363,6 @@ public:
void SetConnectivityDirty( bool aDirty = true ) { m_connectivity_dirty = aDirty; }
virtual bool HitTest( const wxPoint& aPosition ) const override
{
return HitTest( aPosition, 0 );
}
/**
* Function HitTest
* tests if \a aPosition is contained within or on the bounding box of an item.
*
* @param aPosition A reference to a wxPoint object containing the coordinates to test.
* @param aAccuracy Increase the item bounding box by this amount.
* @return True if \a aPosition is within the item bounding box.
*/
virtual bool HitTest( const wxPoint& aPosition, int aAccuracy ) const { return false; }
/**
* Function HitTest
* tests if \a aRect intersects or is contained within the bounding box of an item.
*
* @param aRect A reference to a EDA_RECT object containing the rectangle to test.
* @param aContained Set to true to test for containment instead of an intersection.
* @param aAccuracy Increase \a aRect by this amount.
* @return True if \a aRect contains or intersects the item bounding box.
*/
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const
{
return false;
}
virtual bool CanIncrementLabel() const { return false; }
/**

View File

@ -95,8 +95,8 @@ public:
wxPoint GetPosition() const override { return m_pos; }
void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -189,8 +189,8 @@ public:
wxPoint GetPosition() const override { return m_start; }
void SetPosition( const wxPoint& aPosition ) override;
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -154,5 +154,5 @@ void SCH_MARKER::MirrorY( int aYaxis_position )
bool SCH_MARKER::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
return HitTestMarker( aPosition );
return HitTestMarker( aPosition, aAccuracy );
}

View File

@ -93,7 +93,7 @@ public:
wxPoint GetPosition() const override { return m_Pos; }
void SetPosition( const wxPoint& aPosition ) override { m_Pos = aPosition; }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
EDA_ITEM* Clone() const override;

View File

@ -101,8 +101,8 @@ public:
wxPoint GetPosition() const override { return m_pos; }
void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -120,9 +120,10 @@ const EDA_RECT SCH_PIN::GetBoundingBox() const
}
bool SCH_PIN::HitTest( const wxPoint& aPosition ) const
bool SCH_PIN::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
return GetBoundingBox().Contains( aPosition );
EDA_RECT rect = GetBoundingBox();
return rect.Inflate( aAccuracy ).Contains( aPosition );
}

View File

@ -77,7 +77,7 @@ public:
void SetPosition( const wxPoint& aPosition ) override { m_position = aPosition; }
const EDA_RECT GetBoundingBox() const override;
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool IsDangling() const override { return m_isDangling; }
void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; }

View File

@ -372,7 +372,7 @@ SCH_SHEET_PIN* SCH_SHEET::GetPin( const wxPoint& aPosition )
{
for( SCH_SHEET_PIN& pin : m_pins )
{
if( pin.HitTest( aPosition, 0 ) )
if( pin.HitTest( aPosition ) )
return &pin;
}

View File

@ -186,7 +186,7 @@ public:
void SetPosition( const wxPoint& aPosition ) override { ConstrainOnEdge( aPosition ); }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
EDA_ITEM* Clone() const override;
};
@ -531,7 +531,7 @@ public:
void SetPosition( const wxPoint& aPosition ) override;
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -190,8 +190,8 @@ public:
wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); }
void SetPosition( const wxPoint& aPosition ) override { EDA_TEXT::SetTextPos( aPosition ); }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) override;

View File

@ -636,7 +636,7 @@ int SCH_DRAWING_TOOL::PlaceSchematicText( const TOOL_EVENT& aEvent )
int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
{
VECTOR2I cursorPos = m_controls->GetCursorPosition();
SCH_ITEM* item = nullptr;
EDA_ITEM* item = nullptr;
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_controls->ShowCursor( true );
@ -719,7 +719,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
// ... and second click places:
else
{
m_frame->AddItemToScreenAndUndoList( item );
m_frame->AddItemToScreenAndUndoList( (SCH_ITEM*) item );
item = nullptr;
m_view->ClearPreview();
@ -749,7 +749,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
}
else if( item && ( evt->IsAction( &SCH_ACTIONS::refreshPreview ) || evt->IsMotion() ) )
{
item->SetPosition( (wxPoint)cursorPos );
static_cast<SCH_ITEM*>( item )->SetPosition( (wxPoint)cursorPos );
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
}

View File

@ -960,30 +960,28 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
}
static bool deleteItem( SCH_EDIT_FRAME* aFrame, const VECTOR2D& aPosition )
static bool deleteItem( SCH_BASE_FRAME* aFrame, const VECTOR2D& aPosition )
{
SCH_SELECTION_TOOL* selectionTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
wxCHECK( selectionTool, false );
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::clearSelection, true );
SCH_ITEM* item = selectionTool->SelectPoint( aPosition );
EDA_ITEM* item = selectionTool->SelectPoint( aPosition );
SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
if( sch_item && sch_item->IsLocked() )
{
STATUS_TEXT_POPUP statusPopup( aFrame );
statusPopup.SetText( _( "Item locked." ) );
statusPopup.Expire( 2000 );
statusPopup.Popup();
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
return true;
}
if( item )
{
if( item->IsLocked() )
{
STATUS_TEXT_POPUP statusPopup( aFrame );
statusPopup.SetText( _( "Item locked." ) );
statusPopup.Expire( 2000 );
statusPopup.Popup();
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
}
else
{
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::doDelete, true );
}
}
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::doDelete, true );
return true;
}

View File

@ -89,7 +89,6 @@ private:
private:
SCH_SELECTION_TOOL* m_selectionTool;
KIGFX::VIEW_CONTROLS* m_controls;
SCH_EDIT_FRAME* m_frame;
/// Menu model displayed by the tool.

View File

@ -233,7 +233,7 @@ static bool probeSimulation( SCH_EDIT_FRAME* aFrame, const VECTOR2D& aPosition )
constexpr KICAD_T wiresAndComponents[] = { SCH_LINE_T, SCH_COMPONENT_T, SCH_SHEET_PIN_T, EOT };
SCH_SELECTION_TOOL* selTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
SCH_ITEM* item = selTool->SelectPoint( aPosition, wiresAndComponents );
EDA_ITEM* item = selTool->SelectPoint( aPosition, wiresAndComponents );
if( !item )
return false;
@ -279,14 +279,14 @@ static bool tuneSimulation( SCH_EDIT_FRAME* aFrame, const VECTOR2D& aPosition )
{
constexpr KICAD_T fieldsAndComponents[] = { SCH_COMPONENT_T, SCH_FIELD_T, EOT };
SCH_SELECTION_TOOL* selTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
SCH_ITEM* item = selTool->SelectPoint( aPosition, fieldsAndComponents );
EDA_ITEM* item = selTool->SelectPoint( aPosition, fieldsAndComponents );
if( !item )
return false;
if( item->Type() != SCH_COMPONENT_T )
{
item = static_cast<SCH_ITEM*>( item->GetParent() );
item = item->GetParent();
if( item->Type() != SCH_COMPONENT_T )
return false;
@ -341,7 +341,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
}
else
{
SCH_ITEM* item = selTool->GetNode( aPosition );
SCH_ITEM* item = (SCH_ITEM*) selTool->GetNode( aPosition );
if( item && item->Connection( *g_CurrentSheet ) )
netName = item->Connection( *g_CurrentSheet )->Name();

View File

@ -343,7 +343,7 @@ int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP;
if( component )
m_frame->SelectUnit( component, unit );
static_cast<SCH_EDIT_FRAME*>( m_frame )->SelectUnit( component, unit );
}
}
@ -374,7 +374,7 @@ SELECTION& SCH_SELECTION_TOOL::GetSelection()
}
SCH_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList,
EDA_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList,
bool* aSelectionCancelledFlag, bool aCheckLocked )
{
SCH_COLLECTOR collector;
@ -419,7 +419,7 @@ SCH_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T
if( collector.GetCount() == 1 )
{
SCH_ITEM* item = collector[ 0 ];
EDA_ITEM* item = collector[ 0 ];
toggleSelection( item );
return item;
@ -442,8 +442,8 @@ void SCH_SELECTION_TOOL::guessSelectionCandidates( SCH_COLLECTOR& collector,
// all the various overlap and coverage issues that we do in Pcbnew.
if( collector.GetCount() == 2 )
{
SCH_ITEM* a = collector[ 0 ];
SCH_ITEM* b = collector[ 1 ];
EDA_ITEM* a = collector[ 0 ];
EDA_ITEM* b = collector[ 1 ];
if( a->GetParent() == b )
collector.Remove( b );
@ -457,15 +457,6 @@ void SCH_SELECTION_TOOL::guessSelectionCandidates( SCH_COLLECTOR& collector,
}
static EDA_RECT getRect( const SCH_ITEM* aItem )
{
if( aItem->Type() == SCH_COMPONENT_T )
return static_cast<const SCH_COMPONENT*>( aItem )->GetBodyBoundingBox();
return aItem->GetBoundingBox();
}
SELECTION& SCH_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] )
{
if( m_selection.Empty() )
@ -482,7 +473,7 @@ SELECTION& SCH_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] )
{
for( int i = m_selection.GetSize() - 1; i >= 0; --i )
{
SCH_ITEM* item = (SCH_ITEM*) m_selection.GetItem( i );
EDA_ITEM* item = (EDA_ITEM*) m_selection.GetItem( i );
if( !item->IsType( aFilterList ) )
toggleSelection( item );
@ -551,39 +542,24 @@ bool SCH_SELECTION_TOOL::selectMultiple()
if( view->IsMirroredX() )
windowSelection = !windowSelection;
// Construct an EDA_RECT to determine SCH_ITEM selection
// Construct an EDA_RECT to determine EDA_ITEM selection
EDA_RECT selectionRect( (wxPoint)area.GetOrigin(), wxSize( width, height ) );
selectionRect.Normalize();
for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
{
SCH_ITEM* item = static_cast<SCH_ITEM*>( it->first );
EDA_ITEM* item = static_cast<EDA_ITEM*>( it->first );
if( !item || !selectable( item ) )
continue;
if( windowSelection )
if( item->HitTest( selectionRect, windowSelection ) )
{
BOX2I bbox = getRect( item );
if( selectionBox.Contains( bbox ) )
{
if( m_subtractive )
unselect( item );
else
select( item );
}
}
else
{
if( item->HitTest( selectionRect, false ) )
{
if( m_subtractive )
unselect( item );
else
select( item );
}
if( m_subtractive )
unselect( item );
else
select( item );
}
}
@ -623,7 +599,7 @@ static KICAD_T nodeTypes[] =
};
SCH_ITEM* SCH_SELECTION_TOOL::GetNode( VECTOR2I aPosition )
EDA_ITEM* SCH_SELECTION_TOOL::GetNode( VECTOR2I aPosition )
{
SCH_COLLECTOR collector;
@ -658,7 +634,7 @@ int SCH_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent )
m_frame->GetScreen()->ClearDrawingState();
m_frame->GetScreen()->MarkConnections( line );
for( SCH_ITEM* item = m_frame->GetScreen()->GetDrawItems(); item; item = item->Next() )
for( EDA_ITEM* item = m_frame->GetScreen()->GetDrawItems(); item; item = item->Next() )
{
if( item->GetFlags() & CANDIDATE )
select( item );
@ -673,7 +649,7 @@ int SCH_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent )
int SCH_SELECTION_TOOL::AddItemToSel( const TOOL_EVENT& aEvent )
{
AddItemToSel( aEvent.Parameter<SCH_ITEM*>() );
AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
return 0;
}
@ -714,7 +690,7 @@ void SCH_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
int SCH_SELECTION_TOOL::RemoveItemFromSel( const TOOL_EVENT& aEvent )
{
RemoveItemFromSel( aEvent.Parameter<SCH_ITEM*>() );
RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
return 0;
}
@ -774,7 +750,7 @@ int SCH_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector )
{
SCH_ITEM* current = nullptr;
EDA_ITEM* current = nullptr;
CONTEXT_MENU menu;
int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() );
@ -782,7 +758,7 @@ bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector )
for( int i = 0; i < limit; ++i )
{
wxString text;
SCH_ITEM* item = ( *aCollector )[i];
EDA_ITEM* item = ( *aCollector )[i];
text = item->GetSelectMenuText( m_frame->GetUserUnits() );
wxString menuText = wxString::Format("&%d. %s", i + 1, text );
@ -883,7 +859,7 @@ void SCH_SELECTION_TOOL::clearSelection()
return;
while( m_selection.GetSize() )
unhighlight( static_cast<SCH_ITEM*>( m_selection.Front() ), SELECTED, &m_selection );
unhighlight( (EDA_ITEM*) m_selection.Front(), SELECTED, &m_selection );
getView()->Update( &m_selection );

View File

@ -100,7 +100,7 @@ public:
* was cancelled (for instance, by clicking outside of the disambiguation menu).
* @param aCheckLocked indicates if locked items should be excluded
*/
SCH_ITEM* SelectPoint( const VECTOR2I& aWhere,
EDA_ITEM* SelectPoint( const VECTOR2I& aWhere,
const KICAD_T* aFilterList = SCH_COLLECTOR::AllItems,
bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false );
@ -115,7 +115,7 @@ public:
void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false );
///> Find (but don't select) node under cursor
SCH_ITEM* GetNode( VECTOR2I aPosition );
EDA_ITEM* GetNode( VECTOR2I aPosition );
///> Select node under cursor
int SelectNode( const TOOL_EVENT& aEvent );
@ -228,7 +228,7 @@ private:
void setTransitions() override;
private:
SCH_EDIT_FRAME* m_frame; // Pointer to the parent frame
SCH_BASE_FRAME* m_frame; // Pointer to the parent frame
SELECTION m_selection; // Current state of selection
bool m_additive; // Items should be added to selection (instead of replacing)

View File

@ -213,7 +213,7 @@ void GERBVIEW_FRAME::Block_Move()
{
GERBER_DRAW_ITEM* gerb_item = item;
if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
if( gerb_item->HitTest( GetScreen()->m_BlockLocate, true ) )
gerb_item->MoveAB( delta );
}
}

View File

@ -791,7 +791,7 @@ BITMAP_DEF GERBER_DRAW_ITEM::GetMenuImage() const
}
bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const
bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos, int aAccuracy ) const
{
// In case the item has a very tiny width defined, allow it to be selected
const int MIN_HIT_TEST_RADIUS = Millimeter2iu( 0.01 );
@ -878,7 +878,7 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const
}
bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea ) const
bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea, bool aContained, int aAccuracy ) const
{
wxPoint pos = GetABPosition( m_Start );

View File

@ -263,7 +263,7 @@ public:
* @param aRefPos a wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& aRefPos ) const override;
bool HitTest( const wxPoint& aRefPos, int aAccuracy = 0 ) const override;
/**
* Function HitTest (overloaded)
@ -272,7 +272,7 @@ public:
* @param aRefArea a wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const EDA_RECT& aRefArea ) const;
bool HitTest( const EDA_RECT& aRefArea, bool aContained, int aAccuracy = 0 ) const override;
/**
* Function GetClass

View File

@ -424,27 +424,12 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple()
* Left > Right : Select objects that are fully enclosed by selection
* Right > Left : Select objects that are crossed by selection
*/
if( width >= 0 )
if( item->HitTest( selectionRect, width >= 0 ) )
{
if( selectionBox.Contains( item->ViewBBox() ) )
{
if( m_subtractive )
unselect( item );
else
select( item );
}
}
else
{
if( item->HitTest( selectionRect ) )
{
if( m_subtractive )
unselect( item );
else
select( item );
}
if( m_subtractive )
unselect( item );
else
select( item );
}
}

View File

@ -318,16 +318,30 @@ public:
/**
* Function HitTest
* tests if \a aPosition is contained within or on the bounding area of an item.
* tests if \a aPosition is contained within or on the bounding box of an item.
*
* @param aPosition A reference to a wxPoint object containing the coordinates to test.
* @return True if \a aPosition is within or on the item bounding area.
* @param aAccuracy Increase the item bounding box by this amount.
* @return True if \a aPosition is within the item bounding box.
*/
virtual bool HitTest( const wxPoint& aPosition ) const
virtual bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const
{
return false; // derived classes should override this function
}
/**
* Function HitTest
* tests if \a aRect intersects or is contained within the bounding box of an item.
*
* @param aRect A reference to a EDA_RECT object containing the rectangle to test.
* @param aContained Set to true to test for containment instead of an intersection.
* @param aAccuracy Increase \a aRect by this amount.
* @return True if \a aRect contains or intersects the item bounding box.
*/
virtual bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const
{
return false; // derived classes should override this function
}
/**
* Function GetBoundingBox

View File

@ -286,27 +286,6 @@ public:
*/
wxString GetLayerName() const;
virtual bool HitTest( const wxPoint& aPosition ) const override
{
return EDA_ITEM::HitTest( aPosition );
}
/**
* Function HitTest
* tests if the \a aRect intersects or contains this object (depending on \a aContained).
*
* @param aRect A reference to an EDA_RECT object containg the area to test.
* @param aContained Test if \a aRect contains this object completly.
* @param aAccuracy Increase the item bounding box by this amount.
* @return bool - True if \a aRect contains this object completly or if \a aRect intersects
* the object and \a aContained is False, otherwise false.
*/
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0) const
{
return false; // derived classes should override this function
}
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
/**

View File

@ -303,7 +303,7 @@ public:
* @param aAccuracy - Amount to inflate the bounding box.
* @return bool - true if a hit, else false
*/
virtual bool TextHitTest( const EDA_RECT& aRect, bool aContains = false, int aAccuracy = 0 ) const;
virtual bool TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy = 0 ) const;
/**
* Function LenSize

View File

@ -551,10 +551,10 @@ public:
*
* Checks if point aP lies inside a polygon (any type) defined by the line chain.
* For closed shapes only.
* @param aP point to check
* @param aPt 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;
bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0 ) const;
/**
* Function PointOnEdge()
@ -563,7 +563,7 @@ public:
* @param aP point to check
* @return true if the point lies on the edge.
*/
bool PointOnEdge( const VECTOR2I& aP ) const;
bool PointOnEdge( const VECTOR2I& aP, int aAccuracy = 0 ) const;
/**
* Function EdgeContainingPoint()
@ -572,7 +572,7 @@ public:
* @param aP point to check
* @return index of the first edge containing the point, otherwise negative
*/
int EdgeContainingPoint( const VECTOR2I& aP ) const;
int EdgeContainingPoint( const VECTOR2I& aP, int aAccuracy = 0 ) const;
/**
* Function CheckClearance()

View File

@ -256,7 +256,7 @@ public:
* @param aHitPosition is the wxPoint to test (in internal units)
* @return bool - true if a hit, else false
*/
bool HitTestMarker( const wxPoint& aHitPosition ) const;
bool HitTestMarker( const wxPoint& aHitPosition, int aAccuracy ) const;
/**
* Function GetBoundingBoxMarker

View File

@ -866,7 +866,7 @@ int MarkItemsInBloc( MODULE* module, EDA_RECT& Rect )
switch( item->Type() )
{
case PCB_MODULE_EDGE_T:
if( ((EDGE_MODULE*)item )->HitTest( Rect ) )
if( ((EDGE_MODULE*)item )->HitTest( Rect, false ) )
{
item->SetFlags( SELECTED );
ItemsCount++;

View File

@ -263,9 +263,8 @@ public:
BOARD();
~BOARD();
virtual const wxPoint GetPosition() const override;
virtual void SetPosition( const wxPoint& aPos ) override;
const wxPoint GetPosition() const override;
void SetPosition( const wxPoint& aPos ) override;
bool IsEmpty() const
{

View File

@ -386,12 +386,12 @@ void DIMENSION::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM
}
bool DIMENSION::HitTest( const wxPoint& aPosition ) const
bool DIMENSION::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
if( m_Text.TextHitTest( aPosition ) )
return true;
int dist_max = m_Width / 2;
int dist_max = aAccuracy + ( m_Width / 2 );
// Locate SEGMENTS

View File

@ -220,13 +220,12 @@ public:
* the layer is not changed
* @param axis_pos : vertical axis position
*/
void Mirror( const wxPoint& axis_pos );
void Mirror( const wxPoint& axis_pos );
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
wxString GetClass() const override
{
@ -234,13 +233,13 @@ public:
}
// Virtual function
const EDA_RECT GetBoundingBox() const override;
const EDA_RECT GetBoundingBox() const override;
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
BITMAP_DEF GetMenuImage() const override;
EDA_ITEM* Clone() const override;
EDA_ITEM* Clone() const override;
virtual const BOX2I ViewBBox() const override;

View File

@ -594,8 +594,10 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
}
bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
bool DRAWSEGMENT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
int maxdist = aAccuracy + ( m_Width / 2 );
switch( m_Shape )
{
case S_CIRCLE:
@ -605,7 +607,7 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
int radius = GetRadius();
int dist = KiROUND( EuclideanNorm( relPos ) );
if( abs( radius - dist ) <= ( m_Width / 2 ) )
if( abs( radius - dist ) <= maxdist )
{
if( m_Shape == S_CIRCLE )
return true;
@ -647,13 +649,13 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
for( unsigned int i= 1; i < m_BezierPoints.size(); i++)
{
if( TestSegmentHit( aPosition, m_BezierPoints[i-1], m_BezierPoints[i-1], m_Width / 2 ) )
if( TestSegmentHit( aPosition, m_BezierPoints[i-1], m_BezierPoints[i-1], maxdist ) )
return true;
}
break;
case S_SEGMENT:
if( TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ) )
if( TestSegmentHit( aPosition, m_Start, m_End, maxdist ) )
return true;
break;
@ -663,11 +665,11 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
{
SHAPE_POLY_SET::VERTEX_INDEX i;
auto poly = m_Poly; //todo: Fix CollideEdge to be const
return poly.CollideEdge(VECTOR2I( aPosition ), i,
std::max( m_Width / 2, Millimeter2iu( 0.25 ) ) );
return poly.CollideEdge( VECTOR2I( aPosition ), i,
std::max( maxdist, Millimeter2iu( 0.25 ) ) );
}
else
return m_Poly.Collide( VECTOR2I( aPosition ), m_Width / 2 );
return m_Poly.Collide( VECTOR2I( aPosition ), maxdist );
}
break;

View File

@ -211,18 +211,15 @@ public:
void SetPolyPoints( const std::vector<wxPoint>& aPoints );
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset ) override;
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
const wxPoint& aOffset = ZeroOffset ) override;
virtual void GetMsgPanelInfo( EDA_UNITS_T aUnits,
std::vector< MSG_PANEL_ITEM >& aList ) override;
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector<MSG_PANEL_ITEM>& aList ) override;
virtual const EDA_RECT GetBoundingBox() const override;
const EDA_RECT GetBoundingBox() const override;
virtual bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = true,
int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
wxString GetClass() const override
{

View File

@ -97,9 +97,9 @@ public:
const wxPoint GetPosition() const override { return m_Pos; }
void SetPosition( const wxPoint& aPos ) override { m_Pos = aPos; }
bool HitTest( const wxPoint& aPosition ) const override
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override
{
return HitTestMarker( aPosition );
return HitTestMarker( aPosition, aAccuracy );
}
bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;

View File

@ -631,15 +631,18 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
}
bool MODULE::HitTest( const wxPoint& aPosition ) const
bool MODULE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
return m_BoundaryBox.Contains( aPosition );
EDA_RECT rect = m_BoundaryBox;
return rect.Inflate( aAccuracy ).Contains( aPosition );
}
bool MODULE::HitTestAccurate( const wxPoint& aPosition ) const
bool MODULE::HitTestAccurate( const wxPoint& aPosition, int aAccuracy ) const
{
auto shape = GetBoundingPoly();
SHAPE_POLY_SET shape = GetBoundingPoly();
shape.Inflate( aAccuracy, 4 );
return shape.Contains( aPosition, -1, true );
}

View File

@ -440,7 +440,7 @@ public:
///> @copydoc EDA_ITEM::GetMsgPanelInfo
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector<MSG_PANEL_ITEM>& aList ) override;
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
/**
* Tests if a point is inside the bounding polygon of the module
@ -451,9 +451,9 @@ public:
* @param aPosition is the point to test
* @return true if aPosition is inside the bounding polygon
*/
bool HitTestAccurate( const wxPoint& aPosition ) const;
bool HitTestAccurate( const wxPoint& aPosition, int aAccuracy = 0 ) const;
bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
/**
* Function GetReference

View File

@ -868,7 +868,7 @@ void D_PAD::GetOblongDrillGeometry( wxPoint& aStartPoint,
}
bool D_PAD::HitTest( const wxPoint& aPosition ) const
bool D_PAD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
int dx, dy;

View File

@ -714,8 +714,7 @@ public:
return m_layerMask[aLayer];
}
bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
wxString GetClass() const override

View File

@ -137,11 +137,11 @@ void PCB_TARGET::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color,
}
bool PCB_TARGET::HitTest( const wxPoint& aPosition ) const
bool PCB_TARGET::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
int dX = aPosition.x - m_Pos.x;
int dY = aPosition.y - m_Pos.y;
int radius = m_Size / 2;
int radius = aAccuracy + ( m_Size / 2 );
return abs( dX ) <= radius && abs( dY ) <= radius;
}

View File

@ -87,17 +87,13 @@ public:
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset ) override;
bool HitTest( const wxPoint& aPosition ) const override;
wxString GetClass() const override
{
return wxT( "PCB_TARGET" );
}
/** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
* bool aContained = true, int aAccuracy ) const
*/
bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
// Virtual function
const EDA_RECT GetBoundingBox() const override;

View File

@ -80,15 +80,15 @@ public:
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
virtual bool HitTest( const wxPoint& aPosition ) const override
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override
{
return TextHitTest( aPosition );
return TextHitTest( aPosition, aAccuracy );
}
/** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
* bool aContained = true, int aAccuracy ) const
*/
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override
{
return TextHitTest( aRect, aContained, aAccuracy );
}

View File

@ -109,13 +109,9 @@ bool TEXTE_MODULE::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccu
rect.Inflate( aAccuracy );
if( aContains )
{
return rect.Contains( GetBoundingBox() );
}
else
{
return rect.Intersects( GetTextBox( -1 ), GetDrawRotation() );
}
}

View File

@ -205,16 +205,15 @@ public:
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
virtual bool TextHitTest( const wxPoint& aPoint, int aAccuracy = 0 ) const override;
bool TextHitTest( const wxPoint& aPoint, int aAccuracy = 0 ) const override;
bool TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy = 0 ) const override;
virtual bool TextHitTest( const EDA_RECT& aRect, bool aContains = false, int aAccuracy = 0 ) const override;
virtual bool HitTest( const wxPoint& aPosition ) const override
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override
{
return TextHitTest( aPosition );
return TextHitTest( aPosition, aAccuracy );
}
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override
{
return TextHitTest( aRect, aContained, aAccuracy );
}

View File

@ -1184,14 +1184,14 @@ void VIA::GetMsgPanelInfoBase( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >
}
bool TRACK::HitTest( const wxPoint& aPosition ) const
bool TRACK::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 );
return TestSegmentHit( aPosition, m_Start, m_End, aAccuracy + ( m_Width / 2 ) );
}
bool VIA::HitTest( const wxPoint& aPosition ) const
bool VIA::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
int max_dist = m_Width / 2;
int max_dist = aAccuracy + ( m_Width / 2 );
// rel_pos is aPosition relative to m_Start (or the center of the via)
wxPoint rel_pos = aPosition - m_Start;

View File

@ -230,9 +230,8 @@ public:
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
virtual bool HitTest( const wxPoint& aPosition ) const override;
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
/**
* Function GetVia
@ -411,9 +410,8 @@ public:
const wxPoint GetPosition() const override { return m_Start; }
void SetPosition( const wxPoint& aPoint ) override { m_Start = aPoint; m_End = aPoint; }
virtual bool HitTest( const wxPoint& aPosition ) const override;
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
wxString GetClass() const override
{

View File

@ -650,11 +650,11 @@ void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
}
bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition ) const
bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
// Normally accuracy is zoom-relative, but for the generic HitTest we just use
// a fixed (small) value.
int accuracy = Millimeter2iu( 0.05 );
int accuracy = std::max( aAccuracy, Millimeter2iu( 0.1 ) );
return HitTestForCorner( aPosition, accuracy * 2 ) || HitTestForEdge( aPosition, accuracy );
}

View File

@ -268,7 +268,7 @@ public:
* @param aPosition the wxPoint to test
* @return bool - true if a hit, else false
*/
virtual bool HitTest( const wxPoint& aPosition ) const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
/**
* Function HitTest

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -22,10 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file class_netinfo.h
*/
/*
* Classes to handle info on nets
*/

View File

@ -53,6 +53,11 @@ public:
/// @copydoc VIEW_ITEM::ViewGetLayers()
void ViewGetLayers( int aLayers[], int& aCount ) const override;
bool HitTest( const wxPoint& aPoint, int aAccuracy = 0 ) const override
{
return false; // Not selectable
}
#if defined(DEBUG)
/// @copydoc EDA_ITEM::Show()
void Show( int x, std::ostream& st ) const override

View File

@ -770,25 +770,21 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
BOARD_COMMIT commit( m_frame );
// Build the undo list & add items to the current view
for( auto it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
for( auto& ptr : list)
{
EDA_ITEM* item = it->get();
EDA_ITEM* item = ptr.get();
if( m_editModules )
{
wxASSERT( item->Type() == PCB_MODULE_EDGE_T || item->Type() == PCB_MODULE_TEXT_T );
}
else
{
wxASSERT( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T );
}
if( dlg.IsPlacementInteractive() )
preview.Add( item );
else
commit.Add( item );
it->release();
ptr.release();
}
if( !dlg.IsPlacementInteractive() )
@ -811,7 +807,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = m_controls->GetCursorPosition();
VECTOR2I delta = cursorPos - firstItem->GetPosition();
for( auto item : preview )
for( EDA_ITEM* item : preview )
static_cast<BOARD_ITEM*>( item )->Move( (wxPoint) delta );
m_view->Update( &preview );
@ -890,8 +886,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR );
Activate();
m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL,
_( "Place the footprint anchor" ) );
m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL, _( "Place the footprint anchor" ) );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );

View File

@ -370,17 +370,18 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
auto curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
std::vector<BOARD_ITEM*> sel_items;
for( auto it : selection )
for( EDA_ITEM* item : selection )
{
if( auto item = dynamic_cast<BOARD_ITEM*>( it ) )
{
sel_items.push_back( item );
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
MODULE* module = dynamic_cast<MODULE*>( item );
if( auto mod = dyn_cast<MODULE*>( item ) )
{
for( auto pad : mod->Pads() )
sel_items.push_back( pad );
}
if( boardItem )
sel_items.push_back( boardItem );
if( module )
{
for( D_PAD* pad : module->Pads() )
sel_items.push_back( pad );
}
}
@ -413,7 +414,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
prevPos = m_cursor;
// Drag items to the current cursor position
for( auto item : selection )
for( EDA_ITEM* item : selection )
{
// Don't double move footprint pads, fields, etc.
if( item->GetParent() && item->GetParent()->IsSelected() )
@ -501,7 +502,6 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, false );
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
}
else if( evt->IsCancel() || evt->IsActivate() )
@ -687,9 +687,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto item : selection )
{
@ -770,11 +768,9 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto item : selection )
for( EDA_ITEM* item : selection )
{
// only modify items we can mirror
switch( item->Type() )
@ -851,11 +847,9 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto item : selection )
for( EDA_ITEM* item : selection )
{
if( !item->IsNew() && !EditingModules() )
m_commit->Modify( item );
@ -896,11 +890,15 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
// If we are in a "Cut" operation, then the copied selection exists already
if( isCut )
{
selectionCopy = m_selectionTool->GetSelection();
}
else
{
selectionCopy = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); } );
}
bool isHover = selectionCopy.IsHover();
@ -930,7 +928,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
// As we are about to remove items, they have to be removed from the selection first
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
for( auto item : selectionCopy )
for( EDA_ITEM* item : selectionCopy )
{
if( m_editModules )
{
@ -1020,11 +1018,9 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto selItem : selection )
for( EDA_ITEM* selItem : selection )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
@ -1091,7 +1087,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
// Each selected item is duplicated and pushed to new_items list
// Old selection is cleared, and new items are then selected.
for( auto item : selection )
for( EDA_ITEM* item : selection )
{
if( !item )
continue;
@ -1134,8 +1130,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
if( !selection.Empty() )
{
editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
(int) new_items.size() ) );
(int) new_items.size() ) );
// If items were duplicated, pick them up
// this works well for "dropping" copies around and pushes the commit

View File

@ -203,7 +203,6 @@ SELECTION_TOOL::SELECTION_TOOL() :
m_menu( *this ),
m_priv( std::make_unique<PRIV>() )
{
}
@ -234,9 +233,7 @@ bool SELECTION_TOOL::Init()
menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 );
if( frame )
{
m_menu.AddStandardSubMenus( frame );
}
return true;
}
@ -256,8 +253,10 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
getView()->GetPainter()->GetSettings()->SetHighlight( false );
}
else
{
// Restore previous properties of selected items and remove them from containers
clearSelection();
}
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW
view()->Remove( &m_selection );
@ -389,15 +388,6 @@ SELECTION& SELECTION_TOOL::GetSelection()
}
static EDA_RECT getRect( const BOARD_ITEM* aItem )
{
if( aItem->Type() == PCB_MODULE_T )
return static_cast<const MODULE*>( aItem )->GetFootprintRect();
return aItem->GetBoundingBox();
}
SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter,
std::vector<BOARD_ITEM*>* aFiltered, bool aConfirmLockedItems )
{
@ -666,27 +656,12 @@ bool SELECTION_TOOL::selectMultiple()
if( !item || !selectable( item ) )
continue;
if( windowSelection )
if( item->HitTest( selectionRect, windowSelection ) )
{
BOX2I bbox = getRect( item );
if( selectionBox.Contains( bbox ) )
{
if( m_subtractive )
unselect( item );
else
select( item );
}
}
else
{
if( item->HitTest( selectionRect, false ) )
{
if( m_subtractive )
unselect( item );
else
select( item );
}
if( m_subtractive )
unselect( item );
else
select( item );
}
}
@ -1918,6 +1893,15 @@ bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
}
static EDA_RECT getRect( const BOARD_ITEM* aItem )
{
if( aItem->Type() == PCB_MODULE_T )
return static_cast<const MODULE*>( aItem )->GetFootprintRect();
return aItem->GetBoundingBox();
}
static double calcArea( const BOARD_ITEM* aItem )
{
if( aItem->Type() == PCB_TRACE_T )