From 68a65ccbf813a4dc2441f6b4fc004629dd791f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20CARLE?= Date: Sun, 13 Jan 2019 03:53:42 +0100 Subject: [PATCH] Timeline Keyboard Shortcuts Recent Files --- CMakeLists.txt | 21 +++++++---------- EditorState.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ EditorState.h | 6 +++++ README.md | 6 +++++ Toolbox.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ Toolbox.h | 17 ++++++++++++++ main.cpp | 52 ++++++++++++++++++++--------------------- screen.cpp | 34 --------------------------- screen.h | 1 + 9 files changed, 187 insertions(+), 73 deletions(-) create mode 100644 README.md create mode 100644 Toolbox.cpp create mode 100644 Toolbox.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 516fa6b..560f144 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,37 +8,32 @@ set(CMAKE_CXX_EXTENSIONS OFF) SET(GCC_COVERAGE_COMPILE_FLAGS "-mwindows") SET(GCC_COVERAGE_LINK_FLAGS "-mwindows") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" ) -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" ) +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS} -static-libgcc -static-libstdc++") set(SOURCE_FILES main.cpp screen.cpp - screen.h Marker.cpp - Marker.h Fumen.cpp - Fumen.h Note.cpp - Note.h Chart.cpp - Chart.h EditorState.cpp - EditorState.h imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_widgets.cpp imgui/imgui-SFML.cpp imgui/imgui_stdlib.cpp - tinyfiledialogs.c - tinyfiledialogs.h) + tinyfiledialogs.c Toolbox.cpp Toolbox.h) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${FEIS_SOURCE_DIR}/cmake") +#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${FEIS_SOURCE_DIR}/cmake") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) -find_package(SFML 2 COMPONENTS system window graphics network audio REQUIRED) +find_library (WinMM libwinmm.a) +find_package (SFML 2.5.1 COMPONENTS system window graphics network audio REQUIRED) find_package (OpenGL REQUIRED) -include_directories(${OPENGL_INCLUDE_DIR} ${SFML_INCLUDE_DIR} imgui/) +include_directories(${OPENGL_INCLUDE_DIR} imgui/) add_executable(FEIS ${SOURCE_FILES}) -target_link_libraries(FEIS stdc++fs ${OPENGL_LIBRARIES} sfml-system sfml-window sfml-graphics sfml-network sfml-audio) \ No newline at end of file +target_link_libraries(FEIS stdc++fs ${OPENGL_LIBRARIES} sfml-system sfml-window sfml-graphics sfml-network sfml-audio WinMM) \ No newline at end of file diff --git a/EditorState.cpp b/EditorState.cpp index bea2ea9..0bce39a 100644 --- a/EditorState.cpp +++ b/EditorState.cpp @@ -7,8 +7,14 @@ #include #include #include "EditorState.h" +#include "tinyfiledialogs.h" +#include "Toolbox.h" EditorState::EditorState(Fumen &fumen) : fumen(fumen) { + reloadFromFumen(); +} + +void EditorState::reloadFromFumen() { if (not this->fumen.Charts.empty()) { this->selectedChart = this->fumen.Charts.begin()->first; } @@ -134,3 +140,59 @@ void EditorState::displayPlaybackStatus() { ImGui::End(); ImGui::PopStyleVar(); } + +void EditorState::displayTimeline() { + + ImGuiIO& io = ImGui::GetIO(); + ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x - 25, io.DisplaySize.y * 0.5f), ImGuiCond_Always, ImVec2(0.5f,0.5f)); + ImGui::SetNextWindowSize({20,io.DisplaySize.y * 0.9f},ImGuiCond_Always); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize,0); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding,0); + ImGui::Begin( + "Timeline", + &showTimeline, + ImGuiWindowFlags_NoNav + |ImGuiWindowFlags_NoDecoration + |ImGuiWindowFlags_NoTitleBar + |ImGuiWindowFlags_NoMove + ); + { + if (music) { + float slider_pos = 1.f - (music->getPlayingOffset().asSeconds()) / music->getDuration().asSeconds(); + ImGui::SetCursorPos({0,0}); + if(ImGui::VSliderFloat("",ImGui::GetContentRegionMax(),&slider_pos,0.f,1.f,"")) { + music->setPlayingOffset(sf::seconds((1.f-slider_pos)*music->getDuration().asSeconds())); + } + } + } + ImGui::End(); + ImGui::PopStyleVar(3); +} + +void EditorState::save() { + try { + fumen.autoSaveAsMemon(); + } catch (const std::exception& e) { + tinyfd_messageBox("Error",e.what(),"ok","error",1); + } +} + +void EditorState::open() { + const char* _filepath = tinyfd_openFileDialog("Open File",nullptr,0,nullptr,nullptr,false); + if (_filepath != nullptr) { + openFromFile(_filepath); + } +} + +void EditorState::openFromFile(std::filesystem::path path) { + try { + Fumen f(path); + f.autoLoadFromMemon(); + fumen = f; + reloadFromFumen(); + Toolbox::pushNewRecentFile(std::filesystem::canonical(fumen.path)); + } catch (const std::exception &e) { + tinyfd_messageBox("Error", e.what(), "ok", "error", 1); + } +} diff --git a/EditorState.h b/EditorState.h index d5ef8a7..d715d7e 100644 --- a/EditorState.h +++ b/EditorState.h @@ -18,17 +18,23 @@ public: std::optional jacket; std::optional selectedChart; + void reloadFromFumen(); void reloadMusic(); void reloadJacket(); bool showProperties; bool showStatus; bool showPlaybackStatus = true; + bool showTimeline = true; void displayProperties(); void displayStatus(); void displayPlaybackStatus(); + void displayTimeline(); + void save(); + void open(); + void openFromFile(std::filesystem::path path); explicit EditorState(Fumen& fumen); }; diff --git a/README.md b/README.md new file mode 100644 index 0000000..f58fe21 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# F.E.I.S. +a.k.a. _Fumen Edit Integration System_ + +Jubeat chart editor written in C++ using SFML & Dear ImGui + +Development status entirely depends on my motivation \ No newline at end of file diff --git a/Toolbox.cpp b/Toolbox.cpp new file mode 100644 index 0000000..665771e --- /dev/null +++ b/Toolbox.cpp @@ -0,0 +1,61 @@ +// +// Created by Syméon on 13/01/2019. +// + +#include +#include +#include +#include +#include "Toolbox.h" + + +bool Toolbox::isShortcutPressed(std::initializer_list anyOf, std::initializer_list allOf) { + for (auto key : allOf) { + if (not sf::Keyboard::isKeyPressed(key)) { + return false; + } + } + for (auto key : anyOf) { + if (sf::Keyboard::isKeyPressed(key)) { + return true; + } + } + return false; +} + +void Toolbox::pushNewRecentFile(std::filesystem::path path) { + std::ifstream readFile(std::filesystem::path("settings/recent files.txt")); + std::list recent; + std::set recent_set; + for(std::string line; getline( readFile, line );) { + if (recent_set.find(line) == recent_set.end()) { + recent.push_back(line); + recent_set.insert(line); + } + } + readFile.close(); + + recent.remove(std::filesystem::canonical(path).string()); + + while (recent.size() >= 10) { + recent.pop_back(); + } + + recent.push_front(std::filesystem::canonical(path).string()); + + std::ofstream writeFile("settings/recent files.txt", std::ofstream::out | std::ofstream::trunc); + for (const auto& line : recent) { + writeFile << line << std::endl; + } + writeFile.close(); +} + +std::vector Toolbox::getRecentFiles() { + std::ifstream readFile(std::filesystem::path("settings/recent files.txt")); + std::vector recent; + for(std::string line; getline( readFile, line ); ){ + recent.push_back(line); + } + readFile.close(); + return recent; +} diff --git a/Toolbox.h b/Toolbox.h new file mode 100644 index 0000000..e1d11ba --- /dev/null +++ b/Toolbox.h @@ -0,0 +1,17 @@ +// +// Created by Syméon on 13/01/2019. +// + +#ifndef FEIS_TOOLBOX_H +#define FEIS_TOOLBOX_H + +#include +#include + +namespace Toolbox { + bool isShortcutPressed(std::initializer_list anyOf, std::initializer_list allOf); + void pushNewRecentFile(std::filesystem::path path); + std::vector getRecentFiles(); +} + +#endif //FEIS_TOOLBOX_H diff --git a/main.cpp b/main.cpp index 8703785..4575d56 100644 --- a/main.cpp +++ b/main.cpp @@ -5,6 +5,7 @@ #include "screen.h" #include "EditorState.h" #include "tinyfiledialogs.h" +#include "Toolbox.h" int main(int argc, char** argv) { @@ -71,12 +72,20 @@ int main(int argc, char** argv) { if (editorState->showPlaybackStatus) { editorState->displayPlaybackStatus(); } - + if (editorState->showTimeline) { + editorState->displayTimeline(); + } window.clear(sf::Color(0, 0, 0)); } else { bg.render(window); } + // Gestion des Raccourcis Clavier + if (Toolbox::isShortcutPressed({sf::Keyboard::LControl,sf::Keyboard::RControl},{sf::Keyboard::S})) { + editorState->save(); + } else if (Toolbox::isShortcutPressed({sf::Keyboard::LControl,sf::Keyboard::RControl},{sf::Keyboard::O})) { + + } // Dessin de l'interface ImGui::BeginMainMenuBar(); @@ -90,42 +99,30 @@ int main(int argc, char** argv) { Fumen f(filepath); f.autoSaveAsMemon(); editorState.emplace(f); + Toolbox::pushNewRecentFile(std::filesystem::canonical(editorState->fumen.path)); } catch (const std::exception& e) { tinyfd_messageBox("Error",e.what(),"ok","error",1); } } } ImGui::Separator(); - if (ImGui::MenuItem("Open")) { - const char* _filepath = tinyfd_openFileDialog("Open File",nullptr,0,nullptr,nullptr,false); - if (_filepath != nullptr) { - std::filesystem::path filepath(_filepath); - try { - Fumen f(filepath); - f.autoLoadFromMemon(); - editorState.emplace(f); - } catch (const std::exception& e) { - tinyfd_messageBox("Error",e.what(),"ok","error",1); - } - } + if (ImGui::MenuItem("Open","Ctrl+O") or Toolbox::isShortcutPressed({sf::Keyboard::LControl,sf::Keyboard::RControl},{sf::Keyboard::O})) { + editorState->open(); } if (ImGui::BeginMenu("Recent Files")) { - for (int i = 1; i<=10; i++) { - ImGui::PushID(i); - std::ostringstream stringStream; - stringStream << i << ". fichier blabla"; - std::string copyOfStr = stringStream.str(); - ImGui::MenuItem(copyOfStr.c_str()); + int i = 0; + for (const auto& file : Toolbox::getRecentFiles()) { + ImGui::PushID(i); + if (ImGui::MenuItem(file.c_str())) { + editorState->openFromFile(file); + } ImGui::PopID(); + ++i; } ImGui::EndMenu(); } - if (ImGui::MenuItem("Save")) { - try { - editorState->fumen.autoSaveAsMemon(); - } catch (const std::exception& e) { - tinyfd_messageBox("Error",e.what(),"ok","error",1); - } + if (ImGui::MenuItem("Save","Ctrl+S")) { + editorState->save(); } if (ImGui::MenuItem("Save As")) { char const * options[1] = {"*.memon"}; @@ -152,7 +149,10 @@ int main(int argc, char** argv) { editorState->showStatus = not editorState->showStatus; } if (ImGui::MenuItem("Playback Status",nullptr,editorState->showPlaybackStatus)) { - editorState->showStatus = not editorState->showPlaybackStatus; + editorState->showPlaybackStatus = not editorState->showPlaybackStatus; + } + if (ImGui::MenuItem("Timeline",nullptr,editorState->showTimeline)) { + editorState->showTimeline = not editorState->showTimeline; } ImGui::EndMenu(); } diff --git a/screen.cpp b/screen.cpp index 01f1ff0..d9b8942 100644 --- a/screen.cpp +++ b/screen.cpp @@ -34,39 +34,5 @@ Ecran_edition::Ecran_edition() : couleur_de_fond(sf::Color(0,0,0)) { void Ecran_edition::render(sf::RenderWindow &window, EditorState editorState) { - sf::Clock clock; - bool fini = false; - while (!fini) - { - sf::Event event; - while (window.pollEvent(event)) - { - if (event.type == sf::Event::Closed) { - fini = true; - } else if (event.type == sf::Event::Resized) { - window.setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height))); - } - } - window.clear(couleur_de_fond); - - // c'est ici qu'on dessine tout - sf::Time temps = clock.getElapsedTime(); - int frame = ((int)(30*temps.asSeconds()))%45; - if (frame < 16) { - sf::Sprite sprite_marker = marker.getSprite(APPROCHE,frame); - sprite_marker.setPosition(sf::Vector2f((window.getSize().x-160)/2, - (window.getSize().y-160)/2)); - window.draw(sprite_marker); - } else if (frame < 32) { - sf::Sprite sprite_marker = marker.getSprite(PERFECT,frame-16); - sprite_marker.setPosition(sf::Vector2f((window.getSize().x-160)/2, - (window.getSize().y-160)/2)); - window.draw(sprite_marker); - } - - - // fin de la frame courante, affichage de tout ce qu'on a dessiné - window.display(); - } } diff --git a/screen.h b/screen.h index 491b4e9..16cc6f0 100644 --- a/screen.h +++ b/screen.h @@ -6,6 +6,7 @@ #define FEIS_SCREEN_H #include +#include #include "Marker.h" #include "EditorState.h"