From 386ead30c5690b14a9ae38e870a4c6f8556f115f Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 29 Jan 2021 10:13:31 -0800 Subject: [PATCH] All circle and arc tools to select all at first Non-layer elements can be logical centers for the circle and arc tools. We allow the non-layer to snap for the center points and revert to only on-layer elements after Fixes https://gitlab.com/kicad/code/kicad/issues/7327 --- pcbnew/tools/drawing_tool.cpp | 19 +++++++++++++++++-- pcbnew/tools/pcb_grid_helper.cpp | 8 ++++---- pcbnew/tools/pcb_grid_helper.h | 10 +++++++++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 3cfd058987..fa2b17c826 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -1304,7 +1304,14 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, PCB_SHAPE** aGraphic, grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); - cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), m_frame->GetActiveLayer() ); + + // The first point in a circle should be able to snap to items on all layers because it doesn't + // overlap the graphical line + if( !started && graphic && shape == S_CIRCLE ) + cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), nullptr ); + else + cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), m_frame->GetActiveLayer() ); + m_controls->ForceCursorPosition( true, cursorPos ); // 45 degree angle constraint enabled with an option and toggled with Ctrl @@ -1607,7 +1614,15 @@ bool DRAWING_TOOL::drawArc( const std::string& aTool, PCB_SHAPE** aGraphic, bool grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); - VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ); + VECTOR2I cursorPos; + + // The first point in an arc should be able to snap to items on all layers because it doesn't + // overlap the graphical line + if( firstPoint ) + cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ); + else + cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), nullptr ); + m_controls->ForceCursorPosition( true, cursorPos ); auto cleanup = diff --git a/pcbnew/tools/pcb_grid_helper.cpp b/pcbnew/tools/pcb_grid_helper.cpp index c1defea850..3274b2b399 100644 --- a/pcbnew/tools/pcb_grid_helper.cpp +++ b/pcbnew/tools/pcb_grid_helper.cpp @@ -189,15 +189,15 @@ VECTOR2I PCB_GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, } -VECTOR2I PCB_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem ) +VECTOR2I PCB_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aReferenceItem ) { LSET layers; std::vector item; - if( aDraggedItem ) + if( aReferenceItem ) { - layers = aDraggedItem->GetLayerSet(); - item.push_back( aDraggedItem ); + layers = aReferenceItem->GetLayerSet(); + item.push_back( aReferenceItem ); } else layers = LSET::AllLayersMask(); diff --git a/pcbnew/tools/pcb_grid_helper.h b/pcbnew/tools/pcb_grid_helper.h index f06f6b0f3f..b5b34d7372 100644 --- a/pcbnew/tools/pcb_grid_helper.h +++ b/pcbnew/tools/pcb_grid_helper.h @@ -60,7 +60,15 @@ public: VECTOR2I AlignToArc ( const VECTOR2I& aPoint, const SHAPE_ARC& aSeg ); - VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem ); + /** + * Chooses the "best" snap anchor around the given point, optionally taking layers from + * the reference item. The reference item will not be snapped to (it is being dragged or + * created) and we choose the layers that can be snapped based on the reference item layer + * @param aOrigin Point we want to snap from + * @param aReferenceItem Reference item for layer/type special casing + * @return snapped screen point + */ + VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aReferenceItem ); VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers, const std::vector& aSkip = {} );