mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Allow drag-drop for schematic elements
Dragging screen elements over a subsheet allows moving elements into a subsheet
This commit is contained in:
parent
3b97804cb6
commit
dcbadb5857
@ -46,6 +46,9 @@
|
|||||||
#include <pgm_base.h>
|
#include <pgm_base.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
#include <settings/settings_manager.h>
|
#include <settings/settings_manager.h>
|
||||||
|
#include <math/box2.h>
|
||||||
|
#include <base_units.h>
|
||||||
|
#include <sch_screen.h>
|
||||||
#include "sch_move_tool.h"
|
#include "sch_move_tool.h"
|
||||||
|
|
||||||
|
|
||||||
@ -500,6 +503,7 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
|||||||
TOOL_EVENT* evt = ©
|
TOOL_EVENT* evt = ©
|
||||||
VECTOR2I prevPos;
|
VECTOR2I prevPos;
|
||||||
GRID_HELPER_GRIDS snapLayer = GRID_CURRENT;
|
GRID_HELPER_GRIDS snapLayer = GRID_CURRENT;
|
||||||
|
SCH_SHEET* hoverSheet = nullptr;
|
||||||
|
|
||||||
m_cursor = controls->GetCursorPosition();
|
m_cursor = controls->GetCursorPosition();
|
||||||
|
|
||||||
@ -771,7 +775,65 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
|||||||
|
|
||||||
m_cursor = grid.BestSnapAnchor( controls->GetCursorPosition( false ),
|
m_cursor = grid.BestSnapAnchor( controls->GetCursorPosition( false ),
|
||||||
snapLayer, selection );
|
snapLayer, selection );
|
||||||
|
// Determine potential target sheet.
|
||||||
|
SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( m_frame->GetScreen()->GetItem( m_cursor, 0,
|
||||||
|
SCH_SHEET_T ) );
|
||||||
|
if( sheet && sheet->IsSelected() )
|
||||||
|
sheet = nullptr; // Never target a selected sheet
|
||||||
|
|
||||||
|
if( !sheet )
|
||||||
|
{
|
||||||
|
// Build current selection bounding box in its (already moved) position.
|
||||||
|
BOX2I selBBox;
|
||||||
|
for( EDA_ITEM* it : selection )
|
||||||
|
{
|
||||||
|
if( SCH_ITEM* schIt = dynamic_cast<SCH_ITEM*>( it ) )
|
||||||
|
selBBox.Merge( schIt->GetBoundingBox() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( selBBox.GetWidth() > 0 && selBBox.GetHeight() > 0 )
|
||||||
|
{
|
||||||
|
VECTOR2I selCenter( selBBox.GetX() + selBBox.GetWidth() / 2,
|
||||||
|
selBBox.GetY() + selBBox.GetHeight() / 2 );
|
||||||
|
|
||||||
|
// Find first non-selected sheet whose body fully contains the selection
|
||||||
|
// or at least contains its center point.
|
||||||
|
for( SCH_ITEM* it : m_frame->GetScreen()->Items().OfType( SCH_SHEET_T ) )
|
||||||
|
{
|
||||||
|
SCH_SHEET* candidate = static_cast<SCH_SHEET*>( it );
|
||||||
|
if( candidate->IsSelected() || candidate->IsRootSheet() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BOX2I body = candidate->GetBodyBoundingBox();
|
||||||
|
|
||||||
|
if( body.Contains( selBBox ) || body.Contains( selCenter ) )
|
||||||
|
{
|
||||||
|
sheet = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sheet != hoverSheet )
|
||||||
|
{
|
||||||
|
if( hoverSheet )
|
||||||
|
{
|
||||||
|
hoverSheet->ClearFlags( BRIGHTENED );
|
||||||
|
m_frame->UpdateItem( hoverSheet, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
hoverSheet = sheet;
|
||||||
|
|
||||||
|
if( hoverSheet )
|
||||||
|
{
|
||||||
|
hoverSheet->SetFlags( BRIGHTENED );
|
||||||
|
m_frame->UpdateItem( hoverSheet, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_frame->GetCanvas()->SetCurrentCursor( hoverSheet ? KICURSOR::PLACE
|
||||||
|
: KICURSOR::MOVING );
|
||||||
VECTOR2I delta( m_cursor - prevPos );
|
VECTOR2I delta( m_cursor - prevPos );
|
||||||
m_anchorPos = m_cursor;
|
m_anchorPos = m_cursor;
|
||||||
|
|
||||||
@ -1032,6 +1094,22 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
|||||||
|
|
||||||
} while( ( evt = Wait() ) ); //Should be assignment not equality test
|
} while( ( evt = Wait() ) ); //Should be assignment not equality test
|
||||||
|
|
||||||
|
SCH_SHEET* targetSheet = hoverSheet;
|
||||||
|
|
||||||
|
if( hoverSheet )
|
||||||
|
{
|
||||||
|
hoverSheet->ClearFlags( BRIGHTENED );
|
||||||
|
m_frame->UpdateItem( hoverSheet, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( targetSheet )
|
||||||
|
{
|
||||||
|
moveSelectionToSheet( selection, targetSheet, aCommit );
|
||||||
|
m_toolMgr->RunAction( ACTIONS::selectionClear );
|
||||||
|
m_newDragLines.clear();
|
||||||
|
m_changedDragLines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Create a selection of original selection, drag selected/changed items, and new
|
// Create a selection of original selection, drag selected/changed items, and new
|
||||||
// bend lines for later before we clear them in the aCommit. We'll need these
|
// bend lines for later before we clear them in the aCommit. We'll need these
|
||||||
// to check for new junctions needed, etc.
|
// to check for new junctions needed, etc.
|
||||||
@ -1135,6 +1213,60 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_MOVE_TOOL::moveSelectionToSheet( SCH_SELECTION& aSelection, SCH_SHEET* aTargetSheet,
|
||||||
|
SCH_COMMIT* aCommit )
|
||||||
|
{
|
||||||
|
SCH_SCREEN* destScreen = aTargetSheet->GetScreen();
|
||||||
|
SCH_SCREEN* srcScreen = m_frame->GetScreen();
|
||||||
|
|
||||||
|
BOX2I bbox;
|
||||||
|
|
||||||
|
for( EDA_ITEM* item : aSelection )
|
||||||
|
bbox.Merge( static_cast<SCH_ITEM*>( item )->GetBoundingBox() );
|
||||||
|
|
||||||
|
VECTOR2I offset = VECTOR2I( 0, 0 ) - bbox.GetPosition();
|
||||||
|
int step = schIUScale.MilsToIU( 50 );
|
||||||
|
bool overlap = false;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
BOX2I moved = bbox;
|
||||||
|
moved.Move( offset );
|
||||||
|
overlap = false;
|
||||||
|
|
||||||
|
for( SCH_ITEM* existing : destScreen->Items() )
|
||||||
|
{
|
||||||
|
if( moved.Intersects( existing->GetBoundingBox() ) )
|
||||||
|
{
|
||||||
|
overlap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( overlap )
|
||||||
|
offset += VECTOR2I( step, step );
|
||||||
|
} while( overlap );
|
||||||
|
|
||||||
|
for( EDA_ITEM* item : aSelection )
|
||||||
|
{
|
||||||
|
SCH_ITEM* schItem = static_cast<SCH_ITEM*>( item );
|
||||||
|
|
||||||
|
// Remove from current screen and view manually
|
||||||
|
m_frame->RemoveFromScreen( schItem, srcScreen );
|
||||||
|
|
||||||
|
// Move the item
|
||||||
|
schItem->Move( offset );
|
||||||
|
|
||||||
|
// Add to destination screen manually (won't add to view since it's not current)
|
||||||
|
destScreen->Append( schItem );
|
||||||
|
|
||||||
|
// Record in commit with CHT_DONE flag to bypass automatic screen/view operations
|
||||||
|
aCommit->Stage( schItem, CHT_REMOVE | CHT_DONE, srcScreen );
|
||||||
|
aCommit->Stage( schItem, CHT_ADD | CHT_DONE, destScreen );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_MOVE_TOOL::trimDanglingLines( SCH_COMMIT* aCommit )
|
void SCH_MOVE_TOOL::trimDanglingLines( SCH_COMMIT* aCommit )
|
||||||
{
|
{
|
||||||
// Need a local cleanup first to ensure we remove unneeded junctions
|
// Need a local cleanup first to ensure we remove unneeded junctions
|
||||||
@ -1163,8 +1295,7 @@ void SCH_MOVE_TOOL::trimDanglingLines( SCH_COMMIT* aCommit )
|
|||||||
{
|
{
|
||||||
line->SetFlags( STRUCT_DELETED );
|
line->SetFlags( STRUCT_DELETED );
|
||||||
aCommit->Removed( line, m_frame->GetScreen() );
|
aCommit->Removed( line, m_frame->GetScreen() );
|
||||||
|
updateItem( line, false ); // Update any cached visuals before commit processes
|
||||||
updateItem( line, false );
|
|
||||||
m_frame->RemoveFromScreen( line, m_frame->GetScreen() );
|
m_frame->RemoveFromScreen( line, m_frame->GetScreen() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,9 @@ class SCH_LINE;
|
|||||||
class SCH_LABEL_BASE;
|
class SCH_LABEL_BASE;
|
||||||
class SCH_SHEET_PIN;
|
class SCH_SHEET_PIN;
|
||||||
class SCH_JUNCTION;
|
class SCH_JUNCTION;
|
||||||
|
class SCH_SELECTION;
|
||||||
|
class SCH_SHEET;
|
||||||
|
class SCH_COMMIT;
|
||||||
|
|
||||||
|
|
||||||
struct SPECIAL_CASE_LABEL_INFO
|
struct SPECIAL_CASE_LABEL_INFO
|
||||||
@ -81,6 +84,8 @@ private:
|
|||||||
void orthoLineDrag( SCH_COMMIT* aCommit, SCH_LINE* line, const VECTOR2I& splitDelta,
|
void orthoLineDrag( SCH_COMMIT* aCommit, SCH_LINE* line, const VECTOR2I& splitDelta,
|
||||||
int& xBendCount, int& yBendCount, const EE_GRID_HELPER& grid );
|
int& xBendCount, int& yBendCount, const EE_GRID_HELPER& grid );
|
||||||
|
|
||||||
|
void moveSelectionToSheet( SCH_SELECTION& aSelection, SCH_SHEET* aTarget, SCH_COMMIT* aCommit );
|
||||||
|
|
||||||
///< Clears the new drag lines and removes them from the screen
|
///< Clears the new drag lines and removes them from the screen
|
||||||
void clearNewDragLines();
|
void clearNewDragLines();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user