From c92ecdf499784e12809c0c84cebfcb586ec629d1 Mon Sep 17 00:00:00 2001
From: Gary Talent <gary@drinkingtea.net>
Date: Wed, 16 Feb 2022 20:16:49 -0600
Subject: [PATCH] [nostalgia/studio] Get Undo/Redo working

---
 src/nostalgia/studio/lib/editor.cpp    |  4 ----
 src/nostalgia/studio/lib/editor.hpp    | 15 +++++++++------
 src/nostalgia/studio/lib/undostack.cpp |  4 ++--
 src/nostalgia/studio/studioapp.cpp     | 18 ++++++++++++++++++
 src/nostalgia/studio/studioapp.hpp     |  1 +
 5 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/src/nostalgia/studio/lib/editor.cpp b/src/nostalgia/studio/lib/editor.cpp
index 8e964642..f16a13a5 100644
--- a/src/nostalgia/studio/lib/editor.cpp
+++ b/src/nostalgia/studio/lib/editor.cpp
@@ -42,10 +42,6 @@ bool Editor::unsavedChanges() const noexcept {
 	return m_unsavedChanges;
 }
 
-UndoStack *Editor::undoStack() {
-	return &m_cmdStack;
-}
-
 void Editor::setExportable(bool exportable) {
 	m_exportable = exportable;
 	exportableChanged.emit(exportable);
diff --git a/src/nostalgia/studio/lib/editor.hpp b/src/nostalgia/studio/lib/editor.hpp
index 2f3952db..5114a6a4 100644
--- a/src/nostalgia/studio/lib/editor.hpp
+++ b/src/nostalgia/studio/lib/editor.hpp
@@ -32,6 +32,7 @@ class NOSTALGIASTUDIO_EXPORT Editor: public Widget {
 		[[nodiscard]]
 		virtual ox::String itemName() const = 0;
 
+		[[nodiscard]]
 		virtual ox::String itemDisplayName() const;
 
 		virtual void cut();
@@ -42,6 +43,14 @@ class NOSTALGIASTUDIO_EXPORT Editor: public Widget {
 
 		virtual void exportFile();
 
+		/**
+		 * Returns the undo stack holding changes to the item being edited.
+		 */
+		[[nodiscard]]
+		virtual UndoStack *undoStack() noexcept {
+			return nullptr;
+		}
+
 		void close();
 
 		/**
@@ -58,12 +67,6 @@ class NOSTALGIASTUDIO_EXPORT Editor: public Widget {
 		[[nodiscard]]
 		bool unsavedChanges() const noexcept;
 
-		/**
-		 * Returns the undo stack holding changes to the item being edited.
-		 */
-		[[nodiscard]]
-		UndoStack *undoStack();
-
 		void setExportable(bool);
 
 		[[nodiscard]]
diff --git a/src/nostalgia/studio/lib/undostack.cpp b/src/nostalgia/studio/lib/undostack.cpp
index c8b4b322..dd5bb88e 100644
--- a/src/nostalgia/studio/lib/undostack.cpp
+++ b/src/nostalgia/studio/lib/undostack.cpp
@@ -22,8 +22,8 @@ void UndoStack::redo() noexcept {
 }
 
 void UndoStack::undo() noexcept {
-	if (m_stackIdx < ox::MaxValue<decltype(m_stackIdx)>) {
-		m_stack[m_stackIdx--]->undo();
+	if (m_stackIdx) {
+		m_stack[--m_stackIdx]->undo();
 	}
 }
 
diff --git a/src/nostalgia/studio/studioapp.cpp b/src/nostalgia/studio/studioapp.cpp
index 45f7d90a..7ea080d6 100644
--- a/src/nostalgia/studio/studioapp.cpp
+++ b/src/nostalgia/studio/studioapp.cpp
@@ -87,6 +87,23 @@ void StudioUI::drawMenu() noexcept {
 			}
 			ImGui::EndMenu();
 		}
+		if (ImGui::BeginMenu("Edit")) {
+			auto undoStack = m_acitveEditor ? m_acitveEditor->undoStack() : nullptr;
+			if (ImGui::MenuItem("Undo", "Ctrl+Z", false, undoStack)) {
+				 m_acitveEditor->undoStack()->undo();
+			}
+			if (ImGui::MenuItem("Redo", "Ctrl+Y", false, undoStack)) {
+				 m_acitveEditor->undoStack()->redo();
+			}
+			ImGui::Separator();
+			if (ImGui::MenuItem("Copy", "Ctrl+N")) {
+			}
+			if (ImGui::MenuItem("Cut", "Ctrl+X")) {
+			}
+			if (ImGui::MenuItem("Paste", "Ctrl+V")) {
+			}
+			ImGui::EndMenu();
+		}
 		if (ImGui::BeginMenu("View", false)) {
 			ImGui::EndMenu();
 		}
@@ -147,6 +164,7 @@ void StudioUI::drawTabs() noexcept {
 		auto const &e = *it;
 		bool open = true;
 		if (ImGui::BeginTabItem(e->itemDisplayName().c_str(), &open)) {
+			m_acitveEditor = e.get();
 			e->draw(m_ctx);
 			ImGui::EndTabItem();
 		}
diff --git a/src/nostalgia/studio/studioapp.hpp b/src/nostalgia/studio/studioapp.hpp
index d1ac9a64..bd1171f0 100644
--- a/src/nostalgia/studio/studioapp.hpp
+++ b/src/nostalgia/studio/studioapp.hpp
@@ -28,6 +28,7 @@ class StudioUI: public ox::SignalHandler {
 		ox::HashMap<ox::String, studio::EditorMaker::Func> m_editorMakers;
 		ProjectExplorer *m_projectExplorer = nullptr;
 		ox::Vector<ox::String> m_openFiles;
+		studio::Editor *m_acitveEditor = nullptr;
 		bool m_saveEnabled = false;
 		bool m_aboutEnabled = false;