/* * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. */ #pragma once #include #include #include #include #include #include "tilesheetpixelgrid.hpp" #include "tilesheetpixels.hpp" namespace nostalgia::core { // Command IDs to use with QUndoCommand::id() enum class CommandId { UpdatePixel = 1, ModPixel = 2, UpdateDimension = 3, InsertTile = 4, ClipboardPaste = 5, }; 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 TypeVersion = 1; common::Point pt; int size = 0; }; oxModelBegin(PixelChunk) oxModelField(pt) oxModelField(size) oxModelEnd() struct TileSheetClipboard { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard"; static constexpr auto TypeVersion = 1; oxModelFriend(TileSheetClipboard); protected: ox::Vector m_pixels; common::Point m_p1; common::Point m_p2; public: void addPixel(int color); [[nodiscard]] bool empty() const; void pastePixels(const common::Point &pt, ox::Vector *tgt, int tgtColumns) const; void setPoints(const common::Point &p1, const common::Point &p2); [[nodiscard]] common::Point point1() const; [[nodiscard]] common::Point point2() const; }; template ox::Error model(T *io, TileSheetClipboard *b) { io->template setTypeInfo(); oxReturnError(io->field("pixels", &b->m_pixels)); oxReturnError(io->field("p1", &b->m_p1)); oxReturnError(io->field("p2", &b->m_p2)); return OxError(0); } class TileSheetEditor: public studio::Editor { private: ox::String m_itemPath; ox::String m_itemName; glutils::FrameBuffer m_framebuffer; TileSheetGrid m_pixelGrid; TileSheetPixels m_pixels; bool m_updated = false; NostalgiaGraphic m_img; AssetRef m_pal; Context *m_ctx = nullptr; float m_pixelSizeMod = 1; public: TileSheetEditor(Context *ctx, const ox::String &path); ~TileSheetEditor() override = default; ox::String itemName() const noexcept override; ox::String itemDisplayName() const noexcept override; void exportFile() override; void cut() override; void copy() override; void paste() override; void draw(core::Context*) noexcept override; void glDraw() noexcept; protected: void saveItem() override; private: void setPalette(); void saveState(); void restoreState(); [[nodiscard]] ox::String paletteName(const ox::String &palettePath) const; [[nodiscard]] ox::String palettePath(const ox::String &palettePath) const; // slots public: ox::Error colorSelected() noexcept; ox::Error setColorTable() noexcept; // slots private: ox::Error updateAfterClicked() noexcept; }; }