Implement repeatDrawItem in modern toolkit and fix bugs.
Fixes moving of SCH_FIELDS. Fixes undo operations around SCH_FIELDS and SCH_PINS.
This commit is contained in:
parent
4e0208dfba
commit
eacc3e67a5
|
@ -309,8 +309,7 @@ bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
|
|||
}
|
||||
|
||||
|
||||
bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, bool aAppend,
|
||||
SCH_SCREEN* aScreen )
|
||||
bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, bool aAppend, SCH_SCREEN* aScreen )
|
||||
{
|
||||
if( aScreen == nullptr )
|
||||
aScreen = GetScreen();
|
||||
|
@ -429,8 +428,7 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
|
|||
}
|
||||
|
||||
|
||||
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition,
|
||||
bool aAppend, bool aFinal )
|
||||
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition, bool aAppend, bool aFinal )
|
||||
{
|
||||
SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition );
|
||||
bool broken_segments = false;
|
||||
|
@ -474,46 +472,3 @@ SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( const wxPoint& aPosition )
|
|||
}
|
||||
|
||||
|
||||
void SCH_EDIT_FRAME::RepeatDrawItem()
|
||||
{
|
||||
SCH_ITEM* repeater = GetRepeatItem();
|
||||
|
||||
if( !repeater )
|
||||
return;
|
||||
|
||||
// clone the repeater, move it, insert into display list, then save a copy
|
||||
// via SetRepeatItem();
|
||||
|
||||
SCH_ITEM* my_clone = (SCH_ITEM*) repeater->Clone();
|
||||
|
||||
// If cloning a component then put into 'move' mode.
|
||||
if( my_clone->Type() == SCH_COMPONENT_T )
|
||||
{
|
||||
wxPoint pos = GetCrossHairPosition() - ( (SCH_COMPONENT*) my_clone )->GetPosition();
|
||||
|
||||
my_clone->SetFlags( IS_NEW );
|
||||
( (SCH_COMPONENT*) my_clone )->SetTimeStamp( GetNewTimeStamp() );
|
||||
my_clone->Move( pos );
|
||||
PrepareMoveItem( my_clone );
|
||||
}
|
||||
else
|
||||
{
|
||||
my_clone->Move( GetRepeatStep() );
|
||||
|
||||
if( my_clone->CanIncrementLabel() )
|
||||
( (SCH_TEXT*) my_clone )->IncrementLabel( GetRepeatDeltaLabel() );
|
||||
|
||||
AddToScreen( my_clone );
|
||||
|
||||
if( my_clone->IsConnectable() )
|
||||
TestDanglingEnds();
|
||||
|
||||
SaveCopyInUndoList( my_clone, UR_NEW );
|
||||
my_clone->ClearFlags();
|
||||
}
|
||||
|
||||
// clone my_clone, now that it has been moved, thus saving new position.
|
||||
SetRepeatItem( my_clone );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 jean-pierre.charras
|
||||
* Copyright (C) 2012-2016 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2012-2019 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -22,10 +22,6 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file edit_bitmap.cpp
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <sch_draw_panel.h>
|
||||
#include <sch_view.h>
|
||||
|
@ -36,42 +32,6 @@
|
|||
#include <view/view_group.h>
|
||||
|
||||
|
||||
SCH_BITMAP* SCH_EDIT_FRAME::CreateNewImage()
|
||||
{
|
||||
wxFileDialog fileDlg( this, _( "Choose Image" ), wxEmptyString, wxEmptyString,
|
||||
_( "Image Files " ) + wxImage::GetImageExtWildcard(),
|
||||
wxFD_OPEN );
|
||||
|
||||
if( fileDlg.ShowModal() != wxID_OK )
|
||||
return nullptr;
|
||||
|
||||
wxString fullFilename = fileDlg.GetPath();
|
||||
|
||||
if( !wxFileExists( fullFilename ) )
|
||||
{
|
||||
wxMessageBox( _( "Couldn't load image from \"%s\"" ), fullFilename );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wxPoint pos = GetCrossHairPosition();
|
||||
|
||||
SCH_BITMAP* image = new SCH_BITMAP( pos );
|
||||
|
||||
if( !image->ReadImageFile( fullFilename ) )
|
||||
{
|
||||
wxMessageBox( _( "Couldn't load image from \"%s\"" ), fullFilename );
|
||||
delete image;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
image->SetFlags( IS_NEW );
|
||||
PrepareMoveItem( image );
|
||||
|
||||
// OnModify();
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_EDIT_FRAME::EditImage( SCH_BITMAP* aItem )
|
||||
{
|
||||
// TODO: change image scale or more
|
||||
|
|
|
@ -492,11 +492,6 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
|||
GetEventHandler()->ProcessEvent( cmd );
|
||||
break;
|
||||
|
||||
case HK_REPEAT_LAST:
|
||||
if( notBusy )
|
||||
RepeatDrawItem();
|
||||
break;
|
||||
|
||||
case HK_END_CURR_LINEWIREBUS:
|
||||
// this key terminates a new line/bus/wire in progress
|
||||
if( aItem && aItem->IsNew() &&
|
||||
|
|
|
@ -751,7 +751,6 @@ public:
|
|||
SCH_BUS_BUS_ENTRY* CreateBusBusEntry();
|
||||
|
||||
SCH_TEXT* CreateNewText( int aType );
|
||||
SCH_BITMAP* CreateNewImage();
|
||||
|
||||
/**
|
||||
* Performs routine schematic cleaning including breaking wire and buses and
|
||||
|
@ -912,14 +911,6 @@ private:
|
|||
*/
|
||||
void NormalizeSchematicOnFirstLoad();
|
||||
|
||||
/**
|
||||
* Start moving \a aItem using the mouse.
|
||||
*
|
||||
* @param aItem A pointer to an SCH_ITEM to move.
|
||||
* @param aDC The device context to draw \a aItem.
|
||||
*/
|
||||
void PrepareMoveItem( SCH_ITEM* aItem );
|
||||
|
||||
// Text, label, glabel
|
||||
void EditSchematicText( SCH_TEXT* TextStruct );
|
||||
|
||||
|
@ -1231,14 +1222,6 @@ public:
|
|||
*/
|
||||
virtual bool HandleBlockEnd( wxDC* aDC ) override;
|
||||
|
||||
/**
|
||||
* Repeat the last item placement if the last item was a bus, bus entry,
|
||||
* label, or component.
|
||||
*
|
||||
* Labels that end with a number will be incremented.
|
||||
*/
|
||||
void RepeatDrawItem();
|
||||
|
||||
/**
|
||||
* Clone \a aItem and owns that clone in this container.
|
||||
*/
|
||||
|
|
|
@ -1123,10 +1123,7 @@ void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer )
|
|||
aComp->GetFields( fields, false );
|
||||
|
||||
for( SCH_FIELD* field : fields )
|
||||
{
|
||||
if( !field->IsMoving() )
|
||||
draw( field, aLayer );
|
||||
}
|
||||
draw( field, aLayer );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -375,149 +375,6 @@ void SCH_EDIT_FRAME::DeleteConnection( bool aFullConnection )
|
|||
}
|
||||
|
||||
|
||||
// This function is a callback function, called by the mouse cursor moving event
|
||||
static void moveItemWithMouseCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
|
||||
const wxPoint& aPosition, bool aErase )
|
||||
{
|
||||
SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
auto panel = static_cast<SCH_DRAW_PANEL*>( aPanel );
|
||||
auto view = panel->GetView();
|
||||
|
||||
wxCHECK_RET( (item != NULL), wxT( "Cannot move invalid schematic item." ) );
|
||||
|
||||
wxPoint cpos = aPanel->GetParent()->GetCrossHairPosition();
|
||||
cpos -= item->GetStoredPos();
|
||||
|
||||
item->SetPosition( cpos );
|
||||
|
||||
view->Hide( item );
|
||||
view->ClearPreview();
|
||||
view->AddToPreview( item->Clone() );
|
||||
|
||||
// Needed when moving a bitmap image to avoid ugly rendering and artifacts,
|
||||
// because a bitmap is drawn only as non cached
|
||||
if( item->Type() == SCH_BITMAP_T )
|
||||
view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback function called when aborting a move item with mouse cursor command.
|
||||
*/
|
||||
static void abortMoveItem( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
|
||||
{
|
||||
SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
SCH_EDIT_FRAME* parent = (SCH_EDIT_FRAME*) aPanel->GetParent();
|
||||
auto panel = static_cast<SCH_DRAW_PANEL*>( aPanel );
|
||||
auto view = panel->GetView();
|
||||
|
||||
parent->SetRepeatItem( NULL );
|
||||
screen->SetCurItem( NULL );
|
||||
view->ClearPreview();
|
||||
view->ClearHiddenFlags();
|
||||
|
||||
if( item == NULL ) /* no current item */
|
||||
return;
|
||||
|
||||
if( item->IsNew() )
|
||||
{
|
||||
delete item;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCH_ITEM* oldItem = parent->GetUndoItem();
|
||||
|
||||
SCH_ITEM* currentItem;
|
||||
|
||||
// Items that are children of other objects are undone by swapping the contents
|
||||
// of the parent items.
|
||||
if( (item->Type() == SCH_SHEET_PIN_T) || (item->Type() == SCH_FIELD_T) )
|
||||
currentItem = (SCH_ITEM*) item->GetParent();
|
||||
else
|
||||
currentItem = item;
|
||||
|
||||
wxCHECK_RET( oldItem != NULL && currentItem->Type() == oldItem->Type(),
|
||||
wxT( "Cannot restore undefined or bad last schematic item." ) );
|
||||
|
||||
// Never delete existing item, because it can be referenced by an undo/redo command
|
||||
// Just restore its data
|
||||
|
||||
view->Remove( currentItem );
|
||||
currentItem->SwapData( oldItem );
|
||||
item->ClearFlags();
|
||||
view->Add( currentItem );
|
||||
view->Hide( item, false );
|
||||
}
|
||||
|
||||
screen->TestDanglingEnds();
|
||||
aPanel->Refresh();
|
||||
}
|
||||
|
||||
|
||||
void SCH_EDIT_FRAME::PrepareMoveItem( SCH_ITEM* aItem )
|
||||
{
|
||||
wxCHECK_RET( aItem != NULL, wxT( "Cannot move invalid schematic item" ) );
|
||||
|
||||
GetToolManager()->DeactivateTool();
|
||||
|
||||
SetRepeatItem( NULL );
|
||||
|
||||
if( !aItem->IsNew() )
|
||||
{
|
||||
if( (aItem->Type() == SCH_SHEET_PIN_T) || (aItem->Type() == SCH_FIELD_T) )
|
||||
SetUndoItem( (SCH_ITEM*) aItem->GetParent() );
|
||||
else
|
||||
SetUndoItem( aItem );
|
||||
}
|
||||
|
||||
std::vector<DANGLING_END_ITEM> emptySet;
|
||||
aItem->UpdateDanglingState( emptySet );
|
||||
|
||||
aItem->SetFlags( IS_MOVED );
|
||||
|
||||
if( aItem->Type() == SCH_FIELD_T && aItem->GetParent()->Type() == SCH_COMPONENT_T )
|
||||
{
|
||||
// Now that we're moving a field, they're no longer autoplaced.
|
||||
SCH_COMPONENT *parent = static_cast<SCH_COMPONENT*>( aItem->GetParent() );
|
||||
parent->ClearFieldsAutoplaced();
|
||||
}
|
||||
|
||||
// These are owned by their parent, and so their parent must erase them
|
||||
if( aItem->Type() == SCH_SHEET_PIN_T || aItem->Type() == SCH_FIELD_T )
|
||||
RefreshItem( aItem );
|
||||
|
||||
// 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)
|
||||
if( aItem->IsMovableFromAnchorPoint() )
|
||||
{
|
||||
SetCrossHairPosition( aItem->GetPosition() );
|
||||
m_canvas->MoveCursorToCrossHair();
|
||||
aItem->SetStoredPos( wxPoint( 0,0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Round the point under the cursor to a multiple of the grid
|
||||
wxPoint cursorpos = GetCrossHairPosition() - aItem->GetPosition();
|
||||
wxPoint gridsize = GetScreen()->GetGridSize();
|
||||
cursorpos.x = ( cursorpos.x / gridsize.x ) * gridsize.x;
|
||||
cursorpos.y = ( cursorpos.y / gridsize.y ) * gridsize.y;
|
||||
|
||||
aItem->SetStoredPos( cursorpos );
|
||||
}
|
||||
|
||||
if( !aItem->IsNew() )
|
||||
OnModify();
|
||||
|
||||
GetScreen()->SetCurItem( aItem );
|
||||
m_canvas->SetMouseCapture( moveItemWithMouseCursor, abortMoveItem );
|
||||
m_canvas->CallMouseCapture( nullptr, wxDefaultPosition, false );
|
||||
|
||||
m_canvas->Refresh();
|
||||
}
|
||||
|
||||
|
||||
void SCH_EDIT_FRAME::SelectAllFromSheet( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
|
|
|
@ -96,9 +96,7 @@ SCH_SHEET_PIN* SCH_EDIT_FRAME::CreateSheetPin( SCH_SHEET* aSheet )
|
|||
m_lastSheetPinTextSize = sheetPin->GetTextSize();
|
||||
|
||||
sheetPin->SetPosition( GetCrossHairPosition() );
|
||||
PrepareMoveItem( sheetPin );
|
||||
|
||||
OnModify();
|
||||
return sheetPin;
|
||||
}
|
||||
|
||||
|
@ -141,7 +139,5 @@ SCH_SHEET_PIN* SCH_EDIT_FRAME::ImportSheetPin( SCH_SHEET* aSheet )
|
|||
sheetPin->SetShape( label->GetShape() );
|
||||
sheetPin->SetPosition( GetCrossHairPosition() );
|
||||
|
||||
PrepareMoveItem( sheetPin );
|
||||
|
||||
return sheetPin;
|
||||
}
|
||||
|
|
|
@ -206,6 +206,9 @@ OPT<TOOL_EVENT> SCH_ACTIONS::TranslateLegacyId( int aId )
|
|||
|
||||
case ID_POPUP_SCH_DUPLICATE:
|
||||
return SCH_ACTIONS::duplicate.MakeEvent();
|
||||
|
||||
case ID_REPEAT_BUTT:
|
||||
return SCH_ACTIONS::repeatDrawItem.MakeEvent();
|
||||
}
|
||||
|
||||
return OPT<TOOL_EVENT>();
|
||||
|
|
|
@ -114,6 +114,7 @@ public:
|
|||
// Editing
|
||||
static TOOL_ACTION move;
|
||||
static TOOL_ACTION duplicate;
|
||||
static TOOL_ACTION repeatDrawItem;
|
||||
static TOOL_ACTION rotateCW;
|
||||
static TOOL_ACTION rotateCCW;
|
||||
static TOOL_ACTION mirrorX;
|
||||
|
|
|
@ -258,7 +258,7 @@ int SCH_DRAWING_TOOL::PlacePower( const TOOL_EVENT& aEvent )
|
|||
|
||||
|
||||
int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER* aFilter,
|
||||
SCH_BASE_FRAME::HISTORY_LIST aHistoryList )
|
||||
SCH_BASE_FRAME::HISTORY_LIST aHistoryList )
|
||||
{
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
|
||||
|
@ -383,6 +383,128 @@ int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER
|
|||
}
|
||||
|
||||
|
||||
int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCH_BITMAP* image = aEvent.Parameter<SCH_BITMAP*>();
|
||||
|
||||
m_frame->SetToolID( ID_ADD_IMAGE_BUTT, wxCURSOR_PENCIL, _( "Add image" ) );
|
||||
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
|
||||
m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true );
|
||||
m_controls->ShowCursor( true );
|
||||
m_controls->SetSnapping( true );
|
||||
|
||||
Activate();
|
||||
|
||||
// Add all the drawable parts to preview
|
||||
if( image )
|
||||
{
|
||||
image->SetPosition( (wxPoint)cursorPos );
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( image->Clone() );
|
||||
}
|
||||
|
||||
// Main loop: keep receiving events
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
cursorPos = m_controls->GetCursorPosition( !evt->Modifier( MD_ALT ) );
|
||||
|
||||
if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() )
|
||||
{
|
||||
if( image )
|
||||
{
|
||||
m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true );
|
||||
getModel<SCH_SCREEN>()->SetCurItem( nullptr );
|
||||
m_view->ClearPreview();
|
||||
m_view->ClearHiddenFlags();
|
||||
delete image;
|
||||
image = nullptr;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
if( evt->IsActivate() ) // now finish unconditionally
|
||||
break;
|
||||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
if( !image )
|
||||
{
|
||||
m_frame->GetCanvas()->SetIgnoreMouseEvents( true );
|
||||
|
||||
wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString,
|
||||
_( "Image Files " ) + wxImage::GetImageExtWildcard(), wxFD_OPEN );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
continue;
|
||||
|
||||
// Restore cursor after dialog
|
||||
m_frame->GetCanvas()->MoveCursorToCrossHair();
|
||||
m_frame->GetCanvas()->SetIgnoreMouseEvents( false );
|
||||
|
||||
wxString fullFilename = dlg.GetPath();
|
||||
|
||||
if( !wxFileExists( fullFilename ) )
|
||||
{
|
||||
wxMessageBox( _( "Couldn't load image from \"%s\"" ), fullFilename );
|
||||
continue;
|
||||
}
|
||||
|
||||
image = new SCH_BITMAP( (wxPoint)cursorPos );
|
||||
|
||||
if( !image->ReadImageFile( fullFilename ) )
|
||||
{
|
||||
wxMessageBox( _( "Couldn't load image from \"%s\"" ), fullFilename );
|
||||
image = nullptr;
|
||||
delete image;
|
||||
continue;
|
||||
}
|
||||
|
||||
MSG_PANEL_ITEMS items;
|
||||
image->GetMsgPanelInfo( m_frame->GetUserUnits(), items );
|
||||
m_frame->SetMsgPanel( items );
|
||||
|
||||
image->SetFlags( IS_MOVED );
|
||||
m_frame->SetRepeatItem( image );
|
||||
m_frame->GetScreen()->SetCurItem( image );
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( image->Clone() );
|
||||
|
||||
m_controls->SetCursorPosition( cursorPos, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_view->ClearPreview();
|
||||
|
||||
m_frame->AddItemToScreen( image );
|
||||
|
||||
image = nullptr;
|
||||
}
|
||||
}
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
// JEY TODO
|
||||
// m_menu.ShowContextMenu( selTool->GetSelection() );
|
||||
}
|
||||
else if( image && ( evt->IsAction( &SCH_ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
||||
{
|
||||
image->SetPosition( (wxPoint)cursorPos );
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( image->Clone() );
|
||||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is a module to be placed
|
||||
m_controls->SetAutoPan( !!image );
|
||||
m_controls->CaptureCursor( !!image );
|
||||
}
|
||||
|
||||
m_frame->SetNoToolSelected();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_DRAWING_TOOL::PlaceNoConnect( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL, _( "Add no connect" ) );
|
||||
|
@ -505,13 +627,6 @@ int SCH_DRAWING_TOOL::PlaceSchematicText( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->SetToolID( ID_ADD_IMAGE_BUTT, wxCURSOR_PENCIL, _( "Add image" ) );
|
||||
return doTwoClickPlace( SCH_BITMAP_T );
|
||||
}
|
||||
|
||||
|
||||
int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||
|
@ -567,9 +682,6 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
|
|||
case SCH_TEXT_T:
|
||||
item = m_frame->CreateNewText( LAYER_NOTES );
|
||||
break;
|
||||
case SCH_BITMAP_T:
|
||||
item = m_frame->CreateNewImage();
|
||||
break;
|
||||
case SCH_SHEET_PIN_T:
|
||||
item = selTool->SelectPoint( cursorPos, SCH_COLLECTOR::SheetsAndSheetLabels );
|
||||
if( item )
|
||||
|
|
|
@ -46,6 +46,10 @@ TOOL_ACTION SCH_ACTIONS::duplicate( "eeschema.InteractiveEdit.duplicate",
|
|||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DUPLICATE ),
|
||||
_( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_xpm );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::repeatDrawItem( "eeschema.InteractiveEdit.repeatDrawItem",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_REPEAT_LAST ),
|
||||
_( "Repeat Last Item" ), _( "Duplicates the last drawn item" ) );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::rotateCW( "eeschema.InteractiveEdit.rotateCW",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Rotate Clockwise" ), _( "Rotates selected item(s) clockwise" ), rotate_cw_xpm );
|
||||
|
@ -133,7 +137,7 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Be sure that there is at least one item that we can modify. If nothing was selected before,
|
||||
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::DraggableItems );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::MovableItems );
|
||||
bool unselect = selection.IsHover();
|
||||
|
||||
if( m_dragging || selection.Empty() )
|
||||
|
@ -169,12 +173,11 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( i ) );
|
||||
|
||||
// Don't double move footprint pads, fields, etc.
|
||||
// Don't double move pins, fields, etc.
|
||||
if( item->GetParent() && item->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
item->Move( (wxPoint)movement );
|
||||
item->SetFlags( IS_MOVED );
|
||||
moveItem( item, movement );
|
||||
updateView( item );
|
||||
}
|
||||
|
||||
|
@ -187,11 +190,12 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( i ) );
|
||||
|
||||
// Don't double move footprint pads, fields, etc.
|
||||
// No need to save children of selected items
|
||||
if( item->GetParent() && item->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
m_frame->SaveCopyInUndoList( item, UR_CHANGED, i > 0 );
|
||||
if( !item->IsNew() )
|
||||
saveCopyInUndoList( item, UR_CHANGED, i > 0 );
|
||||
}
|
||||
|
||||
// Mark dangling pins at the edges of the block:
|
||||
|
@ -221,11 +225,12 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( i ) );
|
||||
|
||||
// Don't double move footprint pads, fields, etc.
|
||||
// Don't double move pins, fields, etc.
|
||||
if( item->GetParent() && item->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
item->Move( (wxPoint)delta );
|
||||
moveItem( item, delta );
|
||||
updateView( item );
|
||||
}
|
||||
|
||||
selection.SetReferencePoint( m_cursor );
|
||||
|
@ -316,6 +321,19 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void SCH_EDIT_TOOL::moveItem( SCH_ITEM* aItem, VECTOR2I delta )
|
||||
{
|
||||
KICAD_T itemType = aItem->Type();
|
||||
|
||||
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T )
|
||||
aItem->Move( wxPoint( delta.x, -delta.y ) );
|
||||
else
|
||||
aItem->Move( (wxPoint)delta );
|
||||
|
||||
aItem->SetFlags( IS_MOVED );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_EDIT_TOOL::updateModificationPoint( SELECTION& aSelection )
|
||||
{
|
||||
if( m_dragging && aSelection.HasReferencePoint() )
|
||||
|
@ -325,16 +343,22 @@ bool SCH_EDIT_TOOL::updateModificationPoint( SELECTION& aSelection )
|
|||
if( aSelection.Size() == 1 )
|
||||
{
|
||||
SCH_ITEM* item = static_cast<SCH_ITEM*>( aSelection.Front() );
|
||||
wxPoint pos = item->GetPosition();
|
||||
aSelection.SetReferencePoint( pos );
|
||||
}
|
||||
// ...otherwise modify items with regard to the grid-snapped cursor position
|
||||
else
|
||||
{
|
||||
m_cursor = getViewControls()->GetCursorPosition( true );
|
||||
aSelection.SetReferencePoint( m_cursor );
|
||||
|
||||
// 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)
|
||||
if( item->IsMovableFromAnchorPoint() )
|
||||
{
|
||||
wxPoint pos = item->GetPosition();
|
||||
aSelection.SetReferencePoint( pos );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ...otherwise modify items with regard to the grid-snapped cursor position
|
||||
m_cursor = getViewControls()->GetCursorPosition( true );
|
||||
aSelection.SetReferencePoint( m_cursor );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -356,7 +380,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
if( selection.GetSize() == 1 )
|
||||
{
|
||||
if( !moving )
|
||||
m_frame->SaveCopyInUndoList( item, UR_CHANGED );
|
||||
saveCopyInUndoList( item, UR_CHANGED );
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
|
@ -449,7 +473,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
|
||||
|
||||
if( !moving )
|
||||
m_frame->SaveCopyInUndoList( item, UR_CHANGED, ii > 0 );
|
||||
saveCopyInUndoList( item, UR_CHANGED, ii > 0 );
|
||||
|
||||
item->Rotate( rotPoint );
|
||||
|
||||
|
@ -490,7 +514,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
if( selection.GetSize() == 1 )
|
||||
{
|
||||
if( !moving )
|
||||
m_frame->SaveCopyInUndoList( item, UR_CHANGED );
|
||||
saveCopyInUndoList( item, UR_CHANGED );
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
|
@ -588,7 +612,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
|
||||
|
||||
if( !moving )
|
||||
m_frame->SaveCopyInUndoList( item, UR_CHANGED, ii > 0 );
|
||||
saveCopyInUndoList( item, UR_CHANGED, ii > 0 );
|
||||
|
||||
if( xAxis )
|
||||
item->MirrorX( mirrorPoint.y );
|
||||
|
@ -635,7 +659,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
SCH_ITEM* newItem = DuplicateStruct( oldItem );
|
||||
newItems.push_back( newItem );
|
||||
|
||||
m_frame->SaveCopyInUndoList( newItem, UR_NEW, ii > 0 );
|
||||
saveCopyInUndoList( newItem, UR_NEW, ii > 0 );
|
||||
|
||||
switch( newItem->Type() )
|
||||
{
|
||||
|
@ -705,6 +729,58 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCH_ITEM* sourceItem = m_frame->GetRepeatItem();
|
||||
|
||||
if( !sourceItem )
|
||||
return 0;
|
||||
|
||||
m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true );
|
||||
|
||||
SCH_ITEM* newItem = (SCH_ITEM*) sourceItem->Clone();
|
||||
bool performDrag = false;
|
||||
|
||||
// If cloning a component then put into 'move' mode.
|
||||
if( newItem->Type() == SCH_COMPONENT_T )
|
||||
{
|
||||
( (SCH_COMPONENT*) newItem )->SetTimeStamp( GetNewTimeStamp() );
|
||||
|
||||
newItem->Move( (wxPoint)m_controls->GetCursorPosition( true ) - newItem->GetPosition() );
|
||||
performDrag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( newItem->CanIncrementLabel() )
|
||||
( (SCH_TEXT*) newItem )->IncrementLabel( m_frame->GetRepeatDeltaLabel() );
|
||||
|
||||
newItem->Move( m_frame->GetRepeatStep() );
|
||||
}
|
||||
|
||||
newItem->SetFlags( IS_NEW );
|
||||
m_frame->AddToScreen( newItem );
|
||||
m_frame->SaveCopyInUndoList( newItem, UR_NEW );
|
||||
|
||||
m_toolMgr->RunAction( SCH_ACTIONS::selectItem, true, newItem );
|
||||
|
||||
if( performDrag )
|
||||
{
|
||||
TOOL_EVENT evt = SCH_ACTIONS::move.MakeEvent();
|
||||
Main( evt );
|
||||
}
|
||||
|
||||
newItem->ClearFlags();
|
||||
|
||||
if( newItem->IsConnectable() )
|
||||
m_frame->TestDanglingEnds();
|
||||
|
||||
// newItem newItem, now that it has been moved, thus saving new position.
|
||||
m_frame->SetRepeatItem( newItem );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||
|
@ -745,8 +821,19 @@ void SCH_EDIT_TOOL::updateView( EDA_ITEM* aItem )
|
|||
|
||||
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
|
||||
getView()->Update( aItem->GetParent() );
|
||||
|
||||
getView()->Update( aItem );
|
||||
}
|
||||
|
||||
|
||||
void SCH_EDIT_TOOL::saveCopyInUndoList( SCH_ITEM* aItem, UNDO_REDO_T aType, bool aAppend )
|
||||
{
|
||||
KICAD_T itemType = aItem->Type();
|
||||
|
||||
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
|
||||
m_frame->SaveCopyInUndoList( (SCH_ITEM*)aItem->GetParent(), aType, aAppend );
|
||||
else
|
||||
getView()->Update( aItem );
|
||||
m_frame->SaveCopyInUndoList( aItem, aType, aAppend );
|
||||
}
|
||||
|
||||
|
||||
|
@ -754,6 +841,7 @@ void SCH_EDIT_TOOL::setTransitions()
|
|||
{
|
||||
Go( &SCH_EDIT_TOOL::Main, SCH_ACTIONS::move.MakeEvent() );
|
||||
Go( &SCH_EDIT_TOOL::Duplicate, SCH_ACTIONS::duplicate.MakeEvent() );
|
||||
Go( &SCH_EDIT_TOOL::RepeatDrawItem, SCH_ACTIONS::repeatDrawItem.MakeEvent() );
|
||||
Go( &SCH_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCW.MakeEvent() );
|
||||
Go( &SCH_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCCW.MakeEvent() );
|
||||
Go( &SCH_EDIT_TOOL::Mirror, SCH_ACTIONS::mirrorX.MakeEvent() );
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
int Mirror( const TOOL_EVENT& aEvent );
|
||||
|
||||
int Duplicate( const TOOL_EVENT& aEvent );
|
||||
int RepeatDrawItem( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function Remove()
|
||||
|
@ -71,6 +72,8 @@ public:
|
|||
int Remove( const TOOL_EVENT& aEvent );
|
||||
|
||||
private:
|
||||
void moveItem( SCH_ITEM* aItem, VECTOR2I delta );
|
||||
|
||||
///> Returns the right modification point (e.g. for rotation), depending on the number of
|
||||
///> selected items.
|
||||
bool updateModificationPoint( SELECTION& aSelection );
|
||||
|
@ -78,6 +81,10 @@ private:
|
|||
///> Similar to getView()->Update(), but handles items that are redrawn by their parents.
|
||||
void updateView( EDA_ITEM* );
|
||||
|
||||
///> Similar to m_frame->SaveCopyInUndoList(), but handles items that are owned by their
|
||||
///> parents.
|
||||
void saveCopyInUndoList( SCH_ITEM*, UNDO_REDO_T aType, bool aAppend = false );
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
|
|
Loading…
Reference in New Issue