mirror of
https://github.com/raysan5/raylib.git
synced 2026-02-20 20:49:17 -05:00
Compare commits
12 Commits
4a3c49cdcb
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c519e9f566 | |||
| 09f22f3c86 | |||
| 29b9c050c7 | |||
| 0343cb6a37 | |||
| d148d9515b | |||
| 19e6352d37 | |||
| d03a59ca3e | |||
| 2454b3ed4b | |||
| d996bf2bbd | |||
| f33823cefe | |||
| 0aacd330d4 | |||
| ce617cd814 |
@ -81,27 +81,6 @@ int main(void)
|
||||
GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 50 },
|
||||
files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused);
|
||||
|
||||
/*
|
||||
for (int i = 0; i < (int)files.count; i++)
|
||||
{
|
||||
Color color = Fade(LIGHTGRAY, 0.3f);
|
||||
|
||||
if (!IsPathFile(files.paths[i]) && DirectoryExists(files.paths[i]))
|
||||
{
|
||||
if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, ""))
|
||||
{
|
||||
TextCopy(directory, files.paths[i]);
|
||||
UnloadDirectoryFiles(files);
|
||||
files = LoadDirectoryFiles(directory);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DrawRectangle(0, 85 + 40*i, screenWidth, 40, color);
|
||||
DrawText(GetFileName(files.paths[i]), 120, 100 + 40*i, 10, GRAY);
|
||||
}
|
||||
*/
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
|
||||
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
|
||||
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
|
||||
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
|
||||
|
||||
// Basic controls set
|
||||
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
|
||||
|
||||
// Advance controls set
|
||||
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
|
||||
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
|
||||
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
|
||||
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
|
||||
static int ColorToInt(Color color); // Returns hexadecimal value for a Color
|
||||
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static int TextToInteger(const char *text); // Get integer value from text
|
||||
static float TextToFloat(const char *text); // Get float value from text
|
||||
|
||||
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
|
||||
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
|
||||
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
|
||||
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
|
||||
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
|
||||
|
||||
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
|
||||
|
||||
// Tab Bar control
|
||||
// NOTE: Using GuiToggle() for the TABS
|
||||
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
|
||||
{
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 148
|
||||
|
||||
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
|
||||
// Get substrings items from text (items pointers)
|
||||
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
|
||||
int prevRow = rows[0];
|
||||
|
||||
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers)
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
if (*active < 0) *active = 0;
|
||||
else if (*active > (itemCount - 1)) *active = itemCount - 1;
|
||||
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
Rectangle boundsOpen = bounds;
|
||||
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
|
||||
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
{
|
||||
int result = 0;
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
}
|
||||
|
||||
// List View control with extended parameters
|
||||
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
{
|
||||
int result = 0;
|
||||
GuiState state = guiState;
|
||||
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
|
||||
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
|
||||
int result = -1;
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
||||
|
||||
// Get text divided into lines (by line-breaks '\n')
|
||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||
static const char **GetTextLines(const char *text, int *count)
|
||||
static char **GetTextLines(const char *text, int *count)
|
||||
{
|
||||
#define RAYGUI_MAX_TEXT_LINES 128
|
||||
|
||||
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||
|
||||
int textLength = (int)strlen(text);
|
||||
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
|
||||
lines[0] = text;
|
||||
*count = 1;
|
||||
|
||||
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
{
|
||||
if (text[i] == '\n')
|
||||
if ((text[i] == '\n') && ((i + 1) < textLength))
|
||||
{
|
||||
k++;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
lines[*count] = &text[i + 1];
|
||||
*count += 1;
|
||||
}
|
||||
}
|
||||
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||
int lineCount = 0;
|
||||
const char **lines = GetTextLines(text, &lineCount);
|
||||
char **lines = GetTextLines(text, &lineCount);
|
||||
|
||||
// Text style variables
|
||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
|
||||
|
||||
// Split controls text into multiple strings
|
||||
// Also check for multiple columns (required by GuiToggleGroup())
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
|
||||
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
|
||||
#endif
|
||||
|
||||
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
|
||||
|
||||
result[0] = buffer;
|
||||
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
|
||||
}
|
||||
|
||||
// Split string into multiple strings
|
||||
const char **TextSplit(const char *text, char delimiter, int *count)
|
||||
char **TextSplit(const char *text, char delimiter, int *count)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
|
||||
@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
|
||||
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
|
||||
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
|
||||
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
|
||||
|
||||
// Basic controls set
|
||||
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
|
||||
|
||||
// Advance controls set
|
||||
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
|
||||
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
|
||||
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
|
||||
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
|
||||
static int ColorToInt(Color color); // Returns hexadecimal value for a Color
|
||||
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static int TextToInteger(const char *text); // Get integer value from text
|
||||
static float TextToFloat(const char *text); // Get float value from text
|
||||
|
||||
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
|
||||
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
|
||||
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
|
||||
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
|
||||
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
|
||||
|
||||
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
|
||||
|
||||
// Tab Bar control
|
||||
// NOTE: Using GuiToggle() for the TABS
|
||||
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
|
||||
{
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 148
|
||||
|
||||
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
|
||||
// Get substrings items from text (items pointers)
|
||||
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
|
||||
int prevRow = rows[0];
|
||||
|
||||
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers)
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
if (*active < 0) *active = 0;
|
||||
else if (*active > (itemCount - 1)) *active = itemCount - 1;
|
||||
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
Rectangle boundsOpen = bounds;
|
||||
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
|
||||
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
{
|
||||
int result = 0;
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
}
|
||||
|
||||
// List View control with extended parameters
|
||||
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
{
|
||||
int result = 0;
|
||||
GuiState state = guiState;
|
||||
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
|
||||
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
|
||||
int result = -1;
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
||||
|
||||
// Get text divided into lines (by line-breaks '\n')
|
||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||
static const char **GetTextLines(const char *text, int *count)
|
||||
static char **GetTextLines(const char *text, int *count)
|
||||
{
|
||||
#define RAYGUI_MAX_TEXT_LINES 128
|
||||
|
||||
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||
|
||||
int textLength = (int)strlen(text);
|
||||
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
|
||||
lines[0] = text;
|
||||
*count = 1;
|
||||
|
||||
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
{
|
||||
if (text[i] == '\n')
|
||||
if ((text[i] == '\n') && ((i + 1) < textLength))
|
||||
{
|
||||
k++;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
lines[*count] = &text[i + 1];
|
||||
*count += 1;
|
||||
}
|
||||
}
|
||||
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||
int lineCount = 0;
|
||||
const char **lines = GetTextLines(text, &lineCount);
|
||||
char **lines = GetTextLines(text, &lineCount);
|
||||
|
||||
// Text style variables
|
||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
|
||||
|
||||
// Split controls text into multiple strings
|
||||
// Also check for multiple columns (required by GuiToggleGroup())
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
|
||||
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
|
||||
#endif
|
||||
|
||||
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
|
||||
|
||||
result[0] = buffer;
|
||||
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
|
||||
}
|
||||
|
||||
// Split string into multiple strings
|
||||
const char **TextSplit(const char *text, char delimiter, int *count)
|
||||
char **TextSplit(const char *text, char delimiter, int *count)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
|
||||
@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
|
||||
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
|
||||
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
|
||||
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
|
||||
|
||||
// Basic controls set
|
||||
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
|
||||
|
||||
// Advance controls set
|
||||
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
|
||||
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
|
||||
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
|
||||
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
|
||||
static int ColorToInt(Color color); // Returns hexadecimal value for a Color
|
||||
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static int TextToInteger(const char *text); // Get integer value from text
|
||||
static float TextToFloat(const char *text); // Get float value from text
|
||||
|
||||
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
|
||||
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
|
||||
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
|
||||
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
|
||||
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
|
||||
|
||||
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
|
||||
|
||||
// Tab Bar control
|
||||
// NOTE: Using GuiToggle() for the TABS
|
||||
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
|
||||
{
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 148
|
||||
|
||||
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
|
||||
// Get substrings items from text (items pointers)
|
||||
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
|
||||
int prevRow = rows[0];
|
||||
|
||||
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers)
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
if (*active < 0) *active = 0;
|
||||
else if (*active > (itemCount - 1)) *active = itemCount - 1;
|
||||
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
Rectangle boundsOpen = bounds;
|
||||
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
|
||||
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
{
|
||||
int result = 0;
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
}
|
||||
|
||||
// List View control with extended parameters
|
||||
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
{
|
||||
int result = 0;
|
||||
GuiState state = guiState;
|
||||
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
|
||||
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
|
||||
int result = -1;
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
||||
|
||||
// Get text divided into lines (by line-breaks '\n')
|
||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||
static const char **GetTextLines(const char *text, int *count)
|
||||
static char **GetTextLines(const char *text, int *count)
|
||||
{
|
||||
#define RAYGUI_MAX_TEXT_LINES 128
|
||||
|
||||
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||
|
||||
int textLength = (int)strlen(text);
|
||||
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
|
||||
lines[0] = text;
|
||||
*count = 1;
|
||||
|
||||
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
{
|
||||
if (text[i] == '\n')
|
||||
if ((text[i] == '\n') && ((i + 1) < textLength))
|
||||
{
|
||||
k++;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
lines[*count] = &text[i + 1];
|
||||
*count += 1;
|
||||
}
|
||||
}
|
||||
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||
int lineCount = 0;
|
||||
const char **lines = GetTextLines(text, &lineCount);
|
||||
char **lines = GetTextLines(text, &lineCount);
|
||||
|
||||
// Text style variables
|
||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
|
||||
|
||||
// Split controls text into multiple strings
|
||||
// Also check for multiple columns (required by GuiToggleGroup())
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
|
||||
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
|
||||
#endif
|
||||
|
||||
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
|
||||
|
||||
result[0] = buffer;
|
||||
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
|
||||
}
|
||||
|
||||
// Split string into multiple strings
|
||||
const char **TextSplit(const char *text, char delimiter, int *count)
|
||||
char **TextSplit(const char *text, char delimiter, int *count)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
|
||||
@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
|
||||
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
|
||||
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
|
||||
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
|
||||
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
|
||||
|
||||
// Basic controls set
|
||||
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
|
||||
|
||||
// Advance controls set
|
||||
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
|
||||
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
|
||||
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
|
||||
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
|
||||
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
|
||||
static int ColorToInt(Color color); // Returns hexadecimal value for a Color
|
||||
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
static int TextToInteger(const char *text); // Get integer value from text
|
||||
static float TextToFloat(const char *text); // Get float value from text
|
||||
|
||||
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
|
||||
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
|
||||
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
|
||||
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
|
||||
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
|
||||
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
|
||||
|
||||
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
|
||||
|
||||
// Tab Bar control
|
||||
// NOTE: Using GuiToggle() for the TABS
|
||||
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
|
||||
{
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 148
|
||||
|
||||
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
|
||||
// Get substrings items from text (items pointers)
|
||||
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, rows);
|
||||
|
||||
int prevRow = rows[0];
|
||||
|
||||
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers)
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
if (*active < 0) *active = 0;
|
||||
else if (*active > (itemCount - 1)) *active = itemCount - 1;
|
||||
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
|
||||
|
||||
// Get substrings items from text (items pointers, lengths and count)
|
||||
int itemCount = 0;
|
||||
const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
char **items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
Rectangle boundsOpen = bounds;
|
||||
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
|
||||
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
{
|
||||
int result = 0;
|
||||
int itemCount = 0;
|
||||
const char **items = NULL;
|
||||
char **items = NULL;
|
||||
|
||||
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
|
||||
|
||||
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
|
||||
}
|
||||
|
||||
// List View control with extended parameters
|
||||
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
|
||||
{
|
||||
int result = 0;
|
||||
GuiState state = guiState;
|
||||
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
|
||||
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
|
||||
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
|
||||
int result = -1;
|
||||
|
||||
int buttonCount = 0;
|
||||
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
|
||||
Rectangle buttonBounds = { 0 };
|
||||
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
|
||||
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
||||
|
||||
// Get text divided into lines (by line-breaks '\n')
|
||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||
static const char **GetTextLines(const char *text, int *count)
|
||||
static char **GetTextLines(const char *text, int *count)
|
||||
{
|
||||
#define RAYGUI_MAX_TEXT_LINES 128
|
||||
|
||||
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||
|
||||
int textLength = (int)strlen(text);
|
||||
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
|
||||
lines[0] = text;
|
||||
*count = 1;
|
||||
|
||||
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
{
|
||||
if (text[i] == '\n')
|
||||
if ((text[i] == '\n') && ((i + 1) < textLength))
|
||||
{
|
||||
k++;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
lines[*count] = &text[i + 1];
|
||||
*count += 1;
|
||||
}
|
||||
}
|
||||
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||
int lineCount = 0;
|
||||
const char **lines = GetTextLines(text, &lineCount);
|
||||
char **lines = GetTextLines(text, &lineCount);
|
||||
|
||||
// Text style variables
|
||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
|
||||
|
||||
// Split controls text into multiple strings
|
||||
// Also check for multiple columns (required by GuiToggleGroup())
|
||||
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
|
||||
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
|
||||
#endif
|
||||
|
||||
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
|
||||
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
|
||||
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
|
||||
|
||||
result[0] = buffer;
|
||||
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
|
||||
}
|
||||
|
||||
// Split string into multiple strings
|
||||
const char **TextSplit(const char *text, char delimiter, int *count)
|
||||
char **TextSplit(const char *text, char delimiter, int *count)
|
||||
{
|
||||
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
|
||||
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "reasings.h" // Required for easing functions
|
||||
#include "reasings.h" // Required for: easing functions
|
||||
|
||||
#define FONT_SIZE 20
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@ int main(void)
|
||||
float hue = t*t;
|
||||
float saturation = t;
|
||||
float value = t;
|
||||
|
||||
palette[i] = ColorFromHSV(250.0f + 150.0f*hue, saturation, value);
|
||||
}
|
||||
|
||||
@ -66,11 +67,9 @@ int main(void)
|
||||
// Grow flameRoot
|
||||
for (int x = 2; x < flameWidth; x++)
|
||||
{
|
||||
unsigned char flame = flameRootBuffer[x];
|
||||
if (flame == 255) continue;
|
||||
int flame = (int)flameRootBuffer[x];
|
||||
flame += GetRandomValue(0, 2);
|
||||
if (flame > 255) flame = 255;
|
||||
flameRootBuffer[x] = flame;
|
||||
flameRootBuffer[x] = (flame > 255)? 255: (unsigned char)flame;
|
||||
}
|
||||
|
||||
// Transfer flameRoot to indexBuffer
|
||||
@ -83,8 +82,7 @@ int main(void)
|
||||
// Clear top row, because it can't move any higher
|
||||
for (int x = 0; x < imageWidth; x++)
|
||||
{
|
||||
if (indexBuffer[x] == 0) continue;
|
||||
indexBuffer[x] = 0;
|
||||
if (indexBuffer[x] != 0) indexBuffer[x] = 0;
|
||||
}
|
||||
|
||||
// Skip top row, it is already cleared
|
||||
@ -94,18 +92,22 @@ int main(void)
|
||||
{
|
||||
unsigned int i = x + y*imageWidth;
|
||||
unsigned char colorIndex = indexBuffer[i];
|
||||
if (colorIndex == 0) continue;
|
||||
|
||||
// Move pixel a row above
|
||||
indexBuffer[i] = 0;
|
||||
int moveX = GetRandomValue(0, 2) - 1;
|
||||
int newX = x + moveX;
|
||||
if (newX < 0 || newX >= imageWidth) continue;
|
||||
if (colorIndex != 0)
|
||||
{
|
||||
// Move pixel a row above
|
||||
indexBuffer[i] = 0;
|
||||
int moveX = GetRandomValue(0, 2) - 1;
|
||||
int newX = x + moveX;
|
||||
|
||||
unsigned int iabove = i - imageWidth + moveX;
|
||||
int decay = GetRandomValue(0, 3);
|
||||
colorIndex -= (decay < colorIndex)? decay : colorIndex;
|
||||
indexBuffer[iabove] = colorIndex;
|
||||
if ((newX > 0) && (newX < imageWidth))
|
||||
{
|
||||
unsigned int iabove = i - imageWidth + moveX;
|
||||
int decay = GetRandomValue(0, 3);
|
||||
colorIndex -= (decay < colorIndex)? decay : colorIndex;
|
||||
indexBuffer[iabove] = colorIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +119,7 @@ int main(void)
|
||||
unsigned int i = x + y*imageWidth;
|
||||
unsigned char colorIndex = indexBuffer[i];
|
||||
Color col = palette[colorIndex];
|
||||
|
||||
ImageDrawPixel(&screenImage, x, y, col);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2016,6 +2016,15 @@ int InitPlatform(void)
|
||||
// Init window
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
platform.window = SDL_CreateWindow(CORE.Window.title, CORE.Window.screen.width, CORE.Window.screen.height, flags);
|
||||
|
||||
|
||||
// NOTE: SDL3 no longer enables text input by default,
|
||||
// it is needed to be enabled manually to keep GetCharPressed() working
|
||||
// REF: https://github.com/libsdl-org/SDL/commit/72fc6f86e5d605a3787222bc7dc18c5379047f4a
|
||||
const char *enableOSK = SDL_GetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD);
|
||||
if (enableOSK == NULL) SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0");
|
||||
if (!SDL_StartTextInput(platform.window)) TRACELOG(LOG_WARNING, "SDL: Failed to start text input: %s", SDL_GetError());
|
||||
if (enableOSK == NULL) SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, NULL);
|
||||
#else
|
||||
platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags);
|
||||
#endif
|
||||
|
||||
92
src/raudio.c
92
src/raudio.c
@ -295,6 +295,10 @@ typedef struct tagBITMAPINFOHEADER {
|
||||
#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Audio pool channels
|
||||
#endif
|
||||
|
||||
#ifndef AUDIO_BUFFER_RESIDUAL_CAPACITY
|
||||
#define AUDIO_BUFFER_RESIDUAL_CAPACITY 8 // In PCM frames. For resampling and pitch shifting.
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -337,6 +341,8 @@ typedef enum {
|
||||
// Audio buffer struct
|
||||
struct rAudioBuffer {
|
||||
ma_data_converter converter; // Audio data converter
|
||||
unsigned char* converterResidual; // Cached residual input frames for use by the converter
|
||||
unsigned int converterResidualCount; // The number of valid frames sitting in converterResidual
|
||||
|
||||
AudioCallback callback; // Audio buffer callback for buffer filling on audio threads
|
||||
rAudioProcessor *processor; // Audio processor
|
||||
@ -586,6 +592,15 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// A cache for use by the converter is necessary when resampling because
|
||||
// when generating output frames a different number of input frames will
|
||||
// be consumed. Any residual input frames need to be kept track of to
|
||||
// ensure there are no discontinuities. Since raylib supports pitch
|
||||
// shifting, which is done through resampling, a cache will always be
|
||||
// required. This will be kept relatively small to avoid too much wastage.
|
||||
audioBuffer->converterResidualCount = 0;
|
||||
audioBuffer->converterResidual = (unsigned char*)RL_CALLOC(AUDIO_BUFFER_RESIDUAL_CAPACITY*ma_get_bytes_per_frame(format, channels), 1);
|
||||
|
||||
// Init audio buffer values
|
||||
audioBuffer->volume = 1.0f;
|
||||
audioBuffer->pitch = 1.0f;
|
||||
@ -621,6 +636,7 @@ void UnloadAudioBuffer(AudioBuffer *buffer)
|
||||
{
|
||||
UntrackAudioBuffer(buffer);
|
||||
ma_data_converter_uninit(&buffer->converter, NULL);
|
||||
RL_FREE(buffer->converterResidual);
|
||||
RL_FREE(buffer->data);
|
||||
RL_FREE(buffer);
|
||||
}
|
||||
@ -705,7 +721,7 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
|
||||
// Note that this changes the duration of the sound:
|
||||
// - higher pitches will make the sound faster
|
||||
// - lower pitches make it slower
|
||||
ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.sampleRateOut/pitch);
|
||||
ma_uint32 outputSampleRate = (ma_uint32)((float)AUDIO.System.device.sampleRate/pitch);
|
||||
ma_data_converter_set_rate(&buffer->converter, buffer->converter.sampleRateIn, outputSampleRate);
|
||||
|
||||
buffer->pitch = pitch;
|
||||
@ -2456,38 +2472,78 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
|
||||
// NOTE: Continuously converting data from the AudioBuffer's internal format to the mixing format,
|
||||
// which should be defined by the output format of the data converter.
|
||||
// This is done until frameCount frames have been output.
|
||||
// The important detail to remember is that more data than required should neeveer be read,
|
||||
// for the specified number of output frames.
|
||||
// This can be achieved with ma_data_converter_get_required_input_frame_count()
|
||||
ma_uint32 bpf = ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
|
||||
ma_uint8 inputBuffer[4096] = { 0 };
|
||||
ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
|
||||
ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/bpf;
|
||||
|
||||
ma_uint32 totalOutputFramesProcessed = 0;
|
||||
while (totalOutputFramesProcessed < frameCount)
|
||||
{
|
||||
float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut);
|
||||
ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed;
|
||||
ma_uint64 inputFramesToProcessThisIteration = 0;
|
||||
|
||||
(void)ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration, &inputFramesToProcessThisIteration);
|
||||
if (inputFramesToProcessThisIteration > inputBufferFrameCap)
|
||||
// Process any residual input frames from the previous read first.
|
||||
if (audioBuffer->converterResidualCount > 0)
|
||||
{
|
||||
inputFramesToProcessThisIteration = inputBufferFrameCap;
|
||||
ma_uint64 inputFramesProcessedThisIteration = audioBuffer->converterResidualCount;
|
||||
ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
|
||||
ma_data_converter_process_pcm_frames(&audioBuffer->converter, audioBuffer->converterResidual, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
|
||||
|
||||
// Make sure the data in the cache is consumed. This can be optimized to use a cursor instead of a memmove().
|
||||
memmove(audioBuffer->converterResidual, audioBuffer->converterResidual + inputFramesProcessedThisIteration*bpf, (size_t)(AUDIO_BUFFER_RESIDUAL_CAPACITY - inputFramesProcessedThisIteration) * bpf);
|
||||
audioBuffer->converterResidualCount -= (ma_uint32)inputFramesProcessedThisIteration; // Safe cast
|
||||
|
||||
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; // Safe cast
|
||||
}
|
||||
else
|
||||
{
|
||||
// Getting here means there are no residual frames from the previous read. Fresh data can now be
|
||||
// pulled from the AudioBuffer and processed.
|
||||
//
|
||||
// A best guess needs to be used made to determine how many input frames to pull from the
|
||||
// buffer. There are three possible outcomes: 1) exact; 2) underestimated; 3) overestimated.
|
||||
//
|
||||
// When the guess is exactly correct or underestimated there is nothing special to handle - it'll be
|
||||
// handled naturally by the loop.
|
||||
//
|
||||
// When the guess is overestimated, that's when it gets more complicated. In this case, any overflow
|
||||
// needs to be stored in a buffer for later processing by the next read.
|
||||
ma_uint32 estimatedInputFrameCount = (ma_uint32)(((float)audioBuffer->converter.resampler.sampleRateIn / audioBuffer->converter.resampler.sampleRateOut) * outputFramesToProcessThisIteration);
|
||||
if (estimatedInputFrameCount == 0)
|
||||
{
|
||||
estimatedInputFrameCount = 1; // Make sure at least one input frame is read.
|
||||
}
|
||||
|
||||
float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut);
|
||||
if (estimatedInputFrameCount > inputBufferFrameCap)
|
||||
{
|
||||
estimatedInputFrameCount = inputBufferFrameCap;
|
||||
}
|
||||
|
||||
// At this point we can convert the data to our mixing format
|
||||
ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration);
|
||||
ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
|
||||
ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
|
||||
estimatedInputFrameCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount);
|
||||
|
||||
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; // Safe cast
|
||||
ma_uint64 inputFramesProcessedThisIteration = estimatedInputFrameCount;
|
||||
ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
|
||||
ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
|
||||
|
||||
if (inputFramesProcessedThisIteration < inputFramesToProcessThisIteration) break; // Ran out of input data
|
||||
if (estimatedInputFrameCount > inputFramesProcessedThisIteration)
|
||||
{
|
||||
// Getting here means the estimated input frame count was overestimated. The residual needs
|
||||
// be stored for later use.
|
||||
ma_uint64 residualFrameCount = estimatedInputFrameCount - inputFramesProcessedThisIteration;
|
||||
|
||||
// This should never be hit, but added here for safety
|
||||
// Ensures we get out of the loop when no input nor output frames are processed
|
||||
if ((inputFramesProcessedThisIteration == 0) && (outputFramesProcessedThisIteration == 0)) break;
|
||||
// A safety check to make sure the capacity of the residual cache is not exceeded.
|
||||
if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY)
|
||||
{
|
||||
residualFrameCount = AUDIO_BUFFER_RESIDUAL_CAPACITY;
|
||||
}
|
||||
|
||||
memcpy(audioBuffer->converterResidual, inputBuffer + inputFramesProcessedThisIteration*bpf, (size_t)(residualFrameCount * bpf));
|
||||
audioBuffer->converterResidualCount = residualFrameCount;
|
||||
}
|
||||
|
||||
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration;
|
||||
}
|
||||
}
|
||||
|
||||
return totalOutputFramesProcessed;
|
||||
|
||||
@ -3422,7 +3422,7 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
|
||||
// Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F
|
||||
unsigned int glInternalFormat = GL_DEPTH_COMPONENT;
|
||||
|
||||
#if (defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_ES3))
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT)
|
||||
// while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities
|
||||
if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer)
|
||||
|
||||
56
src/rtext.c
56
src/rtext.c
@ -1497,15 +1497,14 @@ void UnloadTextLines(char **lines, int lineCount)
|
||||
}
|
||||
|
||||
// Get text length in bytes, check for \0 character
|
||||
// NOTE: Alternative: use strlen(text)
|
||||
unsigned int TextLength(const char *text)
|
||||
{
|
||||
unsigned int length = 0;
|
||||
|
||||
if (text != NULL)
|
||||
{
|
||||
// NOTE: Alternative: use strlen(text)
|
||||
|
||||
while (*text++) length++;
|
||||
while (text[length] != '\0') length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
@ -1718,7 +1717,7 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
||||
{
|
||||
char *result = NULL;
|
||||
|
||||
if ((text != NULL) && (search != NULL))
|
||||
if ((text != NULL) && (search != NULL) && (search[0] != '\0'))
|
||||
{
|
||||
if (replacement == NULL) replacement = "";
|
||||
|
||||
@ -1732,8 +1731,6 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
||||
|
||||
textLen = TextLength(text);
|
||||
searchLen = TextLength(search);
|
||||
if (searchLen == 0) return NULL; // Empty search causes infinite loop during count
|
||||
|
||||
replaceLen = TextLength(replacement);
|
||||
|
||||
// Count the number of replacements needed
|
||||
@ -1742,34 +1739,37 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
||||
|
||||
// Allocate returning string and point temp to it
|
||||
int tempLen = textLen + (replaceLen - searchLen)*count + 1;
|
||||
temp = result = (char *)RL_MALLOC(tempLen);
|
||||
temp = result = (char *)RL_CALLOC(tempLen, sizeof(char));
|
||||
|
||||
if (!result) return NULL; // Memory could not be allocated
|
||||
|
||||
// First time through the loop, all the variable are set correctly from here on,
|
||||
// - 'temp' points to the end of the result string
|
||||
// - 'insertPoint' points to the next occurrence of replace in text
|
||||
// - 'text' points to the remainder of text after "end of replace"
|
||||
while (count--)
|
||||
if (result != NULL) // Memory was allocated
|
||||
{
|
||||
insertPoint = (char *)strstr(text, search);
|
||||
lastReplacePos = (int)(insertPoint - text);
|
||||
|
||||
memcpy(temp, text, lastReplacePos);
|
||||
temp += lastReplacePos;
|
||||
|
||||
if (replaceLen > 0)
|
||||
// First time through the loop, all the variable are set correctly from here on,
|
||||
// - 'temp' points to the end of the result string
|
||||
// - 'insertPoint' points to the next occurrence of replace in text
|
||||
// - 'text' points to the remainder of text after "end of replace"
|
||||
while (count > 0)
|
||||
{
|
||||
memcpy(temp, replacement, replaceLen);
|
||||
temp += replaceLen;
|
||||
insertPoint = (char *)strstr(text, search);
|
||||
lastReplacePos = (int)(insertPoint - text);
|
||||
|
||||
memcpy(temp, text, lastReplacePos);
|
||||
temp += lastReplacePos;
|
||||
|
||||
if (replaceLen > 0)
|
||||
{
|
||||
memcpy(temp, replacement, replaceLen);
|
||||
temp += replaceLen;
|
||||
}
|
||||
|
||||
text += (lastReplacePos + searchLen); // Move to next "end of replace"
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
text += lastReplacePos + searchLen; // Move to next "end of replace"
|
||||
// Copy remaind text part after replacement to result (pointed by moving temp)
|
||||
// NOTE: Text pointer internal copy has been updated along the process
|
||||
strncpy(temp, text, TextLength(text));
|
||||
}
|
||||
|
||||
// Copy remaind text part after replacement to result (pointed by moving temp)
|
||||
strcpy(temp, text); // OK
|
||||
//strncpy(temp, text, tempLen - 1); // WRONG
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user