Refactor GetDocumentExtents()

CHANGED: GetDocumentExtents() in 'eda_draw_frame.h' now has a bool
parameter "aIncludeAllVisible" with a default value "true" which makes
it behave as it did before adding parameter.  If "aIncludeAllVisible"
is false, the returned bbox ignores some items depending on which
program it is running in.

CHANGED: Made "Zoom to Objects" use only PCB edge in Pcbnew.  This
allows text, notes, etc outside the PCB edge to be excluded in the
zoom calculation.

CHANGED: Added "Zoom to Objects" to Pcbnew main menu, and to RMB context
menus for Eeschema and Pcbnew.

Fixes https://gitlab.com/kicad/code/kicad/issues/5787
This commit is contained in:
PJM 2020-09-25 00:31:56 -07:00
parent 0783669633
commit d1322e7d1d
22 changed files with 123 additions and 87 deletions

View File

@ -437,6 +437,8 @@ void EDA_DRAW_FRAME::AddStandardSubMenus( TOOL_MENU& aToolMenu )
aMenu.AddItem( ACTIONS::zoomIn, SELECTION_CONDITIONS::ShowAlways, 1000 );
aMenu.AddItem( ACTIONS::zoomOut, SELECTION_CONDITIONS::ShowAlways, 1000 );
aMenu.AddItem( ACTIONS::zoomFitScreen, SELECTION_CONDITIONS::ShowAlways, 1000 );
if( IsType( FRAME_SCH ) || IsType( FRAME_PCB_EDITOR ) )
aMenu.AddItem( ACTIONS::zoomFitObjects, SELECTION_CONDITIONS::ShowAlways, 1000 );
aMenu.AddSeparator( 1000 );
@ -734,7 +736,7 @@ wxPoint EDA_DRAW_FRAME::GetNearestGridPosition( const wxPoint& aPosition ) const
}
const BOX2I EDA_DRAW_FRAME::GetDocumentExtents() const
const BOX2I EDA_DRAW_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
{
return BOX2I();
}

View File

@ -23,22 +23,22 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <base_screen.h>
#include <base_units.h>
#include <bitmaps.h>
#include <tool/actions.h>
#include <tool/tool_manager.h>
#include <eda_draw_frame.h>
#include <class_draw_panel_gal.h>
#include <dialog_configure_paths.h>
#include <eda_draw_frame.h>
#include <gal/graphics_abstraction_layer.h>
#include <id.h>
#include <kiface_i.h>
#include <project.h>
#include <settings/app_settings.h>
#include <tool/actions.h>
#include <tool/common_tools.h>
#include <tool/tool_manager.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <gal/graphics_abstraction_layer.h>
#include <settings/app_settings.h>
#include <base_screen.h>
#include <tool/common_tools.h>
#include <id.h>
#include <project.h>
#include <kiface_i.h>
#include <dialog_configure_paths.h>
#include <base_units.h>
void COMMON_TOOLS::Reset( RESET_REASON aReason )
@ -274,17 +274,21 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
// at init time)
VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
// Currently "Zoom to Objects" is only supported on Eeschema. Support for other
// Currently "Zoom to Objects" is only supported in Eeschema & Pcbnew. Support for other
// programs in the suite can be added as needed.
if( aFitType == ZOOM_FIT_OBJECTS )
{
if( frame->IsType( FRAME_SCH ) )
bBox = view->GetItemsExtents(); // Get a BBox of all items except page and border
if( frame->IsType( FRAME_SCH ) || frame->IsType( FRAME_PCB_EDITOR ) )
{
bBox = m_frame->GetDocumentExtents( false );
}
else
aFitType = ZOOM_FIT_ALL; // Just do a "Zoom to Fit" for unsupported editors
}
// If the screen is empty then use the default view bbox
if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 )
bBox = defaultBox;
@ -299,6 +303,7 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
{
case ZOOM_FIT_ALL:
// Leave a bigger margin for library editors & viewers
if( frame->IsType( FRAME_FOOTPRINT_VIEWER ) || frame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
|| frame->IsType( FRAME_SCH_VIEWER ) || frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
{

View File

@ -1591,10 +1591,4 @@ void VIEW::ShowPreview( bool aShow )
const int VIEW::TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
const BOX2I VIEW::GetItemsExtents() const
{
// To be implemented by subclasses.
return BOX2I();
}
} // namespace KIGFX

View File

@ -767,7 +767,7 @@ void LIB_VIEW_FRAME::SetFilter( const SCHLIB_FILTER* aFilter )
}
const BOX2I LIB_VIEW_FRAME::GetDocumentExtents() const
const BOX2I LIB_VIEW_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
{
LIB_PART* part = GetSelectedSymbol();

View File

@ -143,7 +143,7 @@ public:
LIB_PART* GetSelectedSymbol() const;
const BOX2I GetDocumentExtents() const override;
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override;
SELECTION& GetCurrentSelection() override;

View File

@ -1012,7 +1012,7 @@ void LIB_EDIT_FRAME::HardRedraw()
}
const BOX2I LIB_EDIT_FRAME::GetDocumentExtents() const
const BOX2I LIB_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
{
if( !m_my_part )
{

View File

@ -441,7 +441,7 @@ public:
void SetScreen( BASE_SCREEN* aScreen ) override;
const BOX2I GetDocumentExtents() const override;
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override;
void RebuildView();

View File

@ -71,11 +71,14 @@
#include <tools/sch_editor_control.h>
#include <tools/sch_line_wire_bus_tool.h>
#include <tools/sch_move_tool.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <widgets/infobar.h>
#include <wildcards_and_files_ext.h>
#include <wx/cmdline.h>
#include <gal/graphics_abstraction_layer.h>
#include <ws_proxy_view_item.h>
// non-member so it can be moved easily, and kept REALLY private.
// Do NOT Clear() in here.
@ -1212,12 +1215,44 @@ void SCH_EDIT_FRAME::SetScreen( BASE_SCREEN* aScreen )
}
const BOX2I SCH_EDIT_FRAME::GetDocumentExtents() const
const BOX2I SCH_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
{
BOX2I bBoxDoc;
if( aIncludeAllVisible )
{
// Get the whole page size and return that
int sizeX = GetScreen()->GetPageSettings().GetWidthIU();
int sizeY = GetScreen()->GetPageSettings().GetHeightIU();
bBoxDoc = BOX2I( VECTOR2I( 0, 0 ), VECTOR2I( sizeX, sizeY ) );
}
else
{
// Get current worksheet in a form we can compare to an EDA_ITEM
KIGFX::WS_PROXY_VIEW_ITEM* currWs = SCH_BASE_FRAME::GetCanvas()->GetView()->GetWorksheet();
EDA_ITEM* currWsAsItem = static_cast<EDA_ITEM*>( currWs );
return BOX2I( VECTOR2I(0, 0), VECTOR2I( sizeX, sizeY ) );
// Need an EDA_RECT so the first ".Merge" sees it's uninitialized
EDA_RECT bBoxItems;
// Calc the bounding box of all items on screen except the page border
for( EDA_ITEM* item : GetScreen()->Items() )
{
if( item != currWsAsItem ) // Ignore the worksheet itself
{
if( item->Type() == SCH_COMPONENT_T )
{
// For components we need to get the bounding box without invisible text
SCH_COMPONENT* comp = static_cast<SCH_COMPONENT*>( item );
bBoxItems.Merge( comp->GetBoundingBox( false ) );
}
else
bBoxItems.Merge( item->GetBoundingBox() );
}
bBoxDoc = bBoxItems;
}
}
return bBoxDoc;
}

View File

@ -920,7 +920,7 @@ public:
void SetScreen( BASE_SCREEN* aScreen ) override;
const BOX2I GetDocumentExtents() const override;
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override;
void FixupJunctions();

View File

@ -81,29 +81,6 @@ void SCH_VIEW::SetScale( double aScale, VECTOR2D aAnchor )
}
const BOX2I SCH_VIEW::GetItemsExtents() const
{
// Calc the bounding box of all items on screen except the page border
EDA_RECT bBoxItems;
for( EDA_ITEM* item : m_frame->GetScreen()->Items() )
{
if( item != m_worksheet.get() ) // Ignore the worksheet itself
{
if( item->Type() == SCH_COMPONENT_T )
{
// For components we need to get the bounding box without invisible text
SCH_COMPONENT* comp = static_cast<SCH_COMPONENT*>( item );
bBoxItems.Merge( comp->GetBoundingBox( false ) );
}
else
bBoxItems.Merge( item->GetBoundingBox() );
}
}
return bBoxItems;
}
void SCH_VIEW::ResizeSheetWorkingArea( SCH_SCREEN* aScreen )
{
const PAGE_INFO& page_info = aScreen->GetPageSettings();

View File

@ -88,12 +88,6 @@ public:
void SetScale( double aScale, VECTOR2D aAnchor = { 0, 0 } ) override;
/**
* Return BBox of all items on screen except page and border
*/
const BOX2I GetItemsExtents() const override;
/**
* Clear the hide flag of all items in the view
*/

View File

@ -139,7 +139,7 @@ public:
///> @copydoc EDA_DRAW_FRAME::SetGridColor()
virtual void SetGridColor( COLOR4D aColor ) override;
const BOX2I GetDocumentExtents() const override
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override
{
wxASSERT( m_gerberLayout );
return m_gerberLayout->ViewBBox();

View File

@ -474,10 +474,23 @@ public:
GetCanvas()->Refresh();
}
virtual const BOX2I GetDocumentExtents() const;
/**
* Returns bbox of document with option to not include some items.
*
* Used most commonly by "Zoom to Fit" and "Zoom to Objects". In Eeschema
* for "Zoom to Fit", it's passed "true" to include worksheet border. It's
* passed false by "Zoom To Objects" to ignore worksheet border. In Pcbnew,
* false makes it ignore any items outside the PCB edge such as fabrication
* notes.
*
* @param aIncludeAllVisible - True = Include everything visible in bbox calculations
* False = Ignore some visible items (program dependent)
* @return BOX2I - Bounding box of document (ignoring some items as requested)
*/
virtual const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const;
/**
* Rebuild all toolbars, and update the checked state of ckeck tools
* Rebuild all toolbars, and update the checked state of check tools
*/
void RecreateToolbars();

View File

@ -32,17 +32,18 @@
#define PCB_BASE_FRAME_H
#include <vector>
#include <eda_draw_frame.h>
#include <base_struct.h>
#include <class_board.h>
#include <eda_draw_frame.h>
#include <eda_text.h> // EDA_DRAW_MODE_T
#include <richio.h>
#include <pcb_screen.h>
#include <lib_id.h>
#include <pcb_display_options.h>
#include <pcb_draw_panel_gal.h>
#include <lib_id.h>
#include <pcb_origin_transforms.h>
#include <pcb_screen.h>
#include <richio.h>
#include <vector>
/* Forward declarations of classes. */
class APP_SETTINGS_BASE;
@ -135,9 +136,24 @@ public:
*/
EDA_RECT GetBoardBoundingBox( bool aBoardEdgesOnly = false ) const;
const BOX2I GetDocumentExtents() const override
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override
{
/* "Zoom to Fit" calls this with "aIncludeAllVisible" as true. Since that
* feature always ignored the page and border, this function returns a bbox
* without them as well when passed true. This technically is not all things
* visible, but it keeps behavior consistent.
*
* When passed false, this function returns a bbox of just the board edge.
* This allows things like fabrication text or anything else outside the board
* edge to be ignored, and just zooms up to the board itself.
*
* Calling "GetBoardBoundingBox(true)" when edge cuts are turned off will return bbox of
* entire page and border, so we make sure to do "GetBoardBoundingBox(false)" instead.
*/
if( aIncludeAllVisible || ( !aIncludeAllVisible && !m_Pcb->IsLayerVisible( Edge_Cuts ) ) )
return GetBoardBoundingBox( false );
else
return GetBoardBoundingBox( true );
}
virtual void SetPageSettings( const PAGE_INFO& aPageSettings ) override;

View File

@ -289,11 +289,6 @@ public:
return m_boundary;
}
/**
* Return BBox of all items on screen except page and border
*/
virtual const BOX2I GetItemsExtents() const;
/**
* Function SetScaleLimits()
* Sets minimum and maximum values for scale.

View File

@ -432,7 +432,7 @@ void PL_EDITOR_FRAME::ToPrinter( bool doPreview )
}
const BOX2I PL_EDITOR_FRAME::GetDocumentExtents() const
const BOX2I PL_EDITOR_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
{
BOX2I rv( VECTOR2I( 0, 0 ), GetPageLayout().GetPageSettings().GetSizeIU() );
return rv;

View File

@ -163,7 +163,7 @@ public:
const PL_EDITOR_LAYOUT& GetPageLayout() const { return m_pageLayout; }
PL_EDITOR_LAYOUT& GetPageLayout() { return m_pageLayout; }
const BOX2I GetDocumentExtents() const override;
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override;
/**
* Page layout editor can show the title block using a page number 1 or another number.

View File

@ -502,7 +502,7 @@ MAGNETIC_SETTINGS* FOOTPRINT_EDIT_FRAME::GetMagneticItemsSettings()
}
const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents() const
const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
{
MODULE* module = GetBoard()->GetFirstModule();

View File

@ -87,7 +87,7 @@ public:
COLOR_SETTINGS* GetColorSettings() override;
const BOX2I GetDocumentExtents() const override;
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override;
bool canCloseWindow( wxCloseEvent& Event ) override;
void doCloseWindow() override;

View File

@ -245,6 +245,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
viewMenu->Add( ACTIONS::zoomInCenter );
viewMenu->Add( ACTIONS::zoomOutCenter );
viewMenu->Add( ACTIONS::zoomFitScreen );
viewMenu->Add( ACTIONS::zoomFitObjects );
viewMenu->Add( ACTIONS::zoomTool );
viewMenu->Add( ACTIONS::zoomRedraw );

View File

@ -256,6 +256,7 @@ void PCB_EDIT_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomFitObjects );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->AddScaledSeparator( this );

View File

@ -239,7 +239,7 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
selectPoint( evt->Position() );
}
// right click? if there is any object - show the context menu
// Right click? if there is any object - show the context menu
else if( evt->IsClick( BUT_RIGHT ) )
{
bool selectionCancelled = false;
@ -256,7 +256,7 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
m_menu.ShowContextMenu( m_selection );
}
// double click? Display the properties window
// Double click? Display the properties window
else if( evt->IsDblClick( BUT_LEFT ) )
{
m_frame->FocusOnItem( nullptr );
@ -274,13 +274,16 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
}
}
// Middle double click? Do zoom to fit
// Middle double click? Do zoom to fit or zoom to objects
else if( evt->IsDblClick( BUT_MIDDLE ) )
{
if( m_exclusive_or ) // Is CTRL key down?
m_toolMgr->RunAction( ACTIONS::zoomFitObjects, true );
else
m_toolMgr->RunAction( ACTIONS::zoomFitScreen, true );
}
// drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
// Drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
else if( evt->IsDrag( BUT_LEFT ) )
{
m_frame->FocusOnItem( nullptr );
@ -291,7 +294,7 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
}
else
{
// selection is empty? try to start dragging the item under the point where drag
// Selection is empty? try to start dragging the item under the point where drag
// started
if( m_selection.Empty() && selectCursor() )
m_selection.SetIsHover( true );