Added class ListSelectionModel, representing a selection of list (i.e. indexed)
elements. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34567 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1031a2b4ca
commit
446ac6d727
@ -13,6 +13,7 @@ MergeObject DebugAnalyzer_gui.o
|
||||
AbstractGeneralPage.cpp
|
||||
ColorCheckBox.cpp
|
||||
HeaderView.cpp
|
||||
ListSelectionModel.cpp
|
||||
SubWindow.cpp
|
||||
SubWindowManager.cpp
|
||||
:
|
||||
|
224
src/apps/debuganalyzer/gui/ListSelectionModel.cpp
Normal file
224
src/apps/debuganalyzer/gui/ListSelectionModel.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ListSelectionModel.h"
|
||||
|
||||
|
||||
// #pragma mark - ListSelectionModel
|
||||
|
||||
|
||||
ListSelectionModel::ListSelectionModel()
|
||||
:
|
||||
fItemCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
// count already selected items
|
||||
int32 alreadySelectedCount = _CountSelectedItemsInRange(index,
|
||||
endItemIndex);
|
||||
if (alreadySelectedCount == count)
|
||||
return true;
|
||||
|
||||
// make room for the new items
|
||||
if (!fSelectedItems.InsertUninitialized(index + alreadySelectedCount,
|
||||
count - alreadySelectedCount)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// TODO: Don't clear -- just resize to the right size!
|
||||
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);
|
||||
|
||||
// count actually selected items
|
||||
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;
|
||||
|
||||
// re-index following items
|
||||
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);
|
||||
|
||||
// count selected items in the range
|
||||
int32 actuallySelectedCount = _CountSelectedItemsInRange(index,
|
||||
itemIndex + count);
|
||||
if (actuallySelectedCount > 0)
|
||||
fSelectedItems.Remove(index, actuallySelectedCount);
|
||||
|
||||
// re-index following items
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ListSelectionModel::_FindItem(int32 itemIndex) const
|
||||
{
|
||||
// binary search the index of the first item >= itemIndex
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Listener
|
||||
|
||||
|
||||
ListSelectionModel::Listener::~Listener()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ListSelectionModel::Listener::ItemsSelected(ListSelectionModel* model,
|
||||
int32 index, int32 count)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ListSelectionModel::Listener::ItemsDeselected(ListSelectionModel* model,
|
||||
int32 index, int32 count)
|
||||
{
|
||||
}
|
103
src/apps/debuganalyzer/gui/ListSelectionModel.h
Normal file
103
src/apps/debuganalyzer/gui/ListSelectionModel.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef LIST_SELECTION_MODEL_H
|
||||
#define LIST_SELECTION_MODEL_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "../debugger/util/Array.h"
|
||||
|
||||
|
||||
class ListSelectionModel {
|
||||
public:
|
||||
class Listener;
|
||||
|
||||
public:
|
||||
ListSelectionModel();
|
||||
~ListSelectionModel();
|
||||
|
||||
int32 CountSelectedItems() const
|
||||
{ return fSelectedItems.Count(); }
|
||||
int32 SelectedItemAt(int32 index) const;
|
||||
bool IsItemSelected(int32 itemIndex) const;
|
||||
|
||||
void Clear();
|
||||
bool SelectItem(int32 itemIndex,
|
||||
bool extendSelection);
|
||||
bool SelectItems(int32 itemIndex, int32 count,
|
||||
bool extendSelection);
|
||||
void DeselectItem(int32 itemIndex);
|
||||
void DeselectItems(int32 itemIndex, int32 count);
|
||||
|
||||
void ItemsAdded(int32 itemIndex, int32 count);
|
||||
void ItemsRemoved(int32 itemIndex, int32 count);
|
||||
|
||||
bool AddListener(Listener* listener);
|
||||
void RemoveListener(Listener* listener);
|
||||
|
||||
private:
|
||||
typedef BObjectList<Listener> ListenerList;
|
||||
|
||||
private:
|
||||
int32 _FindItem(int32 itemIndex) const;
|
||||
int32 _CountSelectedItemsInRange(int32 index,
|
||||
int32 endItemIndex) const;
|
||||
|
||||
void _NotifyItemsSelected(int32 index, int32 count);
|
||||
void _NotifyItemsDeselected(int32 index,
|
||||
int32 count);
|
||||
|
||||
private:
|
||||
int32 fItemCount;
|
||||
Array<int32> fSelectedItems;
|
||||
ListenerList fListeners;
|
||||
};
|
||||
|
||||
|
||||
class ListSelectionModel::Listener {
|
||||
public:
|
||||
virtual ~Listener();
|
||||
|
||||
virtual void ItemsSelected(ListSelectionModel* model,
|
||||
int32 index, int32 count);
|
||||
virtual void ItemsDeselected(ListSelectionModel* model,
|
||||
int32 index, int32 count);
|
||||
};
|
||||
|
||||
|
||||
inline bool
|
||||
ListSelectionModel::IsItemSelected(int32 itemIndex) const
|
||||
{
|
||||
int32 index = _FindItem(itemIndex);
|
||||
return index < fSelectedItems.Count() && fSelectedItems[index] == itemIndex;
|
||||
}
|
||||
|
||||
|
||||
inline int32
|
||||
ListSelectionModel::SelectedItemAt(int32 index) const
|
||||
{
|
||||
return index >= 0 && index < fSelectedItems.Count()
|
||||
? fSelectedItems[index] : -1;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
ListSelectionModel::SelectItem(int32 itemIndex, bool extendSelection)
|
||||
{
|
||||
return SelectItems(itemIndex, 1, extendSelection);
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
ListSelectionModel::DeselectItem(int32 itemIndex)
|
||||
{
|
||||
DeselectItems(itemIndex, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif // LIST_SELECTION_MODEL_H
|
Loading…
Reference in New Issue
Block a user