Hook up EE_GRID_HELPER to some more tools.
Also implements EE_GRID_HELPER layers so that connectable things snap to connectable things and graphics snap to graphics. Fixes https://gitlab.com/kicad/code/kicad/issues/5641
This commit is contained in:
parent
e79df4a3ed
commit
a19028a396
|
@ -75,4 +75,7 @@
|
|||
///< The intersheets references suffix string
|
||||
#define DEFAULT_IREF_SUFFIX "]"
|
||||
|
||||
///< Radius of snap "gravity well"
|
||||
#define SNAP_RANGE 55
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,15 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* EE_GRID_HELPER
|
||||
*
|
||||
* A helper class for doing grid and object snapping.
|
||||
*
|
||||
* It shares its roots with PCBNew's GRID_HELPER, but uses the layers architecture to split
|
||||
* connectable items from graphic items.
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
using namespace std::placeholders;
|
||||
|
||||
|
@ -174,7 +183,8 @@ VECTOR2I EE_GRID_HELPER::AlignToWire( const VECTOR2I& aPoint, const SEG& aSeg )
|
|||
return nearest;
|
||||
}
|
||||
|
||||
VECTOR2I EE_GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, const EE_SELECTION& aItems )
|
||||
VECTOR2I EE_GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, int aLayer,
|
||||
const EE_SELECTION& aItems )
|
||||
{
|
||||
clearAnchors();
|
||||
|
||||
|
@ -184,9 +194,9 @@ VECTOR2I EE_GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, const EE_SEL
|
|||
double worldScale = m_toolMgr->GetView()->GetGAL()->GetWorldScale();
|
||||
double lineSnapMinCornerDistance = 50.0 / worldScale;
|
||||
|
||||
ANCHOR* nearestOutline = nearestAnchor( aMousePos, OUTLINE, LSET::AllLayersMask() );
|
||||
ANCHOR* nearestCorner = nearestAnchor( aMousePos, CORNER, LSET::AllLayersMask() );
|
||||
ANCHOR* nearestOrigin = nearestAnchor( aMousePos, ORIGIN, LSET::AllLayersMask() );
|
||||
ANCHOR* nearestOutline = nearestAnchor( aMousePos, OUTLINE, aLayer );
|
||||
ANCHOR* nearestCorner = nearestAnchor( aMousePos, CORNER, aLayer );
|
||||
ANCHOR* nearestOrigin = nearestAnchor( aMousePos, ORIGIN, aLayer );
|
||||
ANCHOR* best = NULL;
|
||||
double minDist = std::numeric_limits<double>::max();
|
||||
|
||||
|
@ -245,20 +255,20 @@ std::set<SCH_ITEM*> EE_GRID_HELPER::queryVisible( const BOX2I& aArea,
|
|||
}
|
||||
|
||||
|
||||
VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, SCH_ITEM* aDraggedItem )
|
||||
VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, int aLayer, SCH_ITEM* aSkip )
|
||||
{
|
||||
EE_SELECTION draggedItems;
|
||||
draggedItems.Add( aDraggedItem );
|
||||
EE_SELECTION skipItems;
|
||||
skipItems.Add( aSkip );
|
||||
|
||||
return BestSnapAnchor( aOrigin, LSET::AllLayersMask(), draggedItems );
|
||||
return BestSnapAnchor( aOrigin, aLayer, skipItems );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers,
|
||||
VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, int aLayer,
|
||||
const EE_SELECTION& aSkip )
|
||||
{
|
||||
int snapDist = GetGrid().x;
|
||||
int snapRange = snapDist;
|
||||
int snapRange = SNAP_RANGE * IU_PER_MILS;
|
||||
|
||||
BOX2I bb( VECTOR2I( aOrigin.x - snapRange / 2, aOrigin.y - snapRange / 2 ),
|
||||
VECTOR2I( snapRange, snapRange ) );
|
||||
|
@ -268,7 +278,7 @@ VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aL
|
|||
for( SCH_ITEM* item : queryVisible( bb, aSkip ) )
|
||||
computeAnchors( item, aOrigin );
|
||||
|
||||
ANCHOR* nearest = nearestAnchor( aOrigin, SNAPPABLE, aLayers );
|
||||
ANCHOR* nearest = nearestAnchor( aOrigin, SNAPPABLE, aLayer );
|
||||
VECTOR2I nearestGrid = m_enableGrid ? Align( aOrigin ) : aOrigin;
|
||||
|
||||
if( nearest )
|
||||
|
@ -358,7 +368,7 @@ void EE_GRID_HELPER::computeAnchors( SCH_ITEM* aItem, const VECTOR2I& aRefPos, b
|
|||
{
|
||||
std::vector<wxPoint> pts = aItem->GetConnectionPoints();
|
||||
|
||||
for( auto pt : pts )
|
||||
for( const wxPoint& pt : pts )
|
||||
addAnchor( VECTOR2I( pt ), SNAPPABLE | CORNER, aItem );
|
||||
|
||||
break;
|
||||
|
@ -371,7 +381,7 @@ void EE_GRID_HELPER::computeAnchors( SCH_ITEM* aItem, const VECTOR2I& aRefPos, b
|
|||
|
||||
|
||||
EE_GRID_HELPER::ANCHOR* EE_GRID_HELPER::nearestAnchor( const VECTOR2I& aPos, int aFlags,
|
||||
LSET aMatchLayers )
|
||||
int aMatchLayer )
|
||||
{
|
||||
double minDist = std::numeric_limits<double>::max();
|
||||
ANCHOR* best = NULL;
|
||||
|
@ -381,6 +391,11 @@ EE_GRID_HELPER::ANCHOR* EE_GRID_HELPER::nearestAnchor( const VECTOR2I& aPos, int
|
|||
if( ( aFlags & a.flags ) != aFlags )
|
||||
continue;
|
||||
|
||||
if( aMatchLayer == LAYER_CONNECTABLE && !a.item->IsConnectable() )
|
||||
continue;
|
||||
else if( aMatchLayer == LAYER_GRAPHICS && a.item->IsConnectable() )
|
||||
continue;
|
||||
|
||||
double dist = a.Distance( aPos );
|
||||
|
||||
if( dist < minDist )
|
||||
|
|
|
@ -23,6 +23,15 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* EE_GRID_HELPER
|
||||
*
|
||||
* A helper class for doing grid and object snapping.
|
||||
*
|
||||
* It shares its roots with PCBNew's GRID_HELPER, but uses the layers architecture to split
|
||||
* connectable items from graphic items.
|
||||
*/
|
||||
|
||||
#ifndef __GRID_HELPER_H
|
||||
#define __GRID_HELPER_H
|
||||
|
||||
|
@ -35,7 +44,17 @@ class LSET;
|
|||
class SCH_ITEM;
|
||||
class SEG;
|
||||
|
||||
class EE_GRID_HELPER {
|
||||
|
||||
enum EE_GRID_HELPER_LAYERS : int
|
||||
{
|
||||
LAYER_ANY = SCH_LAYER_ID_END + 1,
|
||||
LAYER_CONNECTABLE,
|
||||
LAYER_GRAPHICS
|
||||
};
|
||||
|
||||
|
||||
class EE_GRID_HELPER
|
||||
{
|
||||
public:
|
||||
|
||||
EE_GRID_HELPER( TOOL_MANAGER* aToolMgr );
|
||||
|
@ -61,11 +80,10 @@ public:
|
|||
|
||||
VECTOR2I AlignToWire( const VECTOR2I& aPoint, const SEG& aSeg );
|
||||
|
||||
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, const EE_SELECTION& aItems );
|
||||
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, int aLayer, const EE_SELECTION& aItems );
|
||||
|
||||
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, SCH_ITEM* aDraggedItem );
|
||||
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers,
|
||||
const EE_SELECTION& aSkip = {} );
|
||||
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, int aLayer, SCH_ITEM* aDraggedItem );
|
||||
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, int aLayer, const EE_SELECTION& aSkip = {} );
|
||||
|
||||
void SetSkipPoint( const VECTOR2I& aPoint )
|
||||
{
|
||||
|
@ -119,7 +137,7 @@ private:
|
|||
m_anchors.emplace_back( ANCHOR( aPos, aFlags, aItem ) );
|
||||
}
|
||||
|
||||
ANCHOR* nearestAnchor( const VECTOR2I& aPos, int aFlags, LSET aMatchLayers );
|
||||
ANCHOR* nearestAnchor( const VECTOR2I& aPos, int aFlags, int aMatchLayer );
|
||||
|
||||
/**
|
||||
* computeAnchors inserts the local anchor points in to the grid helper for the specified
|
||||
|
|
|
@ -342,7 +342,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
if( collector.GetCount() == 1 && !m_isSymbolEditor && !modifier_enabled )
|
||||
{
|
||||
// Check if we want to auto start wires
|
||||
VECTOR2I snappedCursorPos = grid.BestSnapAnchor( evt->Position(), nullptr );
|
||||
VECTOR2I snappedCursorPos = grid.BestSnapAnchor( evt->Position(),
|
||||
LAYER_CONNECTABLE, nullptr );
|
||||
|
||||
if( m_frame->eeconfig()->m_Drawing.auto_start_wires
|
||||
&& collector[0]->IsPointClickableAnchor( (wxPoint) snappedCursorPos ) )
|
||||
|
@ -507,7 +508,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( collector.GetCount() == 1 && !modifier_enabled )
|
||||
{
|
||||
VECTOR2I snappedCursorPos = grid.BestSnapAnchor( evt->Position(), nullptr );
|
||||
VECTOR2I snappedCursorPos = grid.BestSnapAnchor( evt->Position(),
|
||||
LAYER_CONNECTABLE, nullptr );
|
||||
|
||||
if( m_frame->eeconfig()->m_Drawing.auto_start_wires
|
||||
&& collector[0]->IsPointClickableAnchor( (wxPoint) snappedCursorPos ) )
|
||||
|
@ -864,10 +866,12 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
// pin should select the symbol with this setting
|
||||
// To avoid conflict with the auto-start wires option
|
||||
EE_GRID_HELPER grid( m_toolMgr );
|
||||
wxPoint cursorPos = wxPoint( grid.BestSnapAnchor( aPos, nullptr ) );
|
||||
wxPoint cursorPos = wxPoint( grid.BestSnapAnchor( aPos, LAYER_CONNECTABLE,
|
||||
nullptr ) );
|
||||
|
||||
if( !m_isSymbolEditor && m_frame->eeconfig()->m_Selection.select_pin_selects_symbol
|
||||
&& !other->IsPointClickableAnchor( cursorPos ) )
|
||||
if( !m_isSymbolEditor
|
||||
&& m_frame->eeconfig()->m_Selection.select_pin_selects_symbol
|
||||
&& !other->IsPointClickableAnchor( cursorPos ) )
|
||||
{
|
||||
collector.Transfer( other );
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "sch_drawing_tools.h"
|
||||
#include "ee_selection_tool.h"
|
||||
#include "ee_grid_helper.h"
|
||||
#include <ee_actions.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <project.h>
|
||||
|
@ -806,16 +807,20 @@ SCH_SHEET_PIN* SCH_DRAWING_TOOLS::createSheetPin( SCH_SHEET* aSheet, SCH_HIERLAB
|
|||
|
||||
int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCH_ITEM* item = nullptr;
|
||||
SCH_ITEM* item = nullptr;
|
||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||
EE_GRID_HELPER grid( m_toolMgr );
|
||||
|
||||
bool isImportMode = aEvent.IsAction( &EE_ACTIONS::importSheetPin );
|
||||
bool isText = aEvent.IsAction( &EE_ACTIONS::placeSchematicText );
|
||||
bool isGlobalLabel = aEvent.IsAction( &EE_ACTIONS::placeGlobalLabel );
|
||||
bool isHierLabel = aEvent.IsAction( &EE_ACTIONS::placeHierLabel );
|
||||
bool isNetLabel = aEvent.IsAction( &EE_ACTIONS::placeLabel );
|
||||
KICAD_T type = aEvent.Parameter<KICAD_T>();
|
||||
int snapLayer = isText ? LAYER_GRAPHICS : LAYER_CONNECTABLE;
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
|
||||
getViewControls()->ShowCursor( true );
|
||||
controls->ShowCursor( true );
|
||||
|
||||
std::string tool = aEvent.GetCommandStr().get();
|
||||
m_frame->PushTool( tool );
|
||||
|
@ -849,8 +854,11 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
|||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
setCursor();
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
|
||||
|
||||
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
|
||||
VECTOR2I cursorPos = grid.BestSnapAnchor( controls->GetCursorPosition( false ), snapLayer,
|
||||
item );
|
||||
|
||||
auto cleanup =
|
||||
[&] ()
|
||||
|
@ -956,7 +964,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
// Restore cursor after dialog
|
||||
getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
|
||||
controls->WarpCursor( controls->GetCursorPosition(), true );
|
||||
|
||||
if( item )
|
||||
{
|
||||
|
@ -969,7 +977,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
|||
setCursor();
|
||||
}
|
||||
|
||||
getViewControls()->SetCursorPosition( cursorPos, false );
|
||||
controls->SetCursorPosition( cursorPos, false );
|
||||
}
|
||||
|
||||
// ... and second click places:
|
||||
|
@ -1020,8 +1028,8 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is a footprint to be placed
|
||||
getViewControls()->SetAutoPan( item != nullptr );
|
||||
getViewControls()->CaptureCursor( item != nullptr );
|
||||
controls->SetAutoPan( item != nullptr );
|
||||
controls->CaptureCursor( item != nullptr );
|
||||
}
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
|
|
@ -406,7 +406,7 @@ const SCH_SHEET_PIN* SCH_LINE_WIRE_BUS_TOOL::getSheetPin( const wxPoint& aPositi
|
|||
|
||||
|
||||
void SCH_LINE_WIRE_BUS_TOOL::computeBreakPoint( const std::pair<SCH_LINE*, SCH_LINE*>& aSegments,
|
||||
wxPoint& aPosition )
|
||||
wxPoint& aPosition )
|
||||
{
|
||||
wxCHECK_RET( aSegments.first && aSegments.second,
|
||||
wxT( "Cannot compute break point of NULL line segment." ) );
|
||||
|
@ -503,10 +503,13 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
|
|||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
setCursor();
|
||||
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
wxPoint cursorPos = wxPoint( grid.BestSnapAnchor(
|
||||
evt->IsPrime() ? evt->Position() : controls->GetMousePosition(), nullptr ) );
|
||||
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
|
||||
|
||||
wxPoint cursorPos = evt->IsPrime() ? (wxPoint) evt->Position()
|
||||
: (wxPoint) controls->GetMousePosition();
|
||||
|
||||
cursorPos = (wxPoint) grid.BestSnapAnchor( cursorPos, LAYER_CONNECTABLE, nullptr );
|
||||
controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
bool forceHV = m_frame->eeconfig()->m_Drawing.hv_lines_only;
|
||||
|
@ -516,7 +519,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
|
|||
{
|
||||
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
|
||||
|
||||
for( auto wire : m_wires )
|
||||
for( SCH_LINE* wire : m_wires )
|
||||
delete wire;
|
||||
|
||||
m_wires.clear();
|
||||
|
|
|
@ -172,6 +172,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
bool chain_commands = false;
|
||||
TOOL_EVENT* evt = const_cast<TOOL_EVENT*>( &aEvent );
|
||||
VECTOR2I prevPos;
|
||||
int snapLayer = UNDEFINED_LAYER;
|
||||
|
||||
m_cursor = controls->GetCursorPosition();
|
||||
|
||||
|
@ -247,6 +248,21 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
//
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
if( static_cast<SCH_ITEM*>( item )->IsConnectable() )
|
||||
{
|
||||
if( snapLayer == LAYER_GRAPHICS )
|
||||
snapLayer = LAYER_ANY;
|
||||
else
|
||||
snapLayer = LAYER_CONNECTABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( snapLayer == LAYER_CONNECTABLE )
|
||||
snapLayer = LAYER_ANY;
|
||||
else
|
||||
snapLayer = LAYER_GRAPHICS;
|
||||
}
|
||||
|
||||
if( item->IsNew() )
|
||||
{
|
||||
if( item->HasFlag( TEMP_SELECTED ) && m_isDragOperation )
|
||||
|
@ -317,7 +333,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
if( m_frame->GetMoveWarpsCursor() )
|
||||
{
|
||||
// User wants to warp the mouse
|
||||
m_cursor = grid.BestDragOrigin( m_cursor, selection );
|
||||
m_cursor = grid.BestDragOrigin( m_cursor, snapLayer, selection );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -338,7 +354,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
// Follow the mouse
|
||||
//
|
||||
m_cursor = grid.BestSnapAnchor( controls->GetCursorPosition( false ),
|
||||
LSET::AllLayersMask(), selection );
|
||||
snapLayer, selection );
|
||||
|
||||
VECTOR2I delta( m_cursor - prevPos );
|
||||
m_anchorPos = m_cursor;
|
||||
|
|
Loading…
Reference in New Issue