Add metatile selector in tileset editor window

This commit is contained in:
Marcus Huderle 2018-09-29 15:24:35 -05:00
parent 9abda07c48
commit 990a4aafb7
7 changed files with 350 additions and 13 deletions

View file

@ -16,10 +16,152 @@
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGraphicsView" name="graphicsView_PrimaryTilesetMetatiles"/>
<widget class="QScrollArea" name="scrollArea_Metatiles">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>386</width>
<height>539</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QGraphicsView" name="graphicsView_Metatiles"/>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QGraphicsView" name="graphicsView_PrimaryTilesetTiles"/>
<widget class="QScrollArea" name="scrollArea_Tiles">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>386</width>
<height>539</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QGraphicsView" name="graphicsView_Tiles"/>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
@ -37,4 +179,4 @@
</widget>
<resources/>
<connections/>
</ui>
</ui>

View file

@ -3,6 +3,7 @@
#include <QMainWindow>
#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

View file

@ -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

View file

@ -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 \

View file

@ -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()) {

View file

@ -1,14 +1,18 @@
#include "tileseteditor.h"
#include "ui_tileseteditor.h"
#include <QDebug>
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) {
}

View file

@ -0,0 +1,111 @@
#include "tileseteditormetatileselector.h"
#include "imageproviders.h"
#include "project.h"
#include <QPainter>
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<uint16_t>(index);
} else {
return static_cast<uint16_t>(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);
}