From 18010b1104aa246a0459abfc67f3a492a1c4eb50 Mon Sep 17 00:00:00 2001 From: Mike Williams <mike@mikebwilliams.com> Date: Wed, 19 Mar 2025 10:25:35 -0400 Subject: [PATCH] selection: sort box selection by rows and columns by default Some tools can take a selection order and it is nice to provide a sane human-oriented default sorting when box selecting. --- eeschema/tools/sch_selection_tool.cpp | 18 +++++++++++++++++- pcbnew/tools/pcb_selection_tool.cpp | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/eeschema/tools/sch_selection_tool.cpp b/eeschema/tools/sch_selection_tool.cpp index c517be750f..b86386756f 100644 --- a/eeschema/tools/sch_selection_tool.cpp +++ b/eeschema/tools/sch_selection_tool.cpp @@ -1976,6 +1976,22 @@ bool SCH_SELECTION_TOOL::selectMultiple() } } + std::vector<EDA_ITEM*> sortedNearbyItems( nearbyItems.begin(), nearbyItems.end() ); + + // Sort the filtered selection by rows and columns to have a nice default + // for tools that can use it. + std::sort( sortedNearbyItems.begin(), sortedNearbyItems.end(), + []( EDA_ITEM* a, EDA_ITEM* b ) + { + VECTOR2I aPos = a->GetPosition(); + VECTOR2I bPos = b->GetPosition(); + + if( aPos.y == bPos.y ) + return aPos.x < bPos.x; + + return aPos.y < bPos.y; + } ); + BOX2I selectionRect( area.GetOrigin(), VECTOR2I( width, height ) ); selectionRect.Normalize(); @@ -2011,7 +2027,7 @@ bool SCH_SELECTION_TOOL::selectMultiple() } }; - for( EDA_ITEM* item : nearbyItems ) + for( EDA_ITEM* item : sortedNearbyItems ) { bool selected = false; EDA_ITEM_FLAGS flags = 0; diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index cee1feaa55..e11d7d2849 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -1189,6 +1189,20 @@ bool PCB_SELECTION_TOOL::selectMultiple() FilterCollectorForHierarchy( collector, true ); } + // Sort the filtered selection by rows and columns to have a nice default + // for tools that can use it. + std::sort( collector.begin(), collector.end(), + []( EDA_ITEM* a, EDA_ITEM* b ) + { + VECTOR2I aPos = a->GetPosition(); + VECTOR2I bPos = b->GetPosition(); + + if( aPos.y == bPos.y ) + return aPos.x < bPos.x; + + return aPos.y < bPos.y; + } ); + for( EDA_ITEM* i : collector ) { BOARD_ITEM* item = static_cast<BOARD_ITEM*>( i );