#pragma once #include #include #include #include "better_song.hpp" #include "chart_state.hpp" #include "generic_interval.hpp" #include "history.hpp" #include "history_actions.hpp" #include "marker.hpp" #include "metadata_in_gui.hpp" #include "music_state.hpp" #include "notes_clipboard.hpp" #include "notifications_queue.hpp" #include "precise_music.hpp" #include "src/better_note.hpp" #include "widgets/linear_view.hpp" #include "widgets/playfield.hpp" class ActionWithMessage; class OpenChart; enum class UserWantsToSave { Yes, No, Cancel, DidNotDisplayDialog }; /* * The god class, holds everything there is to know about the currently open * file */ class EditorState { public: explicit EditorState(const std::filesystem::path& assets); EditorState( const better::Song& song, const std::filesystem::path& assets, const std::filesystem::path& save_path ); better::Song song; std::optional song_path; std::optional chart_state; std::optional music_state; std::optional preview_audio; Playfield playfield; LinearView linear_view; unsigned int snap = 1; std::optional jacket; bool playing; sf::Time playback_position; sf::Time previous_playback_position; const Interval& get_editable_range(); void set_playback_position(sf::Time new_position); Fraction current_exact_beats() const; Fraction current_snaped_beats() const; Fraction beats_at(sf::Time time) const; sf::Time time_at(Fraction beat) const; Fraction get_snap_step() const; bool showPlayfield = true; void display_playfield(Marker& marker, MarkerEndingState markerEndingState); bool showProperties; void display_properties(); bool showStatus; void display_status(); bool showPlaybackStatus = true; void display_playback_status(); bool showTimeline = true; void display_timeline(); bool showChartList; void display_chart_list(); bool showLinearView; void display_linear_view(); bool showNewChartDialog; bool showChartProperties; bool showHistory; bool showSoundSettings; /* Return ::DidNotDisplayDialog if the current chart state is marked as saved, otherwise ask the user if they want to save and return their answer */ UserWantsToSave ask_to_save_if_needed(); /* If the given song already has a dedicated file on disk, returns its path. Otherwise use a dialog box to ask the user for a path and return it, or return nothing if the user canceled */ std::optional ask_for_save_path_if_needed(); bool save_changes_or_cancel(); void toggle_note_at_current_time(const better::Position& pos); void move_backwards_in_time(); void move_forwards_in_time(); void undo(NotificationsQueue& nq); void redo(NotificationsQueue& nq); void save(const std::filesystem::path& path); private: /* sf::Time bounds (in the audio file "coordinates") which are accessible (and maybe editable) from the editor, can extend before and after the audio file */ Interval editable_range; void reload_editable_range(); void reload_jacket(); void reload_music(); void reload_preview_audio(); better::Timing& applicable_timing; void reload_applicable_timing(); void open_chart(better::Chart& chart, const std::string& name); std::filesystem::path assets; friend class ESHelper::NewChartDialog; }; namespace feis { void open(std::optional& ed, std::filesystem::path assets, std::filesystem::path settings); void openFromFile( std::optional& ed, std::filesystem::path file, std::filesystem::path assets, std::filesystem::path settings ); bool saveOrCancel(std::optional& ed); 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; }; class ChartPropertiesDialog { public: void display(EditorState& editorState, std::filesystem::path assets); bool shouldRefreshValues = true; private: int level; std::string difficulty_name; std::string comboPreview; std::set difNamesInUse; bool showCustomDifName = false; }; }