2023-07-29 23:18:02 +06:00
/*******************************************************************************************
*
* raygui - basic calculator app with custom input box for float values
*
* DEPENDENCIES :
* raylib 4.5 - Windowing / input management and drawing .
* raygui 3.5 - Immediate - mode GUI controls .
*
* COMPILATION ( Windows - MinGW ) :
* gcc - o $ ( NAME_PART ) . exe $ ( FILE_NAME ) - I . . / . . / src - lraylib - lopengl32 - lgdi32 - std = c99
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2024-02-03 19:59:59 +01:00
# include "raylib.h"
2023-07-29 23:18:02 +06:00
# define RAYGUI_IMPLEMENTATION
2024-02-03 19:59:59 +01:00
# include "raygui.h"
2023-07-29 23:18:02 +06:00
2024-02-03 19:59:59 +01:00
int guiFloatingPointIndex = 0 ; // Global variable shared by all GuiFloatBox()
2023-07-29 23:18:02 +06:00
int GuiFloatBox ( Rectangle bounds , const char * text , float * value , int minValue , int maxValue , bool editMode ) ; // Custom input box that works with float values. Basicly GuiValueBox(), but with some changes
int main ( )
{
InitWindow ( 250 , 100 , " Basic calculator " ) ;
// General variables
SetTargetFPS ( 60 ) ;
float variableA = 0.0f ;
float variableB = 0.0f ;
float result = 0.0f ;
char operation [ 2 ] ;
operation [ 0 ] = ' + ' ;
operation [ 1 ] = ' \0 ' ;
bool variableAMode = false ;
bool variableBMode = false ;
//--------------------------------------------------------------------------------------
// Main game loop
while ( ! WindowShouldClose ( ) )
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing ( ) ;
ClearBackground ( RAYWHITE ) ;
if ( GuiFloatBox ( ( Rectangle ) { 10 , 10 , 100 , 20 } , NULL , & variableA , - 1000000.0 , 1000000.0 , variableAMode ) ) variableAMode = ! variableAMode ;
if ( GuiFloatBox ( ( Rectangle ) { 140 , 10 , 100 , 20 } , NULL , & variableB , - 1000000.0 , 1000000.0 , variableBMode ) ) variableBMode = ! variableBMode ;
if ( GuiButton ( ( Rectangle ) { 10 , 70 , 50 , 20 } , " + " ) )
{
result = variableA + variableB ;
operation [ 0 ] = ' + ' ;
}
if ( GuiButton ( ( Rectangle ) { 70 , 70 , 50 , 20 } , " - " ) )
{
result = variableA - variableB ;
operation [ 0 ] = ' - ' ;
}
if ( GuiButton ( ( Rectangle ) { 130 , 70 , 50 , 20 } , " * " ) )
{
result = variableA * variableB ;
operation [ 0 ] = ' * ' ;
}
if ( GuiButton ( ( Rectangle ) { 190 , 70 , 50 , 20 } , " / " ) )
{
result = variableA / variableB ;
operation [ 0 ] = ' / ' ;
}
DrawText ( operation , 123 , 15 , 10 , DARKGRAY ) ;
GuiFloatBox ( ( Rectangle ) { 55 , 40 , 135 , 20 } , " = " , & result , - 2000000.0 , 2000000.0 , false ) ;
EndDrawing ( ) ;
//----------------------------------------------------------------------------------
}
CloseWindow ( ) ;
}
// Float Box control, updates input text with numbers
int GuiFloatBox ( Rectangle bounds , const char * text , float * value , int minValue , int maxValue , bool editMode )
{
# if !defined(RAYGUI_VALUEBOX_MAX_CHARS)
# define RAYGUI_VALUEBOX_MAX_CHARS 32
# endif
int result = 0 ;
GuiState state = guiState ;
char textValue [ RAYGUI_VALUEBOX_MAX_CHARS + 1 ] = " \0 " ;
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 & & ! guiSliderDragging )
{
Vector2 mousePoint = GetMousePosition ( ) ;
if ( * value > = 0 ) sprintf ( textValue , " +%.3f " , * value ) ;
else sprintf ( textValue , " %.3f " , * value ) ;
bool valueHasChanged = false ;
int keyCount = ( int ) strlen ( textValue ) - guiFloatingPointIndex ;
if ( editMode )
{
state = STATE_PRESSED ;
// Only allow keys in range [48..57]
if ( keyCount < RAYGUI_VALUEBOX_MAX_CHARS )
{
if ( GetTextWidth ( textValue ) < bounds . width )
{
int key = GetCharPressed ( ) ;
if ( ( key > = 48 ) & & ( key < = 57 ) & & guiFloatingPointIndex )
{
if ( guiFloatingPointIndex & & guiFloatingPointIndex ! = 4 ) guiFloatingPointIndex - - ;
textValue [ keyCount ] = ( char ) key ;
textValue [ + + keyCount ] = ' \0 ' ;
valueHasChanged = true ;
}
}
}
// Delete text
if ( keyCount > 0 )
{
if ( IsKeyPressed ( KEY_BACKSPACE ) )
{
if ( guiFloatingPointIndex < 4 ) guiFloatingPointIndex + + ;
keyCount - - ;
textValue [ keyCount ] = ' \0 ' ;
valueHasChanged = true ;
}
}
// Change sign
if ( IsKeyPressed ( KEY_MINUS ) )
{
if ( textValue [ 0 ] = = ' + ' ) textValue [ 0 ] = ' - ' ;
else if ( textValue [ 0 ] = = ' - ' ) textValue [ 0 ] = ' + ' ;
valueHasChanged = true ;
}
// Add decimal separator
if ( ( IsKeyPressed ( KEY_COMMA ) | | IsKeyPressed ( KEY_PERIOD ) ) & & guiFloatingPointIndex = = 4 )
{
guiFloatingPointIndex - - ;
valueHasChanged = true ;
}
if ( valueHasChanged )
{
* value = TextToFloat ( textValue ) ;
}
if ( IsKeyPressed ( KEY_ENTER ) | | ( ! CheckCollisionPointRec ( mousePoint , bounds ) & & IsMouseButtonPressed ( MOUSE_LEFT_BUTTON ) ) )
{
guiFloatingPointIndex = 0 ;
result = 1 ;
}
}
else
{
if ( * value > maxValue ) * value = maxValue ;
else if ( * value < minValue ) * value = minValue ;
if ( CheckCollisionPointRec ( mousePoint , bounds ) )
{
state = STATE_FOCUSED ;
if ( IsMouseButtonPressed ( MOUSE_LEFT_BUTTON ) ) result = 1 ;
}
}
}
//--------------------------------------------------------------------
// Draw control
//--------------------------------------------------------------------
Color baseColor = BLANK ;
sprintf ( textValue , " %.3f " , * value ) ;
if ( state = = STATE_PRESSED )
{
baseColor = GetColor ( GuiGetStyle ( VALUEBOX , BASE_COLOR_PRESSED ) ) ;
textValue [ ( int ) strlen ( textValue ) - guiFloatingPointIndex ] = ' \0 ' ;
}
else if ( state = = STATE_DISABLED ) baseColor = GetColor ( GuiGetStyle ( VALUEBOX , BASE_COLOR_DISABLED ) ) ;
// WARNING: BLANK color does not work properly with Fade()
GuiDrawRectangle ( bounds , GuiGetStyle ( VALUEBOX , BORDER_WIDTH ) , Fade ( GetColor ( GuiGetStyle ( VALUEBOX , BORDER + ( state * 3 ) ) ) , guiAlpha ) , baseColor ) ;
GuiDrawText ( textValue , GetTextBounds ( VALUEBOX , bounds ) , TEXT_ALIGN_CENTER , Fade ( GetColor ( GuiGetStyle ( VALUEBOX , TEXT + ( state * 3 ) ) ) , guiAlpha ) ) ;
// Draw cursor
if ( editMode )
{
// NOTE: ValueBox internal text is always centered
Rectangle cursor = { bounds . x + GetTextWidth ( textValue ) / 2 + bounds . width / 2 + 1 , bounds . y + 2 * GuiGetStyle ( VALUEBOX , BORDER_WIDTH ) , 4 , bounds . height - 4 * GuiGetStyle ( VALUEBOX , BORDER_WIDTH ) } ;
GuiDrawRectangle ( cursor , 0 , BLANK , Fade ( GetColor ( GuiGetStyle ( VALUEBOX , BORDER_COLOR_PRESSED ) ) , guiAlpha ) ) ;
}
// Draw text label if provided
GuiDrawText ( text , textBounds , ( GuiGetStyle ( VALUEBOX , TEXT_ALIGNMENT ) = = TEXT_ALIGN_RIGHT ) ? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT , Fade ( GetColor ( GuiGetStyle ( LABEL , TEXT + ( state * 3 ) ) ) , guiAlpha ) ) ;
//--------------------------------------------------------------------
return result ;
}