|
void GuiLoadStyle(const char *fileName) |
|
{ |
|
#define MAX_LINE_BUFFER_SIZE 256 |
|
|
|
bool tryBinary = false; |
|
if (!guiStyleLoaded) GuiLoadStyleDefault(); |
|
|
|
// Try reading the files as text file first |
|
FILE *rgsFile = fopen(fileName, "rt"); |
|
|
|
if (rgsFile != NULL) |
|
{ |
|
char buffer[MAX_LINE_BUFFER_SIZE] = { 0 }; |
|
fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile); |
|
|
|
if (buffer[0] == '#') |
|
{ |
|
int controlId = 0; |
|
int propertyId = 0; |
|
unsigned int propertyValue = 0; |
|
|
|
while (!feof(rgsFile)) |
|
{ |
|
switch (buffer[0]) |
|
{ |
|
case 'p': |
|
{ |
|
// Style property: p <control_id> <property_id> <property_value> <property_name> |
|
|
|
sscanf(buffer, "p %d %d 0x%x", &controlId, &propertyId, &propertyValue); |
|
GuiSetStyle(controlId, propertyId, (int)propertyValue); |
|
|
|
} break; |
|
case 'f': |
|
{ |
|
// Style font: f <gen_font_size> <charmap_file> <font_file> |
|
|
|
int fontSize = 0; |
|
char charmapFileName[256] = { 0 }; |
|
char fontFileName[256] = { 0 }; |
|
sscanf(buffer, "f %d %s %[^\r\n]s", &fontSize, charmapFileName, fontFileName); |
|
|
|
Font font = { 0 }; |
|
int *codepoints = NULL; |
|
int codepointCount = 0; |
|
|
|
if (charmapFileName[0] != '0') |
|
{ |
|
// Load text data from file |
|
// NOTE: Expected an UTF-8 array of codepoints, no separation |
|
char *textData = LoadFileText(TextFormat("%s/%s", GetDirectoryPath(fileName), charmapFileName)); |
|
codepoints = LoadCodepoints(textData, &codepointCount); |
|
UnloadFileText(textData); |
|
} |
|
|
|
if (fontFileName[0] != '\0') |
|
{ |
|
// In case a font is already loaded and it is not default internal font, unload it |
|
if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture); |
|
|
|
if (codepointCount > 0) font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, codepoints, codepointCount); |
|
else font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, NULL, 0); // Default to 95 standard codepoints |
|
} |
|
|
|
// If font texture not properly loaded, revert to default font and size/spacing |
|
if (font.texture.id == 0) |
|
{ |
|
font = GetFontDefault(); |
|
GuiSetStyle(DEFAULT, TEXT_SIZE, 10); |
|
GuiSetStyle(DEFAULT, TEXT_SPACING, 1); |
|
} |
|
|
|
UnloadCodepoints(codepoints); |
|
|
|
if ((font.texture.id > 0) && (font.glyphCount > 0)) GuiSetFont(font); |
|
|
|
} break; |
|
default: break; |
|
} |
|
|
|
fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile); |
|
} |
|
} |
|
else tryBinary = true; |
|
|
|
fclose(rgsFile); |
|
} |
|
|
|
if (tryBinary) |
|
{ |
|
rgsFile = fopen(fileName, "rb"); |
|
|
|
if (rgsFile != NULL) |
|
{ |
|
fseek(rgsFile, 0, SEEK_END); |
|
int fileDataSize = ftell(rgsFile); |
|
fseek(rgsFile, 0, SEEK_SET); |
|
|
|
if (fileDataSize > 0) |
|
{ |
|
unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); |
|
if (fileData != NULL) |
|
{ |
|
fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); |
|
|
|
GuiLoadStyleFromMemory(fileData, fileDataSize); |
Request
I would like to use the
GuiLoadStyleFromMemoryfunction.Currently, the
GuiLoadStyleFromMemoryfunction is private and not available to usercode.raygui/src/raygui.h
Line 4848 in 6d2b28f
They must resort to
GuiLoadStyleFromFile(which, ultimately, still usesGuiLoadStyleFromMemory):raygui/src/raygui.h
Lines 4372 to 4477 in 6d2b28f
While it seems that the body of
GuiLoadStyleFromMemoryhas some hintsraygui/src/raygui.h
Lines 4890 to 4892 in 6d2b28f
about its implementation being highly dependant on
raylib, this does not change the fact that the same code section can be reached publicly with theFromFilemethod.This limitation ultimately limits the ability to embed styles in programs using
raygui.Switching between theme definitions obtained from embedding the style files requires some funny code to:
Which is prone to error and arguably just worse than exposing the existing, and ultimately already used (same-control-flow-reachable),
GuiLoadStyleFromMemory.Usecase
I have prepared a draft PR for my usecase, involving the rust bindings.
uuid, which is currently needed only for this tempfile-load-trash chicanery.Proposed solutions
I don't really see a real drawback to exposing the function since the same logic is reachable with the
GuiLoadStyleFromFile()method.As a side note, it seems that currently the
dataSizeargument is not used.If the function is deemed "unsafe" for some reason, I would like at least a specific build flag to turn a macro guard on an expose it...
But ultimately, having this API just available, without jumping through hoops (for no better or worse guarantees), would be better.