Add dragging of wire ends, corners and junctions.

Fixes: lp:1830007
* https://bugs.launchpad.net/kicad/+bug/1830007
This commit is contained in:
Jeff Young 2019-06-11 21:17:05 +01:00
parent b1b7408cf2
commit c0e1f7a17a
4 changed files with 69 additions and 12 deletions

View File

@ -601,6 +601,16 @@ void SCH_LINE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
} }
void SCH_LINE::GetSelectedPoints( std::vector< wxPoint >& aPoints ) const
{
if( m_Flags & STARTPOINT )
aPoints.push_back( m_start );
if( m_Flags & ENDPOINT )
aPoints.push_back( m_end );
}
wxString SCH_LINE::GetSelectMenuText( EDA_UNITS_T aUnits ) const wxString SCH_LINE::GetSelectMenuText( EDA_UNITS_T aUnits ) const
{ {
wxString txtfmt, orient; wxString txtfmt, orient;

View File

@ -176,7 +176,9 @@ public:
bool IsConnectable() const override; bool IsConnectable() const override;
void GetConnectionPoints(std::vector< wxPoint >& aPoints ) const override; void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const override;
void GetSelectedPoints( std::vector< wxPoint >& aPoints ) const;
bool CanConnect( const SCH_ITEM* aItem ) const override; bool CanConnect( const SCH_ITEM* aItem ) const override;

View File

@ -33,6 +33,7 @@
#include <sch_component.h> #include <sch_component.h>
#include <sch_sheet.h> #include <sch_sheet.h>
#include <sch_field.h> #include <sch_field.h>
#include <sch_line.h>
#include <view/view.h> #include <view/view.h>
#include <view/view_controls.h> #include <view/view_controls.h>
#include <view/view_group.h> #include <view/view_group.h>
@ -487,7 +488,7 @@ EDA_ITEM* EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T*
bool anyCollected = collector.GetCount() != 0; bool anyCollected = collector.GetCount() != 0;
// Remove unselectable items // Post-process collected items
for( int i = collector.GetCount() - 1; i >= 0; --i ) for( int i = collector.GetCount() - 1; i >= 0; --i )
{ {
if( !selectable( collector[ i ] ) ) if( !selectable( collector[ i ] ) )
@ -495,6 +496,20 @@ EDA_ITEM* EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T*
if( aCheckLocked && collector[ i ]->IsLocked() ) if( aCheckLocked && collector[ i ]->IsLocked() )
collector.Remove( i ); collector.Remove( i );
// SelectPoint, unlike other selection routines, can select line ends
if( collector[ i ]->Type() == SCH_LINE_T )
{
SCH_LINE* line = (SCH_LINE*) collector[ i ];
line->ClearFlags( STARTPOINT | ENDPOINT );
if( HitTestPoints( line->GetStartPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
line->SetFlags( STARTPOINT );
else if (HitTestPoints( line->GetEndPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
line->SetFlags( ENDPOINT );
else
line->SetFlags( STARTPOINT | ENDPOINT );
}
} }
m_selection.ClearReferencePoint(); m_selection.ClearReferencePoint();
@ -580,6 +595,30 @@ void EE_SELECTION_TOOL::guessSelectionCandidates( EE_COLLECTOR& collector, const
if( item->Type() == SCH_FIELD_T && other->Type() == SCH_COMPONENT_T ) if( item->Type() == SCH_FIELD_T && other->Type() == SCH_COMPONENT_T )
collector.Remove( other ); collector.Remove( other );
} }
// No need for multiple wires at a single point; if there's a junction select that;
// otherwise any of the wires will do
bool junction = false;
bool wiresOnly = true;
for( EDA_ITEM* item : collector )
{
if( item->Type() == SCH_JUNCTION_T )
junction = true;
else if( item->Type() != SCH_LINE_T )
wiresOnly = false;
}
if( wiresOnly )
{
for( int j = collector.GetCount() - 1; j >= 0; --j )
{
if( junction && collector[ j ]->Type() != SCH_JUNCTION_T )
collector.Remove( j );
else if( !junction && j > 0 )
collector.Remove( j );
}
}
} }

View File

@ -194,17 +194,16 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
{ {
if( !m_moveInProgress ) // Prepare to start moving/dragging if( !m_moveInProgress ) // Prepare to start moving/dragging
{ {
bool appendUndo = selection.Front()->IsNew(); SCH_ITEM* sch_item = (SCH_ITEM*) selection.Front();
bool appendUndo = sch_item->IsNew();
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Setup a drag or a move // Setup a drag or a move
// //
for( SCH_ITEM* it = m_frame->GetScreen()->GetDrawItems(); it; it = it->Next() ) for( SCH_ITEM* it = m_frame->GetScreen()->GetDrawItems(); it; it = it->Next() )
{ {
it->ClearFlags( STARTPOINT | ENDPOINT | SELECTEDNODE ); if( !it->IsSelected() )
it->ClearFlags( STARTPOINT | ENDPOINT | SELECTEDNODE );
if( it->IsSelected() )
it->SetFlags( STARTPOINT | ENDPOINT );
} }
if( m_isDragOperation ) if( m_isDragOperation )
@ -216,7 +215,11 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
if( static_cast<SCH_ITEM*>( item )->IsConnectable() ) if( static_cast<SCH_ITEM*>( item )->IsConnectable() )
{ {
std::vector<wxPoint> connections; std::vector<wxPoint> connections;
static_cast<SCH_ITEM*>( item )->GetConnectionPoints( connections );
if( item->Type() == SCH_LINE_T )
static_cast<SCH_LINE*>( item )->GetSelectedPoints( connections );
else
static_cast<SCH_ITEM*>( item )->GetConnectionPoints( connections );
for( wxPoint point : connections ) for( wxPoint point : connections )
getConnectedDragItems( (SCH_ITEM*) item, point, m_dragAdditions ); getConnectedDragItems( (SCH_ITEM*) item, point, m_dragAdditions );
@ -301,11 +304,14 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
} }
// For some items, moving the cursor to anchor is not good (for instance large // For some items, moving the cursor to anchor is not good (for instance large
// hierarchical sheets or components can have the anchor outside the view) // hierarchical sheets or components can have the anchor outside the view)
else if( selection.Size() == 1 else if( selection.Size() == 1 && sch_item->IsMovableFromAnchorPoint()
&& static_cast<SCH_ITEM*>( selection.Front() )->IsMovableFromAnchorPoint() && m_frame->GetMoveWarpsCursor() )
&& m_frame->GetMoveWarpsCursor() )
{ {
m_anchorPos = static_cast<SCH_ITEM*>( selection.Front() )->GetPosition(); if( sch_item->Type() == SCH_LINE_T && !( sch_item->GetFlags() & STARTPOINT ) )
m_anchorPos = static_cast<SCH_LINE*>( sch_item )->GetEndPoint();
else
m_anchorPos = sch_item->GetPosition();
getViewControls()->WarpCursor( *m_anchorPos ); getViewControls()->WarpCursor( *m_anchorPos );
m_cursor = *m_anchorPos; m_cursor = *m_anchorPos;
} }