diff --git a/forms/tileseteditor.ui b/forms/tileseteditor.ui
index 33074d3f..dbc84d15 100644
--- a/forms/tileseteditor.ui
+++ b/forms/tileseteditor.ui
@@ -16,10 +16,152 @@
-
-
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 386
+ 539
+
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
-
-
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 386
+ 539
+
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
@@ -37,4 +179,4 @@
-
\ No newline at end of file
+
diff --git a/include/ui/tileseteditor.h b/include/ui/tileseteditor.h
index 7725a16f..2ea6f3ed 100644
--- a/include/ui/tileseteditor.h
+++ b/include/ui/tileseteditor.h
@@ -3,6 +3,7 @@
#include
#include "project.h"
+#include "tileseteditormetatileselector.h"
namespace Ui {
class TilesetEditor;
@@ -13,14 +14,22 @@ class TilesetEditor : public QMainWindow
Q_OBJECT
public:
- explicit TilesetEditor(QWidget *parent = nullptr, Project *project = nullptr);
+ explicit TilesetEditor(Project*, QString, QString, QWidget *parent = nullptr);
~TilesetEditor();
+private slots:
+ void onHoveredMetatileChanged(uint16_t);
+ void onHoveredMetatileCleared();
+ void onSelectedMetatileChanged(uint16_t);
+
private:
- void displayPrimaryTilesetTiles();
+ void initMetatilesSelector();
Ui::TilesetEditor *ui;
+ TilesetEditorMetatileSelector *metatileSelector;
Project *project;
QString primaryTilesetLabel;
+ QString secondaryTilesetLabel;
+ QGraphicsScene *metatilesScene;
};
#endif // TILESETEDITOR_H
diff --git a/include/ui/tileseteditormetatileselector.h b/include/ui/tileseteditormetatileselector.h
new file mode 100644
index 00000000..eb8d45fe
--- /dev/null
+++ b/include/ui/tileseteditormetatileselector.h
@@ -0,0 +1,43 @@
+#ifndef TILESETEDITORMETATILESELECTOR_H
+#define TILESETEDITORMETATILESELECTOR_H
+
+#include "selectablepixmapitem.h"
+#include "tileset.h"
+
+class TilesetEditorMetatileSelector: public SelectablePixmapItem {
+ Q_OBJECT
+public:
+ TilesetEditorMetatileSelector(Tileset *primaryTileset, Tileset *secondaryTileset): SelectablePixmapItem(32, 32, 1, 1) {
+ this->primaryTileset = primaryTileset;
+ this->secondaryTileset = secondaryTileset;
+ this->numMetatilesWide = 8;
+ setAcceptHoverEvents(true);
+ }
+ void draw();
+ void select(uint16_t metatileId);
+ void setTilesets(Tileset*, Tileset*);
+ uint16_t getSelectedMetatile();
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent*);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent*);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
+ void hoverMoveEvent(QGraphicsSceneHoverEvent*);
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent*);
+
+private:
+ Tileset *primaryTileset;
+ Tileset *secondaryTileset;
+ uint16_t selectedMetatile;
+ int numMetatilesWide;
+ void updateSelectedMetatile();
+ uint16_t getMetatileId(int x, int y);
+ QPoint getMetatileIdCoords(uint16_t);
+
+signals:
+ void hoveredMetatileChanged(uint16_t);
+ void hoveredMetatileCleared();
+ void selectedMetatileChanged(uint16_t);
+};
+
+#endif // TILESETEDITORMETATILESELECTOR_H
diff --git a/porymap.pro b/porymap.pro
index 3a027a4c..62c92337 100644
--- a/porymap.pro
+++ b/porymap.pro
@@ -41,6 +41,7 @@ SOURCES += src/core/block.cpp \
src/ui/noscrollspinbox.cpp \
src/ui/selectablepixmapitem.cpp \
src/ui/tileseteditor.cpp \
+ src/ui/tileseteditormetatileselector.cpp \
src/editor.cpp \
src/main.cpp \
src/mainwindow.cpp \
@@ -76,6 +77,7 @@ HEADERS += include/core/block.h \
include/ui/noscrollspinbox.h \
include/ui/selectablepixmapitem.h \
include/ui/tileseteditor.h \
+ include/ui/tileseteditormetatileselector.h \
include/editor.h \
include/mainwindow.h \
include/project.h \
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 581d84e2..9f77938d 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1231,7 +1231,7 @@ void MainWindow::on_checkBox_ToggleBorder_stateChanged(int selected)
void MainWindow::on_actionTileset_Editor_triggered()
{
if (!this->tilesetEditor) {
- this->tilesetEditor = new TilesetEditor(nullptr, this->editor->project);
+ this->tilesetEditor = new TilesetEditor(this->editor->project, this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
}
if (!this->tilesetEditor->isVisible()) {
diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp
index 8b6dc5c6..6579d72d 100644
--- a/src/ui/tileseteditor.cpp
+++ b/src/ui/tileseteditor.cpp
@@ -1,14 +1,18 @@
#include "tileseteditor.h"
#include "ui_tileseteditor.h"
+#include
-TilesetEditor::TilesetEditor(QWidget *parent, Project *project) :
+TilesetEditor::TilesetEditor(Project *project, QString primaryTilesetLabel, QString secondaryTilesetLabel, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::TilesetEditor)
{
ui->setupUi(this);
this->project = project;
- displayPrimaryTilesetTiles();
+ this->primaryTilesetLabel = primaryTilesetLabel;
+ this->secondaryTilesetLabel = secondaryTilesetLabel;
+
+ initMetatilesSelector();
}
TilesetEditor::~TilesetEditor()
@@ -16,11 +20,37 @@ TilesetEditor::~TilesetEditor()
delete ui;
}
-void TilesetEditor::displayPrimaryTilesetTiles()
+void TilesetEditor::initMetatilesSelector()
{
Tileset *primaryTileset = this->project->getTileset(this->primaryTilesetLabel);
-// scene_metatiles = new QGraphicsScene;
-// metatiles_item = new MetatilesPixmapItem(map);
-// metatiles_item->draw();
-// scene_metatiles->addItem(metatiles_item);
+ Tileset *secondaryTileset = this->project->getTileset(this->secondaryTilesetLabel);
+ this->metatileSelector = new TilesetEditorMetatileSelector(primaryTileset, secondaryTileset);
+ connect(this->metatileSelector, SIGNAL(hoveredMetatileChanged(uint16_t)),
+ this, SLOT(onHoveredMetatileChanged(uint16_t)));
+ connect(this->metatileSelector, SIGNAL(hoveredMetatileCleared()),
+ this, SLOT(onHoveredMetatileCleared()));
+ connect(this->metatileSelector, SIGNAL(selectedMetatileChanged(uint16_t)),
+ this, SLOT(onSelectedMetatileChanged(uint16_t)));
+
+ this->metatilesScene = new QGraphicsScene;
+ this->metatilesScene->addItem(this->metatileSelector);
+ this->metatileSelector->select(0);
+ this->metatileSelector->draw();
+
+ this->ui->graphicsView_Metatiles->setScene(this->metatilesScene);
+ this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
+}
+
+void TilesetEditor::onHoveredMetatileChanged(uint16_t metatileId) {
+ QString message = QString("Metatile: 0x%1")
+ .arg(QString("%1").arg(metatileId, 3, 16, QChar('0')).toUpper());
+ this->ui->statusbar->showMessage(message);
+}
+
+void TilesetEditor::onHoveredMetatileCleared() {
+ this->ui->statusbar->clearMessage();
+}
+
+void TilesetEditor::onSelectedMetatileChanged(uint16_t) {
+
}
diff --git a/src/ui/tileseteditormetatileselector.cpp b/src/ui/tileseteditormetatileselector.cpp
new file mode 100644
index 00000000..a5e607f7
--- /dev/null
+++ b/src/ui/tileseteditormetatileselector.cpp
@@ -0,0 +1,111 @@
+#include "tileseteditormetatileselector.h"
+#include "imageproviders.h"
+#include "project.h"
+#include
+
+void TilesetEditorMetatileSelector::draw() {
+ if (!this->primaryTileset || !this->primaryTileset->metatiles
+ || !this->secondaryTileset || !this->secondaryTileset->metatiles) {
+ this->setPixmap(QPixmap());
+ }
+
+ int primaryLength = this->primaryTileset->metatiles->length();
+ int length_ = primaryLength + this->secondaryTileset->metatiles->length();
+ int height_ = length_ / this->numMetatilesWide;
+ QImage image(this->numMetatilesWide * 32, height_ * 32, QImage::Format_RGBA8888);
+ QPainter painter(&image);
+ for (int i = 0; i < length_; i++) {
+ int tile = i;
+ if (i >= primaryLength) {
+ tile += Project::getNumMetatilesPrimary() - primaryLength;
+ }
+ QImage metatile_image = getMetatileImage(tile, this->primaryTileset, this->secondaryTileset).scaled(32, 32);
+ int map_y = i / this->numMetatilesWide;
+ int map_x = i % this->numMetatilesWide;
+ QPoint metatile_origin = QPoint(map_x * 32, map_y * 32);
+ painter.drawImage(metatile_origin, metatile_image);
+ }
+
+ painter.end();
+ this->setPixmap(QPixmap::fromImage(image));
+ this->drawSelection();
+}
+
+void TilesetEditorMetatileSelector::select(uint16_t metatileId) {
+ QPoint coords = this->getMetatileIdCoords(metatileId);
+ SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0);
+ this->selectedMetatile = metatileId;
+ emit selectedMetatileChanged(metatileId);
+}
+
+void TilesetEditorMetatileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
+ this->primaryTileset = primaryTileset;
+ this->secondaryTileset = secondaryTileset;
+ this->draw();
+}
+
+void TilesetEditorMetatileSelector::updateSelectedMetatile() {
+ QPoint origin = this->getSelectionStart();
+ this->selectedMetatile = this->getMetatileId(origin.x(), origin.y());
+}
+
+uint16_t TilesetEditorMetatileSelector::getSelectedMetatile() {
+ return this->selectedMetatile;
+}
+
+uint16_t TilesetEditorMetatileSelector::getMetatileId(int x, int y) {
+ int index = y * this->numMetatilesWide + x;
+ if (index < this->primaryTileset->metatiles->length()) {
+ return static_cast(index);
+ } else {
+ return static_cast(Project::getNumMetatilesPrimary() + index - this->primaryTileset->metatiles->length());
+ }
+}
+
+void TilesetEditorMetatileSelector::mousePressEvent(QGraphicsSceneMouseEvent *event) {
+ SelectablePixmapItem::mousePressEvent(event);
+ this->updateSelectedMetatile();
+ emit selectedMetatileChanged(this->selectedMetatile);
+}
+
+void TilesetEditorMetatileSelector::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
+ SelectablePixmapItem::mouseMoveEvent(event);
+ this->updateSelectedMetatile();
+
+ QPoint pos = this->getCellPos(event->pos());
+ uint16_t metatileId = this->getMetatileId(pos.x(), pos.y());
+ emit hoveredMetatileChanged(metatileId);
+ emit selectedMetatileChanged(metatileId);
+}
+
+void TilesetEditorMetatileSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
+ SelectablePixmapItem::mouseReleaseEvent(event);
+ this->updateSelectedMetatile();
+ emit selectedMetatileChanged(this->selectedMetatile);
+}
+
+void TilesetEditorMetatileSelector::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
+ QPoint pos = this->getCellPos(event->pos());
+ uint16_t metatileId = this->getMetatileId(pos.x(), pos.y());
+ emit this->hoveredMetatileChanged(metatileId);
+}
+
+void TilesetEditorMetatileSelector::hoverLeaveEvent(QGraphicsSceneHoverEvent*) {
+ emit this->hoveredMetatileCleared();
+}
+
+QPoint TilesetEditorMetatileSelector::getMetatileIdCoords(uint16_t metatileId) {
+ if (metatileId >= Project::getNumMetatilesTotal()
+ || (metatileId < Project::getNumMetatilesPrimary() && metatileId >= this->primaryTileset->metatiles->length())
+ || (metatileId < Project::getNumMetatilesTotal() && metatileId >= Project::getNumMetatilesPrimary() + this->secondaryTileset->metatiles->length()))
+ {
+ // Invalid metatile id.
+ return QPoint(0, 0);
+ }
+
+ int index = metatileId < Project::getNumMetatilesPrimary()
+ ? metatileId
+ : metatileId - Project::getNumMetatilesPrimary() + this->primaryTileset->metatiles->length();
+ return QPoint(index % this->numMetatilesWide, index / this->numMetatilesWide);
+}
+