diff --git a/EditorState.cpp b/EditorState.cpp index d33eda1..2d6da64 100644 --- a/EditorState.cpp +++ b/EditorState.cpp @@ -18,9 +18,9 @@ EditorState::EditorState(Fumen &fumen) : fumen(fumen) { void EditorState::reloadFromFumen() { if (not this->fumen.Charts.empty()) { - this->selectedChart = this->fumen.Charts.begin()->second; + this->chart.emplace(this->fumen.Charts.begin()->second); } else { - this->selectedChart.reset(); + this->chart.reset(); } reloadMusic(); reloadJacket(); @@ -50,14 +50,14 @@ void EditorState::reloadPlaybackPositionAndChartRuntime() { playbackPosition = sf::seconds(-(fumen.offset)); previousPos = playbackPosition; if (music) { - if (selectedChart) { - chartRuntime = sf::seconds(std::max(music->getDuration().asSeconds(),fumen.getChartRuntime(*selectedChart)-fumen.offset)+2.f); + if (chart) { + chartRuntime = sf::seconds(std::max(music->getDuration().asSeconds(),fumen.getChartRuntime(chart->ref)-fumen.offset)+2.f); } else { chartRuntime = sf::seconds(std::max(-fumen.offset,music->getDuration().asSeconds())); } } else { - if (selectedChart) { - chartRuntime = sf::seconds(std::max(fumen.getChartRuntime(*selectedChart)-fumen.offset,2.f)); + if (chart) { + chartRuntime = sf::seconds(std::max(fumen.getChartRuntime(chart->ref)-fumen.offset,2.f)); } else { chartRuntime = sf::seconds(std::max(-fumen.offset,2.f)); } @@ -106,7 +106,7 @@ void EditorState::displayPlayfield(Marker& marker, MarkerEndingState markerEndin float squareSize = ImGui::GetWindowSize().x / 4.f; float TitlebarHeight = ImGui::GetWindowSize().y - ImGui::GetWindowSize().x; - if (selectedChart) { + if (chart) { int ImGuiIndex = 0; @@ -403,8 +403,8 @@ void EditorState::displayPlaybackStatus() { |ImGuiWindowFlags_AlwaysAutoResize ); { - if (selectedChart) { - ImGui::Text("%s %d",selectedChart->get().dif_name.c_str(),selectedChart->get().level); ImGui::SameLine(); + if (chart) { + ImGui::Text("%s %d",chart->ref.dif_name.c_str(),chart->ref.level); ImGui::SameLine(); } else { ImGui::TextDisabled("No chart selected"); ImGui::SameLine(); } @@ -469,8 +469,8 @@ void EditorState::displayChartList() { ImGui::TextDisabled("Note Count"); ImGui::NextColumn(); ImGui::Separator(); for (auto& tuple : fumen.Charts) { - if (ImGui::Selectable(tuple.first.c_str(), selectedChart ? selectedChart->get()==tuple.second : false , ImGuiSelectableFlags_SpanAllColumns)) { - selectedChart = tuple.second; + if (ImGui::Selectable(tuple.first.c_str(), chart ? chart->ref==tuple.second : false , ImGuiSelectableFlags_SpanAllColumns)) { + chart.emplace(tuple.second); } ImGui::NextColumn(); ImGui::Text("%d",tuple.second.level); ImGui::NextColumn(); @@ -490,11 +490,11 @@ void EditorState::updateVisibleNotes() { visibleNotes.clear(); - if (selectedChart) { + if (chart) { float position = playbackPosition.asSeconds(); - for (auto const& note : selectedChart->get().Notes) { + for (auto const& note : chart->ref.Notes) { float note_timing_in_seconds = getSecondsAt(note.getTiming()); @@ -520,18 +520,23 @@ void EditorState::updateVisibleNotes() { * Otherwise create note at nearest tick */ void EditorState::toggleNoteAtCurrentTime(int pos) { - if (selectedChart) { + + if (chart) { + + chart->history.push(chart->ref); + bool deleted_something = false; for (auto note : visibleNotes) { if (note.getPos() == pos) { - selectedChart->get().Notes.erase(note); + chart->ref.Notes.erase(note); deleted_something = true; } } if (not deleted_something) { - selectedChart->get().Notes.emplace(pos,static_cast(roundf(getTicks()))); + chart->ref.Notes.emplace(pos,static_cast(roundf(getTicks()))); } } + } void ESHelper::save(EditorState& ed) { @@ -651,20 +656,20 @@ std::optional ESHelper::NewChartDialog::display(EditorState &editorState) void ESHelper::ChartPropertiesDialog::display(EditorState &editorState) { - assert(editorState.selectedChart.has_value()); + assert(editorState.chart.has_value()); if (this->shouldRefreshValues) { shouldRefreshValues = false; difNamesInUse.clear(); - this->level = editorState.selectedChart->get().level; - this->difficulty = editorState.selectedChart->get().dif_name; + this->level = editorState.chart->ref.level; + this->difficulty = editorState.chart->ref.dif_name; std::set difNames{"BSC","ADV","EXT"}; showCustomDifName = (difNames.find(difficulty) == difNames.end()); for (auto const& tuple : editorState.fumen.Charts) { - if (tuple.second != editorState.selectedChart) { + if (tuple.second != editorState.chart->ref) { difNamesInUse.insert(tuple.first); } } @@ -722,10 +727,11 @@ void ESHelper::ChartPropertiesDialog::display(EditorState &editorState) { } else { if (ImGui::Button("Apply##New Chart")) { try { - editorState.fumen.Charts.erase(editorState.selectedChart->get().dif_name); - editorState.selectedChart->get().dif_name = this->difficulty; - editorState.selectedChart->get().level = this->level; - if (not (editorState.fumen.Charts.emplace(this->difficulty,editorState.selectedChart.value())).second) { + editorState.chart->history.push(editorState.chart->ref); + editorState.fumen.Charts.erase(editorState.chart->ref.dif_name); + editorState.chart->ref.dif_name = this->difficulty; + editorState.chart->ref.level = this->level; + if (not (editorState.fumen.Charts.emplace(this->difficulty,editorState.chart->ref)).second) { throw std::runtime_error("Could not insert modified chart in fumen"); } else { shouldRefreshValues = true; diff --git a/EditorState.h b/EditorState.h index 2d2ce81..b160b32 100644 --- a/EditorState.h +++ b/EditorState.h @@ -11,15 +11,21 @@ #include "Fumen.h" #include "Marker.h" #include "Widgets.h" +#include "History.h" class EditorState { - public: + struct Chart_with_History { + explicit Chart_with_History(Chart& c) : ref(c) {}; + Chart& ref; + History history; + }; + explicit EditorState(Fumen& fumen); Fumen fumen; - std::optional> selectedChart; + std::optional chart; Widgets::Playfield playfield; int snap = 1; @@ -43,7 +49,7 @@ public: float getTicks () {return getTicksAt(playbackPosition.asSeconds());}; float getTicksAt (float seconds) {return getBeatsAt(seconds) * getResolution();} float getSecondsAt (int tick) {return (60.f * tick)/(fumen.BPM * getResolution()) - fumen.offset;}; - int getResolution () {return selectedChart ? selectedChart->get().getResolution() : 240;}; + int getResolution () {return chart ? chart->ref.getResolution() : 240;}; int getSnapStep () {return getResolution() / snap;}; float ticksToSeconds (int ticks) {return (60.f * ticks)/(fumen.BPM * getResolution());}; diff --git a/LNMarker.h b/LNMarker.h index 8c3581e..9e1c43d 100644 --- a/LNMarker.h +++ b/LNMarker.h @@ -20,7 +20,7 @@ class LNMarker { public: - LNMarker(std::filesystem::path folder="assets/textures/long"); + explicit LNMarker(std::filesystem::path folder="assets/textures/long"); std::optional> getTriangleTexture(float seconds, int tail_pos); diff --git a/main.cpp b/main.cpp index 311da9d..fc0ef6a 100644 --- a/main.cpp +++ b/main.cpp @@ -98,7 +98,7 @@ int main(int argc, char** argv) { } } } else { - if (editorState and editorState->selectedChart) { + if (editorState and editorState->chart) { float floatTicks = editorState->getTicks(); int prevTick = static_cast(floorf(floatTicks)); int step = editorState->getSnapStep(); @@ -121,7 +121,7 @@ int main(int argc, char** argv) { } } } else { - if (editorState and editorState->selectedChart) { + if (editorState and editorState->chart) { float floatTicks = editorState->getTicks(); int nextTick = static_cast(ceilf(floatTicks)); int step = editorState->getSnapStep(); @@ -131,13 +131,13 @@ int main(int argc, char** argv) { } break; case sf::Keyboard::Left: - if (editorState and editorState->selectedChart) { - editorState->snap = Toolbox::getPreviousDivisor(editorState->selectedChart->get().getResolution(),editorState->snap); + if (editorState and editorState->chart) { + editorState->snap = Toolbox::getPreviousDivisor(editorState->chart->ref.getResolution(),editorState->snap); } break; case sf::Keyboard::Right: - if (editorState and editorState->selectedChart) { - editorState->snap = Toolbox::getNextDivisor(editorState->selectedChart->get().getResolution(),editorState->snap); + if (editorState and editorState->chart) { + editorState->snap = Toolbox::getNextDivisor(editorState->chart->ref.getResolution(),editorState->snap); } break; case sf::Keyboard::F3: @@ -168,6 +168,26 @@ int main(int argc, char** argv) { ESHelper::save(*editorState); } break; + case sf::Keyboard::Y: + if (event.key.control) { + if (editorState and editorState->chart) { + std::optional next = editorState->chart->history.get_next(); + if (next) { + editorState->chart->ref = *next; + } + } + } + break; + case sf::Keyboard::Z: + if (event.key.control) { + if (editorState and editorState->chart) { + std::optional previous = editorState->chart->history.get_previous(); + if (previous) { + editorState->chart->ref = *previous; + } + } + } + break; default: break; } @@ -238,7 +258,7 @@ int main(int argc, char** argv) { } } - // Dessin du fond + // Drawing if (editorState) { window.clear(sf::Color(0, 0, 0)); @@ -278,7 +298,7 @@ int main(int argc, char** argv) { if (c) { editorState->showNewChartDialog = false; if(editorState->fumen.Charts.try_emplace(c->dif_name,*c).second) { - editorState->selectedChart = editorState->fumen.Charts[c->dif_name]; + editorState->chart->ref = editorState->fumen.Charts[c->dif_name]; } } } else { @@ -359,7 +379,7 @@ int main(int argc, char** argv) { if (ImGui::MenuItem("Chart List")) { editorState->showChartList = true; } - if (ImGui::MenuItem("Properties##Chart",nullptr,false,editorState->selectedChart.has_value())) { + if (ImGui::MenuItem("Properties##Chart",nullptr,false,editorState->chart.has_value())) { editorState->showChartProperties = true; } ImGui::Separator(); @@ -367,9 +387,9 @@ int main(int argc, char** argv) { editorState->showNewChartDialog = true; } ImGui::Separator(); - if (ImGui::MenuItem("Delete Chart",nullptr,false,editorState->selectedChart.has_value())) { - editorState->fumen.Charts.erase(editorState->selectedChart->get().dif_name); - editorState->selectedChart.reset(); + if (ImGui::MenuItem("Delete Chart",nullptr,false,editorState->chart.has_value())) { + editorState->fumen.Charts.erase(editorState->chart->ref.dif_name); + editorState->chart.reset(); } ImGui::EndMenu(); }