From e882753ebffb07969bcc8440d4995bd05eff43c1 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 3 Dec 2020 19:53:39 +0000 Subject: [PATCH] Grid snapping fixes. 1) Uniformly honour the GAL grid snap settings 2) Make more uniform use of GRID_HELPERs 3) Smarten EDIT_LINE for mid-point snapping Fixes https://gitlab.com/kicad/code/kicad/issues/6558 --- eeschema/tools/sch_drawing_tools.cpp | 2 +- eeschema/tools/sch_line_wire_bus_tool.cpp | 2 +- include/tool/edit_constraints.h | 9 +++++ include/tool/edit_points.h | 22 +++++----- pcbnew/tools/drawing_tool.cpp | 10 ++--- pcbnew/tools/edit_tool.cpp | 2 +- pcbnew/tools/pcb_viewer_tools.cpp | 2 +- pcbnew/tools/pcbnew_picker_tool.cpp | 2 +- pcbnew/tools/point_editor.cpp | 49 +++++++++++++++++++---- 9 files changed, 71 insertions(+), 29 deletions(-) diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 847cc953d7..02a4f99fa8 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -855,7 +855,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) { setCursor(); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( !evt->Modifier( MD_ALT ) ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = grid.BestSnapAnchor( controls->GetCursorPosition( false ), snapLayer, item ); diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index 59b4472a0e..75fb48983b 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -504,7 +504,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType, { setCursor(); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( !evt->Modifier( MD_ALT ) ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); wxPoint cursorPos = evt->IsPrime() ? (wxPoint) evt->Position() : (wxPoint) controls->GetMousePosition(); diff --git a/include/tool/edit_constraints.h b/include/tool/edit_constraints.h index 7c4423c765..d4302d65b8 100644 --- a/include/tool/edit_constraints.h +++ b/include/tool/edit_constraints.h @@ -32,6 +32,15 @@ class EDIT_POINT; class EDIT_LINE; class EDIT_POINTS; + +enum GRID_CONSTRAINT_TYPE +{ + IGNORE_GRID, + SNAP_TO_GRID, + SNAP_BY_GRID // Keep it on grid if it started on grid (treat x and y independently) +}; + + /** * EDIT_CONSTRAINT * diff --git a/include/tool/edit_points.h b/include/tool/edit_points.h index ba3f4dcd60..573d83f723 100644 --- a/include/tool/edit_points.h +++ b/include/tool/edit_points.h @@ -30,13 +30,12 @@ #include #include - -#include "edit_constraints.h" - #include +#include "edit_constraints.h" #include + /** * EDIT_POINT * @@ -55,7 +54,7 @@ public: m_position( aPoint ), m_isActive( false ), m_isHover( false ), - m_gridFree( false ), + m_gridConstraint( SNAP_TO_GRID ), m_connected( aConnected ) { } @@ -188,8 +187,8 @@ public: bool IsHover() const { return m_isHover; } void SetHover( bool aHover = true ) { m_isHover = aHover; } - bool IsGridFree() const { return m_gridFree; } - void SetGridFree( bool aGridFree = true ) { m_gridFree = aGridFree; } + GRID_CONSTRAINT_TYPE GetGridConstraint() const { return m_gridConstraint; } + void SetGridConstraint( GRID_CONSTRAINT_TYPE aConstraint ) { m_gridConstraint = aConstraint; } bool operator==( const EDIT_POINT& aOther ) const { @@ -206,10 +205,10 @@ public: static const int HOVER_SIZE = 5; private: - VECTOR2I m_position; // Position of EDIT_POINT - bool m_isActive; // True if this point is being manipulated - bool m_isHover; // True if this point is being hovered over - bool m_gridFree; // True if this point should not be snapped to the grid. + VECTOR2I m_position; // Position of EDIT_POINT + bool m_isActive; // True if this point is being manipulated + bool m_isHover; // True if this point is being hovered over + GRID_CONSTRAINT_TYPE m_gridConstraint; // Describes the grid snapping behavior. ///> An optional connected item record used to mimic polyLine behaviour with individual /// line segments. @@ -241,8 +240,7 @@ public: m_origin( aOrigin ), m_end( aEnd ) { - // Don't snap the line center to the grid - SetGridFree(); + SetGridConstraint( SNAP_BY_GRID ); } ///> @copydoc EDIT_POINT::GetPosition() diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 6a5c146a01..53a9b25247 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -694,7 +694,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) setCursor(); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( m_frame->IsGridVisible() ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = evt->IsPrime() ? evt->Position() : m_controls->GetMousePosition(); cursorPos = grid.BestSnapAnchor( cursorPos, nullptr ); m_controls->ForceCursorPosition( true, cursorPos ); @@ -1184,7 +1184,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent ) setCursor(); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( m_frame->IsGridVisible() ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), LSET::AllLayersMask() ); m_controls->ForceCursorPosition( true, cursorPos ); @@ -1297,7 +1297,7 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, PCB_SHAPE** aGraphic, m_frame->SetMsgPanel( graphic ); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( m_frame->IsGridVisible() ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), m_frame->GetActiveLayer() ); m_controls->ForceCursorPosition( true, cursorPos ); @@ -1593,7 +1593,7 @@ bool DRAWING_TOOL::drawArc( const std::string& aTool, PCB_SHAPE** aGraphic, bool graphic->SetLayer( layer ); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( m_frame->IsGridVisible() ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ); m_controls->ForceCursorPosition( true, cursorPos ); @@ -1878,7 +1878,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent ) LSET layers( m_frame->GetActiveLayer() ); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( m_frame->IsGridVisible() ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = grid.BestSnapAnchor( evt->IsPrime() ? evt->Position() : m_controls->GetMousePosition(), layers ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index f91596d672..a98a2fdd4a 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -416,7 +416,7 @@ int EDIT_TOOL::doMoveSelection( TOOL_EVENT aEvent, bool aPickReference ) VECTOR2I movement; editFrame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING ); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( !evt->Modifier( MD_ALT ) ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); if( evt->IsAction( &PCB_ACTIONS::move ) || evt->IsMotion() || evt->IsDrag( BUT_LEFT ) || evt->IsAction( &ACTIONS::refreshPreview ) diff --git a/pcbnew/tools/pcb_viewer_tools.cpp b/pcbnew/tools/pcb_viewer_tools.cpp index c93a45b440..f4b9cfd963 100644 --- a/pcbnew/tools/pcb_viewer_tools.cpp +++ b/pcbnew/tools/pcb_viewer_tools.cpp @@ -233,7 +233,7 @@ int PCB_VIEWER_TOOLS::MeasureTool( const TOOL_EVENT& aEvent ) { setCursor(); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( !evt->Modifier( MD_ALT ) ); + grid.SetUseGrid( view.GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr ); controls.ForceCursorPosition(true, cursorPos ); diff --git a/pcbnew/tools/pcbnew_picker_tool.cpp b/pcbnew/tools/pcbnew_picker_tool.cpp index 6fac0af5b2..0966cf0d24 100644 --- a/pcbnew/tools/pcbnew_picker_tool.cpp +++ b/pcbnew/tools/pcbnew_picker_tool.cpp @@ -67,7 +67,7 @@ int PCBNEW_PICKER_TOOL::Main( const TOOL_EVENT& aEvent ) setCursor(); grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( !evt->Modifier( MD_ALT ) ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = grid.BestSnapAnchor( controls->GetMousePosition(), nullptr ); controls->ForceCursorPosition(true, cursorPos ); diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index e3b0a00a73..111f99cd11 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -171,7 +171,7 @@ public: points->Point( ARC_MID ).SetConstraint( new EC_LINE( points->Point( ARC_MID ), points->Point( ARC_CENTER ) ) ); - points->Point( ARC_MID ).SetGridFree(); + points->Point( ARC_MID ).SetGridConstraint( IGNORE_GRID ); break; case S_CIRCLE: @@ -437,11 +437,13 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) while( TOOL_EVENT* evt = Wait() ) { grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); - grid.SetUseGrid( editFrame->IsGridVisible() ); + grid.SetUseGrid( view->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) ); if( !m_editPoints || evt->IsSelectionEvent() || evt->Matches( EVENTS::InhibitSelectionEditing ) ) + { break; + } EDIT_POINT* prevHover = m_hoveredPoint; @@ -469,14 +471,46 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) } //TODO: unify the constraints to solve simultaneously instead of sequentially - if( m_editedPoint->IsGridFree() ) + switch( m_editedPoint->GetGridConstraint() ) { + case IGNORE_GRID: m_editedPoint->SetPosition( evt->Position() ); - } - else - { + break; + + case SNAP_TO_GRID: m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(), snapLayers, { item } ) ); + break; + + case SNAP_BY_GRID: + { + VECTOR2I start = m_editedPoint->GetPosition(); + VECTOR2I startGrid = grid.BestSnapAnchor( start, snapLayers, { item } ); + VECTOR2I end = evt->Position(); + VECTOR2I endGrid = grid.BestSnapAnchor( end, snapLayers, { item } ); + + if( start == startGrid ) + { + end = endGrid; + } + else if( start.x == startGrid.x ) + { + end.x = endGrid.x; + + if( abs( end.y - start.y ) < grid.GetGrid().y ) + end.y = start.y; + } + else if( start.y == startGrid.y ) + { + end.y = endGrid.y; + + if( abs( end.x - start.x ) < grid.GetGrid().x ) + end.x = start.x; + } + + m_editedPoint->SetPosition( end ); + } + break; } // The alternative constraint limits to 45° @@ -487,12 +521,13 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) else m_editedPoint->ApplyConstraint(); - if( !m_editedPoint->IsGridFree() ) + if( m_editedPoint->GetGridConstraint() == SNAP_TO_GRID ) { m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(), snapLayers, { item } ) ); } + controls->ForceCursorPosition( true, m_editedPoint->GetPosition() ); updateItem(); updatePoints(); }