Centralize zoom-to-fit code.
Fixes a bunch of errors: - libedit and libbrowser would zoom to bounding box but centre on canvas - libedit, libbrowser and gerbview didn’t take the scroll bars into account - pcbnew didn’t take scroll bars into account or apply the 10% margin - appending a board file would re-centre, but not re-zoom Fixes: lp:1504302 * https://bugs.launchpad.net/kicad/+bug/1504302
This commit is contained in:
parent
ac9fc949bd
commit
4bae901dc8
|
@ -107,6 +107,7 @@ int COMMON_TOOLS::ZoomFitScreen( const TOOL_EVENT& aEvent )
|
|||
KIGFX::VIEW* view = getView();
|
||||
EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas();
|
||||
EDA_ITEM* model = getModel<EDA_ITEM>();
|
||||
EDA_BASE_FRAME* frame = getEditFrame<EDA_BASE_FRAME>();
|
||||
|
||||
BOX2I bBox = model->ViewBBox();
|
||||
VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() );
|
||||
|
@ -121,7 +122,18 @@ int COMMON_TOOLS::ZoomFitScreen( const TOOL_EVENT& aEvent )
|
|||
double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
|
||||
fabs( vsize.y / screenSize.y ) );
|
||||
|
||||
view->SetScale( scale );
|
||||
// Reserve a 10% margin around component bounding box.
|
||||
double margin_scale_factor = 1.1;
|
||||
|
||||
// Leave 20% for library editors & viewers
|
||||
if( frame->IsType( FRAME_PCB_MODULE_VIEWER ) || frame->IsType( FRAME_PCB_MODULE_VIEWER_MODAL )
|
||||
|| frame->IsType( FRAME_SCH_VIEWER ) || frame->IsType( FRAME_SCH_VIEWER_MODAL )
|
||||
|| frame->IsType( FRAME_SCH_LIB_EDITOR ) || frame->IsType( FRAME_PCB_MODULE_EDITOR ) )
|
||||
{
|
||||
margin_scale_factor = 1.2;
|
||||
}
|
||||
|
||||
view->SetScale( scale / margin_scale_factor );
|
||||
view->SetCenter( bBox.Centre() );
|
||||
|
||||
// Take scrollbars into account
|
||||
|
|
|
@ -78,6 +78,27 @@ void EDA_DRAW_FRAME::RedrawScreen2( const wxPoint& posBefore )
|
|||
}
|
||||
|
||||
|
||||
// Factor out the calculation portion of the various BestZoom() implementations.
|
||||
//
|
||||
// Note that like it's forerunners this routine has an intentional side-effect: it
|
||||
// sets the scroll centre position. While I'm not happy about that, it's probably
|
||||
// not worth fixing as its days are numbered (GAL canvases use a different method).
|
||||
double EDA_DRAW_FRAME::bestZoom( double sizeX, double sizeY, double scaleFactor, wxPoint centre )
|
||||
{
|
||||
double bestzoom = std::max( sizeX * scaleFactor / (double) m_canvas->GetClientSize().x,
|
||||
sizeY * scaleFactor / (double) m_canvas->GetClientSize().y );
|
||||
|
||||
// Take scrollbars into account
|
||||
DSIZE scrollbarSize = m_canvas->GetSize() - m_canvas->GetClientSize();
|
||||
centre.x -= int( bestzoom * scrollbarSize.x / 2.0 );
|
||||
centre.y -= int( bestzoom * scrollbarSize.y / 2.0 );
|
||||
|
||||
SetScrollCenterPosition( centre );
|
||||
|
||||
return bestzoom;
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::Zoom_Automatique( bool aWarpPointer )
|
||||
{
|
||||
BASE_SCREEN* screen = GetScreen();
|
||||
|
|
|
@ -357,49 +357,25 @@ void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
|||
|
||||
double LIB_EDIT_FRAME::BestZoom()
|
||||
{
|
||||
/* Please, note: wxMSW before version 2.9 seems have
|
||||
* problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched:
|
||||
* edit file <wxWidgets>/src/msw/dc.cpp
|
||||
* search for line static const int VIEWPORT_EXTENT = 1000;
|
||||
* and replace by static const int VIEWPORT_EXTENT = 10000;
|
||||
*/
|
||||
int dx, dy;
|
||||
|
||||
LIB_PART* part = GetCurPart();
|
||||
double defaultLibraryZoom = 7.33;
|
||||
|
||||
if( part )
|
||||
if( !part )
|
||||
{
|
||||
SetScrollCenterPosition( wxPoint( 0, 0 ) );
|
||||
return defaultLibraryZoom;
|
||||
}
|
||||
|
||||
EDA_RECT boundingBox = part->GetUnitBoundingBox( m_unit, m_convert );
|
||||
|
||||
dx = boundingBox.GetWidth();
|
||||
dy = boundingBox.GetHeight();
|
||||
SetScrollCenterPosition( wxPoint( 0, 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
const PAGE_INFO& pageInfo = GetScreen()->GetPageSettings();
|
||||
double sizeX = (double) boundingBox.GetWidth();
|
||||
double sizeY = (double) boundingBox.GetHeight();
|
||||
wxPoint centre = boundingBox.Centre();
|
||||
|
||||
dx = pageInfo.GetSizeIU().x;
|
||||
dy = pageInfo.GetSizeIU().y;
|
||||
// Reserve a 20% margin around component bounding box.
|
||||
double margin_scale_factor = 1.2;
|
||||
|
||||
SetScrollCenterPosition( wxPoint( 0, 0 ) );
|
||||
}
|
||||
|
||||
wxSize size = m_canvas->GetClientSize();
|
||||
|
||||
// Reserve a 10% margin around component bounding box.
|
||||
double margin_scale_factor = 0.8;
|
||||
double zx =(double) dx / ( margin_scale_factor * (double)size.x );
|
||||
double zy = (double) dy / ( margin_scale_factor * (double)size.y );
|
||||
|
||||
double bestzoom = std::max( zx, zy );
|
||||
|
||||
// keep it >= minimal existing zoom (can happen for very small components
|
||||
// for instance when starting a new component
|
||||
if( bestzoom < GetScreen()->m_ZoomList[0] )
|
||||
bestzoom = GetScreen()->m_ZoomList[0];
|
||||
|
||||
return bestzoom;
|
||||
return bestZoom( sizeX, sizeY, margin_scale_factor, centre);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -435,9 +435,6 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
|
|||
|
||||
m_auimgr.Update();
|
||||
|
||||
// Now Drawpanel is sized, we can use BestZoom to show the component (if any)
|
||||
GetScreen()->SetZoom( BestZoom() );
|
||||
|
||||
Zoom_Automatique( false );
|
||||
|
||||
// Net list generator
|
||||
|
@ -718,25 +715,15 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
|||
|
||||
double SCH_EDIT_FRAME::BestZoom()
|
||||
{
|
||||
int dx, dy;
|
||||
wxSize size;
|
||||
double sizeX = (double) GetScreen()->GetPageSettings().GetWidthIU();
|
||||
double sizeY = (double) GetScreen()->GetPageSettings().GetHeightIU();
|
||||
wxPoint centre( wxPoint( sizeX / 2, sizeY / 2 ) );
|
||||
|
||||
dx = GetScreen()->GetPageSettings().GetWidthIU();
|
||||
dy = GetScreen()->GetPageSettings().GetHeightIU();
|
||||
// The sheet boundary already affords us some margin, so add only an
|
||||
// additional 5%.
|
||||
double margin_scale_factor = 1.05;
|
||||
|
||||
size = m_canvas->GetClientSize();
|
||||
|
||||
// Reserve no margin because best zoom shows the full page
|
||||
// and margins are already included in function that draws the sheet refernces
|
||||
double margin_scale_factor = 1.0;
|
||||
double zx =(double) dx / ( margin_scale_factor * (double)size.x );
|
||||
double zy = (double) dy / ( margin_scale_factor * (double)size.y );
|
||||
|
||||
double bestzoom = std::max( zx, zy );
|
||||
|
||||
SetScrollCenterPosition( wxPoint( dx / 2, dy / 2 ) );
|
||||
|
||||
return bestzoom;
|
||||
return bestZoom( sizeX, sizeY, margin_scale_factor, centre );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
|
|||
|
||||
// Now Drawpanel is sized, we can use BestZoom to show the component (if any)
|
||||
#ifdef USE_WX_GRAPHICS_CONTEXT
|
||||
GetScreen()->SetZoom( BestZoom() );
|
||||
GetScreen()->SetScalingFactor( BestZoom() );
|
||||
#else
|
||||
Zoom_Automatique( false );
|
||||
#endif
|
||||
|
@ -369,20 +369,13 @@ void LIB_VIEW_FRAME::OnUpdateElectricalType( wxUpdateUIEvent& aEvent )
|
|||
|
||||
double LIB_VIEW_FRAME::BestZoom()
|
||||
{
|
||||
/* Please, note: wxMSW before version 2.9 seems have
|
||||
* problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched:
|
||||
* edit file <wxWidgets>/src/msw/dc.cpp
|
||||
* search for line static const int VIEWPORT_EXTENT = 1000;
|
||||
* and replace by static const int VIEWPORT_EXTENT = 10000;
|
||||
*/
|
||||
|
||||
LIB_PART* part = NULL;
|
||||
double bestzoom = 16.0; // default value for bestzoom
|
||||
double defaultLibraryZoom = 7.33;
|
||||
|
||||
if( m_libraryName.IsEmpty() || m_entryName.IsEmpty() )
|
||||
{
|
||||
SetScrollCenterPosition( wxPoint( 0, 0 ) );
|
||||
return bestzoom;
|
||||
return defaultLibraryZoom;
|
||||
}
|
||||
|
||||
LIB_ALIAS* alias = nullptr;
|
||||
|
@ -401,29 +394,19 @@ double LIB_VIEW_FRAME::BestZoom()
|
|||
if( !part )
|
||||
{
|
||||
SetScrollCenterPosition( wxPoint( 0, 0 ) );
|
||||
return bestzoom;
|
||||
return defaultLibraryZoom;
|
||||
}
|
||||
|
||||
wxSize size = m_canvas->GetClientSize();
|
||||
|
||||
EDA_RECT boundingBox = part->GetUnitBoundingBox( m_unit, m_convert );
|
||||
|
||||
// Reserve a 10% margin around component bounding box.
|
||||
double margin_scale_factor = 0.8;
|
||||
double zx =(double) boundingBox.GetWidth() / ( margin_scale_factor * (double)size.x );
|
||||
double zy = (double) boundingBox.GetHeight() / ( margin_scale_factor * (double)size.y);
|
||||
double sizeX = (double) boundingBox.GetWidth();
|
||||
double sizeY = (double) boundingBox.GetHeight();
|
||||
wxPoint centre = boundingBox.Centre();
|
||||
|
||||
// Calculates the best zoom
|
||||
bestzoom = std::max( zx, zy );
|
||||
// Reserve a 20% margin around component bounding box.
|
||||
double margin_scale_factor = 1.2;
|
||||
|
||||
// keep it >= minimal existing zoom (can happen for very small components
|
||||
// like small power symbols
|
||||
if( bestzoom < GetScreen()->m_ZoomList[0] )
|
||||
bestzoom = GetScreen()->m_ZoomList[0];
|
||||
|
||||
SetScrollCenterPosition( boundingBox.Centre() );
|
||||
|
||||
return bestzoom;
|
||||
return bestZoom( sizeX, sizeY, margin_scale_factor, centre );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -361,24 +361,23 @@ bool GERBVIEW_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
|
||||
double GERBVIEW_FRAME::BestZoom()
|
||||
{
|
||||
double defaultGerberZoom = 1.0;
|
||||
EDA_RECT bbox = GetGerberLayout()->ComputeBoundingBox();
|
||||
|
||||
// gives a size to bbox (current page size), if no item in list
|
||||
if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 )
|
||||
{
|
||||
wxSize pagesize = GetPageSettings().GetSizeMils();
|
||||
bbox.SetSize( wxSize( Mils2iu( pagesize.x ), Mils2iu( pagesize.y ) ) );
|
||||
SetScrollCenterPosition( wxPoint( 0, 0 ) );
|
||||
return defaultGerberZoom;
|
||||
}
|
||||
|
||||
// Compute best zoom:
|
||||
wxSize size = m_canvas->GetClientSize();
|
||||
double x = (double) bbox.GetWidth() / (double) size.x;
|
||||
double y = (double) bbox.GetHeight() / (double) size.y;
|
||||
double best_zoom = std::max( x, y ) * 1.1;
|
||||
double sizeX = (double) bbox.GetWidth();
|
||||
double sizeY = (double) bbox.GetHeight();
|
||||
wxPoint centre = bbox.Centre();
|
||||
|
||||
SetScrollCenterPosition( bbox.Centre() );
|
||||
// Reserve no margin because GetGerberLayout()->ComputeBoundingBox() builds one in.
|
||||
double margin_scale_factor = 1.0;
|
||||
|
||||
return best_zoom;
|
||||
return bestZoom( sizeX, sizeY, margin_scale_factor, centre );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -149,6 +149,8 @@ protected:
|
|||
|
||||
void SetScreen( BASE_SCREEN* aScreen ) { m_currentScreen = aScreen; }
|
||||
|
||||
double bestZoom( double sizeX, double sizeY, double scaleFactor, wxPoint centre );
|
||||
|
||||
/**
|
||||
* Function unitsChangeRefresh
|
||||
* is called when when the units setting has changed to allow for any derived classes
|
||||
|
|
|
@ -277,25 +277,15 @@ void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
|||
|
||||
double PL_EDITOR_FRAME::BestZoom()
|
||||
{
|
||||
int dx, dy;
|
||||
wxSize size;
|
||||
double sizeX = (double) GetPageLayout().GetPageSettings().GetWidthIU();
|
||||
double sizeY = (double) GetPageLayout().GetPageSettings().GetHeightIU();
|
||||
wxPoint centre( sizeX / 2, sizeY / 2 );
|
||||
|
||||
dx = GetPageLayout().GetPageSettings().GetWidthIU();
|
||||
dy = GetPageLayout().GetPageSettings().GetHeightIU();
|
||||
// The sheet boundary already affords us some margin, so add only an
|
||||
// additional 5%.
|
||||
double margin_scale_factor = 1.05;
|
||||
|
||||
size = m_canvas->GetClientSize();
|
||||
|
||||
// Reserve no margin because best zoom shows the full page
|
||||
// and margins are already included in function that draws the sheet refernces
|
||||
double margin_scale_factor = 1.0;
|
||||
double zx =(double) dx / ( margin_scale_factor * (double)size.x );
|
||||
double zy = (double) dy / ( margin_scale_factor * (double)size.y );
|
||||
|
||||
double bestzoom = std::max( zx, zy );
|
||||
|
||||
SetScrollCenterPosition( wxPoint( dx / 2, dy / 2 ) );
|
||||
|
||||
return bestzoom;
|
||||
return bestZoom( sizeX, sizeY, margin_scale_factor, centre );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl )
|
|||
GetBoard()->SynchronizeNetsAndNetClasses();
|
||||
|
||||
SetStatusText( wxEmptyString );
|
||||
BestZoom();
|
||||
Zoom_Automatique( false );
|
||||
|
||||
// Finish block move command:
|
||||
wxPoint cpos = GetNearestGridPosition( bbox.Centre() );
|
||||
|
|
|
@ -533,7 +533,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
loadedBoard->SynchronizeNetsAndNetClasses();
|
||||
|
||||
SetStatusText( wxEmptyString );
|
||||
BestZoom();
|
||||
Zoom_Automatique( false );
|
||||
|
||||
// update the layer names in the listbox
|
||||
ReCreateLayerBox( false );
|
||||
|
|
|
@ -532,6 +532,21 @@ void FOOTPRINT_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
|
|||
}
|
||||
|
||||
|
||||
double FOOTPRINT_EDIT_FRAME::BestZoom()
|
||||
{
|
||||
EDA_RECT ibbbox = GetBoardBoundingBox();
|
||||
|
||||
double sizeX = (double) ibbbox.GetWidth();
|
||||
double sizeY = (double) ibbbox.GetHeight();
|
||||
|
||||
wxPoint centre = ibbbox.Centre();
|
||||
|
||||
// Reserve a 20% margin around "board" bounding box.
|
||||
double margin_scale_factor = 1.2;
|
||||
return bestZoom( sizeX, sizeY, margin_scale_factor, centre );
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
||||
{
|
||||
if( GetScreen()->IsModify() )
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
void LoadSettings( wxConfigBase* aCfg ) override;
|
||||
void SaveSettings( wxConfigBase* aCfg ) override;
|
||||
|
||||
double BestZoom() override;
|
||||
|
||||
/**
|
||||
* Function GetConfigurationSettings
|
||||
* returns the footpr<EFBFBD>int editor settings list.
|
||||
|
|
|
@ -294,7 +294,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
|
|||
|
||||
// Now Drawpanel is sized, we can use BestZoom to show the component (if any)
|
||||
#ifdef USE_WX_GRAPHICS_CONTEXT
|
||||
GetScreen()->SetZoom( BestZoom() );
|
||||
GetScreen()->SetScalingFactor( BestZoom() );
|
||||
#else
|
||||
Zoom_Automatique( false );
|
||||
#endif
|
||||
|
|
|
@ -211,7 +211,7 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
|
|||
|
||||
// Now Drawpanel is sized, we can use BestZoom to show the component (if any)
|
||||
#ifdef USE_WX_GRAPHICS_CONTEXT
|
||||
GetScreen()->SetZoom( BestZoom() );
|
||||
GetScreen()->SetScalingFactor( BestZoom() );
|
||||
#else
|
||||
Zoom_Automatique( false );
|
||||
#endif
|
||||
|
|
|
@ -322,21 +322,16 @@ EDA_RECT PCB_BASE_FRAME::GetBoardBoundingBox( bool aBoardEdgesOnly ) const
|
|||
|
||||
double PCB_BASE_FRAME::BestZoom()
|
||||
{
|
||||
if( m_Pcb == NULL )
|
||||
return 1.0;
|
||||
|
||||
EDA_RECT ibbbox = GetBoardBoundingBox();
|
||||
DSIZE clientz = m_canvas->GetClientSize();
|
||||
DSIZE boardz( ibbbox.GetWidth(), ibbbox.GetHeight() );
|
||||
|
||||
double iu_per_du_X = clientz.x ? boardz.x / clientz.x : 1.0;
|
||||
double iu_per_du_Y = clientz.y ? boardz.y / clientz.y : 1.0;
|
||||
double sizeX = (double) ibbbox.GetWidth();
|
||||
double sizeY = (double) ibbbox.GetHeight();
|
||||
wxPoint centre = ibbbox.Centre();
|
||||
|
||||
double bestzoom = std::max( iu_per_du_X, iu_per_du_Y );
|
||||
// Reserve a 10% margin around board bounding box.
|
||||
double margin_scale_factor = 1.1;
|
||||
|
||||
SetScrollCenterPosition( ibbbox.Centre() );
|
||||
|
||||
return bestzoom;
|
||||
return bestZoom( sizeX, sizeY, margin_scale_factor, centre );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue