2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include "ListSelectionModel.h"
10 // #pragma mark - ListSelectionModel
13 ListSelectionModel::ListSelectionModel()
18 ListSelectionModel::ListSelectionModel(const ListSelectionModel
& other
)
24 ListSelectionModel::~ListSelectionModel()
30 ListSelectionModel::Clear()
32 int32 selectedCount
= fSelectedItems
.Count();
33 if (selectedCount
> 0) {
34 int32 firstSelected
= fSelectedItems
[0];
35 int32 lastSelected
= fSelectedItems
[selectedCount
- 1];
37 fSelectedItems
.Clear();
39 _NotifyItemsDeselected(firstSelected
, lastSelected
- firstSelected
+ 1);
45 ListSelectionModel::SelectItems(int32 itemIndex
, int32 count
,
48 int32 endItemIndex
= itemIndex
+ count
;
51 if (extendSelection
) {
55 index
= _FindItem(itemIndex
);
57 // count already selected items
58 int32 alreadySelectedCount
= _CountSelectedItemsInRange(index
,
60 if (alreadySelectedCount
== count
)
63 // make room for the new items
64 if (!fSelectedItems
.InsertUninitialized(index
+ alreadySelectedCount
,
65 count
- alreadySelectedCount
)) {
69 // TODO: Don't clear -- just resize to the right size!
75 if (!fSelectedItems
.AddUninitialized(count
))
79 for (int32 i
= 0; i
< count
; i
++)
80 fSelectedItems
[index
+ i
] = itemIndex
+ i
;
82 _NotifyItemsSelected(itemIndex
, count
);
89 ListSelectionModel::DeselectItems(int32 itemIndex
, int32 count
)
91 int32 endItemIndex
= itemIndex
+ count
;
92 int32 index
= _FindItem(itemIndex
);
94 // count actually selected items
95 int32 actuallySelectedCount
= _CountSelectedItemsInRange(index
,
97 if (actuallySelectedCount
== 0)
100 fSelectedItems
.Remove(index
, actuallySelectedCount
);
102 _NotifyItemsDeselected(itemIndex
, count
);
107 ListSelectionModel::ItemsAdded(int32 itemIndex
, int32 count
)
112 // re-index following items
113 int32 index
= _FindItem(itemIndex
);
114 int32 selectedCount
= fSelectedItems
.Count();
115 for (int32 i
= index
; i
< selectedCount
; i
++)
116 fSelectedItems
[i
] += count
;
121 ListSelectionModel::ItemsRemoved(int32 itemIndex
, int32 count
)
126 int32 index
= _FindItem(itemIndex
);
128 // count selected items in the range
129 int32 actuallySelectedCount
= _CountSelectedItemsInRange(index
,
131 if (actuallySelectedCount
> 0)
132 fSelectedItems
.Remove(index
, actuallySelectedCount
);
134 // re-index following items
135 int32 selectedCount
= fSelectedItems
.Count();
136 for (int32 i
= index
; i
< selectedCount
; i
++)
137 fSelectedItems
[i
] -= count
;
142 ListSelectionModel::AddListener(Listener
* listener
)
144 return fListeners
.AddItem(listener
);
149 ListSelectionModel::RemoveListener(Listener
* listener
)
151 fListeners
.RemoveItem(listener
);
156 ListSelectionModel::operator=(const ListSelectionModel
& other
)
160 fSelectedItems
= other
.fSelectedItems
;
162 int32 selectedCount
= CountSelectedItems();
163 if (selectedCount
> 0) {
164 int32 firstSelected
= fSelectedItems
[0];
165 int32 lastSelected
= fSelectedItems
[selectedCount
- 1];
166 _NotifyItemsDeselected(firstSelected
, lastSelected
- firstSelected
+ 1);
174 ListSelectionModel::_FindItem(int32 itemIndex
) const
176 // binary search the index of the first item >= itemIndex
178 int32 upper
= fSelectedItems
.Count();
180 while (lower
< upper
) {
181 int32 mid
= (lower
+ upper
) / 2;
183 if (fSelectedItems
[mid
] < itemIndex
)
194 ListSelectionModel::_CountSelectedItemsInRange(int32 index
,
195 int32 endItemIndex
) const
198 int32 selectedCount
= fSelectedItems
.Count();
199 for (int32 i
= index
; i
< selectedCount
; i
++) {
200 if (SelectedItemAt(i
) >= endItemIndex
)
210 ListSelectionModel::_NotifyItemsSelected(int32 index
, int32 count
)
212 int32 listenerCount
= fListeners
.CountItems();
213 for (int32 i
= listenerCount
- 1; i
>= 0; i
--)
214 fListeners
.ItemAt(i
)->ItemsSelected(this, index
, count
);
219 ListSelectionModel::_NotifyItemsDeselected(int32 index
, int32 count
)
221 int32 listenerCount
= fListeners
.CountItems();
222 for (int32 i
= listenerCount
- 1; i
>= 0; i
--)
223 fListeners
.ItemAt(i
)->ItemsDeselected(this, index
, count
);
227 // #pragma mark - Listener
230 ListSelectionModel::Listener::~Listener()
236 ListSelectionModel::Listener::ItemsSelected(ListSelectionModel
* model
,
237 int32 index
, int32 count
)
243 ListSelectionModel::Listener::ItemsDeselected(ListSelectionModel
* model
,
244 int32 index
, int32 count
)