2019-01-03 23:20:35 +01:00
|
|
|
#ifndef FEIS_EDITORSTATE_H
|
|
|
|
#define FEIS_EDITORSTATE_H
|
|
|
|
|
|
|
|
#include <SFML/Audio.hpp>
|
2019-01-12 17:16:20 +01:00
|
|
|
#include <SFML/Graphics.hpp>
|
2021-12-31 14:59:39 +01:00
|
|
|
#include <optional>
|
|
|
|
|
|
|
|
#include "chart_with_history.hpp"
|
2021-12-31 00:57:06 +01:00
|
|
|
#include "fumen.hpp"
|
|
|
|
#include "history.hpp"
|
|
|
|
#include "history_actions.hpp"
|
2021-12-31 14:59:39 +01:00
|
|
|
#include "marker.hpp"
|
2021-12-31 00:57:06 +01:00
|
|
|
#include "notes_clipboard.hpp"
|
2022-02-28 23:10:22 +01:00
|
|
|
#include "precise_music.hpp"
|
2021-12-31 14:59:39 +01:00
|
|
|
#include "time_selection.hpp"
|
2021-12-31 00:57:06 +01:00
|
|
|
#include "widgets/linear_view.hpp"
|
|
|
|
#include "widgets/playfield.hpp"
|
2019-01-03 23:20:35 +01:00
|
|
|
|
2019-03-02 13:47:26 +01:00
|
|
|
class ActionWithMessage;
|
|
|
|
class OpenChart;
|
2019-01-03 23:20:35 +01:00
|
|
|
|
2019-03-28 10:07:19 +01:00
|
|
|
enum saveChangesResponses {
|
|
|
|
saveChangesYes,
|
|
|
|
saveChangesNo,
|
|
|
|
saveChangesCancel,
|
|
|
|
saveChangesDidNotDisplayDialog
|
|
|
|
};
|
|
|
|
|
2019-03-27 20:37:30 +01:00
|
|
|
/*
|
2021-12-31 14:59:39 +01:00
|
|
|
* The god class, holds everything there is to know about the currently open
|
|
|
|
* .memon file
|
2019-03-27 20:37:30 +01:00
|
|
|
*/
|
2019-03-02 13:47:26 +01:00
|
|
|
class EditorState {
|
2019-01-03 23:20:35 +01:00
|
|
|
public:
|
2022-01-04 01:31:17 +01:00
|
|
|
EditorState(Fumen& fumen, std::filesystem::path assets);
|
2019-01-17 15:37:15 +01:00
|
|
|
|
2019-03-02 13:47:26 +01:00
|
|
|
std::optional<Chart_with_History> chart;
|
2019-03-26 00:04:29 +01:00
|
|
|
|
2019-03-27 20:37:30 +01:00
|
|
|
Fumen fumen;
|
2019-03-26 00:04:29 +01:00
|
|
|
|
2019-04-06 22:35:17 +02:00
|
|
|
Playfield playfield;
|
|
|
|
LinearView linearView;
|
2019-03-26 00:04:29 +01:00
|
|
|
|
2021-12-31 14:59:39 +01:00
|
|
|
// the snap but divided by 4 because you can't set a snap to anything lower
|
|
|
|
// than 4ths
|
2019-01-17 01:08:38 +01:00
|
|
|
int snap = 1;
|
2019-01-16 22:10:20 +01:00
|
|
|
|
2022-02-28 23:10:22 +01:00
|
|
|
std::optional<PreciseMusic> music;
|
2021-12-31 14:59:39 +01:00
|
|
|
int musicVolume = 10; // 0 -> 10
|
2019-03-24 23:19:06 +01:00
|
|
|
void setMusicVolume(int newMusicVolume);
|
2022-02-09 02:53:41 +01:00
|
|
|
void musicVolumeUp();
|
|
|
|
void musicVolumeDown();
|
2019-03-24 23:19:06 +01:00
|
|
|
|
2021-12-31 14:59:39 +01:00
|
|
|
int musicSpeed = 10; // 1 -> 20
|
2019-03-24 23:19:06 +01:00
|
|
|
void setMusicSpeed(int newMusicSpeed);
|
2022-02-09 02:53:41 +01:00
|
|
|
void musicSpeedUp();
|
|
|
|
void musicSpeedDown();
|
2019-01-16 22:10:20 +01:00
|
|
|
|
2019-03-24 15:13:13 +01:00
|
|
|
std::optional<sf::Texture> albumCover;
|
2019-01-12 17:16:20 +01:00
|
|
|
|
2019-03-28 02:16:29 +01:00
|
|
|
bool playing;
|
|
|
|
|
2019-01-17 03:02:37 +01:00
|
|
|
sf::Time previousPos;
|
2019-01-14 12:21:58 +01:00
|
|
|
sf::Time playbackPosition;
|
2019-04-09 23:07:22 +02:00
|
|
|
|
|
|
|
private:
|
2022-01-05 12:44:56 +01:00
|
|
|
sf::Time previewEnd; // sf::Time (in the audio file "coordinates") at which the chart preview stops, can be
|
|
|
|
// after the end of the actual audio file
|
2019-01-17 01:08:38 +01:00
|
|
|
|
2019-04-09 23:07:22 +02:00
|
|
|
public:
|
2021-12-31 14:59:39 +01:00
|
|
|
const sf::Time& getPreviewEnd();
|
2019-04-09 23:07:22 +02:00
|
|
|
|
|
|
|
public:
|
2019-01-17 01:08:38 +01:00
|
|
|
void setPlaybackAndMusicPosition(sf::Time newPosition);
|
|
|
|
|
2021-12-31 14:59:39 +01:00
|
|
|
float getBeats() { return getBeatsAt(playbackPosition.asSeconds()); };
|
|
|
|
float getBeatsAt(float seconds) {
|
|
|
|
return ((seconds + fumen.offset) / 60.f) * fumen.BPM;
|
|
|
|
};
|
|
|
|
float getCurrentTick() { 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 chart ? chart->ref.getResolution() : 240; };
|
|
|
|
int getSnapStep() { return getResolution() / snap; };
|
2019-02-09 16:05:46 +01:00
|
|
|
|
2021-12-31 14:59:39 +01:00
|
|
|
float ticksToSeconds(int ticks) {
|
|
|
|
return (60.f * ticks) / (fumen.BPM * getResolution());
|
|
|
|
};
|
2019-01-14 12:21:58 +01:00
|
|
|
|
2021-12-31 14:59:39 +01:00
|
|
|
float getChartRuntime() {
|
|
|
|
return getPreviewEnd().asSeconds() + fumen.offset;
|
|
|
|
};
|
2019-03-25 19:16:45 +01:00
|
|
|
|
2022-01-04 01:31:17 +01:00
|
|
|
void reloadFromFumen(std::filesystem::path assets);
|
2019-01-12 17:16:20 +01:00
|
|
|
void reloadMusic();
|
2019-03-24 15:13:13 +01:00
|
|
|
void reloadAlbumCover();
|
2019-04-09 23:07:22 +02:00
|
|
|
void reloadPreviewEnd();
|
2019-01-12 17:16:20 +01:00
|
|
|
|
2019-01-13 22:29:29 +01:00
|
|
|
bool showPlayfield = true;
|
2019-01-03 23:20:35 +01:00
|
|
|
bool showProperties;
|
2019-01-12 03:13:30 +01:00
|
|
|
bool showStatus;
|
2019-01-12 17:16:20 +01:00
|
|
|
bool showPlaybackStatus = true;
|
2019-01-13 03:53:42 +01:00
|
|
|
bool showTimeline = true;
|
2019-01-16 01:59:02 +01:00
|
|
|
bool showChartList;
|
|
|
|
bool showNewChartDialog;
|
2019-01-16 19:12:01 +01:00
|
|
|
bool showChartProperties;
|
2019-03-02 13:47:26 +01:00
|
|
|
bool showHistory;
|
2019-03-25 19:16:45 +01:00
|
|
|
bool showSoundSettings;
|
2019-03-26 00:04:29 +01:00
|
|
|
bool showLinearView;
|
2019-01-12 17:16:20 +01:00
|
|
|
|
2019-01-17 15:37:15 +01:00
|
|
|
void displayPlayfield(Marker& marker, MarkerEndingState markerEndingState);
|
2019-01-12 17:16:20 +01:00
|
|
|
void displayProperties();
|
|
|
|
void displayStatus();
|
|
|
|
void displayPlaybackStatus();
|
2019-01-13 03:53:42 +01:00
|
|
|
void displayTimeline();
|
2022-01-04 01:31:17 +01:00
|
|
|
void displayChartList(std::filesystem::path assets);
|
2019-03-26 00:04:29 +01:00
|
|
|
void displayLinearView();
|
2019-01-14 21:43:56 +01:00
|
|
|
|
2019-03-28 10:07:19 +01:00
|
|
|
saveChangesResponses alertSaveChanges();
|
2019-03-28 10:54:50 +01:00
|
|
|
bool saveChangesOrCancel();
|
2019-03-28 02:16:29 +01:00
|
|
|
|
2019-01-17 19:39:59 +01:00
|
|
|
void updateVisibleNotes();
|
|
|
|
std::set<Note> visibleNotes;
|
|
|
|
|
|
|
|
void toggleNoteAtCurrentTime(int pos);
|
2019-01-03 23:20:35 +01:00
|
|
|
};
|
|
|
|
|
2019-01-13 22:29:29 +01:00
|
|
|
namespace ESHelper {
|
|
|
|
void save(EditorState& ed);
|
2022-01-04 01:31:17 +01:00
|
|
|
void open(std::optional<EditorState>& ed, std::filesystem::path assets, std::filesystem::path settings);
|
|
|
|
void openFromFile(
|
|
|
|
std::optional<EditorState>& ed,
|
|
|
|
std::filesystem::path file,
|
|
|
|
std::filesystem::path assets,
|
|
|
|
std::filesystem::path settings
|
|
|
|
);
|
2019-01-16 01:59:02 +01:00
|
|
|
|
2019-03-28 10:54:50 +01:00
|
|
|
bool saveOrCancel(std::optional<EditorState>& ed);
|
|
|
|
|
2019-01-16 01:59:02 +01:00
|
|
|
class NewChartDialog {
|
|
|
|
public:
|
|
|
|
std::optional<Chart> display(EditorState& editorState);
|
2021-12-31 14:59:39 +01:00
|
|
|
void resetValues() {
|
|
|
|
level = 1;
|
|
|
|
resolution = 240;
|
|
|
|
difficulty = "";
|
|
|
|
comboPreview = "";
|
|
|
|
showCustomDifName = false;
|
|
|
|
};
|
2019-01-16 01:59:02 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
int level = 1;
|
|
|
|
int resolution = 240;
|
|
|
|
std::string difficulty;
|
|
|
|
std::string comboPreview;
|
|
|
|
bool showCustomDifName = false;
|
|
|
|
};
|
2019-01-16 19:12:01 +01:00
|
|
|
|
|
|
|
class ChartPropertiesDialog {
|
|
|
|
public:
|
2022-01-04 01:31:17 +01:00
|
|
|
void display(EditorState& editorState, std::filesystem::path assets);
|
2019-01-16 19:12:01 +01:00
|
|
|
bool shouldRefreshValues = true;
|
|
|
|
|
|
|
|
private:
|
|
|
|
int level;
|
2019-03-02 13:47:26 +01:00
|
|
|
std::string difficulty_name;
|
2019-01-16 19:12:01 +01:00
|
|
|
std::string comboPreview;
|
|
|
|
std::set<std::string> difNamesInUse;
|
|
|
|
bool showCustomDifName = false;
|
|
|
|
};
|
2019-01-13 22:29:29 +01:00
|
|
|
}
|
|
|
|
|
2021-12-31 14:59:39 +01:00
|
|
|
#endif // FEIS_EDITORSTATE_H
|