From f750c56e296186e96b8311c76a970941e89551a6 Mon Sep 17 00:00:00 2001 From: garak Date: Mon, 20 May 2019 22:08:04 -0400 Subject: [PATCH] create map image export window --- forms/mapimageexporter.ui | 322 ++++++++++++++++++++++++++++++++++ include/mainwindow.h | 20 +-- include/ui/mapimageexporter.h | 67 +++++++ porymap.pro | 5 +- src/mainwindow.cpp | 16 +- src/ui/mapimageexporter.cpp | 195 ++++++++++++++++++++ 6 files changed, 602 insertions(+), 23 deletions(-) create mode 100644 forms/mapimageexporter.ui create mode 100644 include/ui/mapimageexporter.h create mode 100644 src/ui/mapimageexporter.cpp diff --git a/forms/mapimageexporter.ui b/forms/mapimageexporter.ui new file mode 100644 index 00000000..aa0f3d2d --- /dev/null +++ b/forms/mapimageexporter.ui @@ -0,0 +1,322 @@ + + + MapImageExporter + + + + 0 + 0 + 696 + 396 + + + + Export Map Image + + + true + + + + + + Preview + + + + + + true + + + + + 0 + 0 + 337 + 334 + + + + + + + + 0 + 0 + + + + false + + + false + + + QAbstractScrollArea::AdjustIgnored + + + QGraphicsView::NoDrag + + + + + + + Qt::Vertical + + + + 10 + 100 + + + + + + + + Qt::Vertical + + + + 10 + 100 + + + + + + + + Qt::Horizontal + + + + 100 + 10 + + + + + + + + Qt::Horizontal + + + + 100 + 10 + + + + + + + + + + + + + + + + + + + Map + + + + + + + QComboBox::AdjustToContents + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Events + + + + + + + + Warps + + + + + + + Objects + + + + + + + BGs + + + + + + + Triggers + + + + + + + Heal Spots + + + + + + + + + + + + Connections + + + + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + + + + + + Miscellaneous + + + + + + + + Grid + + + + + + + Collision + + + + + + + Border + + + + + + + + + + + + + + Reset + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + Save + + + + + + + + + + + + diff --git a/include/mainwindow.h b/include/mainwindow.h index 2915e169..540e985a 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -16,6 +16,7 @@ #include "editor.h" #include "tileseteditor.h" #include "regionmapeditor.h" +#include "mapimageexporter.h" #include "filterchildrenproxymodel.h" #include "newmappopup.h" #include "newtilesetdialog.h" @@ -71,7 +72,6 @@ private slots: void on_tabWidget_currentChanged(int index); void on_actionUndo_triggered(); - void on_actionRedo_triggered(); void on_actionZoom_In_triggered(); @@ -94,15 +94,10 @@ private slots: void updateObjects(); void on_toolButton_Paint_clicked(); - void on_toolButton_Select_clicked(); - void on_toolButton_Fill_clicked(); - void on_toolButton_Dropper_clicked(); - void on_toolButton_Move_clicked(); - void on_toolButton_Shift_clicked(); void onOpenMapListContextMenu(const QPoint &point); @@ -115,29 +110,17 @@ private slots: void on_action_Export_Map_Image_triggered(); void on_comboBox_ConnectionDirection_currentIndexChanged(const QString &arg1); - void on_spinBox_ConnectionOffset_valueChanged(int offset); - void on_comboBox_ConnectedMap_currentTextChanged(const QString &mapName); - void on_pushButton_AddConnection_clicked(); - void on_pushButton_RemoveConnection_clicked(); - void on_comboBox_DiveMap_currentTextChanged(const QString &mapName); - void on_comboBox_EmergeMap_currentTextChanged(const QString &mapName); - void on_comboBox_PrimaryTileset_activated(const QString &arg1); - void on_comboBox_SecondaryTileset_activated(const QString &arg1); - void on_pushButton_clicked(); - void on_checkBox_smartPaths_stateChanged(int selected); - void on_checkBox_Visibility_clicked(bool checked); - void on_checkBox_ToggleBorder_stateChanged(int arg1); void resetMapViewScale(); @@ -169,6 +152,7 @@ private: Ui::MainWindow *ui; TilesetEditor *tilesetEditor = nullptr; RegionMapEditor *regionMapEditor = nullptr; + MapImageExporter *mapImageExporter = nullptr; FilterChildrenProxyModel *mapListProxyModel; NewMapPopup *newmapprompt = nullptr; QStandardItemModel *mapListModel; diff --git a/include/ui/mapimageexporter.h b/include/ui/mapimageexporter.h new file mode 100644 index 00000000..a6772ed1 --- /dev/null +++ b/include/ui/mapimageexporter.h @@ -0,0 +1,67 @@ +#ifndef MAPIMAGEEXPORTER_H +#define MAPIMAGEEXPORTER_H + +#include "map.h" +#include "editor.h" + +#include + +namespace Ui { +class MapImageExporter; +} + +class MapImageExporter : public QDialog +{ + Q_OBJECT + +public: + explicit MapImageExporter(QWidget *parent, Editor *editor); + ~MapImageExporter(); + +private: + Ui::MapImageExporter *ui; + + Map *map = nullptr; + Editor *editor = nullptr; + QGraphicsScene *scene = nullptr; + + QPixmap preview; + + bool showObjects = false; + bool showWarps = false; + bool showBGs = false; + bool showTriggers = false; + bool showHealSpots = false; + bool showUpConnections = false; + bool showDownConnections = false; + bool showLeftConnections = false; + bool showRightConnections = false; + bool showGrid = false; + bool showBorder = false; + bool showCollision = false; + + void updatePreview(); + void saveImage(); + +private slots: + void on_checkBox_Objects_stateChanged(int state); + void on_checkBox_Warps_stateChanged(int state); + void on_checkBox_BGs_stateChanged(int state); + void on_checkBox_Triggers_stateChanged(int state); + void on_checkBox_HealSpots_stateChanged(int state); + + void on_checkBox_ConnectionUp_stateChanged(int state); + void on_checkBox_ConnectionDown_stateChanged(int state); + void on_checkBox_ConnectionLeft_stateChanged(int state); + void on_checkBox_ConnectionRight_stateChanged(int state); + + void on_checkBox_Elevation_stateChanged(int state); + void on_checkBox_Grid_stateChanged(int state); + void on_checkBox_Border_stateChanged(int state); + + void on_pushButton_Save_pressed(); + void on_pushButton_Reset_pressed(); + void on_pushButton_Cancel_pressed(); +}; + +#endif // MAPIMAGEEXPORTER_H diff --git a/porymap.pro b/porymap.pro index 6492f342..76a0433f 100644 --- a/porymap.pro +++ b/porymap.pro @@ -61,6 +61,7 @@ SOURCES += src/core/block.cpp \ src/ui/tilemaptileselector.cpp \ src/ui/regionmapeditor.cpp \ src/ui/newmappopup.cpp \ + src/ui/mapimageexporter.cpp \ src/config.cpp \ src/editor.cpp \ src/main.cpp \ @@ -119,6 +120,7 @@ HEADERS += include/core/block.h \ include/ui/tilemaptileselector.h \ include/ui/regionmapeditor.h \ include/ui/newmappopup.h \ + include/ui/mapimageexporter.h \ include/config.h \ include/editor.h \ include/mainwindow.h \ @@ -134,7 +136,8 @@ FORMS += forms/mainwindow.ui \ forms/regionmapeditor.ui \ forms/newmappopup.ui \ forms/aboutporymap.ui \ - forms/newtilesetdialog.ui + forms/newtilesetdialog.ui \ + forms/mapimageexporter.ui RESOURCES += \ resources/images.qrc diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index dad5fbae..61a022cc 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1913,10 +1913,18 @@ void MainWindow::onTilesetsSaved(QString primaryTilesetLabel, QString secondaryT void MainWindow::on_action_Export_Map_Image_triggered() { - QString defaultFilepath = QString("%1/%2.png").arg(editor->project->root).arg(editor->map->name); - QString filepath = QFileDialog::getSaveFileName(this, "Export Map Image", defaultFilepath, "Image Files (*.png *.jpg *.bmp)"); - if (!filepath.isEmpty()) { - editor->map_item->pixmap().save(filepath); + if (!this->mapImageExporter) { + this->mapImageExporter = new MapImageExporter(this, this->editor); + connect(this->mapImageExporter, &QObject::destroyed, [=](QObject *) { this->mapImageExporter = nullptr; }); + this->mapImageExporter->setAttribute(Qt::WA_DeleteOnClose); + } + + if (!this->mapImageExporter->isVisible()) { + this->mapImageExporter->show(); + } else if (this->mapImageExporter->isMinimized()) { + this->mapImageExporter->showNormal(); + } else { + this->mapImageExporter->activateWindow(); } } diff --git a/src/ui/mapimageexporter.cpp b/src/ui/mapimageexporter.cpp new file mode 100644 index 00000000..4e3b6e05 --- /dev/null +++ b/src/ui/mapimageexporter.cpp @@ -0,0 +1,195 @@ +#include "mapimageexporter.h" +#include "ui_mapimageexporter.h" + +#include +#include +#include +#include +#include + +MapImageExporter::MapImageExporter(QWidget *parent_, Editor *editor_) : + QDialog(parent_), + ui(new Ui::MapImageExporter) +{ + ui->setupUi(this); + this->map = editor_->map; + this->editor = editor_; + + this->ui->comboBox_MapSelection->addItems(*editor->project->mapNames); + this->ui->comboBox_MapSelection->setCurrentText(map->name); + this->ui->comboBox_MapSelection->setEnabled(false);// TODO: allow selecting map from drop-down + + updatePreview(); +} + +MapImageExporter::~MapImageExporter() { + delete ui; +} + +void MapImageExporter::saveImage() { + QString defaultFilepath = QString("%1/%2.png").arg(editor->project->root).arg(map->name); + QString filepath = QFileDialog::getSaveFileName(this, "Export Map Image", defaultFilepath, + "Image Files (*.png *.jpg *.bmp)"); + if (!filepath.isEmpty()) { + this->ui->graphicsView_Preview->grab(this->ui->graphicsView_Preview->sceneRect().toRect()).save(filepath); + this->close(); + } +} + +void MapImageExporter::updatePreview() { + if (scene) { + delete scene; + scene = nullptr; + } + scene = new QGraphicsScene; + + // draw background layer / base image + if (showCollision) { + preview = map->collision_pixmap; + } else { + preview = map->pixmap; + } + + // draw events + QPainter eventPainter(&preview); + QList events = map->getAllEvents(); + for (Event *event : events) { + QString group = event->get("event_group_type"); + if ((showObjects && group == "object_event_group") + || (showWarps && group == "warp_event_group") + || (showBGs && group == "bg_event_group") + || (showTriggers && group == "coord_event_group") + || (showHealSpots && group == "heal_event_group")) + eventPainter.drawImage(QPoint(event->getPixelX(), event->getPixelY()), event->pixmap.toImage()); + } + eventPainter.end(); + + // draw map border + // note: this will break when allowing map to be selected from drop down maybe + int borderHeight = 0, borderWidth = 0; + if (showUpConnections || showDownConnections || showLeftConnections || showRightConnections) showBorder = true; + if (showBorder) { + borderHeight = 32 * 3, borderWidth = 32 * 3; + QPixmap newPreview = QPixmap(map->pixmap.width() + borderWidth * 2, map->pixmap.height() + borderHeight * 2); + QPainter borderPainter(&newPreview); + for (auto borderItem : editor->borderItems) { + borderPainter.drawImage(QPoint(borderItem->x() + borderWidth, borderItem->y() + borderHeight), + borderItem->pixmap().toImage()); + } + borderPainter.drawImage(QPoint(borderWidth, borderHeight), preview.toImage()); + borderPainter.end(); + preview = newPreview; + } + + // if showing connections, draw on outside of image + QPainter connectionPainter(&preview); + for (auto connectionItem : editor->connection_edit_items) { + QString direction = connectionItem->connection->direction; + if ((showUpConnections && direction == "up") + || (showDownConnections && direction == "down") + || (showLeftConnections && direction == "left") + || (showRightConnections && direction == "right")) + connectionPainter.drawImage(connectionItem->initialX + borderWidth, connectionItem->initialY + borderHeight, + connectionItem->basePixmap.toImage()); + } + connectionPainter.end(); + + // draw grid directly onto the pixmap + // since the last grid lines are outside of the pixmap, add a pixel to the bottom and right + if (showGrid) { + int addX = 1, addY = 1; + if (borderHeight) addY = 0; + if (borderWidth) addX = 0; + + QPixmap newPreview = QPixmap(preview.width() + addX, preview.height() + addY); + QPainter gridPainter(&newPreview); + gridPainter.drawImage(QPoint(0, 0), preview.toImage()); + for (auto lineItem : editor->gridLines) { + QPointF addPos(borderWidth, borderHeight); + gridPainter.drawLine(lineItem->line().p1() + addPos, lineItem->line().p2() + addPos); + } + gridPainter.end(); + preview = newPreview; + } + + scene->addPixmap(preview); + + this->scene->setSceneRect(this->scene->itemsBoundingRect()); + + this->ui->graphicsView_Preview->setScene(scene); + this->ui->graphicsView_Preview->setFixedSize(scene->itemsBoundingRect().width() + 2, + scene->itemsBoundingRect().height() + 2); +} + +void MapImageExporter::on_checkBox_Elevation_stateChanged(int state) { + showCollision = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_Grid_stateChanged(int state) { + showGrid = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_Border_stateChanged(int state) { + showBorder = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_Objects_stateChanged(int state) { + showObjects = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_Warps_stateChanged(int state) { + showWarps = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_BGs_stateChanged(int state) { + showBGs = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_Triggers_stateChanged(int state) { + showTriggers = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_HealSpots_stateChanged(int state) { + showHealSpots = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_ConnectionUp_stateChanged(int state) { + showUpConnections = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_ConnectionDown_stateChanged(int state) { + showDownConnections = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_ConnectionLeft_stateChanged(int state) { + showLeftConnections = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_checkBox_ConnectionRight_stateChanged(int state) { + showRightConnections = (state == Qt::Checked); + updatePreview(); +} + +void MapImageExporter::on_pushButton_Save_pressed() { + saveImage(); +} + +void MapImageExporter::on_pushButton_Reset_pressed() { + for (auto widget : this->findChildren()) + widget->setChecked(false); +} + +void MapImageExporter::on_pushButton_Cancel_pressed() { + this->close(); +}