23 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
24 ImGui::InputTextWithHint(
"##SongFilter",
ICON_MD_SEARCH " Search songs...",
41 " Oracle of Secrets expanded music detected");
43 ImGui::TextDisabled(
"Expanded bank at $%06X, Aux at $%06X",
44 info.main_rom_offset, info.aux_rom_offset);
49 static const char* bank_names[] = {
"Overworld",
"Dungeon",
"Credits",
50 "Expanded",
"Auxiliary"};
58 for (
int i = 0; i < num_banks; ++i) {
60 if (space.total_bytes == 0)
69 ImGui::Text(
"%s:", bank_names[i]);
75 float fraction = space.usage_percent / 100.0f;
77 absl::StrFormat(
"%d / %d bytes (%.1f%%)", space.used_bytes,
78 space.total_bytes, space.usage_percent);
79 ImGui::ProgressBar(fraction, ImVec2(-1, 0), overlay.c_str());
83 if (space.is_critical) {
85 space.recommendation.c_str());
86 }
else if (space.is_warning) {
88 space.recommendation.c_str());
97 ImGui::TextDisabled(
"Songs won't fit in ROM. Remove or shorten songs.");
103 ImGui::Unindent(8.0f);
126 ImGui::BeginChild(
"SongList", ImVec2(0, 0),
true);
130 ImGuiTreeNodeFlags_DefaultOpen)) {
131 const float item_height = ImGui::GetTextLineHeightWithSpacing();
132 ImGuiListClipper clipper;
136 while (clipper.Step()) {
137 for (
int row = clipper.DisplayStart; row < clipper.DisplayEnd; ++row) {
139 const auto* song = bank.
GetSong(i);
143 std::string display_name =
144 absl::StrFormat(
"%02X: %s", i + 1, song->name);
153 if (ImGui::Selectable(label.c_str(), is_selected)) {
161 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
168 if (ImGui::BeginPopupContextItem()) {
198 if (ImGui::CollapsingHeader(
ICON_MD_EDIT " Custom Songs",
199 ImGuiTreeNodeFlags_DefaultOpen)) {
201 ImGui::TextDisabled(
"No custom songs match filter");
202 ImGui::TextDisabled(
"Click 'New Song' or duplicate a vanilla song");
204 const float item_height = ImGui::GetTextLineHeightWithSpacing();
205 ImGuiListClipper clipper;
209 while (clipper.Step()) {
210 for (
int row = clipper.DisplayStart; row < clipper.DisplayEnd; ++row) {
212 const auto* song = bank.
GetSong(i);
216 std::string display_name =
217 absl::StrFormat(
"%02X: %s", i + 1, song->name);
220 std::string label = absl::StrFormat(
226 if (ImGui::Selectable(label.c_str(), is_selected)) {
234 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
241 if (ImGui::BeginPopupContextItem()) {
260 const auto* rename_song = bank.
GetSong(i);
298 ImGui::OpenPopup(
"Rename Song");
302 if (ImGui::BeginPopupModal(
"Rename Song",
nullptr,
303 ImGuiWindowFlags_AlwaysAutoResize)) {
304 ImGui::Text(
"Enter a new name for the song:");
305 ImGui::SetNextItemWidth(300);
307 bool enter_pressed = ImGui::InputText(
"##RenameSongInput",
rename_buffer_,
309 ImGuiInputTextFlags_EnterReturnsTrue);
312 if (ImGui::IsWindowAppearing()) {
313 ImGui::SetKeyboardFocusHere(-1);
316 bool apply = enter_pressed || ImGui::Button(
"OK");
318 bool cancel = ImGui::Button(
"Cancel");
324 target_song->modified =
true;
330 ImGui::CloseCurrentPopup();
335 ImGui::CloseCurrentPopup();
347 std::string lower_name = name;
349 std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(),
351 std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(),
354 return lower_name.find(lower_search) != std::string::npos;