Chart creation dialog

Chart list view
Chart correctly ordered according to difficulty name
This commit is contained in:
Stepland 2019-01-16 01:59:02 +01:00
parent 3dbfc2820c
commit 76f3d1ae4f
8 changed files with 227 additions and 5 deletions

View File

@ -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")

View File

@ -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);
}

View File

@ -9,13 +9,11 @@
#include <set>
#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<Note> Notes;
bool operator==(const Chart &rhs) const;
bool operator!=(const Chart &rhs) const;
private:
int resolution;

View File

@ -6,6 +6,7 @@
#include <imgui.h>
#include <imgui-SFML.h>
#include <imgui_stdlib.h>
#include <imgui_internal.h>
#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<Chart> 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<int>(tuple.second.Notes.size())); ImGui::NextColumn();
}
}
}
ImGui::End();
}
std::vector<Note> EditorState::getVisibleNotes() {
if (selectedChart) {
@ -317,3 +345,108 @@ void ESHelper::openFromFile(std::optional<EditorState> &ed, std::filesystem::pat
tinyfd_messageBox("Error", e.what(), "ok", "error", 1);
}
}
/*
* Returns the newly created chart if there is
*/
std::optional<Chart> ESHelper::NewChartDialog::display(EditorState &editorState) {
std::optional<Chart> 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;
}

View File

@ -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<EditorState>& ed);
void openFromFile(std::optional<EditorState>& ed, std::filesystem::path path);
class NewChartDialog {
public:
std::optional<Chart> 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;
};
}

View File

@ -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

11
Fumen.h
View File

@ -15,6 +15,15 @@
#include "Note.h"
#include "Chart.h"
struct cmpDifName {
std::map<std::string,int> 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<std::string,Chart> Charts;
std::map<std::string,Chart,cmpDifName> Charts;
std::filesystem::path path;
std::string songTitle;
std::string artist;

View File

@ -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> 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<Chart> 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;