Initial commit, reusable code for my nvgt based games.
This commit is contained in:
204
docs_browser.nvgt
Normal file
204
docs_browser.nvgt
Normal file
@@ -0,0 +1,204 @@
|
||||
#include "audio_paths.nvgt"
|
||||
#include "file_viewer.nvgt"
|
||||
|
||||
funcdef void docs_browser_speak_callback(const string &in message, bool interrupt);
|
||||
funcdef void docs_browser_tick_callback();
|
||||
|
||||
docs_browser_speak_callback@ docsBrowserSpeakCallback = null;
|
||||
docs_browser_tick_callback@ docsBrowserTickCallback = null;
|
||||
|
||||
string docsBrowserDirectory = "files";
|
||||
string docsBrowserMenuSoundDir = "sounds/menu";
|
||||
bool docsBrowserWrap = true;
|
||||
|
||||
string[] docsBrowserExtensions = {"md", "MD", "txt", "TXT"};
|
||||
|
||||
sound docsBrowserMoveSound;
|
||||
sound docsBrowserSelectSound;
|
||||
|
||||
void docs_browser_set_speak_callback(docs_browser_speak_callback@ callback) {
|
||||
@docsBrowserSpeakCallback = @callback;
|
||||
}
|
||||
|
||||
void docs_browser_set_tick_callback(docs_browser_tick_callback@ callback) {
|
||||
@docsBrowserTickCallback = @callback;
|
||||
}
|
||||
|
||||
void docs_browser_set_docs_dir(const string docsDir) {
|
||||
docsBrowserDirectory = docsDir;
|
||||
}
|
||||
|
||||
void docs_browser_set_menu_sound_dir(const string menuSoundDir) {
|
||||
docsBrowserMenuSoundDir = menuSoundDir;
|
||||
}
|
||||
|
||||
void docs_browser_set_wrap(bool wrap) {
|
||||
docsBrowserWrap = wrap;
|
||||
}
|
||||
|
||||
void docs_browser_set_extensions(string[]@ extensions) {
|
||||
docsBrowserExtensions.resize(0);
|
||||
if (@extensions is null) return;
|
||||
for (uint extIndex = 0; extIndex < extensions.length(); extIndex++) {
|
||||
docsBrowserExtensions.insert_last(extensions[extIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
void docs_browser_reset_default_extensions() {
|
||||
string[] defaults = {"md", "MD", "txt", "TXT"};
|
||||
docs_browser_set_extensions(defaults);
|
||||
}
|
||||
|
||||
void docs_browser_speak(const string &in message, bool interrupt) {
|
||||
if (@docsBrowserSpeakCallback !is null) {
|
||||
docsBrowserSpeakCallback(message, interrupt);
|
||||
return;
|
||||
}
|
||||
screen_reader_speak(message, interrupt);
|
||||
}
|
||||
|
||||
void docs_browser_tick() {
|
||||
if (@docsBrowserTickCallback !is null) {
|
||||
docsBrowserTickCallback();
|
||||
}
|
||||
}
|
||||
|
||||
bool docs_browser_sort_case_insensitive(const string &in a, const string &in b) {
|
||||
return a.lower() < b.lower();
|
||||
}
|
||||
|
||||
void docs_browser_append_unique_case_insensitive(string[]@ items, const string&in value) {
|
||||
string lowerValue = value.lower();
|
||||
for (uint itemIndex = 0; itemIndex < items.length(); itemIndex++) {
|
||||
if (items[itemIndex].lower() == lowerValue) return;
|
||||
}
|
||||
items.insert_last(value);
|
||||
}
|
||||
|
||||
string docs_browser_collapse_spaces(const string&in text) {
|
||||
string result = text;
|
||||
while (result.find_first(" ") > -1) {
|
||||
result = result.replace(" ", " ", true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
string docs_browser_format_label(const string&in filename) {
|
||||
string name = filename;
|
||||
int dotPos = name.find_last_of(".");
|
||||
if (dotPos > 0) {
|
||||
name = name.substr(0, dotPos);
|
||||
}
|
||||
|
||||
name = name.replace("_", " ", true);
|
||||
name = name.replace("-", " ", true);
|
||||
name = docs_browser_collapse_spaces(name);
|
||||
name = name.lower();
|
||||
name.trim_whitespace_this();
|
||||
|
||||
if (name.length() == 0) return "Document";
|
||||
string first = name.substr(0, 1).upper();
|
||||
if (name.length() == 1) return first;
|
||||
return first + name.substr(1);
|
||||
}
|
||||
|
||||
void docs_browser_collect_entries(string[]@ labels, string[]@ paths) {
|
||||
labels.resize(0);
|
||||
paths.resize(0);
|
||||
|
||||
if (!directory_exists(docsBrowserDirectory)) return;
|
||||
|
||||
string[] docFiles;
|
||||
for (uint extIndex = 0; extIndex < docsBrowserExtensions.length(); extIndex++) {
|
||||
string ext = docsBrowserExtensions[extIndex];
|
||||
if (ext == "") continue;
|
||||
if (ext.substr(0, 1) == ".") {
|
||||
ext = ext.substr(1);
|
||||
}
|
||||
|
||||
string[]@ found = find_files(docsBrowserDirectory + "/*." + ext);
|
||||
if (@found is null) continue;
|
||||
for (uint fileIndex = 0; fileIndex < found.length(); fileIndex++) {
|
||||
docs_browser_append_unique_case_insensitive(docFiles, found[fileIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
if (docFiles.length() > 1) {
|
||||
docFiles.sort(docs_browser_sort_case_insensitive);
|
||||
}
|
||||
|
||||
for (uint fileIndex = 0; fileIndex < docFiles.length(); fileIndex++) {
|
||||
labels.insert_last(docs_browser_format_label(docFiles[fileIndex]));
|
||||
paths.insert_last(docsBrowserDirectory + "/" + docFiles[fileIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
void docs_browser_add_entries(string[]@ labels, string[]@ paths, int[]@ types, const int typeValue = 1) {
|
||||
string[] docLabels;
|
||||
string[] docPaths;
|
||||
docs_browser_collect_entries(docLabels, docPaths);
|
||||
|
||||
for (uint entryIndex = 0; entryIndex < docLabels.length(); entryIndex++) {
|
||||
labels.insert_last(docLabels[entryIndex]);
|
||||
paths.insert_last(docPaths[entryIndex]);
|
||||
types.insert_last(typeValue);
|
||||
}
|
||||
}
|
||||
|
||||
void docs_browser_play_ui_sound(sound &inout soundObj, const string basePath) {
|
||||
string soundPath = resolve_audio_path(basePath);
|
||||
if (soundPath == "") return;
|
||||
|
||||
soundObj.close();
|
||||
if (!soundObj.load(soundPath)) return;
|
||||
soundObj.play();
|
||||
}
|
||||
|
||||
void docs_browser_run_menu(const string menuTitle = "Documents") {
|
||||
string[] labels;
|
||||
string[] paths;
|
||||
docs_browser_collect_entries(labels, paths);
|
||||
|
||||
docs_browser_speak(menuTitle + ".", true);
|
||||
if (labels.length() == 0) {
|
||||
docs_browser_speak("No documents found.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
int selection = 0;
|
||||
docs_browser_speak(labels[selection], true);
|
||||
|
||||
while (true) {
|
||||
wait(5);
|
||||
docs_browser_tick();
|
||||
|
||||
if (key_pressed(KEY_ESCAPE)) {
|
||||
docs_browser_speak("Closed.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_pressed(KEY_DOWN)) {
|
||||
docs_browser_play_ui_sound(docsBrowserMoveSound, docsBrowserMenuSoundDir + "/menu_move");
|
||||
selection++;
|
||||
if (selection >= int(labels.length())) {
|
||||
selection = docsBrowserWrap ? 0 : int(labels.length()) - 1;
|
||||
}
|
||||
docs_browser_speak(labels[selection], true);
|
||||
}
|
||||
|
||||
if (key_pressed(KEY_UP)) {
|
||||
docs_browser_play_ui_sound(docsBrowserMoveSound, docsBrowserMenuSoundDir + "/menu_move");
|
||||
selection--;
|
||||
if (selection < 0) {
|
||||
selection = docsBrowserWrap ? int(labels.length()) - 1 : 0;
|
||||
}
|
||||
docs_browser_speak(labels[selection], true);
|
||||
}
|
||||
|
||||
if (key_pressed(KEY_RETURN)) {
|
||||
docs_browser_play_ui_sound(docsBrowserSelectSound, docsBrowserMenuSoundDir + "/menu_select");
|
||||
file_viewer_file(paths[selection], labels[selection], true);
|
||||
docs_browser_speak(labels[selection], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user