[nostalgia/core/studio] Add select and cut/copy/paste to TileSheetEditor

This commit is contained in:
2020-10-20 22:14:56 -05:00
parent 985b2b57ba
commit 2580dbb7ab
7 changed files with 447 additions and 69 deletions
+128 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2016 - 2019 gtalent2@gmail.com
* Copyright 2016 - 2020 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -8,16 +8,100 @@
#pragma once
#include <QButtonGroup>
#include <QStringList>
#include <QStyledItemDelegate>
#include <QUndoStack>
#include <QVariant>
#include <nostalgia/common/bounds.hpp>
#include <nostalgia/core/gfx.hpp>
#include <nostalgia/studio/studio.hpp>
namespace nostalgia::core {
// Command IDs to use with QUndoCommand::id()
enum class CommandId {
UpdatePixel = 1,
ModPixel = 2,
UpdateDimension = 3,
InsertTile = 4,
ClipboardPaste = 4,
};
enum class TileSheetTool: int {
Select,
Draw,
Fill,
};
[[nodiscard]] constexpr auto toString(TileSheetTool t) noexcept {
switch (t) {
case TileSheetTool::Select:
return "Select";
case TileSheetTool::Draw:
return "Draw";
case TileSheetTool::Fill:
return "Fill";
}
return "";
}
struct PixelChunk {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.PixelChunk";
static constexpr auto Fields = 2;
static constexpr auto TypeVersion = 1;
int index = -1;
int size = 0;
};
template<typename T>
ox::Error model(T *io, PixelChunk *c) {
io->template setTypeInfo<PixelChunk>();
oxReturnError(io->field("index", &c->index));
oxReturnError(io->field("size", &c->size));
return OxError(0);
}
struct TileSheetClipboard {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard";
static constexpr auto Fields = 2;
static constexpr auto TypeVersion = 1;
template<typename T>
friend ox::Error model(T*, TileSheetClipboard*);
protected:
ox::Vector<PixelChunk> m_chunks;
ox::Vector<int> m_pixels;
common::Point m_p1;
common::Point m_p2;
public:
void add(int idx, int color);
void clear();
[[nodiscard]] bool empty() const;
void paste(int targetIdx, QVector<int> *pixels) const;
void setPoints(common::Point p1, common::Point p2);
[[nodiscard]] common::Point point1() const;
[[nodiscard]] common::Point point2() const;
};
template<typename T>
ox::Error model(T *io, TileSheetClipboard *b) {
io->template setTypeInfo<TileSheetClipboard>();
oxReturnError(io->field("chunks", &b->m_chunks));
oxReturnError(io->field("pixels", &b->m_pixels));
return OxError(0);
}
struct TileSheetEditorColorTableDelegate: public QStyledItemDelegate {
void paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &idx) const;
@@ -28,24 +112,33 @@ class SheetData: public QObject {
Q_OBJECT
Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged)
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
Q_PROPERTY(QVector<int> pixelSelected READ pixelSelected NOTIFY pixelSelectedChanged)
Q_PROPERTY(QVector<int> pixels READ pixels NOTIFY pixelsChanged)
Q_PROPERTY(QStringList palette READ palette NOTIFY paletteChanged)
Q_PROPERTY(QString activeTool READ activeToolString)
private:
class QQuickItem *m_prevPixelUpdated = nullptr;
class QQuickItem *m_prevPixelOperand = nullptr;
QString m_tilesheetPath;
QString m_currentPalettePath;
uint64_t m_cmdIdx = 0;
QUndoStack *m_cmdStack;
QStringList m_palette;
QVector<int> m_pixelSelected;
QVector<int> m_pixels;
common::Point m_selectionStart = {-1, -1};
common::Point m_selectionEnd = {-1, -1};
int m_columns = 1;
int m_rows = 1;
int m_selectedColor = 0;
TileSheetTool m_activeTool = TileSheetTool::Draw;
TileSheetClipboard m_clipboard;
public:
SheetData(QUndoStack*);
Q_INVOKABLE void selectPixel(QVariant pixel);
Q_INVOKABLE void updatePixel(QVariant pixel);
Q_INVOKABLE void beginCmd();
@@ -60,6 +153,8 @@ class SheetData: public QObject {
[[nodiscard]] int rows() const;
[[nodiscard]] const QVector<int> &pixelSelected() const;
[[nodiscard]] const QVector<int> &pixels() const;
[[nodiscard]] QStringList palette() const;
@@ -88,6 +183,24 @@ class SheetData: public QObject {
[[nodiscard]] std::unique_ptr<NostalgiaGraphic> toNostalgiaGraphic() const;
[[nodiscard]] int activeTool() const;
[[nodiscard]] bool clipboardEmpty() const;
void cutToClipboard();
void cutToClipboard(TileSheetClipboard *cb);
void copyToClipboard();
void copyToClipboard(TileSheetClipboard *cb);
void pasteClipboard();
void applyClipboard(const TileSheetClipboard &cb);
void markSelection(common::Point selectionEnd);
public slots:
void setColumns(int columns);
@@ -103,9 +216,13 @@ class SheetData: public QObject {
*/
void updateRows(int rows);
void setActiveTool(int t);
private:
void updatePixels(const NostalgiaGraphic *ng);
const char *activeToolString() const;
signals:
void changeOccurred();
@@ -113,6 +230,8 @@ class SheetData: public QObject {
void rowsChanged(int);
void pixelSelectedChanged(int pixelsSelected);
void pixelsChanged();
void paletteChanged();
@@ -129,10 +248,10 @@ class TileSheetEditor: public studio::Editor {
QString m_itemName;
const studio::Context *m_ctx = nullptr;
SheetData m_sheetData;
QButtonGroup m_toolBtns;
class QSplitter *m_splitter = nullptr;
struct LabeledSpinner *m_tilesX = nullptr;
struct LabeledSpinner *m_tilesY = nullptr;
class QPushButton *m_updateAfterBtn = nullptr;
class QQuickWidget* m_canvas = nullptr;
struct {
QComboBox *palette = nullptr;
@@ -148,6 +267,12 @@ class TileSheetEditor: public studio::Editor {
void exportFile() override;
void cut() override;
void copy() override;
void paste() override;
protected:
void saveItem() override;