mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-14 14:29:36 +00:00
Implement more aggressive re-entrancy blocking for drawing tools.
A similar strategy was already implemented in Eeschema. Also adds some safety around clearing of autopan and mouse capture. Fixes https://gitlab.com/kicad/code/kicad/issues/6909
This commit is contained in:
parent
19f76ae77c
commit
b72545a432
eeschema/tools
pagelayout_editor/tools
pcbnew/tools
@ -353,11 +353,13 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is a footprint to be placed
|
||||
// Enable autopanning and cursor capture only when there is a symbol to be placed
|
||||
getViewControls()->SetAutoPan( symbol != nullptr );
|
||||
getViewControls()->CaptureCursor( symbol != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_inPlaceSymbol = false;
|
||||
return 0;
|
||||
@ -569,11 +571,13 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is a footprint to be placed
|
||||
// Enable autopanning and cursor capture only when there is an image to be placed
|
||||
getViewControls()->SetAutoPan( image != nullptr );
|
||||
getViewControls()->CaptureCursor( image != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_inPlaceImage = false;
|
||||
return 0;
|
||||
@ -1221,13 +1225,15 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is a footprint to be placed
|
||||
// Enable autopanning and cursor capture only when there is an item to be placed
|
||||
controls->SetAutoPan( item != nullptr );
|
||||
controls->CaptureCursor( item != nullptr );
|
||||
}
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
controls->SetAutoPan( false );
|
||||
controls->CaptureCursor( false );
|
||||
controls->ForceCursorPosition( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_inTwoClickPlace = false;
|
||||
return 0;
|
||||
}
|
||||
@ -1407,6 +1413,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
||||
getViewControls()->CaptureCursor( sheet != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_inDrawSheet = false;
|
||||
return 0;
|
||||
|
@ -771,6 +771,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
|
||||
controls->CaptureCursor( segment != nullptr );
|
||||
}
|
||||
|
||||
controls->SetAutoPan( false );
|
||||
controls->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
controls->ForceCursorPosition( false );
|
||||
return 0;
|
||||
|
@ -253,6 +253,8 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
||||
getViewControls()->CaptureCursor( item != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
return 0;
|
||||
}
|
||||
@ -414,6 +416,8 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||
getViewControls()->CaptureCursor( item != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
return 0;
|
||||
}
|
||||
|
@ -212,6 +212,8 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
|
||||
getViewControls()->CaptureCursor( item != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
return 0;
|
||||
}
|
||||
@ -332,6 +334,8 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||
getViewControls()->CaptureCursor( item != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_frame->PopTool( tool );
|
||||
return 0;
|
||||
|
@ -177,7 +177,9 @@ protected:
|
||||
|
||||
BOARD_EDITOR_CONTROL::BOARD_EDITOR_CONTROL() :
|
||||
PCB_TOOL_BASE( "pcbnew.EditorControl" ),
|
||||
m_frame( nullptr )
|
||||
m_frame( nullptr ),
|
||||
m_inPlaceFootprint( false ),
|
||||
m_inPlaceTarget( false )
|
||||
{
|
||||
m_placeOrigin = std::make_unique<KIGFX::ORIGIN_VIEWITEM>(
|
||||
KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ),
|
||||
@ -916,6 +918,11 @@ int BOARD_EDITOR_CONTROL::ViaSizeDec( const TOOL_EVENT& aEvent )
|
||||
|
||||
int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_inPlaceFootprint )
|
||||
return 0;
|
||||
else
|
||||
m_inPlaceFootprint = true;
|
||||
|
||||
FOOTPRINT* fp = aEvent.Parameter<FOOTPRINT*>();
|
||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
@ -1073,11 +1080,15 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is a footprint to be placed
|
||||
controls->SetAutoPan( !!fp );
|
||||
controls->CaptureCursor( !!fp );
|
||||
controls->SetAutoPan( fp != nullptr );
|
||||
controls->CaptureCursor( fp != nullptr );
|
||||
}
|
||||
|
||||
controls->SetAutoPan( false );
|
||||
controls->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
||||
m_inPlaceFootprint = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1161,6 +1172,11 @@ int BOARD_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode )
|
||||
|
||||
int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_inPlaceTarget )
|
||||
return 0;
|
||||
else
|
||||
m_inPlaceTarget = true;
|
||||
|
||||
KIGFX::VIEW* view = getView();
|
||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||
BOARD* board = getModel<BOARD>();
|
||||
@ -1267,6 +1283,8 @@ int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
|
||||
view->Remove( &preview );
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
||||
m_inPlaceTarget = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -124,9 +124,12 @@ private:
|
||||
///< Set up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
PCB_EDIT_FRAME* m_frame; ///< Pointer to the currently used edit frame.
|
||||
private:
|
||||
PCB_EDIT_FRAME* m_frame;
|
||||
bool m_inPlaceFootprint; // Re-entrancy guard.
|
||||
bool m_inPlaceTarget; // Re-entrancy guard.
|
||||
|
||||
std::unique_ptr<KIGFX::ORIGIN_VIEWITEM> m_placeOrigin; ///< Place & drill origin marker
|
||||
std::unique_ptr<KIGFX::ORIGIN_VIEWITEM> m_placeOrigin;
|
||||
|
||||
static const int WIDTH_STEP; ///< How does line width change after one -/+ key press.
|
||||
};
|
||||
|
@ -157,7 +157,8 @@ DRAWING_TOOL::DRAWING_TOOL() :
|
||||
m_board( nullptr ),
|
||||
m_frame( nullptr ),
|
||||
m_mode( MODE::NONE ),
|
||||
m_lineWidth( 1 )
|
||||
m_lineWidth( 1 ),
|
||||
m_inDrawingTool( false )
|
||||
{
|
||||
}
|
||||
|
||||
@ -246,6 +247,11 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
|
||||
PCB_SHAPE* line = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
@ -283,6 +289,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
||||
line->SetFlags( IS_NEW );
|
||||
}
|
||||
|
||||
m_inDrawingTool = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -292,6 +299,11 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
|
||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
|
||||
PCB_SHAPE* rect = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
@ -329,6 +341,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
|
||||
startingPoint = NULLOPT;
|
||||
}
|
||||
|
||||
m_inDrawingTool = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -338,6 +351,11 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
|
||||
PCB_SHAPE* circle = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
@ -375,6 +393,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
||||
startingPoint = NULLOPT;
|
||||
}
|
||||
|
||||
m_inDrawingTool = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -384,6 +403,11 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
|
||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
|
||||
PCB_SHAPE* arc = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
@ -416,6 +440,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
|
||||
immediateMode = false;
|
||||
}
|
||||
|
||||
m_inDrawingTool = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -425,6 +450,11 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
BOARD_ITEM* text = NULL;
|
||||
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
@ -637,8 +667,12 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
}
|
||||
|
||||
m_controls->SetAutoPan( false );
|
||||
m_controls->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
m_inDrawingTool = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -657,6 +691,11 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
enum DIMENSION_STEPS
|
||||
{
|
||||
SET_ORIGIN = 0,
|
||||
@ -1080,6 +1119,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||
|
||||
m_view->Remove( &preview );
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
m_inDrawingTool = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1089,6 +1130,11 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
||||
if( !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
// Note: PlaceImportedGraphics() will convert PCB_SHAPE_T and PCB_TEXT_T to footprint
|
||||
// items if needed
|
||||
DIALOG_IMPORT_GFX dlg( m_frame, m_isFootprintEditor );
|
||||
@ -1236,7 +1282,10 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
||||
m_view->Remove( &preview );
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
||||
m_inDrawingTool = false;
|
||||
m_frame->PopTool( tool );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1248,6 +1297,11 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
||||
if( !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
else
|
||||
m_inDrawingTool = true;
|
||||
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR );
|
||||
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
||||
|
||||
@ -1312,6 +1366,8 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
||||
m_inDrawingTool = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,7 @@ private:
|
||||
BOARD* m_board;
|
||||
PCB_BASE_EDIT_FRAME* m_frame;
|
||||
MODE m_mode;
|
||||
bool m_inDrawingTool; // Re-entrancy guard
|
||||
|
||||
unsigned int m_lineWidth; // Current line width for multi-segment drawing
|
||||
static const unsigned int WIDTH_STEP; // Amount of width change for one -/+ key press
|
||||
|
Loading…
Reference in New Issue
Block a user