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_line_chain.h>
#include <geometry/shape_circle.h> #include <geometry/shape_circle.h>
#include <trigo.h>
#include "clipper.hpp" #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; return false;
bool inside = false; bool inside = false;
@ -371,37 +375,40 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const
if( diff.y != 0 ) 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; 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() ) if( !PointCount() )
return -1; return -1;
else if( PointCount() == 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++ ) for( int i = 0; i < SegmentCount(); i++ )
{ {
const SEG s = CSegment( i ); const SEG s = CSegment( i );
if( s.A == aP || s.B == aP ) if( s.A == aPt || s.B == aPt )
return i; return i;
if( s.Distance( aP ) <= 1 ) if( s.Distance( aPt ) <= aAccuracy + 1 )
return i; 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(); EDA_RECT bbox = GetBoundingBoxMarker();
bbox.Inflate( aAccuracy );
// Fast hit test using boundary box. A finer test will be made if requested // Fast hit test using boundary box. A finer test will be made if requested
bool hit = bbox.Contains( aHitPosition ); bool hit = bbox.Contains( aHitPosition );
@ -172,7 +173,7 @@ bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition ) const
SHAPE_LINE_CHAIN polygon; SHAPE_LINE_CHAIN polygon;
ShapeToPolygon( polygon ); ShapeToPolygon( polygon );
VECTOR2I rel_pos( aHitPosition - m_Pos ); VECTOR2I rel_pos( aHitPosition - m_Pos );
hit = polygon.PointInside( rel_pos ); hit = polygon.PointInside( rel_pos, aAccuracy );
} }
return hit; 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; int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint relativePosition = aRefPoint;
// 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;
relativePosition.y = -relativePosition.y; // reverse Y axis relativePosition.y = -relativePosition.y; // reverse Y axis
int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) ); int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) );
if( abs( distance - m_Radius ) > aThreshold ) if( abs( distance - m_Radius ) > mindist )
return false; return false;
// We are on the circle, ensure we are only on the arc, i.e. between // 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 // When the cross products have a different sign, the point lies in sector
// also check, if the reference is near start or end point // also check, if the reference is near start or end point
return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) || return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) || HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
( crossProductStart <= 0 && crossProductEnd >= 0 ); ( 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" ); return _( "Arc" );
} }
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;
bool HitTest( const wxPoint& aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
const EDA_RECT GetBoundingBox() const override; const EDA_RECT GetBoundingBox() const override;
@ -101,9 +100,7 @@ public:
int GetPenSize() const override; int GetPenSize() const override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override; bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) override; void SetOffset( const wxPoint& aOffset ) override;
@ -115,7 +112,6 @@ public:
wxPoint GetPosition() const override { return m_Pos; } wxPoint GetPosition() const override { return m_Pos; }
void MirrorHorizontal( const wxPoint& aCenter ) override; void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override; void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -124,27 +120,21 @@ public:
const TRANSFORM& aTransform ) override; const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; } int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; } void SetWidth( int aWidth ) override { m_Width = aWidth; }
void SetRadius( int aRadius ) { m_Radius = aRadius; } void SetRadius( int aRadius ) { m_Radius = aRadius; }
int GetRadius() const { return m_Radius; } int GetRadius() const { return m_Radius; }
void SetFirstRadiusAngle( int aAngle ) { m_t1 = aAngle; } void SetFirstRadiusAngle( int aAngle ) { m_t1 = aAngle; }
int GetFirstRadiusAngle() const { return m_t1; } int GetFirstRadiusAngle() const { return m_t1; }
void SetSecondRadiusAngle( int aAngle ) { m_t2 = aAngle; } void SetSecondRadiusAngle( int aAngle ) { m_t2 = aAngle; }
int GetSecondRadiusAngle() const { return m_t2; } int GetSecondRadiusAngle() const { return m_t2; }
wxPoint GetStart() const { return m_ArcStart; } wxPoint GetStart() const { return m_ArcStart; }
void SetStart( const wxPoint& aPoint ) { m_ArcStart = aPoint; } void SetStart( const wxPoint& aPoint ) { m_ArcStart = aPoint; }
wxPoint GetEnd() const { return m_ArcEnd; } wxPoint GetEnd() const { return m_ArcEnd; }
void SetEnd( const wxPoint& aPoint ) { m_ArcEnd = aPoint; } 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 bool LIB_BEZIER::HitTest( const wxPoint& aRefPos, 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( aRefPos, mindist, DefaultTransform );
}
bool LIB_BEZIER::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const
{ {
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint start, end; wxPoint start, end;
if( aThreshold < 0 )
aThreshold = GetPenSize() / 2;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{ {
start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] ); start = DefaultTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = aTransform.TransformCoordinate( m_PolyPoints[ii] ); end = DefaultTransform.TransformCoordinate( m_PolyPoints[ii] );
if ( TestSegmentHit( aPosRef, start, end, aThreshold ) ) if ( TestSegmentHit( aRefPos, start, end, mindist ) )
return true; 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 const EDA_RECT LIB_BEZIER::GetBoundingBox() const
{ {
EDA_RECT rect; EDA_RECT rect;

View File

@ -78,9 +78,8 @@ public:
return m_BezierPoints; return m_BezierPoints;
} }
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;
bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
const EDA_RECT GetBoundingBox() const override; const EDA_RECT GetBoundingBox() const override;
@ -91,7 +90,6 @@ public:
wxPoint GetPosition() const override; wxPoint GetPosition() const override;
void MirrorHorizontal( const wxPoint& aCenter ) override; void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override; void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -100,7 +98,6 @@ public:
const TRANSFORM& aTransform ) override; const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; } int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; } void SetWidth( int aWidth ) override { m_Width = aWidth; }
int GetPenSize( ) const override; 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( abs( dist - m_Radius ) <= mindist )
if( mindist < MINIMUM_SELECTION_DISTANCE ) return true;
mindist = MINIMUM_SELECTION_DISTANCE;
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 ) if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
aThreshold = GetPenSize() / 2; return false;
int dist = KiROUND( GetLineLength( aPosRef, aTransform.TransformCoordinate( m_Pos ) ) ); EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect );
if( abs( dist - m_Radius ) <= aThreshold ) if ( aAccuracy )
return true; rect.Inflate( aAccuracy );
return false;
if( aContained )
return rect.Contains( GetBoundingBox() );
return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse...
} }

View File

@ -60,9 +60,8 @@ public:
return _( "Circle" ); return _( "Circle" );
} }
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;
bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
int GetPenSize( ) 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 GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override; bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) override; void SetOffset( const wxPoint& aOffset ) override;
@ -85,7 +82,6 @@ public:
wxPoint GetPosition() const override { return m_Pos; } wxPoint GetPosition() const override { return m_Pos; }
void MirrorHorizontal( const wxPoint& aCenter ) override; void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override; void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -94,11 +90,9 @@ public:
const TRANSFORM& aTransform ) override; const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; } int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; } void SetWidth( int aWidth ) override { m_Width = aWidth; }
void SetRadius( int aRadius ) { m_Radius = aRadius; } void SetRadius( int aRadius ) { m_Radius = aRadius; }
int GetRadius() const { return m_Radius; } int GetRadius() const { return m_Radius; }
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; 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() ) ) 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() ) ) || ( 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; return SEARCH_CONTINUE;
Append( aItem ); 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, void LIB_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, void* aData,
const TRANSFORM& aTransform ) const TRANSFORM& aTransform )
{ {

View File

@ -201,27 +201,21 @@ public:
*/ */
virtual int GetPenSize() const = 0; 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; 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 );
} }
/** bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
* @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;
/** /**
* @return the boundary box for this, in library coordinates * @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 // Because HitTest is mainly used to select the field return false if it is void
// return always false if this field is void
if( IsVoid() ) if( IsVoid() )
return false; 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 // Build a temporary copy of the text for hit testing
EDA_TEXT tmp_text( *this ); 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.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 /* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped. * transformation matrix causes xy axes to be flipped.
* this simple algo works only for schematic matrix (rot 90 or/and mirror) * 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 ); 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; 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;
bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
void operator=( const LIB_FIELD& field ); void operator=( const LIB_FIELD& field );
@ -191,9 +189,7 @@ public:
COLOR4D GetDefaultColor() override; COLOR4D GetDefaultColor() override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override; bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void Rotate() override; void Rotate() override;
@ -220,7 +216,6 @@ public:
wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); } wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); }
void MirrorHorizontal( const wxPoint& aCenter ) override; void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override; void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -229,7 +224,6 @@ public:
const TRANSFORM& aTransform ) override; const TRANSFORM& aTransform ) override;
int GetWidth() const override { return GetThickness(); } int GetWidth() const override { return GetThickness(); }
void SetWidth( int aWidth ) override { SetThickness( aWidth ); } void SetWidth( int aWidth ) override { SetThickness( aWidth ); }
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; 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(); EDA_RECT rect = GetBoundingBox();
rect.Inflate( aThreshold );
//Restore matrix return rect.Inflate( aAccuracy ).Contains( aPosition );
DefaultTransform = transform;
return rect.Contains( aPosition );
} }

View File

@ -110,9 +110,7 @@ public:
void Show( int nestLevel, std::ostream& os ) const override; void Show( int nestLevel, std::ostream& os ) const override;
#endif #endif
bool HitTest( const wxPoint& aPosition ) const override; bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
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;

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 bool LIB_POLYLINE::HitTest( const wxPoint& aPosition, 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( aPosition, mindist, DefaultTransform );
}
bool LIB_POLYLINE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
{ {
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint start, end; wxPoint start, end;
if( aThreshold < 0 )
aThreshold = GetPenSize() / 2;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{ {
start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] ); start = DefaultTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = aTransform.TransformCoordinate( m_PolyPoints[ii] ); end = DefaultTransform.TransformCoordinate( m_PolyPoints[ii] );
if( TestSegmentHit( aPosition, start, end, aThreshold ) ) if( TestSegmentHit( aPosition, start, end, mindist ) )
return true; 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 const EDA_RECT LIB_POLYLINE::GetBoundingBox() const
{ {
EDA_RECT rect; EDA_RECT rect;

View File

@ -76,9 +76,8 @@ public:
*/ */
unsigned GetCornerCount() const { return m_PolyPoints.size(); } unsigned GetCornerCount() const { return m_PolyPoints.size(); }
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;
bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
const EDA_RECT GetBoundingBox() 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 GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override; bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) override; void SetOffset( const wxPoint& aOffset ) override;
@ -101,7 +98,6 @@ public:
wxPoint GetPosition() const override { return m_PolyPoints[0]; } wxPoint GetPosition() const override { return m_PolyPoints[0]; }
void MirrorHorizontal( const wxPoint& aCenter ) override; void MirrorHorizontal( const wxPoint& aCenter ) override;
void MirrorVertical( const wxPoint& aCenter ) override; void MirrorVertical( const wxPoint& aCenter ) override;
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
@ -110,7 +106,6 @@ public:
const TRANSFORM& aTransform ) override; const TRANSFORM& aTransform ) override;
int GetWidth() const override { return m_Width; } int GetWidth() const override { return m_Width; }
void SetWidth( int aWidth ) override { m_Width = aWidth; } void SetWidth( int aWidth ) override { m_Width = aWidth; }
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; 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; int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
wxPoint actualStart = DefaultTransform.TransformCoordinate( m_Pos );
// Have a minimal tolerance for hit test wxPoint actualEnd = DefaultTransform.TransformCoordinate( m_End );
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 );
// locate lower segment // locate lower segment
wxPoint start, end; wxPoint start, end;
@ -246,21 +232,21 @@ bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRA
end.x = actualEnd.x; end.x = actualEnd.x;
end.y = actualStart.y; end.y = actualStart.y;
if( TestSegmentHit( aPosition, start, end, aThreshold ) ) if( TestSegmentHit( aPosition, start, end, mindist ) )
return true; return true;
// locate right segment // locate right segment
start.x = actualEnd.x; start.x = actualEnd.x;
end.y = actualEnd.y; end.y = actualEnd.y;
if( TestSegmentHit( aPosition, start, end, aThreshold ) ) if( TestSegmentHit( aPosition, start, end, mindist ) )
return true; return true;
// locate upper segment // locate upper segment
start.y = actualEnd.y; start.y = actualEnd.y;
end.x = actualStart.x; end.x = actualStart.x;
if( TestSegmentHit( aPosition, start, end, aThreshold ) ) if( TestSegmentHit( aPosition, start, end, mindist ) )
return true; return true;
// locate left segment // locate left segment
@ -268,7 +254,7 @@ bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRA
end.x = actualStart.x; end.x = actualStart.x;
end.y = actualEnd.y; end.y = actualEnd.y;
if( TestSegmentHit( aPosition, start, end, aThreshold ) ) if( TestSegmentHit( aPosition, start, end, mindist ) )
return true; return true;
return false; return false;

View File

@ -65,9 +65,7 @@ public:
void SetEndPosition( const wxPoint& aPosition ) { m_End = aPosition; } void SetEndPosition( const wxPoint& aPosition ) { m_End = aPosition; }
bool HitTest( const wxPoint& aPosition ) const override; bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override;
int GetPenSize( ) 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 GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override;
bool ContinueEdit( const wxPoint aNextPoint ) override; bool ContinueEdit( const wxPoint aNextPoint ) override;
void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override;
void SetOffset( const wxPoint& aOffset ) 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 bool LIB_TEXT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
return HitTest( aPosition, 0, DefaultTransform );
}
bool LIB_TEXT::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
{ {
EDA_TEXT tmp_text( *this ); 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 /* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped. * transformation matrix causes xy axes to be flipped.
* this simple algo works only for schematic matrix (rot 90 or/and mirror) * 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 ); 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; 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, bool aContained, int aAccuracy = 0 ) const override
bool HitTest( const EDA_RECT& aRect ) const
{ {
return TextHitTest( aRect ); return TextHitTest( aRect, aContained, aAccuracy );
} }

View File

@ -152,8 +152,8 @@ public:
wxPoint GetPosition() const override { return m_pos; } wxPoint GetPosition() const override { return m_pos; }
void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; } 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;
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; void Plot( PLOTTER* aPlotter ) override;

View File

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

View File

@ -611,8 +611,8 @@ public:
wxPoint GetPosition() const override { return m_Pos; } wxPoint GetPosition() const override { return m_Pos; }
void SetPosition( const wxPoint& aPosition ) override { Move( aPosition - m_Pos ); } void SetPosition( const wxPoint& aPosition ) override { Move( aPosition - m_Pos ); }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) 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; void Plot( PLOTTER* aPlotter ) override;

View File

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

View File

@ -363,35 +363,6 @@ public:
void SetConnectivityDirty( bool aDirty = true ) { m_connectivity_dirty = aDirty; } 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; } virtual bool CanIncrementLabel() const { return false; }
/** /**

View File

@ -95,8 +95,8 @@ public:
wxPoint GetPosition() const override { return m_pos; } wxPoint GetPosition() const override { return m_pos; }
void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; } 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;
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; void Plot( PLOTTER* aPlotter ) override;

View File

@ -189,8 +189,8 @@ public:
wxPoint GetPosition() const override { return m_start; } wxPoint GetPosition() const override { return m_start; }
void SetPosition( const wxPoint& aPosition ) override; void SetPosition( const wxPoint& aPosition ) override;
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) 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; 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 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; } wxPoint GetPosition() const override { return m_Pos; }
void SetPosition( const wxPoint& aPosition ) override { m_Pos = aPosition; } 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; EDA_ITEM* Clone() const override;

View File

@ -101,8 +101,8 @@ public:
wxPoint GetPosition() const override { return m_pos; } wxPoint GetPosition() const override { return m_pos; }
void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; } 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;
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; 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; } void SetPosition( const wxPoint& aPosition ) override { m_position = aPosition; }
const EDA_RECT GetBoundingBox() const override; 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; } bool IsDangling() const override { return m_isDangling; }
void SetIsDangling( bool isDangling ) { m_isDangling = 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 ) for( SCH_SHEET_PIN& pin : m_pins )
{ {
if( pin.HitTest( aPosition, 0 ) ) if( pin.HitTest( aPosition ) )
return &pin; return &pin;
} }

View File

@ -186,7 +186,7 @@ public:
void SetPosition( const wxPoint& aPosition ) override { ConstrainOnEdge( aPosition ); } 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; EDA_ITEM* Clone() const override;
}; };
@ -531,7 +531,7 @@ public:
void SetPosition( const wxPoint& aPosition ) override; void SetPosition( const wxPoint& aPosition ) override;
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const 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; void Plot( PLOTTER* aPlotter ) override;

View File

@ -190,8 +190,8 @@ public:
wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); } wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); }
void SetPosition( const wxPoint& aPosition ) override { EDA_TEXT::SetTextPos( aPosition ); } void SetPosition( const wxPoint& aPosition ) override { EDA_TEXT::SetTextPos( aPosition ); }
bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const override; bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
void Plot( PLOTTER* aPlotter ) 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 ) int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
{ {
VECTOR2I cursorPos = m_controls->GetCursorPosition(); VECTOR2I cursorPos = m_controls->GetCursorPosition();
SCH_ITEM* item = nullptr; EDA_ITEM* item = nullptr;
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_controls->ShowCursor( true ); m_controls->ShowCursor( true );
@ -719,7 +719,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
// ... and second click places: // ... and second click places:
else else
{ {
m_frame->AddItemToScreenAndUndoList( item ); m_frame->AddItemToScreenAndUndoList( (SCH_ITEM*) item );
item = nullptr; item = nullptr;
m_view->ClearPreview(); 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() ) ) 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->ClearPreview();
m_view->AddToPreview( item->Clone() ); 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>(); SCH_SELECTION_TOOL* selectionTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
wxCHECK( selectionTool, false ); wxCHECK( selectionTool, false );
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::clearSelection, true ); 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 )
{ aFrame->GetToolManager()->RunAction( SCH_ACTIONS::doDelete, true );
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 );
}
}
return true; return true;
} }

View File

@ -89,7 +89,6 @@ private:
private: private:
SCH_SELECTION_TOOL* m_selectionTool; SCH_SELECTION_TOOL* m_selectionTool;
KIGFX::VIEW_CONTROLS* m_controls;
SCH_EDIT_FRAME* m_frame; SCH_EDIT_FRAME* m_frame;
/// Menu model displayed by the tool. /// 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 }; 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_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 ) if( !item )
return false; 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 }; constexpr KICAD_T fieldsAndComponents[] = { SCH_COMPONENT_T, SCH_FIELD_T, EOT };
SCH_SELECTION_TOOL* selTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>(); 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 ) if( !item )
return false; return false;
if( item->Type() != SCH_COMPONENT_T ) if( item->Type() != SCH_COMPONENT_T )
{ {
item = static_cast<SCH_ITEM*>( item->GetParent() ); item = item->GetParent();
if( item->Type() != SCH_COMPONENT_T ) if( item->Type() != SCH_COMPONENT_T )
return false; return false;
@ -341,7 +341,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
} }
else else
{ {
SCH_ITEM* item = selTool->GetNode( aPosition ); SCH_ITEM* item = (SCH_ITEM*) selTool->GetNode( aPosition );
if( item && item->Connection( *g_CurrentSheet ) ) if( item && item->Connection( *g_CurrentSheet ) )
netName = item->Connection( *g_CurrentSheet )->Name(); 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; int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP;
if( component ) 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 ) bool* aSelectionCancelledFlag, bool aCheckLocked )
{ {
SCH_COLLECTOR collector; SCH_COLLECTOR collector;
@ -419,7 +419,7 @@ SCH_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T
if( collector.GetCount() == 1 ) if( collector.GetCount() == 1 )
{ {
SCH_ITEM* item = collector[ 0 ]; EDA_ITEM* item = collector[ 0 ];
toggleSelection( item ); toggleSelection( item );
return 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. // all the various overlap and coverage issues that we do in Pcbnew.
if( collector.GetCount() == 2 ) if( collector.GetCount() == 2 )
{ {
SCH_ITEM* a = collector[ 0 ]; EDA_ITEM* a = collector[ 0 ];
SCH_ITEM* b = collector[ 1 ]; EDA_ITEM* b = collector[ 1 ];
if( a->GetParent() == b ) if( a->GetParent() == b )
collector.Remove( 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[] ) SELECTION& SCH_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] )
{ {
if( m_selection.Empty() ) 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 ) 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 ) ) if( !item->IsType( aFilterList ) )
toggleSelection( item ); toggleSelection( item );
@ -551,39 +542,24 @@ bool SCH_SELECTION_TOOL::selectMultiple()
if( view->IsMirroredX() ) if( view->IsMirroredX() )
windowSelection = !windowSelection; 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 ) ); EDA_RECT selectionRect( (wxPoint)area.GetOrigin(), wxSize( width, height ) );
selectionRect.Normalize(); selectionRect.Normalize();
for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it ) 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 ) ) if( !item || !selectable( item ) )
continue; continue;
if( windowSelection ) if( item->HitTest( selectionRect, windowSelection ) )
{ {
BOX2I bbox = getRect( item ); if( m_subtractive )
unselect( item );
if( selectionBox.Contains( bbox ) ) else
{ select( item );
if( m_subtractive )
unselect( item );
else
select( item );
}
}
else
{
if( item->HitTest( selectionRect, false ) )
{
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; SCH_COLLECTOR collector;
@ -658,7 +634,7 @@ int SCH_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent )
m_frame->GetScreen()->ClearDrawingState(); m_frame->GetScreen()->ClearDrawingState();
m_frame->GetScreen()->MarkConnections( line ); 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 ) if( item->GetFlags() & CANDIDATE )
select( item ); select( item );
@ -673,7 +649,7 @@ int SCH_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent )
int SCH_SELECTION_TOOL::AddItemToSel( 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; 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 ) int SCH_SELECTION_TOOL::RemoveItemFromSel( const TOOL_EVENT& aEvent )
{ {
RemoveItemFromSel( aEvent.Parameter<SCH_ITEM*>() ); RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
return 0; return 0;
} }
@ -774,7 +750,7 @@ int SCH_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector ) bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector )
{ {
SCH_ITEM* current = nullptr; EDA_ITEM* current = nullptr;
CONTEXT_MENU menu; CONTEXT_MENU menu;
int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() ); 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 ) for( int i = 0; i < limit; ++i )
{ {
wxString text; wxString text;
SCH_ITEM* item = ( *aCollector )[i]; EDA_ITEM* item = ( *aCollector )[i];
text = item->GetSelectMenuText( m_frame->GetUserUnits() ); text = item->GetSelectMenuText( m_frame->GetUserUnits() );
wxString menuText = wxString::Format("&%d. %s", i + 1, text ); wxString menuText = wxString::Format("&%d. %s", i + 1, text );
@ -883,7 +859,7 @@ void SCH_SELECTION_TOOL::clearSelection()
return; return;
while( m_selection.GetSize() ) 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 ); getView()->Update( &m_selection );

View File

@ -100,7 +100,7 @@ public:
* was cancelled (for instance, by clicking outside of the disambiguation menu). * was cancelled (for instance, by clicking outside of the disambiguation menu).
* @param aCheckLocked indicates if locked items should be excluded * @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, const KICAD_T* aFilterList = SCH_COLLECTOR::AllItems,
bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false ); bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false );
@ -115,7 +115,7 @@ public:
void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false ); void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false );
///> Find (but don't select) node under cursor ///> Find (but don't select) node under cursor
SCH_ITEM* GetNode( VECTOR2I aPosition ); EDA_ITEM* GetNode( VECTOR2I aPosition );
///> Select node under cursor ///> Select node under cursor
int SelectNode( const TOOL_EVENT& aEvent ); int SelectNode( const TOOL_EVENT& aEvent );
@ -228,7 +228,7 @@ private:
void setTransitions() override; void setTransitions() override;
private: 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 SELECTION m_selection; // Current state of selection
bool m_additive; // Items should be added to selection (instead of replacing) 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; 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 ); 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 // In case the item has a very tiny width defined, allow it to be selected
const int MIN_HIT_TEST_RADIUS = Millimeter2iu( 0.01 ); 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 ); wxPoint pos = GetABPosition( m_Start );

View File

@ -263,7 +263,7 @@ public:
* @param aRefPos a wxPoint to test * @param aRefPos a wxPoint to test
* @return bool - true if a hit, else false * @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) * Function HitTest (overloaded)
@ -272,7 +272,7 @@ public:
* @param aRefArea a wxPoint to test * @param aRefArea a wxPoint to test
* @return bool - true if a hit, else false * @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 * Function GetClass

View File

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

View File

@ -318,16 +318,30 @@ public:
/** /**
* Function HitTest * 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. * @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 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 * Function GetBoundingBox

View File

@ -286,27 +286,6 @@ public:
*/ */
wxString GetLayerName() const; 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; virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
/** /**

View File

@ -303,7 +303,7 @@ public:
* @param aAccuracy - Amount to inflate the bounding box. * @param aAccuracy - Amount to inflate the bounding box.
* @return bool - true if a hit, else false * @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 * Function LenSize

View File

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

View File

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

View File

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

View File

@ -263,9 +263,8 @@ public:
BOARD(); BOARD();
~BOARD(); ~BOARD();
virtual const wxPoint GetPosition() const override; const wxPoint GetPosition() const override;
void SetPosition( const wxPoint& aPos ) override;
virtual void SetPosition( const wxPoint& aPos ) override;
bool IsEmpty() const 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 ) ) if( m_Text.TextHitTest( aPosition ) )
return true; return true;
int dist_max = m_Width / 2; int dist_max = aAccuracy + ( m_Width / 2 );
// Locate SEGMENTS // Locate SEGMENTS

View File

@ -220,13 +220,12 @@ public:
* the layer is not changed * the layer is not changed
* @param axis_pos : vertical axis position * @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 wxPoint& aPosition, int aAccuracy ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
wxString GetClass() const override wxString GetClass() const override
{ {
@ -234,13 +233,13 @@ public:
} }
// Virtual function // 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; BITMAP_DEF GetMenuImage() const override;
EDA_ITEM* Clone() const override; EDA_ITEM* Clone() const override;
virtual const BOX2I ViewBBox() 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 ) switch( m_Shape )
{ {
case S_CIRCLE: case S_CIRCLE:
@ -605,7 +607,7 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
int radius = GetRadius(); int radius = GetRadius();
int dist = KiROUND( EuclideanNorm( relPos ) ); int dist = KiROUND( EuclideanNorm( relPos ) );
if( abs( radius - dist ) <= ( m_Width / 2 ) ) if( abs( radius - dist ) <= maxdist )
{ {
if( m_Shape == S_CIRCLE ) if( m_Shape == S_CIRCLE )
return true; return true;
@ -647,13 +649,13 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
for( unsigned int i= 1; i < m_BezierPoints.size(); i++) 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; return true;
} }
break; break;
case S_SEGMENT: case S_SEGMENT:
if( TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ) ) if( TestSegmentHit( aPosition, m_Start, m_End, maxdist ) )
return true; return true;
break; break;
@ -663,11 +665,11 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
{ {
SHAPE_POLY_SET::VERTEX_INDEX i; SHAPE_POLY_SET::VERTEX_INDEX i;
auto poly = m_Poly; //todo: Fix CollideEdge to be const auto poly = m_Poly; //todo: Fix CollideEdge to be const
return poly.CollideEdge(VECTOR2I( aPosition ), i, return poly.CollideEdge( VECTOR2I( aPosition ), i,
std::max( m_Width / 2, Millimeter2iu( 0.25 ) ) ); std::max( maxdist, Millimeter2iu( 0.25 ) ) );
} }
else else
return m_Poly.Collide( VECTOR2I( aPosition ), m_Width / 2 ); return m_Poly.Collide( VECTOR2I( aPosition ), maxdist );
} }
break; break;

View File

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

View File

@ -97,9 +97,9 @@ public:
const wxPoint GetPosition() const override { return m_Pos; } const wxPoint GetPosition() const override { return m_Pos; }
void SetPosition( const wxPoint& aPos ) override { m_Pos = aPos; } 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; 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 ); return shape.Contains( aPosition, -1, true );
} }

View File

@ -440,7 +440,7 @@ public:
///> @copydoc EDA_ITEM::GetMsgPanelInfo ///> @copydoc EDA_ITEM::GetMsgPanelInfo
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 wxPoint& aPosition, int aAccuracy = 0 ) const override;
/** /**
* Tests if a point is inside the bounding polygon of the module * Tests if a point is inside the bounding polygon of the module
@ -451,9 +451,9 @@ public:
* @param aPosition is the point to test * @param aPosition is the point to test
* @return true if aPosition is inside the bounding polygon * @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 * 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; int dx, dy;

View File

@ -714,8 +714,7 @@ public:
return m_layerMask[aLayer]; 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; bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
wxString GetClass() 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 dX = aPosition.x - m_Pos.x;
int dY = aPosition.y - m_Pos.y; 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; return abs( dX ) <= radius && abs( dY ) <= radius;
} }

View File

@ -87,17 +87,13 @@ public:
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset ) override; GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset ) override;
bool HitTest( const wxPoint& aPosition ) const override;
wxString GetClass() const override wxString GetClass() const override
{ {
return wxT( "PCB_TARGET" ); return wxT( "PCB_TARGET" );
} }
/** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
* bool aContained = true, int aAccuracy ) const bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
*/
bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
// Virtual function // Virtual function
const EDA_RECT GetBoundingBox() const override; 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; 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, /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
* bool aContained = true, int aAccuracy ) const * 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 ); 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 ); rect.Inflate( aAccuracy );
if( aContains ) if( aContains )
{
return rect.Contains( GetBoundingBox() ); return rect.Contains( GetBoundingBox() );
}
else else
{
return rect.Intersects( GetTextBox( -1 ), GetDrawRotation() ); 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; 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; bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override
virtual bool HitTest( const wxPoint& aPosition ) 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 ); 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) // rel_pos is aPosition relative to m_Start (or the center of the via)
wxPoint rel_pos = aPosition - m_Start; 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; SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
virtual 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;
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
/** /**
* Function GetVia * Function GetVia
@ -411,9 +410,8 @@ public:
const wxPoint GetPosition() const override { return m_Start; } const wxPoint GetPosition() const override { return m_Start; }
void SetPosition( const wxPoint& aPoint ) override { m_Start = aPoint; m_End = aPoint; } void SetPosition( const wxPoint& aPoint ) override { m_Start = aPoint; m_End = aPoint; }
virtual 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;
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
wxString GetClass() 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 // Normally accuracy is zoom-relative, but for the generic HitTest we just use
// a fixed (small) value. // 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 ); return HitTestForCorner( aPosition, accuracy * 2 ) || HitTestForEdge( aPosition, accuracy );
} }

View File

@ -268,7 +268,7 @@ public:
* @param aPosition the wxPoint to test * @param aPosition the wxPoint to test
* @return bool - true if a hit, else false * @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 * Function HitTest

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * 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) 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -22,10 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file class_netinfo.h
*/
/* /*
* Classes to handle info on nets * Classes to handle info on nets
*/ */

View File

@ -53,6 +53,11 @@ public:
/// @copydoc VIEW_ITEM::ViewGetLayers() /// @copydoc VIEW_ITEM::ViewGetLayers()
void ViewGetLayers( int aLayers[], int& aCount ) const override; 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) #if defined(DEBUG)
/// @copydoc EDA_ITEM::Show() /// @copydoc EDA_ITEM::Show()
void Show( int x, std::ostream& st ) const override 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 ); BOARD_COMMIT commit( m_frame );
// Build the undo list & add items to the current view // 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 ) if( m_editModules )
{
wxASSERT( item->Type() == PCB_MODULE_EDGE_T || item->Type() == PCB_MODULE_TEXT_T ); wxASSERT( item->Type() == PCB_MODULE_EDGE_T || item->Type() == PCB_MODULE_TEXT_T );
}
else else
{
wxASSERT( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T ); wxASSERT( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T );
}
if( dlg.IsPlacementInteractive() ) if( dlg.IsPlacementInteractive() )
preview.Add( item ); preview.Add( item );
else else
commit.Add( item ); commit.Add( item );
it->release(); ptr.release();
} }
if( !dlg.IsPlacementInteractive() ) if( !dlg.IsPlacementInteractive() )
@ -811,7 +807,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = m_controls->GetCursorPosition(); VECTOR2I cursorPos = m_controls->GetCursorPosition();
VECTOR2I delta = cursorPos - firstItem->GetPosition(); VECTOR2I delta = cursorPos - firstItem->GetPosition();
for( auto item : preview ) for( EDA_ITEM* item : preview )
static_cast<BOARD_ITEM*>( item )->Move( (wxPoint) delta ); static_cast<BOARD_ITEM*>( item )->Move( (wxPoint) delta );
m_view->Update( &preview ); m_view->Update( &preview );
@ -890,8 +886,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR ); SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR );
Activate(); Activate();
m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL, m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL, _( "Place the footprint anchor" ) );
_( "Place the footprint anchor" ) );
m_controls->ShowCursor( true ); m_controls->ShowCursor( true );
m_controls->SetSnapping( 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() ); auto curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
std::vector<BOARD_ITEM*> sel_items; std::vector<BOARD_ITEM*> sel_items;
for( auto it : selection ) for( EDA_ITEM* item : selection )
{ {
if( auto item = dynamic_cast<BOARD_ITEM*>( it ) ) BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
{ MODULE* module = dynamic_cast<MODULE*>( item );
sel_items.push_back( item );
if( auto mod = dyn_cast<MODULE*>( item ) ) if( boardItem )
{ sel_items.push_back( boardItem );
for( auto pad : mod->Pads() )
sel_items.push_back( pad ); 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; prevPos = m_cursor;
// Drag items to the current cursor position // Drag items to the current cursor position
for( auto item : selection ) for( EDA_ITEM* item : selection )
{ {
// Don't double move footprint pads, fields, etc. // Don't double move footprint pads, fields, etc.
if( item->GetParent() && item->GetParent()->IsSelected() ) 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::selectionModified, false );
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false ); m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
} }
else if( evt->IsCancel() || evt->IsActivate() ) 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 // When editing modules, all items have the same parent
if( EditingModules() ) if( EditingModules() )
{
m_commit->Modify( selection.Front() ); m_commit->Modify( selection.Front() );
}
for( auto item : selection ) 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 // When editing modules, all items have the same parent
if( EditingModules() ) if( EditingModules() )
{
m_commit->Modify( selection.Front() ); m_commit->Modify( selection.Front() );
}
for( auto item : selection ) for( EDA_ITEM* item : selection )
{ {
// only modify items we can mirror // only modify items we can mirror
switch( item->Type() ) switch( item->Type() )
@ -851,11 +847,9 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
// When editing modules, all items have the same parent // When editing modules, all items have the same parent
if( EditingModules() ) if( EditingModules() )
{
m_commit->Modify( selection.Front() ); m_commit->Modify( selection.Front() );
}
for( auto item : selection ) for( EDA_ITEM* item : selection )
{ {
if( !item->IsNew() && !EditingModules() ) if( !item->IsNew() && !EditingModules() )
m_commit->Modify( item ); 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 we are in a "Cut" operation, then the copied selection exists already
if( isCut ) if( isCut )
{
selectionCopy = m_selectionTool->GetSelection(); selectionCopy = m_selectionTool->GetSelection();
}
else else
{
selectionCopy = m_selectionTool->RequestSelection( selectionCopy = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector ) []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); } ); { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); } );
}
bool isHover = selectionCopy.IsHover(); 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 // As we are about to remove items, they have to be removed from the selection first
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
for( auto item : selectionCopy ) for( EDA_ITEM* item : selectionCopy )
{ {
if( m_editModules ) if( m_editModules )
{ {
@ -1020,11 +1018,9 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
// When editing modules, all items have the same parent // When editing modules, all items have the same parent
if( EditingModules() ) if( EditingModules() )
{
m_commit->Modify( selection.Front() ); m_commit->Modify( selection.Front() );
}
for( auto selItem : selection ) for( EDA_ITEM* selItem : selection )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem ); 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 // Each selected item is duplicated and pushed to new_items list
// Old selection is cleared, and new items are then selected. // Old selection is cleared, and new items are then selected.
for( auto item : selection ) for( EDA_ITEM* item : selection )
{ {
if( !item ) if( !item )
continue; continue;
@ -1134,8 +1130,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
if( !selection.Empty() ) if( !selection.Empty() )
{ {
editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ), editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
(int) new_items.size() ) ); (int) new_items.size() ) );
// If items were duplicated, pick them up // If items were duplicated, pick them up
// this works well for "dropping" copies around and pushes the commit // 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_menu( *this ),
m_priv( std::make_unique<PRIV>() ) m_priv( std::make_unique<PRIV>() )
{ {
} }
@ -234,9 +233,7 @@ bool SELECTION_TOOL::Init()
menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 ); menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 );
if( frame ) if( frame )
{
m_menu.AddStandardSubMenus( frame ); m_menu.AddStandardSubMenus( frame );
}
return true; return true;
} }
@ -256,8 +253,10 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
getView()->GetPainter()->GetSettings()->SetHighlight( false ); getView()->GetPainter()->GetSettings()->SetHighlight( false );
} }
else else
{
// Restore previous properties of selected items and remove them from containers // Restore previous properties of selected items and remove them from containers
clearSelection(); clearSelection();
}
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
view()->Remove( &m_selection ); 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, SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter,
std::vector<BOARD_ITEM*>* aFiltered, bool aConfirmLockedItems ) std::vector<BOARD_ITEM*>* aFiltered, bool aConfirmLockedItems )
{ {
@ -666,27 +656,12 @@ bool SELECTION_TOOL::selectMultiple()
if( !item || !selectable( item ) ) if( !item || !selectable( item ) )
continue; continue;
if( windowSelection ) if( item->HitTest( selectionRect, windowSelection ) )
{ {
BOX2I bbox = getRect( item ); if( m_subtractive )
unselect( item );
if( selectionBox.Contains( bbox ) ) else
{ select( item );
if( m_subtractive )
unselect( item );
else
select( item );
}
}
else
{
if( item->HitTest( selectionRect, false ) )
{
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 ) static double calcArea( const BOARD_ITEM* aItem )
{ {
if( aItem->Type() == PCB_TRACE_T ) if( aItem->Type() == PCB_TRACE_T )