Skip to content

Commit 4794f5e

Browse files
Selection are now updated when appending/prepending/inserting/removing an item
1 parent 4894750 commit 4794f5e

3 files changed

Lines changed: 90 additions & 11 deletions

File tree

examples/ListBox.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ int main() {
8787

8888
window.resetGLStates();
8989

90+
int i = 0;
91+
9092
while (window.isOpen())
9193
{
9294
while (window.pollEvent(event))
@@ -97,6 +99,20 @@ int main() {
9799
case sf::Event::Closed:
98100
window.close();
99101
break;
102+
case sf::Event::KeyPressed:
103+
if( event.key.code == sf::Keyboard::R ) {
104+
listbox3->RemoveItem(2);
105+
} else if( event.key.code == sf::Keyboard::I ) {
106+
listbox3->InsertItem(3, "Inserted item #" + std::to_string(i));
107+
++i;
108+
} else if( event.key.code == sf::Keyboard::A) {
109+
listbox3->AppendItem("Appended item #" + std::to_string(i));
110+
++i;
111+
} else if( event.key.code == sf::Keyboard::P) {
112+
listbox3->PrependItem("Prepended item #" + std::to_string(i));
113+
++i;
114+
}
115+
break;
100116
default:
101117
break;
102118
}

include/SFGUI/ListBox.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <SFML/System/String.hpp>
77
#include <memory>
8+
#include <set>
89
#include <vector>
910

1011
namespace sfg {
@@ -60,6 +61,7 @@ class SFGUI_API ListBox : public Container {
6061
IndexType GetMaxDisplayedItemsCount() const;
6162

6263
void AppendItem( const sf::String& str );
64+
void InsertItem( IndexType index, const sf::String& str );
6365
void PrependItem( const sf::String& str );
6466
void RemoveItem( IndexType index );
6567
void Clear();
@@ -108,7 +110,7 @@ class SFGUI_API ListBox : public Container {
108110
std::vector<sf::String> m_items;
109111

110112
SelectionMode m_selection_mode;
111-
std::vector<IndexType> m_selected_items;
113+
std::set<IndexType> m_selected_items;
112114

113115
IndexType m_highlighted_item;
114116

src/SFGUI/ListBox.cpp

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
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

811
namespace sfg {
@@ -87,7 +90,7 @@ ListBox::IndexType ListBox::GetHighlightedItem() const {
8790
}
8891

8992
bool 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

9396
ListBox::IndexType ListBox::GetSelectedItemsCount() const {
@@ -97,11 +100,14 @@ ListBox::IndexType ListBox::GetSelectedItemsCount() const {
97100
ListBox::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

103109
const sf::String& ListBox::GetSelectedItemText( IndexType index ) const {
104-
return m_items[ m_selected_items[ index ] ];
110+
return m_items[ GetSelectedItemIndex( index ) ];
105111
}
106112

107113
ListBox::IndexType ListBox::GetFirstDisplayedItemIndex() const {
@@ -117,7 +123,30 @@ ListBox::IndexType ListBox::GetMaxDisplayedItemsCount() const {
117123
}
118124

119125
void 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 ) {
127156
void 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 ) {
135176
void 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

143202
void 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

Comments
 (0)