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 )
|
if( m_lockedPoints.PointCount() > 0 )
|
||||||
|
{
|
||||||
|
last = m_lockedPoints.GetPoint( m_lockedPoints.PointCount() - 1 );
|
||||||
m_lockedPoints.Remove( m_lockedPoints.PointCount() - 1 );
|
m_lockedPoints.Remove( m_lockedPoints.PointCount() - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
// update the new last segment (was previously
|
// update the new last segment (was previously
|
||||||
// locked in), reusing last constraints
|
// locked in), reusing last constraints
|
||||||
|
@ -140,6 +145,7 @@ void POLYGON_GEOM_MANAGER::DeleteLastCorner()
|
||||||
updateTemporaryLines( m_leaderPts.CLastPoint() );
|
updateTemporaryLines( m_leaderPts.CLastPoint() );
|
||||||
|
|
||||||
m_client.OnGeometryChange( *this );
|
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->DeleteJunction( &commit, junction );
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_frame->TestDanglingEnds();
|
|
||||||
|
|
||||||
m_frame->GetCanvas()->Refresh();
|
m_frame->GetCanvas()->Refresh();
|
||||||
commit.Push( _( "Delete" ) );
|
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() );
|
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 )
|
if( ( currentMode == LINE_MODE::LINE_MODE_FREE && m_wires.size() > 1 )
|
||||||
|| ( LINE_MODE::LINE_MODE_90 && m_wires.size() > 2 ) )
|
|| ( 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;
|
delete segment;
|
||||||
|
|
||||||
segment = m_wires.back();
|
segment = m_wires.back();
|
||||||
segment->SetEndPoint( cursorPos );
|
cursorPos = segment->GetEndPoint();
|
||||||
|
getViewControls()->WarpMouseCursor( cursorPos, true );
|
||||||
|
|
||||||
// Find new bend point for current mode
|
// Find new bend point for current mode
|
||||||
if( twoSegments && m_wires.size() >= 2 )
|
if( twoSegments && m_wires.size() >= 2 )
|
||||||
|
@ -1001,10 +1004,6 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const TOOL_EVENT& aTool, int aType,
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::doDelete ) && ( segment || m_busUnfold.in_progress ) )
|
|
||||||
{
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
|
|
|
@ -151,7 +151,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Remove the last-added point from the polygon
|
* Remove the last-added point from the polygon
|
||||||
*/
|
*/
|
||||||
void DeleteLastCorner();
|
std::optional<VECTOR2I> DeleteLastCorner();
|
||||||
|
|
||||||
/* =================================================================
|
/* =================================================================
|
||||||
* Interfaces for users of the geometry
|
* Interfaces for users of the geometry
|
||||||
|
|
|
@ -689,6 +689,11 @@ void PCB_EDIT_FRAME::setupUIConditions()
|
||||||
if( drawingTool && drawingTool->GetDrawingMode() != DRAWING_TOOL::MODE::NONE )
|
if( drawingTool && drawingTool->GetDrawingMode() != DRAWING_TOOL::MODE::NONE )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
|
||||||
|
|
||||||
|
if( routerTool && routerTool->RoutingInProgress() )
|
||||||
|
return true;
|
||||||
|
|
||||||
return GetUndoCommandCount() > 0;
|
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;
|
FIXED_TAIL::STAGE st;
|
||||||
|
std::optional<VECTOR2I> ret;
|
||||||
|
|
||||||
if ( !m_fixedTail.PopStage( st ) )
|
if ( !m_fixedTail.PopStage( st ) )
|
||||||
{
|
return ret;
|
||||||
return false;
|
|
||||||
}
|
if( m_head.Line().PointCount() )
|
||||||
|
ret = m_head.Line().CPoint( 0 );
|
||||||
|
|
||||||
m_head.Line().Clear();
|
m_head.Line().Clear();
|
||||||
m_tail.Line().Clear();
|
m_tail.Line().Clear();
|
||||||
|
@ -1740,7 +1742,7 @@ bool LINE_PLACER::UnfixRoute()
|
||||||
|
|
||||||
m_lastNode = m_currentNode->Branch();
|
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 FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish ) override;
|
||||||
|
|
||||||
bool UnfixRoute() override;
|
std::optional<VECTOR2I> UnfixRoute() override;
|
||||||
|
|
||||||
bool CommitPlacement() override;
|
bool CommitPlacement() override;
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish = false ) = 0;
|
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; };
|
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() )
|
if( !RoutingInProgress() )
|
||||||
return;
|
return std::nullopt;
|
||||||
|
|
||||||
m_logger->Log( LOGGER::EVT_UNFIX );
|
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 );
|
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish = false );
|
||||||
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
||||||
|
|
||||||
void UndoLastSegment();
|
std::optional<VECTOR2I> UndoLastSegment();
|
||||||
void CommitRouting();
|
void CommitRouting();
|
||||||
|
|
||||||
void GetUpdatedItems( std::vector<PNS::ITEM*>& aRemoved, std::vector<PNS::ITEM*>& aAdded,
|
void GetUpdatedItems( std::vector<PNS::ITEM*>& aRemoved, std::vector<PNS::ITEM*>& aAdded,
|
||||||
|
|
|
@ -1362,9 +1362,16 @@ void ROUTER_TOOL::performRouting()
|
||||||
updateEndItem( *evt );
|
updateEndItem( *evt );
|
||||||
m_router->Move( m_endSnapPoint, m_endItem );
|
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 );
|
updateEndItem( *evt );
|
||||||
m_router->Move( m_endSnapPoint, m_endItem );
|
m_router->Move( m_endSnapPoint, m_endItem );
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,6 +328,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
||||||
BOARD_COMMIT commit( m_frame );
|
BOARD_COMMIT commit( m_frame );
|
||||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::LINE );
|
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::LINE );
|
||||||
std::optional<VECTOR2D> startingPoint;
|
std::optional<VECTOR2D> startingPoint;
|
||||||
|
std::stack<PCB_SHAPE*> committedLines;
|
||||||
|
|
||||||
line->SetShape( SHAPE_T::SEGMENT );
|
line->SetShape( SHAPE_T::SEGMENT );
|
||||||
line->SetFlags( IS_NEW );
|
line->SetFlags( IS_NEW );
|
||||||
|
@ -338,13 +339,14 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
||||||
m_frame->PushTool( aEvent );
|
m_frame->PushTool( aEvent );
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
while( drawShape( aEvent, &line, startingPoint ) )
|
while( drawShape( aEvent, &line, startingPoint, &committedLines ) )
|
||||||
{
|
{
|
||||||
if( line )
|
if( line )
|
||||||
{
|
{
|
||||||
commit.Add( line );
|
commit.Add( line );
|
||||||
commit.Push( _( "Draw a line segment" ) );
|
commit.Push( _( "Draw a line segment" ) );
|
||||||
startingPoint = VECTOR2D( line->GetEnd() );
|
startingPoint = VECTOR2D( line->GetEnd() );
|
||||||
|
committedLines.push( line );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -388,7 +390,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
|
||||||
m_frame->PushTool( aEvent );
|
m_frame->PushTool( aEvent );
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
while( drawShape( aEvent, &rect, startingPoint ) )
|
while( drawShape( aEvent, &rect, startingPoint, nullptr ) )
|
||||||
{
|
{
|
||||||
if( rect )
|
if( rect )
|
||||||
{
|
{
|
||||||
|
@ -449,7 +451,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
||||||
m_frame->PushTool( aEvent );
|
m_frame->PushTool( aEvent );
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
while( drawShape( aEvent, &circle, startingPoint ) )
|
while( drawShape( aEvent, &circle, startingPoint, nullptr ) )
|
||||||
{
|
{
|
||||||
if( circle )
|
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,
|
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();
|
SHAPE_T shape = ( *aGraphic )->GetShape();
|
||||||
|
|
||||||
|
@ -1863,7 +1866,7 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
COORDS_PADDING );
|
COORDS_PADDING );
|
||||||
m_controls->ForceCursorPosition( true, cursorPos );
|
m_controls->ForceCursorPosition( true, cursorPos );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() )
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
|
@ -2071,6 +2074,34 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
m_view->Update( &twoPointAsst );
|
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 ) )
|
else if( graphic && evt->IsAction( &PCB_ACTIONS::incWidth ) )
|
||||||
{
|
{
|
||||||
m_stroke.SetWidth( m_stroke.GetWidth() + WIDTH_STEP );
|
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
|
polyGeomMgr.SetLeaderMode( Is45Limited() ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45
|
||||||
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
|
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() )
|
||||||
{
|
{
|
||||||
if( polyGeomMgr.PolygonPointCount() >= 2 && evt->IsAction( &ACTIONS::undo ) )
|
if( polyGeomMgr.IsPolygonInProgress() )
|
||||||
{
|
|
||||||
polyGeomMgr.DeleteLastCorner();
|
|
||||||
}
|
|
||||||
else if( polyGeomMgr.IsPolygonInProgress() )
|
|
||||||
{
|
{
|
||||||
cleanup();
|
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( std::optional<VECTOR2I> last = polyGeomMgr.DeleteLastCorner() )
|
||||||
|
|
||||||
if( !polyGeomMgr.IsPolygonInProgress() )
|
|
||||||
{
|
{
|
||||||
// report finished as an empty shape
|
cursorPos = last.value();
|
||||||
polyGeomMgr.SetFinished();
|
getViewControls()->WarpMouseCursor( cursorPos, true );
|
||||||
|
m_controls->ForceCursorPosition( true, cursorPos );
|
||||||
// start again
|
polyGeomMgr.SetCursorPosition( cursorPos );
|
||||||
started = false;
|
}
|
||||||
m_controls->SetAutoPan( false );
|
else if( polyGeomMgr.IsPolygonInProgress() )
|
||||||
m_controls->CaptureCursor( false );
|
{
|
||||||
|
cleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( polyGeomMgr.IsPolygonInProgress()
|
else if( polyGeomMgr.IsPolygonInProgress()
|
||||||
|
|
|
@ -230,7 +230,8 @@ private:
|
||||||
* the same point.
|
* the same point.
|
||||||
*/
|
*/
|
||||||
bool drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
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.
|
* 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>();
|
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||||
|
|
||||||
if( isRouterActive() )
|
|
||||||
{
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::routerUndoLastSegment, true );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
editFrame->PushTool( aEvent );
|
editFrame->PushTool( aEvent );
|
||||||
|
|
||||||
std::vector<BOARD_ITEM*> lockedItems;
|
std::vector<BOARD_ITEM*> lockedItems;
|
||||||
|
|
Loading…
Reference in New Issue