From 88f7c55d9592488d8dafc6d111a164f64d074d3b Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Wed, 22 Feb 2017 23:31:26 -0500 Subject: [PATCH] Move ZoomFitScreen and ZoomPreset from PCBNEW_CONTROL to COMMON_TOOLS BOARD::GetBoundingBox() now directly calls BOARD::ComputeBoundingBox() and there is a new method BOARD::GetBoardEdgesBoundingBox() used for call sites that needed to use ComputeBoundingBox( true ) in the past. This allows COMMON_TOOLS to implement ZoomFitScreen without knowledge of the BOARD class. --- common/tool/common_tools.cpp | 65 ++++++++++++++++++++ include/tool/common_tools.h | 2 + pcbnew/autorouter/auto_place_footprints.cpp | 2 +- pcbnew/autorouter/routing_matrix.cpp | 4 +- pcbnew/autorouter/spread_footprints.cpp | 2 +- pcbnew/basepcbframe.cpp | 2 +- pcbnew/board_netlist_updater.cpp | 2 +- pcbnew/class_board.cpp | 5 +- pcbnew/class_board.h | 21 ++++++- pcbnew/dialogs/dialog_export_idf.cpp | 2 +- pcbnew/dialogs/dialog_update_pcb.cpp | 2 +- pcbnew/eagle_plugin.cpp | 2 +- pcbnew/exporters/export_idf.cpp | 2 +- pcbnew/exporters/gen_drill_report_files.cpp | 2 +- pcbnew/netlist.cpp | 2 +- pcbnew/specctra_export.cpp | 2 +- pcbnew/tools/pcbnew_control.cpp | 68 --------------------- pcbnew/tools/pcbnew_control.h | 4 -- 18 files changed, 100 insertions(+), 91 deletions(-) diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp index 46965291d6..d512cd834c 100644 --- a/common/tool/common_tools.cpp +++ b/common/tool/common_tools.cpp @@ -98,6 +98,69 @@ int COMMON_TOOLS::ZoomCenter( const TOOL_EVENT& aEvent ) } +int COMMON_TOOLS::ZoomFitScreen( const TOOL_EVENT& aEvent ) +{ + KIGFX::VIEW* view = getView(); + EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas(); + EDA_ITEM* model = getModel(); + + BOX2I bBox = model->ViewBBox(); + VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() ); + VECTOR2D screenSize = view->ToWorld( galCanvas->GetClientSize(), false ); + + if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 ) + { + // Empty view + view->SetScale( 17.0 ); // works fine for the standard worksheet frame + + view->SetCenter( screenSize / 2.0 ); + } + else + { + VECTOR2D vsize = bBox.GetSize(); + double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ), + fabs( vsize.y / screenSize.y ) ); + + view->SetScale( scale ); + view->SetCenter( bBox.Centre() ); + } + + + // Take scrollbars into account + VECTOR2D worldScrollbarSize = view->ToWorld( scrollbarSize, false ); + view->SetCenter( view->GetCenter() + worldScrollbarSize / 2.0 ); + + return 0; +} + + +int COMMON_TOOLS::ZoomPreset( const TOOL_EVENT& aEvent ) +{ + unsigned int idx = aEvent.Parameter(); + std::vector& zoomList = m_frame->GetScreen()->m_ZoomList; + KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); + KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL(); + + m_frame->SetPresetZoom( idx ); + + if( idx == 0 ) // Zoom Auto + { + return ZoomFitScreen( aEvent ); + } + else if( idx >= zoomList.size() ) + { + assert( false ); + return 0; + } + + double selectedZoom = zoomList[idx]; + double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); + view->SetScale( 1.0 / ( zoomFactor * selectedZoom ) ); + + return 0; +} + + // Grid control int COMMON_TOOLS::GridNext( const TOOL_EVENT& aEvent ) { @@ -135,6 +198,8 @@ void COMMON_TOOLS::SetTransitions() Go( &COMMON_TOOLS::ZoomInOutCenter, ACTIONS::zoomInCenter.MakeEvent() ); Go( &COMMON_TOOLS::ZoomInOutCenter, ACTIONS::zoomOutCenter.MakeEvent() ); Go( &COMMON_TOOLS::ZoomCenter, ACTIONS::zoomCenter.MakeEvent() ); + Go( &COMMON_TOOLS::ZoomFitScreen, ACTIONS::zoomFitScreen.MakeEvent() ); + Go( &COMMON_TOOLS::ZoomPreset, ACTIONS::zoomPreset.MakeEvent() ); Go( &COMMON_TOOLS::GridNext, ACTIONS::gridNext.MakeEvent() ); Go( &COMMON_TOOLS::GridPrev, ACTIONS::gridPrev.MakeEvent() ); diff --git a/include/tool/common_tools.h b/include/tool/common_tools.h index c37d0cd2d3..9f604026f5 100644 --- a/include/tool/common_tools.h +++ b/include/tool/common_tools.h @@ -48,6 +48,8 @@ public: int ZoomInOut( const TOOL_EVENT& aEvent ); int ZoomInOutCenter( const TOOL_EVENT& aEvent ); int ZoomCenter( const TOOL_EVENT& aEvent ); + int ZoomFitScreen( const TOOL_EVENT& aEvent ); + int ZoomPreset( const TOOL_EVENT& aEvent ); // Grid control int GridNext( const TOOL_EVENT& aEvent ); diff --git a/pcbnew/autorouter/auto_place_footprints.cpp b/pcbnew/autorouter/auto_place_footprints.cpp index 2de743e6f2..ddb75bed75 100644 --- a/pcbnew/autorouter/auto_place_footprints.cpp +++ b/pcbnew/autorouter/auto_place_footprints.cpp @@ -459,7 +459,7 @@ int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel ) RoutingMatrix.UnInitRoutingMatrix(); - EDA_RECT bbox = aBrd->ComputeBoundingBox( true ); + EDA_RECT bbox = aBrd->GetBoardEdgesBoundingBox(); if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 ) { diff --git a/pcbnew/autorouter/routing_matrix.cpp b/pcbnew/autorouter/routing_matrix.cpp index f3daa2e793..94163641e1 100644 --- a/pcbnew/autorouter/routing_matrix.cpp +++ b/pcbnew/autorouter/routing_matrix.cpp @@ -69,10 +69,8 @@ MATRIX_ROUTING_HEAD::~MATRIX_ROUTING_HEAD() bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly ) { - aPcb->ComputeBoundingBox( aUseBoardEdgesOnly ); - // The boundary box must have its start point on routing grid: - m_BrdBox = aPcb->GetBoundingBox(); + m_BrdBox = aUseBoardEdgesOnly ? aPcb->GetBoardEdgesBoundingBox() : aPcb->GetBoundingBox(); m_BrdBox.SetX( m_BrdBox.GetX() - ( m_BrdBox.GetX() % m_GridRouting ) ); m_BrdBox.SetY( m_BrdBox.GetY() - ( m_BrdBox.GetY() % m_GridRouting ) ); diff --git a/pcbnew/autorouter/spread_footprints.cpp b/pcbnew/autorouter/spread_footprints.cpp index 2502ae4aa1..d23d5ea86b 100644 --- a/pcbnew/autorouter/spread_footprints.cpp +++ b/pcbnew/autorouter/spread_footprints.cpp @@ -177,7 +177,7 @@ void PCB_EDIT_FRAME::SpreadFootprints( std::vector* aFootprints, wxPoint aSpreadAreaPosition, bool aPrepareUndoCommand ) { - EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true ); + EDA_RECT bbox = GetBoard()->GetBoardEdgesBoundingBox(); bool edgesExist = bbox.GetWidth() || bbox.GetHeight(); // if aFootprintsOutsideBoardOnly is true, and if board outline exists, // we have to filter footprints to move: diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 0636e6b048..d192bb2a14 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -294,7 +294,7 @@ EDA_RECT PCB_BASE_FRAME::GetBoardBoundingBox( bool aBoardEdgesOnly ) const { wxASSERT( m_Pcb ); - EDA_RECT area = m_Pcb->ComputeBoundingBox( aBoardEdgesOnly ); + EDA_RECT area = aBoardEdgesOnly ? m_Pcb->GetBoardEdgesBoundingBox() : m_Pcb->GetBoundingBox(); if( area.GetWidth() == 0 && area.GetHeight() == 0 ) { diff --git a/pcbnew/board_netlist_updater.cpp b/pcbnew/board_netlist_updater.cpp index 0d32d02cdf..d531b05d99 100644 --- a/pcbnew/board_netlist_updater.cpp +++ b/pcbnew/board_netlist_updater.cpp @@ -79,7 +79,7 @@ wxPoint BOARD_NETLIST_UPDATER::estimateComponentInsertionPosition() if( !m_board->IsEmpty() ) { // Position new components below any existing board features. - EDA_RECT bbox = m_board->ComputeBoundingBox( true ); + EDA_RECT bbox = m_board->GetBoardEdgesBoundingBox(); if( bbox.GetWidth() || bbox.GetHeight() ) { diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 4d672ab59b..f8ace58b83 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1054,7 +1054,7 @@ unsigned BOARD::GetNodesCount() const } -EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) +EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const { bool hasItems = false; EDA_RECT area; @@ -2364,6 +2364,7 @@ ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, LAYER_ID layer, int x m_ZoneDescriptorList.push_back( new_area ); new_area->Outline()->Start( layer, x, y, hatch ); + return new_area; } @@ -2425,7 +2426,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, if( !IsEmpty() ) { // Position new components below any existing board features. - EDA_RECT bbbox = ComputeBoundingBox( true ); + EDA_RECT bbbox = GetBoardEdgesBoundingBox(); if( bbbox.GetWidth() || bbbox.GetHeight() ) { diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 1045e6da57..07a95d036f 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -185,7 +185,7 @@ private: int m_fileFormatVersionAtLoad; ///< the version loaded from the file - EDA_RECT m_BoundingBox; + mutable EDA_RECT m_BoundingBox; NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints .. RN_DATA* m_ratsnest; @@ -825,7 +825,7 @@ public: * @return EDA_RECT - the board's bounding box * @see PCB_BASE_FRAME::GetBoardBoundingBox() which calls this and doctors the result */ - EDA_RECT ComputeBoundingBox( bool aBoardEdgesOnly = false ); + EDA_RECT ComputeBoundingBox( bool aBoardEdgesOnly = false ) const; /** * Function GetBoundingBox @@ -833,7 +833,22 @@ public: * as long as the BOARD has not changed. Remember, ComputeBoundingBox()'s * aBoardEdgesOnly argument is considered in this return value also. */ - const EDA_RECT GetBoundingBox() const override { return m_BoundingBox; } + const EDA_RECT GetBoundingBox() const override + { + return ComputeBoundingBox(); + } + + /** + * Function GetBoardEdgesBoundingBox + * Returns the board bounding box calculated using exclusively the board edges (graphics + * on Edge.Cuts layer). If there are items outside of the area limited by Edge.Cuts graphics, + * the items will not be taken into account. + * @return bounding box calculated using exclusively the board edges. + */ + const EDA_RECT GetBoardEdgesBoundingBox() const + { + return ComputeBoundingBox( true ); + } void SetBoundingBox( const EDA_RECT& aBox ) { m_BoundingBox = aBox; } diff --git a/pcbnew/dialogs/dialog_export_idf.cpp b/pcbnew/dialogs/dialog_export_idf.cpp index 80c55ef594..4f72767799 100644 --- a/pcbnew/dialogs/dialog_export_idf.cpp +++ b/pcbnew/dialogs/dialog_export_idf.cpp @@ -183,7 +183,7 @@ void PCB_EDIT_FRAME::OnExportIDF3( wxCommandEvent& event ) if( dlg.GetAutoAdjustOffset() ) { - EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true ); + EDA_RECT bbox = GetBoard()->GetBoardEdgesBoundingBox(); aXRef = bbox.Centre().x * MM_PER_IU; aYRef = bbox.Centre().y * MM_PER_IU; diff --git a/pcbnew/dialogs/dialog_update_pcb.cpp b/pcbnew/dialogs/dialog_update_pcb.cpp index b291a0a7cf..ea10825be2 100644 --- a/pcbnew/dialogs/dialog_update_pcb.cpp +++ b/pcbnew/dialogs/dialog_update_pcb.cpp @@ -70,7 +70,7 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun ) // keep trace of the initial baord area, if we want to place new footprints // outside the existinag board - EDA_RECT bbox = board->ComputeBoundingBox( false ); + EDA_RECT bbox = board->GetBoundingBox(); if( !aDryRun ) { diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 3913f29a25..21efba876b 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -2991,7 +2991,7 @@ void EAGLE_PLUGIN::centerBoard() if( m_props->Value( "page_width", &page_width ) && m_props->Value( "page_height", &page_height ) ) { - EDA_RECT bbbox = m_board->ComputeBoundingBox( true ); + EDA_RECT bbbox = m_board->GetBoardEdgesBoundingBox(); int w = atoi( page_width.c_str() ); int h = atoi( page_height.c_str() ); diff --git a/pcbnew/exporters/export_idf.cpp b/pcbnew/exporters/export_idf.cpp index dffceab5ce..ae8b318364 100644 --- a/pcbnew/exporters/export_idf.cpp +++ b/pcbnew/exporters/export_idf.cpp @@ -199,7 +199,7 @@ UseBoundingBox: // there is always some uncertainty in the board dimensions // computed via ComputeBoundingBox() since this depends on the // individual module entities. - EDA_RECT bbbox = aPcb->ComputeBoundingBox( true ); + EDA_RECT bbbox = aPcb->GetBoardEdgesBoundingBox(); // convert to mm and compensate for an assumed LINE_WIDTH line thickness double x = ( bbbox.GetOrigin().x + LINE_WIDTH / 2 ) * scale + offX; diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp index ffc9459a79..06b69c854e 100644 --- a/pcbnew/exporters/gen_drill_report_files.cpp +++ b/pcbnew/exporters/gen_drill_report_files.cpp @@ -70,7 +70,7 @@ bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName, const PAGE_INFO& page_info = m_pageInfo ? *m_pageInfo : dummy; // Calculate dimensions and center of PCB - EDA_RECT bbbox = m_pcb->ComputeBoundingBox( true ); + EDA_RECT bbbox = m_pcb->GetBoardEdgesBoundingBox(); // Calculate the scale for the format type, scale 1 in HPGL, drawing on // an A4 sheet in PS, + text description of symbols diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index a2decdc50b..c0a836abee 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -72,7 +72,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, std::vector newFootprints; // keep trace of the initial baord area, if we want to place new footprints // outside the existinag board - EDA_RECT bbox = board->ComputeBoundingBox( false ); + EDA_RECT bbox = board->GetBoundingBox(); netlist.SetIsDryRun( aIsDryRun ); netlist.SetFindByTimeStamp( aSelectByTimeStamp ); diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index eb2c7e51c3..3e8e99fbb3 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1396,7 +1396,7 @@ bool SPECCTRA_DB::GetBoardPolygonOutlines( BOARD* aBoard, if( aErrorText ) *aErrorText = ioe.What(); - EDA_RECT bbbox = aBoard->ComputeBoundingBox( true ); + EDA_RECT bbbox = aBoard->GetBoardEdgesBoundingBox(); // Ensure non null area. If happen, gives a minimal size. if( ( bbbox.GetWidth() ) == 0 || ( bbbox.GetHeight() == 0 ) ) diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 3ff1cc3dbb..3c6b08e527 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -251,70 +251,6 @@ void PCBNEW_CONTROL::Reset( RESET_REASON aReason ) } -int PCBNEW_CONTROL::ZoomFitScreen( const TOOL_EVENT& aEvent ) -{ - KIGFX::VIEW* view = getView(); - EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas(); - BOARD* board = getModel(); - board->ComputeBoundingBox(); - - BOX2I boardBBox = board->ViewBBox(); - VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() ); - VECTOR2D screenSize = view->ToWorld( galCanvas->GetClientSize(), false ); - - if( boardBBox.GetWidth() == 0 || boardBBox.GetHeight() == 0 ) - { - // Empty view - view->SetScale( 17.0 ); // works fine for the standard worksheet frame - - view->SetCenter( screenSize / 2.0 ); - } - else - { - VECTOR2D vsize = boardBBox.GetSize(); - double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ), - fabs( vsize.y / screenSize.y ) ); - - view->SetScale( scale ); - view->SetCenter( boardBBox.Centre() ); - } - - - // Take scrollbars into account - VECTOR2D worldScrollbarSize = view->ToWorld( scrollbarSize, false ); - view->SetCenter( view->GetCenter() + worldScrollbarSize / 2.0 ); - - return 0; -} - - -int PCBNEW_CONTROL::ZoomPreset( const TOOL_EVENT& aEvent ) -{ - unsigned int idx = aEvent.Parameter(); - std::vector& zoomList = m_frame->GetScreen()->m_ZoomList; - KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); - KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL(); - - m_frame->SetPresetZoom( idx ); - - if( idx == 0 ) // Zoom Auto - { - return ZoomFitScreen( aEvent ); - } - else if( idx >= zoomList.size() ) - { - assert( false ); - return 0; - } - - double selectedZoom = zoomList[idx]; - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - view->SetScale( 1.0 / ( zoomFactor * selectedZoom ) ); - - return 0; -} - - int PCBNEW_CONTROL::TrackDisplayMode( const TOOL_EVENT& aEvent ) { auto painter = static_cast( getView()->GetPainter() ); @@ -998,10 +934,6 @@ int PCBNEW_CONTROL::ToBeDone( const TOOL_EVENT& aEvent ) void PCBNEW_CONTROL::SetTransitions() { - // View controls - Go( &PCBNEW_CONTROL::ZoomFitScreen, ACTIONS::zoomFitScreen.MakeEvent() ); - Go( &PCBNEW_CONTROL::ZoomPreset, ACTIONS::zoomPreset.MakeEvent() ); - // Display modes Go( &PCBNEW_CONTROL::TrackDisplayMode, PCB_ACTIONS::trackDisplayMode.MakeEvent() ); Go( &PCBNEW_CONTROL::PadDisplayMode, PCB_ACTIONS::padDisplayMode.MakeEvent() ); diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index 2e017cb05a..946b185c19 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -48,10 +48,6 @@ public: /// @copydoc TOOL_INTERACTIVE::Reset() void Reset( RESET_REASON aReason ) override; - // View controls - int ZoomFitScreen( const TOOL_EVENT& aEvent ); - int ZoomPreset( const TOOL_EVENT& aEvent ); - // Display modes int TrackDisplayMode( const TOOL_EVENT& aEvent ); int PadDisplayMode( const TOOL_EVENT& aEvent );