Implement layer move functionality using buttons

This commit is contained in:
Dan Paulat 2023-10-16 22:29:35 -05:00
parent b45ec9dfa5
commit 5d06f6bc21
3 changed files with 190 additions and 39 deletions

View file

@ -529,6 +529,62 @@ bool LayerModel::removeRows(int row, int count, const QModelIndex& parent)
return true;
}
bool LayerModel::moveRows(const QModelIndex& sourceParent,
int sourceRow,
int count,
const QModelIndex& destinationParent,
int destinationChild)
{
bool moved = false;
if (sourceParent != destinationParent || // Only accept internal moves
count < 1 || // Minimum selection size of 1
sourceRow < 0 || // Valid source row (start)
sourceRow + count > p->layers_.size() || // Valid source row (end)
destinationChild < 0 || // Valid destination row
destinationChild > p->layers_.size())
{
return false;
}
if (destinationChild < sourceRow)
{
// Move up
auto first = p->layers_.begin() + destinationChild;
auto middle = p->layers_.begin() + sourceRow;
auto last = middle + count;
beginMoveRows(sourceParent,
sourceRow,
sourceRow + count - 1,
destinationParent,
destinationChild);
std::rotate(first, middle, last);
endMoveRows();
moved = true;
}
else if (sourceRow + count < destinationChild)
{
// Move down
auto first = p->layers_.begin() + sourceRow;
auto middle = first + count;
auto last = p->layers_.begin() + destinationChild;
beginMoveRows(sourceParent,
sourceRow,
sourceRow + count - 1,
destinationParent,
destinationChild);
std::rotate(first, middle, last);
endMoveRows();
moved = true;
}
return moved;
}
void LayerModel::HandlePlacefileRemoved(const std::string& name)
{
auto it =

View file

@ -66,6 +66,11 @@ public:
bool removeRows(int row,
int count,
const QModelIndex& parent = QModelIndex()) override;
bool moveRows(const QModelIndex& sourceParent,
int sourceRow,
int count,
const QModelIndex& destinationParent,
int destinationChild) override;
public slots:
void HandlePlacefileRemoved(const std::string& name);

View file

@ -24,6 +24,9 @@ public:
~LayerDialogImpl() = default;
void ConnectSignals();
void UpdateMoveButtonsEnabled();
std::vector<int> GetSelectedRows();
LayerDialog* self_;
model::LayerModel* layerModel_;
@ -69,53 +72,140 @@ LayerDialog::~LayerDialog()
void LayerDialogImpl::ConnectSignals()
{
QObject::connect(self_->ui->layerTreeView->selectionModel(),
&QItemSelectionModel::selectionChanged,
self_,
[this](const QItemSelection& /* selected */,
const QItemSelection& /* deselected */)
{ UpdateMoveButtonsEnabled(); });
QObject::connect(layerModel_,
&QAbstractItemModel::rowsMoved,
self_,
[this]()
{
UpdateMoveButtonsEnabled();
auto selectedRows = GetSelectedRows();
if (!selectedRows.empty())
{
self_->ui->layerTreeView->scrollTo(
layerModel_->index(selectedRows.front(), 0));
}
});
QObject::connect(
self_->ui->layerTreeView->selectionModel(),
&QItemSelectionModel::selectionChanged,
self_->ui->moveTopButton,
&QAbstractButton::clicked,
self_,
[this](const QItemSelection& /* selected */,
const QItemSelection& /* deselected */)
[this]()
{
QModelIndexList selectedRows =
self_->ui->layerTreeView->selectionModel()->selectedRows();
auto selectedRows = GetSelectedRows();
int sourceRow = selectedRows.front();
int count = static_cast<int>(selectedRows.size());
int destinationChild = 0;
bool itemsSelected = selectedRows.size() > 0;
bool itemsMovableUp = itemsSelected;
bool itemsMovableDown = itemsSelected;
int rowCount = layerModel_->rowCount();
layerModel_->moveRows(
QModelIndex(), sourceRow, count, QModelIndex(), destinationChild);
});
QObject::connect(
self_->ui->moveUpButton,
&QAbstractButton::clicked,
self_,
[this]()
{
auto selectedRows = GetSelectedRows();
int sourceRow = selectedRows.front();
int count = static_cast<int>(selectedRows.size());
int destinationChild = sourceRow - 1;
for (auto& rowIndex : selectedRows)
layerModel_->moveRows(
QModelIndex(), sourceRow, count, QModelIndex(), destinationChild);
});
QObject::connect(
self_->ui->moveDownButton,
&QAbstractButton::clicked,
self_,
[this]()
{
auto selectedRows = GetSelectedRows();
int sourceRow = selectedRows.front();
int count = static_cast<int>(selectedRows.size());
int destinationChild = selectedRows.back() + 2;
layerModel_->moveRows(
QModelIndex(), sourceRow, count, QModelIndex(), destinationChild);
});
QObject::connect(
self_->ui->moveBottomButton,
&QAbstractButton::clicked,
self_,
[this]()
{
auto selectedRows = GetSelectedRows();
int sourceRow = selectedRows.front();
int count = static_cast<int>(selectedRows.size());
int destinationChild = layerModel_->rowCount();
layerModel_->moveRows(
QModelIndex(), sourceRow, count, QModelIndex(), destinationChild);
});
}
std::vector<int> LayerDialogImpl::GetSelectedRows()
{
QModelIndexList selectedRows =
self_->ui->layerTreeView->selectionModel()->selectedRows();
std::vector<int> rows {};
for (auto& selectedRow : selectedRows)
{
rows.push_back(selectedRow.row());
}
std::sort(rows.begin(), rows.end());
return rows;
}
void LayerDialogImpl::UpdateMoveButtonsEnabled()
{
QModelIndexList selectedRows =
self_->ui->layerTreeView->selectionModel()->selectedRows();
bool itemsSelected = selectedRows.size() > 0;
bool itemsMovableUp = itemsSelected;
bool itemsMovableDown = itemsSelected;
int rowCount = layerModel_->rowCount();
for (auto& rowIndex : selectedRows)
{
int row = rowIndex.row();
if (!layerModel_->IsMovable(row))
{
// If an item in the selection is not movable, disable all moves
itemsMovableUp = false;
itemsMovableDown = false;
break;
}
else
{
// If the first row is selected, items cannot be moved up
if (row == 0)
{
int row = rowIndex.row();
if (!layerModel_->IsMovable(row))
{
// If an item in the selection is not movable, disable all moves
itemsMovableUp = false;
itemsMovableDown = false;
break;
}
else
{
// If the first row is selected, items cannot be moved up
if (row == 0)
{
itemsMovableUp = false;
}
// If the last row is selected, items cannot be moved down
if (row == rowCount - 1)
{
itemsMovableDown = false;
}
}
itemsMovableUp = false;
}
// Enable move buttons according to selection
self_->ui->moveTopButton->setEnabled(itemsMovableUp);
self_->ui->moveUpButton->setEnabled(itemsMovableUp);
self_->ui->moveDownButton->setEnabled(itemsMovableDown);
self_->ui->moveBottomButton->setEnabled(itemsMovableDown);
});
// If the last row is selected, items cannot be moved down
if (row == rowCount - 1)
{
itemsMovableDown = false;
}
}
}
// Enable move buttons according to selection
self_->ui->moveTopButton->setEnabled(itemsMovableUp);
self_->ui->moveUpButton->setEnabled(itemsMovableUp);
self_->ui->moveDownButton->setEnabled(itemsMovableDown);
self_->ui->moveBottomButton->setEnabled(itemsMovableDown);
}
} // namespace ui