From fd546da640333a7bb1b632d233e9bb113340cfad Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 5 May 2019 11:33:34 +0100 Subject: [PATCH] Homogenize hit testing and selection return types. Prep work for sharing SCH_SELECTION_TOOL with LibEdit. --- common/geometry/shape_line_chain.cpp | 29 ++++++---- common/marker_base.cpp | 5 +- eeschema/lib_arc.cpp | 46 ++++++++-------- eeschema/lib_arc.h | 14 +---- eeschema/lib_bezier.cpp | 42 +++++++------- eeschema/lib_bezier.h | 7 +-- eeschema/lib_circle.cpp | 30 +++++----- eeschema/lib_circle.h | 10 +--- eeschema/lib_collectors.cpp | 2 +- eeschema/lib_draw_item.cpp | 17 ++++++ eeschema/lib_draw_item.h | 20 +++---- eeschema/lib_field.cpp | 20 ++----- eeschema/lib_field.h | 8 +-- eeschema/lib_pin.cpp | 20 +------ eeschema/lib_pin.h | 4 +- eeschema/lib_polyline.cpp | 42 +++++++------- eeschema/lib_polyline.h | 9 +-- eeschema/lib_rectangle.cpp | 30 +++------- eeschema/lib_rectangle.h | 6 +- eeschema/lib_text.cpp | 14 ++--- eeschema/lib_text.h | 8 +-- eeschema/sch_bitmap.h | 4 +- eeschema/sch_bus_entry.h | 6 +- eeschema/sch_component.h | 4 +- eeschema/sch_field.h | 6 +- eeschema/sch_item_struct.h | 29 ---------- eeschema/sch_junction.h | 4 +- eeschema/sch_line.h | 4 +- eeschema/sch_marker.cpp | 2 +- eeschema/sch_marker.h | 2 +- eeschema/sch_no_connect.h | 4 +- eeschema/sch_pin.cpp | 5 +- eeschema/sch_pin.h | 2 +- eeschema/sch_sheet.cpp | 2 +- eeschema/sch_sheet.h | 4 +- eeschema/sch_text.h | 4 +- eeschema/tools/sch_drawing_tool.cpp | 6 +- eeschema/tools/sch_edit_tool.cpp | 30 +++++----- eeschema/tools/sch_edit_tool.h | 1 - eeschema/tools/sch_editor_control.cpp | 8 +-- eeschema/tools/sch_selection_tool.cpp | 64 +++++++--------------- eeschema/tools/sch_selection_tool.h | 6 +- gerbview/block.cpp | 2 +- gerbview/gerber_draw_item.cpp | 4 +- gerbview/gerber_draw_item.h | 4 +- gerbview/tools/gerbview_selection_tool.cpp | 25 ++------- include/base_struct.h | 20 ++++++- include/class_board_item.h | 21 ------- include/eda_text.h | 2 +- include/geometry/shape_line_chain.h | 8 +-- include/marker_base.h | 2 +- pcbnew/block_footprint_editor.cpp | 2 +- pcbnew/class_board.h | 5 +- pcbnew/class_dimension.cpp | 4 +- pcbnew/class_dimension.h | 15 +++-- pcbnew/class_drawsegment.cpp | 16 +++--- pcbnew/class_drawsegment.h | 15 ++--- pcbnew/class_marker_pcb.h | 4 +- pcbnew/class_module.cpp | 11 ++-- pcbnew/class_module.h | 6 +- pcbnew/class_pad.cpp | 2 +- pcbnew/class_pad.h | 3 +- pcbnew/class_pcb_target.cpp | 4 +- pcbnew/class_pcb_target.h | 8 +-- pcbnew/class_pcb_text.h | 6 +- pcbnew/class_text_mod.cpp | 4 -- pcbnew/class_text_mod.h | 11 ++-- pcbnew/class_track.cpp | 8 +-- pcbnew/class_track.h | 10 ++-- pcbnew/class_zone.cpp | 4 +- pcbnew/class_zone.h | 2 +- pcbnew/netinfo.h | 6 +- pcbnew/ratsnest_viewitem.h | 5 ++ pcbnew/tools/drawing_tool.cpp | 15 ++--- pcbnew/tools/edit_tool.cpp | 47 +++++++--------- pcbnew/tools/selection_tool.cpp | 48 ++++++---------- 76 files changed, 380 insertions(+), 549 deletions(-) diff --git a/common/geometry/shape_line_chain.cpp b/common/geometry/shape_line_chain.cpp index 7e690ecc0d..bd8bb9223a 100644 --- a/common/geometry/shape_line_chain.cpp +++ b/common/geometry/shape_line_chain.cpp @@ -26,6 +26,7 @@ #include #include +#include #include "clipper.hpp" @@ -348,9 +349,12 @@ int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const } -bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const +bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy ) const { - if( !m_closed || PointCount() < 3 || !BBox().Contains( aP ) ) + BOX2I bbox = BBox(); + bbox.Inflate( aAccuracy ); + + if( !m_closed || PointCount() < 3 || !BBox().Contains( aPt ) ) return false; bool inside = false; @@ -371,37 +375,40 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const if( diff.y != 0 ) { - const int d = rescale( diff.x, ( aP.y - p1.y ), diff.y ); + const int d = rescale( diff.x, ( aPt.y - p1.y ), diff.y ); - if( ( ( p1.y > aP.y ) != ( p2.y > aP.y ) ) && ( aP.x - p1.x < d ) ) + if( ( ( p1.y > aPt.y ) != ( p2.y > aPt.y ) ) && ( aPt.x - p1.x < d ) ) inside = !inside; } } - return inside && !PointOnEdge( aP ); + return inside && !PointOnEdge( aPt, aAccuracy ); } -bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const +bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aPt, int aAccuracy ) const { - return EdgeContainingPoint( aP ) >= 0; + return EdgeContainingPoint( aPt, aAccuracy ) >= 0; } -int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aP ) const +int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aPt, int aAccuracy ) const { if( !PointCount() ) return -1; else if( PointCount() == 1 ) - return m_points[0] == aP ? 0 : -1; + { + VECTOR2I dist = m_points[0] - aPt; + return ( hypot( dist.x, dist.y ) <= aAccuracy + 1 ) ? 0 : -1; + } for( int i = 0; i < SegmentCount(); i++ ) { const SEG s = CSegment( i ); - if( s.A == aP || s.B == aP ) + if( s.A == aPt || s.B == aPt ) return i; - if( s.Distance( aP ) <= 1 ) + if( s.Distance( aPt ) <= aAccuracy + 1 ) return i; } diff --git a/common/marker_base.cpp b/common/marker_base.cpp index c77cdbb4c5..56dc01bd49 100644 --- a/common/marker_base.cpp +++ b/common/marker_base.cpp @@ -160,9 +160,10 @@ void MARKER_BASE::SetData( int aErrorCode, const wxPoint& aMarkerPos, } -bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition ) const +bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition, int aAccuracy ) const { EDA_RECT bbox = GetBoundingBoxMarker(); + bbox.Inflate( aAccuracy ); // Fast hit test using boundary box. A finer test will be made if requested bool hit = bbox.Contains( aHitPosition ); @@ -172,7 +173,7 @@ bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition ) const SHAPE_LINE_CHAIN polygon; ShapeToPolygon( polygon ); VECTOR2I rel_pos( aHitPosition - m_Pos ); - hit = polygon.PointInside( rel_pos ); + hit = polygon.PointInside( rel_pos, aAccuracy ); } return hit; diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp index d6f6083e1e..ea6f1c69d6 100644 --- a/eeschema/lib_arc.cpp +++ b/eeschema/lib_arc.cpp @@ -99,32 +99,16 @@ LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent ) } -bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) const +bool LIB_ARC::HitTest( const wxPoint& aRefPoint, int aAccuracy ) const { - int mindist = GetPenSize() / 2; - - // Have a minimal tolerance for hit test - if( mindist < MINIMUM_SELECTION_DISTANCE ) - mindist = MINIMUM_SELECTION_DISTANCE; - - return HitTest( aRefPoint, mindist, DefaultTransform ); -} - - -bool LIB_ARC::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const -{ - - if( aThreshold < 0 ) - aThreshold = GetPenSize() / 2; - - // TODO: use aTransMat to calculates parameters - wxPoint relativePosition = aPosition; + int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE ); + wxPoint relativePosition = aRefPoint; relativePosition.y = -relativePosition.y; // reverse Y axis int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) ); - if( abs( distance - m_Radius ) > aThreshold ) + if( abs( distance - m_Radius ) > mindist ) return false; // We are on the circle, ensure we are only on the arc, i.e. between @@ -151,8 +135,26 @@ bool LIB_ARC::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM // When the cross products have a different sign, the point lies in sector // also check, if the reference is near start or end point return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) || - HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) || - ( crossProductStart <= 0 && crossProductEnd >= 0 ); + HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) || + ( crossProductStart <= 0 && crossProductEnd >= 0 ); +} + + +bool LIB_ARC::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +{ + if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) ) + return false; + + EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect ); + + if ( aAccuracy ) + rect.Inflate( aAccuracy ); + + if( aContained ) + return rect.Contains( GetBoundingBox() ); + + return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse for filled arcs, + // egregiously coarse for unfilled... } diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h index 5df62c2498..2fb8c1873b 100644 --- a/eeschema/lib_arc.h +++ b/eeschema/lib_arc.h @@ -90,9 +90,8 @@ public: return _( "Arc" ); } - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const wxPoint& aPosition, int aThreshold, const TRANSFORM& aTransform ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; const EDA_RECT GetBoundingBox() const override; @@ -101,9 +100,7 @@ public: int GetPenSize() const override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; - bool ContinueEdit( const wxPoint aNextPoint ) override; - void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void SetOffset( const wxPoint& aOffset ) override; @@ -115,7 +112,6 @@ public: wxPoint GetPosition() const override { return m_Pos; } void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; @@ -124,27 +120,21 @@ public: const TRANSFORM& aTransform ) override; int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } void SetRadius( int aRadius ) { m_Radius = aRadius; } - int GetRadius() const { return m_Radius; } void SetFirstRadiusAngle( int aAngle ) { m_t1 = aAngle; } - int GetFirstRadiusAngle() const { return m_t1; } void SetSecondRadiusAngle( int aAngle ) { m_t2 = aAngle; } - int GetSecondRadiusAngle() const { return m_t2; } wxPoint GetStart() const { return m_ArcStart; } - void SetStart( const wxPoint& aPoint ) { m_ArcStart = aPoint; } wxPoint GetEnd() const { return m_ArcEnd; } - void SetEnd( const wxPoint& aPoint ) { m_ArcEnd = aPoint; } /** diff --git a/eeschema/lib_bezier.cpp b/eeschema/lib_bezier.cpp index 43fe71cac5..b43509b35d 100644 --- a/eeschema/lib_bezier.cpp +++ b/eeschema/lib_bezier.cpp @@ -266,31 +266,17 @@ void LIB_BEZIER::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& } -bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) const -{ - int mindist = GetPenSize() / 2; - - // Have a minimal tolerance for hit test - if ( mindist < MINIMUM_SELECTION_DISTANCE ) - mindist = MINIMUM_SELECTION_DISTANCE; - - return HitTest( aRefPos, mindist, DefaultTransform ); -} - - -bool LIB_BEZIER::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const +bool LIB_BEZIER::HitTest( const wxPoint& aRefPos, int aAccuracy ) const { + int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE ); wxPoint start, end; - if( aThreshold < 0 ) - aThreshold = GetPenSize() / 2; - for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) { - start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] ); - end = aTransform.TransformCoordinate( m_PolyPoints[ii] ); + start = DefaultTransform.TransformCoordinate( m_PolyPoints[ii - 1] ); + end = DefaultTransform.TransformCoordinate( m_PolyPoints[ii] ); - if ( TestSegmentHit( aPosRef, start, end, aThreshold ) ) + if ( TestSegmentHit( aRefPos, start, end, mindist ) ) return true; } @@ -298,6 +284,24 @@ bool LIB_BEZIER::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFOR } +bool LIB_BEZIER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +{ + if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) ) + return false; + + EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect ); + + if ( aAccuracy ) + rect.Inflate( aAccuracy ); + + if( aContained ) + return rect.Contains( GetBoundingBox() ); + + return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse for filled beziers, + // egregiously coarse for unfilled... +} + + const EDA_RECT LIB_BEZIER::GetBoundingBox() const { EDA_RECT rect; diff --git a/eeschema/lib_bezier.h b/eeschema/lib_bezier.h index d4d9fba8ab..29be7f0649 100644 --- a/eeschema/lib_bezier.h +++ b/eeschema/lib_bezier.h @@ -78,9 +78,8 @@ public: return m_BezierPoints; } - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; const EDA_RECT GetBoundingBox() const override; @@ -91,7 +90,6 @@ public: wxPoint GetPosition() const override; void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; @@ -100,7 +98,6 @@ public: const TRANSFORM& aTransform ) override; int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } int GetPenSize( ) const override; diff --git a/eeschema/lib_circle.cpp b/eeschema/lib_circle.cpp index 8993996d04..5afc82e6b0 100644 --- a/eeschema/lib_circle.cpp +++ b/eeschema/lib_circle.cpp @@ -52,28 +52,32 @@ LIB_CIRCLE::LIB_CIRCLE( LIB_PART* aParent ) : } -bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) const +bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef, int aAccuracy ) const { - int mindist = GetPenSize() / 2; + int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE ); + int dist = KiROUND( GetLineLength( aPosRef, DefaultTransform.TransformCoordinate( m_Pos ) ) ); - // Have a minimal tolerance for hit test - if( mindist < MINIMUM_SELECTION_DISTANCE ) - mindist = MINIMUM_SELECTION_DISTANCE; + if( abs( dist - m_Radius ) <= mindist ) + return true; - return HitTest( aPosRef, mindist, DefaultTransform ); + return false; } -bool LIB_CIRCLE::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const +bool LIB_CIRCLE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { - if( aThreshold < 0 ) - aThreshold = GetPenSize() / 2; + if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) ) + return false; - int dist = KiROUND( GetLineLength( aPosRef, aTransform.TransformCoordinate( m_Pos ) ) ); + EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect ); - if( abs( dist - m_Radius ) <= aThreshold ) - return true; - return false; + if ( aAccuracy ) + rect.Inflate( aAccuracy ); + + if( aContained ) + return rect.Contains( GetBoundingBox() ); + + return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse... } diff --git a/eeschema/lib_circle.h b/eeschema/lib_circle.h index ace76a0b16..e2ea25f98a 100644 --- a/eeschema/lib_circle.h +++ b/eeschema/lib_circle.h @@ -60,9 +60,8 @@ public: return _( "Circle" ); } - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; int GetPenSize( ) const override; @@ -71,9 +70,7 @@ public: void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; - bool ContinueEdit( const wxPoint aNextPoint ) override; - void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void SetOffset( const wxPoint& aOffset ) override; @@ -85,7 +82,6 @@ public: wxPoint GetPosition() const override { return m_Pos; } void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; @@ -94,11 +90,9 @@ public: const TRANSFORM& aTransform ) override; int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } void SetRadius( int aRadius ) { m_Radius = aRadius; } - int GetRadius() const { return m_Radius; } wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; diff --git a/eeschema/lib_collectors.cpp b/eeschema/lib_collectors.cpp index 612cfb0dde..e8ac195710 100644 --- a/eeschema/lib_collectors.cpp +++ b/eeschema/lib_collectors.cpp @@ -114,7 +114,7 @@ SEARCH_RESULT LIB_COLLECTOR::Inspect( EDA_ITEM* aItem, void* testData ) if( ( m_data.m_unit && item->GetUnit() && ( m_data.m_unit != item->GetUnit() ) ) || ( m_data.m_convert && item->GetConvert() && ( m_data.m_convert != item->GetConvert() ) ) - || !item->HitTest( m_RefPos, -1, DefaultTransform ) ) + || !item->HitTest( m_RefPos ) ) return SEARCH_CONTINUE; Append( aItem ); diff --git a/eeschema/lib_draw_item.cpp b/eeschema/lib_draw_item.cpp index cb8d8b5fd0..bfc7c58492 100644 --- a/eeschema/lib_draw_item.cpp +++ b/eeschema/lib_draw_item.cpp @@ -107,6 +107,23 @@ bool LIB_ITEM::operator<( const LIB_ITEM& aOther ) const } +bool LIB_ITEM::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +{ + if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) ) + return false; + + EDA_RECT rect = DefaultTransform.TransformCoordinate( aRect ); + + if ( aAccuracy ) + rect.Inflate( aAccuracy ); + + if( aContained ) + return rect.Contains( GetBoundingBox() ); + + return rect.Intersects( GetBoundingBox() ); +} + + void LIB_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, void* aData, const TRANSFORM& aTransform ) { diff --git a/eeschema/lib_draw_item.h b/eeschema/lib_draw_item.h index 1e88780584..8cb0b30b7c 100644 --- a/eeschema/lib_draw_item.h +++ b/eeschema/lib_draw_item.h @@ -201,27 +201,21 @@ public: */ virtual int GetPenSize() const = 0; - LIB_PART* GetParent() const + LIB_PART* GetParent() const { - return (LIB_PART *)m_Parent; + return (LIB_PART*) m_Parent; } void ViewGetLayers( int aLayers[], int& aCount ) const override; - virtual bool HitTest( const wxPoint& aPosition ) const override + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override { - return EDA_ITEM::HitTest( aPosition ); + // This is just here to prevent annoying compiler warnings about hidden overloaded + // virtual functions + return EDA_ITEM::HitTest( aPosition, aAccuracy ); } - /** - * @param aPosition A wxPoint to test. - * @param aThreshold Maximum distance to this object (usually the half thickness of a line) - * if < 0, it will be automatically set to half pen size when locating - * lines or arcs and set to 0 for other items. - * @param aTransform The transform matrix. - * @return True if the point \a aPosition is near this object - */ - virtual bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const = 0; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; /** * @return the boundary box for this, in library coordinates diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index c64c01c1cd..cd4e61fb88 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -156,22 +156,12 @@ void LIB_FIELD::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& a } -bool LIB_FIELD::HitTest( const wxPoint& aPosition ) const +bool LIB_FIELD::HitTest( const wxPoint& aPosition, int aAccuracy ) const { - // Because HitTest is mainly used to select the field - // return always false if this field is void + // Because HitTest is mainly used to select the field return false if it is void if( IsVoid() ) return false; - return HitTest( aPosition, 0, DefaultTransform ); -} - - -bool LIB_FIELD::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const -{ - if( aThreshold < 0 ) - aThreshold = 0; - // Build a temporary copy of the text for hit testing EDA_TEXT tmp_text( *this ); @@ -188,16 +178,16 @@ bool LIB_FIELD::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFO tmp_text.SetText( extended_text ); } - tmp_text.SetTextPos( aTransform.TransformCoordinate( GetTextPos() ) ); + tmp_text.SetTextPos( DefaultTransform.TransformCoordinate( GetTextPos() ) ); /* The text orientation may need to be flipped if the * transformation matrix causes xy axes to be flipped. * this simple algo works only for schematic matrix (rot 90 or/and mirror) */ - bool t1 = ( aTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 ); + bool t1 = ( DefaultTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 ); tmp_text.SetTextAngle( t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT ); - return tmp_text.TextHitTest( aPosition ); + return tmp_text.TextHitTest( aPosition, aAccuracy ); } diff --git a/eeschema/lib_field.h b/eeschema/lib_field.h index 5fd127cbe1..aa71977f16 100644 --- a/eeschema/lib_field.h +++ b/eeschema/lib_field.h @@ -168,9 +168,7 @@ public: void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; void operator=( const LIB_FIELD& field ); @@ -191,9 +189,7 @@ public: COLOR4D GetDefaultColor() override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; - bool ContinueEdit( const wxPoint aNextPoint ) override; - void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void Rotate() override; @@ -220,7 +216,6 @@ public: wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); } void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; @@ -229,7 +224,6 @@ public: const TRANSFORM& aTransform ) override; int GetWidth() const override { return GetThickness(); } - void SetWidth( int aWidth ) override { SetThickness( aWidth ); } wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index ecb246aaf0..ccb2de9fb4 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -538,27 +538,11 @@ void LIB_PIN::EnableEditMode( bool aEnable, bool aEditPinByPin ) } -bool LIB_PIN::HitTest( const wxPoint& aPosition ) const +bool LIB_PIN::HitTest( const wxPoint& aPosition, int aAccuracy ) const { - return HitTest( aPosition, 0, DefaultTransform ); -} - - -bool LIB_PIN::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const -{ - if( aThreshold < 0 ) - aThreshold = 0; - - TRANSFORM transform = DefaultTransform; - DefaultTransform = aTransform; - EDA_RECT rect = GetBoundingBox(); - rect.Inflate( aThreshold ); - //Restore matrix - DefaultTransform = transform; - - return rect.Contains( aPosition ); + return rect.Inflate( aAccuracy ).Contains( aPosition ); } diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h index c6488ea193..e93eb06d04 100644 --- a/eeschema/lib_pin.h +++ b/eeschema/lib_pin.h @@ -110,9 +110,7 @@ public: void Show( int nestLevel, std::ostream& os ) const override; #endif - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; diff --git a/eeschema/lib_polyline.cpp b/eeschema/lib_polyline.cpp index 75e3dede24..9ae01c0313 100644 --- a/eeschema/lib_polyline.cpp +++ b/eeschema/lib_polyline.cpp @@ -214,31 +214,17 @@ void LIB_POLYLINE::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint } -bool LIB_POLYLINE::HitTest( const wxPoint& aPosition ) const -{ - int mindist = GetPenSize() / 2; - - // Have a minimal tolerance for hit test - if( mindist < MINIMUM_SELECTION_DISTANCE ) - mindist = MINIMUM_SELECTION_DISTANCE; - - return HitTest( aPosition, mindist, DefaultTransform ); -} - - -bool LIB_POLYLINE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const +bool LIB_POLYLINE::HitTest( const wxPoint& aPosition, int aAccuracy ) const { + int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE ); wxPoint start, end; - if( aThreshold < 0 ) - aThreshold = GetPenSize() / 2; - for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) { - start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] ); - end = aTransform.TransformCoordinate( m_PolyPoints[ii] ); + start = DefaultTransform.TransformCoordinate( m_PolyPoints[ii - 1] ); + end = DefaultTransform.TransformCoordinate( m_PolyPoints[ii] ); - if( TestSegmentHit( aPosition, start, end, aThreshold ) ) + if( TestSegmentHit( aPosition, start, end, mindist ) ) return true; } @@ -246,6 +232,24 @@ bool LIB_POLYLINE::HitTest( const wxPoint &aPosition, int aThreshold, const TRAN } +bool LIB_POLYLINE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +{ + if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) ) + return false; + + EDA_RECT rect = aRect; + + if ( aAccuracy ) + rect.Inflate( aAccuracy ); + + if( aContained ) + return rect.Contains( GetBoundingBox() ); + + return rect.Intersects( GetBoundingBox() ); // JEY TODO somewhat coarse for filled polylines, + // egregiously coarse for unfilled... +} + + const EDA_RECT LIB_POLYLINE::GetBoundingBox() const { EDA_RECT rect; diff --git a/eeschema/lib_polyline.h b/eeschema/lib_polyline.h index d795636301..d79e54c5a6 100644 --- a/eeschema/lib_polyline.h +++ b/eeschema/lib_polyline.h @@ -76,9 +76,8 @@ public: */ unsigned GetCornerCount() const { return m_PolyPoints.size(); } - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; const EDA_RECT GetBoundingBox() const override; @@ -87,9 +86,7 @@ public: void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; - bool ContinueEdit( const wxPoint aNextPoint ) override; - void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void SetOffset( const wxPoint& aOffset ) override; @@ -101,7 +98,6 @@ public: wxPoint GetPosition() const override { return m_PolyPoints[0]; } void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; @@ -110,7 +106,6 @@ public: const TRANSFORM& aTransform ) override; int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; diff --git a/eeschema/lib_rectangle.cpp b/eeschema/lib_rectangle.cpp index 8d6a70b96d..dbb8c41fa0 100644 --- a/eeschema/lib_rectangle.cpp +++ b/eeschema/lib_rectangle.cpp @@ -219,25 +219,11 @@ const EDA_RECT LIB_RECTANGLE::GetBoundingBox() const } -bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition ) const +bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition, int aAccuracy ) const { - int mindist = ( GetPenSize() / 2 ) + 1; - - // Have a minimal tolerance for hit test - if( mindist < MINIMUM_SELECTION_DISTANCE ) - mindist = MINIMUM_SELECTION_DISTANCE; - - return HitTest( aPosition, mindist, DefaultTransform ); -} - - -bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const -{ - if( aThreshold < 0 ) - aThreshold = GetPenSize() / 2; - - wxPoint actualStart = aTransform.TransformCoordinate( m_Pos ); - wxPoint actualEnd = aTransform.TransformCoordinate( m_End ); + int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE ); + wxPoint actualStart = DefaultTransform.TransformCoordinate( m_Pos ); + wxPoint actualEnd = DefaultTransform.TransformCoordinate( m_End ); // locate lower segment wxPoint start, end; @@ -246,21 +232,21 @@ bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRA end.x = actualEnd.x; end.y = actualStart.y; - if( TestSegmentHit( aPosition, start, end, aThreshold ) ) + if( TestSegmentHit( aPosition, start, end, mindist ) ) return true; // locate right segment start.x = actualEnd.x; end.y = actualEnd.y; - if( TestSegmentHit( aPosition, start, end, aThreshold ) ) + if( TestSegmentHit( aPosition, start, end, mindist ) ) return true; // locate upper segment start.y = actualEnd.y; end.x = actualStart.x; - if( TestSegmentHit( aPosition, start, end, aThreshold ) ) + if( TestSegmentHit( aPosition, start, end, mindist ) ) return true; // locate left segment @@ -268,7 +254,7 @@ bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRA end.x = actualStart.x; end.y = actualEnd.y; - if( TestSegmentHit( aPosition, start, end, aThreshold ) ) + if( TestSegmentHit( aPosition, start, end, mindist ) ) return true; return false; diff --git a/eeschema/lib_rectangle.h b/eeschema/lib_rectangle.h index abb6b248a3..b1fa1cc60e 100644 --- a/eeschema/lib_rectangle.h +++ b/eeschema/lib_rectangle.h @@ -65,9 +65,7 @@ public: void SetEndPosition( const wxPoint& aPosition ) { m_End = aPosition; } - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; int GetPenSize( ) const override; @@ -76,9 +74,7 @@ public: void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) override; - bool ContinueEdit( const wxPoint aNextPoint ) override; - void EndEdit( const wxPoint& aPosition, bool aAbort = false ) override; void SetOffset( const wxPoint& aOffset ) override; diff --git a/eeschema/lib_text.cpp b/eeschema/lib_text.cpp index 55e59b69fd..ce2e82f3fd 100644 --- a/eeschema/lib_text.cpp +++ b/eeschema/lib_text.cpp @@ -59,25 +59,19 @@ void LIB_TEXT::ViewGetLayers( int aLayers[], int& aCount ) const } -bool LIB_TEXT::HitTest( const wxPoint& aPosition ) const -{ - return HitTest( aPosition, 0, DefaultTransform ); -} - - -bool LIB_TEXT::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const +bool LIB_TEXT::HitTest( const wxPoint& aPosition, int aAccuracy ) const { EDA_TEXT tmp_text( *this ); - tmp_text.SetTextPos( aTransform.TransformCoordinate( GetTextPos() ) ); + tmp_text.SetTextPos( DefaultTransform.TransformCoordinate( GetTextPos() ) ); /* The text orientation may need to be flipped if the * transformation matrix causes xy axes to be flipped. * this simple algo works only for schematic matrix (rot 90 or/and mirror) */ - bool t1 = ( aTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 ); + bool t1 = ( DefaultTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 ); tmp_text.SetTextAngle( t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT ); - return tmp_text.TextHitTest( aPosition ); + return tmp_text.TextHitTest( aPosition, aAccuracy ); } diff --git a/eeschema/lib_text.h b/eeschema/lib_text.h index bbd2df0b0e..c16401c475 100644 --- a/eeschema/lib_text.h +++ b/eeschema/lib_text.h @@ -83,13 +83,11 @@ public: */ void SetText( const wxString& aText ) override; - bool HitTest( const wxPoint& aPosition ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; - bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const override; - - bool HitTest( const EDA_RECT& aRect ) const + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override { - return TextHitTest( aRect ); + return TextHitTest( aRect, aContained, aAccuracy ); } diff --git a/eeschema/sch_bitmap.h b/eeschema/sch_bitmap.h index 32cd31ce7f..d1b8a455b1 100644 --- a/eeschema/sch_bitmap.h +++ b/eeschema/sch_bitmap.h @@ -152,8 +152,8 @@ public: wxPoint GetPosition() const override { return m_pos; } void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_bus_entry.h b/eeschema/sch_bus_entry.h index 4fc189fce9..777ebef96e 100644 --- a/eeschema/sch_bus_entry.h +++ b/eeschema/sch_bus_entry.h @@ -105,12 +105,10 @@ public: void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const override; wxPoint GetPosition() const override { return m_pos; } - void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 5e194bd60c..9b7b19dfec 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -611,8 +611,8 @@ public: wxPoint GetPosition() const override { return m_Pos; } void SetPosition( const wxPoint& aPosition ) override { Move( aPosition - m_Pos ); } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h index b4d7c49e45..bc66109499 100644 --- a/eeschema/sch_field.h +++ b/eeschema/sch_field.h @@ -195,12 +195,10 @@ public: wxPoint GetLibPosition() const { return EDA_TEXT::GetTextPos(); } wxPoint GetPosition() const override; - void SetPosition( const wxPoint& aPosition ) override; - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_item_struct.h b/eeschema/sch_item_struct.h index 82241a3d20..90122e67b5 100644 --- a/eeschema/sch_item_struct.h +++ b/eeschema/sch_item_struct.h @@ -363,35 +363,6 @@ public: void SetConnectivityDirty( bool aDirty = true ) { m_connectivity_dirty = aDirty; } - virtual bool HitTest( const wxPoint& aPosition ) const override - { - return HitTest( aPosition, 0 ); - } - - /** - * Function HitTest - * tests if \a aPosition is contained within or on the bounding box of an item. - * - * @param aPosition A reference to a wxPoint object containing the coordinates to test. - * @param aAccuracy Increase the item bounding box by this amount. - * @return True if \a aPosition is within the item bounding box. - */ - virtual bool HitTest( const wxPoint& aPosition, int aAccuracy ) const { return false; } - - /** - * Function HitTest - * tests if \a aRect intersects or is contained within the bounding box of an item. - * - * @param aRect A reference to a EDA_RECT object containing the rectangle to test. - * @param aContained Set to true to test for containment instead of an intersection. - * @param aAccuracy Increase \a aRect by this amount. - * @return True if \a aRect contains or intersects the item bounding box. - */ - virtual bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const - { - return false; - } - virtual bool CanIncrementLabel() const { return false; } /** diff --git a/eeschema/sch_junction.h b/eeschema/sch_junction.h index ce6362f6b2..a3bc3a4159 100644 --- a/eeschema/sch_junction.h +++ b/eeschema/sch_junction.h @@ -95,8 +95,8 @@ public: wxPoint GetPosition() const override { return m_pos; } void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_line.h b/eeschema/sch_line.h index 57877d8afa..65fea5d0e0 100644 --- a/eeschema/sch_line.h +++ b/eeschema/sch_line.h @@ -189,8 +189,8 @@ public: wxPoint GetPosition() const override { return m_start; } void SetPosition( const wxPoint& aPosition ) override; - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_marker.cpp b/eeschema/sch_marker.cpp index 4a38275a2f..99a5ef4963 100644 --- a/eeschema/sch_marker.cpp +++ b/eeschema/sch_marker.cpp @@ -154,5 +154,5 @@ void SCH_MARKER::MirrorY( int aYaxis_position ) bool SCH_MARKER::HitTest( const wxPoint& aPosition, int aAccuracy ) const { - return HitTestMarker( aPosition ); + return HitTestMarker( aPosition, aAccuracy ); } diff --git a/eeschema/sch_marker.h b/eeschema/sch_marker.h index 1091471257..1a25837c65 100644 --- a/eeschema/sch_marker.h +++ b/eeschema/sch_marker.h @@ -93,7 +93,7 @@ public: wxPoint GetPosition() const override { return m_Pos; } void SetPosition( const wxPoint& aPosition ) override { m_Pos = aPosition; } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; EDA_ITEM* Clone() const override; diff --git a/eeschema/sch_no_connect.h b/eeschema/sch_no_connect.h index 2bba432ea3..405f5f0573 100644 --- a/eeschema/sch_no_connect.h +++ b/eeschema/sch_no_connect.h @@ -101,8 +101,8 @@ public: wxPoint GetPosition() const override { return m_pos; } void SetPosition( const wxPoint& aPosition ) override { m_pos = aPosition; } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_pin.cpp b/eeschema/sch_pin.cpp index d81c1b4a51..02bc6ec0ab 100644 --- a/eeschema/sch_pin.cpp +++ b/eeschema/sch_pin.cpp @@ -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 ); } diff --git a/eeschema/sch_pin.h b/eeschema/sch_pin.h index c83c2a8130..f98c7361cd 100644 --- a/eeschema/sch_pin.h +++ b/eeschema/sch_pin.h @@ -77,7 +77,7 @@ public: void SetPosition( const wxPoint& aPosition ) override { m_position = aPosition; } const EDA_RECT GetBoundingBox() const override; - bool HitTest( const wxPoint& aPosition ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; bool IsDangling() const override { return m_isDangling; } void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; } diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 091bbbb5b6..004b97ad4c 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -372,7 +372,7 @@ SCH_SHEET_PIN* SCH_SHEET::GetPin( const wxPoint& aPosition ) { for( SCH_SHEET_PIN& pin : m_pins ) { - if( pin.HitTest( aPosition, 0 ) ) + if( pin.HitTest( aPosition ) ) return &pin; } diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index b0fab862c5..a249d768ed 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -186,7 +186,7 @@ public: void SetPosition( const wxPoint& aPosition ) override { ConstrainOnEdge( aPosition ); } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; EDA_ITEM* Clone() const override; }; @@ -531,7 +531,7 @@ public: void SetPosition( const wxPoint& aPosition ) override; bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h index 9e8e55790a..47f6f36770 100644 --- a/eeschema/sch_text.h +++ b/eeschema/sch_text.h @@ -190,8 +190,8 @@ public: wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); } void SetPosition( const wxPoint& aPosition ) override { EDA_TEXT::SetTextPos( aPosition ); } - bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; void Plot( PLOTTER* aPlotter ) override; diff --git a/eeschema/tools/sch_drawing_tool.cpp b/eeschema/tools/sch_drawing_tool.cpp index 766e24c8b5..6723673ed5 100644 --- a/eeschema/tools/sch_drawing_tool.cpp +++ b/eeschema/tools/sch_drawing_tool.cpp @@ -636,7 +636,7 @@ int SCH_DRAWING_TOOL::PlaceSchematicText( const TOOL_EVENT& aEvent ) int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) { VECTOR2I cursorPos = m_controls->GetCursorPosition(); - SCH_ITEM* item = nullptr; + EDA_ITEM* item = nullptr; m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true ); m_controls->ShowCursor( true ); @@ -719,7 +719,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) // ... and second click places: else { - m_frame->AddItemToScreenAndUndoList( item ); + m_frame->AddItemToScreenAndUndoList( (SCH_ITEM*) item ); item = nullptr; m_view->ClearPreview(); @@ -749,7 +749,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) } else if( item && ( evt->IsAction( &SCH_ACTIONS::refreshPreview ) || evt->IsMotion() ) ) { - item->SetPosition( (wxPoint)cursorPos ); + static_cast( item )->SetPosition( (wxPoint)cursorPos ); m_view->ClearPreview(); m_view->AddToPreview( item->Clone() ); } diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 9fbe3465c7..a4ce7172ef 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -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(); wxCHECK( selectionTool, false ); aFrame->GetToolManager()->RunAction( SCH_ACTIONS::clearSelection, true ); - SCH_ITEM* item = selectionTool->SelectPoint( aPosition ); + EDA_ITEM* item = selectionTool->SelectPoint( aPosition ); + SCH_ITEM* sch_item = dynamic_cast( item ); + + if( sch_item && sch_item->IsLocked() ) + { + STATUS_TEXT_POPUP statusPopup( aFrame ); + statusPopup.SetText( _( "Item locked." ) ); + statusPopup.Expire( 2000 ); + statusPopup.Popup(); + statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) ); + return true; + } if( item ) - { - if( item->IsLocked() ) - { - STATUS_TEXT_POPUP statusPopup( aFrame ); - statusPopup.SetText( _( "Item locked." ) ); - statusPopup.Expire( 2000 ); - statusPopup.Popup(); - statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) ); - } - else - { - aFrame->GetToolManager()->RunAction( SCH_ACTIONS::doDelete, true ); - } - } + aFrame->GetToolManager()->RunAction( SCH_ACTIONS::doDelete, true ); return true; } diff --git a/eeschema/tools/sch_edit_tool.h b/eeschema/tools/sch_edit_tool.h index 0f5d06cf5f..eb92bac71f 100644 --- a/eeschema/tools/sch_edit_tool.h +++ b/eeschema/tools/sch_edit_tool.h @@ -89,7 +89,6 @@ private: private: SCH_SELECTION_TOOL* m_selectionTool; - KIGFX::VIEW_CONTROLS* m_controls; SCH_EDIT_FRAME* m_frame; /// Menu model displayed by the tool. diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 76c9ee0108..23ceeb0059 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -233,7 +233,7 @@ static bool probeSimulation( SCH_EDIT_FRAME* aFrame, const VECTOR2D& aPosition ) constexpr KICAD_T wiresAndComponents[] = { SCH_LINE_T, SCH_COMPONENT_T, SCH_SHEET_PIN_T, EOT }; SCH_SELECTION_TOOL* selTool = aFrame->GetToolManager()->GetTool(); - SCH_ITEM* item = selTool->SelectPoint( aPosition, wiresAndComponents ); + EDA_ITEM* item = selTool->SelectPoint( aPosition, wiresAndComponents ); if( !item ) return false; @@ -279,14 +279,14 @@ static bool tuneSimulation( SCH_EDIT_FRAME* aFrame, const VECTOR2D& aPosition ) { constexpr KICAD_T fieldsAndComponents[] = { SCH_COMPONENT_T, SCH_FIELD_T, EOT }; SCH_SELECTION_TOOL* selTool = aFrame->GetToolManager()->GetTool(); - SCH_ITEM* item = selTool->SelectPoint( aPosition, fieldsAndComponents ); + EDA_ITEM* item = selTool->SelectPoint( aPosition, fieldsAndComponents ); if( !item ) return false; if( item->Type() != SCH_COMPONENT_T ) { - item = static_cast( item->GetParent() ); + item = item->GetParent(); if( item->Type() != SCH_COMPONENT_T ) return false; @@ -341,7 +341,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) } else { - SCH_ITEM* item = selTool->GetNode( aPosition ); + SCH_ITEM* item = (SCH_ITEM*) selTool->GetNode( aPosition ); if( item && item->Connection( *g_CurrentSheet ) ) netName = item->Connection( *g_CurrentSheet )->Name(); diff --git a/eeschema/tools/sch_selection_tool.cpp b/eeschema/tools/sch_selection_tool.cpp index c5e6cca1a9..e404e83de0 100644 --- a/eeschema/tools/sch_selection_tool.cpp +++ b/eeschema/tools/sch_selection_tool.cpp @@ -343,7 +343,7 @@ int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP; if( component ) - m_frame->SelectUnit( component, unit ); + static_cast( m_frame )->SelectUnit( component, unit ); } } @@ -374,7 +374,7 @@ SELECTION& SCH_SELECTION_TOOL::GetSelection() } -SCH_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList, +EDA_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList, bool* aSelectionCancelledFlag, bool aCheckLocked ) { SCH_COLLECTOR collector; @@ -419,7 +419,7 @@ SCH_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T if( collector.GetCount() == 1 ) { - SCH_ITEM* item = collector[ 0 ]; + EDA_ITEM* item = collector[ 0 ]; toggleSelection( item ); return item; @@ -442,8 +442,8 @@ void SCH_SELECTION_TOOL::guessSelectionCandidates( SCH_COLLECTOR& collector, // all the various overlap and coverage issues that we do in Pcbnew. if( collector.GetCount() == 2 ) { - SCH_ITEM* a = collector[ 0 ]; - SCH_ITEM* b = collector[ 1 ]; + EDA_ITEM* a = collector[ 0 ]; + EDA_ITEM* b = collector[ 1 ]; if( a->GetParent() == b ) collector.Remove( b ); @@ -457,15 +457,6 @@ void SCH_SELECTION_TOOL::guessSelectionCandidates( SCH_COLLECTOR& collector, } -static EDA_RECT getRect( const SCH_ITEM* aItem ) -{ - if( aItem->Type() == SCH_COMPONENT_T ) - return static_cast( aItem )->GetBodyBoundingBox(); - - return aItem->GetBoundingBox(); -} - - SELECTION& SCH_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] ) { if( m_selection.Empty() ) @@ -482,7 +473,7 @@ SELECTION& SCH_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] ) { for( int i = m_selection.GetSize() - 1; i >= 0; --i ) { - SCH_ITEM* item = (SCH_ITEM*) m_selection.GetItem( i ); + EDA_ITEM* item = (EDA_ITEM*) m_selection.GetItem( i ); if( !item->IsType( aFilterList ) ) toggleSelection( item ); @@ -551,39 +542,24 @@ bool SCH_SELECTION_TOOL::selectMultiple() if( view->IsMirroredX() ) windowSelection = !windowSelection; - // Construct an EDA_RECT to determine SCH_ITEM selection + // Construct an EDA_RECT to determine EDA_ITEM selection EDA_RECT selectionRect( (wxPoint)area.GetOrigin(), wxSize( width, height ) ); selectionRect.Normalize(); for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it ) { - SCH_ITEM* item = static_cast( it->first ); + EDA_ITEM* item = static_cast( it->first ); if( !item || !selectable( item ) ) continue; - if( windowSelection ) + if( item->HitTest( selectionRect, windowSelection ) ) { - BOX2I bbox = getRect( item ); - - if( selectionBox.Contains( bbox ) ) - { - if( m_subtractive ) - unselect( item ); - else - select( item ); - } - } - else - { - if( item->HitTest( selectionRect, false ) ) - { - if( m_subtractive ) - unselect( item ); - else - select( item ); - } + if( m_subtractive ) + unselect( item ); + else + select( item ); } } @@ -623,7 +599,7 @@ static KICAD_T nodeTypes[] = }; -SCH_ITEM* SCH_SELECTION_TOOL::GetNode( VECTOR2I aPosition ) +EDA_ITEM* SCH_SELECTION_TOOL::GetNode( VECTOR2I aPosition ) { SCH_COLLECTOR collector; @@ -658,7 +634,7 @@ int SCH_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent ) m_frame->GetScreen()->ClearDrawingState(); m_frame->GetScreen()->MarkConnections( line ); - for( SCH_ITEM* item = m_frame->GetScreen()->GetDrawItems(); item; item = item->Next() ) + for( EDA_ITEM* item = m_frame->GetScreen()->GetDrawItems(); item; item = item->Next() ) { if( item->GetFlags() & CANDIDATE ) select( item ); @@ -673,7 +649,7 @@ int SCH_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent ) int SCH_SELECTION_TOOL::AddItemToSel( const TOOL_EVENT& aEvent ) { - AddItemToSel( aEvent.Parameter() ); + AddItemToSel( aEvent.Parameter() ); return 0; } @@ -714,7 +690,7 @@ void SCH_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode ) int SCH_SELECTION_TOOL::RemoveItemFromSel( const TOOL_EVENT& aEvent ) { - RemoveItemFromSel( aEvent.Parameter() ); + RemoveItemFromSel( aEvent.Parameter() ); return 0; } @@ -774,7 +750,7 @@ int SCH_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent ) bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector ) { - SCH_ITEM* current = nullptr; + EDA_ITEM* current = nullptr; CONTEXT_MENU menu; int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() ); @@ -782,7 +758,7 @@ bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector ) for( int i = 0; i < limit; ++i ) { wxString text; - SCH_ITEM* item = ( *aCollector )[i]; + EDA_ITEM* item = ( *aCollector )[i]; text = item->GetSelectMenuText( m_frame->GetUserUnits() ); wxString menuText = wxString::Format("&%d. %s", i + 1, text ); @@ -883,7 +859,7 @@ void SCH_SELECTION_TOOL::clearSelection() return; while( m_selection.GetSize() ) - unhighlight( static_cast( m_selection.Front() ), SELECTED, &m_selection ); + unhighlight( (EDA_ITEM*) m_selection.Front(), SELECTED, &m_selection ); getView()->Update( &m_selection ); diff --git a/eeschema/tools/sch_selection_tool.h b/eeschema/tools/sch_selection_tool.h index f1527764bd..6c9e7dc718 100644 --- a/eeschema/tools/sch_selection_tool.h +++ b/eeschema/tools/sch_selection_tool.h @@ -100,7 +100,7 @@ public: * was cancelled (for instance, by clicking outside of the disambiguation menu). * @param aCheckLocked indicates if locked items should be excluded */ - SCH_ITEM* SelectPoint( const VECTOR2I& aWhere, + EDA_ITEM* SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList = SCH_COLLECTOR::AllItems, bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false ); @@ -115,7 +115,7 @@ public: void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false ); ///> Find (but don't select) node under cursor - SCH_ITEM* GetNode( VECTOR2I aPosition ); + EDA_ITEM* GetNode( VECTOR2I aPosition ); ///> Select node under cursor int SelectNode( const TOOL_EVENT& aEvent ); @@ -228,7 +228,7 @@ private: void setTransitions() override; private: - SCH_EDIT_FRAME* m_frame; // Pointer to the parent frame + SCH_BASE_FRAME* m_frame; // Pointer to the parent frame SELECTION m_selection; // Current state of selection bool m_additive; // Items should be added to selection (instead of replacing) diff --git a/gerbview/block.cpp b/gerbview/block.cpp index 3a6408116a..3220d8c7b5 100644 --- a/gerbview/block.cpp +++ b/gerbview/block.cpp @@ -213,7 +213,7 @@ void GERBVIEW_FRAME::Block_Move() { GERBER_DRAW_ITEM* gerb_item = item; - if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) ) + if( gerb_item->HitTest( GetScreen()->m_BlockLocate, true ) ) gerb_item->MoveAB( delta ); } } diff --git a/gerbview/gerber_draw_item.cpp b/gerbview/gerber_draw_item.cpp index 289dceff84..258fc89e33 100644 --- a/gerbview/gerber_draw_item.cpp +++ b/gerbview/gerber_draw_item.cpp @@ -791,7 +791,7 @@ BITMAP_DEF GERBER_DRAW_ITEM::GetMenuImage() const } -bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const +bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos, int aAccuracy ) const { // In case the item has a very tiny width defined, allow it to be selected const int MIN_HIT_TEST_RADIUS = Millimeter2iu( 0.01 ); @@ -878,7 +878,7 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const } -bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea ) const +bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea, bool aContained, int aAccuracy ) const { wxPoint pos = GetABPosition( m_Start ); diff --git a/gerbview/gerber_draw_item.h b/gerbview/gerber_draw_item.h index 77e26fe6e7..0b69d83bb1 100644 --- a/gerbview/gerber_draw_item.h +++ b/gerbview/gerber_draw_item.h @@ -263,7 +263,7 @@ public: * @param aRefPos a wxPoint to test * @return bool - true if a hit, else false */ - bool HitTest( const wxPoint& aRefPos ) const override; + bool HitTest( const wxPoint& aRefPos, int aAccuracy = 0 ) const override; /** * Function HitTest (overloaded) @@ -272,7 +272,7 @@ public: * @param aRefArea a wxPoint to test * @return bool - true if a hit, else false */ - bool HitTest( const EDA_RECT& aRefArea ) const; + bool HitTest( const EDA_RECT& aRefArea, bool aContained, int aAccuracy = 0 ) const override; /** * Function GetClass diff --git a/gerbview/tools/gerbview_selection_tool.cpp b/gerbview/tools/gerbview_selection_tool.cpp index 76b048131b..62c41f0a14 100644 --- a/gerbview/tools/gerbview_selection_tool.cpp +++ b/gerbview/tools/gerbview_selection_tool.cpp @@ -424,27 +424,12 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple() * Left > Right : Select objects that are fully enclosed by selection * Right > Left : Select objects that are crossed by selection */ - - if( width >= 0 ) + if( item->HitTest( selectionRect, width >= 0 ) ) { - if( selectionBox.Contains( item->ViewBBox() ) ) - { - if( m_subtractive ) - unselect( item ); - else - select( item ); - } - } - else - { - if( item->HitTest( selectionRect ) ) - { - if( m_subtractive ) - unselect( item ); - else - select( item ); - } - + if( m_subtractive ) + unselect( item ); + else + select( item ); } } diff --git a/include/base_struct.h b/include/base_struct.h index e470fd2ca1..1985613d6f 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -318,16 +318,30 @@ public: /** * Function HitTest - * tests if \a aPosition is contained within or on the bounding area of an item. + * tests if \a aPosition is contained within or on the bounding box of an item. * * @param aPosition A reference to a wxPoint object containing the coordinates to test. - * @return True if \a aPosition is within or on the item bounding area. + * @param aAccuracy Increase the item bounding box by this amount. + * @return True if \a aPosition is within the item bounding box. */ - virtual bool HitTest( const wxPoint& aPosition ) const + virtual bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const { return false; // derived classes should override this function } + /** + * Function HitTest + * tests if \a aRect intersects or is contained within the bounding box of an item. + * + * @param aRect A reference to a EDA_RECT object containing the rectangle to test. + * @param aContained Set to true to test for containment instead of an intersection. + * @param aAccuracy Increase \a aRect by this amount. + * @return True if \a aRect contains or intersects the item bounding box. + */ + virtual bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const + { + return false; // derived classes should override this function + } /** * Function GetBoundingBox diff --git a/include/class_board_item.h b/include/class_board_item.h index 47c67d16b9..09ec22bf37 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -286,27 +286,6 @@ public: */ wxString GetLayerName() const; - virtual bool HitTest( const wxPoint& aPosition ) const override - { - return EDA_ITEM::HitTest( aPosition ); - } - - /** - * Function HitTest - * tests if the \a aRect intersects or contains this object (depending on \a aContained). - * - * @param aRect A reference to an EDA_RECT object containg the area to test. - * @param aContained Test if \a aRect contains this object completly. - * @param aAccuracy Increase the item bounding box by this amount. - * @return bool - True if \a aRect contains this object completly or if \a aRect intersects - * the object and \a aContained is False, otherwise false. - */ - virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0) const - { - return false; // derived classes should override this function - } - - virtual void ViewGetLayers( int aLayers[], int& aCount ) const override; /** diff --git a/include/eda_text.h b/include/eda_text.h index 252351d41f..9f5444a83d 100644 --- a/include/eda_text.h +++ b/include/eda_text.h @@ -303,7 +303,7 @@ public: * @param aAccuracy - Amount to inflate the bounding box. * @return bool - true if a hit, else false */ - virtual bool TextHitTest( const EDA_RECT& aRect, bool aContains = false, int aAccuracy = 0 ) const; + virtual bool TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy = 0 ) const; /** * Function LenSize diff --git a/include/geometry/shape_line_chain.h b/include/geometry/shape_line_chain.h index adcbef0248..665a4e3463 100644 --- a/include/geometry/shape_line_chain.h +++ b/include/geometry/shape_line_chain.h @@ -551,10 +551,10 @@ public: * * Checks if point aP lies inside a polygon (any type) defined by the line chain. * For closed shapes only. - * @param aP point to check + * @param aPt point to check * @return true if the point is inside the shape (edge is not treated as being inside). */ - bool PointInside( const VECTOR2I& aP ) const; + bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0 ) const; /** * Function PointOnEdge() @@ -563,7 +563,7 @@ public: * @param aP point to check * @return true if the point lies on the edge. */ - bool PointOnEdge( const VECTOR2I& aP ) const; + bool PointOnEdge( const VECTOR2I& aP, int aAccuracy = 0 ) const; /** * Function EdgeContainingPoint() @@ -572,7 +572,7 @@ public: * @param aP point to check * @return index of the first edge containing the point, otherwise negative */ - int EdgeContainingPoint( const VECTOR2I& aP ) const; + int EdgeContainingPoint( const VECTOR2I& aP, int aAccuracy = 0 ) const; /** * Function CheckClearance() diff --git a/include/marker_base.h b/include/marker_base.h index d54f80a43f..a3a4839dee 100644 --- a/include/marker_base.h +++ b/include/marker_base.h @@ -256,7 +256,7 @@ public: * @param aHitPosition is the wxPoint to test (in internal units) * @return bool - true if a hit, else false */ - bool HitTestMarker( const wxPoint& aHitPosition ) const; + bool HitTestMarker( const wxPoint& aHitPosition, int aAccuracy ) const; /** * Function GetBoundingBoxMarker diff --git a/pcbnew/block_footprint_editor.cpp b/pcbnew/block_footprint_editor.cpp index 88fc6008e0..3e17154839 100644 --- a/pcbnew/block_footprint_editor.cpp +++ b/pcbnew/block_footprint_editor.cpp @@ -866,7 +866,7 @@ int MarkItemsInBloc( MODULE* module, EDA_RECT& Rect ) switch( item->Type() ) { case PCB_MODULE_EDGE_T: - if( ((EDGE_MODULE*)item )->HitTest( Rect ) ) + if( ((EDGE_MODULE*)item )->HitTest( Rect, false ) ) { item->SetFlags( SELECTED ); ItemsCount++; diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 1132081106..a0f44a072b 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -263,9 +263,8 @@ public: BOARD(); ~BOARD(); - virtual const wxPoint GetPosition() const override; - - virtual void SetPosition( const wxPoint& aPos ) override; + const wxPoint GetPosition() const override; + void SetPosition( const wxPoint& aPos ) override; bool IsEmpty() const { diff --git a/pcbnew/class_dimension.cpp b/pcbnew/class_dimension.cpp index 4fbb5353ee..eb11d1f911 100644 --- a/pcbnew/class_dimension.cpp +++ b/pcbnew/class_dimension.cpp @@ -386,12 +386,12 @@ void DIMENSION::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM } -bool DIMENSION::HitTest( const wxPoint& aPosition ) const +bool DIMENSION::HitTest( const wxPoint& aPosition, int aAccuracy ) const { if( m_Text.TextHitTest( aPosition ) ) return true; - int dist_max = m_Width / 2; + int dist_max = aAccuracy + ( m_Width / 2 ); // Locate SEGMENTS diff --git a/pcbnew/class_dimension.h b/pcbnew/class_dimension.h index fa79427d13..4121cccd48 100644 --- a/pcbnew/class_dimension.h +++ b/pcbnew/class_dimension.h @@ -220,13 +220,12 @@ public: * the layer is not changed * @param axis_pos : vertical axis position */ - void Mirror( const wxPoint& axis_pos ); + void Mirror( const wxPoint& axis_pos ); - void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; + void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; - bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; wxString GetClass() const override { @@ -234,13 +233,13 @@ public: } // Virtual function - const EDA_RECT GetBoundingBox() const override; + const EDA_RECT GetBoundingBox() const override; - wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; + wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; BITMAP_DEF GetMenuImage() const override; - EDA_ITEM* Clone() const override; + EDA_ITEM* Clone() const override; virtual const BOX2I ViewBBox() const override; diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index f8407dcceb..a114c8bef1 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -594,8 +594,10 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const } -bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const +bool DRAWSEGMENT::HitTest( const wxPoint& aPosition, int aAccuracy ) const { + int maxdist = aAccuracy + ( m_Width / 2 ); + switch( m_Shape ) { case S_CIRCLE: @@ -605,7 +607,7 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const int radius = GetRadius(); int dist = KiROUND( EuclideanNorm( relPos ) ); - if( abs( radius - dist ) <= ( m_Width / 2 ) ) + if( abs( radius - dist ) <= maxdist ) { if( m_Shape == S_CIRCLE ) return true; @@ -647,13 +649,13 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const for( unsigned int i= 1; i < m_BezierPoints.size(); i++) { - if( TestSegmentHit( aPosition, m_BezierPoints[i-1], m_BezierPoints[i-1], m_Width / 2 ) ) + if( TestSegmentHit( aPosition, m_BezierPoints[i-1], m_BezierPoints[i-1], maxdist ) ) return true; } break; case S_SEGMENT: - if( TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ) ) + if( TestSegmentHit( aPosition, m_Start, m_End, maxdist ) ) return true; break; @@ -663,11 +665,11 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const { SHAPE_POLY_SET::VERTEX_INDEX i; auto poly = m_Poly; //todo: Fix CollideEdge to be const - return poly.CollideEdge(VECTOR2I( aPosition ), i, - std::max( m_Width / 2, Millimeter2iu( 0.25 ) ) ); + return poly.CollideEdge( VECTOR2I( aPosition ), i, + std::max( maxdist, Millimeter2iu( 0.25 ) ) ); } else - return m_Poly.Collide( VECTOR2I( aPosition ), m_Width / 2 ); + return m_Poly.Collide( VECTOR2I( aPosition ), maxdist ); } break; diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 8bcfc970e6..732e97003c 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -211,18 +211,15 @@ public: void SetPolyPoints( const std::vector& aPoints ); - void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, - GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset ) override; + void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, + const wxPoint& aOffset = ZeroOffset ) override; - virtual void GetMsgPanelInfo( EDA_UNITS_T aUnits, - std::vector< MSG_PANEL_ITEM >& aList ) override; + void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector& aList ) override; - virtual const EDA_RECT GetBoundingBox() const override; + const EDA_RECT GetBoundingBox() const override; - virtual bool HitTest( const wxPoint& aPosition ) const override; - - bool HitTest( const EDA_RECT& aRect, bool aContained = true, - int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; wxString GetClass() const override { diff --git a/pcbnew/class_marker_pcb.h b/pcbnew/class_marker_pcb.h index ef4a7f81d7..428db22fd5 100644 --- a/pcbnew/class_marker_pcb.h +++ b/pcbnew/class_marker_pcb.h @@ -97,9 +97,9 @@ public: const wxPoint GetPosition() const override { return m_Pos; } void SetPosition( const wxPoint& aPos ) override { m_Pos = aPos; } - bool HitTest( const wxPoint& aPosition ) const override + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override { - return HitTestMarker( aPosition ); + return HitTestMarker( aPosition, aAccuracy ); } bool IsOnLayer( PCB_LAYER_ID aLayer ) const override; diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 1da87ca3de..eb44ddf232 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -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 ); } diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 1cd94a02a0..1db84f4d35 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -440,7 +440,7 @@ public: ///> @copydoc EDA_ITEM::GetMsgPanelInfo void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector& aList ) override; - bool HitTest( const wxPoint& aPosition ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; /** * Tests if a point is inside the bounding polygon of the module @@ -451,9 +451,9 @@ public: * @param aPosition is the point to test * @return true if aPosition is inside the bounding polygon */ - bool HitTestAccurate( const wxPoint& aPosition ) const; + bool HitTestAccurate( const wxPoint& aPosition, int aAccuracy = 0 ) const; - bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; /** * Function GetReference diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 16f1501252..063238ec86 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -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; diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index e829a6636e..9b387c09b5 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -714,8 +714,7 @@ public: return m_layerMask[aLayer]; } - bool HitTest( const wxPoint& aPosition ) const override; - + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; wxString GetClass() const override diff --git a/pcbnew/class_pcb_target.cpp b/pcbnew/class_pcb_target.cpp index 729f9677ef..25fdc3b200 100644 --- a/pcbnew/class_pcb_target.cpp +++ b/pcbnew/class_pcb_target.cpp @@ -137,11 +137,11 @@ void PCB_TARGET::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color, } -bool PCB_TARGET::HitTest( const wxPoint& aPosition ) const +bool PCB_TARGET::HitTest( const wxPoint& aPosition, int aAccuracy ) const { int dX = aPosition.x - m_Pos.x; int dY = aPosition.y - m_Pos.y; - int radius = m_Size / 2; + int radius = aAccuracy + ( m_Size / 2 ); return abs( dX ) <= radius && abs( dY ) <= radius; } diff --git a/pcbnew/class_pcb_target.h b/pcbnew/class_pcb_target.h index 8f8a60132a..80cda78ca5 100644 --- a/pcbnew/class_pcb_target.h +++ b/pcbnew/class_pcb_target.h @@ -87,17 +87,13 @@ public: void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset ) override; - bool HitTest( const wxPoint& aPosition ) const override; - wxString GetClass() const override { return wxT( "PCB_TARGET" ); } - /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, - * bool aContained = true, int aAccuracy ) const - */ - bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; // Virtual function const EDA_RECT GetBoundingBox() const override; diff --git a/pcbnew/class_pcb_text.h b/pcbnew/class_pcb_text.h index afe81c8ba0..9cf441c014 100644 --- a/pcbnew/class_pcb_text.h +++ b/pcbnew/class_pcb_text.h @@ -80,15 +80,15 @@ public: void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; - virtual bool HitTest( const wxPoint& aPosition ) const override + bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override { - return TextHitTest( aPosition ); + return TextHitTest( aPosition, aAccuracy ); } /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const */ - virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override { return TextHitTest( aRect, aContained, aAccuracy ); } diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index 17874f46ae..e209be8b75 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -109,13 +109,9 @@ bool TEXTE_MODULE::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccu rect.Inflate( aAccuracy ); if( aContains ) - { return rect.Contains( GetBoundingBox() ); - } else - { return rect.Intersects( GetTextBox( -1 ), GetDrawRotation() ); - } } diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index 92e0a48b02..53ec61975e 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -205,16 +205,15 @@ public: void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override; - virtual bool TextHitTest( const wxPoint& aPoint, int aAccuracy = 0 ) const override; + bool TextHitTest( const wxPoint& aPoint, int aAccuracy = 0 ) const override; + bool TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy = 0 ) const override; - virtual bool TextHitTest( const EDA_RECT& aRect, bool aContains = false, int aAccuracy = 0 ) const override; - - virtual bool HitTest( const wxPoint& aPosition ) const override + bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override { - return TextHitTest( aPosition ); + return TextHitTest( aPosition, aAccuracy ); } - virtual bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override { return TextHitTest( aRect, aContained, aAccuracy ); } diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 36ccd345ca..a780e3be10 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -1184,14 +1184,14 @@ void VIA::GetMsgPanelInfoBase( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > } -bool TRACK::HitTest( const wxPoint& aPosition ) const +bool TRACK::HitTest( const wxPoint& aPosition, int aAccuracy ) const { - return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ); + return TestSegmentHit( aPosition, m_Start, m_End, aAccuracy + ( m_Width / 2 ) ); } -bool VIA::HitTest( const wxPoint& aPosition ) const +bool VIA::HitTest( const wxPoint& aPosition, int aAccuracy ) const { - int max_dist = m_Width / 2; + int max_dist = aAccuracy + ( m_Width / 2 ); // rel_pos is aPosition relative to m_Start (or the center of the via) wxPoint rel_pos = aPosition - m_Start; diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index fd0afc7b1a..b4f3e9c1a3 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -230,9 +230,8 @@ public: SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override; - virtual bool HitTest( const wxPoint& aPosition ) const override; - - virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; /** * Function GetVia @@ -411,9 +410,8 @@ public: const wxPoint GetPosition() const override { return m_Start; } void SetPosition( const wxPoint& aPoint ) override { m_Start = aPoint; m_End = aPoint; } - virtual bool HitTest( const wxPoint& aPosition ) const override; - - virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; wxString GetClass() const override { diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index f210db9853..51829e4d29 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -650,11 +650,11 @@ void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius ) } -bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition ) const +bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition, int aAccuracy ) const { // Normally accuracy is zoom-relative, but for the generic HitTest we just use // a fixed (small) value. - int accuracy = Millimeter2iu( 0.05 ); + int accuracy = std::max( aAccuracy, Millimeter2iu( 0.1 ) ); return HitTestForCorner( aPosition, accuracy * 2 ) || HitTestForEdge( aPosition, accuracy ); } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 233afb6332..58ca4ff372 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -268,7 +268,7 @@ public: * @param aPosition the wxPoint to test * @return bool - true if a hit, else false */ - virtual bool HitTest( const wxPoint& aPosition ) const override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; /** * Function HitTest diff --git a/pcbnew/netinfo.h b/pcbnew/netinfo.h index f4ba5d6693..3c80c85515 100644 --- a/pcbnew/netinfo.h +++ b/pcbnew/netinfo.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,10 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/** - * @file class_netinfo.h - */ - /* * Classes to handle info on nets */ diff --git a/pcbnew/ratsnest_viewitem.h b/pcbnew/ratsnest_viewitem.h index a6551c801a..432c89133e 100644 --- a/pcbnew/ratsnest_viewitem.h +++ b/pcbnew/ratsnest_viewitem.h @@ -53,6 +53,11 @@ public: /// @copydoc VIEW_ITEM::ViewGetLayers() void ViewGetLayers( int aLayers[], int& aCount ) const override; + bool HitTest( const wxPoint& aPoint, int aAccuracy = 0 ) const override + { + return false; // Not selectable + } + #if defined(DEBUG) /// @copydoc EDA_ITEM::Show() void Show( int x, std::ostream& st ) const override diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 4b8c01d340..2442adf6f8 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -770,25 +770,21 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) BOARD_COMMIT commit( m_frame ); // Build the undo list & add items to the current view - for( auto it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) + for( auto& ptr : list) { - EDA_ITEM* item = it->get(); + EDA_ITEM* item = ptr.get(); if( m_editModules ) - { wxASSERT( item->Type() == PCB_MODULE_EDGE_T || item->Type() == PCB_MODULE_TEXT_T ); - } else - { wxASSERT( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T ); - } if( dlg.IsPlacementInteractive() ) preview.Add( item ); else commit.Add( item ); - it->release(); + ptr.release(); } if( !dlg.IsPlacementInteractive() ) @@ -811,7 +807,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) VECTOR2I cursorPos = m_controls->GetCursorPosition(); VECTOR2I delta = cursorPos - firstItem->GetPosition(); - for( auto item : preview ) + for( EDA_ITEM* item : preview ) static_cast( item )->Move( (wxPoint) delta ); m_view->Update( &preview ); @@ -890,8 +886,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent ) SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR ); Activate(); - m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL, - _( "Place the footprint anchor" ) ); + m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL, _( "Place the footprint anchor" ) ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 1d8739a038..9c251b52b5 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -370,17 +370,18 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) auto curr_item = static_cast( selection.Front() ); std::vector sel_items; - for( auto it : selection ) + for( EDA_ITEM* item : selection ) { - if( auto item = dynamic_cast( it ) ) - { - sel_items.push_back( item ); + BOARD_ITEM* boardItem = dynamic_cast( item ); + MODULE* module = dynamic_cast( item ); - if( auto mod = dyn_cast( item ) ) - { - for( auto pad : mod->Pads() ) - sel_items.push_back( pad ); - } + if( boardItem ) + sel_items.push_back( boardItem ); + + if( module ) + { + for( D_PAD* pad : module->Pads() ) + sel_items.push_back( pad ); } } @@ -413,7 +414,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) prevPos = m_cursor; // Drag items to the current cursor position - for( auto item : selection ) + for( EDA_ITEM* item : selection ) { // Don't double move footprint pads, fields, etc. if( item->GetParent() && item->GetParent()->IsSelected() ) @@ -501,7 +502,6 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, false ); m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false ); - } else if( evt->IsCancel() || evt->IsActivate() ) @@ -687,9 +687,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) // When editing modules, all items have the same parent if( EditingModules() ) - { m_commit->Modify( selection.Front() ); - } for( auto item : selection ) { @@ -770,11 +768,9 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent ) // When editing modules, all items have the same parent if( EditingModules() ) - { m_commit->Modify( selection.Front() ); - } - for( auto item : selection ) + for( EDA_ITEM* item : selection ) { // only modify items we can mirror switch( item->Type() ) @@ -851,11 +847,9 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent ) // When editing modules, all items have the same parent if( EditingModules() ) - { m_commit->Modify( selection.Front() ); - } - for( auto item : selection ) + for( EDA_ITEM* item : selection ) { if( !item->IsNew() && !EditingModules() ) m_commit->Modify( item ); @@ -896,11 +890,15 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) // If we are in a "Cut" operation, then the copied selection exists already if( isCut ) + { selectionCopy = m_selectionTool->GetSelection(); + } else + { selectionCopy = m_selectionTool->RequestSelection( []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector ) { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); } ); + } bool isHover = selectionCopy.IsHover(); @@ -930,7 +928,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) // As we are about to remove items, they have to be removed from the selection first m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - for( auto item : selectionCopy ) + for( EDA_ITEM* item : selectionCopy ) { if( m_editModules ) { @@ -1020,11 +1018,9 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent ) // When editing modules, all items have the same parent if( EditingModules() ) - { m_commit->Modify( selection.Front() ); - } - for( auto selItem : selection ) + for( EDA_ITEM* selItem : selection ) { BOARD_ITEM* item = static_cast( selItem ); @@ -1091,7 +1087,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) // Each selected item is duplicated and pushed to new_items list // Old selection is cleared, and new items are then selected. - for( auto item : selection ) + for( EDA_ITEM* item : selection ) { if( !item ) continue; @@ -1134,8 +1130,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) if( !selection.Empty() ) { editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ), - (int) new_items.size() ) ); - + (int) new_items.size() ) ); // If items were duplicated, pick them up // this works well for "dropping" copies around and pushes the commit diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 753802f0c7..6dd004b4de 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -203,7 +203,6 @@ SELECTION_TOOL::SELECTION_TOOL() : m_menu( *this ), m_priv( std::make_unique() ) { - } @@ -234,9 +233,7 @@ bool SELECTION_TOOL::Init() menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 ); if( frame ) - { m_menu.AddStandardSubMenus( frame ); - } return true; } @@ -256,8 +253,10 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) getView()->GetPainter()->GetSettings()->SetHighlight( false ); } else + { // Restore previous properties of selected items and remove them from containers clearSelection(); + } // Reinsert the VIEW_GROUP, in case it was removed from the VIEW view()->Remove( &m_selection ); @@ -389,15 +388,6 @@ SELECTION& SELECTION_TOOL::GetSelection() } -static EDA_RECT getRect( const BOARD_ITEM* aItem ) -{ - if( aItem->Type() == PCB_MODULE_T ) - return static_cast( aItem )->GetFootprintRect(); - - return aItem->GetBoundingBox(); -} - - SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter, std::vector* aFiltered, bool aConfirmLockedItems ) { @@ -666,27 +656,12 @@ bool SELECTION_TOOL::selectMultiple() if( !item || !selectable( item ) ) continue; - if( windowSelection ) + if( item->HitTest( selectionRect, windowSelection ) ) { - BOX2I bbox = getRect( item ); - - if( selectionBox.Contains( bbox ) ) - { - if( m_subtractive ) - unselect( item ); - else - select( item ); - } - } - else - { - if( item->HitTest( selectionRect, false ) ) - { - if( m_subtractive ) - unselect( item ); - else - select( item ); - } + if( m_subtractive ) + unselect( item ); + else + select( item ); } } @@ -1918,6 +1893,15 @@ bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const } +static EDA_RECT getRect( const BOARD_ITEM* aItem ) +{ + if( aItem->Type() == PCB_MODULE_T ) + return static_cast( aItem )->GetFootprintRect(); + + return aItem->GetBoundingBox(); +} + + static double calcArea( const BOARD_ITEM* aItem ) { if( aItem->Type() == PCB_TRACE_T )