Added selection support to Table.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31096 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-06-18 00:23:16 +00:00
parent 2903bc659c
commit 6d9fec816e
4 changed files with 215 additions and 9 deletions
@@ -82,3 +82,24 @@ AbstractTable::ResizeAllColumnsToPreferred()
{
BColumnListView::ResizeAllColumnsToPreferred();
}
list_view_type
AbstractTable::SelectionMode() const
{
return BColumnListView::SelectionMode();
}
void
AbstractTable::SetSelectionMode(list_view_type type)
{
BColumnListView::SetSelectionMode(type);
}
void
AbstractTable::DeselectAll()
{
BColumnListView::DeselectAll();
}
@@ -33,6 +33,10 @@ public:
void ResizeColumnToPreferred(int32 index);
void ResizeAllColumnsToPreferred();
list_view_type SelectionMode() const;
void SetSelectionMode(list_view_type type);
void DeselectAll();
protected:
class AbstractColumn;
+154 -9
View File
@@ -93,6 +93,83 @@ TableModel::NotifyRowsRemoved(int32 rowIndex, int32 count)
}
// #pragma mark - TableSelectionModel
TableSelectionModel::TableSelectionModel(Table* table)
:
fTable(table),
fRows(NULL),
fRowCount(-1)
{
}
TableSelectionModel::~TableSelectionModel()
{
delete[] fRows;
}
int32
TableSelectionModel::CountRows()
{
_Update();
return fRowCount;
}
int32
TableSelectionModel::RowAt(int32 index)
{
_Update();
return index >= 0 && index < fRowCount ? fRows[index] : -1;
}
void
TableSelectionModel::_SelectionChanged()
{
if (fRowCount >= 0) {
fRowCount = -1;
delete[] fRows;
fRows = NULL;
}
}
void
TableSelectionModel::_Update()
{
if (fRowCount >= 0)
return;
// count the rows
fRowCount = 0;
BRow* row = NULL;
while ((row = fTable->CurrentSelection(row)) != NULL)
fRowCount++;
if (fRowCount == 0)
return;
// allocate row array
fRows = new(std::nothrow) int32[fRowCount];
if (fRows == NULL) {
fRowCount = 0;
return;
}
// get the rows
row = NULL;
int32 index = 0;
while ((row = fTable->CurrentSelection(row)) != NULL)
fRows[index++] = fTable->_ModelIndexOfRow(row);
}
// #pragma mark - TableListener
@@ -101,6 +178,12 @@ TableListener::~TableListener()
}
void
TableListener::TableSelectionChanged(Table* table)
{
}
void
TableListener::TableRowInvoked(Table* table, int32 rowIndex)
{
@@ -233,7 +316,9 @@ Table::Table(const char* name, uint32 flags, border_style borderStyle,
bool showHorizontalScrollbar)
:
AbstractTable(name, flags, borderStyle, showHorizontalScrollbar),
fModel(NULL)
fModel(NULL),
fSelectionModel(this),
fIgnoreSelectionChange(0)
{
}
@@ -242,7 +327,9 @@ Table::Table(TableModel* model, const char* name, uint32 flags,
border_style borderStyle, bool showHorizontalScrollbar)
:
AbstractTable(name, flags, borderStyle, showHorizontalScrollbar),
fModel(NULL)
fModel(NULL),
fSelectionModel(this),
fIgnoreSelectionChange(0)
{
SetTableModel(model);
}
@@ -287,6 +374,38 @@ Table::SetTableModel(TableModel* model)
}
TableSelectionModel*
Table::SelectionModel()
{
return &fSelectionModel;
}
void
Table::SelectRow(int32 rowIndex, bool extendSelection)
{
BRow* row = fRows.ItemAt(rowIndex);
if (row == NULL)
return;
if (!extendSelection) {
fIgnoreSelectionChange++;
DeselectAll();
fIgnoreSelectionChange--;
}
AddToSelection(row);
}
void
Table::DeselectRow(int32 rowIndex)
{
if (BRow* row = fRows.ItemAt(rowIndex))
Deselect(row);
}
bool
Table::AddTableListener(TableListener* listener)
{
@@ -301,6 +420,22 @@ Table::RemoveTableListener(TableListener* listener)
}
void
Table::SelectionChanged()
{
if (fIgnoreSelectionChange > 0)
return;
fSelectionModel._SelectionChanged();
if (!fListeners.IsEmpty()) {
int32 listenerCount = fListeners.CountItems();
for (int32 i = listenerCount - 1; i >= 0; i--)
fListeners.ItemAt(i)->TableSelectionChanged(this);
}
}
AbstractTable::AbstractColumn*
Table::CreateColumn(TableColumn* column)
{
@@ -367,15 +502,25 @@ Table::ItemInvoked()
if (fListeners.IsEmpty())
return;
BRow* row = CurrentSelection();
if (row == NULL)
return;
TableField* field = dynamic_cast<TableField*>(row->GetField(0));
if (field == NULL)
int32 index = _ModelIndexOfRow(CurrentSelection());
if (index < 0)
return;
int32 listenerCount = fListeners.CountItems();
for (int32 i = listenerCount - 1; i >= 0; i--)
fListeners.ItemAt(i)->TableRowInvoked(this, field->RowIndex());
fListeners.ItemAt(i)->TableRowInvoked(this, index);
}
int32
Table::_ModelIndexOfRow(BRow* row)
{
if (row == NULL)
return -1;
TableField* field = dynamic_cast<TableField*>(row->GetField(0));
if (field == NULL)
return -1;
return field->RowIndex();
}
+36
View File
@@ -55,10 +55,33 @@ protected:
};
class TableSelectionModel {
public:
TableSelectionModel(Table* table);
~TableSelectionModel();
int32 CountRows();
int32 RowAt(int32 index);
private:
friend class Table;
private:
void _SelectionChanged();
void _Update();
private:
Table* fTable;
int32* fRows;
int32 fRowCount;
};
class TableListener {
public:
virtual ~TableListener();
virtual void TableSelectionChanged(Table* table);
virtual void TableRowInvoked(Table* table, int32 rowIndex);
};
@@ -77,10 +100,17 @@ public:
void SetTableModel(TableModel* model);
TableModel* GetTableModel() const { return fModel; }
TableSelectionModel* SelectionModel();
void SelectRow(int32 rowIndex, bool extendSelection);
void DeselectRow(int32 rowIndex);
bool AddTableListener(TableListener* listener);
void RemoveTableListener(TableListener* listener);
protected:
virtual void SelectionChanged();
virtual AbstractColumn* CreateColumn(TableColumn* column);
private:
@@ -92,16 +122,22 @@ private:
private:
class Column;
friend class TableSelectionModel;
typedef BObjectList<TableListener> ListenerList;
typedef BObjectList<BRow> RowList;
private:
virtual void ItemInvoked();
int32 _ModelIndexOfRow(BRow* row);
private:
TableModel* fModel;
RowList fRows;
TableSelectionModel fSelectionModel;
ListenerList fListeners;
int32 fIgnoreSelectionChange;
};