Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add floating point value box to raygui #356

Merged
merged 8 commits into from
May 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions src/raygui.h
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ RAYGUIAPI int GuiComboBox(Rectangle bounds, const char *text, int *active);
RAYGUIAPI int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control
RAYGUIAPI int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control
RAYGUIAPI int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers
RAYGUIAPI int GuiValueBoxF(Rectangle bounds,const char* text, char *val_str, float *value, bool editMode); // Floating point Value box control, val_str is buffer where string representation is stored
raysan5 marked this conversation as resolved.
Show resolved Hide resolved
RAYGUIAPI int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text

RAYGUIAPI int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider control
Expand Down Expand Up @@ -1449,6 +1450,7 @@ static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if
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 int TextToInteger(const char *text); // Get integer value from text
static int TextToFloat(const char *text); // Get float value from text

static int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded text
static const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode codepoint into UTF-8 text (char array size returned as parameter)
Expand Down Expand Up @@ -2935,6 +2937,121 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
return result;
}

// Floating point Value Box control, updates input val_str with numbers
// NOTE: Requires static variables: frameCounter
int GuiValueBoxF(Rectangle bounds,const char* text, char *val_str, float *value, bool editMode)
{
#if !defined(RAYGUI_VALUEBOX_MAX_CHARS)
#define RAYGUI_VALUEBOX_MAX_CHARS 32
#endif

int result = 0;
GuiState state = guiState;

Rectangle textBounds = {0};
if (text != NULL)
{
textBounds.width = (float)GetTextWidth(text) + 2;
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING);
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)
textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING);
}

// Update control
//--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
{
Vector2 mousePoint = GetMousePosition();

bool valueHasChanged = false;

if (editMode)
{
state = STATE_PRESSED;

int keyCount = (int)strlen(val_str);

// Only allow keys in range [48..57]
if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
{
if (GetTextWidth(val_str) < bounds.width)
{
int key = GetCharPressed();
if (
((key >= 48) && (key <= 57))
||key=='.'
||(!keyCount && key=='+') //sign can only be in first position
||(!keyCount && key=='-')
)
{
val_str[keyCount] = (char) key;
keyCount++;
valueHasChanged = true;
}
}
}

// Pressed backspace
if (IsKeyPressed(KEY_BACKSPACE))
{
if (keyCount > 0)
{
keyCount--;
val_str[keyCount] = '\0';
valueHasChanged = true;
}
}

if (valueHasChanged)
*value = TextToFloat(val_str);

if (IsKeyPressed(KEY_ENTER) ||
(!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
result = 1;
} else
{
if (CheckCollisionPointRec(mousePoint, bounds))
{
state = STATE_FOCUSED;
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
result = 1;
}
}
}
//--------------------------------------------------------------------

// Draw control
//--------------------------------------------------------------------
Color baseColor = BLANK;
if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED));
else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED));

GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), GetColor(GuiGetStyle(VALUEBOX, BORDER + (state * 3))),
baseColor);
GuiDrawText(val_str, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER,
GetColor(GuiGetStyle(VALUEBOX, TEXT + (state * 3))));

// Draw cursor
if (editMode)
{
// NOTE: ValueBox internal text is always centered
Rectangle cursor = {bounds.x + GetTextWidth(val_str) / 2 + bounds.width / 2 + 1,
bounds.y + 2 * GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4,
bounds.height - 4 * GuiGetStyle(VALUEBOX, BORDER_WIDTH)};
GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED)));
}

// Draw text label if provided
GuiDrawText(text, textBounds,
(GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) ? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT,
GetColor(GuiGetStyle(LABEL, TEXT + (state * 3))));
//--------------------------------------------------------------------

return result;
}

// Slider control with pro parameters
// NOTE: Other GuiSlider*() controls use this one
int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth)
Expand Down Expand Up @@ -5450,6 +5567,28 @@ static int TextToInteger(const char *text)
return value*sign;
}

static float TextToFloat(const char *text)
{
float value = 0.0f;
float sign = 1.0f;

if ((text[0] == '+') || (text[0] == '-'))
{
if (text[0] == '-') sign = -1;
text++;
}
int i = 0;
for (; ((text[i] >= '0') && (text[i] <= '9')); ++i) value = value*10.0f + (float)(text[i] - '0');
if (text[i++] != '.') return value*sign;
float divisor = 10.0f;
for (; ((text[i] >= '0') && (text[i] <= '9')); ++i)
{
value += ((float)(text[i] - '0'))/divisor;
divisor = divisor*10.0f;
}
return value;
}

// Encode codepoint into UTF-8 text (char array size returned as parameter)
static const char *CodepointToUTF8(int codepoint, int *byteSize)
{
Expand Down