25 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
26 ImGui::InputTextWithHint(
"##SongFilter",
ICON_MD_SEARCH " Search songs...",
43 " Oracle of Secrets expanded music detected");
45 ImGui::TextDisabled(tr(
"Expanded bank at $%06X, Aux at $%06X"),
46 info.main_rom_offset, info.aux_rom_offset);
51 static const char* bank_names[] = {
"Overworld",
"Dungeon",
"Credits",
52 "Expanded",
"Auxiliary"};
60 for (
int i = 0; i < num_banks; ++i) {
62 if (space.total_bytes == 0)
71 ImGui::Text(
"%s:", bank_names[i]);
77 float fraction = space.usage_percent / 100.0f;
79 absl::StrFormat(
"%d / %d bytes (%.1f%%)", space.used_bytes,
80 space.total_bytes, space.usage_percent);
81 ImGui::ProgressBar(fraction, ImVec2(-1, 0), overlay.c_str());
85 if (space.is_critical) {
87 space.recommendation.c_str());
88 }
else if (space.is_warning) {
90 space.recommendation.c_str());
100 tr(
"Songs won't fit in ROM. Remove or shorten songs."));
106 ImGui::Unindent(8.0f);
129 ImGui::BeginChild(
"SongList", ImVec2(0, 0),
true);
133 ImGuiTreeNodeFlags_DefaultOpen)) {
134 const float item_height = ImGui::GetTextLineHeightWithSpacing();
135 ImGuiListClipper clipper;
139 while (clipper.Step()) {
140 for (
int row = clipper.DisplayStart; row < clipper.DisplayEnd; ++row) {
142 const auto* song = bank.
GetSong(i);
146 std::string display_name =
147 absl::StrFormat(
"%02X: %s", i + 1, song->name);
156 if (ImGui::Selectable(label.c_str(), is_selected)) {
164 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
172 std::vector<gui::MenuItemSpec> items;
177 items.emplace_back(
"Open Piano Roll",
ICON_MD_PIANO, [
this, i]() {
181 items.back().separator_after =
true;
190 items.back().separator_after =
true;
204 if (ImGui::CollapsingHeader(
ICON_MD_EDIT " Custom Songs",
205 ImGuiTreeNodeFlags_DefaultOpen)) {
207 ImGui::TextDisabled(tr(
"No custom songs match filter"));
208 ImGui::TextDisabled(tr(
"Click 'New Song' or duplicate a vanilla song"));
210 const float item_height = ImGui::GetTextLineHeightWithSpacing();
211 ImGuiListClipper clipper;
215 while (clipper.Step()) {
216 for (
int row = clipper.DisplayStart; row < clipper.DisplayEnd; ++row) {
218 const auto* song = bank.
GetSong(i);
222 std::string display_name =
223 absl::StrFormat(
"%02X: %s", i + 1, song->name);
226 std::string label = absl::StrFormat(
232 if (ImGui::Selectable(label.c_str(), is_selected)) {
240 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
248 std::vector<gui::MenuItemSpec> items;
253 items.emplace_back(
"Open Piano Roll",
ICON_MD_PIANO, [
this, i]() {
257 items.back().separator_after =
true;
270 const auto* rename_song = bank.
GetSong(i);
277 items.back().separator_after =
true;
288 items.back().separator_after =
true;
312 ImGui::OpenPopup(
"Rename Song");
316 if (ImGui::BeginPopupModal(
"Rename Song",
nullptr,
317 ImGuiWindowFlags_AlwaysAutoResize)) {
318 ImGui::Text(tr(
"Enter a new name for the song:"));
319 ImGui::SetNextItemWidth(300);
321 bool enter_pressed = ImGui::InputText(
"##RenameSongInput",
rename_buffer_,
323 ImGuiInputTextFlags_EnterReturnsTrue);
326 if (ImGui::IsWindowAppearing()) {
327 ImGui::SetKeyboardFocusHere(-1);
330 bool apply = enter_pressed || ImGui::Button(tr(
"OK"));
332 bool cancel = ImGui::Button(tr(
"Cancel"));
338 target_song->modified =
true;
344 ImGui::CloseCurrentPopup();
349 ImGui::CloseCurrentPopup();
361 std::string lower_name = name;
363 std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(),
365 std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(),
368 return lower_name.find(lower_search) != std::string::npos;