[nostalgia/core/studio] Add command sequence grouping to tile sheet editor

This commit is contained in:
Gary Talent 2019-12-06 00:50:32 -06:00
parent 1edd322352
commit 37b6095e13
3 changed files with 53 additions and 30 deletions

View File

@ -17,22 +17,19 @@ Rectangle {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onPositionChanged: {
var gridX = mouseX - tileGrid.x; onPressed: {
var gridY = mouseY - tileGrid.y; var pixel = pixelAt(mouseX, mouseY);
var tile = tileGrid.childAt(gridX, gridY); if (pixel) {
if (tile === null) { sheetData.beginCmd()
return; sheetData.updatePixel(pixel)
} }
var tileX = gridX - tile.x;
var tileY = gridY - tile.y;
var pixel = tile.pixelAt(tileX, tileY);
if (pixel === null) {
return;
}
sheetData.updatePixels([pixel]);
} }
onPositionChanged: sheetData.updatePixel(pixelAt(mouseX, mouseY))
onReleased: sheetData.endCmd();
onCanceled: sheetData.endCmd();
Grid { Grid {
id: tileGrid id: tileGrid
property int baseTileSize: Math.min(parent.width / tileGrid.columns, parent.height / tileGrid.rows) property int baseTileSize: Math.min(parent.width / tileGrid.columns, parent.height / tileGrid.rows)
@ -51,6 +48,20 @@ Rectangle {
} }
} }
} }
function pixelAt(x, y) {
var gridX = x - tileGrid.x;
var gridY = y - tileGrid.y;
var tile = tileGrid.childAt(gridX, gridY);
if (tile === null) {
return null;
}
var tileX = gridX - tile.x;
var tileY = gridY - tile.y;
var pixel = tile.pixelAt(tileX, tileY);
return pixel;
}
} }
} }

View File

@ -9,7 +9,6 @@
#include <QHeaderView> #include <QHeaderView>
#include <QPointer> #include <QPointer>
#include <QQmlContext> #include <QQmlContext>
#include <QQuickItem>
#include <QQuickWidget> #include <QQuickWidget>
#include <QSet> #include <QSet>
#include <QSettings> #include <QSettings>
@ -50,25 +49,20 @@ class UpdatePixelsCommand: public QUndoCommand {
} }
}; };
uint64_t cmdIdx = 0; uint64_t m_cmdIdx = 0;
int m_newColorId = 0; int m_newColorId = 0;
const QStringList &m_palette; const QStringList &m_palette;
QVector<uint8_t> &m_pixels; QVector<uint8_t> &m_pixels;
QSet<PixelUpdate> m_pixelUpdates; QSet<PixelUpdate> m_pixelUpdates;
public: public:
UpdatePixelsCommand(QVector<uint8_t> &pixels, const QStringList &palette, const QVariantList &pixelItems, int newColorId, uint64_t cmdIdx): m_palette(palette), m_pixels(pixels) { UpdatePixelsCommand(QVector<uint8_t> &pixels, const QStringList &palette, QQuickItem *pixelItem, int newColorId, uint64_t cmdIdx): m_palette(palette), m_pixels(pixels) {
m_newColorId = newColorId; m_newColorId = newColorId;
cmdIdx = cmdIdx; m_cmdIdx = cmdIdx;
for (auto &pi : pixelItems) { PixelUpdate pu;
auto p = qobject_cast<QQuickItem*>(pi.value<QObject*>()); pu.item = pixelItem;
if (p) { pu.oldColorId = m_palette.indexOf(pixelItem->property("color").toString());
PixelUpdate pu; m_pixelUpdates.insert(pu);
pu.item = p;
pu.oldColorId = m_palette.indexOf(p->property("color").toString());
m_pixelUpdates.insert(pu);
}
}
} }
virtual ~UpdatePixelsCommand() = default; virtual ~UpdatePixelsCommand() = default;
@ -79,7 +73,7 @@ class UpdatePixelsCommand: public QUndoCommand {
bool mergeWith(const QUndoCommand *cmd) override { bool mergeWith(const QUndoCommand *cmd) override {
auto other = static_cast<const UpdatePixelsCommand*>(cmd); auto other = static_cast<const UpdatePixelsCommand*>(cmd);
if (cmdIdx == other->cmdIdx) { if (m_cmdIdx == other->m_cmdIdx) {
m_pixelUpdates.unite(other->m_pixelUpdates); m_pixelUpdates.unite(other->m_pixelUpdates);
return true; return true;
} }
@ -106,8 +100,12 @@ QString SheetData::pixel(int index) {
return m_palette[m_pixels[index]]; return m_palette[m_pixels[index]];
} }
void SheetData::updatePixels(QVariantList pixelItems) { void SheetData::updatePixel(QVariant pixelItem) {
m_cmdStack.push(new UpdatePixelsCommand(m_pixels, m_palette, pixelItems, m_selectedColor, m_cmdIdx++)); auto p = qobject_cast<QQuickItem*>(pixelItem.value<QObject*>());
if (p && p != m_prevPixelUpdated) {
m_cmdStack.push(new UpdatePixelsCommand(m_pixels, m_palette, p, m_selectedColor, m_cmdIdx));
m_prevPixelUpdated = p;
}
} }
int SheetData::columns() { int SheetData::columns() {
@ -180,6 +178,14 @@ void SheetData::updatePixels(const NostalgiaGraphic *ng, const NostalgiaPalette
} }
} }
void SheetData::beginCmd() {
++m_cmdIdx;
}
void SheetData::endCmd() {
m_prevPixelUpdated = nullptr;
}
TileSheetEditor::TileSheetEditor(QString path, const studio::Context *ctx, QWidget *parent): QWidget(parent) { TileSheetEditor::TileSheetEditor(QString path, const studio::Context *ctx, QWidget *parent): QWidget(parent) {
m_ctx = ctx; m_ctx = ctx;

View File

@ -8,6 +8,7 @@
#pragma once #pragma once
#include <QQuickItem>
#include <QSplitter> #include <QSplitter>
#include <QStringList> #include <QStringList>
#include <QStringView> #include <QStringView>
@ -27,6 +28,7 @@ class SheetData: public QObject {
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
private: private:
QQuickItem *m_prevPixelUpdated = nullptr;
uint64_t m_cmdIdx = 0; uint64_t m_cmdIdx = 0;
QUndoStack m_cmdStack; QUndoStack m_cmdStack;
QStringList m_palette; QStringList m_palette;
@ -38,7 +40,11 @@ class SheetData: public QObject {
public: public:
Q_INVOKABLE QString pixel(int index); Q_INVOKABLE QString pixel(int index);
Q_INVOKABLE void updatePixels(QVariantList pixels); Q_INVOKABLE void updatePixel(QVariant pixel);
Q_INVOKABLE void beginCmd();
Q_INVOKABLE void endCmd();
int columns(); int columns();