diff --git a/examples/controls_test_suite/controls_test_suite.c b/examples/controls_test_suite/controls_test_suite.c index 00939ee..a600eab 100644 --- a/examples/controls_test_suite/controls_test_suite.c +++ b/examples/controls_test_suite/controls_test_suite.c @@ -44,11 +44,9 @@ int main() // GUI controls initialization //---------------------------------------------------------------------------------- int dropdownBox000Active = 0; - const char *dropdownBox000TextList[3] = { "ONE", "TWO", "THREE" }; bool dropDown000EditMode = false; int dropdownBox001Active = 0; - const char *dropdownBox001TextList[5] = { "ONE", "TWO", "THREE", "FOUR", "FIVE" }; bool dropDown001EditMode = false; int spinner001Value = 0; @@ -114,7 +112,7 @@ int main() //GuiDisable(); // First GUI column - forceSquaredChecked = GuiCheckBoxEx((Rectangle){ 25, 108, 15, 15 }, forceSquaredChecked, "Force Square"); + forceSquaredChecked = GuiCheckBox((Rectangle){ 25, 108, 15, 15 }, "Force Square", forceSquaredChecked); if (GuiSpinner((Rectangle){ 25, 135, 125, 30 }, &spinner001Value, 0, 100, 25, spinnerEditMode)) spinnerEditMode = !spinnerEditMode; if (GuiValueBox((Rectangle){ 25, 175, 125, 30 }, &valueBox002Value, 0, 100, valueBoxEditMode)) valueBoxEditMode = !valueBoxEditMode; if (GuiTextBox((Rectangle){ 25, 215, 125, 30 }, textBoxText, 64, textBoxEditMode)) textBoxEditMode = !textBoxEditMode; @@ -129,19 +127,18 @@ int main() GuiState(GUI_STATE_NORMAL); GuiUnlock(); - //comboBoxActive = GuiComboBox((Rectangle){ 25, 470, 125, 30 }, dropdownBox001TextList, 5, comboBoxActive); - comboBoxActive = GuiComboBox2((Rectangle){ 25, 470, 125, 30 }, "ONE;TWO;THREE;FOUR", comboBoxActive); + comboBoxActive = GuiComboBox((Rectangle){ 25, 470, 125, 30 }, "ONE;TWO;THREE;FOUR", comboBoxActive); // NOTE: GuiDropdownBox must draw after any other control that can be covered on unfolding - if (GuiDropdownBox((Rectangle){ 25, 65, 125, 30 }, dropdownBox001TextList, 5, &dropdownBox001Active, dropDown001EditMode)) dropDown001EditMode = !dropDown001EditMode; - if (GuiDropdownBox((Rectangle){ 25, 25, 125, 30 }, dropdownBox000TextList, 3, &dropdownBox000Active, dropDown000EditMode)) dropDown000EditMode = !dropDown000EditMode; + if (GuiDropdownBox((Rectangle){ 25, 65, 125, 30 }, "ONE;TWO;THREE;FOUR", &dropdownBox001Active, dropDown001EditMode)) dropDown001EditMode = !dropDown001EditMode; + if (GuiDropdownBox((Rectangle){ 25, 25, 125, 30 }, "ONE;TWO;THREE", &dropdownBox000Active, dropDown000EditMode)) dropDown000EditMode = !dropDown000EditMode; // Second GUI column if (GuiListView((Rectangle){ 165, 25, 140, 140 }, listViewList, 6, &listViewScrollIndex, &listViewActive, listViewEditMode)) listViewEditMode = !listViewEditMode; if (GuiListViewEx((Rectangle){ 165, 180, 140, 200 }, listViewExList, listViewExElementsEnable, 8, &listViewExScrollIndex, &listViewExActive, &listViewExFocus, listViewExEditMode)) listViewExEditMode = !listViewExEditMode; if (listViewExFocus >= 0 && listViewExFocus < 8) DrawText(FormatText("FOCUS: %s", listViewExList[listViewExFocus]), 165, 390, 10, listViewExElementsEnable[listViewExFocus] ? LIME : MAROON); - toggleGroupActive = GuiToggleGroupEx((Rectangle){ 165, 400, 140, 25 }, dropdownBox001TextList, 4, toggleGroupActive, 4, 1); + toggleGroupActive = GuiToggleGroupEx((Rectangle){ 165, 400, 140, 25 }, "ONE;TWO;THREE;FOUR", toggleGroupActive, 4, 1); // Third GUI column if (GuiTextBoxMulti((Rectangle){ 320, 25, 225, 140 }, multiTextBoxText, 141, multiTextBoxEditMode)) multiTextBoxEditMode = !multiTextBoxEditMode; diff --git a/src/raygui.h b/src/raygui.h index 14229e7..582379b 100644 --- a/src/raygui.h +++ b/src/raygui.h @@ -129,12 +129,13 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define VALIGN_OFFSET(h) ((int)h%2) // Vertical alignment for pixel perfect -#define LINE_BLINK_FRAMES 20 // Text edit controls cursor blink timming +#define VALIGN_OFFSET(h) ((int)h%2) // Vertical alignment for pixel perfect -#define NUM_CONTROLS 12 // Number of standard controls -#define NUM_PROPS_DEFAULT 16 // Number of standard properties -#define NUM_PROPS_EXTENDED 8 // Number of extended properties +#define TEXTEDIT_CURSOR_BLINK_FRAMES 20 // Text edit controls cursor blink timming + +#define NUM_CONTROLS 12 // Number of standard controls +#define NUM_PROPS_DEFAULT 16 // Number of standard properties +#define NUM_PROPS_EXTENDED 8 // Number of extended properties //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -329,13 +330,12 @@ RAYGUIDEF bool GuiButton(Rectangle bounds, const char *text); RAYGUIDEF bool GuiLabelButton(Rectangle bounds, const char *text); // Label button control, show true when clicked RAYGUIDEF bool GuiImageButton(Rectangle bounds, Texture2D texture); // Image button control, returns true when clicked RAYGUIDEF bool GuiImageButtonEx(Rectangle bounds, Texture2D texture, Rectangle texSource, const char *text); // Image button extended control, returns true when clicked -RAYGUIDEF bool GuiToggle(Rectangle bounds, const char *text, bool toggle); // Toggle Button control, returns true when active -RAYGUIDEF int GuiToggleGroup(Rectangle bounds, const char **text, int count, int active); // Toggle Group control, returns toggled button index -RAYGUIDEF int GuiToggleGroupEx(Rectangle bounds, const char **text, int count, int active, int padding, int columns); // Toggle Group with extended parameters -RAYGUIDEF bool GuiCheckBox(Rectangle bounds, bool checked); // Check Box control, returns true when active -RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text); // Check Box control with text, returns true when active -RAYGUIDEF int GuiComboBox(Rectangle bounds, const char **text, int count, int active); // Combo Box control, returns selected item index -RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char **text, int count, int *active, bool editMode); // Dropdown Box control, returns selected item +RAYGUIDEF bool GuiToggle(Rectangle bounds, const char *text, bool active); // Toggle Button control, returns true when active +RAYGUIDEF int GuiToggleGroup(Rectangle bounds, const char *text, int active); // Toggle Group control, returns active toggle index +RAYGUIDEF int GuiToggleGroupEx(Rectangle bounds, const char *text, int active, int padding, int columns); // Toggle Group with extended parameters +RAYGUIDEF bool GuiCheckBox(Rectangle bounds, const char *text, bool checked); // Check Box control, returns true when active +RAYGUIDEF int GuiComboBox(Rectangle bounds, const char *text, int active); // Combo Box control, returns selected item index +RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control, returns selected item RAYGUIDEF bool GuiSpinner(Rectangle bounds, int *value, int minValue, int maxValue, int btnWidth, bool editMode); // Spinner control, returns selected value RAYGUIDEF bool GuiValueBox(Rectangle bounds, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers RAYGUIDEF bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text @@ -434,11 +434,11 @@ static bool guiStyleLoaded = false; #define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo) // This functions are directly implemented in raygui -static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value -static int ColorToInt(Color color); // Returns hexadecimal value for a Color -static Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f -static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle -static const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' +static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value +static int ColorToInt(Color color); // Returns hexadecimal value for a Color +static Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f +static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle +static const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' // raygui depend on some raylib input and drawing functions // NOTE: To use raygui as standalone library, below functions must be defined by the user @@ -478,6 +478,9 @@ static bool GuiListElement(Rectangle bounds, const char *text, bool active, bool static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV +// Get pointers to substrings separated by delimiter +static void GetSubTextPtrs(const char *text, char delimiter, const char **ptrs, int *lengths, int *count); + // Gui draw text using default font static void GuiDrawText(const char *text, int posX, int posY, Color tint) { @@ -1039,22 +1042,31 @@ RAYGUIDEF bool GuiToggle(Rectangle bounds, const char *text, bool active) } // Toggle Group control, returns toggled button index -RAYGUIDEF int GuiToggleGroup(Rectangle bounds, const char **text, int count, int active) +RAYGUIDEF int GuiToggleGroup(Rectangle bounds, const char *text, int active) { - return GuiToggleGroupEx(bounds, text, count, active, GuiGetStyle(TOGGLE, GROUP_PADDING), 512); + return GuiToggleGroupEx(bounds, text, active, GuiGetStyle(TOGGLE, GROUP_PADDING), 32); } // Toggle Group with pro parameters, returns toggled button index // NOTE: bounds refer to an individual toggle size, spacing refers to toggles separation and columns defines number of columns -RAYGUIDEF int GuiToggleGroupEx(Rectangle bounds, const char **text, int count, int active, int padding, int columns) +RAYGUIDEF int GuiToggleGroupEx(Rectangle bounds, const char *text, int active, int padding, int columns) { + #define TOGGLEGROUP_MAX_ELEMENTS 16 + #define TOGGLEGROUP_ELEMENTS_DELIMITER ';' + float initBoundsX = bounds.x; int currentColumn = 0; + + // Get substrings elements from text (elements pointers, lengths and count) + const char *elementsPtrs[TOGGLEGROUP_MAX_ELEMENTS] = { NULL }; + int elementsLen[TOGGLEGROUP_MAX_ELEMENTS] = { 0 }; + int elementsCount = 0; + GetSubTextPtrs(text, TOGGLEGROUP_ELEMENTS_DELIMITER, elementsPtrs, elementsLen, &elementsCount); - for (int i = 0; i < count; i++) + for (int i = 0; i < elementsCount; i++) { - if (i == active) GuiToggle(bounds, text[i], true); - else if (GuiToggle(bounds, text[i], false) == true) active = i; + if (i == active) GuiToggle(bounds, SubText(elementsPtrs[i], 0, elementsLen[i]), true); + else if (GuiToggle(bounds, SubText(elementsPtrs[i], 0, elementsLen[i]), false) == true) active = i; bounds.x += (bounds.width + padding); currentColumn++; @@ -1071,14 +1083,8 @@ RAYGUIDEF int GuiToggleGroupEx(Rectangle bounds, const char **text, int count, i } // Check Box control, returns true when active -RAYGUIDEF bool GuiCheckBox(Rectangle bounds, bool checked) -{ - return GuiCheckBoxEx(bounds, checked, NULL); -} - -// Check Box extended control, returns true when active // TODO: Focus check box when text selected! -RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) +RAYGUIDEF bool GuiCheckBox(Rectangle bounds, const char *text, bool checked) { GuiControlState state = guiState; int textWidth = (text == NULL) ? 0 : GuiTextWidth(text); @@ -1090,7 +1096,7 @@ RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) Vector2 mousePoint = GetMousePosition(); // Check checkbox state - if (CheckCollisionPointRec(mousePoint, bounds)) + if (CheckCollisionPointRec(mousePoint, (Rectangle){ bounds.x, bounds.y, bounds.width + textWidth, bounds.height })) { if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED; else state = GUI_STATE_FOCUSED; @@ -1102,8 +1108,6 @@ RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) // Draw control //-------------------------------------------------------------------- - if (text != NULL) if (GuiLabelButton((Rectangle){ bounds.x + bounds.width + GuiGetStyle(CHECKBOX, CHECK_TEXT_PADDING), bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, textWidth, GuiGetStyle(DEFAULT, TEXT_SIZE) }, text)) checked = !checked; - switch (state) { case GUI_STATE_NORMAL: @@ -1113,6 +1117,9 @@ RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING), bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), Fade(GetColor(GuiGetStyle(CHECKBOX, TEXT_COLOR_PRESSED)), guiAlpha)); + + if (text != NULL) GuiDrawText(text, bounds.x + bounds.width + GuiGetStyle(CHECKBOX, CHECK_TEXT_PADDING), bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, Fade(GetColor(GuiGetStyle(LABEL, TEXT_COLOR_NORMAL)), guiAlpha)); + } break; case GUI_STATE_FOCUSED: { @@ -1121,6 +1128,9 @@ RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING), bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), Fade(GetColor(GuiGetStyle(CHECKBOX, TEXT_COLOR_FOCUSED)), guiAlpha)); + + if (text != NULL) GuiDrawText(text, bounds.x + bounds.width + GuiGetStyle(CHECKBOX, CHECK_TEXT_PADDING), bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, Fade(GetColor(GuiGetStyle(LABEL, TEXT_COLOR_FOCUSED)), guiAlpha)); + } break; case GUI_STATE_PRESSED: { @@ -1129,6 +1139,9 @@ RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING), bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), Fade(GetColor(GuiGetStyle(CHECKBOX, TEXT_COLOR_PRESSED)), guiAlpha)); + + if (text != NULL) GuiDrawText(text, bounds.x + bounds.width + GuiGetStyle(CHECKBOX, CHECK_TEXT_PADDING), bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, Fade(GetColor(GuiGetStyle(LABEL, TEXT_COLOR_PRESSED)), guiAlpha)); + } break; case GUI_STATE_DISABLED: { @@ -1137,6 +1150,9 @@ RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING), bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, INNER_PADDING)), Fade(GetColor(GuiGetStyle(DEFAULT, TEXT_COLOR_DISABLED)), guiAlpha)); + + if (text != NULL) GuiDrawText(text, bounds.x + bounds.width + GuiGetStyle(CHECKBOX, CHECK_TEXT_PADDING), bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, Fade(GetColor(GuiGetStyle(LABEL, TEXT_COLOR_DISABLED)), guiAlpha)); + } break; default: break; } @@ -1146,9 +1162,10 @@ RAYGUIDEF bool GuiCheckBoxEx(Rectangle bounds, bool checked, const char *text) } // Combo Box control, returns selected item index -RAYGUIDEF int GuiComboBox2(Rectangle bounds, char *text, int active) +RAYGUIDEF int GuiComboBox(Rectangle bounds, const char *text, int active) { - #define MAX_COMBOBOX_SLOTS 5 + #define COMBOBOX_MAX_ELEMENTS 16 + #define COMBOBOX_ELEMENTS_DELIMITER ';' GuiControlState state = guiState; @@ -1157,38 +1174,16 @@ RAYGUIDEF int GuiComboBox2(Rectangle bounds, char *text, int active) Rectangle selector = { bounds.x + bounds.width + GuiGetStyle(COMBOBOX, SELECTOR_PADDING), bounds.y, GuiGetStyle(COMBOBOX, SELECTOR_WIDTH), bounds.height }; - // Get substrings from text - //-------------------------------------------------------------------- - char *ptrs[MAX_COMBOBOX_SLOTS] = { NULL }; // Pointers to substrings - int lens[MAX_COMBOBOX_SLOTS] = { 0 }; // Substrings lengths - int elementsCount = 0; // Substrings elementsCount - - int len = strlen(text); - ptrs[0] = text; - int charsCount = 0; - - for (int i = 0; i < len; i++) - { - charsCount++; - - if (text[i] == ';') - { - lens[elementsCount] = charsCount - 1; - charsCount = 0; - elementsCount++; - - ptrs[elementsCount] = &text[i + 1]; - } - } - - lens[elementsCount] = charsCount; - elementsCount++; - //-------------------------------------------------------------------- + // Get substrings elements from text (elements pointers, lengths and count) + const char *elementsPtrs[COMBOBOX_MAX_ELEMENTS] = { NULL }; + int elementsLen[COMBOBOX_MAX_ELEMENTS] = { 0 }; + int elementsCount = 0; + GetSubTextPtrs(text, COMBOBOX_ELEMENTS_DELIMITER, elementsPtrs, elementsLen, &elementsCount); if (active < 0) active = 0; else if (active > elementsCount - 1) active = elementsCount - 1; - int textWidth = GuiTextWidth(SubText(ptrs[active], 0, lens[active])); + int textWidth = GuiTextWidth(SubText(elementsPtrs[active], 0, elementsLen[active])); int textHeight = GuiGetStyle(DEFAULT, TEXT_SIZE); if (bounds.width < textWidth) bounds.width = textWidth; @@ -1229,7 +1224,7 @@ RAYGUIDEF int GuiComboBox2(Rectangle bounds, char *text, int active) DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_NORMAL)), guiAlpha)); DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_NORMAL)), guiAlpha)); - GuiDrawText(SubText(ptrs[active], 0, lens[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_NORMAL)), guiAlpha)); + GuiDrawText(SubText(elementsPtrs[active], 0, elementsLen[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_NORMAL)), guiAlpha)); GuiDrawText(FormatText("%i/%i", active + 1, elementsCount), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, elementsCount))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_NORMAL)), guiAlpha)); } break; case GUI_STATE_FOCUSED: @@ -1240,7 +1235,7 @@ RAYGUIDEF int GuiComboBox2(Rectangle bounds, char *text, int active) DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_FOCUSED)), guiAlpha)); DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_FOCUSED)), guiAlpha)); - GuiDrawText(SubText(ptrs[active], 0, lens[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_FOCUSED)), guiAlpha)); + GuiDrawText(SubText(elementsPtrs[active], 0, elementsLen[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_FOCUSED)), guiAlpha)); GuiDrawText(FormatText("%i/%i", active + 1, elementsCount), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, elementsCount))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_FOCUSED)), guiAlpha)); } break; case GUI_STATE_PRESSED: @@ -1251,7 +1246,7 @@ RAYGUIDEF int GuiComboBox2(Rectangle bounds, char *text, int active) DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_PRESSED)), guiAlpha)); DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_PRESSED)), guiAlpha)); - GuiDrawText(SubText(ptrs[active], 0, lens[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_PRESSED)), guiAlpha)); + GuiDrawText(SubText(elementsPtrs[active], 0, elementsLen[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_PRESSED)), guiAlpha)); GuiDrawText(FormatText("%i/%i", active + 1, elementsCount), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, elementsCount))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_PRESSED)), guiAlpha)); } break; case GUI_STATE_DISABLED: @@ -1262,7 +1257,7 @@ RAYGUIDEF int GuiComboBox2(Rectangle bounds, char *text, int active) DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_DISABLED)), guiAlpha)); DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_DISABLED)), guiAlpha)); - GuiDrawText(SubText(ptrs[active], 0, lens[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_DISABLED)), guiAlpha)); + GuiDrawText(SubText(elementsPtrs[active], 0, elementsLen[active]), bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_DISABLED)), guiAlpha)); GuiDrawText(FormatText("%i/%i", active + 1, elementsCount), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, elementsCount))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_DISABLED)), guiAlpha)); } break; default: break; @@ -1272,110 +1267,23 @@ RAYGUIDEF int GuiComboBox2(Rectangle bounds, char *text, int active) return active; } -// Combo Box control, returns selected item index -RAYGUIDEF int GuiComboBox(Rectangle bounds, const char **text, int count, int active) -{ - GuiControlState state = guiState; - - bounds.width -= (GuiGetStyle(COMBOBOX, SELECTOR_WIDTH) + GuiGetStyle(COMBOBOX, SELECTOR_PADDING)); - - Rectangle selector = { bounds.x + bounds.width + GuiGetStyle(COMBOBOX, SELECTOR_PADDING), - bounds.y, GuiGetStyle(COMBOBOX, SELECTOR_WIDTH), bounds.height }; - - if (active < 0) active = 0; - else if (active > count - 1) active = count - 1; - - int textWidth = GuiTextWidth(text[active]); - int textHeight = GuiGetStyle(DEFAULT, TEXT_SIZE); - - if (bounds.width < textWidth) bounds.width = textWidth; - if (bounds.height < textHeight) bounds.height = textHeight; - - // Update control - //-------------------------------------------------------------------- - if ((state != GUI_STATE_DISABLED) && !guiLocked) - { - Vector2 mousePoint = GetMousePosition(); - - if (CheckCollisionPointRec(mousePoint, bounds) || - CheckCollisionPointRec(mousePoint, selector)) - { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) - { - active += 1; - if (active >= count) active = 0; - } - - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED; - else state = GUI_STATE_FOCUSED; - } - } - //-------------------------------------------------------------------- - - // Draw control - //-------------------------------------------------------------------- - switch (state) - { - case GUI_STATE_NORMAL: - { - // Draw combo box main - DrawRectangleLinesEx(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_NORMAL)), guiAlpha)); - DrawRectangle(bounds.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_NORMAL)), guiAlpha)); - - // Draw selector - DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_NORMAL)), guiAlpha)); - DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_NORMAL)), guiAlpha)); - - GuiDrawText(text[active], bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_NORMAL)), guiAlpha)); - GuiDrawText(FormatText("%i/%i", active + 1, count), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, count))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_NORMAL)), guiAlpha)); - } break; - case GUI_STATE_FOCUSED: - { - DrawRectangleLinesEx(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_FOCUSED)), guiAlpha)); - DrawRectangle(bounds.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_FOCUSED)), guiAlpha)); - - DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_FOCUSED)), guiAlpha)); - DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_FOCUSED)), guiAlpha)); - - GuiDrawText(text[active], bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_FOCUSED)), guiAlpha)); - GuiDrawText(FormatText("%i/%i", active + 1, count), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, count))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_FOCUSED)), guiAlpha)); - } break; - case GUI_STATE_PRESSED: - { - DrawRectangleLinesEx(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_PRESSED)), guiAlpha)); - DrawRectangle(bounds.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_PRESSED)), guiAlpha)); - - DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_PRESSED)), guiAlpha)); - DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_PRESSED)), guiAlpha)); - - GuiDrawText(text[active], bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_PRESSED)), guiAlpha)); - GuiDrawText(FormatText("%i/%i", active + 1, count), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, count))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_PRESSED)), guiAlpha)); - } break; - case GUI_STATE_DISABLED: - { - DrawRectangleLinesEx(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_DISABLED)), guiAlpha)); - DrawRectangle(bounds.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), bounds.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_DISABLED)), guiAlpha)); - - DrawRectangleLinesEx(selector, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER_COLOR_DISABLED)), guiAlpha)); - DrawRectangle(selector.x + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.y + GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.width - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), selector.height - 2*GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE_COLOR_DISABLED)), guiAlpha)); - - GuiDrawText(text[active], bounds.x + bounds.width/2 - textWidth/2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_DISABLED)), guiAlpha)); - GuiDrawText(FormatText("%i/%i", active + 1, count), selector.x + selector.width/2 - GuiTextWidth(FormatText("%i/%i", active + 1, count))/2, selector.y + selector.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2 + VALIGN_OFFSET(bounds.height), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT_COLOR_DISABLED)), guiAlpha)); - } break; - default: break; - } - //-------------------------------------------------------------------- - - return active; -} - // Dropdown Box control, returns selected item -RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char **text, int count, int *active, bool editMode) +RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode) { + #define DROPDOWNBOX_MAX_ELEMENTS 16 + #define DROPDOWNBOX_ELEMENTS_DELIMITER ';' + GuiControlState state = guiState; + + // Get substrings elements from text (elements pointers, lengths and count) + const char *elementsPtrs[DROPDOWNBOX_MAX_ELEMENTS] = { NULL }; + int elementsLen[DROPDOWNBOX_MAX_ELEMENTS] = { 0 }; + int elementsCount = 0; + GetSubTextPtrs(text, DROPDOWNBOX_ELEMENTS_DELIMITER, elementsPtrs, elementsLen, &elementsCount); + bool pressed = false; int auxActive = *active; - int textWidth = GuiTextWidth(text[auxActive]); + int textWidth = GuiTextWidth(SubText(elementsPtrs[auxActive], 0, elementsLen[auxActive])); int textHeight = GuiGetStyle(DEFAULT, TEXT_SIZE); if (bounds.width < textWidth) bounds.width = textWidth; @@ -1383,7 +1291,8 @@ RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char **text, int count, in Rectangle closeBounds = bounds; Rectangle openBounds = bounds; - openBounds.height *= (count + 1); + + openBounds.height *= (elementsCount + 1); // Update control //-------------------------------------------------------------------- @@ -1427,7 +1336,7 @@ RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char **text, int count, in { DrawRectangle(bounds.x, bounds.y, bounds.width, bounds.height, Fade(GetColor(GuiGetStyle(DEFAULT, BASE_COLOR_NORMAL)), guiAlpha)); DrawRectangleLinesEx(bounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_NORMAL)), guiAlpha)); - GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, text[auxActive], false, false); + GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, SubText(elementsPtrs[auxActive], 0, elementsLen[auxActive]), false, false); DrawTriangle((Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_RIGHT_PADDING), bounds.y + bounds.height/2 - 2 }, (Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_RIGHT_PADDING) + 5, bounds.y + bounds.height/2 - 2 + 5 }, @@ -1435,7 +1344,7 @@ RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char **text, int count, in } break; case GUI_STATE_FOCUSED: { - GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, text[auxActive], false, editMode); + GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, SubText(elementsPtrs[auxActive], 0, elementsLen[auxActive]), false, editMode); DrawTriangle((Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_RIGHT_PADDING), bounds.y + bounds.height/2 - 2 }, (Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_RIGHT_PADDING) + 5, bounds.y + bounds.height/2 - 2 + 5 }, @@ -1444,22 +1353,22 @@ RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char **text, int count, in case GUI_STATE_PRESSED: { - if (!editMode) GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, text[auxActive], true, true); + if (!editMode) GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, SubText(elementsPtrs[auxActive], 0, elementsLen[auxActive]), true, true); if (editMode) { GuiPanel(openBounds); - GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, text[auxActive], true, true); + GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, SubText(elementsPtrs[auxActive], 0, elementsLen[auxActive]), true, true); - for (int i = 0; i < count; i++) + for (int i = 0; i < elementsCount; i++) { if (i == auxActive && editMode) { - if (GuiListElement((Rectangle){ bounds.x, bounds.y + bounds.height*(i+1) + GuiGetStyle(DROPDOWNBOX, INNER_PADDING), bounds.width, bounds.height - GuiGetStyle(DROPDOWNBOX, INNER_PADDING) }, text[i], true, true) == false) pressed = true; //auxActive = i; + if (GuiListElement((Rectangle){ bounds.x, bounds.y + bounds.height*(i+1) + GuiGetStyle(DROPDOWNBOX, INNER_PADDING), bounds.width, bounds.height - GuiGetStyle(DROPDOWNBOX, INNER_PADDING) }, SubText(elementsPtrs[i], 0, elementsLen[i]), true, true) == false) pressed = true; //auxActive = i; } else { - if (GuiListElement((Rectangle){ bounds.x, bounds.y + bounds.height*(i+1) + GuiGetStyle(DROPDOWNBOX, INNER_PADDING), bounds.width, bounds.height - GuiGetStyle(DROPDOWNBOX, INNER_PADDING) }, text[i], false, true)) + if (GuiListElement((Rectangle){ bounds.x, bounds.y + bounds.height*(i+1) + GuiGetStyle(DROPDOWNBOX, INNER_PADDING), bounds.width, bounds.height - GuiGetStyle(DROPDOWNBOX, INNER_PADDING) }, SubText(elementsPtrs[i], 0, elementsLen[i]), false, true)) { auxActive = i; pressed = true; @@ -1476,7 +1385,7 @@ RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char **text, int count, in { DrawRectangle(bounds.x, bounds.y, bounds.width, bounds.height, Fade(GetColor(GuiGetStyle(DEFAULT, BASE_COLOR_DISABLED)), guiAlpha)); DrawRectangleLinesEx(bounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), guiAlpha)); - GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, text[auxActive], false, false); + GuiListElement((Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height }, SubText(elementsPtrs[auxActive], 0, elementsLen[auxActive]), false, false); DrawTriangle((Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_RIGHT_PADDING), bounds.y + bounds.height/2 - 2 }, (Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_RIGHT_PADDING) + 5, bounds.y + bounds.height/2 - 2 + 5 }, @@ -1535,14 +1444,14 @@ RAYGUIDEF bool GuiSpinner(Rectangle bounds, int *value, int minValue, int maxVal // NOTE: Requires static variables: framesCounter RAYGUIDEF bool GuiValueBox(Rectangle bounds, int *value, int minValue, int maxValue, bool editMode) { - #define MAX_VALUE_CHARS 32 + #define VALUEBOX_MAX_CHARS 32 static int framesCounter = 0; // Required for blinking cursor GuiControlState state = guiState; bool pressed = false; - char text[MAX_VALUE_CHARS + 1] = "\0"; + char text[VALUEBOX_MAX_CHARS + 1] = "\0"; sprintf(text, "%i", *value); int textWidth = GuiTextWidth(text); @@ -1563,7 +1472,7 @@ RAYGUIDEF bool GuiValueBox(Rectangle bounds, int *value, int minValue, int maxVa int keyCount = strlen(text); // Only allow keys in range [48..57] - if (keyCount < MAX_VALUE_CHARS) + if (keyCount < VALUEBOX_MAX_CHARS) { int maxWidth = (bounds.width - (GuiGetStyle(DEFAULT, INNER_PADDING)*2)); if (GuiTextWidth(text) < maxWidth) @@ -1591,7 +1500,7 @@ RAYGUIDEF bool GuiValueBox(Rectangle bounds, int *value, int minValue, int maxVa } else if (IsKeyDown(KEY_BACKSPACE)) { - if ((framesCounter > LINE_BLINK_FRAMES) && (framesCounter%2) == 0) keyCount--; + if ((framesCounter > TEXTEDIT_CURSOR_BLINK_FRAMES) && (framesCounter%2) == 0) keyCount--; text[keyCount] = '\0'; if (keyCount < 0) keyCount = 0; valueHasChanged = true; @@ -1709,7 +1618,7 @@ RAYGUIDEF bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editM } else if (IsKeyDown(KEY_BACKSPACE)) { - if ((framesCounter > LINE_BLINK_FRAMES) && (framesCounter%2) == 0) keyCount--; + if ((framesCounter > TEXTEDIT_CURSOR_BLINK_FRAMES) && (framesCounter%2) == 0) keyCount--; text[keyCount] = '\0'; if (keyCount < 0) keyCount = 0; } @@ -1844,7 +1753,7 @@ RAYGUIDEF bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool } else if (IsKeyDown(KEY_BACKSPACE)) { - if ((framesCounter > LINE_BLINK_FRAMES) && (framesCounter%2) == 0) keyCount--; + if ((framesCounter > TEXTEDIT_CURSOR_BLINK_FRAMES) && (framesCounter%2) == 0) keyCount--; text[keyCount] = '\0'; if (keyCount < 0) keyCount = 0; textHasChange = true; @@ -2650,7 +2559,7 @@ RAYGUIDEF Color GuiColorPanel(Rectangle bounds, Color color) // NOTE: Returns alpha value normalized [0..1] RAYGUIDEF float GuiColorBarAlpha(Rectangle bounds, float alpha) { - #define BACK_CHECKER_SIZE 10 + #define COLORBARALPHA_CHECKED_SIZE 10 GuiControlState state = guiState; Rectangle selector = { bounds.x + alpha*bounds.width - GuiGetStyle(COLORPICKER, BAR_SELECTOR_PADDING), bounds.y - GuiGetStyle(COLORPICKER, BAR_SELECTOR_PADDING), GuiGetStyle(COLORPICKER, BAR_SELECTOR_HEIGHT), bounds.height + GuiGetStyle(COLORPICKER, BAR_SELECTOR_PADDING)*2 }; @@ -2684,8 +2593,8 @@ RAYGUIDEF float GuiColorBarAlpha(Rectangle bounds, float alpha) // Draw alpha bar: checked background if (state != GUI_STATE_DISABLED) { - for (int i = 0; i < bounds.width/BACK_CHECKER_SIZE; i++) DrawRectangle(bounds.x + BACK_CHECKER_SIZE*(i%((int)bounds.width/BACK_CHECKER_SIZE)), bounds.y, bounds.width/(bounds.width/BACK_CHECKER_SIZE), BACK_CHECKER_SIZE, (i%2) ? Fade(Fade(GRAY, 0.4f), guiAlpha) : Fade(Fade(RAYWHITE, 0.4f), guiAlpha)); - for (int i = 0; i < bounds.width/BACK_CHECKER_SIZE; i++) DrawRectangle(bounds.x + BACK_CHECKER_SIZE*(i%((int)bounds.width/BACK_CHECKER_SIZE)), bounds.y + BACK_CHECKER_SIZE, bounds.width/(bounds.width/BACK_CHECKER_SIZE), BACK_CHECKER_SIZE, (i%2) ? Fade(Fade(RAYWHITE, 0.4f), guiAlpha) : Fade(Fade(GRAY, 0.4f), guiAlpha)); + for (int i = 0; i < bounds.width/COLORBARALPHA_CHECKED_SIZE; i++) DrawRectangle(bounds.x + COLORBARALPHA_CHECKED_SIZE*(i%((int)bounds.width/COLORBARALPHA_CHECKED_SIZE)), bounds.y, bounds.width/(bounds.width/COLORBARALPHA_CHECKED_SIZE), COLORBARALPHA_CHECKED_SIZE, (i%2) ? Fade(Fade(GRAY, 0.4f), guiAlpha) : Fade(Fade(RAYWHITE, 0.4f), guiAlpha)); + for (int i = 0; i < bounds.width/COLORBARALPHA_CHECKED_SIZE; i++) DrawRectangle(bounds.x + COLORBARALPHA_CHECKED_SIZE*(i%((int)bounds.width/COLORBARALPHA_CHECKED_SIZE)), bounds.y + COLORBARALPHA_CHECKED_SIZE, bounds.width/(bounds.width/COLORBARALPHA_CHECKED_SIZE), COLORBARALPHA_CHECKED_SIZE, (i%2) ? Fade(Fade(RAYWHITE, 0.4f), guiAlpha) : Fade(Fade(GRAY, 0.4f), guiAlpha)); DrawRectangleGradientH(bounds.x, bounds.y, bounds.width, bounds.height, Fade((Color){ 255,255,255,0 }, guiAlpha), Fade((Color){ 0,0,0,255 }, guiAlpha)); } else DrawRectangleGradientH(bounds.x, bounds.y, bounds.width, bounds.height, Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha)); @@ -3223,6 +3132,38 @@ static Vector3 ConvertHSVtoRGB(Vector3 hsv) return rgb; } +// Get pointers to substrings separated by delimiter +static void GetSubTextPtrs(const char *text, char delimiter, const char **ptrs, int *lengths, int *count) +{ + #define MAX_MULTITEXT_LENGTH 1024 + + int elementsCount = 0; + int charsCount = 0; + //int len = strlen(text); // We already traverse text array in loop + + ptrs[0] = text; + + for (int i = 0; i < MAX_MULTITEXT_LENGTH; i++) + { + charsCount++; + + if (text[i] == delimiter) + { + lengths[elementsCount] = charsCount - 1; + charsCount = 0; + elementsCount++; + + ptrs[elementsCount] = &text[i + 1]; + } + else if (text[i] == '\0') break; + } + + lengths[elementsCount] = charsCount; + elementsCount++; + + *count = elementsCount; +} + #if defined(RAYGUI_STANDALONE) // Returns a Color struct from hexadecimal value static Color GetColor(int hexValue)