[nostalgia/core/studio] Get Undo/Redo working

This commit is contained in:
Gary Talent 2022-02-16 20:17:33 -06:00
parent c92ecdf499
commit 302dd23a36
6 changed files with 39 additions and 14 deletions

View File

@ -56,6 +56,10 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept {
ImGui::EndChild(); ImGui::EndChild();
} }
studio::UndoStack *TileSheetEditorImGui::undoStack() noexcept {
return m_tileSheetEditor.undoStack();
}
void TileSheetEditorImGui::saveItem() { void TileSheetEditorImGui::saveItem() {
} }
@ -93,7 +97,7 @@ void TileSheetEditorImGui::drawTileSheet(const geo::Vec2 &fbSize) noexcept {
const auto &winPos = ImGui::GetWindowPos(); const auto &winPos = ImGui::GetWindowPos();
clickPos.x -= winPos.x + 10; clickPos.x -= winPos.x + 10;
clickPos.y -= winPos.y + 10; clickPos.y -= winPos.y + 10;
m_tileSheetEditor.click(fbSize, clickPos, m_palIdx); m_tileSheetEditor.click(fbSize, clickPos);
} }
} }
if (io.MouseReleased[0]) { if (io.MouseReleased[0]) {
@ -113,13 +117,13 @@ void TileSheetEditorImGui::drawPalettePicker() noexcept {
// Column: color idx // Column: color idx
ImGui::TableNextColumn(); ImGui::TableNextColumn();
const auto label = ox::BString<8>() + (i + 1); const auto label = ox::BString<8>() + (i + 1);
const auto rowSelected = i == m_palIdx; const auto rowSelected = i == m_tileSheetEditor.palIdx();
if (ImGui::Selectable(label.c_str(), rowSelected, ImGuiSelectableFlags_SpanAllColumns)) { if (ImGui::Selectable(label.c_str(), rowSelected, ImGuiSelectableFlags_SpanAllColumns)) {
m_palIdx = i; m_tileSheetEditor.setPalIdx(i);
} }
// Column: color RGB // Column: color RGB
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("(%d, %d, %d)", red16(c), green16(c), blue16(c)); ImGui::Text("(%02d, %02d, %02d)", red16(c), green16(c), blue16(c));
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::PopID(); ImGui::PopID();
++i; ++i;

View File

@ -28,9 +28,6 @@ class TileSheetEditorImGui: public studio::Editor {
float m_palViewWidth = 200; float m_palViewWidth = 200;
geo::Vec2 m_prevMouseDownPos; geo::Vec2 m_prevMouseDownPos;
// palette view vars
std::size_t m_palIdx = 0;
public: public:
TileSheetEditorImGui(Context *ctx, const ox::String &path); TileSheetEditorImGui(Context *ctx, const ox::String &path);
@ -50,6 +47,8 @@ class TileSheetEditorImGui: public studio::Editor {
void draw(core::Context*) noexcept override; void draw(core::Context*) noexcept override;
virtual studio::UndoStack *undoStack() noexcept override;
protected: protected:
void saveItem() override; void saveItem() override;

View File

@ -63,7 +63,7 @@ void TileSheetEditor::scrollH(const geo::Vec2 &paneSz, float wheelh) noexcept {
m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f); m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f);
} }
void TileSheetEditor::click(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos, size_t palIdx) noexcept { void TileSheetEditor::click(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept {
auto [x, y] = clickPos; auto [x, y] = clickPos;
const auto pixDrawSz = m_pixelsDrawer.pixelSize(paneSize); const auto pixDrawSz = m_pixelsDrawer.pixelSize(paneSize);
x /= paneSize.x; x /= paneSize.x;
@ -73,7 +73,7 @@ void TileSheetEditor::click(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos
x /= pixDrawSz.x; x /= pixDrawSz.x;
y /= pixDrawSz.y; y /= pixDrawSz.y;
const auto pt = geo::Point(static_cast<int>(x * 2), static_cast<int>(y * 2)); const auto pt = geo::Point(static_cast<int>(x * 2), static_cast<int>(y * 2));
m_model.drawCommand(pt, palIdx); m_model.drawCommand(pt, m_palIdx);
} }
void TileSheetEditor::releaseMouseButton() noexcept { void TileSheetEditor::releaseMouseButton() noexcept {

View File

@ -45,6 +45,7 @@ class TileSheetEditor {
float m_pixelSizeMod = 1; float m_pixelSizeMod = 1;
bool m_updated = false; bool m_updated = false;
geo::Vec2 m_scrollOffset; geo::Vec2 m_scrollOffset;
std::size_t m_palIdx = 0;
public: public:
TileSheetEditor(Context *ctx, const ox::String &path); TileSheetEditor(Context *ctx, const ox::String &path);
@ -59,7 +60,7 @@ class TileSheetEditor {
void draw() noexcept; void draw() noexcept;
void click(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos, size_t palIdx) noexcept; void click(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept;
void releaseMouseButton() noexcept; void releaseMouseButton() noexcept;
@ -75,11 +76,24 @@ class TileSheetEditor {
[[nodiscard]] [[nodiscard]]
constexpr const NostalgiaPalette &pal() const noexcept; constexpr const NostalgiaPalette &pal() const noexcept;
constexpr auto setPalIdx(auto palIdx) noexcept {
m_palIdx = palIdx;
}
[[nodiscard]]
constexpr auto palIdx() const noexcept {
return m_palIdx;
}
[[nodiscard]] [[nodiscard]]
bool updated() const noexcept; bool updated() const noexcept;
void ackUpdate() noexcept; void ackUpdate() noexcept;
constexpr studio::UndoStack *undoStack() noexcept {
return m_model.undoStack();
}
protected: protected:
void saveItem(); void saveItem();

View File

@ -29,7 +29,7 @@ void TileSheetEditorModel::drawCommand(const geo::Point &pt, std::size_t palIdx)
} else { } else {
const auto idx = ptToIdx(pt, m_img.columns); const auto idx = ptToIdx(pt, m_img.columns);
if (m_img.getPixel(idx) != palIdx) { if (m_img.getPixel(idx) != palIdx) {
pushCommand(new DrawCommand(&m_img, idx, palIdx)); pushCommand(new DrawCommand(&m_updated, &m_img, idx, palIdx));
} }
} }
} }

View File

@ -31,9 +31,11 @@ struct DrawCommand: public studio::UndoCommand {
NostalgiaGraphic *m_img = nullptr; NostalgiaGraphic *m_img = nullptr;
ox::Vector<Change, 8> m_changes; ox::Vector<Change, 8> m_changes;
int m_palIdx = 0; int m_palIdx = 0;
bool *m_modelUpdated = nullptr;
public: public:
constexpr DrawCommand(NostalgiaGraphic *img, std::size_t idx, int palIdx) noexcept { constexpr DrawCommand(bool *updated, NostalgiaGraphic *img, std::size_t idx, int palIdx) noexcept {
m_modelUpdated = updated;
m_img = img; m_img = img;
m_changes.emplace_back(idx, m_img->getPixel(idx)); m_changes.emplace_back(idx, m_img->getPixel(idx));
m_palIdx = palIdx; m_palIdx = palIdx;
@ -55,16 +57,18 @@ struct DrawCommand: public studio::UndoCommand {
} }
void redo() noexcept final { void redo() noexcept final {
for (const auto &c : m_changes) { for (const auto &c : m_changes
oxDebugf("{} to {}", c.idx, m_palIdx); ) {
m_img->setPixel(c.idx, m_palIdx); m_img->setPixel(c.idx, m_palIdx);
} }
*m_modelUpdated = true;
} }
void undo() noexcept final { void undo() noexcept final {
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
m_img->setPixel(c.idx, c.oldPalIdx); m_img->setPixel(c.idx, c.oldPalIdx);
} }
*m_modelUpdated = true;
} }
}; };
@ -146,6 +150,10 @@ class TileSheetEditorModel {
void ackUpdate() noexcept; void ackUpdate() noexcept;
constexpr studio::UndoStack *undoStack() noexcept {
return &m_undoStack;
}
protected: protected:
void saveItem(); void saveItem();