diff --git a/pcbnew/connectivity.cpp b/pcbnew/connectivity.cpp index e5627817ff..b1c15a2dad 100644 --- a/pcbnew/connectivity.cpp +++ b/pcbnew/connectivity.cpp @@ -275,7 +275,12 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector& void CONNECTIVITY_DATA::ClearDynamicRatsnest() { m_connAlgo->ForEachAnchor( [] (CN_ANCHOR_PTR anchor ) { anchor->SetNoLine( false ); } ); + HideDynamicRatsnest(); +} + +void CONNECTIVITY_DATA::HideDynamicRatsnest() +{ m_dynamicConnectivity.reset(); m_dynamicRatsnest.clear(); } diff --git a/pcbnew/connectivity.h b/pcbnew/connectivity.h index bcd5cfa491..b9df91406a 100644 --- a/pcbnew/connectivity.h +++ b/pcbnew/connectivity.h @@ -164,11 +164,16 @@ public: /** * Function ClearDynamicRatsnest() - * Erases the temporary dynamic ratsnest (i.e. the ratsnest lines that) - * pcbnew displays when moving an item/set of items + * Erases the temporary dynamic ratsnest (i.e. the ratsnest lines that + * pcbnew displays when moving an item/set of items) */ void ClearDynamicRatsnest(); + /** + * Hides the temporary dynamic ratsnest lines. + */ + void HideDynamicRatsnest(); + /** * Function ComputeDynamicRatsnest() * Calculates the temporary dynamic ratsnest (i.e. the ratsnest lines that) diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 461573aa9f..e97b2becbc 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -375,6 +375,13 @@ bool PCB_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType ) } +void PCB_DRAW_PANEL_GAL::RedrawRatsnest() +{ + if( m_ratsnest ) + m_view->Update( m_ratsnest.get() ); +} + + void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps() { // caching makes no sense for Cairo and other software renderers diff --git a/pcbnew/pcb_draw_panel_gal.h b/pcbnew/pcb_draw_panel_gal.h index 605b3780e7..1db0825ecc 100644 --- a/pcbnew/pcb_draw_panel_gal.h +++ b/pcbnew/pcb_draw_panel_gal.h @@ -99,6 +99,9 @@ public: bool SwitchBackend( GAL_TYPE aGalType ) override; + ///> Forces refresh of the ratsnest visual representation + void RedrawRatsnest(); + protected: ///> Reassigns layer order to the initial settings. void setDefaultLayerOrder(); diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index 26074d94b9..34528d7aa6 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include @@ -53,6 +53,7 @@ #include #include #include +#include #include @@ -239,6 +240,7 @@ PCB_EDITOR_CONTROL::PCB_EDITOR_CONTROL() : m_placeOrigin.reset( new KIGFX::ORIGIN_VIEWITEM( KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ), KIGFX::ORIGIN_VIEWITEM::CIRCLE_CROSS ) ); m_probingSchToPcb = false; + m_slowRatsnest = false; } @@ -309,6 +311,10 @@ bool PCB_EDITOR_CONTROL::Init() menu.AddMenu( zoneMenu.get(), false, toolActiveFunctor( DRAWING_TOOL::MODE::ZONE ) ); } + m_ratsnestTimer.SetOwner( this ); + Connect( m_ratsnestTimer.GetId(), wxEVT_TIMER, + wxTimerEventHandler( PCB_EDITOR_CONTROL::ratsnestTimer ), NULL, this ); + return true; } @@ -1138,21 +1144,32 @@ int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent ) { auto selectionTool = m_toolMgr->GetTool(); auto& selection = selectionTool->GetSelection(); + auto connectivity = getModel()->GetConnectivity(); if( selection.Empty() ) { - getModel()->GetConnectivity()->ClearDynamicRatsnest(); + connectivity->ClearDynamicRatsnest(); + } + else if( m_slowRatsnest ) + { + // Compute ratsnest only when user stops dragging for a moment + connectivity->HideDynamicRatsnest(); + m_ratsnestTimer.Start( 40 ); } else { - auto connectivity = getModel()->GetConnectivity(); - std::vector items; - items.reserve( selection.Size() ); + // Check how much time doest it take to calculate ratsnest + PROF_COUNTER counter; + calculateSelectionRatsnest(); + counter.Stop(); - for( auto item : selection ) - items.push_back( static_cast( item ) ); - - connectivity->ComputeDynamicRatsnest( items ); + // If it is too slow, then switch to 'slow ratsnest' mode when + // ratsnest is calculated when user stops dragging items for a moment + if( counter.msecs() > 10 ) + { + m_slowRatsnest = true; + connectivity->HideDynamicRatsnest(); + } } return 0; @@ -1162,11 +1179,35 @@ int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent ) int PCB_EDITOR_CONTROL::HideSelectionRatsnest( const TOOL_EVENT& aEvent ) { getModel()->GetConnectivity()->ClearDynamicRatsnest(); - + m_slowRatsnest = false; return 0; } +void PCB_EDITOR_CONTROL::ratsnestTimer( wxTimerEvent& aEvent ) +{ + m_ratsnestTimer.Stop(); + calculateSelectionRatsnest(); + static_cast( m_frame->GetGalCanvas() )->RedrawRatsnest(); + m_frame->GetGalCanvas()->Refresh(); +} + + +void PCB_EDITOR_CONTROL::calculateSelectionRatsnest() +{ + auto selectionTool = m_toolMgr->GetTool(); + auto& selection = selectionTool->GetSelection(); + auto connectivity = getModel()->GetConnectivity(); + std::vector items; + items.reserve( selection.Size() ); + + for( auto item : selection ) + items.push_back( static_cast( item ) ); + + connectivity->ComputeDynamicRatsnest( items ); +} + + void PCB_EDITOR_CONTROL::setTransitions() { // Track & via size control diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h index 1daa86c4bb..49539a2209 100644 --- a/pcbnew/tools/pcb_editor_control.h +++ b/pcbnew/tools/pcb_editor_control.h @@ -38,7 +38,7 @@ class PCB_EDIT_FRAME; * * Handles actions specific to the board editor in pcbnew. */ -class PCB_EDITOR_CONTROL : public PCB_TOOL +class PCB_EDITOR_CONTROL : public wxEvtHandler, public PCB_TOOL { public: PCB_EDITOR_CONTROL(); @@ -111,10 +111,16 @@ public: ///> Shows local ratsnest of a component int ShowLocalRatsnest( const TOOL_EVENT& aEvent ); +private: + ///> Event handler to recalculate dynamic ratsnest + void ratsnestTimer( wxTimerEvent& aEvent ); + + ///> Recalculates dynamic ratsnest for the current selection + void calculateSelectionRatsnest(); + ///> Sets up handlers for various events. void setTransitions() override; -private: ///> Pointer to the currently used edit frame. PCB_EDIT_FRAME* m_frame; @@ -124,6 +130,12 @@ private: ///> Flag to ignore a single crossprobe message from eeschema. bool m_probingSchToPcb; + ///> Flag to indicate whether the current selection ratsnest is slow to calculate. + bool m_slowRatsnest; + + ///> Timer that start ratsnest calculation when it is slow to compute. + wxTimer m_ratsnestTimer; + ///> How to modify a property for selected items. enum MODIFY_MODE { ON, OFF, TOGGLE };