setLayout to create layout-only edit mode

This commit is contained in:
garak 2023-02-01 20:28:54 -05:00
parent 90f8218c32
commit 18eb3ceb1e
12 changed files with 186 additions and 56 deletions

View file

@ -92,6 +92,8 @@ public:
void clearBorderCache();
void cacheBorder();
bool hasUnsavedChanges();
bool layoutBlockChanged(int i, const Blockdata &cache);
uint16_t getBorderMetatileId(int x, int y);

View file

@ -60,11 +60,14 @@ public:
void closeProject();
bool setMap(QString map_name);
bool setLayout(QString layoutName);
void unsetMap();
Tileset *getCurrentMapPrimaryTileset();
bool displayMap();
bool displayLayout();
void displayMetatileSelector();
void displayMapMetatiles();
void displayMapMovementPermissions();

View file

@ -357,7 +357,7 @@ private:
bool tilesetNeedsRedraw = false;
bool setLayout(QString layoutName);
bool setLayout(QString layoutId);
bool setMap(QString, bool scrollTreeView = false);
void unsetMap();

View file

@ -145,6 +145,7 @@ public:
QSet<QString> getTopLevelMapFields();
bool loadMapData(Map*);
bool readMapLayouts();
Layout *loadLayout(QString layoutId);
bool loadLayout(Layout *);
bool loadMapLayout(Map*);
bool loadLayoutTilesets(Layout *);

View file

@ -62,9 +62,9 @@ public:
QVariant data(const QModelIndex &index, int role) const override;
public:
void setLayout(QString layoutName) { this->openLayout = layoutName; }
void setLayout(QString layoutId) { this->openLayout = layoutId; }
QStandardItem *createLayoutItem(QString layoutName);
QStandardItem *createLayoutItem(QString layoutId);
QStandardItem *createMapItem(QString mapName);
QStandardItem *getItem(const QModelIndex &index) const;

View file

@ -154,5 +154,6 @@ void Map::clean() {
}
bool Map::hasUnsavedChanges() {
return !editHistory.isClean() /* || !this->layout->editHistory.isClean() */ || hasUnsavedDataChanges || !isPersistedToFile;
// !TODO: layout not working here? map needs to be in cache before the layout being edited works
return !editHistory.isClean() || !this->layout->editHistory.isClean() || hasUnsavedDataChanges || !isPersistedToFile;
}

View file

@ -388,3 +388,7 @@ QPixmap Layout::renderBorder(bool ignoreCache) {
}
return this->border_pixmap;
}
bool Layout::hasUnsavedChanges() {
return !this->editHistory.isClean();
}

View file

@ -81,6 +81,7 @@ void Editor::closeProject() {
}
void Editor::setEditingMap() {
qDebug() << "Editor::setEditingMap()";
current_view = map_item;
if (map_item) {
map_item->paintingMode = LayoutPixmapItem::PaintMode::Metatiles;
@ -932,8 +933,8 @@ void Editor::onHoveredMovementPermissionCleared() {
}
QString Editor::getMetatileDisplayMessage(uint16_t metatileId) {
Metatile *metatile = Tileset::getMetatile(metatileId, map->layout->tileset_primary, map->layout->tileset_secondary);
QString label = Tileset::getMetatileLabel(metatileId, map->layout->tileset_primary, map->layout->tileset_secondary);
Metatile *metatile = Tileset::getMetatile(metatileId, this->layout->tileset_primary, this->layout->tileset_secondary);
QString label = Tileset::getMetatileLabel(metatileId, this->layout->tileset_primary, this->layout->tileset_secondary);
QString message = QString("Metatile: %1").arg(Metatile::getMetatileIdString(metatileId));
if (label.size())
message += QString(" \"%1\"").arg(label);
@ -1113,17 +1114,21 @@ bool Editor::setMap(QString map_name) {
return false;
}
map = loadedMap;
this->layout = map->layout; // !TODO:
this->map = loadedMap;
// remove this
//this->layout = this->map->layout;
setLayout(map->layout->id);
editGroup.addStack(&map->editHistory);
// !TODO: determine which stack is active based on edit mode too since layout will have something different
editGroup.setActiveStack(&map->editHistory);
selected_events->clear();
if (!displayMap()) {
return false;
}
map_ruler->setMapDimensions(QSize(map->getWidth(), map->getHeight()));
connect(map, &Map::mapDimensionsChanged, map_ruler, &MapRuler::setMapDimensions);
connect(map, &Map::openScriptRequested, this, &Editor::openScript);
updateSelectedEvents();
}
@ -1131,6 +1136,20 @@ bool Editor::setMap(QString map_name) {
return true;
}
bool Editor::setLayout(QString layoutId) {
//
this->layout = this->project->loadLayout(layoutId);
if (!displayLayout()) {
return false;
}
map_ruler->setMapDimensions(QSize(this->layout->getWidth(), this->layout->getHeight()));
connect(map, &Map::mapDimensionsChanged, map_ruler, &MapRuler::setMapDimensions);
return true;
}
void Editor::onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item) {
if (item->paintingMode != LayoutPixmapItem::PaintMode::Metatiles) {
return;
@ -1337,6 +1356,18 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm
}
bool Editor::displayMap() {
displayMapEvents();
displayMapConnections();
displayWildMonTables();
if (events_group) {
events_group->setVisible(false);
}
return true;
}
bool Editor::displayLayout() {
if (!scene) {
scene = new QGraphicsScene;
MapSceneEventFilter *filter = new MapSceneEventFilter();
@ -1351,17 +1382,15 @@ bool Editor::displayMap() {
scene->removeItem(this->map_ruler);
}
// !TODO: disassociate these functions from Map
displayMetatileSelector();
displayMovementPermissionSelector();
displayMapMetatiles();
displayMovementPermissionSelector();
displayMapMovementPermissions();
displayBorderMetatiles();
displayCurrentMetatilesSelection();
displayMapEvents();
displayMapConnections();
displayMapBorder();
displayMapGrid();
displayWildMonTables();
this->map_ruler->setZValue(1000);
scene->addItem(this->map_ruler);
@ -1372,9 +1401,7 @@ bool Editor::displayMap() {
if (collision_item) {
collision_item->setVisible(false);
}
if (events_group) {
events_group->setVisible(false);
}
return true;
}
@ -1396,12 +1423,12 @@ void Editor::displayMetatileSelector() {
} else {
metatile_selector_item->setLayout(this->layout);
if (metatile_selector_item->primaryTileset
&& metatile_selector_item->primaryTileset != map->layout->tileset_primary)
emit tilesetUpdated(map->layout->tileset_primary->name);
&& metatile_selector_item->primaryTileset != this->layout->tileset_primary)
emit tilesetUpdated(this->layout->tileset_primary->name);
if (metatile_selector_item->secondaryTileset
&& metatile_selector_item->secondaryTileset != map->layout->tileset_secondary)
emit tilesetUpdated(map->layout->tileset_secondary->name);
metatile_selector_item->setTilesets(map->layout->tileset_primary, map->layout->tileset_secondary);
&& metatile_selector_item->secondaryTileset != this->layout->tileset_secondary)
emit tilesetUpdated(this->layout->tileset_secondary->name);
metatile_selector_item->setTilesets(this->layout->tileset_primary, this->layout->tileset_secondary);
}
scene_metatiles->addItem(metatile_selector_item);
@ -1548,11 +1575,13 @@ void Editor::displayMapConnections() {
selected_connection_item = nullptr;
connection_items.clear();
for (MapConnection *connection : map->connections) {
if (connection->direction == "dive" || connection->direction == "emerge") {
continue;
if (map) {
for (MapConnection *connection : map->connections) {
if (connection->direction == "dive" || connection->direction == "emerge") {
continue;
}
createConnectionItem(connection);
}
createConnectionItem(connection);
}
if (!connection_items.empty()) {
@ -1611,8 +1640,8 @@ void Editor::maskNonVisibleConnectionTiles() {
mask.addRect(
-BORDER_DISTANCE * 16,
-BORDER_DISTANCE * 16,
(map->getWidth() + BORDER_DISTANCE * 2) * 16,
(map->getHeight() + BORDER_DISTANCE * 2) * 16
(layout->getWidth() + BORDER_DISTANCE * 2) * 16,
(layout->getHeight() + BORDER_DISTANCE * 2) * 16
);
// Mask the tiles with the current theme's background color.
@ -1631,13 +1660,13 @@ void Editor::displayMapBorder() {
}
borderItems.clear();
int borderWidth = map->getBorderWidth();
int borderHeight = map->getBorderHeight();
int borderWidth = this->layout->getBorderWidth();
int borderHeight = this->layout->getBorderHeight();
int borderHorzDist = getBorderDrawDistance(borderWidth);
int borderVertDist = getBorderDrawDistance(borderHeight);
QPixmap pixmap = this->layout->renderBorder();
for (int y = -borderVertDist; y < map->getHeight() + borderVertDist; y += borderHeight)
for (int x = -borderHorzDist; x < map->getWidth() + borderHorzDist; x += borderWidth) {
for (int y = -borderVertDist; y < this->layout->getHeight() + borderVertDist; y += borderHeight)
for (int x = -borderHorzDist; x < this->layout->getWidth() + borderHorzDist; x += borderWidth) {
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
item->setX(x * 16);
item->setY(y * 16);
@ -1692,16 +1721,16 @@ void Editor::displayMapGrid() {
gridLines.clear();
ui->checkBox_ToggleGrid->disconnect();
int pixelWidth = map->getWidth() * 16;
int pixelHeight = map->getHeight() * 16;
for (int i = 0; i <= map->getWidth(); i++) {
int pixelWidth = this->layout->getWidth() * 16;
int pixelHeight = this->layout->getHeight() * 16;
for (int i = 0; i <= this->layout->getWidth(); i++) {
int x = i * 16;
QGraphicsLineItem *line = new QGraphicsLineItem(x, 0, x, pixelHeight);
line->setVisible(ui->checkBox_ToggleGrid->isChecked());
gridLines.append(line);
connect(ui->checkBox_ToggleGrid, &QCheckBox::toggled, [=](bool checked){line->setVisible(checked);});
}
for (int j = 0; j <= map->getHeight(); j++) {
for (int j = 0; j <= this->layout->getHeight(); j++) {
int y = j * 16;
QGraphicsLineItem *line = new QGraphicsLineItem(0, y, pixelWidth, y);
line->setVisible(ui->checkBox_ToggleGrid->isChecked());
@ -1921,20 +1950,20 @@ void Editor::updateDiveEmergeMap(QString mapName, QString direction) {
void Editor::updatePrimaryTileset(QString tilesetLabel, bool forceLoad)
{
if (map->layout->tileset_primary_label != tilesetLabel || forceLoad)
if (this->layout->tileset_primary_label != tilesetLabel || forceLoad)
{
map->layout->tileset_primary_label = tilesetLabel;
map->layout->tileset_primary = project->getTileset(tilesetLabel, forceLoad);
this->layout->tileset_primary_label = tilesetLabel;
this->layout->tileset_primary = project->getTileset(tilesetLabel, forceLoad);
layout->clearBorderCache();
}
}
void Editor::updateSecondaryTileset(QString tilesetLabel, bool forceLoad)
{
if (map->layout->tileset_secondary_label != tilesetLabel || forceLoad)
if (this->layout->tileset_secondary_label != tilesetLabel || forceLoad)
{
map->layout->tileset_secondary_label = tilesetLabel;
map->layout->tileset_secondary = project->getTileset(tilesetLabel, forceLoad);
this->layout->tileset_secondary_label = tilesetLabel;
this->layout->tileset_secondary = project->getTileset(tilesetLabel, forceLoad);
layout->clearBorderCache();
}
}
@ -1956,7 +1985,7 @@ void Editor::updateCustomMapHeaderValues(QTableWidget *table)
Tileset* Editor::getCurrentMapPrimaryTileset()
{
QString tilesetLabel = map->layout->tileset_primary_label;
QString tilesetLabel = this->layout->tileset_primary_label;
return project->getTileset(tilesetLabel);
}

View file

@ -679,6 +679,53 @@ bool MainWindow::setMap(QString map_name, bool scrollTreeView) {
return true;
}
bool MainWindow::setLayout(QString layoutId) {
// if this->editor->setLayout(layoutName);
// this->editor->layout = layout;
if (!this->editor->setLayout(layoutId)) {
return false;
}
layoutTreeModel->setLayout(layoutId);
refreshMapScene();
// if (scrollTreeView) {
// // Make sure we clear the filter first so we actually have a scroll target
// /// !TODO: make this onto a function that scrolls the current view taking a map name or layout name
// groupListProxyModel->setFilterRegularExpression(QString());
// ui->mapList->setCurrentIndex(groupListProxyModel->mapFromSource(mapGroupModel->indexOfMap(map_name)));
// ui->mapList->scrollTo(ui->mapList->currentIndex(), QAbstractItemView::PositionAtCenter);
// }
showWindowTitle();
updateMapList();
// connect(editor->map, &Map::mapChanged, this, &MainWindow::onMapChanged);
// connect(editor->map, &Map::mapNeedsRedrawing, this, &MainWindow::onMapNeedsRedrawing);
// connect(editor->map, &Map::modified, [this](){ this->markMapEdited(); });
// displayMapProperties
ui->comboBox_PrimaryTileset->blockSignals(true);
ui->comboBox_SecondaryTileset->blockSignals(true);
ui->comboBox_PrimaryTileset->setCurrentText(this->editor->layout->tileset_primary_label);
ui->comboBox_SecondaryTileset->setCurrentText(this->editor->layout->tileset_secondary_label);
ui->comboBox_PrimaryTileset->blockSignals(false);
ui->comboBox_SecondaryTileset->blockSignals(false);
//
// connect(editor->layout, &Layout::mapChanged, this, &MainWindow::onMapChanged);
// connect(editor->layout, &Layout::mapNeedsRedrawing, this, &MainWindow::onMapNeedsRedrawing);
// connect(editor->layout, &Layout::modified, [this](){ this->markMapEdited(); });
//
updateTilesetEditor();
return true;
}
void MainWindow::redrawMapScene()
{
if (!editor->displayMap())
@ -1426,12 +1473,22 @@ void MainWindow::on_layoutList_activated(const QModelIndex &index) {
QVariant data = index.data(Qt::UserRole);
if (index.data(MapListRoles::TypeRole) == "map_layout" && !data.isNull()) {
QString layoutName = data.toString();
QString layoutId = data.toString();
//
logInfo("Switching to a layout-only editing mode");
setMap(QString());
//setLayout(layoutId);
// setLayout(layout)
qDebug() << "set layout" << layoutName;
qDebug() << "set layout" << layoutId;
if (!setLayout(layoutId)) {
QMessageBox msgBox(this);
QString errorMsg = QString("There was an error opening layout %1. Please see %2 for full error details.\n\n%3")
.arg(layoutId)
.arg(getLogPath())
.arg(getMostRecentError());
msgBox.critical(nullptr, "Error Opening Layout", errorMsg);
}
}
}
@ -1468,8 +1525,15 @@ void MainWindow::drawMapListIcons(QAbstractItemModel *model) {
void MainWindow::updateMapList() {
//MapGroupModel *model = static_cast<MapGroupModel *>(this->ui->mapList->model());
mapGroupModel->setMap(this->editor->map->name);
groupListProxyModel->layoutChanged();
if (this->editor->map) {
mapGroupModel->setMap(this->editor->map->name);
groupListProxyModel->layoutChanged();
}
if (this->editor->layout) {
layoutTreeModel->setLayout(this->editor->layout->id);
layoutListProxyModel->layoutChanged();
}
//mapGroupModel->layoutChanged();
// drawMapListIcons(mapListModel);
}
@ -1746,6 +1810,7 @@ void MainWindow::on_mapViewTab_tabBarClicked(int index)
Scripting::cb_MapViewTabChanged(oldIndex, index);
if (index == 0) {
//if ()
editor->setEditingMap();
} else if (index == 1) {
editor->setEditingCollision();
@ -1768,6 +1833,8 @@ void MainWindow::on_action_Exit_triggered()
void MainWindow::on_mainTabBar_tabBarClicked(int index)
{
//if (!editor->map) return;
int oldIndex = ui->mainTabBar->currentIndex();
ui->mainTabBar->setCurrentIndex(index);
if (index != oldIndex)
@ -1787,6 +1854,8 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index)
} else if (index == 3) {
editor->setEditingConnections();
}
if (!editor->map) return;
if (index != 4) {
if (userConfig.getEncounterJsonActive())
editor->saveEncounterTabData();

View file

@ -390,6 +390,19 @@ bool Project::loadLayout(MapLayout *layout) {
&& loadedBorder;
}
Layout *Project::loadLayout(QString layoutId) {
//
if (mapLayouts.contains(layoutId)) {
Layout *layout = mapLayouts[layoutId];
if (loadLayout(layout)) {
return layout;
}
}
logError(QString("Error: Failed to load layout '%1'").arg(layoutId));
return nullptr;
}
bool Project::loadMapLayout(Map* map) {
if (!map->isPersistedToFile) {
return true;

View file

@ -51,7 +51,7 @@ void CollisionPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
void CollisionPixmapItem::draw(bool ignoreCache) {
if (this->layout) {
// !TODO
// this->layout->setCollisionItem(this);
this->layout->setCollisionItem(this);
setPixmap(this->layout->renderCollision(ignoreCache));
setOpacity(*this->opacity);
}

View file

@ -272,14 +272,14 @@ LayoutTreeModel::LayoutTreeModel(Project *project, QObject *parent) : QStandardI
initialize();
}
QStandardItem *LayoutTreeModel::createLayoutItem(QString layoutName) {
QStandardItem *LayoutTreeModel::createLayoutItem(QString layoutId) {
QStandardItem *layout = new QStandardItem;
layout->setText(layoutName);
layout->setText(layoutId);
layout->setEditable(false);
layout->setData(layoutName, Qt::UserRole);
layout->setData(layoutId, Qt::UserRole);
layout->setData("map_layout", MapListRoles::TypeRole);
// // group->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
this->layoutItems.insert(layoutName, layout);
this->layoutItems.insert(layoutId, layout);
return layout;
}
@ -298,17 +298,16 @@ void LayoutTreeModel::initialize() {
for (int i = 0; i < this->project->mapLayoutsTable.length(); i++) {
//
QString layoutId = project->mapLayoutsTable.value(i);
MapLayout *layout = project->mapLayouts.value(layoutId);
QStandardItem *layoutItem = createLayoutItem(layout->name);
QStandardItem *layoutItem = createLayoutItem(layoutId);
this->root->appendRow(layoutItem);
}
for (auto mapList : this->project->groupedMapNames) {
for (auto mapName : mapList) {
//
QString layoutName = project->readMapLayoutName(mapName);
QString layoutId = project->readMapLayoutId(mapName);
QStandardItem *map = createMapItem(mapName);
this->layoutItems[layoutName]->appendRow(map);
this->layoutItems[layoutId]->appendRow(map);
}
}
@ -344,6 +343,15 @@ QVariant LayoutTreeModel::data(const QModelIndex &index, int role) const {
QString type = item->data(MapListRoles::TypeRole).toString();
if (type == "map_layout") {
QString layoutId = item->data(Qt::UserRole).toString();
if (layoutId == this->openLayout) {
return mapOpenedIcon;
}
else if (this->project->mapLayouts.contains(layoutId)) {
if (this->project->mapLayouts.value(layoutId)->hasUnsavedChanges()) {
return mapEditedIcon;
}
}
return mapIcon;
}
else if (type == "map_name") {