33#include < SFGUI/Engine.hpp>
44#include < SFGUI/RenderQueue.hpp>
55#include < SFGUI/Widgets.hpp>
6+
7+ #include < algorithm>
8+
69#include < SFML/Graphics.hpp>
710
811namespace sfg {
@@ -87,7 +90,7 @@ ListBox::IndexType ListBox::GetHighlightedItem() const {
8790}
8891
8992bool ListBox::IsItemSelected (IndexType index) const {
90- return std::find ( m_selected_items.begin (), m_selected_items. end (), index) != m_selected_items.end ();
93+ return m_selected_items.find ( index ) != m_selected_items.end ();
9194}
9295
9396ListBox::IndexType ListBox::GetSelectedItemsCount () const {
@@ -97,11 +100,14 @@ ListBox::IndexType ListBox::GetSelectedItemsCount() const {
97100ListBox::IndexType ListBox::GetSelectedItemIndex ( IndexType index ) const {
98101 if ( index >= m_selected_items.size () )
99102 return NONE;
100- return m_selected_items[ index ];
103+
104+ auto it = m_selected_items.cbegin ();
105+ std::advance ( it, index );
106+ return *it;
101107}
102108
103109const sf::String& ListBox::GetSelectedItemText ( IndexType index ) const {
104- return m_items[ m_selected_items[ index ] ];
110+ return m_items[ GetSelectedItemIndex ( index ) ];
105111}
106112
107113ListBox::IndexType ListBox::GetFirstDisplayedItemIndex () const {
@@ -117,7 +123,30 @@ ListBox::IndexType ListBox::GetMaxDisplayedItemsCount() const {
117123}
118124
119125void ListBox::AppendItem ( const sf::String& str ) {
120- m_items.push_back (str);
126+ m_items.push_back ( str );
127+
128+ UpdateDisplayedItems ();
129+ RequestResize ();
130+ Invalidate ();
131+ }
132+
133+ void ListBox::InsertItem ( IndexType index, const sf::String& str ) {
134+ m_items.insert ( m_items.begin () + index, str );
135+
136+ // Update next selected indexes (decrement them).
137+ std::set<IndexType> new_selected_items;
138+ std::transform (
139+ m_selected_items.cbegin (),
140+ m_selected_items.cend (),
141+ std::inserter (new_selected_items, new_selected_items.end ()),
142+ [&](IndexType i){
143+ if ( i < index )
144+ return i;
145+ else
146+ return ++i;
147+ }
148+ );
149+ m_selected_items = std::move (new_selected_items);
121150
122151 UpdateDisplayedItems ();
123152 RequestResize ();
@@ -127,6 +156,18 @@ void ListBox::AppendItem( const sf::String& str ) {
127156void ListBox::PrependItem ( const sf::String& str ) {
128157 m_items.insert ( m_items.begin (), str );
129158
159+ // Update selected items indexes.
160+ std::set<IndexType> new_selected_items;
161+ std::transform (
162+ m_selected_items.cbegin (),
163+ m_selected_items.cend (),
164+ std::inserter (new_selected_items, new_selected_items.end ()),
165+ [&](IndexType i){
166+ return ++i;
167+ }
168+ );
169+ m_selected_items = std::move (new_selected_items);
170+
130171 UpdateDisplayedItems ();
131172 RequestResize ();
132173 Invalidate ();
@@ -135,13 +176,32 @@ void ListBox::PrependItem( const sf::String& str ) {
135176void ListBox::RemoveItem ( IndexType index ) {
136177 m_items.erase ( m_items.begin () + index );
137178
179+ // Remove it from the selected indexes.
180+ m_selected_items.erase ( index );
181+
182+ // Update next selected indexes (decrement them).
183+ std::set<IndexType> new_selected_items;
184+ std::transform (
185+ m_selected_items.cbegin (),
186+ m_selected_items.cend (),
187+ std::inserter (new_selected_items, new_selected_items.end ()),
188+ [&](IndexType i){
189+ if ( i > index )
190+ return --i;
191+ else
192+ return i;
193+ }
194+ );
195+ m_selected_items = std::move (new_selected_items);
196+
138197 UpdateDisplayedItems ();
139198 RequestResize ();
140199 Invalidate ();
141200}
142201
143202void ListBox::Clear () {
144203 m_items.clear ();
204+ m_selected_items.clear ();
145205
146206 UpdateDisplayedItems ();
147207 RequestResize ();
@@ -159,7 +219,9 @@ void ListBox::SetSelectionMode( SelectionMode mode ) {
159219 m_selected_items.clear ();
160220 Invalidate ();
161221 } else if ( m_selection_mode == SelectionMode::SINGLE_SELECTION && m_selected_items.size () > 1 ) {
162- m_selected_items.resize ( 1 );
222+ auto it = m_selected_items.begin ();
223+ std::advance ( it, 1 );
224+ m_selected_items.erase ( it, m_selected_items.end () );
163225 }
164226}
165227
@@ -242,17 +304,16 @@ void ListBox::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int
242304
243305 // Clear the selection and add the item to the selection.
244306 m_selected_items.clear ();
245- m_selected_items.push_back ( clicked_item_index );
307+ m_selected_items.insert ( clicked_item_index );
246308 } else {
247309 // In MULTI_SELECTION and when Ctrl is pressed, the selection has changed (as if the clicked item is already selected, it is removed from the selection).
248310 selection_changed = true ;
249311
250312 // Add or remove the clicked item, depending on if it was in the selection or not.
251- auto iterator_to_clicked_index = std::find ( m_selected_items.begin (), m_selected_items.end (), clicked_item_index );
252- if (iterator_to_clicked_index == m_selected_items.end () )
253- m_selected_items.push_back ( clicked_item_index );
313+ if (m_selected_items.find ( clicked_item_index ) == m_selected_items.end () )
314+ m_selected_items.insert ( clicked_item_index );
254315 else
255- m_selected_items.erase (iterator_to_clicked_index );
316+ m_selected_items.erase ( clicked_item_index );
256317 }
257318
258319 if ( selection_changed ) // Only emit the OnSelect signal if the selection changed.
0 commit comments