Don't center objects behind the DRC dialog.

(cherry picked from commit d5bb39f)
This commit is contained in:
Jeff Young 2018-01-30 06:45:53 +00:00
parent 3e190cee4b
commit 6ad37972c0
7 changed files with 108 additions and 4 deletions

View File

@ -609,6 +609,43 @@ void VIEW::SetCenter( const VECTOR2D& aCenter )
}
void VIEW::SetCenter( VECTOR2D aCenter, const BOX2D& occultingScreenRect )
{
BOX2D screenRect( VECTOR2D( 0, 0 ), m_gal->GetScreenPixelSize() );
if( !screenRect.Intersects( occultingScreenRect ) )
{
SetCenter( aCenter );
return;
}
BOX2D occultedRect = screenRect.Intersect( occultingScreenRect );
VECTOR2D offset( occultedRect.GetWidth() / 2, occultedRect.GetHeight() / 2 );
double topExposed = occultedRect.GetTop() - screenRect.GetTop();
double bottomExposed = screenRect.GetBottom() - occultedRect.GetBottom();
double leftExposed = occultedRect.GetLeft() - screenRect.GetLeft();
double rightExposed = screenRect.GetRight() - occultedRect.GetRight();
if( std::max( topExposed, bottomExposed ) > std::max( leftExposed, rightExposed ) )
{
if( topExposed > bottomExposed )
aCenter.y += ToWorld( occultedRect.GetHeight() / 2 );
else
aCenter.y -= ToWorld( occultedRect.GetHeight() / 2 );
}
else
{
if( leftExposed > rightExposed )
aCenter.x += ToWorld( occultedRect.GetWidth() / 2 );
else
aCenter.x -= ToWorld( occultedRect.GetWidth() / 2 );
}
SetCenter( aCenter );
}
void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder )
{
m_layers[aLayer].renderingOrder = aRenderingOrder;

View File

@ -58,6 +58,16 @@ public:
Normalize();
}
#ifdef WX_COMPATIBILITY
/// Constructor with a wxRect as argument
BOX2( const wxRect& aRect ) :
m_Pos( aRect.GetPosition() ),
m_Size( aRect.GetSize() )
{
Normalize();
}
#endif
void SetMaximum()
{
m_Pos.x = m_Pos.y = coord_limits::lowest() / 2 + coord_limits::epsilon();
@ -249,6 +259,30 @@ public:
return rc;
}
/**
* Function Intersect
* Returns the intersection of this with another rectangle.
*/
BOX2<Vec> Intersect( const BOX2<Vec>& aRect )
{
BOX2<Vec> me( *this );
BOX2<Vec> rect( aRect );
me.Normalize(); // ensure size is >= 0
rect.Normalize(); // ensure size is >= 0
Vec topLeft, bottomRight;
topLeft.x = std::max( me.m_Pos.x, rect.m_Pos.x );
bottomRight.x = std::min( me.m_Pos.x + me.m_Size.x, rect.m_Pos.x + rect.m_Size.x );
topLeft.y = std::max( me.m_Pos.y, rect.m_Pos.y );
bottomRight.y = std::min( me.m_Pos.y + me.m_Size.y, rect.m_Pos.y + rect.m_Size.y );
if ( topLeft.x < bottomRight.x && topLeft.y < bottomRight.y )
return BOX2<Vec>( topLeft, bottomRight - topLeft );
else
return BOX2<Vec>( Vec( 0, 0 ), Vec( 0, 0 ) );
}
const std::string Format() const
{
std::stringstream ss;

View File

@ -308,6 +308,15 @@ public:
*/
void SetCenter( const VECTOR2D& aCenter );
/**
* Function SetCenter()
* Sets the center point of the VIEW, attempting to avoid \a occultingScreenRect (for
* instance, the screen rect of a modeless dialog in front of the VIEW).
* @param aCenter: the new center point, in world space coordinates.
* @param occultingScreenRect: the occulting rect, in screen space coordinates.
*/
void SetCenter( VECTOR2D aCenter, const BOX2D& occultingScreenRect );
/**
* Function GetCenter()
* Returns the center point of this VIEW (in world space coordinates)

View File

@ -1017,7 +1017,7 @@ const BOX2I MODULE::ViewBBox() const
}
return BOX2I( area );
return area;
}

View File

@ -807,7 +807,7 @@ unsigned int TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
const BOX2I TRACK::ViewBBox() const
{
BOX2I bbox( GetBoundingBox() );
BOX2I bbox = GetBoundingBox();
bbox.Inflate( 2 * GetClearance() );
return bbox;
}

View File

@ -362,13 +362,37 @@ double PCB_BASE_FRAME::BestZoom()
}
// Find the first child dialog.
wxWindow* findDialog( wxWindowList& aList )
{
for( wxWindowList::iterator iter = aList.begin(); iter != aList.end(); ++iter )
{
if( dynamic_cast<DIALOG_SHIM*>( *iter ) )
return *iter;
}
return NULL;
}
void PCB_BASE_FRAME::FocusOnLocation( const wxPoint& aPos,
bool aWarpMouseCursor, bool aCenterView )
{
if( IsGalCanvasActive() )
{
if( aCenterView )
GetGalCanvas()->GetView()->SetCenter( aPos );
{
wxWindow* dialog = findDialog( GetChildren() );
// If a dialog partly obscures the window, then center on the uncovered area.
if( dialog )
{
wxRect dialogRect( GetGalCanvas()->ScreenToClient( dialog->GetScreenPosition() ),
dialog->GetSize() );
GetGalCanvas()->GetView()->SetCenter( aPos, dialogRect );
}
else
GetGalCanvas()->GetView()->SetCenter( aPos );
}
if( aWarpMouseCursor )
GetGalCanvas()->GetViewControls()->SetCursorPosition( aPos );

View File

@ -628,7 +628,7 @@ bool SELECTION_TOOL::selectMultiple()
if( windowSelection )
{
BOX2I bbox( item->GetBoundingBox() );
BOX2I bbox = item->GetBoundingBox();
if( selectionBox.Contains( bbox ) )
{