mirror of
https://github.com/raysan5/raygui.git
synced 2025-12-25 10:22:33 -05:00
Update to raylib 4.2 (#223)
This commit is contained in:
@ -68,8 +68,7 @@ typedef struct {
|
|||||||
|
|
||||||
// Custom state variables (depend on development software)
|
// Custom state variables (depend on development software)
|
||||||
// NOTE: This variables should be added manually if required
|
// NOTE: This variables should be added manually if required
|
||||||
char **dirFiles;
|
FilePathList dirFiles;
|
||||||
int dirFilesCount;
|
|
||||||
|
|
||||||
char filterExt[256];
|
char filterExt[256];
|
||||||
|
|
||||||
@ -156,8 +155,6 @@ FileInfo *dirFilesIcon = NULL;
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Internal Module Functions Definition
|
// Internal Module Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Read all filenames from directory (supported file types)
|
|
||||||
static char **LoadDirectoryFiles(const char *dir, int *filesCount, char *filterExt);
|
|
||||||
// Read files in new path
|
// Read files in new path
|
||||||
static void ReloadDirectoryFiles(GuiFileDialogState *state);
|
static void ReloadDirectoryFiles(GuiFileDialogState *state);
|
||||||
|
|
||||||
@ -211,8 +208,7 @@ GuiFileDialogState InitGuiFileDialog(int width, int height, const char *initPath
|
|||||||
|
|
||||||
strcpy(state.filterExt, "all");
|
strcpy(state.filterExt, "all");
|
||||||
|
|
||||||
state.dirFilesCount = 0;
|
state.dirFiles.count = 0;
|
||||||
state.dirFiles = NULL; // NOTE: Loaded lazily on window active
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -234,13 +230,13 @@ void GuiFileDialog(GuiFileDialogState *state)
|
|||||||
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) dirFilesIcon[i] = (char *)RL_CALLOC(MAX_DIR_PATH_LENGTH, 1); // Max file name length
|
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) dirFilesIcon[i] = (char *)RL_CALLOC(MAX_DIR_PATH_LENGTH, 1); // Max file name length
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->dirFiles == NULL)
|
if (state->dirFiles.paths == NULL)
|
||||||
{
|
{
|
||||||
state->dirFiles = LoadDirectoryFiles(state->dirPathText, &state->dirFilesCount, state->filterExt);
|
state->dirFiles = LoadDirectoryFilesEx(state->dirPathText, state->filterExt, false);
|
||||||
|
|
||||||
for(int f = 0; f < state->dirFilesCount; f++)
|
for(int f = 0; f < state->dirFiles.count; f++)
|
||||||
{
|
{
|
||||||
if (strcmp(state->fileNameText, state->dirFiles[f]) == 0)
|
if (strcmp(state->fileNameText, state->dirFiles.paths[f]) == 0)
|
||||||
{
|
{
|
||||||
if (state->filesListActive != f) state->filesListScrollIndex = state->filesListActive = f; // Make it active and visible only on first call
|
if (state->filesListActive != f) state->filesListScrollIndex = state->filesListActive = f; // Make it active and visible only on first call
|
||||||
|
|
||||||
@ -292,9 +288,9 @@ void GuiFileDialog(GuiFileDialogState *state)
|
|||||||
// TODO: ListViewElements should be aligned left
|
// TODO: ListViewElements should be aligned left
|
||||||
# if defined(USE_CUSTOM_LISTVIEW_FILEINFO)
|
# if defined(USE_CUSTOM_LISTVIEW_FILEINFO)
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
state->filesListActive = GuiListViewFiles((Rectangle){ state->position.x + 10, state->position.y + 70, winWidth - 20, winHeight - 135 }, fileInfo, state->dirFilesCount, &state->itemFocused, &state->filesListScrollIndex, state->filesListActive);
|
state->filesListActive = GuiListViewFiles((Rectangle){ state->position.x + 10, state->position.y + 70, winWidth - 20, winHeight - 135 }, fileInfo, state->dirFiles.count, &state->itemFocused, &state->filesListScrollIndex, state->filesListActive);
|
||||||
# else
|
# else
|
||||||
state->filesListActive = GuiListViewEx((Rectangle){ state->position.x + 10, state->position.y + 70, winWidth - 20, winHeight - 135 }, (const char**)dirFilesIcon, state->dirFilesCount, &state->itemFocused, &state->filesListScrollIndex, state->filesListActive);
|
state->filesListActive = GuiListViewEx((Rectangle){ state->position.x + 10, state->position.y + 70, winWidth - 20, winHeight - 135 }, (const char**)dirFilesIcon, state->dirFiles.count, &state->itemFocused, &state->filesListScrollIndex, state->filesListActive);
|
||||||
# endif
|
# endif
|
||||||
GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, prevTextAlignment);
|
GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, prevTextAlignment);
|
||||||
GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, prevElementsHeight);
|
GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, prevElementsHeight);
|
||||||
@ -302,7 +298,7 @@ void GuiFileDialog(GuiFileDialogState *state)
|
|||||||
if ((state->filesListActive >= 0) && (state->filesListActive != state->prevFilesListActive))
|
if ((state->filesListActive >= 0) && (state->filesListActive != state->prevFilesListActive))
|
||||||
//&& (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_DPAD_A)))
|
//&& (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_DPAD_A)))
|
||||||
{
|
{
|
||||||
strcpy(state->fileNameText, state->dirFiles[state->filesListActive]);
|
strcpy(state->fileNameText, state->dirFiles.paths[state->filesListActive]);
|
||||||
|
|
||||||
if (DirectoryExists(TextFormat("%s/%s", state->dirPathText, state->fileNameText)))
|
if (DirectoryExists(TextFormat("%s/%s", state->dirPathText, state->fileNameText)))
|
||||||
{
|
{
|
||||||
@ -334,9 +330,9 @@ void GuiFileDialog(GuiFileDialogState *state)
|
|||||||
if (FileExists(TextFormat("%s/%s", state->dirPathText, state->fileNameText)))
|
if (FileExists(TextFormat("%s/%s", state->dirPathText, state->fileNameText)))
|
||||||
{
|
{
|
||||||
// Select filename from list view
|
// Select filename from list view
|
||||||
for (int i = 0; i < state->dirFilesCount; i++)
|
for (int i = 0; i < state->dirFiles.count; i++)
|
||||||
{
|
{
|
||||||
if (TextIsEqual(state->fileNameText, state->dirFiles[i]))
|
if (TextIsEqual(state->fileNameText, state->dirFiles.paths[i]))
|
||||||
{
|
{
|
||||||
state->filesListActive = i;
|
state->filesListActive = i;
|
||||||
strcpy(state->fileNameTextCopy, state->fileNameText);
|
strcpy(state->fileNameTextCopy, state->fileNameText);
|
||||||
@ -376,15 +372,17 @@ void GuiFileDialog(GuiFileDialogState *state)
|
|||||||
// Free dirFiles memory
|
// Free dirFiles memory
|
||||||
for (int i = 0; i < MAX_DIRECTORY_FILES; i++)
|
for (int i = 0; i < MAX_DIRECTORY_FILES; i++)
|
||||||
{
|
{
|
||||||
RL_FREE(state->dirFiles[i]);
|
|
||||||
RL_FREE(dirFilesIcon[i]);
|
RL_FREE(dirFilesIcon[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
RL_FREE(state->dirFiles);
|
UnloadDirectoryFiles(state->dirFiles);
|
||||||
|
state->dirFiles.count = 0;
|
||||||
|
state->dirFiles.capacity = 0;
|
||||||
|
state->dirFiles.paths = NULL;
|
||||||
|
|
||||||
RL_FREE(dirFilesIcon);
|
RL_FREE(dirFilesIcon);
|
||||||
|
|
||||||
dirFilesIcon = NULL;
|
dirFilesIcon = NULL;
|
||||||
state->dirFiles = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,107 +402,12 @@ static inline int FileCompare(const char *d1, const char *d2, const char *dir)
|
|||||||
return strcmp(d1, d2);
|
return strcmp(d1, d2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read all filenames from directory (supported file types)
|
|
||||||
static char **LoadDirectoryFiles(const char *dir, int *filesCount, char *filterExt)
|
|
||||||
{
|
|
||||||
int validFilesCount = 0;
|
|
||||||
char **validFiles = (char **)RL_CALLOC(MAX_DIRECTORY_FILES, sizeof(char *)); // Max files to read
|
|
||||||
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) validFiles[i] = (char *)RL_CALLOC(MAX_DIR_PATH_LENGTH, 1); // Max file name length
|
|
||||||
|
|
||||||
int filterExtCount = 0;
|
|
||||||
const char **extensions = GuiTextSplit(filterExt, &filterExtCount, NULL);
|
|
||||||
bool filterExtensions = true;
|
|
||||||
|
|
||||||
int dirFilesCount = 0;
|
|
||||||
char **files = LoadDirectoryFiles(dir, &dirFilesCount);
|
|
||||||
|
|
||||||
// Sort files and directories: dir by name + files by name
|
|
||||||
// https://en.wikibooks.org/wiki/Algorithm_Implementation/Sorting/Quicksort#C
|
|
||||||
if (dirFilesCount > 1)
|
|
||||||
{
|
|
||||||
const int MAX = 64;
|
|
||||||
unsigned int left = 0, stack[64], pos = 0, seed = rand(), len = dirFilesCount;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
for (; left + 1 < len; len++) // Sort left to len - 1
|
|
||||||
{
|
|
||||||
if (pos == MAX) len = stack[pos = 0]; // Stack overflow, reset
|
|
||||||
char *pivot = files[left + seed%(len - left)]; // Pick random pivot
|
|
||||||
seed = seed*69069 + 1; // Next pseudo-random number
|
|
||||||
stack[pos++] = len; // Sort right part later
|
|
||||||
|
|
||||||
for (unsigned int right = left - 1;;) // Inner loop: partitioning
|
|
||||||
{
|
|
||||||
while (FileCompare(files[++right], pivot, dir) < 0); // Look for greater element
|
|
||||||
while (FileCompare(pivot, files[--len], dir) < 0); // Look for smaller element
|
|
||||||
if (right >= len) break; // Partition point found?
|
|
||||||
char *temp = files[right];
|
|
||||||
files[right] = files[len]; // The only swap
|
|
||||||
files[len] = temp;
|
|
||||||
} // Partitioned, continue left part
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos == 0) break; // Stack empty?
|
|
||||||
left = len; // Left to right is sorted
|
|
||||||
len = stack[--pos]; // Get next range to sort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TextIsEqual(extensions[0], "all")) filterExtensions = false;
|
|
||||||
|
|
||||||
for (int i = 0; (i < dirFilesCount) && (validFilesCount < MAX_DIRECTORY_FILES); i++)
|
|
||||||
{
|
|
||||||
if (TextIsEqual(files[i], ".")) continue;
|
|
||||||
|
|
||||||
if (!filterExtensions)
|
|
||||||
{
|
|
||||||
strncpy(validFiles[validFilesCount], files[i], MAX_DIR_PATH_LENGTH);
|
|
||||||
|
|
||||||
// Only filter files by extensions, directories should be available
|
|
||||||
if (DirectoryExists(TextFormat("%s/%s", dir, files[i]))) strcpy(dirFilesIcon[validFilesCount], TextFormat("#%i#%s", 1, files[i]));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: Assign custom filetype icons depending on file extension (image, audio, text, video, models...)
|
|
||||||
|
|
||||||
if (IsFileExtension(files[i], ".png")) strcpy(dirFilesIcon[validFilesCount], TextFormat("#%i#%s", 12, files[i]));
|
|
||||||
else strcpy(dirFilesIcon[validFilesCount], TextFormat("#%i#%s", 10, files[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
validFilesCount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int j = 0; j < filterExtCount; j++)
|
|
||||||
{
|
|
||||||
// Check file type extensions supported
|
|
||||||
// NOTE: We just store valid files list
|
|
||||||
if (IsFileExtension(files[i], extensions[j]))
|
|
||||||
{
|
|
||||||
// TODO: Assign custom filetype icons depending on file extension (image, audio, text, video, models...)
|
|
||||||
|
|
||||||
if (IsFileExtension(files[i], ".png")) strcpy(dirFilesIcon[validFilesCount], TextFormat("#%i#%s", 12, files[i]));
|
|
||||||
else strcpy(dirFilesIcon[validFilesCount], TextFormat("#%i#%s", 10, files[i]));
|
|
||||||
|
|
||||||
validFilesCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UnloadDirectoryFiles();
|
|
||||||
|
|
||||||
*filesCount = validFilesCount;
|
|
||||||
return validFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read files in new path
|
// Read files in new path
|
||||||
static void ReloadDirectoryFiles(GuiFileDialogState *state)
|
static void ReloadDirectoryFiles(GuiFileDialogState *state)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) RL_FREE(state->dirFiles[i]);
|
UnloadDirectoryFiles(state->dirFiles);
|
||||||
RL_FREE(state->dirFiles);
|
|
||||||
|
|
||||||
state->dirFiles = LoadDirectoryFiles(state->dirPathText, &state->dirFilesCount, state->filterExt);
|
state->dirFiles = LoadDirectoryFilesEx(state->dirPathText, state->filterExt, false);
|
||||||
state->itemFocused = 0;
|
state->itemFocused = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,14 +66,13 @@ int main(int argc, char **argv)
|
|||||||
// Fonts drag & drop logic
|
// Fonts drag & drop logic
|
||||||
if (IsFileDropped())
|
if (IsFileDropped())
|
||||||
{
|
{
|
||||||
int count = 0;
|
FilePathList files = LoadDroppedFiles();
|
||||||
char **files = LoadDroppedFiles(&count);
|
|
||||||
|
|
||||||
if (IsFileExtension(files[0], ".ttf") ||
|
if (IsFileExtension(files.paths[0], ".ttf") ||
|
||||||
IsFileExtension(files[0], ".otf") ||
|
IsFileExtension(files.paths[0], ".otf") ||
|
||||||
IsFileExtension(files[0], ".fnt"))
|
IsFileExtension(files.paths[0], ".fnt"))
|
||||||
{
|
{
|
||||||
Font fnt = LoadFont(files[0]);
|
Font fnt = LoadFont(files.paths[0]);
|
||||||
|
|
||||||
if (fnt.texture.id != 0)
|
if (fnt.texture.id != 0)
|
||||||
{
|
{
|
||||||
@ -86,7 +85,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnloadDroppedFiles();
|
UnloadDroppedFiles(files);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ if (NOT raylib_FOUND)
|
|||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
raylib
|
raylib
|
||||||
GIT_REPOSITORY https://github.com/raysan5/raylib.git
|
GIT_REPOSITORY https://github.com/raysan5/raylib.git
|
||||||
GIT_TAG 0851960397f02a477d80eda2239f90fae14dec64
|
GIT_TAG 4.2.0
|
||||||
)
|
)
|
||||||
FetchContent_GetProperties(raylib)
|
FetchContent_GetProperties(raylib)
|
||||||
if (NOT raylib_POPULATED) # Have we downloaded raylib yet?
|
if (NOT raylib_POPULATED) # Have we downloaded raylib yet?
|
||||||
|
|||||||
Reference in New Issue
Block a user