From 76f3d1ae4f89774dc61eee3cbe5806bee8c72941 Mon Sep 17 00:00:00 2001 From: Stepland Date: Wed, 16 Jan 2019 01:59:02 +0100 Subject: [PATCH] Chart creation dialog Chart list view Chart correctly ordered according to difficulty name --- CMakeLists.txt | 1 + Chart.cpp | 11 ++++ Chart.h | 8 +-- EditorState.cpp | 135 +++++++++++++++++++++++++++++++++++++++++++++++- EditorState.h | 21 ++++++++ Fumen.cpp | 16 ++++++ Fumen.h | 11 +++- main.cpp | 29 +++++++++++ 8 files changed, 227 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 092ede9..36afa60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ set(SOURCE_FILES imgui/imgui_widgets.cpp imgui/imgui-SFML.cpp imgui/imgui_stdlib.cpp + imgui/imgui_demo.cpp tinyfiledialogs.c Toolbox.cpp Toolbox.h) #set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${FEIS_SOURCE_DIR}/cmake") diff --git a/Chart.cpp b/Chart.cpp index f171f3d..74244b5 100644 --- a/Chart.cpp +++ b/Chart.cpp @@ -24,3 +24,14 @@ Chart::Chart(const std::string &dif, int level, int resolution) : dif_name(dif), throw std::invalid_argument("Can't set a resolution of "+std::to_string(resolution)); } } + +bool Chart::operator==(const Chart &rhs) const { + return dif_name == rhs.dif_name && + level == rhs.level && + Notes == rhs.Notes && + resolution == rhs.resolution; +} + +bool Chart::operator!=(const Chart &rhs) const { + return !(rhs == *this); +} diff --git a/Chart.h b/Chart.h index dd7447f..b8db097 100644 --- a/Chart.h +++ b/Chart.h @@ -9,13 +9,11 @@ #include #include "Note.h" -// TODO : finir la classe Chart - class Chart { public: - Chart(const std::string &dif, + Chart(const std::string &dif = "Edit", int level = 1, int resolution = 240); @@ -26,6 +24,10 @@ public: int level; std::set Notes; + bool operator==(const Chart &rhs) const; + + bool operator!=(const Chart &rhs) const; + private: int resolution; diff --git a/EditorState.cpp b/EditorState.cpp index 9afcc33..1ce20f3 100644 --- a/EditorState.cpp +++ b/EditorState.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "EditorState.h" #include "tinyfiledialogs.h" #include "Toolbox.h" @@ -188,7 +189,6 @@ void EditorState::displayPlaybackStatus() { ImGuiWindowFlags_NoNav |ImGuiWindowFlags_NoDecoration |ImGuiWindowFlags_NoInputs - |ImGuiWindowFlags_NoTitleBar |ImGuiWindowFlags_NoMove |ImGuiWindowFlags_AlwaysAutoResize ); @@ -262,6 +262,34 @@ void EditorState::displayTimeline() { ImGui::PopStyleVar(3); } +void EditorState::displayChartList() { + + if (ImGui::Begin("Chart List",&showChartList,ImGuiWindowFlags_AlwaysAutoResize)) { + if (this->fumen.Charts.empty()) { + ImGui::Dummy({100,0}); ImGui::SameLine(); + ImGui::Text("- no charts -"); ImGui::SameLine(); + ImGui::Dummy({100,0}); + } else { + ImGui::Dummy(ImVec2(300,0)); + ImGui::Columns(3, "mycolumns"); + ImGui::TextDisabled("Difficulty"); ImGui::NextColumn(); + ImGui::TextDisabled("Level"); ImGui::NextColumn(); + ImGui::TextDisabled("Note Count"); ImGui::NextColumn(); + ImGui::Separator(); + std::optional selected; + for (auto tuple : fumen.Charts) { + if (ImGui::Selectable(tuple.first.c_str(), selected ? *selected==tuple.second : false , ImGuiSelectableFlags_SpanAllColumns)) { + selected = tuple.second; + } + ImGui::NextColumn(); + ImGui::Text("%d",tuple.second.level); ImGui::NextColumn(); + ImGui::Text("%d", static_cast(tuple.second.Notes.size())); ImGui::NextColumn(); + } + } + } + ImGui::End(); +} + std::vector EditorState::getVisibleNotes() { if (selectedChart) { @@ -317,3 +345,108 @@ void ESHelper::openFromFile(std::optional &ed, std::filesystem::pat tinyfd_messageBox("Error", e.what(), "ok", "error", 1); } } + +/* + * Returns the newly created chart if there is + */ +std::optional ESHelper::NewChartDialog::display(EditorState &editorState) { + + std::optional newChart; + if (ImGui::Begin( + "New Chart", + &editorState.showNewChartDialog, + ImGuiWindowFlags_NoResize + |ImGuiWindowFlags_AlwaysAutoResize)) + { + + ImColor FrameBg_Green = {0.163f, 0.480f, 0.160f, 0.540f}; + ImColor FrameBgHovered_Green = {0.261f, 0.980f, 0.261f, 0.400f}; + ImColor FrameBgActive_Green = {0.261f, 0.980f, 0.261f, 0.671f}; + + ImColor FrameBg_Red = {0.480f, 0.160f, 0.160f, 0.540f}; + ImColor FrameBgHovered_Red = {0.980f, 0.261f, 0.261f, 0.400f}; + ImColor FrameBgActive_Red = {0.980f, 0.261f, 0.261f, 0.671f}; + + if (showCustomDifName) { + comboPreview = "Custom"; + } else { + if (difficulty.empty()) { + comboPreview = "Choose One"; + } else { + comboPreview = difficulty; + } + } + if(ImGui::BeginCombo("Difficulty",comboPreview.c_str())) { + for (auto dif_name : {"BSC","ADV","EXT"}) { + if (editorState.fumen.Charts.find(dif_name) == editorState.fumen.Charts.end()) { + if(ImGui::Selectable(dif_name,dif_name == difficulty)) { + showCustomDifName = false; + difficulty = dif_name; + } + } else { + ImGui::TextDisabled(dif_name); + } + } + ImGui::Separator(); + if (ImGui::Selectable("Custom",&showCustomDifName)) { + difficulty = ""; + } + ImGui::EndCombo(); + } + if (showCustomDifName) { + if (difficulty.empty()) { + ImGui::InputText("Difficulty Name",&difficulty); + } else { + // Si le nom custom est déjà trouvé, rouge, sinon, vert + if (editorState.fumen.Charts.find(difficulty) != editorState.fumen.Charts.end()) { + ImGui::PushStyleColor(ImGuiCol_FrameBg, FrameBg_Red.Value); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, FrameBgHovered_Red.Value); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, FrameBgActive_Red.Value); + } else { + ImGui::PushStyleColor(ImGuiCol_FrameBg, FrameBg_Green.Value); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, FrameBgHovered_Green.Value); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, FrameBgActive_Green.Value); + } + ImGui::InputText("Difficulty Name",&difficulty); + if (ImGui::IsItemHovered() and (editorState.fumen.Charts.find(difficulty) != editorState.fumen.Charts.end())) { + ImGui::BeginTooltip(); + ImGui::TextUnformatted("Chart name has to be unique"); + ImGui::EndTooltip(); + } + ImGui::PopStyleColor(3); + } + } + ImGui::InputInt("Level",&level); + if (ImGui::InputInt("Resolution",&resolution)) { + if (resolution < 1) { + resolution = 1; + } + }; + ImGui::SameLine(); + ImGui::TextDisabled("(?)"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::TextUnformatted("Number of ticks in a beat"); + ImGui::BulletText("Has nothing to do with time signature"); + ImGui::BulletText("Leave the default unless you know what you're doing"); + ImGui::EndTooltip(); + } + if (difficulty.empty() or (editorState.fumen.Charts.find(difficulty) != editorState.fumen.Charts.end())) { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + ImGui::Button("Create Chart##New Chart"); + ImGui::PopItemFlag(); + ImGui::PopStyleVar(); + } else { + if (ImGui::Button("Create Chart##New Chart")) { + try { + newChart.emplace(difficulty,level,resolution); + } catch (const std::exception& e) { + tinyfd_messageBox("Error",e.what(),"ok","error",1); + } + } + } + } + ImGui::End(); + return newChart; +} diff --git a/EditorState.h b/EditorState.h index 58620d4..9a9bac3 100644 --- a/EditorState.h +++ b/EditorState.h @@ -53,12 +53,16 @@ public: bool showStatus; bool showPlaybackStatus = true; bool showTimeline = true; + bool showChartList; + bool showNewChartDialog; void displayPlayfield(); void displayProperties(); void displayStatus(); void displayPlaybackStatus(); void displayTimeline(); + void displayChartList(); + void displayNewChartDialog(); bool playBeatTick; bool playNoteTick; @@ -72,6 +76,23 @@ namespace ESHelper { void save(EditorState& ed); void open(std::optional& ed); void openFromFile(std::optional& ed, std::filesystem::path path); + + class NewChartDialog { + + public: + + std::optional display(EditorState& editorState); + void resetValues() {level = 1; resolution = 240; difficulty = ""; comboPreview = ""; showCustomDifName = false;}; + + private: + + int level = 1; + int resolution = 240; + std::string difficulty; + std::string comboPreview; + bool showCustomDifName = false; + + }; } diff --git a/Fumen.cpp b/Fumen.cpp index edaa97e..3b2ba02 100644 --- a/Fumen.cpp +++ b/Fumen.cpp @@ -4,6 +4,22 @@ #include "Fumen.h" +bool cmpDifName::operator()(const std::string &a, const std::string &b) const { + if (dif_names.find(a) != dif_names.end()) { + if (dif_names.find(b) != dif_names.end()) { + return dif_names.find(a)->second < dif_names.find(b)->second; + } else { + return true; + } + } else { + if (dif_names.find(b) != dif_names.end()) { + return false; + } else { + return a < b; + } + } +} + void Fumen::loadFromMemon(std::filesystem::path path) { // for convenience diff --git a/Fumen.h b/Fumen.h index 7328b67..91a9c70 100644 --- a/Fumen.h +++ b/Fumen.h @@ -15,6 +15,15 @@ #include "Note.h" #include "Chart.h" +struct cmpDifName { + std::map dif_names; + + cmpDifName() { + dif_names = {{"BSC",1},{"ADV",2},{"EXT",3}}; + } + bool operator()(const std::string& a, const std::string& b) const; +}; + class Fumen { public: @@ -42,7 +51,7 @@ public: void autoLoadFromMemon() {loadFromMemon(path);}; void autoSaveAsMemon() {saveAsMemon(path);}; - std::map Charts; + std::map Charts; std::filesystem::path path; std::string songTitle; std::string artist; diff --git a/main.cpp b/main.cpp index 11fe6e7..ef1cc10 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,12 @@ int main(int argc, char** argv) { + // TODO : Suppression des charts + // TODO : Volume de la musique + // TODO : Volume des claps + // TODO : Bruit des notes + // TODO : Volume des notes + // Création de la fenêtre sf::RenderWindow window(sf::VideoMode(800, 600), "FEIS"); sf::RenderWindow & ref_window = window; @@ -42,6 +48,7 @@ int main(int argc, char** argv) { Widgets::Ecran_attente bg; std::optional editorState; + ESHelper::NewChartDialog newChartDialog; sf::Clock deltaClock; while (window.isOpen()) { @@ -140,6 +147,18 @@ int main(int argc, char** argv) { } if (editorState->showTimeline) { editorState->displayTimeline(); + } + if (editorState->showChartList) { + editorState->displayChartList(); + } + if (editorState->showNewChartDialog) { + std::optional c = newChartDialog.display(*editorState); + if (c) { + editorState->showNewChartDialog = false; + editorState->fumen.Charts.try_emplace(c->dif_name,*c); + } + } else { + newChartDialog.resetValues(); } window.clear(sf::Color(0, 0, 0)); } else { @@ -224,6 +243,16 @@ int main(int argc, char** argv) { if (ImGui::BeginMenu("Edit")) { ImGui::EndMenu(); } + if (ImGui::BeginMenu("Chart",editorState.has_value())) { + if (ImGui::MenuItem("Chart List")) { + editorState->showChartList = true; + } + ImGui::Separator(); + if (ImGui::MenuItem("New Chart")) { + editorState->showNewChartDialog = true; + } + ImGui::EndMenu(); + } if (ImGui::BeginMenu("View",editorState.has_value())) { if (ImGui::MenuItem("Playfield", nullptr,editorState->showPlayfield)) { editorState->showPlayfield = not editorState->showPlayfield;