|
@@ -5,7 +5,7 @@
|
|
* DESCRIPTION:
|
|
* DESCRIPTION:
|
|
* raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also
|
|
* raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also
|
|
* available as a standalone library, as long as input and drawing functions are provided.
|
|
* available as a standalone library, as long as input and drawing functions are provided.
|
|
-*
|
|
|
|
|
|
+*
|
|
* FEATURES:
|
|
* FEATURES:
|
|
* - Immediate-mode gui, minimal retained data
|
|
* - Immediate-mode gui, minimal retained data
|
|
* - +25 controls provided (basic and advanced)
|
|
* - +25 controls provided (basic and advanced)
|
|
@@ -13,11 +13,11 @@
|
|
* - Icons supported, embeds a complete 1-bit icons pack
|
|
* - Icons supported, embeds a complete 1-bit icons pack
|
|
* - Standalone usage mode option (custom graphics backends)
|
|
* - Standalone usage mode option (custom graphics backends)
|
|
* - Multiple tools provided for raygui development
|
|
* - Multiple tools provided for raygui development
|
|
-*
|
|
|
|
|
|
+*
|
|
* POSSIBLE IMPROVEMENTS:
|
|
* POSSIBLE IMPROVEMENTS:
|
|
* - Allow some controls to work in exclusive mode: GuiSlider(), GuiScrollBar()
|
|
* - Allow some controls to work in exclusive mode: GuiSlider(), GuiScrollBar()
|
|
* - Better standalone mode API for easy plug of custom backends
|
|
* - Better standalone mode API for easy plug of custom backends
|
|
-*
|
|
|
|
|
|
+*
|
|
* LIMITATIONS:
|
|
* LIMITATIONS:
|
|
* - No auto-layout mechanism provided, up to the user to define controls position and size
|
|
* - No auto-layout mechanism provided, up to the user to define controls position and size
|
|
* - Standalone mode requires library modification and some user work to plug another backend
|
|
* - Standalone mode requires library modification and some user work to plug another backend
|
|
@@ -105,7 +105,7 @@
|
|
* layouts must be defined manually on controls drawing, providing the right bounds Rectangle for it.
|
|
* layouts must be defined manually on controls drawing, providing the right bounds Rectangle for it.
|
|
*
|
|
*
|
|
* TOOL: rGuiLayout is a visual tool to create raygui layouts: github.com/raysan5/rguilayout
|
|
* TOOL: rGuiLayout is a visual tool to create raygui layouts: github.com/raysan5/rguilayout
|
|
-*
|
|
|
|
|
|
+*
|
|
* CONFIGURATION:
|
|
* CONFIGURATION:
|
|
* #define RAYGUI_IMPLEMENTATION
|
|
* #define RAYGUI_IMPLEMENTATION
|
|
* Generates the implementation of the library into the included file.
|
|
* Generates the implementation of the library into the included file.
|
|
@@ -188,7 +188,7 @@
|
|
*
|
|
*
|
|
* DEPENDENCIES:
|
|
* DEPENDENCIES:
|
|
* raylib 4.5 Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
|
|
* raylib 4.5 Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
|
|
-*
|
|
|
|
|
|
+*
|
|
* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled
|
|
* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled
|
|
* with the config flag RAYGUI_STANDALONE. In that case is up to the user to provide another backend to cover library needs.
|
|
* with the config flag RAYGUI_STANDALONE. In that case is up to the user to provide another backend to cover library needs.
|
|
*
|
|
*
|
|
@@ -2121,7 +2121,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
{
|
|
{
|
|
#define AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement
|
|
#define AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement
|
|
#define AUTO_CURSOR_DELAY 1 // Frames delay for autocursor movement
|
|
#define AUTO_CURSOR_DELAY 1 // Frames delay for autocursor movement
|
|
-
|
|
|
|
|
|
+
|
|
GuiState state = guiState;
|
|
GuiState state = guiState;
|
|
bool pressed = false;
|
|
bool pressed = false;
|
|
|
|
|
|
@@ -2151,7 +2151,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
|
|
|
|
if (cursor.height >= bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2;
|
|
if (cursor.height >= bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2;
|
|
if (cursor.y < (bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH))) cursor.y = bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH);
|
|
if (cursor.y < (bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH))) cursor.y = bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH);
|
|
-
|
|
|
|
|
|
+
|
|
// Auto-cursor movement logic
|
|
// Auto-cursor movement logic
|
|
// NOTE: Cursor moves automatically when key down after some time
|
|
// NOTE: Cursor moves automatically when key down after some time
|
|
if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE)) autoCursorCooldownCounter++;
|
|
if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE)) autoCursorCooldownCounter++;
|
|
@@ -2175,7 +2175,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
{
|
|
{
|
|
state = STATE_PRESSED;
|
|
state = STATE_PRESSED;
|
|
|
|
|
|
- // If text does not fit in the textbox and current cursor position is out of bounds,
|
|
|
|
|
|
+ // If text does not fit in the textbox and current cursor position is out of bounds,
|
|
// we add an index offset to text for drawing only what requires depending on cursor
|
|
// we add an index offset to text for drawing only what requires depending on cursor
|
|
while (textWidth >= textBounds.width)
|
|
while (textWidth >= textBounds.width)
|
|
{
|
|
{
|
|
@@ -2192,7 +2192,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n';
|
|
if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n';
|
|
|
|
|
|
if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength;
|
|
if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength;
|
|
-
|
|
|
|
|
|
+
|
|
// Encode codepoint as UTF-8
|
|
// Encode codepoint as UTF-8
|
|
int codepointSize = 0;
|
|
int codepointSize = 0;
|
|
const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize);
|
|
const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize);
|
|
@@ -2219,7 +2219,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
{
|
|
{
|
|
autoCursorDelayCounter++;
|
|
autoCursorDelayCounter++;
|
|
|
|
|
|
- if (IsKeyPressed(KEY_BACKSPACE) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
|
|
|
|
|
+ if (IsKeyPressed(KEY_BACKSPACE) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
|
{
|
|
{
|
|
int prevCodepointSize = 0;
|
|
int prevCodepointSize = 0;
|
|
GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
|
|
GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
|
|
@@ -2241,7 +2241,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
{
|
|
{
|
|
autoCursorDelayCounter++;
|
|
autoCursorDelayCounter++;
|
|
|
|
|
|
- if (IsKeyPressed(KEY_LEFT) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
|
|
|
|
|
+ if (IsKeyPressed(KEY_LEFT) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
|
{
|
|
{
|
|
int prevCodepointSize = 0;
|
|
int prevCodepointSize = 0;
|
|
GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
|
|
GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
|
|
@@ -2253,7 +2253,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
{
|
|
{
|
|
autoCursorDelayCounter++;
|
|
autoCursorDelayCounter++;
|
|
|
|
|
|
- if (IsKeyPressed(KEY_RIGHT) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
|
|
|
|
|
+ if (IsKeyPressed(KEY_RIGHT) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
|
{
|
|
{
|
|
int nextCodepointSize = 0;
|
|
int nextCodepointSize = 0;
|
|
GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
|
|
GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
|
|
@@ -2273,7 +2273,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
//if (multiline) cursor.y = GetTextLines()
|
|
//if (multiline) cursor.y = GetTextLines()
|
|
|
|
|
|
// Finish text editing on ENTER (if not multiline mode) or mouse click outside bounds
|
|
// Finish text editing on ENTER (if not multiline mode) or mouse click outside bounds
|
|
- if ((!multiline && IsKeyPressed(KEY_ENTER)) ||
|
|
|
|
|
|
+ if ((!multiline && IsKeyPressed(KEY_ENTER)) ||
|
|
(!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
|
|
(!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
|
|
{
|
|
{
|
|
pressed = true; // Exiting edit mode
|
|
pressed = true; // Exiting edit mode
|
|
@@ -2313,9 +2313,9 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|
GuiDrawText(text + textIndexOffset, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
|
|
GuiDrawText(text + textIndexOffset, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
|
|
|
|
|
|
// Draw cursor
|
|
// Draw cursor
|
|
- if (editMode)
|
|
|
|
|
|
+ if (editMode)
|
|
{
|
|
{
|
|
- //if (autoCursorMode || ((blinkCursorFrameCounter/40)%2 == 0))
|
|
|
|
|
|
+ //if (autoCursorMode || ((blinkCursorFrameCounter/40)%2 == 0))
|
|
GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
|
|
GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
|
|
}
|
|
}
|
|
else if (state == STATE_FOCUSED) GuiTooltip(bounds);
|
|
else if (state == STATE_FOCUSED) GuiTooltip(bounds);
|
|
@@ -4323,26 +4323,26 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
|
|
{
|
|
{
|
|
arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + bounds.height - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
|
|
arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + bounds.height - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
|
|
scrollbar = RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), arrowUpLeft.y + arrowUpLeft.height, bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)), bounds.height - arrowUpLeft.height - arrowDownRight.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) };
|
|
scrollbar = RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), arrowUpLeft.y + arrowUpLeft.height, bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)), bounds.height - arrowUpLeft.height - arrowDownRight.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) };
|
|
-
|
|
|
|
|
|
+
|
|
// Make sure the slider won't get outside of the scrollbar
|
|
// Make sure the slider won't get outside of the scrollbar
|
|
sliderSize = (sliderSize >= scrollbar.height)? ((int)scrollbar.height - 2) : sliderSize;
|
|
sliderSize = (sliderSize >= scrollbar.height)? ((int)scrollbar.height - 2) : sliderSize;
|
|
- slider = RAYGUI_CLITERAL(Rectangle){
|
|
|
|
- bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING),
|
|
|
|
- scrollbar.y + (int)(((float)(value - minValue)/valueRange)*(scrollbar.height - sliderSize)),
|
|
|
|
- bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)),
|
|
|
|
|
|
+ slider = RAYGUI_CLITERAL(Rectangle){
|
|
|
|
+ bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING),
|
|
|
|
+ scrollbar.y + (int)(((float)(value - minValue)/valueRange)*(scrollbar.height - sliderSize)),
|
|
|
|
+ bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)),
|
|
(float)sliderSize };
|
|
(float)sliderSize };
|
|
}
|
|
}
|
|
else // horizontal
|
|
else // horizontal
|
|
{
|
|
{
|
|
arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + bounds.width - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
|
|
arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + bounds.width - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
|
|
scrollbar = RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x + arrowUpLeft.width, bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), bounds.width - arrowUpLeft.width - arrowDownRight.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)) };
|
|
scrollbar = RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x + arrowUpLeft.width, bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), bounds.width - arrowUpLeft.width - arrowDownRight.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)) };
|
|
-
|
|
|
|
|
|
+
|
|
// Make sure the slider won't get outside of the scrollbar
|
|
// Make sure the slider won't get outside of the scrollbar
|
|
sliderSize = (sliderSize >= scrollbar.width)? ((int)scrollbar.width - 2) : sliderSize;
|
|
sliderSize = (sliderSize >= scrollbar.width)? ((int)scrollbar.width - 2) : sliderSize;
|
|
- slider = RAYGUI_CLITERAL(Rectangle){
|
|
|
|
- scrollbar.x + (int)(((float)(value - minValue)/valueRange)*(scrollbar.width - sliderSize)),
|
|
|
|
- bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING),
|
|
|
|
- (float)sliderSize,
|
|
|
|
|
|
+ slider = RAYGUI_CLITERAL(Rectangle){
|
|
|
|
+ scrollbar.x + (int)(((float)(value - minValue)/valueRange)*(scrollbar.width - sliderSize)),
|
|
|
|
+ bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING),
|
|
|
|
+ (float)sliderSize,
|
|
bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)) };
|
|
bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)) };
|
|
}
|
|
}
|
|
|
|
|