[nostalgia/core/studio] Add select and cut/copy/paste to TileSheetEditor
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user