153 lines
4.6 KiB
Plaintext
153 lines
4.6 KiB
Plaintext
#include "menu.nvgt"
|
|
#include "audio_paths.nvgt"
|
|
|
|
// Applies common menu sounds from a directory.
|
|
// Looks for both .ogg and .wav files automatically.
|
|
void menu_apply_default_sounds(menu @menuRef, const string soundDir = "sounds/menu") {
|
|
if (@menuRef is null) {
|
|
return;
|
|
}
|
|
|
|
menuRef.click_sound = resolve_audio_path(soundDir + "/menu_move");
|
|
menuRef.select_sound = resolve_audio_path(soundDir + "/menu_select");
|
|
menuRef.edge_sound = resolve_audio_path(soundDir + "/menu_edge");
|
|
menuRef.wrap_sound = resolve_audio_path(soundDir + "/menu_wrap");
|
|
menuRef.open_sound = resolve_audio_path(soundDir + "/menu_open");
|
|
menuRef.close_sound = resolve_audio_path(soundDir + "/menu_close");
|
|
}
|
|
|
|
// Minimal blocking list menu.
|
|
// Returns selected index or -1 on empty input/escape.
|
|
int menu_run_simple(const string introText, string[] @options, bool wrap = true, int startIndex = 0,
|
|
const string soundDir = "sounds/menu") {
|
|
if (@options is null || options.length() == 0) {
|
|
return -1;
|
|
}
|
|
|
|
menu menuRef;
|
|
menu_apply_default_sounds(menuRef, soundDir);
|
|
menuRef.intro_text = introText;
|
|
menuRef.wrap = wrap;
|
|
menuRef.focus_first_item = true;
|
|
menuRef.add_items(options);
|
|
|
|
if (startIndex >= 0 && startIndex < int(options.length())) {
|
|
menuRef.focused_item = startIndex;
|
|
}
|
|
|
|
return menuRef.run();
|
|
}
|
|
|
|
// Returns a-z for menu prefix filtering, or empty string when no letter key was pressed.
|
|
string menu_get_filter_letter() {
|
|
if (key_pressed(KEY_A))
|
|
return "a";
|
|
if (key_pressed(KEY_B))
|
|
return "b";
|
|
if (key_pressed(KEY_C))
|
|
return "c";
|
|
if (key_pressed(KEY_D))
|
|
return "d";
|
|
if (key_pressed(KEY_E))
|
|
return "e";
|
|
if (key_pressed(KEY_F))
|
|
return "f";
|
|
if (key_pressed(KEY_G))
|
|
return "g";
|
|
if (key_pressed(KEY_H))
|
|
return "h";
|
|
if (key_pressed(KEY_I))
|
|
return "i";
|
|
if (key_pressed(KEY_J))
|
|
return "j";
|
|
if (key_pressed(KEY_K))
|
|
return "k";
|
|
if (key_pressed(KEY_L))
|
|
return "l";
|
|
if (key_pressed(KEY_M))
|
|
return "m";
|
|
if (key_pressed(KEY_N))
|
|
return "n";
|
|
if (key_pressed(KEY_O))
|
|
return "o";
|
|
if (key_pressed(KEY_P))
|
|
return "p";
|
|
if (key_pressed(KEY_Q))
|
|
return "q";
|
|
if (key_pressed(KEY_R))
|
|
return "r";
|
|
if (key_pressed(KEY_S))
|
|
return "s";
|
|
if (key_pressed(KEY_T))
|
|
return "t";
|
|
if (key_pressed(KEY_U))
|
|
return "u";
|
|
if (key_pressed(KEY_V))
|
|
return "v";
|
|
if (key_pressed(KEY_W))
|
|
return "w";
|
|
if (key_pressed(KEY_X))
|
|
return "x";
|
|
if (key_pressed(KEY_Y))
|
|
return "y";
|
|
if (key_pressed(KEY_Z))
|
|
return "z";
|
|
return "";
|
|
}
|
|
|
|
// Applies a prefix filter to menu options.
|
|
void menu_apply_prefix_filter(const string& in filterText, const string[] @options, int[] @filteredIndices,
|
|
string[] @filteredOptions) {
|
|
filteredIndices.resize(0);
|
|
filteredOptions.resize(0);
|
|
|
|
if (@options is null) {
|
|
return;
|
|
}
|
|
|
|
string filterLower = filterText.lower();
|
|
for (uint optionIndex = 0; optionIndex < options.length(); optionIndex++) {
|
|
if (filterLower.length() == 0) {
|
|
filteredIndices.insert_last(optionIndex);
|
|
filteredOptions.insert_last(options[optionIndex]);
|
|
continue;
|
|
}
|
|
|
|
string optionLower = options[optionIndex].lower();
|
|
if (optionLower.length() >= filterLower.length() &&
|
|
optionLower.substr(0, filterLower.length()) == filterLower) {
|
|
filteredIndices.insert_last(optionIndex);
|
|
filteredOptions.insert_last(options[optionIndex]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Updates filter text from keyboard input and reapplies filtering.
|
|
bool menu_update_prefix_filter(string& inout filterText, const string[] @options, int[] @filteredIndices,
|
|
string[] @filteredOptions, int& inout selection) {
|
|
bool filterChanged = false;
|
|
|
|
if (key_pressed(KEY_BACK) && filterText.length() > 0) {
|
|
filterText = filterText.substr(0, filterText.length() - 1);
|
|
filterChanged = true;
|
|
}
|
|
|
|
string filterLetter = menu_get_filter_letter();
|
|
if (filterLetter != "") {
|
|
filterText += filterLetter;
|
|
filterChanged = true;
|
|
}
|
|
|
|
if (filterChanged) {
|
|
menu_apply_prefix_filter(filterText, options, filteredIndices, filteredOptions);
|
|
if (selection < 0) {
|
|
selection = 0;
|
|
}
|
|
if (selection >= int(filteredOptions.length())) {
|
|
selection = 0;
|
|
}
|
|
}
|
|
|
|
return filterChanged;
|
|
}
|