Only center focused items when they're not visible.

This includes outside the window and behind an occluding dialog.
This keeps the view from jumping around when focusing on nearby
objects.
This commit is contained in:
Jeff Young 2020-02-24 17:18:23 +00:00
parent 7fdb74569f
commit c7ec110fba
8 changed files with 76 additions and 12 deletions

View File

@ -686,12 +686,32 @@ wxWindow* findDialog( wxWindowList& aList )
}
void EDA_DRAW_FRAME::FocusOnLocation( const wxPoint& aPos, bool aCenterView )
void EDA_DRAW_FRAME::FocusOnLocation( const wxPoint& aPos )
{
if( aCenterView )
{
bool centerView = false;
BOX2D r = GetCanvas()->GetView()->GetViewport();
// Center if we're off the current view, or within 10% of its edge
r.Inflate( - (int) r.GetWidth() / 10 );
if( !r.Contains( aPos ) )
centerView = true;
// Center if we're behind an obscuring dialog, or within 10% of its edge
wxWindow* dialog = findDialog( GetChildren() );
if( dialog )
{
wxRect dialogRect( GetCanvas()->ScreenToClient( dialog->GetScreenPosition() ),
dialog->GetSize() );
dialogRect.Inflate( dialogRect.GetWidth() / 10 );
if( dialogRect.Contains( (wxPoint) GetCanvas()->GetView()->ToScreen( aPos ) ) )
centerView = true;
}
if( centerView )
{
// If a dialog partly obscures the window, then center on the uncovered area.
if( dialog )
{

View File

@ -292,7 +292,7 @@ void DIALOG_ERC::OnLeftClickMarkersList( wxHtmlLinkEvent& event )
}
m_lastMarkerFound = marker;
m_parent->FocusOnLocation( marker->m_Pos, true );
m_parent->FocusOnLocation( marker->m_Pos );
RedrawDrawPanel();
}
@ -303,7 +303,7 @@ void DIALOG_ERC::OnLeftDblClickMarkersList( wxMouseEvent& event )
// was initialized (NULL if not found).
if( m_lastMarkerFound )
{
m_parent->FocusOnLocation( m_lastMarkerFound->m_Pos, true );
m_parent->FocusOnLocation( m_lastMarkerFound->m_Pos );
RedrawDrawPanel();
}

View File

@ -276,7 +276,7 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent )
if( item )
{
m_selectionTool->AddItemToSel( item );
m_frame->FocusOnLocation( item->GetBoundingBox().GetCenter(), true );
m_frame->FocusOnLocation( item->GetBoundingBox().GetCenter() );
m_frame->GetCanvas()->Refresh();
}
else

View File

@ -338,9 +338,8 @@ public:
* Move the graphic cursor (crosshair cursor) at a given coordinate and reframes
* the drawing if the requested point is out of view or if center on location is requested.
* @param aPos is the point to go to.
* @param aCenterView is true if the new cursor position should be centered on canvas.
*/
void FocusOnLocation( const wxPoint& aPos, bool aCenterView = false );
void FocusOnLocation( const wxPoint& aPos );
/**
* @return The current zoom level.

View File

@ -211,6 +211,8 @@ public:
return m_Pcb;
}
void FocusOnItem( BOARD_ITEM* aItem );
// General
virtual void OnCloseWindow( wxCloseEvent& Event ) = 0;
virtual void ReCreateOptToolbar() override { }

View File

@ -147,7 +147,7 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnSelectItem( wxCommandEvent& event )
if( item )
{
m_parentFrame->FocusOnLocation( item->GetPointA(), true );
m_parentFrame->FocusOnLocation( item->GetPointA() );
WINDOW_THAWER thawer( m_parentFrame );
m_parentFrame->GetCanvas()->Refresh();
}
@ -170,7 +170,7 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnLeftDClickItem( wxMouseEvent& event )
const DRC_ITEM* item = m_ItemsListBox->GetItem( selection );
if( item )
{
m_parentFrame->FocusOnLocation( item->GetPointA(), true );
m_parentFrame->FocusOnLocation( item->GetPointA() );
if( !IsModal() )
Show( false );

View File

@ -330,7 +330,7 @@ void DIALOG_FIND::search( bool aDirection )
if( m_it != m_hitList.end() )
{
m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectItem, true, *m_it );
m_frame->FocusOnLocation( ( *m_it )->GetPosition(), true );
m_frame->FocusOnLocation( ( *m_it )->GetPosition() );
msg.Printf( _( "\"%s\" found" ), searchString );
m_frame->SetStatusText( msg );

View File

@ -185,6 +185,49 @@ void PCB_BASE_FRAME::AddModuleToBoard( MODULE* module )
}
void PCB_BASE_FRAME::FocusOnItem( BOARD_ITEM* aItem )
{
static KIID lastBrightenedItemID( niluuid );
BOARD_ITEM* lastItem = GetBoard()->GetItem( lastBrightenedItemID );
if( lastItem && lastItem != aItem )
{
lastItem->ClearBrightened();
if( lastItem->Type() == PCB_MODULE_T )
{
static_cast<MODULE*>( lastItem )->RunOnChildren( [&] ( BOARD_ITEM* child )
{
child->ClearBrightened();
});
}
GetCanvas()->GetView()->Update( lastItem );
lastBrightenedItemID = niluuid;
GetCanvas()->Refresh();
}
if( aItem )
{
aItem->SetBrightened();
if( aItem->Type() == PCB_MODULE_T )
{
static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* child )
{
child->SetBrightened();
});
}
GetCanvas()->GetView()->Update( aItem );
lastBrightenedItemID = aItem->m_Uuid;
FocusOnLocation( aItem->GetPosition() );
GetCanvas()->Refresh();
}
}
void PCB_BASE_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
{
wxASSERT( m_Pcb );