* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "ListSelectionModel.h"
ListSelectionModel::ListSelectionModel()
{
}
ListSelectionModel::ListSelectionModel(const ListSelectionModel& other)
{
*this = other;
}
ListSelectionModel::~ListSelectionModel()
{
}
void
ListSelectionModel::Clear()
{
int32 selectedCount = fSelectedItems.Count();
if (selectedCount > 0) {
int32 firstSelected = fSelectedItems[0];
int32 lastSelected = fSelectedItems[selectedCount - 1];
fSelectedItems.Clear();
_NotifyItemsDeselected(firstSelected, lastSelected - firstSelected + 1);
}
}
bool
ListSelectionModel::SelectItems(int32 itemIndex, int32 count,
bool extendSelection)
{
int32 endItemIndex = itemIndex + count;
int32 index;
if (extendSelection) {
if (count <= 0)
return true;
index = _FindItem(itemIndex);
int32 alreadySelectedCount = _CountSelectedItemsInRange(index,
endItemIndex);
if (alreadySelectedCount == count)
return true;
if (!fSelectedItems.InsertUninitialized(index + alreadySelectedCount,
count - alreadySelectedCount)) {
return false;
}
} else {
Clear();
if (count <= 0)
return true;
index = 0;
if (!fSelectedItems.AddUninitialized(count))
return false;
}
for (int32 i = 0; i < count; i++)
fSelectedItems[index + i] = itemIndex + i;
_NotifyItemsSelected(itemIndex, count);
return true;
}
void
ListSelectionModel::DeselectItems(int32 itemIndex, int32 count)
{
int32 endItemIndex = itemIndex + count;
int32 index = _FindItem(itemIndex);
int32 actuallySelectedCount = _CountSelectedItemsInRange(index,
endItemIndex);
if (actuallySelectedCount == 0)
return;
fSelectedItems.Remove(index, actuallySelectedCount);
_NotifyItemsDeselected(itemIndex, count);
}
void
ListSelectionModel::ItemsAdded(int32 itemIndex, int32 count)
{
if (count <= 0)
return;
int32 index = _FindItem(itemIndex);
int32 selectedCount = fSelectedItems.Count();
for (int32 i = index; i < selectedCount; i++)
fSelectedItems[i] += count;
}
void
ListSelectionModel::ItemsRemoved(int32 itemIndex, int32 count)
{
if (count <= 0)
return;
int32 index = _FindItem(itemIndex);
int32 actuallySelectedCount = _CountSelectedItemsInRange(index,
itemIndex + count);
if (actuallySelectedCount > 0)
fSelectedItems.Remove(index, actuallySelectedCount);
int32 selectedCount = fSelectedItems.Count();
for (int32 i = index; i < selectedCount; i++)
fSelectedItems[i] -= count;
}
bool
ListSelectionModel::AddListener(Listener* listener)
{
return fListeners.AddItem(listener);
}
void
ListSelectionModel::RemoveListener(Listener* listener)
{
fListeners.RemoveItem(listener);
}
ListSelectionModel&
ListSelectionModel::operator=(const ListSelectionModel& other)
{
Clear();
fSelectedItems = other.fSelectedItems;
int32 selectedCount = CountSelectedItems();
if (selectedCount > 0) {
int32 firstSelected = fSelectedItems[0];
int32 lastSelected = fSelectedItems[selectedCount - 1];
_NotifyItemsDeselected(firstSelected, lastSelected - firstSelected + 1);
}
return *this;
}
int32
ListSelectionModel::_FindItem(int32 itemIndex) const
{
int32 lower = 0;
int32 upper = fSelectedItems.Count();
while (lower < upper) {
int32 mid = (lower + upper) / 2;
if (fSelectedItems[mid] < itemIndex)
lower = mid + 1;
else
upper = mid;
}
return lower;
}
int32
ListSelectionModel::_CountSelectedItemsInRange(int32 index,
int32 endItemIndex) const
{
int32 count = 0;
int32 selectedCount = fSelectedItems.Count();
for (int32 i = index; i < selectedCount; i++) {
if (SelectedItemAt(i) >= endItemIndex)
break;
count++;
}
return count;
}
void
ListSelectionModel::_NotifyItemsSelected(int32 index, int32 count)
{
int32 listenerCount = fListeners.CountItems();
for (int32 i = listenerCount - 1; i >= 0; i--)
fListeners.ItemAt(i)->ItemsSelected(this, index, count);
}
void
ListSelectionModel::_NotifyItemsDeselected(int32 index, int32 count)
{
int32 listenerCount = fListeners.CountItems();
for (int32 i = listenerCount - 1; i >= 0; i--)
fListeners.ItemAt(i)->ItemsDeselected(this, index, count);
}
ListSelectionModel::Listener::~Listener()
{
}
void
ListSelectionModel::Listener::ItemsSelected(ListSelectionModel* model,
int32 index, int32 count)
{
}
void
ListSelectionModel::Listener::ItemsDeselected(ListSelectionModel* model,
int32 index, int32 count)
{
}