[nostalgia/core/studio] Get Undo/Redo working
This commit is contained in:
parent
c92ecdf499
commit
302dd23a36
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user