Metadata history + edit now kind of works

This commit is contained in:
Stepland 2022-10-14 02:42:13 +02:00
parent cff5b4f9b8
commit f24c8dc31b
7 changed files with 318 additions and 65 deletions

View File

@ -32,6 +32,7 @@
#include "long_note_dummy.hpp"
#include "notifications_queue.hpp"
#include "special_numeric_types.hpp"
#include "src/better_metadata.hpp"
#include "src/custom_sfml_audio/synced_sound_streams.hpp"
#include "variant_visitor.hpp"
@ -485,59 +486,102 @@ void EditorState::display_file_properties() {
ImGui::EndChild();
}
ImGui::InputText("Title", &song.metadata.title);
ImGui::InputText("Artist", &song.metadata.artist);
auto edited_title = song.metadata.title;
ImGui::InputText("Title", &edited_title);
if (ImGui::IsItemDeactivatedAfterEdit()) {
history.push(std::make_shared<ChangeTitle>(song.metadata.title, edited_title));
song.metadata.title = edited_title;
}
auto edited_artist = song.metadata.artist;
ImGui::InputText("Artist", &edited_artist);
if (ImGui::IsItemDeactivatedAfterEdit()) {
history.push(std::make_shared<ChangeArtist>(song.metadata.artist, edited_artist));
song.metadata.artist = edited_artist;
}
if (feis::InputTextColored(
auto edited_audio = song.metadata.audio;
feis::InputTextColored(
"Audio",
&song.metadata.audio,
&edited_audio,
music.has_value(),
"Invalid Audio Path"
)) {
);
if (ImGui::IsItemDeactivatedAfterEdit()) {
history.push(std::make_shared<ChangeAudio>(song.metadata.audio, edited_audio));
song.metadata.audio = edited_audio;
reload_music();
}
if (feis::InputTextColored(
auto edited_jacket = song.metadata.jacket;
feis::InputTextColored(
"Jacket",
&song.metadata.jacket,
&edited_jacket,
jacket.has_value(),
"Invalid Jacket Path"
)) {
);
if (ImGui::IsItemDeactivatedAfterEdit()) {
history.push(std::make_shared<ChangeJacket>(song.metadata.jacket, edited_jacket));
song.metadata.jacket = edited_jacket;
reload_jacket();
}
ImGui::Separator();
ImGui::Text("Preview");
ImGui::Checkbox("Use separate preview file", &song.metadata.use_preview_file);
if (ImGui::Checkbox("Use separate preview file", &song.metadata.use_preview_file)) {
if (song.metadata.use_preview_file) {
if (feis::InputTextColored(
history.push(std::make_shared<ChangePreview>(song.metadata.preview_loop, song.metadata.preview_file));
} else {
history.push(std::make_shared<ChangePreview>(song.metadata.preview_file, song.metadata.preview_loop));
}
};
if (song.metadata.use_preview_file) {
auto edited_preview_file = song.metadata.preview_file;
feis::InputTextColored(
"File",
&song.metadata.preview_file,
&edited_preview_file,
preview_audio.has_value(),
"Invalid Path"
)) {
);
if (ImGui::IsItemDeactivatedAfterEdit()) {
history.push(std::make_shared<ChangePreview>(song.metadata.preview_file, edited_preview_file));
song.metadata.preview_file = edited_preview_file;
reload_preview_audio();
}
} else {
if (feis::InputDecimal("Start", &song.metadata.preview_loop.start)) {
song.metadata.preview_loop.start = std::max(
auto edited_loop_start = song.metadata.preview_loop.start;
feis::InputDecimal(
"Start",
&edited_loop_start
);
if (ImGui::IsItemDeactivatedAfterEdit()) {
edited_loop_start = std::max(
Decimal{0},
song.metadata.preview_loop.start
edited_loop_start
);
if (music.has_value()) {
song.metadata.preview_loop.start = std::min(
edited_loop_start = std::min(
Decimal{(**music).getDuration().asMicroseconds()} / 1000000,
song.metadata.preview_loop.start
edited_loop_start
);
}
history.push(std::make_shared<ChangePreview>(
song.metadata.preview_loop,
better::PreviewLoop{edited_loop_start, song.metadata.preview_loop.duration}
));
song.metadata.preview_loop.start = edited_loop_start;
}
if (feis::InputDecimal("Duration", &song.metadata.preview_loop.duration)) {
song.metadata.preview_loop.duration = std::max(
auto edited_loop_duration = song.metadata.preview_loop.duration;
feis::InputDecimal(
"Duration",
&edited_loop_duration
);
if (ImGui::IsItemDeactivatedAfterEdit()) {
edited_loop_duration = std::max(
Decimal{0},
song.metadata.preview_loop.duration
edited_loop_duration
);
if (music.has_value()) {
song.metadata.preview_loop.start = std::min(
edited_loop_duration = std::min(
(
Decimal{
(**music)
@ -546,9 +590,14 @@ void EditorState::display_file_properties() {
} / 1000000
- song.metadata.preview_loop.start
),
song.metadata.preview_loop.start
edited_loop_duration
);
}
history.push(std::make_shared<ChangePreview>(
song.metadata.preview_loop,
better::PreviewLoop{song.metadata.preview_loop.start, edited_loop_duration}
));
song.metadata.preview_loop.duration = edited_loop_duration;
}
}

View File

@ -6,6 +6,7 @@
#include <SFML/Audio.hpp>
#include <SFML/Audio/SoundSource.hpp>
#include <SFML/Graphics.hpp>
#include <type_traits>
#include "custom_sfml_audio/beat_ticks.hpp"
@ -13,6 +14,7 @@
#include "custom_sfml_audio/note_claps.hpp"
#include "custom_sfml_audio/open_music.hpp"
#include "custom_sfml_audio/synced_sound_streams.hpp"
#include "src/history_item.hpp"
#include "widgets/linear_view.hpp"
#include "better_note.hpp"
#include "better_song.hpp"
@ -188,6 +190,10 @@ public:
void update_visible_notes();
void reload_jacket();
void reload_music();
void reload_preview_audio();
private:
int volume = 10; // 0 -> 10
@ -207,10 +213,7 @@ private:
Interval<sf::Time> editable_range;
void reload_editable_range();
Interval<sf::Time> choose_editable_range();
void reload_jacket();
void reload_music();
void clear_music();
void reload_preview_audio();
better::Timing& applicable_timing;
void reload_applicable_timing();

View File

@ -5,9 +5,11 @@
#include <tuple>
#include <fmt/core.h>
#include <variant>
#include "better_song.hpp"
#include "editor_state.hpp"
#include "src/better_metadata.hpp"
const std::string& HistoryItem::get_message() const {
@ -160,3 +162,102 @@ void RenameChart::undo_action(EditorState& ed) const {
);
}
}
ChangeTitle::ChangeTitle(
const std::string& old_value,
const std::string& new_value
) :
ChangeMetadataValue(old_value, new_value)
{
message = fmt::format(
"Change song title : \"{}\" -> \"{}\"",
old_value,
new_value
);
}
void ChangeTitle::set_value(EditorState& ed, const std::string& value) const {
ed.song.metadata.title = value;
}
ChangeArtist::ChangeArtist(
const std::string& old_value,
const std::string& new_value
) :
ChangeMetadataValue(old_value, new_value)
{
message = fmt::format(
"Change song artist : \"{}\" -> \"{}\"",
old_value,
new_value
);
}
void ChangeArtist::set_value(EditorState& ed, const std::string& value) const {
ed.song.metadata.artist = value;
}
ChangeAudio::ChangeAudio(
const std::string& old_value,
const std::string& new_value
) :
ChangeMetadataValue(old_value, new_value)
{
message = fmt::format(
"Change audio : \"{}\" -> \"{}\"",
old_value,
new_value
);
}
void ChangeAudio::set_value(EditorState& ed, const std::string& value) const {
ed.song.metadata.audio = value;
ed.reload_music();
}
ChangeJacket::ChangeJacket(
const std::string& old_value,
const std::string& new_value
) :
ChangeMetadataValue(old_value, new_value)
{
message = fmt::format(
"Change jacket : \"{}\" -> \"{}\"",
old_value,
new_value
);
}
void ChangeJacket::set_value(EditorState& ed, const std::string& value) const {
ed.song.metadata.jacket = value;
ed.reload_jacket();
}
ChangePreview::ChangePreview(
const PreviewState& old_value,
const PreviewState& new_value
) :
ChangeMetadataValue(old_value, new_value)
{
message = fmt::format(
"Change preview : {} -> {}",
old_value,
new_value
);
}
void ChangePreview::set_value(EditorState& ed, const PreviewState& value) const {
const auto set_value_ = VariantVisitor {
[&](const better::PreviewLoop& loop) {
ed.song.metadata.use_preview_file = false;
ed.song.metadata.preview_loop.start = loop.start;
ed.song.metadata.preview_loop.duration = loop.duration;
},
[&](const std::string& file) {
ed.song.metadata.use_preview_file = true;
ed.song.metadata.preview_file = file;
ed.reload_preview_audio();
},
};
std::visit(set_value_, value);
}

View File

@ -5,6 +5,7 @@
#include <utility>
#include <variant>
#include "better_metadata.hpp"
#include "better_notes.hpp"
#include "better_song.hpp"
@ -87,3 +88,82 @@ protected:
std::string old_name;
std::string new_name;
};
template<class T>
class ChangeMetadataValue : public HistoryItem {
public:
ChangeMetadataValue(const T& old_value, const T& new_value) :
old_value(old_value),
new_value(new_value)
{
}
void do_action(EditorState& ed) const override {
set_value(ed, new_value);
}
void undo_action(EditorState& ed) const override {
set_value(ed, old_value);
}
protected:
virtual void set_value(EditorState& ed, const T& value) const = 0;
T old_value;
T new_value;
};
class ChangeTitle : public ChangeMetadataValue<std::string> {
public:
ChangeTitle(const std::string& old_value, const std::string& new_value);
protected:
void set_value(EditorState& ed, const std::string& value) const override;
};
class ChangeArtist : public ChangeMetadataValue<std::string> {
public:
ChangeArtist(const std::string& old_value, const std::string& new_value);
protected:
void set_value(EditorState& ed, const std::string& value) const override;
};
class ChangeAudio : public ChangeMetadataValue<std::string> {
public:
ChangeAudio(const std::string& old_value, const std::string& new_value);
protected:
void set_value(EditorState& ed, const std::string& value) const override;
};
class ChangeJacket : public ChangeMetadataValue<std::string> {
public:
ChangeJacket(const std::string& old_value, const std::string& new_value);;
protected:
void set_value(EditorState& ed, const std::string& value) const override;
};
using PreviewState = std::variant<better::PreviewLoop, std::string>;
template <>
struct fmt::formatter<PreviewState>: formatter<string_view> {
// parse is inherited from formatter<string_view>.
template <typename FormatContext>
auto format(const PreviewState& c, FormatContext& ctx) {
const auto format_ = VariantVisitor {
[&](const better::PreviewLoop& loop) {
return format_to(ctx.out(), "{}", loop);
},
[&](const std::string& file) {
return format_to(ctx.out(), "\"{}\"", file);
},
};
return std::visit(format_, c);
}
};
class ChangePreview : public ChangeMetadataValue<PreviewState> {
public:
ChangePreview(const PreviewState& old_value, const PreviewState& new_value);
protected:
void set_value(EditorState& ed, const PreviewState& value) const override;
};

View File

@ -1,6 +1,7 @@
#include "imgui_extras.hpp"
#include <imgui_stdlib.h>
#include "imgui.h"
bool feis::ColorEdit4(const char* label, sf::Color& col, ImGuiColorEditFlags flags) {
float array_col[4] = {
@ -20,9 +21,13 @@ bool feis::ColorEdit4(const char* label, sf::Color& col, ImGuiColorEditFlags fla
return false;
}
bool feis::InputDecimal(const char *label, Decimal* value) {
bool feis::InputDecimal(
const char *label,
Decimal* value,
const ImGuiInputTextFlags flags
) {
auto s = value->format("f");
if (ImGui::InputText(label, &s, ImGuiInputTextFlags_CharsDecimal)) {
if (ImGui::InputText(label, &s, flags | ImGuiInputTextFlags_CharsDecimal)) {
Decimal new_value;
try {
new_value = Decimal{s};
@ -44,11 +49,12 @@ bool feis::InputTextColored(
const char* label,
std::string* str,
bool isValid,
const std::string& hoverHelpText
const std::string& hoverHelpText,
const ImGuiInputTextFlags flags
) {
bool return_value;
if (str->empty()) {
return ImGui::InputText(label, str);
return ImGui::InputText(label, str, flags);
} else {
if (not isValid) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, colors::red.Value);

View File

@ -10,8 +10,18 @@
namespace feis {
bool ColorEdit4(const char* label, sf::Color& col, ImGuiColorEditFlags flags = 0);
bool InputDecimal(const char *label, Decimal* value);
bool InputTextColored(const char* label, std::string* str, bool isValid, const std::string& hoverHelpText);
bool InputDecimal(
const char *label,
Decimal* value,
const ImGuiInputTextFlags flags = ImGuiInputTextFlags_None
);
bool InputTextColored(
const char* label,
std::string* str,
bool isValid,
const std::string& hoverHelpText,
const ImGuiInputTextFlags flags = ImGuiInputTextFlags_None
);
void HelpMarker(const char* desc);
}

View File

@ -258,6 +258,7 @@ int main() {
}
break;
case sf::Keyboard::Left:
if (not ImGui::GetIO().WantTextInput) {
if (event.key.shift) {
if (editor_state) {
editor_state->speed_down();
@ -277,8 +278,10 @@ int main() {
);
}
}
}
break;
case sf::Keyboard::Right:
if (not ImGui::GetIO().WantTextInput) {
if (event.key.shift) {
if (editor_state) {
editor_state->speed_up();
@ -298,6 +301,7 @@ int main() {
);
}
}
}
break;
/*