24 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
25 ImGui::InputTextWithHint(
"##SongFilter",
ICON_MD_SEARCH " Search songs...",
42 " Oracle of Secrets expanded music detected");
44 ImGui::TextDisabled(tr(
"Expanded bank at $%06X, Aux at $%06X"),
45 info.main_rom_offset, info.aux_rom_offset);
50 static const char* bank_names[] = {
"Overworld",
"Dungeon",
"Credits",
51 "Expanded",
"Auxiliary"};
59 for (
int i = 0; i < num_banks; ++i) {
61 if (space.total_bytes == 0)
70 ImGui::Text(
"%s:", bank_names[i]);
76 float fraction = space.usage_percent / 100.0f;
78 absl::StrFormat(
"%d / %d bytes (%.1f%%)", space.used_bytes,
79 space.total_bytes, space.usage_percent);
80 ImGui::ProgressBar(fraction, ImVec2(-1, 0), overlay.c_str());
84 if (space.is_critical) {
86 space.recommendation.c_str());
87 }
else if (space.is_warning) {
89 space.recommendation.c_str());
99 tr(
"Songs won't fit in ROM. Remove or shorten songs."));
105 ImGui::Unindent(8.0f);
128 ImGui::BeginChild(
"SongList", ImVec2(0, 0),
true);
132 ImGuiTreeNodeFlags_DefaultOpen)) {
133 const float item_height = ImGui::GetTextLineHeightWithSpacing();
134 ImGuiListClipper clipper;
138 while (clipper.Step()) {
139 for (
int row = clipper.DisplayStart; row < clipper.DisplayEnd; ++row) {
141 const auto* song = bank.
GetSong(i);
145 std::string display_name =
146 absl::StrFormat(
"%02X: %s", i + 1, song->name);
155 if (ImGui::Selectable(label.c_str(), is_selected)) {
163 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
170 if (ImGui::BeginPopupContextItem()) {
200 if (ImGui::CollapsingHeader(
ICON_MD_EDIT " Custom Songs",
201 ImGuiTreeNodeFlags_DefaultOpen)) {
203 ImGui::TextDisabled(tr(
"No custom songs match filter"));
204 ImGui::TextDisabled(tr(
"Click 'New Song' or duplicate a vanilla song"));
206 const float item_height = ImGui::GetTextLineHeightWithSpacing();
207 ImGuiListClipper clipper;
211 while (clipper.Step()) {
212 for (
int row = clipper.DisplayStart; row < clipper.DisplayEnd; ++row) {
214 const auto* song = bank.
GetSong(i);
218 std::string display_name =
219 absl::StrFormat(
"%02X: %s", i + 1, song->name);
222 std::string label = absl::StrFormat(
228 if (ImGui::Selectable(label.c_str(), is_selected)) {
236 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
243 if (ImGui::BeginPopupContextItem()) {
262 const auto* rename_song = bank.
GetSong(i);
300 ImGui::OpenPopup(
"Rename Song");
304 if (ImGui::BeginPopupModal(
"Rename Song",
nullptr,
305 ImGuiWindowFlags_AlwaysAutoResize)) {
306 ImGui::Text(tr(
"Enter a new name for the song:"));
307 ImGui::SetNextItemWidth(300);
309 bool enter_pressed = ImGui::InputText(
"##RenameSongInput",
rename_buffer_,
311 ImGuiInputTextFlags_EnterReturnsTrue);
314 if (ImGui::IsWindowAppearing()) {
315 ImGui::SetKeyboardFocusHere(-1);
318 bool apply = enter_pressed || ImGui::Button(tr(
"OK"));
320 bool cancel = ImGui::Button(tr(
"Cancel"));
326 target_song->modified =
true;
332 ImGui::CloseCurrentPopup();
337 ImGui::CloseCurrentPopup();
349 std::string lower_name = name;
351 std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(),
353 std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(),
356 return lower_name.find(lower_search) != std::string::npos;