mirror of
https://github.com/huderlem/porymap.git
synced 2026-09-28 02:46:45 -05:00
Merge remote-tracking branch 'origin/master' into better-map-zoom
This commit is contained in:
@@ -122,10 +122,10 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
this->mapSortOrder = MapSortOrder::Group;
|
||||
logWarn(QString("Invalid config value for map_sort_order: '%1'. Must be 'group', 'area', or 'layout'.").arg(value));
|
||||
}
|
||||
} else if (key == "window_geometry") {
|
||||
this->windowGeometry = bytesFromString(value);
|
||||
} else if (key == "window_state") {
|
||||
this->windowState = bytesFromString(value);
|
||||
} else if (key == "main_window_geometry") {
|
||||
this->mainWindowGeometry = bytesFromString(value);
|
||||
} else if (key == "main_window_state") {
|
||||
this->mainWindowState = bytesFromString(value);
|
||||
} else if (key == "map_splitter_state") {
|
||||
this->mapSplitterState = bytesFromString(value);
|
||||
} else if (key == "main_splitter_state") {
|
||||
@@ -137,6 +137,18 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
logWarn(QString("Invalid config value for collision_opacity: '%1'. Must be an integer.").arg(value));
|
||||
this->collisionOpacity = 50;
|
||||
}
|
||||
} else if (key == "tileset_editor_geometry") {
|
||||
this->tilesetEditorGeometry = bytesFromString(value);
|
||||
} else if (key == "tileset_editor_state") {
|
||||
this->tilesetEditorState = bytesFromString(value);
|
||||
} else if (key == "palette_editor_geometry") {
|
||||
this->paletteEditorGeometry = bytesFromString(value);
|
||||
} else if (key == "palette_editor_state") {
|
||||
this->paletteEditorState = bytesFromString(value);
|
||||
} else if (key == "region_map_editor_geometry") {
|
||||
this->regionMapEditorGeometry = bytesFromString(value);
|
||||
} else if (key == "region_map_editor_state") {
|
||||
this->regionMapEditorState = bytesFromString(value);
|
||||
} else if (key == "metatiles_zoom") {
|
||||
bool ok;
|
||||
this->metatilesZoom = qMax(10, qMin(100, value.toInt(&ok)));
|
||||
@@ -186,10 +198,16 @@ QMap<QString, QString> PorymapConfig::getKeyValueMap() {
|
||||
map.insert("recent_map", this->recentMap);
|
||||
map.insert("pretty_cursors", this->prettyCursors ? "1" : "0");
|
||||
map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder));
|
||||
map.insert("window_geometry", stringFromByteArray(this->windowGeometry));
|
||||
map.insert("window_state", stringFromByteArray(this->windowState));
|
||||
map.insert("main_window_geometry", stringFromByteArray(this->mainWindowGeometry));
|
||||
map.insert("main_window_state", stringFromByteArray(this->mainWindowState));
|
||||
map.insert("map_splitter_state", stringFromByteArray(this->mapSplitterState));
|
||||
map.insert("main_splitter_state", stringFromByteArray(this->mainSplitterState));
|
||||
map.insert("tileset_editor_geometry", stringFromByteArray(this->tilesetEditorGeometry));
|
||||
map.insert("tileset_editor_state", stringFromByteArray(this->tilesetEditorState));
|
||||
map.insert("palette_editor_geometry", stringFromByteArray(this->paletteEditorGeometry));
|
||||
map.insert("palette_editor_state", stringFromByteArray(this->paletteEditorState));
|
||||
map.insert("region_map_editor_geometry", stringFromByteArray(this->regionMapEditorGeometry));
|
||||
map.insert("region_map_editor_state", stringFromByteArray(this->regionMapEditorState));
|
||||
map.insert("collision_opacity", QString("%1").arg(this->collisionOpacity));
|
||||
map.insert("metatiles_zoom", QString("%1").arg(this->metatilesZoom));
|
||||
map.insert("show_player_view", this->showPlayerView ? "1" : "0");
|
||||
@@ -243,15 +261,33 @@ void PorymapConfig::setMonitorFiles(bool monitor) {
|
||||
this->save();
|
||||
}
|
||||
|
||||
void PorymapConfig::setGeometry(QByteArray windowGeometry_, QByteArray windowState_,
|
||||
void PorymapConfig::setMainGeometry(QByteArray mainWindowGeometry_, QByteArray mainWindowState_,
|
||||
QByteArray mapSplitterState_, QByteArray mainSplitterState_) {
|
||||
this->windowGeometry = windowGeometry_;
|
||||
this->windowState = windowState_;
|
||||
this->mainWindowGeometry = mainWindowGeometry_;
|
||||
this->mainWindowState = mainWindowState_;
|
||||
this->mapSplitterState = mapSplitterState_;
|
||||
this->mainSplitterState = mainSplitterState_;
|
||||
this->save();
|
||||
}
|
||||
|
||||
void PorymapConfig::setTilesetEditorGeometry(QByteArray tilesetEditorGeometry_, QByteArray tilesetEditorState_) {
|
||||
this->tilesetEditorGeometry = tilesetEditorGeometry_;
|
||||
this->tilesetEditorState = tilesetEditorState_;
|
||||
this->save();
|
||||
}
|
||||
|
||||
void PorymapConfig::setPaletteEditorGeometry(QByteArray paletteEditorGeometry_, QByteArray paletteEditorState_) {
|
||||
this->paletteEditorGeometry = paletteEditorGeometry_;
|
||||
this->paletteEditorState = paletteEditorState_;
|
||||
this->save();
|
||||
}
|
||||
|
||||
void PorymapConfig::setRegionMapEditorGeometry(QByteArray regionMapEditorGeometry_, QByteArray regionMapEditorState_) {
|
||||
this->regionMapEditorGeometry = regionMapEditorGeometry_;
|
||||
this->regionMapEditorState = regionMapEditorState_;
|
||||
this->save();
|
||||
}
|
||||
|
||||
void PorymapConfig::setCollisionOpacity(int opacity) {
|
||||
this->collisionOpacity = opacity;
|
||||
// don't auto-save here because this can be called very frequently.
|
||||
@@ -296,17 +332,44 @@ bool PorymapConfig::getPrettyCursors() {
|
||||
return this->prettyCursors;
|
||||
}
|
||||
|
||||
QMap<QString, QByteArray> PorymapConfig::getGeometry() {
|
||||
QMap<QString, QByteArray> PorymapConfig::getMainGeometry() {
|
||||
QMap<QString, QByteArray> geometry;
|
||||
|
||||
geometry.insert("window_geometry", this->windowGeometry);
|
||||
geometry.insert("window_state", this->windowState);
|
||||
geometry.insert("main_window_geometry", this->mainWindowGeometry);
|
||||
geometry.insert("main_window_state", this->mainWindowState);
|
||||
geometry.insert("map_splitter_state", this->mapSplitterState);
|
||||
geometry.insert("main_splitter_state", this->mainSplitterState);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
QMap<QString, QByteArray> PorymapConfig::getTilesetEditorGeometry() {
|
||||
QMap<QString, QByteArray> geometry;
|
||||
|
||||
geometry.insert("tileset_editor_geometry", this->tilesetEditorGeometry);
|
||||
geometry.insert("tileset_editor_state", this->tilesetEditorState);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
QMap<QString, QByteArray> PorymapConfig::getPaletteEditorGeometry() {
|
||||
QMap<QString, QByteArray> geometry;
|
||||
|
||||
geometry.insert("palette_editor_geometry", this->paletteEditorGeometry);
|
||||
geometry.insert("palette_editor_state", this->paletteEditorState);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
QMap<QString, QByteArray> PorymapConfig::getRegionMapEditorGeometry() {
|
||||
QMap<QString, QByteArray> geometry;
|
||||
|
||||
geometry.insert("region_map_editor_geometry", this->regionMapEditorGeometry);
|
||||
geometry.insert("region_map_editor_state", this->regionMapEditorState);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
int PorymapConfig::getCollisionOpacity() {
|
||||
return this->collisionOpacity;
|
||||
}
|
||||
|
||||
@@ -1646,7 +1646,7 @@ void Editor::setConnectionMap(QString mapName) {
|
||||
if (!selected_connection_item)
|
||||
return;
|
||||
|
||||
if (mapName.isEmpty()) {
|
||||
if (mapName.isEmpty() || mapName == NONE_MAP_NAME) {
|
||||
removeCurrentConnection();
|
||||
return;
|
||||
}
|
||||
@@ -1798,7 +1798,7 @@ void Editor::updateDiveEmergeMap(QString mapName, QString direction) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mapName.isEmpty()) {
|
||||
if (mapName.isEmpty() || mapName == NONE_MAP_NAME) {
|
||||
// Remove dive/emerge connection
|
||||
if (connection) {
|
||||
map->connections.removeOne(connection);
|
||||
|
||||
11
src/log.cpp
11
src/log.cpp
@@ -86,3 +86,14 @@ QString getLogPath() {
|
||||
QString getMostRecentError() {
|
||||
return mostRecentError;
|
||||
}
|
||||
|
||||
bool cleanupLargeLog() {
|
||||
QFile logFile(getLogPath());
|
||||
if (logFile.size() < 20000000)
|
||||
return false;
|
||||
|
||||
bool removed = logFile.remove();
|
||||
if (removed)
|
||||
logWarn(QString("Previous log file %1 was cleared due to being over 20MB in size.").arg(getLogPath()));
|
||||
return removed;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "adjustingstackedwidget.h"
|
||||
#include "draggablepixmapitem.h"
|
||||
#include "editcommands.h"
|
||||
#include "flowlayout.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDirIterator>
|
||||
@@ -53,6 +54,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
QApplication::setWindowIcon(QIcon(":/icons/porymap-icon-2.ico"));
|
||||
ui->setupUi(this);
|
||||
|
||||
cleanupLargeLog();
|
||||
|
||||
this->initWindow();
|
||||
if (!this->openRecentProject()) {
|
||||
// Re-initialize everything to a blank slate if opening the recent project failed.
|
||||
@@ -133,6 +136,19 @@ void MainWindow::initCustomUI() {
|
||||
connect(labelCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index){
|
||||
stack->setCurrentIndex(index);
|
||||
});
|
||||
|
||||
// Convert the layout of the map tools' frame into an adjustable FlowLayout
|
||||
FlowLayout *flowLayout = new FlowLayout;
|
||||
flowLayout->setContentsMargins(ui->frame_mapTools->layout()->contentsMargins());
|
||||
flowLayout->setSpacing(ui->frame_mapTools->layout()->spacing());
|
||||
for (auto *child : ui->frame_mapTools->findChildren<QWidget *>(QString(), Qt::FindDirectChildrenOnly)) {
|
||||
flowLayout->addWidget(child);
|
||||
child->setFixedHeight(
|
||||
ui->frame_mapTools->height() - flowLayout->contentsMargins().top() - flowLayout->contentsMargins().bottom()
|
||||
);
|
||||
}
|
||||
delete ui->frame_mapTools->layout();
|
||||
ui->frame_mapTools->setLayout(flowLayout);
|
||||
}
|
||||
|
||||
void MainWindow::initExtraSignals() {
|
||||
@@ -347,10 +363,10 @@ void MainWindow::loadUserSettings() {
|
||||
}
|
||||
|
||||
void MainWindow::restoreWindowState() {
|
||||
logInfo("Restoring window geometry from previous session.");
|
||||
QMap<QString, QByteArray> geometry = porymapConfig.getGeometry();
|
||||
this->restoreGeometry(geometry.value("window_geometry"));
|
||||
this->restoreState(geometry.value("window_state"));
|
||||
logInfo("Restoring main window geometry from previous session.");
|
||||
QMap<QString, QByteArray> geometry = porymapConfig.getMainGeometry();
|
||||
this->restoreGeometry(geometry.value("main_window_geometry"));
|
||||
this->restoreState(geometry.value("main_window_state"));
|
||||
this->ui->splitter_map->restoreState(geometry.value("map_splitter_state"));
|
||||
this->ui->splitter_main->restoreState(geometry.value("main_splitter_state"));
|
||||
}
|
||||
@@ -1195,8 +1211,11 @@ void MainWindow::on_actionNew_Tileset_triggered() {
|
||||
|
||||
void MainWindow::updateTilesetEditor() {
|
||||
if (this->tilesetEditor) {
|
||||
this->tilesetEditor->setMap(this->editor->map);
|
||||
this->tilesetEditor->setTilesets(editor->ui->comboBox_PrimaryTileset->currentText(), editor->ui->comboBox_SecondaryTileset->currentText());
|
||||
this->tilesetEditor->update(
|
||||
this->editor->map,
|
||||
editor->ui->comboBox_PrimaryTileset->currentText(),
|
||||
editor->ui->comboBox_SecondaryTileset->currentText()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2476,7 +2495,6 @@ void MainWindow::on_actionTileset_Editor_triggered()
|
||||
this->tilesetEditor = new TilesetEditor(this->editor->project, this->editor->map, this);
|
||||
connect(this->tilesetEditor, SIGNAL(tilesetsSaved(QString, QString)), this, SLOT(onTilesetsSaved(QString, QString)));
|
||||
connect(this->tilesetEditor, &QObject::destroyed, [=](QObject *) { this->tilesetEditor = nullptr; });
|
||||
this->tilesetEditor->setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
if (!this->tilesetEditor->isVisible()) {
|
||||
@@ -2617,7 +2635,6 @@ void MainWindow::on_actionRegion_Map_Editor_triggered() {
|
||||
return;
|
||||
}
|
||||
connect(this->regionMapEditor, &QObject::destroyed, [=](QObject *) { this->regionMapEditor = nullptr; });
|
||||
this->regionMapEditor->setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
if (!this->regionMapEditor->isVisible()) {
|
||||
@@ -2656,7 +2673,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
}
|
||||
}
|
||||
|
||||
porymapConfig.setGeometry(
|
||||
porymapConfig.setMainGeometry(
|
||||
this->saveGeometry(),
|
||||
this->saveState(),
|
||||
this->ui->splitter_map->saveState(),
|
||||
|
||||
@@ -247,7 +247,7 @@ void MainWindow::addImage(int x, int y, QString filepath) {
|
||||
|
||||
void MainWindow::refreshAfterPaletteChange(Tileset *tileset) {
|
||||
if (this->tilesetEditor) {
|
||||
this->tilesetEditor->setTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
|
||||
this->tilesetEditor->updateTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
|
||||
}
|
||||
this->editor->metatile_selector_item->draw();
|
||||
this->editor->selected_border_metatiles_item->draw();
|
||||
|
||||
136
src/ui/flowlayout.cpp
Normal file
136
src/ui/flowlayout.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include <flowlayout.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) :
|
||||
QLayout(parent),
|
||||
horzSpace(hSpacing),
|
||||
vertSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) :
|
||||
horzSpace(hSpacing),
|
||||
vertSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::~FlowLayout()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
while ((item = takeAt(0)))
|
||||
delete item;
|
||||
}
|
||||
|
||||
void FlowLayout::addItem(QLayoutItem *item) {
|
||||
itemList.append(item);
|
||||
}
|
||||
|
||||
int FlowLayout::horizontalSpacing() const {
|
||||
if (horzSpace >= 0)
|
||||
return horzSpace;
|
||||
else
|
||||
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
|
||||
}
|
||||
|
||||
int FlowLayout::verticalSpacing() const {
|
||||
if (vertSpace >= 0)
|
||||
return vertSpace;
|
||||
else
|
||||
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
|
||||
}
|
||||
|
||||
int FlowLayout::count() const {
|
||||
return itemList.size();
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAt(int index) const {
|
||||
return itemList.value(index);
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::takeAt(int index) {
|
||||
if (index >= 0 && index < itemList.size())
|
||||
return itemList.takeAt(index);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Qt::Orientations FlowLayout::expandingDirections() const {
|
||||
return { };
|
||||
}
|
||||
|
||||
bool FlowLayout::hasHeightForWidth() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
int FlowLayout::heightForWidth(int width) const {
|
||||
int height = doLayout(QRect(0, 0, width, 0), true);
|
||||
return height;
|
||||
}
|
||||
|
||||
void FlowLayout::setGeometry(const QRect &rect) {
|
||||
QLayout::setGeometry(rect);
|
||||
doLayout(rect, false);
|
||||
}
|
||||
|
||||
QSize FlowLayout::sizeHint() const {
|
||||
return minimumSize();
|
||||
}
|
||||
|
||||
QSize FlowLayout::minimumSize() const {
|
||||
QSize size;
|
||||
for (const QLayoutItem *item : qAsConst(itemList))
|
||||
size = size.expandedTo(item->minimumSize());
|
||||
|
||||
const QMargins margins = contentsMargins();
|
||||
size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
|
||||
return size;
|
||||
}
|
||||
|
||||
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const {
|
||||
int left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
|
||||
int x = effectiveRect.x();
|
||||
int y = effectiveRect.y();
|
||||
int lineHeight = 0;
|
||||
|
||||
for (QLayoutItem *item : qAsConst(itemList)) {
|
||||
const QWidget *wid = item->widget();
|
||||
int spaceX = horizontalSpacing();
|
||||
if (spaceX == -1)
|
||||
spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
|
||||
int spaceY = verticalSpacing();
|
||||
if (spaceY == -1)
|
||||
spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
|
||||
|
||||
int nextX = x + item->sizeHint().width() + spaceX;
|
||||
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
|
||||
x = effectiveRect.x();
|
||||
y = y + lineHeight + spaceY;
|
||||
nextX = x + item->sizeHint().width() + spaceX;
|
||||
lineHeight = 0;
|
||||
}
|
||||
|
||||
if (!testOnly)
|
||||
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
|
||||
x = nextX;
|
||||
lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||
}
|
||||
return y + lineHeight - rect.y() + bottom;
|
||||
}
|
||||
|
||||
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const {
|
||||
QObject *parent = this->parent();
|
||||
if (!parent) {
|
||||
return -1;
|
||||
} else if (parent->isWidgetType()) {
|
||||
QWidget *pw = static_cast<QWidget *>(parent);
|
||||
return pw->style()->pixelMetric(pm, nullptr, pw);
|
||||
} else {
|
||||
return static_cast<QLayout *>(parent)->spacing();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "paletteeditor.h"
|
||||
#include "ui_paletteeditor.h"
|
||||
#include "paletteutil.h"
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include "log.h"
|
||||
|
||||
PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset *secondaryTileset, int paletteId, QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
@@ -112,6 +113,7 @@ PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset
|
||||
this->initColorSliders();
|
||||
this->setPaletteId(paletteId);
|
||||
this->commitEditHistory(this->ui->spinBox_PaletteId->value());
|
||||
this->restoreWindowState();
|
||||
}
|
||||
|
||||
PaletteEditor::~PaletteEditor()
|
||||
@@ -227,6 +229,13 @@ void PaletteEditor::commitEditHistory(int paletteId) {
|
||||
this->palettesHistory[paletteId].push(commit);
|
||||
}
|
||||
|
||||
void PaletteEditor::restoreWindowState() {
|
||||
logInfo("Restoring palette editor geometry from previous session.");
|
||||
QMap<QString, QByteArray> geometry = porymapConfig.getPaletteEditorGeometry();
|
||||
this->restoreGeometry(geometry.value("palette_editor_geometry"));
|
||||
this->restoreState(geometry.value("palette_editor_state"));
|
||||
}
|
||||
|
||||
void PaletteEditor::on_actionUndo_triggered()
|
||||
{
|
||||
int paletteId = this->ui->spinBox_PaletteId->value();
|
||||
@@ -311,3 +320,10 @@ void PaletteEditor::on_actionImport_Palette_triggered()
|
||||
this->commitEditHistory(paletteId);
|
||||
emit this->changedPaletteColor();
|
||||
}
|
||||
|
||||
void PaletteEditor::closeEvent(QCloseEvent*) {
|
||||
porymapConfig.setPaletteEditorGeometry(
|
||||
this->saveGeometry(),
|
||||
this->saveState()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ RegionMapEditor::RegionMapEditor(QWidget *parent, Project *project_) :
|
||||
this->project = project_;
|
||||
this->region_map = new RegionMap;
|
||||
this->ui->action_RegionMap_Resize->setVisible(false);
|
||||
this->restoreWindowState();
|
||||
}
|
||||
|
||||
RegionMapEditor::~RegionMapEditor()
|
||||
@@ -42,6 +43,13 @@ RegionMapEditor::~RegionMapEditor()
|
||||
delete scene_region_map_tiles;
|
||||
}
|
||||
|
||||
void RegionMapEditor::restoreWindowState() {
|
||||
logInfo("Restoring region map editor geometry from previous session.");
|
||||
QMap<QString, QByteArray> geometry = porymapConfig.getRegionMapEditorGeometry();
|
||||
this->restoreGeometry(geometry.value("region_map_editor_geometry"));
|
||||
this->restoreState(geometry.value("region_map_editor_state"));
|
||||
}
|
||||
|
||||
void RegionMapEditor::on_action_RegionMap_Save_triggered() {
|
||||
setCurrentSquareOptions();
|
||||
if (project && region_map) {
|
||||
@@ -899,6 +907,11 @@ void RegionMapEditor::closeEvent(QCloseEvent *event)
|
||||
} else {
|
||||
event->accept();
|
||||
}
|
||||
|
||||
porymapConfig.setRegionMapEditorGeometry(
|
||||
this->saveGeometry(),
|
||||
this->saveState()
|
||||
);
|
||||
}
|
||||
|
||||
void RegionMapEditor::on_verticalSlider_Zoom_Map_Image_valueChanged(int val) {
|
||||
|
||||
@@ -14,10 +14,14 @@
|
||||
|
||||
TilesetEditor::TilesetEditor(Project *project, Map *map, QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::TilesetEditor)
|
||||
ui(new Ui::TilesetEditor),
|
||||
project(project),
|
||||
map(map),
|
||||
hasUnsavedChanges(false)
|
||||
{
|
||||
this->init(project, map);
|
||||
new QShortcut(QKeySequence("Ctrl+Shift+Z"), this, SLOT(on_actionRedo_triggered()));
|
||||
this->setTilesets(this->map->layout->tileset_primary_label, this->map->layout->tileset_secondary_label);
|
||||
this->initUi();
|
||||
this->initMetatileHistory();
|
||||
}
|
||||
|
||||
TilesetEditor::~TilesetEditor()
|
||||
@@ -37,27 +41,78 @@ TilesetEditor::~TilesetEditor()
|
||||
delete metatileLayersScene;
|
||||
}
|
||||
|
||||
void TilesetEditor::init(Project *project, Map *map) {
|
||||
ui->setupUi(this);
|
||||
this->project = project;
|
||||
void TilesetEditor::update(Map *map, QString primaryTilesetLabel, QString secondaryTilesetLabel) {
|
||||
this->updateMap(map);
|
||||
this->updateTilesets(primaryTilesetLabel, secondaryTilesetLabel);
|
||||
}
|
||||
|
||||
void TilesetEditor::updateMap(Map *map) {
|
||||
this->map = map;
|
||||
this->metatileSelector->map = map;
|
||||
}
|
||||
|
||||
void TilesetEditor::updateTilesets(QString primaryTilesetLabel, QString secondaryTilesetLabel) {
|
||||
if (this->hasUnsavedChanges) {
|
||||
QMessageBox::StandardButton result = QMessageBox::question(
|
||||
this,
|
||||
"porymap",
|
||||
"Tileset has been modified, save changes?",
|
||||
QMessageBox::No | QMessageBox::Yes,
|
||||
QMessageBox::Yes);
|
||||
if (result == QMessageBox::Yes)
|
||||
this->on_actionSave_Tileset_triggered();
|
||||
}
|
||||
this->hasUnsavedChanges = false;
|
||||
this->tileXFlip = ui->checkBox_xFlip->isChecked();
|
||||
this->tileYFlip = ui->checkBox_yFlip->isChecked();
|
||||
this->paletteId = ui->spinBox_paletteSelector->value();
|
||||
this->setTilesets(primaryTilesetLabel, secondaryTilesetLabel);
|
||||
this->refresh();
|
||||
}
|
||||
|
||||
Tileset *primaryTileset = project->getTileset(map->layout->tileset_primary_label);
|
||||
Tileset *secondaryTileset = project->getTileset(map->layout->tileset_secondary_label);
|
||||
bool TilesetEditor::selectMetatile(uint16_t metatileId) {
|
||||
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) return false;
|
||||
this->metatileSelector->select(metatileId);
|
||||
QPoint pos = this->metatileSelector->getMetatileIdCoordsOnWidget(metatileId);
|
||||
this->ui->scrollArea_Metatiles->ensureVisible(pos.x(), pos.y());
|
||||
return true;
|
||||
}
|
||||
|
||||
void TilesetEditor::setTilesets(QString primaryTilesetLabel, QString secondaryTilesetLabel) {
|
||||
Tileset *primaryTileset = project->getTileset(primaryTilesetLabel);
|
||||
Tileset *secondaryTileset = project->getTileset(secondaryTilesetLabel);
|
||||
if (this->primaryTileset) delete this->primaryTileset;
|
||||
if (this->secondaryTileset) delete this->secondaryTileset;
|
||||
this->primaryTileset = primaryTileset->copy();
|
||||
this->secondaryTileset = secondaryTileset->copy();
|
||||
}
|
||||
|
||||
QList<QString> sortedBehaviors;
|
||||
void TilesetEditor::initUi() {
|
||||
ui->setupUi(this);
|
||||
new QShortcut(QKeySequence("Ctrl+Shift+Z"), this, SLOT(on_actionRedo_triggered()));
|
||||
this->tileXFlip = ui->checkBox_xFlip->isChecked();
|
||||
this->tileYFlip = ui->checkBox_yFlip->isChecked();
|
||||
this->paletteId = ui->spinBox_paletteSelector->value();
|
||||
this->ui->spinBox_paletteSelector->setMinimum(0);
|
||||
this->ui->spinBox_paletteSelector->setMaximum(Project::getNumPalettesTotal() - 1);
|
||||
|
||||
this->setMetatileBehaviors();
|
||||
this->setMetatileLayersUi();
|
||||
this->setVersionSpecificUi();
|
||||
this->setMetatileLabelValidator();
|
||||
|
||||
this->initMetatileSelector();
|
||||
this->initMetatileLayersItem();
|
||||
this->initTileSelector();
|
||||
this->initSelectedTileItem();
|
||||
this->metatileSelector->select(0);
|
||||
this->restoreWindowState();
|
||||
}
|
||||
|
||||
void TilesetEditor::setMetatileBehaviors() {
|
||||
for (int num : project->metatileBehaviorMapInverse.keys()) {
|
||||
this->ui->comboBox_metatileBehaviors->addItem(project->metatileBehaviorMapInverse[num], num);
|
||||
}
|
||||
}
|
||||
|
||||
void TilesetEditor::setMetatileLayersUi() {
|
||||
if (!projectConfig.getTripleLayerMetatilesEnabled()) {
|
||||
this->ui->comboBox_layerType->addItem("Normal - Middle/Top", 0);
|
||||
this->ui->comboBox_layerType->addItem("Covered - Bottom/Middle", 1);
|
||||
@@ -67,10 +122,9 @@ void TilesetEditor::init(Project *project, Map *map) {
|
||||
this->ui->label_layerType->setVisible(false);
|
||||
this->ui->label_BottomTop->setText("Bottom/Middle/Top");
|
||||
}
|
||||
}
|
||||
|
||||
this->ui->spinBox_paletteSelector->setMinimum(0);
|
||||
this->ui->spinBox_paletteSelector->setMaximum(Project::getNumPalettesTotal() - 1);
|
||||
|
||||
void TilesetEditor::setVersionSpecificUi() {
|
||||
if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) {
|
||||
this->ui->comboBox_encounterType->setVisible(true);
|
||||
this->ui->label_encounterType->setVisible(true);
|
||||
@@ -89,72 +143,18 @@ void TilesetEditor::init(Project *project, Map *map) {
|
||||
this->ui->comboBox_terrainType->setVisible(false);
|
||||
this->ui->label_terrainType->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TilesetEditor::setMetatileLabelValidator() {
|
||||
//only allow characters valid for a symbol
|
||||
QRegExp expression("[_A-Za-z0-9]*$");
|
||||
QRegExpValidator *validator = new QRegExpValidator(expression);
|
||||
this->ui->lineEdit_metatileLabel->setValidator(validator);
|
||||
|
||||
this->initMetatileSelector(map);
|
||||
this->initMetatileLayersItem();
|
||||
this->initTileSelector();
|
||||
this->initSelectedTileItem();
|
||||
this->metatileSelector->select(0);
|
||||
|
||||
MetatileHistoryItem *commit = new MetatileHistoryItem(0, nullptr, this->metatile->copy());
|
||||
metatileHistory.push(commit);
|
||||
}
|
||||
|
||||
bool TilesetEditor::selectMetatile(uint16_t metatileId) {
|
||||
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) return false;
|
||||
this->metatileSelector->select(metatileId);
|
||||
QPoint pos = this->metatileSelector->getMetatileIdCoordsOnWidget(metatileId);
|
||||
this->ui->scrollArea_Metatiles->ensureVisible(pos.x(), pos.y());
|
||||
return true;
|
||||
}
|
||||
|
||||
void TilesetEditor::setMap(Map *map) {
|
||||
this->metatileSelector->map = map;
|
||||
}
|
||||
|
||||
void TilesetEditor::setTilesets(QString primaryTilesetLabel, QString secondaryTilesetLabel) {
|
||||
if (this->hasUnsavedChanges) {
|
||||
QMessageBox::StandardButton result = QMessageBox::question(
|
||||
this,
|
||||
"porymap",
|
||||
"Tileset has been modified, save changes?",
|
||||
QMessageBox::No | QMessageBox::Yes,
|
||||
QMessageBox::Yes);
|
||||
if (result == QMessageBox::Yes)
|
||||
this->on_actionSave_Tileset_triggered();
|
||||
}
|
||||
this->hasUnsavedChanges = false;
|
||||
delete this->primaryTileset;
|
||||
delete this->secondaryTileset;
|
||||
Tileset *primaryTileset = project->getTileset(primaryTilesetLabel);
|
||||
Tileset *secondaryTileset = project->getTileset(secondaryTilesetLabel);
|
||||
this->primaryTileset = primaryTileset->copy();
|
||||
this->secondaryTileset = secondaryTileset->copy();
|
||||
this->refresh();
|
||||
}
|
||||
|
||||
void TilesetEditor::refresh() {
|
||||
this->metatileLayersItem->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
this->tileSelector->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
this->metatileSelector->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
this->metatileSelector->select(this->metatileSelector->getSelectedMetatile());
|
||||
this->drawSelectedTiles();
|
||||
|
||||
this->ui->graphicsView_Tiles->setSceneRect(0, 0, this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_Tiles->setFixedSize(this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_Metatiles->setSceneRect(0, 0, this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width() + 2, this->selectedTilePixmapItem->pixmap().height() + 2);
|
||||
}
|
||||
|
||||
void TilesetEditor::initMetatileSelector(Map *map)
|
||||
void TilesetEditor::initMetatileSelector()
|
||||
{
|
||||
this->metatileSelector = new TilesetEditorMetatileSelector(this->primaryTileset, this->secondaryTileset, map);
|
||||
this->metatileSelector = new TilesetEditorMetatileSelector(this->primaryTileset, this->secondaryTileset, this->map);
|
||||
connect(this->metatileSelector, SIGNAL(hoveredMetatileChanged(uint16_t)),
|
||||
this, SLOT(onHoveredMetatileChanged(uint16_t)));
|
||||
connect(this->metatileSelector, SIGNAL(hoveredMetatileCleared()),
|
||||
@@ -170,6 +170,19 @@ void TilesetEditor::initMetatileSelector(Map *map)
|
||||
this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
|
||||
}
|
||||
|
||||
void TilesetEditor::initMetatileLayersItem() {
|
||||
Metatile *metatile = Tileset::getMetatile(this->metatileSelector->getSelectedMetatile(), this->primaryTileset, this->secondaryTileset);
|
||||
this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset);
|
||||
connect(this->metatileLayersItem, SIGNAL(tileChanged(int, int)),
|
||||
this, SLOT(onMetatileLayerTileChanged(int, int)));
|
||||
connect(this->metatileLayersItem, SIGNAL(selectedTilesChanged(QPoint, int, int)),
|
||||
this, SLOT(onMetatileLayerSelectionChanged(QPoint, int, int)));
|
||||
|
||||
this->metatileLayersScene = new QGraphicsScene;
|
||||
this->metatileLayersScene->addItem(this->metatileLayersItem);
|
||||
this->ui->graphicsView_metatileLayers->setScene(this->metatileLayersScene);
|
||||
}
|
||||
|
||||
void TilesetEditor::initTileSelector()
|
||||
{
|
||||
this->tileSelector = new TilesetEditorTileSelector(this->primaryTileset, this->secondaryTileset, projectConfig.getTripleLayerMetatilesEnabled());
|
||||
@@ -196,6 +209,40 @@ void TilesetEditor::initSelectedTileItem() {
|
||||
this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width() + 2, this->selectedTilePixmapItem->pixmap().height() + 2);
|
||||
}
|
||||
|
||||
void TilesetEditor::restoreWindowState() {
|
||||
logInfo("Restoring tileset editor geometry from previous session.");
|
||||
QMap<QString, QByteArray> geometry = porymapConfig.getTilesetEditorGeometry();
|
||||
this->restoreGeometry(geometry.value("tileset_editor_geometry"));
|
||||
this->restoreState(geometry.value("tileset_editor_state"));
|
||||
}
|
||||
|
||||
void TilesetEditor::initMetatileHistory() {
|
||||
MetatileHistoryItem *commit = new MetatileHistoryItem(0, nullptr, this->metatile->copy());
|
||||
metatileHistory.push(commit);
|
||||
}
|
||||
|
||||
void TilesetEditor::reset() {
|
||||
this->hasUnsavedChanges = false;
|
||||
this->setTilesets(this->primaryTileset->name, this->secondaryTileset->name);
|
||||
if (this->paletteEditor)
|
||||
this->paletteEditor->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
this->refresh();
|
||||
}
|
||||
|
||||
void TilesetEditor::refresh() {
|
||||
this->metatileLayersItem->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
this->tileSelector->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
this->metatileSelector->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
this->metatileSelector->select(this->metatileSelector->getSelectedMetatile());
|
||||
this->drawSelectedTiles();
|
||||
|
||||
this->ui->graphicsView_Tiles->setSceneRect(0, 0, this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_Tiles->setFixedSize(this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_Metatiles->setSceneRect(0, 0, this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
|
||||
this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width() + 2, this->selectedTilePixmapItem->pixmap().height() + 2);
|
||||
}
|
||||
|
||||
void TilesetEditor::drawSelectedTiles() {
|
||||
if (!this->selectedTileScene) {
|
||||
return;
|
||||
@@ -222,19 +269,6 @@ void TilesetEditor::drawSelectedTiles() {
|
||||
this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width() + 2, this->selectedTilePixmapItem->pixmap().height() + 2);
|
||||
}
|
||||
|
||||
void TilesetEditor::initMetatileLayersItem() {
|
||||
Metatile *metatile = Tileset::getMetatile(this->metatileSelector->getSelectedMetatile(), this->primaryTileset, this->secondaryTileset);
|
||||
this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset);
|
||||
connect(this->metatileLayersItem, SIGNAL(tileChanged(int, int)),
|
||||
this, SLOT(onMetatileLayerTileChanged(int, int)));
|
||||
connect(this->metatileLayersItem, SIGNAL(selectedTilesChanged(QPoint, int, int)),
|
||||
this, SLOT(onMetatileLayerSelectionChanged(QPoint, int, int)));
|
||||
|
||||
this->metatileLayersScene = new QGraphicsScene;
|
||||
this->metatileLayersScene->addItem(this->metatileLayersItem);
|
||||
this->ui->graphicsView_metatileLayers->setScene(this->metatileLayersScene);
|
||||
}
|
||||
|
||||
void TilesetEditor::onHoveredMetatileChanged(uint16_t metatileId) {
|
||||
Metatile *metatile = Tileset::getMetatile(metatileId, this->primaryTileset, this->secondaryTileset);
|
||||
QString message;
|
||||
@@ -599,6 +633,7 @@ void TilesetEditor::closeEvent(QCloseEvent *event)
|
||||
this->on_actionSave_Tileset_triggered();
|
||||
event->accept();
|
||||
} else if (result == QMessageBox::No) {
|
||||
this->reset();
|
||||
event->accept();
|
||||
} else if (result == QMessageBox::Cancel) {
|
||||
event->ignore();
|
||||
@@ -606,6 +641,14 @@ void TilesetEditor::closeEvent(QCloseEvent *event)
|
||||
} else {
|
||||
event->accept();
|
||||
}
|
||||
|
||||
if (event->isAccepted()) {
|
||||
if (this->paletteEditor) this->paletteEditor->close();
|
||||
porymapConfig.setTilesetEditorGeometry(
|
||||
this->saveGeometry(),
|
||||
this->saveState()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void TilesetEditor::on_actionChange_Metatiles_Count_triggered()
|
||||
|
||||
Reference in New Issue
Block a user