Eeschema: when placing a new symbol or image, avoid starting the autopan.

When activate the new symbol placement, the mouse cursor is outside the canvas.
Therefore a autopan was started and not so easy to stop.
Now the mouse cursor (and the graphic cursor) are moved to a better location inside the canvas.
Fixes #8156
https://gitlab.com/kicad/code/kicad/issues/8156
This commit is contained in:
jean-pierre charras 2021-04-11 18:01:25 +02:00
parent 258fd07939
commit 15353e3c33
2 changed files with 67 additions and 4 deletions

View File

@ -86,6 +86,24 @@ bool SCH_DRAWING_TOOLS::Init()
} }
EDA_RECT SCH_DRAWING_TOOLS::GetCanvasFreeAreaPixels()
{
// calculate thearea of the canvas in pixels that create no autopan when
// is inside this area the mouse cursor
wxSize canvas_size = m_frame->GetCanvas()->GetSize();
EDA_RECT canvas_area( wxPoint( 0, 0 ), canvas_size );
const KIGFX::VC_SETTINGS& v_settings = getViewControls()->GetSettings();
if( v_settings.m_autoPanEnabled )
canvas_area.Inflate( - v_settings.m_autoPanMargin );
// Gives a margin of 2 pixels
canvas_area.Inflate( -2 );
return canvas_area;
}
int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
{ {
SCH_COMPONENT* symbol = aEvent.Parameter<SCH_COMPONENT*>(); SCH_COMPONENT* symbol = aEvent.Parameter<SCH_COMPONENT*>();
@ -209,13 +227,30 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
{ {
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
// Store the mouse position: if it is outside the canvas,
// (happens when clicking on a toolbar tool) one cannot
// use the last stored cursor position to place the new symbol
// (Current mouse pos after closing the dialog will be used)
KIGFX::VIEW_CONTROLS* controls = getViewControls();
VECTOR2D initialMousePos = controls->GetMousePosition(false);
// Build the rectangle area acceptable to move the cursor without
// having an auto-pan
EDA_RECT canvas_area = GetCanvasFreeAreaPixels();
// Pick the footprint to be placed // Pick the footprint to be placed
bool footprintPreviews = m_frame->eeconfig()->m_Appearance.footprint_preview; bool footprintPreviews = m_frame->eeconfig()->m_Appearance.footprint_preview;
PICKED_SYMBOL sel = m_frame->PickSymbolFromLibTree( &filter, *historyList, true, PICKED_SYMBOL sel = m_frame->PickSymbolFromLibTree( &filter, *historyList, true,
1, 1, footprintPreviews ); 1, 1, footprintPreviews );
// Restore cursor position after closing the dialog,
// but only if it has meaning (i.e inside the canvas)
VECTOR2D newMousePos = controls->GetMousePosition(false);
// Restore cursor after dialog if( canvas_area.Contains( wxPoint( initialMousePos ) ) )
getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true ); controls->WarpCursor( controls->GetCursorPosition(), true );
else if( !canvas_area.Contains( wxPoint( newMousePos ) ) )
// The mouse is outside the canvas area, after closing the dialog,
// thus can creating autopan issues. Warp the mouse to the canvas centre
controls->WarpCursor( canvas_area.Centre(), false );
LIB_PART* part = sel.LibId.IsValid() ? m_frame->GetLibPart( sel.LibId ) : nullptr; LIB_PART* part = sel.LibId.IsValid() ? m_frame->GetLibPart( sel.LibId ) : nullptr;
@ -425,6 +460,17 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
if( !image ) if( !image )
{ {
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
// Store the mouse position: if it is outside the canvas,
// (happens when clicking on a toolbar tool) one cannot
// use the last stored cursor position to place the new symbol
// (Current mouse pos after closing the dialog will be used)
KIGFX::VIEW_CONTROLS* controls = getViewControls();
VECTOR2D initialMousePos = controls->GetMousePosition(false);
// Build the rectangle area acceptable to move the cursor without
// having an auto-pan
EDA_RECT canvas_area = GetCanvasFreeAreaPixels();
wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString, wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString,
_( "Image Files" ) + wxS( " " ) + wxImage::GetImageExtWildcard(), _( "Image Files" ) + wxS( " " ) + wxImage::GetImageExtWildcard(),
wxFD_OPEN ); wxFD_OPEN );
@ -432,8 +478,18 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
if( dlg.ShowModal() != wxID_OK ) if( dlg.ShowModal() != wxID_OK )
continue; continue;
// Restore cursor after dialog // Restore cursor position after closing the dialog,
getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true ); // but only if it has meaning (i.e inside the canvas)
VECTOR2D newMousePos = controls->GetMousePosition( false );
if( canvas_area.Contains( wxPoint( initialMousePos ) ) )
controls->WarpCursor( controls->GetCursorPosition(), true );
else if( !canvas_area.Contains( wxPoint( newMousePos ) ) )
// The mouse is outside the canvas area, after closing the dialog,
// thus can creating autopan issues. Warp the mouse to the canvas centre
controls->WarpCursor( canvas_area.Centre(), false );
cursorPos = controls->GetMousePosition( true );
wxString fullFilename = dlg.GetPath(); wxString fullFilename = dlg.GetPath();

View File

@ -57,6 +57,13 @@ public:
int PlaceImage( const TOOL_EVENT& aEvent ); int PlaceImage( const TOOL_EVENT& aEvent );
private: private:
/**
* @return the "free" area of the canvas in pixels.
* the free area is the area that create no autopan when the mouse cursor
* is inside this area
*/
EDA_RECT GetCanvasFreeAreaPixels();
/** /**
* Get the next queued text item. * Get the next queued text item.
* *