3 #include <BLIB/Audio.hpp>
10 using namespace bl::gui;
15 , songPicker(
core::Properties::MusicPath(), {
"ogg",
"wav"},
16 std::bind(&PlaylistEditorWindow::onSongPick,
this, std::placeholders::_1),
17 std::bind(&PlaylistEditorWindow::closePickers,
this))
19 std::bind(&PlaylistEditorWindow::onPlaylistPick,
this, std::placeholders::_1),
20 std::bind(&PlaylistEditorWindow::closePickers,
this)) {
21 window = Window::create(LinePacker::create(LinePacker::Vertical, 4.f),
"Playlist Editor");
22 window->getSignal(Event::Closed).willAlwaysCall(std::bind(&PlaylistEditorWindow::close,
this));
24 Box::Ptr row = Box::create(LinePacker::create(LinePacker::Horizontal, 4.f));
25 Button::Ptr but = Button::create(
"New");
26 but->getSignal(Event::LeftClicked)
27 .willAlwaysCall(std::bind(&PlaylistEditorWindow::makeNew,
this));
28 row->pack(but,
false,
true);
29 but = Button::create(
"Open");
30 but->getSignal(Event::LeftClicked).willAlwaysCall([
this](
const Event&, Element*) {
32 window->setForceFocus(
false);
33 plistPicker.open(FilePicker::PickExisting,
"Open Playlist", gui);
35 row->pack(but,
false,
true);
36 but = Button::create(
"Set file");
37 but->getSignal(Event::LeftClicked).willAlwaysCall([
this](
const Event&, Element*) {
39 window->setForceFocus(
false);
40 plistPicker.open(FilePicker::CreateOrPick,
"Set Playlist File", gui);
42 row->pack(but,
false,
true);
43 saveBut = Button::create(
"Save");
44 saveBut->getSignal(Event::LeftClicked)
45 .willAlwaysCall(std::bind(&PlaylistEditorWindow::save,
this));
46 row->pack(saveBut,
false,
true);
47 fileLabel = Label::create(
"<set a file>");
48 fileLabel->setColor(sf::Color(20, 230, 245), sf::Color::Transparent);
49 row->pack(fileLabel,
true,
true);
52 row = Box::create(LinePacker::create(LinePacker::Horizontal, 4.f));
53 songList = SelectBox::create();
54 songList->setRequisition({400.f, 350.f});
55 songList->setMaxSize({400.f, 400.f});
56 row->pack(songList,
true,
true);
58 Box::Ptr column = Box::create(LinePacker::create(LinePacker::Vertical, 6.f));
59 but = Button::create(
"Add Song");
60 but->getSignal(Event::LeftClicked).willAlwaysCall([
this](
const Event&, Element*) {
61 window->setForceFocus(
false);
62 songPicker.open(FilePicker::PickExisting,
"Add Song", gui);
64 column->pack(but,
true,
false);
66 shuffleBut = CheckButton::create(
"Shuffle");
67 column->pack(shuffleBut);
68 loopShuffleBut = CheckButton::create(
"Reshuffle on loop");
69 column->pack(loopShuffleBut);
71 but = Button::create(
"Remove");
72 but->getSignal(Event::LeftClicked)
73 .willAlwaysCall(std::bind(&PlaylistEditorWindow::removeSong,
this));
74 but->setColor(sf::Color(170, 0, 0), sf::Color::Black);
76 row->pack(column,
false,
true);
77 window->pack(row,
true,
true);
79 but = Button::create(
"Use Playlist");
80 but->getSignal(Event::LeftClicked)
81 .willAlwaysCall(std::bind(&PlaylistEditorWindow::select,
this));
82 but->setColor(sf::Color(20, 230, 255), sf::Color::Black);
90 if (!p.empty()) { load(p); }
93 window->setForceFocus(
true);
96 void PlaylistEditorWindow::onSongPick(
const std::string& song) {
98 window->setForceFocus(
true);
99 songList->addOption(song);
103 void PlaylistEditorWindow::onPlaylistPick(
const std::string& p) {
104 const std::string plst = bl::util::FileUtil::getExtension(p) ==
"plst" ? p : p +
".plst";
106 fileLabel->setText(plst);
113 void PlaylistEditorWindow::makeNew() {
114 if (!confirmUnsaved())
return;
116 songList->clearOptions();
117 fileLabel->setText(
"<set a file>");
118 shuffleBut->setValue(
true);
119 loopShuffleBut->setValue(
false);
123 void PlaylistEditorWindow::markDirty() {
124 saveBut->setColor(sf::Color::Red, sf::Color::Black);
128 void PlaylistEditorWindow::markClean() {
129 saveBut->setColor(sf::Color::Red, sf::Color::Black);
133 void PlaylistEditorWindow::removeSong() {
134 const auto o = songList->getSelectedOption();
135 if (o.has_value()) { songList->removeOption(o.value()); }
138 void PlaylistEditorWindow::save() {
139 bl::audio::Playlist plst;
140 plst.setShuffle(shuffleBut->getValue());
141 plst.setShuffleOnLoop(loopShuffleBut->getValue());
143 std::vector<std::string> songs;
144 songList->getAllOptions(songs);
145 for (
const auto& song : songs) { plst.addSong(song); }
151 else { bl::dialog::tinyfd_messageBox(
"Error",
"Failed to save playlist",
"ok",
"error", 1); }
154 void PlaylistEditorWindow::load(
const std::string& file) {
155 if (!confirmUnsaved())
return;
157 bl::audio::Playlist plst;
159 bl::dialog::tinyfd_messageBox(
"Error",
"Failed to load playlist",
"ok",
"error", 1);
163 fileLabel->setText(file);
164 songList->clearOptions();
165 for (
const auto& song : plst.getSongList()) { songList->addOption(song); }
166 shuffleBut->setValue(plst.shuffling());
167 loopShuffleBut->setValue(plst.shufflingOnLoop());
171 void PlaylistEditorWindow::close() {
173 window->setForceFocus(
false);
178 void PlaylistEditorWindow::select() {
179 if (!confirmUnsaved())
return;
181 if (!bl::util::FileUtil::exists(
183 bl::dialog::tinyfd_messageBox(
"Error",
"Please select a playlist",
"ok",
"error", 1);
187 std::vector<std::string> songs;
188 songList->getAllOptions(songs);
190 bl::dialog::tinyfd_messageBox(
191 "Error",
"Please add at least one song mate",
"ok",
"error", 1);
196 onSelect(fileLabel->getText());
199 void PlaylistEditorWindow::closePickers() {
202 window->setForceFocus(
true);
205 bool PlaylistEditorWindow::confirmUnsaved() {
207 return 1 == bl::dialog::tinyfd_messageBox(
208 "Warning",
"Discard unsaved changes",
"yesno",
"warning", 0);
Core classes and functionality for both the editor and game.
All classes and functionality used for implementing the game editor.
static const std::string & PlaylistPath()
PlaylistEditorWindow(const SelectedCb &onSelect, const CancelCb &onCancel)
Creates the playlist editor.
std::function< void()> CancelCb
void open(bl::gui::GUI *gui, const std::string &plist)
Opens the window with an optional file to load.
std::function< void(const std::string &)> SelectedCb