diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 6216914cac..f3a7201573 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -509,8 +509,6 @@ void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode */ std::vector< SCH_ITEM* > junctions; - printf("DrawScreen\n"); - // Ensure links are up to date, even if a library was reloaded for some reason: UpdateSymbolLinks(); diff --git a/eeschema/sch_view.cpp b/eeschema/sch_view.cpp index 802dd1e048..ae9e6a6742 100644 --- a/eeschema/sch_view.cpp +++ b/eeschema/sch_view.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,31 @@ SCH_VIEW::~SCH_VIEW() } +static const LAYER_NUM SCH_LAYER_ORDER[] = +{ + LAYER_GP_OVERLAY, + LAYER_DRC, + LAYER_WORKSHEET +}; + + +void SCH_VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority ) +{ + // store the bounding box as eeschema can change them at weird moments (i.e.) + // while changing/resolving library references, resulting in incorrect bboxes + // and invisible components + m_cachedBBoxes[ aItem ] = aItem->ViewBBox(); + + VIEW::Add( aItem, aDrawPriority ); +} + +void SCH_VIEW::Remove( VIEW_ITEM* aItem ) +{ + m_cachedBBoxes.erase( aItem ); + + VIEW::Remove( aItem ); +} + void SCH_VIEW::DisplaySheet( SCH_SCREEN *aSheet ) { @@ -106,7 +132,7 @@ void SCH_VIEW::ClearPreview() delete item; m_previewItems.clear(); - Update( m_preview.get() ); + Update(m_preview.get()); } @@ -156,5 +182,45 @@ void SCH_VIEW::HideWorksheet() } +void SCH_VIEW::Redraw() +{ + std::set toUpdate; + BOX2I rect; + rect.SetMaximum(); + + auto visitor = [&]( VIEW_ITEM* aItem ) -> bool { + auto cached = m_cachedBBoxes.find( aItem ); + const auto bb = aItem->ViewBBox(); + + if( cached == m_cachedBBoxes.end() ) + { + m_cachedBBoxes[aItem] = bb; + return true; + } + + if( bb != cached->second ) + { + Update( aItem, KIGFX::GEOMETRY ); + m_cachedBBoxes[aItem] = bb; + } + + return true; + }; + + /* HACK: since eeschema doesn't have any notification mechanism for changing sch items' geometry, + the bounding boxes may become inconsistend with the VIEW Rtree causing disappearing components + (depending on the zoom level). This code keeps a cache of bboxes and checks (at every redraw) if + they haven't changed wrs to the cached version. It eats up some extra CPU cycles, but for the + complexity of schematics's graphics it has negligible effect on perforamance. + */ + + for( auto i = m_orderedLayers.rbegin(); i != m_orderedLayers.rend(); ++i ) + { + ( *i )->items->Query( rect, visitor ); + } + + VIEW::Redraw(); +} + }; diff --git a/eeschema/sch_view.h b/eeschema/sch_view.h index 0550b3f469..c6bdbadba1 100644 --- a/eeschema/sch_view.h +++ b/eeschema/sch_view.h @@ -3,7 +3,7 @@ #include #include - +#include #include #include @@ -29,6 +29,9 @@ public: SCH_VIEW( bool aIsDynamic ); ~SCH_VIEW(); + virtual void Add( VIEW_ITEM* aItem, int aDrawPriority = -1 ) override; + virtual void Remove( VIEW_ITEM* aItem ) override; + void DisplaySheet( SCH_SHEET *aSheet ); void DisplaySheet( SCH_SCREEN *aSheet ); void DisplayComponent( LIB_PART *aPart ); @@ -46,12 +49,14 @@ public: void ClearHiddenFlags(); void HideWorksheet(); + virtual void Redraw() override; + private: std::unique_ptr m_worksheet; std::unique_ptr m_selectionArea; std::unique_ptr m_preview; - std::vector m_previewItems; + std::unordered_map m_cachedBBoxes; }; }; // namespace