Unify go-back-one-step processing for drawing tools (and router).
Also warps mouse on all go-back-one-step operations for better feedback. Fixes https://gitlab.com/kicad/code/kicad/-/issues/14981 Fixes https://gitlab.com/kicad/code/kicad/-/issues/9985
This commit is contained in:
parent
252769d53e
commit
30336b2fe3
|
@ -129,10 +129,15 @@ bool POLYGON_GEOM_MANAGER::NewPointClosesOutline( const VECTOR2I& aPt ) const
|
|||
}
|
||||
|
||||
|
||||
void POLYGON_GEOM_MANAGER::DeleteLastCorner()
|
||||
std::optional<VECTOR2I> POLYGON_GEOM_MANAGER::DeleteLastCorner()
|
||||
{
|
||||
std::optional<VECTOR2I> last;
|
||||
|
||||
if( m_lockedPoints.PointCount() > 0 )
|
||||
{
|
||||
last = m_lockedPoints.GetPoint( m_lockedPoints.PointCount() - 1 );
|
||||
m_lockedPoints.Remove( m_lockedPoints.PointCount() - 1 );
|
||||
}
|
||||
|
||||
// update the new last segment (was previously
|
||||
// locked in), reusing last constraints
|
||||
|
@ -140,6 +145,7 @@ void POLYGON_GEOM_MANAGER::DeleteLastCorner()
|
|||
updateTemporaryLines( m_leaderPts.CLastPoint() );
|
||||
|
||||
m_client.OnGeometryChange( *this );
|
||||
return last;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1428,8 +1428,6 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
|
|||
m_frame->DeleteJunction( &commit, junction );
|
||||
}
|
||||
|
||||
// m_frame->TestDanglingEnds();
|
||||
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
commit.Push( _( "Delete" ) );
|
||||
|
||||
|
|
|
@ -892,7 +892,9 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const TOOL_EVENT& aTool, int aType,
|
|||
m_view->AddToPreview( wire->Clone() );
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &EE_ACTIONS::undoLastSegment ) || evt->IsAction( &ACTIONS::undo ) )
|
||||
else if( evt->IsAction( &EE_ACTIONS::undoLastSegment )
|
||||
|| evt->IsAction( &ACTIONS::doDelete )
|
||||
|| evt->IsAction( &ACTIONS::undo ) )
|
||||
{
|
||||
if( ( currentMode == LINE_MODE::LINE_MODE_FREE && m_wires.size() > 1 )
|
||||
|| ( LINE_MODE::LINE_MODE_90 && m_wires.size() > 2 ) )
|
||||
|
@ -904,7 +906,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const TOOL_EVENT& aTool, int aType,
|
|||
delete segment;
|
||||
|
||||
segment = m_wires.back();
|
||||
segment->SetEndPoint( cursorPos );
|
||||
cursorPos = segment->GetEndPoint();
|
||||
getViewControls()->WarpMouseCursor( cursorPos, true );
|
||||
|
||||
// Find new bend point for current mode
|
||||
if( twoSegments && m_wires.size() >= 2 )
|
||||
|
@ -1001,10 +1004,6 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const TOOL_EVENT& aTool, int aType,
|
|||
wxBell();
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::doDelete ) && ( segment || m_busUnfold.in_progress ) )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
|
|
|
@ -151,7 +151,7 @@ public:
|
|||
/**
|
||||
* Remove the last-added point from the polygon
|
||||
*/
|
||||
void DeleteLastCorner();
|
||||
std::optional<VECTOR2I> DeleteLastCorner();
|
||||
|
||||
/* =================================================================
|
||||
* Interfaces for users of the geometry
|
||||
|
|
|
@ -689,6 +689,11 @@ void PCB_EDIT_FRAME::setupUIConditions()
|
|||
if( drawingTool && drawingTool->GetDrawingMode() != DRAWING_TOOL::MODE::NONE )
|
||||
return true;
|
||||
|
||||
ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
|
||||
|
||||
if( routerTool && routerTool->RoutingInProgress() )
|
||||
return true;
|
||||
|
||||
return GetUndoCommandCount() > 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -1701,14 +1701,16 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
|
|||
}
|
||||
|
||||
|
||||
bool LINE_PLACER::UnfixRoute()
|
||||
std::optional<VECTOR2I> LINE_PLACER::UnfixRoute()
|
||||
{
|
||||
FIXED_TAIL::STAGE st;
|
||||
std::optional<VECTOR2I> ret;
|
||||
|
||||
if ( !m_fixedTail.PopStage( st ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ret;
|
||||
|
||||
if( m_head.Line().PointCount() )
|
||||
ret = m_head.Line().CPoint( 0 );
|
||||
|
||||
m_head.Line().Clear();
|
||||
m_tail.Line().Clear();
|
||||
|
@ -1740,7 +1742,7 @@ bool LINE_PLACER::UnfixRoute()
|
|||
|
||||
m_lastNode = m_currentNode->Branch();
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
*/
|
||||
bool FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish ) override;
|
||||
|
||||
bool UnfixRoute() override;
|
||||
std::optional<VECTOR2I> UnfixRoute() override;
|
||||
|
||||
bool CommitPlacement() override;
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ public:
|
|||
*/
|
||||
virtual bool FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish = false ) = 0;
|
||||
|
||||
virtual bool UnfixRoute() { return false; };
|
||||
virtual std::optional<VECTOR2I> UnfixRoute() { return std::nullopt; };
|
||||
|
||||
virtual bool CommitPlacement() { return false; };
|
||||
|
||||
|
|
|
@ -893,13 +893,13 @@ bool ROUTER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish )
|
|||
}
|
||||
|
||||
|
||||
void ROUTER::UndoLastSegment()
|
||||
std::optional<VECTOR2I> ROUTER::UndoLastSegment()
|
||||
{
|
||||
if( !RoutingInProgress() )
|
||||
return;
|
||||
return std::nullopt;
|
||||
|
||||
m_logger->Log( LOGGER::EVT_UNFIX );
|
||||
m_placer->UnfixRoute();
|
||||
return m_placer->UnfixRoute();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ public:
|
|||
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish = false );
|
||||
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
||||
|
||||
void UndoLastSegment();
|
||||
std::optional<VECTOR2I> UndoLastSegment();
|
||||
void CommitRouting();
|
||||
|
||||
void GetUpdatedItems( std::vector<PNS::ITEM*>& aRemoved, std::vector<PNS::ITEM*>& aAdded,
|
||||
|
|
|
@ -1362,9 +1362,16 @@ void ROUTER_TOOL::performRouting()
|
|||
updateEndItem( *evt );
|
||||
m_router->Move( m_endSnapPoint, m_endItem );
|
||||
}
|
||||
else if( evt->IsAction( &PCB_ACTIONS::routerUndoLastSegment ) )
|
||||
else if( evt->IsAction( &PCB_ACTIONS::routerUndoLastSegment )
|
||||
|| evt->IsAction( &ACTIONS::doDelete )
|
||||
|| evt->IsAction( &ACTIONS::undo ) )
|
||||
{
|
||||
m_router->UndoLastSegment();
|
||||
if( std::optional<VECTOR2I> last = m_router->UndoLastSegment() )
|
||||
{
|
||||
getViewControls()->WarpMouseCursor( last.value(), true );
|
||||
evt->SetMousePosition( last.value() );
|
||||
}
|
||||
|
||||
updateEndItem( *evt );
|
||||
m_router->Move( m_endSnapPoint, m_endItem );
|
||||
}
|
||||
|
|
|
@ -328,6 +328,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
|||
BOARD_COMMIT commit( m_frame );
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::LINE );
|
||||
std::optional<VECTOR2D> startingPoint;
|
||||
std::stack<PCB_SHAPE*> committedLines;
|
||||
|
||||
line->SetShape( SHAPE_T::SEGMENT );
|
||||
line->SetFlags( IS_NEW );
|
||||
|
@ -338,13 +339,14 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
|||
m_frame->PushTool( aEvent );
|
||||
Activate();
|
||||
|
||||
while( drawShape( aEvent, &line, startingPoint ) )
|
||||
while( drawShape( aEvent, &line, startingPoint, &committedLines ) )
|
||||
{
|
||||
if( line )
|
||||
{
|
||||
commit.Add( line );
|
||||
commit.Push( _( "Draw a line segment" ) );
|
||||
startingPoint = VECTOR2D( line->GetEnd() );
|
||||
committedLines.push( line );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -388,7 +390,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
|
|||
m_frame->PushTool( aEvent );
|
||||
Activate();
|
||||
|
||||
while( drawShape( aEvent, &rect, startingPoint ) )
|
||||
while( drawShape( aEvent, &rect, startingPoint, nullptr ) )
|
||||
{
|
||||
if( rect )
|
||||
{
|
||||
|
@ -449,7 +451,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
|||
m_frame->PushTool( aEvent );
|
||||
Activate();
|
||||
|
||||
while( drawShape( aEvent, &circle, startingPoint ) )
|
||||
while( drawShape( aEvent, &circle, startingPoint, nullptr ) )
|
||||
{
|
||||
if( circle )
|
||||
{
|
||||
|
@ -1773,7 +1775,8 @@ static void updateSegmentFromGeometryMgr( const KIGFX::PREVIEW::TWO_POINT_GEOMET
|
|||
|
||||
|
||||
bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||
std::optional<VECTOR2D> aStartingPoint )
|
||||
std::optional<VECTOR2D> aStartingPoint,
|
||||
std::stack<PCB_SHAPE*>* aCommittedGraphics )
|
||||
{
|
||||
SHAPE_T shape = ( *aGraphic )->GetShape();
|
||||
|
||||
|
@ -1863,7 +1866,7 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
cleanup();
|
||||
|
||||
|
@ -2071,6 +2074,34 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
m_view->Update( &preview );
|
||||
m_view->Update( &twoPointAsst );
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::undo )
|
||||
|| evt->IsAction( &PCB_ACTIONS::doDelete )
|
||||
|| evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) )
|
||||
{
|
||||
if( graphic && !aCommittedGraphics->empty() )
|
||||
{
|
||||
twoPointManager.SetOrigin( aCommittedGraphics->top()->GetStart() );
|
||||
twoPointManager.SetEnd( aCommittedGraphics->top()->GetEnd() );
|
||||
aCommittedGraphics->pop();
|
||||
|
||||
getViewControls()->WarpMouseCursor( twoPointManager.GetEnd(), true );
|
||||
|
||||
if( PICKED_ITEMS_LIST* undo = m_frame->PopCommandFromUndoList() )
|
||||
{
|
||||
m_frame->PutDataInPreviousState( undo );
|
||||
m_frame->ClearListAndDeleteItems( undo );
|
||||
delete undo;
|
||||
}
|
||||
|
||||
updateSegmentFromGeometryMgr( twoPointManager, graphic );
|
||||
m_view->Update( &preview );
|
||||
m_view->Update( &twoPointAsst );
|
||||
}
|
||||
else if( graphic )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
else if( graphic && evt->IsAction( &PCB_ACTIONS::incWidth ) )
|
||||
{
|
||||
m_stroke.SetWidth( m_stroke.GetWidth() + WIDTH_STEP );
|
||||
|
@ -2568,13 +2599,9 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
polyGeomMgr.SetLeaderMode( Is45Limited() ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45
|
||||
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
if( polyGeomMgr.PolygonPointCount() >= 2 && evt->IsAction( &ACTIONS::undo ) )
|
||||
{
|
||||
polyGeomMgr.DeleteLastCorner();
|
||||
}
|
||||
else if( polyGeomMgr.IsPolygonInProgress() )
|
||||
if( polyGeomMgr.IsPolygonInProgress() )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
@ -2658,19 +2685,20 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) )
|
||||
else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint )
|
||||
|| evt->IsAction( &ACTIONS::doDelete )
|
||||
|| evt->IsAction( &ACTIONS::undo ) )
|
||||
{
|
||||
polyGeomMgr.DeleteLastCorner();
|
||||
|
||||
if( !polyGeomMgr.IsPolygonInProgress() )
|
||||
if( std::optional<VECTOR2I> last = polyGeomMgr.DeleteLastCorner() )
|
||||
{
|
||||
// report finished as an empty shape
|
||||
polyGeomMgr.SetFinished();
|
||||
|
||||
// start again
|
||||
started = false;
|
||||
m_controls->SetAutoPan( false );
|
||||
m_controls->CaptureCursor( false );
|
||||
cursorPos = last.value();
|
||||
getViewControls()->WarpMouseCursor( cursorPos, true );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
polyGeomMgr.SetCursorPosition( cursorPos );
|
||||
}
|
||||
else if( polyGeomMgr.IsPolygonInProgress() )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
else if( polyGeomMgr.IsPolygonInProgress()
|
||||
|
|
|
@ -230,7 +230,8 @@ private:
|
|||
* the same point.
|
||||
*/
|
||||
bool drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||
std::optional<VECTOR2D> aStartingPoint );
|
||||
std::optional<VECTOR2D> aStartingPoint,
|
||||
std::stack<PCB_SHAPE*>* aCommittedGraphics );
|
||||
|
||||
/**
|
||||
* Start drawing an arc.
|
||||
|
|
|
@ -1960,12 +1960,6 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
|
||||
if( isRouterActive() )
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::routerUndoLastSegment, true );
|
||||
return 0;
|
||||
}
|
||||
|
||||
editFrame->PushTool( aEvent );
|
||||
|
||||
std::vector<BOARD_ITEM*> lockedItems;
|
||||
|
|
Loading…
Reference in New Issue