mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 19:50:05 +00:00
338 lines
10 KiB
C++
338 lines
10 KiB
C++
#include "layer_dialog.hpp"
|
|
#include "ui_layer_dialog.h"
|
|
|
|
#include <scwx/qt/model/layer_model.hpp>
|
|
#include <scwx/qt/settings/general_settings.hpp>
|
|
#include <scwx/util/logger.hpp>
|
|
|
|
#include <QPushButton>
|
|
#include <QSortFilterProxyModel>
|
|
|
|
namespace scwx
|
|
{
|
|
namespace qt
|
|
{
|
|
namespace ui
|
|
{
|
|
|
|
static const std::string logPrefix_ = "scwx::qt::ui::layer_dialog";
|
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
|
|
|
class LayerDialogImpl
|
|
{
|
|
public:
|
|
explicit LayerDialogImpl(LayerDialog* self) :
|
|
self_ {self},
|
|
layerModel_ {model::LayerModel::Instance()},
|
|
layerProxyModel_ {new QSortFilterProxyModel(self_)}
|
|
{
|
|
layerProxyModel_->setSourceModel(layerModel_.get());
|
|
layerProxyModel_->setFilterCaseSensitivity(
|
|
Qt::CaseSensitivity::CaseInsensitive);
|
|
layerProxyModel_->setFilterKeyColumn(-1);
|
|
}
|
|
~LayerDialogImpl() = default;
|
|
|
|
void ConnectSignals();
|
|
void UpdateMapDisplayColumns();
|
|
void UpdateMoveButtonsEnabled();
|
|
|
|
std::vector<int> GetSelectedRows() const;
|
|
std::vector<std::vector<int>> GetContiguousRows() const;
|
|
|
|
LayerDialog* self_;
|
|
std::shared_ptr<model::LayerModel> layerModel_;
|
|
QSortFilterProxyModel* layerProxyModel_;
|
|
};
|
|
|
|
LayerDialog::LayerDialog(QWidget* parent) :
|
|
QDialog(parent),
|
|
p {std::make_unique<LayerDialogImpl>(this)},
|
|
ui(new Ui::LayerDialog)
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
ui->layerTreeView->setModel(p->layerProxyModel_);
|
|
|
|
auto layerViewHeader = ui->layerTreeView->header();
|
|
|
|
layerViewHeader->setMinimumSectionSize(10);
|
|
|
|
// Give small columns a fixed size
|
|
for (auto column : model::LayerModel::ColumnIterator())
|
|
{
|
|
if (column != model::LayerModel::Column::Description)
|
|
{
|
|
layerViewHeader->setSectionResizeMode(
|
|
static_cast<int>(column),
|
|
QHeaderView::ResizeMode::ResizeToContents);
|
|
}
|
|
}
|
|
|
|
// Disable move buttons
|
|
ui->moveTopButton->setEnabled(false);
|
|
ui->moveUpButton->setEnabled(false);
|
|
ui->moveDownButton->setEnabled(false);
|
|
ui->moveBottomButton->setEnabled(false);
|
|
|
|
p->UpdateMapDisplayColumns();
|
|
|
|
p->ConnectSignals();
|
|
}
|
|
|
|
LayerDialog::~LayerDialog()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void LayerDialogImpl::UpdateMapDisplayColumns()
|
|
{
|
|
auto& generalSettings = settings::GeneralSettings::Instance();
|
|
std::int64_t gridWidth = generalSettings.grid_width().GetValue();
|
|
std::int64_t gridHeight = generalSettings.grid_height().GetValue();
|
|
int mapCount = static_cast<int>(gridWidth * gridHeight);
|
|
|
|
int displayMap1Column =
|
|
static_cast<int>(model::LayerModel::Column::DisplayMap1);
|
|
|
|
// For each 0-based map index, 1-3 (excluding 0, always displayed)
|
|
for (int mapIndex = 1; mapIndex < 4; ++mapIndex)
|
|
{
|
|
const int column = displayMap1Column + mapIndex;
|
|
const bool hide = mapIndex >= mapCount;
|
|
self_->ui->layerTreeView->setColumnHidden(column, hide);
|
|
}
|
|
}
|
|
|
|
void LayerDialogImpl::ConnectSignals()
|
|
{
|
|
QObject::connect(
|
|
self_->ui->buttonBox->button(QDialogButtonBox::StandardButton::Reset),
|
|
&QAbstractButton::clicked,
|
|
self_,
|
|
[this]() { layerModel_->ResetLayers(); });
|
|
|
|
QObject::connect(self_->ui->layerFilter,
|
|
&QLineEdit::textChanged,
|
|
layerProxyModel_,
|
|
&QSortFilterProxyModel::setFilterWildcard);
|
|
|
|
QObject::connect(self_->ui->layerTreeView->selectionModel(),
|
|
&QItemSelectionModel::selectionChanged,
|
|
self_,
|
|
[this](const QItemSelection& /* selected */,
|
|
const QItemSelection& /* deselected */)
|
|
{ UpdateMoveButtonsEnabled(); });
|
|
|
|
QObject::connect(layerModel_.get(),
|
|
&QAbstractItemModel::rowsMoved,
|
|
self_,
|
|
[this]()
|
|
{
|
|
UpdateMoveButtonsEnabled();
|
|
|
|
auto selectedRows = GetSelectedRows();
|
|
if (!selectedRows.empty())
|
|
{
|
|
self_->ui->layerTreeView->scrollTo(
|
|
layerModel_->index(selectedRows.front(), 0));
|
|
}
|
|
});
|
|
|
|
QObject::connect( //
|
|
self_->ui->moveTopButton,
|
|
&QAbstractButton::clicked,
|
|
self_,
|
|
[this]()
|
|
{
|
|
auto contiguousRows = GetContiguousRows();
|
|
int destinationChild = 0;
|
|
|
|
for (auto& selectedRows : contiguousRows)
|
|
{
|
|
int sourceRow = selectedRows.front();
|
|
int count = static_cast<int>(selectedRows.size());
|
|
|
|
layerModel_->moveRows(QModelIndex(),
|
|
sourceRow,
|
|
count,
|
|
QModelIndex(),
|
|
destinationChild);
|
|
|
|
// Next set of rows should follow rows just added
|
|
destinationChild += count;
|
|
}
|
|
});
|
|
QObject::connect( //
|
|
self_->ui->moveUpButton,
|
|
&QAbstractButton::clicked,
|
|
self_,
|
|
[this]()
|
|
{
|
|
auto contiguousRows = GetContiguousRows();
|
|
int destinationChild = -1;
|
|
|
|
for (auto& selectedRows : contiguousRows)
|
|
{
|
|
int sourceRow = selectedRows.front();
|
|
int count = static_cast<int>(selectedRows.size());
|
|
if (destinationChild == -1)
|
|
{
|
|
destinationChild = sourceRow - 1;
|
|
}
|
|
|
|
layerModel_->moveRows(QModelIndex(),
|
|
sourceRow,
|
|
count,
|
|
QModelIndex(),
|
|
destinationChild);
|
|
|
|
// Next set of rows should follow rows just added
|
|
destinationChild += count;
|
|
}
|
|
});
|
|
QObject::connect( //
|
|
self_->ui->moveDownButton,
|
|
&QAbstractButton::clicked,
|
|
self_,
|
|
[this]()
|
|
{
|
|
auto contiguousRows = GetContiguousRows();
|
|
int destinationChild = 0;
|
|
int offset = 0;
|
|
if (!contiguousRows.empty())
|
|
{
|
|
destinationChild = contiguousRows.back().back() + 2;
|
|
}
|
|
|
|
for (auto& selectedRows : contiguousRows)
|
|
{
|
|
int sourceRow = selectedRows.front() - offset;
|
|
int count = static_cast<int>(selectedRows.size());
|
|
|
|
layerModel_->moveRows(QModelIndex(),
|
|
sourceRow,
|
|
count,
|
|
QModelIndex(),
|
|
destinationChild);
|
|
|
|
// Next set of rows should be offset
|
|
offset += count;
|
|
}
|
|
});
|
|
QObject::connect( //
|
|
self_->ui->moveBottomButton,
|
|
&QAbstractButton::clicked,
|
|
self_,
|
|
[this]()
|
|
{
|
|
auto contiguousRows = GetContiguousRows();
|
|
int destinationChild = layerModel_->rowCount();
|
|
int offset = 0;
|
|
|
|
for (auto& selectedRows : contiguousRows)
|
|
{
|
|
int sourceRow = selectedRows.front() - offset;
|
|
int count = static_cast<int>(selectedRows.size());
|
|
|
|
layerModel_->moveRows(QModelIndex(),
|
|
sourceRow,
|
|
count,
|
|
QModelIndex(),
|
|
destinationChild);
|
|
|
|
// Next set of rows should be offset
|
|
offset += count;
|
|
}
|
|
});
|
|
}
|
|
|
|
std::vector<int> LayerDialogImpl::GetSelectedRows() const
|
|
{
|
|
QModelIndexList selectedRows =
|
|
self_->ui->layerTreeView->selectionModel()->selectedRows();
|
|
std::vector<int> rows {};
|
|
for (auto& selectedRow : selectedRows)
|
|
{
|
|
rows.push_back(layerProxyModel_->mapToSource(selectedRow).row());
|
|
}
|
|
std::sort(rows.begin(), rows.end());
|
|
return rows;
|
|
}
|
|
|
|
std::vector<std::vector<int>> LayerDialogImpl::GetContiguousRows() const
|
|
{
|
|
std::vector<std::vector<int>> contiguousRows {};
|
|
std::vector<int> currentContiguousRows {};
|
|
auto rows = GetSelectedRows();
|
|
|
|
for (auto& row : rows)
|
|
{
|
|
// Next row is not contiguous with current row set
|
|
if (!currentContiguousRows.empty() &&
|
|
currentContiguousRows.back() + 1 < row)
|
|
{
|
|
// Add current row set to contiguous rows, and reset current set
|
|
contiguousRows.emplace_back(std::move(currentContiguousRows));
|
|
currentContiguousRows.clear();
|
|
}
|
|
|
|
// Add row to current row set
|
|
currentContiguousRows.push_back(row);
|
|
}
|
|
|
|
if (!currentContiguousRows.empty())
|
|
{
|
|
// Add remaining rows to contiguous rows
|
|
contiguousRows.emplace_back(currentContiguousRows);
|
|
}
|
|
|
|
return contiguousRows;
|
|
}
|
|
|
|
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 = layerProxyModel_->mapToSource(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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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
|
|
} // namespace qt
|
|
} // namespace scwx
|