diff --git a/common/tool/selection.cpp b/common/tool/selection.cpp index d9155358f1..d44360a1d0 100644 --- a/common/tool/selection.cpp +++ b/common/tool/selection.cpp @@ -38,7 +38,10 @@ void SELECTION::Add( EDA_ITEM* aItem ) if( i == m_items.end() || *i > aItem ) { + m_itemsOrders.insert( m_itemsOrders.begin() + std::distance( m_items.begin(), i ), + m_orderCounter ); m_items.insert( i, aItem ); + m_orderCounter++; m_lastAddedItem = aItem; } } @@ -50,6 +53,7 @@ void SELECTION::Remove( EDA_ITEM* aItem ) if( !( i == m_items.end() || *i > aItem ) ) { + m_itemsOrders.erase( m_itemsOrders.begin() + std::distance( m_items.begin(), i ) ); m_items.erase( i ); if( aItem == m_lastAddedItem ) @@ -193,3 +197,33 @@ bool SELECTION::OnlyContains( std::vector aList ) const return ok; } ) ); } + + +const std::vector SELECTION::GetItemsSortedBySelectionOrder() const +{ + using pairedIterators = + std::pair; + + // Create a vector of all {selection item, selection order} iterator pairs + std::vector pairs; + auto item = m_items.begin(); + auto order = m_itemsOrders.begin(); + + for( ; item != m_items.end(); ++item, ++order ) + pairs.emplace_back( make_pair( item, order ) ); + + // Sort the pairs by the selection order + std::sort( pairs.begin(), pairs.end(), + []( pairedIterators const& a, pairedIterators const& b ) + { + return *a.second < *b.second; + } ); + + // Make a vector of just the sortedItems + std::vector sortedItems; + + for( pairedIterators sortedItem : pairs ) + sortedItems.emplace_back( *sortedItem.first ); + + return sortedItems; +} diff --git a/include/tool/selection.h b/include/tool/selection.h index 33d2caeb75..59eb30ab93 100644 --- a/include/tool/selection.h +++ b/include/tool/selection.h @@ -42,21 +42,26 @@ public: { m_isHover = false; m_lastAddedItem = nullptr; + m_orderCounter = 0; } SELECTION( const SELECTION& aOther ) : KIGFX::VIEW_GROUP::VIEW_GROUP() { m_items = aOther.m_items; + m_itemsOrders = aOther.m_itemsOrders; m_isHover = aOther.m_isHover; m_lastAddedItem = aOther.m_lastAddedItem; + m_orderCounter = aOther.m_orderCounter; } SELECTION& operator= ( const SELECTION& aOther ) { m_items = aOther.m_items; + m_itemsOrders = aOther.m_itemsOrders; m_isHover = aOther.m_isHover; m_lastAddedItem = aOther.m_lastAddedItem; + m_orderCounter = aOther.m_orderCounter; return *this; } @@ -85,6 +90,8 @@ public: virtual void Clear() override { m_items.clear(); + m_itemsOrders.clear(); + m_orderCounter = 0; } virtual unsigned int GetSize() const override @@ -157,6 +164,8 @@ public: return sorted_items; } + const std::vector GetItemsSortedBySelectionOrder() const; + /// Returns the center point of the selection area bounding box. virtual VECTOR2I GetCenter() const; @@ -266,6 +275,8 @@ public: protected: std::optional m_referencePoint; std::deque m_items; + std::deque m_itemsOrders; + int m_orderCounter; EDA_ITEM* m_lastAddedItem; bool m_isHover;