-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathnuklear_console_file_system.h
More file actions
189 lines (153 loc) · 5.83 KB
/
nuklear_console_file_system.h
File metadata and controls
189 lines (153 loc) · 5.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/**
* File System for nuklear_console.
*
* Configuration:
* - NK_CONSOLE_FILE_ADD_FILES: Callback which is used to add files to the file widget, matching the signature of nk_console_file_add_files_tinydir().
* - NK_CONSOLE_ENABLE_TINYDIR: Use the tinydir library to list files in a directory. https://github.com/cxong/tinydir
* - NK_CONSOLE_ENABLE_RAYLIB or RAYLIB_VERSION: When defined, will use raylib to enumerate the files. https://github.com/RobLoach/raylib-nuklear
* - NK_CONSOLE_ENABLE_SDL3 or SDL_MAJOR_VERSION == 3: When defined, will use SDL3 to enumerate the files. https://libsdl.org
* - When no file system is enabled, clicking on the Select File button will show an error message.
*/
#ifndef NK_CONSOLE_FILE_SYSTEM_H__
#define NK_CONSOLE_FILE_SYSTEM_H__
#if defined(__cplusplus)
extern "C" {
#endif
// Nothing.
#if defined(__cplusplus)
}
#endif
#endif // NK_CONSOLE_FILE_SYSTEM_H__
#if defined(NK_CONSOLE_IMPLEMENTATION) && !defined(NK_CONSOLE_HEADER_ONLY)
#ifndef NK_CONSOLE_FILE_SYSTEM_IMPLEMENTATION_ONCE
#define NK_CONSOLE_FILE_SYSTEM_IMPLEMENTATION_ONCE
#if defined(__cplusplus)
extern "C" {
#endif
// TODO: Allow disabling tinydir
#ifndef NK_CONSOLE_FILE_ADD_FILES
#ifdef NK_CONSOLE_ENABLE_TINYDIR
#ifndef NK_CONSOLE_FILE_ADD_FILES_TINYDIR_H
#define NK_CONSOLE_FILE_ADD_FILES_TINYDIR_H "vendor/tinydir/tinydir.h"
#endif // NK_CONSOLE_FILE_ADD_FILES_TINYDIR_H
#ifndef NK_CONSOLE_FILE_ADD_FILES_TINYDIR_SKIP
// tinydir uses the same memory function signatures as cvector.
#ifndef _TINYDIR_MALLOC
#define _TINYDIR_MALLOC cvector_clib_malloc
#endif // _TINYDIR_MALLOC
#ifndef _TINYDIR_FREE
#define _TINYDIR_FREE cvector_clib_free
#endif // _TINYDIR_FREE
#include NK_CONSOLE_FILE_ADD_FILES_TINYDIR_H
#endif // NK_CONSOLE_FILE_ADD_FILES_TINYDIR_SKIP
/**
* Iterate through the files in the given directory, and add the contents as widgets.
*
* @param parent The file widget.
* @param directory The directory to enumerate.
*
* @return True if there were entries added.
*
* @see nk_console_file_add_entry()
*/
static nk_bool nk_console_file_add_files_tinydir(nk_console* parent, const char* directory) {
if (parent == NULL || directory == NULL) {
return nk_false;
}
tinydir_dir dir;
if (tinydir_open_sorted(&dir, directory) == -1) {
return nk_false;
}
nk_bool result = nk_false;
// Iterate through the files and add each entry.
for (size_t i = 0; i < dir.n_files; i++) {
tinydir_file file;
tinydir_readfile_n(&dir, &file, i);
if (nk_console_file_add_entry(parent, file.name, file.is_dir == 0 ? nk_false : nk_true) != NULL) {
result = nk_true;
}
}
// Close the directory.
tinydir_close(&dir);
return result;
}
// Tell the file widget to use the tinydir file system.
#define NK_CONSOLE_FILE_ADD_FILES nk_console_file_add_files_tinydir
// Raylib
#elif defined(NK_CONSOLE_ENABLE_RAYLIB) || defined(RAYLIB_VERSION)
/**
* nuklear_console_file callback to iterate through a directory and ad all entries from the given path.
*
* @param console The parent files widget.
* @param path The path to enumerate.
*
* @return True if there were entries that were added.
*
* @see nk_console_file_add_entry()
*/
static nk_bool nk_console_file_add_files_raylib(nk_console* console, const char* path) {
FilePathList filePathList = LoadDirectoryFiles(path);
nk_bool result = nk_false;
// Directories first, then files (two passes to group them).
for (int pass = 0; pass < 2; pass++) {
nk_bool want_dir = (pass == 0) ? nk_true : nk_false;
for (int i = 0; i < (int)filePathList.count; i++) {
nk_bool is_dir = DirectoryExists(filePathList.paths[i]) ? nk_true : nk_false;
if (is_dir != want_dir) {
continue;
}
if (nk_console_file_add_entry(console, filePathList.paths[i], is_dir) != NULL) {
result = nk_true;
}
}
}
UnloadDirectoryFiles(filePathList);
return result;
}
// Tell the file widget to use the raylib file system.
#define NK_CONSOLE_FILE_ADD_FILES nk_console_file_add_files_raylib
// SDL3
#elif defined(NK_CONSOLE_ENABLE_SDL3) || (defined(SDL_MAJOR_VERSION) && SDL_MAJOR_VERSION == 3)
static SDL_EnumerationResult SDLCALL nk_console_file_add_files_sdl3_callback(void* userdata, const char* dirname, const char* fname) {
// Build the full path.
char fullpath[4096];
size_t dirlen = SDL_strlen(dirname);
if (dirlen > 0 && dirname[dirlen - 1] == '/') {
SDL_snprintf(fullpath, sizeof(fullpath), "%s%s", dirname, fname);
} else {
SDL_snprintf(fullpath, sizeof(fullpath), "%s/%s", dirname, fname);
}
// Determine if the entry is a directory.
SDL_PathInfo info;
nk_bool is_dir = nk_false;
if (SDL_GetPathInfo(fullpath, &info)) {
is_dir = (info.type == SDL_PATHTYPE_DIRECTORY) ? nk_true : nk_false;
}
nk_console_file_add_entry((nk_console*)userdata, fullpath, is_dir);
return SDL_ENUM_CONTINUE;
}
/**
* nuklear_console_file callback to iterate through a directory and add all entries from the given path using SDL3.
*
* @param console The parent files widget.
* @param path The path to enumerate.
*
* @return True if there were entries that were added.
*
* @see nk_console_file_add_entry()
*/
static nk_bool nk_console_file_add_files_sdl3(nk_console* console, const char* path) {
if (console == NULL || path == NULL) {
return nk_false;
}
return SDL_EnumerateDirectory(path, nk_console_file_add_files_sdl3_callback, console) ? nk_true : nk_false;
}
// Tell the file widget to use the SDL3 file system.
#define NK_CONSOLE_FILE_ADD_FILES nk_console_file_add_files_sdl3
#endif // NK_CONSOLE_ENABLE_TINYDIR
#endif // NK_CONSOLE_FILE_ADD_FILES
#if defined(__cplusplus)
}
#endif
#endif // NK_CONSOLE_FILE_SYSTEM_IMPLEMENTATION_ONCE
#endif // NK_CONSOLE_IMPLEMENTATION