mirror of
https://github.com/raysan5/raygui.git
synced 2025-12-25 10:22:33 -05:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa81c167f1 | |||
| 37992af28a | |||
| 9cf37c5e51 | |||
| 60e216283d | |||
| 7f46aa5929 | |||
| b54733ec12 | |||
| 7da92d224d | |||
| 1c7ceb6fda | |||
| 251f7fde3a | |||
| 80e802b18d | |||
| 6fc9337cd8 | |||
| 38a3d100e1 | |||
| 628f2e0290 | |||
| ab209bc5d1 | |||
| 8c14e61214 | |||
| 27caba8834 | |||
| 31b097ee3e | |||
| b0d7073551 | |||
| 731bae72d5 | |||
| 4ad311bd6f | |||
| c4d71e1c0b | |||
| d04c68b915 | |||
| 42aaec6640 | |||
| d05586ef0f |
@ -28,12 +28,12 @@
|
|||||||
### basic controls
|
### basic controls
|
||||||
```
|
```
|
||||||
Label | Button | LabelButton | Toggle | ToggleGroup | CheckBox
|
Label | Button | LabelButton | Toggle | ToggleGroup | CheckBox
|
||||||
ComboBox | DropdownBox | TextBox | TextBoxMulti | ValueBox | Spinner
|
ComboBox | DropdownBox | TextBox | ValueBox | Spinner
|
||||||
Slider | SliderBar | ProgressBar | StatusBar | DummyRec | Grid
|
Slider | SliderBar | ProgressBar | StatusBar | DummyRec | Grid
|
||||||
```
|
```
|
||||||
### container/separator controls
|
### container/separator controls
|
||||||
```
|
```
|
||||||
WindowBox | GroupBox | Line | Panel | ScrollPanel
|
WindowBox | GroupBox | Line | Panel | ScrollPanel | TabBar
|
||||||
```
|
```
|
||||||
### advanced controls
|
### advanced controls
|
||||||
```
|
```
|
||||||
|
|||||||
@ -29,11 +29,11 @@ float GuiVerticalSliderPro(Rectangle bounds, const char *textTop, const char *te
|
|||||||
|
|
||||||
bool GuiSliderOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, bool editMode);
|
bool GuiSliderOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, bool editMode);
|
||||||
bool GuiSliderBarOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, bool editMode);
|
bool GuiSliderBarOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, bool editMode);
|
||||||
float GuiSliderProOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth, bool editMode);
|
bool GuiSliderProOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth, bool editMode);
|
||||||
|
|
||||||
bool GuiVerticalSliderOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, bool editMode);
|
bool GuiVerticalSliderOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, bool editMode);
|
||||||
bool GuiVerticalSliderBarOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, bool editMode);
|
bool GuiVerticalSliderBarOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, bool editMode);
|
||||||
float GuiVerticalSliderProOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, int sliderHeight, bool editMode);
|
bool GuiVerticalSliderProOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, int sliderHeight, bool editMode);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
@ -215,7 +215,7 @@ float GuiVerticalSliderBar(Rectangle bounds, const char *textTop, const char *te
|
|||||||
return GuiVerticalSliderPro(bounds, textTop, textBottom, value, minValue, maxValue, 0);
|
return GuiVerticalSliderPro(bounds, textTop, textBottom, value, minValue, maxValue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float GuiSliderProOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth, bool editMode)
|
bool GuiSliderProOwning(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth, bool editMode)
|
||||||
{
|
{
|
||||||
GuiState state = (GuiState)GuiGetState();
|
GuiState state = (GuiState)GuiGetState();
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ bool GuiSliderBarOwning(Rectangle bounds, const char *textLeft, const char *text
|
|||||||
return GuiSliderProOwning(bounds, textLeft, textRight, value, minValue, maxValue, 0, editMode);
|
return GuiSliderProOwning(bounds, textLeft, textRight, value, minValue, maxValue, 0, editMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
float GuiVerticalSliderProOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, int sliderHeight, bool editMode)
|
bool GuiVerticalSliderProOwning(Rectangle bounds, const char *textTop, const char *textBottom, float *value, float minValue, float maxValue, int sliderHeight, bool editMode)
|
||||||
{
|
{
|
||||||
GuiState state = (GuiState)GuiGetState();
|
GuiState state = (GuiState)GuiGetState();
|
||||||
|
|
||||||
|
|||||||
524
src/raygui.h
524
src/raygui.h
@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* raygui v3.5 - A simple and easy-to-use immediate-mode gui library
|
* raygui v3.6 - A simple and easy-to-use immediate-mode gui library
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -15,10 +15,12 @@
|
|||||||
* - 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()
|
* - Redesign functions that require a value as parameter to be returned, pass by reference
|
||||||
* - Better standalone mode API for easy plug of custom backends
|
* - Better standalone mode API for easy plug of custom backends
|
||||||
|
* - Externalize required inputs in some way, allow user customization
|
||||||
*
|
*
|
||||||
* LIMITATIONS:
|
* LIMITATIONS:
|
||||||
|
* - No multi-line word-wraped text box support
|
||||||
* - 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
|
||||||
*
|
*
|
||||||
@ -124,8 +126,20 @@
|
|||||||
* Includes custom ricons.h header defining a set of custom icons,
|
* Includes custom ricons.h header defining a set of custom icons,
|
||||||
* this file can be generated using rGuiIcons tool
|
* this file can be generated using rGuiIcons tool
|
||||||
*
|
*
|
||||||
|
* #define RAYGUI_DEBUG_TEXT_BOUNDS
|
||||||
|
* Draw text bounds rectangles for debug
|
||||||
*
|
*
|
||||||
* VERSIONS HISTORY:
|
* VERSIONS HISTORY:
|
||||||
|
* 3.6 (10-May-2023) ADDED: New icon: SAND_TIMER
|
||||||
|
* ADDED: GuiLoadStyleFromMemory() (binary only)
|
||||||
|
* REVIEWED: GuiScrollBar() horizontal movement key
|
||||||
|
* REVIEWED: GuiTextBox() crash on cursor movement
|
||||||
|
* REVIEWED: GuiTextBox(), additional inputs support
|
||||||
|
* REVIEWED: GuiLabelButton(), avoid text cut
|
||||||
|
* REVIEWED: GuiTextInputBox(), password input
|
||||||
|
* REVIEWED: Local GetCodepointNext(), aligned with raylib
|
||||||
|
* REDESIGNED: GuiSlider*()/GuiScrollBar() to support out-of-bounds
|
||||||
|
*
|
||||||
* 3.5 (20-Apr-2023) ADDED: GuiTabBar(), based on GuiToggle()
|
* 3.5 (20-Apr-2023) ADDED: GuiTabBar(), based on GuiToggle()
|
||||||
* ADDED: Helper functions to split text in separate lines
|
* ADDED: Helper functions to split text in separate lines
|
||||||
* ADDED: Multiple new icons, useful for code editing tools
|
* ADDED: Multiple new icons, useful for code editing tools
|
||||||
@ -137,6 +151,7 @@
|
|||||||
* REVIEWED: Library header info, more info, better organized
|
* REVIEWED: Library header info, more info, better organized
|
||||||
* REDESIGNED: GuiTextBox() to support cursor movement
|
* REDESIGNED: GuiTextBox() to support cursor movement
|
||||||
* REDESIGNED: GuiDrawText() to divide drawing by lines
|
* REDESIGNED: GuiDrawText() to divide drawing by lines
|
||||||
|
*
|
||||||
* 3.2 (22-May-2022) RENAMED: Some enum values, for unification, avoiding prefixes
|
* 3.2 (22-May-2022) RENAMED: Some enum values, for unification, avoiding prefixes
|
||||||
* REMOVED: GuiScrollBar(), only internal
|
* REMOVED: GuiScrollBar(), only internal
|
||||||
* REDESIGNED: GuiPanel() to support text parameter
|
* REDESIGNED: GuiPanel() to support text parameter
|
||||||
@ -146,6 +161,7 @@
|
|||||||
* REDESIGNED: GuiColorBarAlpha() to support text parameter
|
* REDESIGNED: GuiColorBarAlpha() to support text parameter
|
||||||
* REDESIGNED: GuiColorBarHue() to support text parameter
|
* REDESIGNED: GuiColorBarHue() to support text parameter
|
||||||
* REDESIGNED: GuiTextInputBox() to support password
|
* REDESIGNED: GuiTextInputBox() to support password
|
||||||
|
*
|
||||||
* 3.1 (12-Jan-2022) REVIEWED: Default style for consistency (aligned with rGuiLayout v2.5 tool)
|
* 3.1 (12-Jan-2022) REVIEWED: Default style for consistency (aligned with rGuiLayout v2.5 tool)
|
||||||
* REVIEWED: GuiLoadStyle() to support compressed font atlas image data and unload previous textures
|
* REVIEWED: GuiLoadStyle() to support compressed font atlas image data and unload previous textures
|
||||||
* REVIEWED: External icons usage logic
|
* REVIEWED: External icons usage logic
|
||||||
@ -153,10 +169,12 @@
|
|||||||
* RENAMED: Multiple controls properties definitions to prepend RAYGUI_
|
* RENAMED: Multiple controls properties definitions to prepend RAYGUI_
|
||||||
* RENAMED: RICON_ references to RAYGUI_ICON_ for library consistency
|
* RENAMED: RICON_ references to RAYGUI_ICON_ for library consistency
|
||||||
* Projects updated and multiple tweaks
|
* Projects updated and multiple tweaks
|
||||||
|
*
|
||||||
* 3.0 (04-Nov-2021) Integrated ricons data to avoid external file
|
* 3.0 (04-Nov-2021) Integrated ricons data to avoid external file
|
||||||
* REDESIGNED: GuiTextBoxMulti()
|
* REDESIGNED: GuiTextBoxMulti()
|
||||||
* REMOVED: GuiImageButton*()
|
* REMOVED: GuiImageButton*()
|
||||||
* Multiple minor tweaks and bugs corrected
|
* Multiple minor tweaks and bugs corrected
|
||||||
|
*
|
||||||
* 2.9 (17-Mar-2021) REMOVED: Tooltip API
|
* 2.9 (17-Mar-2021) REMOVED: Tooltip API
|
||||||
* 2.8 (03-May-2020) Centralized rectangles drawing to GuiDrawRectangle()
|
* 2.8 (03-May-2020) Centralized rectangles drawing to GuiDrawRectangle()
|
||||||
* 2.7 (20-Feb-2020) ADDED: Possible tooltips API
|
* 2.7 (20-Feb-2020) ADDED: Possible tooltips API
|
||||||
@ -166,6 +184,7 @@
|
|||||||
* Replaced property INNER_PADDING by TEXT_PADDING, renamed some properties
|
* Replaced property INNER_PADDING by TEXT_PADDING, renamed some properties
|
||||||
* ADDED: 8 new custom styles ready to use
|
* ADDED: 8 new custom styles ready to use
|
||||||
* Multiple minor tweaks and bugs corrected
|
* Multiple minor tweaks and bugs corrected
|
||||||
|
*
|
||||||
* 2.5 (28-May-2019) Implemented extended GuiTextBox(), GuiValueBox(), GuiSpinner()
|
* 2.5 (28-May-2019) Implemented extended GuiTextBox(), GuiValueBox(), GuiSpinner()
|
||||||
* 2.3 (29-Apr-2019) ADDED: rIcons auxiliar library and support for it, multiple controls reviewed
|
* 2.3 (29-Apr-2019) ADDED: rIcons auxiliar library and support for it, multiple controls reviewed
|
||||||
* Refactor all controls drawing mechanism to use control state
|
* Refactor all controls drawing mechanism to use control state
|
||||||
@ -227,9 +246,9 @@
|
|||||||
#define RAYGUI_H
|
#define RAYGUI_H
|
||||||
|
|
||||||
#define RAYGUI_VERSION_MAJOR 3
|
#define RAYGUI_VERSION_MAJOR 3
|
||||||
#define RAYGUI_VERSION_MINOR 5
|
#define RAYGUI_VERSION_MINOR 6
|
||||||
#define RAYGUI_VERSION_PATCH 0
|
#define RAYGUI_VERSION_PATCH 0
|
||||||
#define RAYGUI_VERSION "3.5"
|
#define RAYGUI_VERSION "3.6"
|
||||||
|
|
||||||
#if !defined(RAYGUI_STANDALONE)
|
#if !defined(RAYGUI_STANDALONE)
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
@ -826,7 +845,7 @@ typedef enum {
|
|||||||
ICON_REG_EXP = 216,
|
ICON_REG_EXP = 216,
|
||||||
ICON_FOLDER = 217,
|
ICON_FOLDER = 217,
|
||||||
ICON_FILE = 218,
|
ICON_FILE = 218,
|
||||||
ICON_219 = 219,
|
ICON_SAND_TIMER = 219,
|
||||||
ICON_220 = 220,
|
ICON_220 = 220,
|
||||||
ICON_221 = 221,
|
ICON_221 = 221,
|
||||||
ICON_222 = 222,
|
ICON_222 = 222,
|
||||||
@ -894,6 +913,11 @@ typedef enum {
|
|||||||
#define RAYGUI_CLITERAL(name) (name)
|
#define RAYGUI_CLITERAL(name) (name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Check if two rectangles are equal, used to validate a slider bounds as an id
|
||||||
|
#ifndef CHECK_BOUNDS_ID
|
||||||
|
#define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height))
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS)
|
#if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS)
|
||||||
|
|
||||||
// Embedded icons, no external file provided
|
// Embedded icons, no external file provided
|
||||||
@ -1139,7 +1163,7 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] =
|
|||||||
0x00000000, 0x02000000, 0x07000a80, 0x07001fc0, 0x02000a80, 0x00300030, 0x00000000, 0x00000000, // ICON_REG_EXP
|
0x00000000, 0x02000000, 0x07000a80, 0x07001fc0, 0x02000a80, 0x00300030, 0x00000000, 0x00000000, // ICON_REG_EXP
|
||||||
0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_FOLDER
|
0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_FOLDER
|
||||||
0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE
|
0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_219
|
0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_220
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_220
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_221
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_221
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_222
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_222
|
||||||
@ -1211,7 +1235,10 @@ static unsigned int guiIconScale = 1; // Gui icon default scale (if ic
|
|||||||
static bool guiTooltip = false; // Tooltip enabled/disabled
|
static bool guiTooltip = false; // Tooltip enabled/disabled
|
||||||
static const char *guiTooltipPtr = NULL; // Tooltip string pointer (string provided by user)
|
static const char *guiTooltipPtr = NULL; // Tooltip string pointer (string provided by user)
|
||||||
|
|
||||||
static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*()
|
static bool guiSliderDragging = false; // Gui slider drag state (no inputs processed except dragged slider)
|
||||||
|
static Rectangle guiSliderActive = { 0 }; // Gui slider active bounds rectangle, used as an unique identifier
|
||||||
|
|
||||||
|
static unsigned int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*()
|
||||||
//static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking
|
//static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking
|
||||||
static int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down
|
static int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down
|
||||||
static int autoCursorDelayCounter = 0; // Delay frame counter for automatic cursor movement
|
static int autoCursorDelayCounter = 0; // Delay frame counter for automatic cursor movement
|
||||||
@ -1300,6 +1327,8 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only)
|
||||||
|
|
||||||
static int GetTextWidth(const char *text); // Gui get text width using gui font and style
|
static int GetTextWidth(const char *text); // Gui get text width using gui font and style
|
||||||
static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds
|
static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds
|
||||||
static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor
|
static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor
|
||||||
@ -1483,7 +1512,7 @@ void GuiLine(Rectangle bounds, const char *text)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Rectangle textBounds = { 0 };
|
Rectangle textBounds = { 0 };
|
||||||
textBounds.width = (float)GetTextWidth(text);
|
textBounds.width = (float)GetTextWidth(text) + 2;
|
||||||
textBounds.height = bounds.height;
|
textBounds.height = bounds.height;
|
||||||
textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT;
|
textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT;
|
||||||
textBounds.y = bounds.y;
|
textBounds.y = bounds.y;
|
||||||
@ -1656,8 +1685,8 @@ Rectangle GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content,
|
|||||||
#endif
|
#endif
|
||||||
float wheelMove = GetMouseWheelMove();
|
float wheelMove = GetMouseWheelMove();
|
||||||
|
|
||||||
// Horizontal scroll (Shift + Mouse wheel)
|
// Horizontal scroll ((Left Control or Left Shift) + Mouse wheel)
|
||||||
if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_SHIFT))) scrollPos.x += wheelMove*20;
|
if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*20;
|
||||||
else scrollPos.y += wheelMove*20; // Vertical scroll
|
else scrollPos.y += wheelMove*20; // Vertical scroll
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1739,7 +1768,7 @@ bool GuiButton(Rectangle bounds, const char *text)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -1773,11 +1802,11 @@ bool GuiLabelButton(Rectangle bounds, const char *text)
|
|||||||
|
|
||||||
// NOTE: We force bounds.width to be all text
|
// NOTE: We force bounds.width to be all text
|
||||||
float textWidth = (float)GetTextWidth(text);
|
float textWidth = (float)GetTextWidth(text);
|
||||||
if (bounds.width < textWidth) bounds.width = textWidth;
|
if ((bounds.width - 2*GuiGetStyle(LABEL, BORDER_WIDTH) - 2*GuiGetStyle(LABEL, TEXT_PADDING)) < textWidth) bounds.width = textWidth + 2*GuiGetStyle(LABEL, BORDER_WIDTH) + 2*GuiGetStyle(LABEL, TEXT_PADDING) + 2;
|
||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -1807,7 +1836,7 @@ bool GuiToggle(Rectangle bounds, const char *text, bool active)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -1887,7 +1916,7 @@ bool GuiCheckBox(Rectangle bounds, const char *text, bool checked)
|
|||||||
|
|
||||||
if (text != NULL)
|
if (text != NULL)
|
||||||
{
|
{
|
||||||
textBounds.width = (float)GetTextWidth(text);
|
textBounds.width = (float)GetTextWidth(text) + 2;
|
||||||
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
|
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
|
||||||
textBounds.x = bounds.x + bounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING);
|
textBounds.x = bounds.x + bounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING);
|
||||||
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
||||||
@ -1896,7 +1925,7 @@ bool GuiCheckBox(Rectangle bounds, const char *text, bool checked)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -1956,7 +1985,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int active)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1))
|
if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2018,7 +2047,7 @@ bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMo
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1))
|
if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2118,7 +2147,7 @@ bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMo
|
|||||||
bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
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 3 // 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;
|
||||||
@ -2152,7 +2181,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|||||||
|
|
||||||
// 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) || IsKeyDown(KEY_DELETE)) autoCursorCooldownCounter++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter
|
autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter
|
||||||
@ -2165,7 +2194,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2189,6 +2218,8 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|||||||
int codepoint = GetCharPressed(); // Get Unicode codepoint
|
int codepoint = GetCharPressed(); // Get Unicode codepoint
|
||||||
if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n';
|
if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n';
|
||||||
|
|
||||||
|
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);
|
||||||
@ -2210,7 +2241,39 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|||||||
text[textLength] = '\0';
|
text[textLength] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete codepoint from text, at current cursor position
|
// Move cursor to start
|
||||||
|
if ((textLength > 0) && IsKeyPressed(KEY_HOME))
|
||||||
|
{
|
||||||
|
textBoxCursorIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move cursor to end
|
||||||
|
if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END))
|
||||||
|
{
|
||||||
|
textBoxCursorIndex = textLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete codepoint from text, after current cursor position
|
||||||
|
if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && (autoCursorCooldownCounter >= AUTO_CURSOR_COOLDOWN))))
|
||||||
|
{
|
||||||
|
autoCursorDelayCounter++;
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_DELETE) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
||||||
|
{
|
||||||
|
int nextCodepointSize = 0;
|
||||||
|
GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
|
||||||
|
|
||||||
|
// Move backward text from cursor position
|
||||||
|
for (int i = textBoxCursorIndex; i < textLength; i++) text[i] = text[i + nextCodepointSize];
|
||||||
|
|
||||||
|
textLength -= codepointSize;
|
||||||
|
|
||||||
|
// Make sure text last character is EOL
|
||||||
|
text[textLength] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete codepoint from text, before current cursor position
|
||||||
if ((textLength > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && (autoCursorCooldownCounter >= AUTO_CURSOR_COOLDOWN))))
|
if ((textLength > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && (autoCursorCooldownCounter >= AUTO_CURSOR_COOLDOWN))))
|
||||||
{
|
{
|
||||||
autoCursorDelayCounter++;
|
autoCursorDelayCounter++;
|
||||||
@ -2223,8 +2286,12 @@ bool GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
|
|||||||
// Move backward text from cursor position
|
// Move backward text from cursor position
|
||||||
for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize];
|
for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize];
|
||||||
|
|
||||||
textBoxCursorIndex -= codepointSize;
|
// Prevent cursor index from decrementing past 0
|
||||||
textLength -= codepointSize;
|
if (textBoxCursorIndex > 0)
|
||||||
|
{
|
||||||
|
textBoxCursorIndex -= codepointSize;
|
||||||
|
textLength -= codepointSize;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure text last character is EOL
|
// Make sure text last character is EOL
|
||||||
text[textLength] = '\0';
|
text[textLength] = '\0';
|
||||||
@ -2331,7 +2398,8 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int bufferSize, bool editMode
|
|||||||
GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT_VERTICAL, 1);
|
GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT_VERTICAL, 1);
|
||||||
GuiSetStyle(TEXTBOX, TEXT_MULTILINE, 1);
|
GuiSetStyle(TEXTBOX, TEXT_MULTILINE, 1);
|
||||||
|
|
||||||
pressed = GuiTextBox(bounds, text, bufferSize, editMode); // TODO: Implement methods to calculate cursor position properly
|
// TODO: Implement methods to calculate cursor position properly
|
||||||
|
pressed = GuiTextBox(bounds, text, bufferSize, editMode);
|
||||||
|
|
||||||
GuiSetStyle(TEXTBOX, TEXT_MULTILINE, 0);
|
GuiSetStyle(TEXTBOX, TEXT_MULTILINE, 0);
|
||||||
GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT_VERTICAL, 0);
|
GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT_VERTICAL, 0);
|
||||||
@ -2356,7 +2424,7 @@ bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, in
|
|||||||
Rectangle textBounds = { 0 };
|
Rectangle textBounds = { 0 };
|
||||||
if (text != NULL)
|
if (text != NULL)
|
||||||
{
|
{
|
||||||
textBounds.width = (float)GetTextWidth(text);
|
textBounds.width = (float)GetTextWidth(text) + 2;
|
||||||
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
|
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
|
||||||
textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING);
|
textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING);
|
||||||
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
||||||
@ -2365,7 +2433,7 @@ bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, in
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2394,7 +2462,6 @@ bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, in
|
|||||||
|
|
||||||
// Draw control
|
// Draw control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// TODO: Set Spinner properties for ValueBox
|
|
||||||
pressed = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode);
|
pressed = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode);
|
||||||
|
|
||||||
// Draw value selector custom buttons
|
// Draw value selector custom buttons
|
||||||
@ -2432,7 +2499,7 @@ bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, i
|
|||||||
Rectangle textBounds = { 0 };
|
Rectangle textBounds = { 0 };
|
||||||
if (text != NULL)
|
if (text != NULL)
|
||||||
{
|
{
|
||||||
textBounds.width = (float)GetTextWidth(text);
|
textBounds.width = (float)GetTextWidth(text) + 2;
|
||||||
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
|
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
|
||||||
textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING);
|
textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING);
|
||||||
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
||||||
@ -2441,7 +2508,7 @@ bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, i
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2554,11 +2621,29 @@ float GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight
|
|||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
if (CheckCollisionPointRec(mousePoint, bounds))
|
if (guiSliderDragging) // Keep dragging outside of bounds
|
||||||
|
{
|
||||||
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
|
{
|
||||||
|
if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
|
||||||
|
{
|
||||||
|
// Get equivalent value and slider position from mousePoint.x
|
||||||
|
value = ((maxValue - minValue)*(mousePoint.x - (float)(bounds.x + sliderWidth/2)))/(float)(bounds.width - sliderWidth) + minValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guiSliderDragging = false;
|
||||||
|
guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CheckCollisionPointRec(mousePoint, bounds))
|
||||||
{
|
{
|
||||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
state = STATE_PRESSED;
|
state = STATE_PRESSED;
|
||||||
|
guiSliderDragging = true;
|
||||||
|
guiSliderActive = bounds; // Store bounds as an identifier when dragging starts
|
||||||
|
|
||||||
// Get equivalent value and slider position from mousePoint.x
|
// Get equivalent value and slider position from mousePoint.x
|
||||||
value = ((maxValue - minValue)*(mousePoint.x - (float)(bounds.x + sliderWidth/2)))/(float)(bounds.width - sliderWidth) + minValue;
|
value = ((maxValue - minValue)*(mousePoint.x - (float)(bounds.x + sliderWidth/2)))/(float)(bounds.width - sliderWidth) + minValue;
|
||||||
@ -2703,7 +2788,7 @@ void GuiDummyRec(Rectangle bounds, const char *text)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2763,7 +2848,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *focus, in
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2901,7 +2986,7 @@ Color GuiColorPanel(Rectangle bounds, const char *text, Color color)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
@ -2974,12 +3059,30 @@ float GuiColorBarAlpha(Rectangle bounds, const char *text, float alpha)
|
|||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
if (CheckCollisionPointRec(mousePoint, bounds) ||
|
if (guiSliderDragging) // Keep dragging outside of bounds
|
||||||
CheckCollisionPointRec(mousePoint, selector))
|
{
|
||||||
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
|
{
|
||||||
|
if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
|
||||||
|
{
|
||||||
|
alpha = (mousePoint.x - bounds.x)/bounds.width;
|
||||||
|
if (alpha <= 0.0f) alpha = 0.0f;
|
||||||
|
if (alpha >= 1.0f) alpha = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guiSliderDragging = false;
|
||||||
|
guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector))
|
||||||
{
|
{
|
||||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
state = STATE_PRESSED;
|
state = STATE_PRESSED;
|
||||||
|
guiSliderDragging = true;
|
||||||
|
guiSliderActive = bounds; // Store bounds as an identifier when dragging starts
|
||||||
|
|
||||||
alpha = (mousePoint.x - bounds.x)/bounds.width;
|
alpha = (mousePoint.x - bounds.x)/bounds.width;
|
||||||
if (alpha <= 0.0f) alpha = 0.0f;
|
if (alpha <= 0.0f) alpha = 0.0f;
|
||||||
@ -3039,12 +3142,30 @@ float GuiColorBarHue(Rectangle bounds, const char *text, float hue)
|
|||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
if (CheckCollisionPointRec(mousePoint, bounds) ||
|
if (guiSliderDragging) // Keep dragging outside of bounds
|
||||||
CheckCollisionPointRec(mousePoint, selector))
|
{
|
||||||
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
|
{
|
||||||
|
if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
|
||||||
|
{
|
||||||
|
hue = (mousePoint.y - bounds.y)*360/bounds.height;
|
||||||
|
if (hue <= 0.0f) hue = 0.0f;
|
||||||
|
if (hue >= 359.0f) hue = 359.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guiSliderDragging = false;
|
||||||
|
guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector))
|
||||||
{
|
{
|
||||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
state = STATE_PRESSED;
|
state = STATE_PRESSED;
|
||||||
|
guiSliderDragging = true;
|
||||||
|
guiSliderActive = bounds; // Store bounds as an identifier when dragging starts
|
||||||
|
|
||||||
hue = (mousePoint.y - bounds.y)*360/bounds.height;
|
hue = (mousePoint.y - bounds.y)*360/bounds.height;
|
||||||
if (hue <= 0.0f) hue = 0.0f;
|
if (hue <= 0.0f) hue = 0.0f;
|
||||||
@ -3197,7 +3318,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
|
|||||||
Rectangle textBounds = { 0 };
|
Rectangle textBounds = { 0 };
|
||||||
if (message != NULL)
|
if (message != NULL)
|
||||||
{
|
{
|
||||||
int textSize = GetTextWidth(message);
|
int textSize = GetTextWidth(message) + 2;
|
||||||
|
|
||||||
textBounds.x = bounds.x + bounds.width/2 - textSize/2;
|
textBounds.x = bounds.x + bounds.width/2 - textSize/2;
|
||||||
textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + messageInputHeight/4 - (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + messageInputHeight/4 - (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
|
||||||
@ -3248,6 +3369,8 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
|
|||||||
buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING);
|
buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (btnIndex >= 0) textEditMode = false;
|
||||||
|
|
||||||
GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevBtnTextAlignment);
|
GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevBtnTextAlignment);
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
@ -3274,7 +3397,7 @@ Vector2 GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs)
|
|||||||
|
|
||||||
// Update control
|
// Update control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
if ((state != STATE_DISABLED) && !guiLocked)
|
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
if (CheckCollisionPointRec(mousePoint, bounds))
|
if (CheckCollisionPointRec(mousePoint, bounds))
|
||||||
{
|
{
|
||||||
@ -3287,9 +3410,6 @@ Vector2 GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs)
|
|||||||
|
|
||||||
// Draw control
|
// Draw control
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
// TODO: Draw background panel?
|
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case STATE_NORMAL:
|
case STATE_NORMAL:
|
||||||
@ -3426,125 +3546,24 @@ void GuiLoadStyle(const char *fileName)
|
|||||||
{
|
{
|
||||||
rgsFile = fopen(fileName, "rb");
|
rgsFile = fopen(fileName, "rb");
|
||||||
|
|
||||||
if (rgsFile == NULL) return;
|
if (rgsFile != NULL)
|
||||||
|
|
||||||
char signature[5] = { 0 };
|
|
||||||
short version = 0;
|
|
||||||
short reserved = 0;
|
|
||||||
int propertyCount = 0;
|
|
||||||
|
|
||||||
fread(signature, 1, 4, rgsFile);
|
|
||||||
fread(&version, sizeof(short), 1, rgsFile);
|
|
||||||
fread(&reserved, sizeof(short), 1, rgsFile);
|
|
||||||
fread(&propertyCount, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
if ((signature[0] == 'r') &&
|
|
||||||
(signature[1] == 'G') &&
|
|
||||||
(signature[2] == 'S') &&
|
|
||||||
(signature[3] == ' '))
|
|
||||||
{
|
{
|
||||||
short controlId = 0;
|
fseek(rgsFile, 0, SEEK_END);
|
||||||
short propertyId = 0;
|
int fileDataSize = ftell(rgsFile);
|
||||||
unsigned int propertyValue = 0;
|
fseek(rgsFile, 0, SEEK_SET);
|
||||||
|
|
||||||
for (int i = 0; i < propertyCount; i++)
|
if (fileDataSize > 0)
|
||||||
{
|
{
|
||||||
fread(&controlId, sizeof(short), 1, rgsFile);
|
unsigned char *fileData = (unsigned char *)RL_MALLOC(fileDataSize*sizeof(unsigned char));
|
||||||
fread(&propertyId, sizeof(short), 1, rgsFile);
|
fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile);
|
||||||
fread(&propertyValue, sizeof(unsigned int), 1, rgsFile);
|
|
||||||
|
|
||||||
if (controlId == 0) // DEFAULT control
|
GuiLoadStyleFromMemory(fileData, fileDataSize);
|
||||||
{
|
|
||||||
// If a DEFAULT property is loaded, it is propagated to all controls
|
|
||||||
// NOTE: All DEFAULT properties should be defined first in the file
|
|
||||||
GuiSetStyle(0, (int)propertyId, propertyValue);
|
|
||||||
|
|
||||||
if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) GuiSetStyle(i, (int)propertyId, propertyValue);
|
RL_FREE(fileData);
|
||||||
}
|
|
||||||
else GuiSetStyle((int)controlId, (int)propertyId, propertyValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Font loading is highly dependant on raylib API to load font data and image
|
fclose(rgsFile);
|
||||||
#if !defined(RAYGUI_STANDALONE)
|
|
||||||
// Load custom font if available
|
|
||||||
int fontDataSize = 0;
|
|
||||||
fread(&fontDataSize, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
if (fontDataSize > 0)
|
|
||||||
{
|
|
||||||
Font font = { 0 };
|
|
||||||
int fontType = 0; // 0-Normal, 1-SDF
|
|
||||||
Rectangle whiteRec = { 0 };
|
|
||||||
|
|
||||||
fread(&font.baseSize, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphCount, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&fontType, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
// Load font white rectangle
|
|
||||||
fread(&whiteRec, sizeof(Rectangle), 1, rgsFile);
|
|
||||||
|
|
||||||
// Load font image parameters
|
|
||||||
int fontImageUncompSize = 0;
|
|
||||||
int fontImageCompSize = 0;
|
|
||||||
fread(&fontImageUncompSize, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&fontImageCompSize, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
Image imFont = { 0 };
|
|
||||||
imFont.mipmaps = 1;
|
|
||||||
fread(&imFont.width, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&imFont.height, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&imFont.format, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
if (fontImageCompSize < fontImageUncompSize)
|
|
||||||
{
|
|
||||||
// Compressed font atlas image data (DEFLATE), it requires DecompressData()
|
|
||||||
int dataUncompSize = 0;
|
|
||||||
unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize);
|
|
||||||
fread(compData, 1, fontImageCompSize, rgsFile);
|
|
||||||
imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize);
|
|
||||||
|
|
||||||
// Security check, dataUncompSize must match the provided fontImageUncompSize
|
|
||||||
if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted");
|
|
||||||
|
|
||||||
RAYGUI_FREE(compData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Font atlas image data is not compressed
|
|
||||||
imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize);
|
|
||||||
fread(imFont.data, 1, fontImageUncompSize, rgsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
|
|
||||||
font.texture = LoadTextureFromImage(imFont);
|
|
||||||
if (font.texture.id == 0) font = GetFontDefault();
|
|
||||||
|
|
||||||
RAYGUI_FREE(imFont.data);
|
|
||||||
|
|
||||||
// Load font recs data
|
|
||||||
font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle));
|
|
||||||
for (int i = 0; i < font.glyphCount; i++) fread(&font.recs[i], sizeof(Rectangle), 1, rgsFile);
|
|
||||||
|
|
||||||
// Load font chars info data
|
|
||||||
font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo));
|
|
||||||
for (int i = 0; i < font.glyphCount; i++)
|
|
||||||
{
|
|
||||||
fread(&font.glyphs[i].value, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphs[i].offsetX, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphs[i].offsetY, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphs[i].advanceX, sizeof(int), 1, rgsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
GuiSetFont(font);
|
|
||||||
|
|
||||||
// Set font texture source rectangle to be used as white texture to draw shapes
|
|
||||||
// NOTE: This way, all gui can be draw using a single draw call
|
|
||||||
if ((whiteRec.width != 0) && (whiteRec.height != 0)) SetShapesTexture(font.texture, whiteRec);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(rgsFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3603,7 +3622,7 @@ void GuiLoadStyleDefault(void)
|
|||||||
GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2);
|
GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2);
|
||||||
GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16);
|
GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16);
|
||||||
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2);
|
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2);
|
||||||
GuiSetStyle(TEXTBOX, TEXT_LINES_SPACING, 4);
|
GuiSetStyle(TEXTBOX, TEXT_LINES_SPACING, (int)((float)GuiGetStyle(DEFAULT, TEXT_SIZE)*1.5f));
|
||||||
GuiSetStyle(TEXTBOX, TEXT_INNER_PADDING, 4);
|
GuiSetStyle(TEXTBOX, TEXT_INNER_PADDING, 4);
|
||||||
GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24);
|
GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24);
|
||||||
GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2);
|
GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2);
|
||||||
@ -3632,9 +3651,10 @@ void GuiLoadStyleDefault(void)
|
|||||||
// Setup default raylib font
|
// Setup default raylib font
|
||||||
guiFont = GetFontDefault();
|
guiFont = GetFontDefault();
|
||||||
|
|
||||||
// Setup default raylib font rectangle
|
// NOTE: Default raylib font character 95 is a white square
|
||||||
Rectangle whiteChar = { 41, 46, 2, 8 };
|
Rectangle whiteChar = guiFont.recs[95];
|
||||||
SetShapesTexture(guiFont.texture, whiteChar);
|
// NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
|
||||||
|
SetShapesTexture(guiFont.texture, RAYGUI_CLITERAL(Rectangle){ whiteChar.x + 1, whiteChar.y + 1, whiteChar.width - 2, whiteChar.height - 2 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3781,6 +3801,145 @@ void GuiSetIconScale(int scale)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Load style from memory (binary only)
|
||||||
|
static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize)
|
||||||
|
{
|
||||||
|
unsigned char *fileDataPtr = (unsigned char *)fileData;
|
||||||
|
|
||||||
|
char signature[5] = { 0 };
|
||||||
|
short version = 0;
|
||||||
|
short reserved = 0;
|
||||||
|
int propertyCount = 0;
|
||||||
|
|
||||||
|
memcpy(signature, fileDataPtr, 4);
|
||||||
|
memcpy(&version, fileDataPtr + 4, sizeof(short));
|
||||||
|
memcpy(&reserved, fileDataPtr + 4 + 2, sizeof(short));
|
||||||
|
memcpy(&propertyCount, fileDataPtr + 4 + 2 + 2, sizeof(int));
|
||||||
|
fileDataPtr += 12;
|
||||||
|
|
||||||
|
if ((signature[0] == 'r') &&
|
||||||
|
(signature[1] == 'G') &&
|
||||||
|
(signature[2] == 'S') &&
|
||||||
|
(signature[3] == ' '))
|
||||||
|
{
|
||||||
|
short controlId = 0;
|
||||||
|
short propertyId = 0;
|
||||||
|
unsigned int propertyValue = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < propertyCount; i++)
|
||||||
|
{
|
||||||
|
memcpy(&controlId, fileDataPtr, sizeof(short));
|
||||||
|
memcpy(&propertyId, fileDataPtr + 2, sizeof(short));
|
||||||
|
memcpy(&propertyValue, fileDataPtr + 2 + 2, sizeof(unsigned int));
|
||||||
|
fileDataPtr += 8;
|
||||||
|
|
||||||
|
if (controlId == 0) // DEFAULT control
|
||||||
|
{
|
||||||
|
// If a DEFAULT property is loaded, it is propagated to all controls
|
||||||
|
// NOTE: All DEFAULT properties should be defined first in the file
|
||||||
|
GuiSetStyle(0, (int)propertyId, propertyValue);
|
||||||
|
|
||||||
|
if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) GuiSetStyle(i, (int)propertyId, propertyValue);
|
||||||
|
}
|
||||||
|
else GuiSetStyle((int)controlId, (int)propertyId, propertyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Font loading is highly dependant on raylib API to load font data and image
|
||||||
|
|
||||||
|
#if !defined(RAYGUI_STANDALONE)
|
||||||
|
// Load custom font if available
|
||||||
|
int fontDataSize = 0;
|
||||||
|
memcpy(&fontDataSize, fileDataPtr, sizeof(int));
|
||||||
|
fileDataPtr += 4;
|
||||||
|
|
||||||
|
if (fontDataSize > 0)
|
||||||
|
{
|
||||||
|
Font font = { 0 };
|
||||||
|
int fontType = 0; // 0-Normal, 1-SDF
|
||||||
|
Rectangle whiteRec = { 0 };
|
||||||
|
|
||||||
|
memcpy(&font.baseSize, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&font.glyphCount, fileDataPtr + 4, sizeof(int));
|
||||||
|
memcpy(&fontType, fileDataPtr + 4 + 4, sizeof(int));
|
||||||
|
fileDataPtr += 12;
|
||||||
|
|
||||||
|
// Load font white rectangle
|
||||||
|
memcpy(&whiteRec, fileDataPtr, sizeof(Rectangle));
|
||||||
|
fileDataPtr += 16;
|
||||||
|
|
||||||
|
// Load font image parameters
|
||||||
|
int fontImageUncompSize = 0;
|
||||||
|
int fontImageCompSize = 0;
|
||||||
|
memcpy(&fontImageUncompSize, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&fontImageCompSize, fileDataPtr + 4, sizeof(int));
|
||||||
|
fileDataPtr += 8;
|
||||||
|
|
||||||
|
Image imFont = { 0 };
|
||||||
|
imFont.mipmaps = 1;
|
||||||
|
memcpy(&imFont.width, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&imFont.height, fileDataPtr + 4, sizeof(int));
|
||||||
|
memcpy(&imFont.format, fileDataPtr + 4 + 4, sizeof(int));
|
||||||
|
fileDataPtr += 12;
|
||||||
|
|
||||||
|
if (fontImageCompSize < fontImageUncompSize)
|
||||||
|
{
|
||||||
|
// Compressed font atlas image data (DEFLATE), it requires DecompressData()
|
||||||
|
int dataUncompSize = 0;
|
||||||
|
unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize);
|
||||||
|
memcpy(compData, fileDataPtr, fontImageCompSize);
|
||||||
|
fileDataPtr += fontImageCompSize;
|
||||||
|
|
||||||
|
imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize);
|
||||||
|
|
||||||
|
// Security check, dataUncompSize must match the provided fontImageUncompSize
|
||||||
|
if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted");
|
||||||
|
|
||||||
|
RAYGUI_FREE(compData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Font atlas image data is not compressed
|
||||||
|
imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize);
|
||||||
|
memcpy(imFont.data, fileDataPtr, fontImageUncompSize);
|
||||||
|
fileDataPtr += fontImageUncompSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
|
||||||
|
font.texture = LoadTextureFromImage(imFont);
|
||||||
|
if (font.texture.id == 0) font = GetFontDefault();
|
||||||
|
|
||||||
|
RAYGUI_FREE(imFont.data);
|
||||||
|
|
||||||
|
// Load font recs data
|
||||||
|
font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle));
|
||||||
|
for (int i = 0; i < font.glyphCount; i++)
|
||||||
|
{
|
||||||
|
memcpy(&font.recs[i], fileDataPtr, sizeof(Rectangle));
|
||||||
|
fileDataPtr += sizeof(Rectangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load font chars info data
|
||||||
|
font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo));
|
||||||
|
for (int i = 0; i < font.glyphCount; i++)
|
||||||
|
{
|
||||||
|
memcpy(&font.glyphs[i].value, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&font.glyphs[i].offsetX, fileDataPtr + 4, sizeof(int));
|
||||||
|
memcpy(&font.glyphs[i].offsetY, fileDataPtr + 8, sizeof(int));
|
||||||
|
memcpy(&font.glyphs[i].advanceX, fileDataPtr + 12, sizeof(int));
|
||||||
|
fileDataPtr += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiSetFont(font);
|
||||||
|
|
||||||
|
// Set font texture source rectangle to be used as white texture to draw shapes
|
||||||
|
// NOTE: This way, all gui can be draw using a single draw call
|
||||||
|
if ((whiteRec.width != 0) && (whiteRec.height != 0)) SetShapesTexture(font.texture, whiteRec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Gui get text width considering icon
|
// Gui get text width considering icon
|
||||||
static int GetTextWidth(const char *text)
|
static int GetTextWidth(const char *text)
|
||||||
{
|
{
|
||||||
@ -3795,7 +3954,7 @@ static int GetTextWidth(const char *text)
|
|||||||
{
|
{
|
||||||
if (text[0] == '#')
|
if (text[0] == '#')
|
||||||
{
|
{
|
||||||
for (int i = 1; (text[i] != '\0') && (i < 5); i++)
|
for (int i = 1; (i < 5) && (text[i] != '\0'); i++)
|
||||||
{
|
{
|
||||||
if (text[i] == '#')
|
if (text[i] == '#')
|
||||||
{
|
{
|
||||||
@ -3854,10 +4013,10 @@ static Rectangle GetTextBounds(int control, Rectangle bounds)
|
|||||||
textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING);
|
textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING);
|
||||||
|
|
||||||
// Consider TEXT_PADDING properly, depends on control type and TEXT_ALIGNMENT
|
// Consider TEXT_PADDING properly, depends on control type and TEXT_ALIGNMENT
|
||||||
|
// TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW (scrollbar?)
|
||||||
|
// More special cases (label on side): CHECKBOX, SLIDER, VALUEBOX, SPINNER
|
||||||
switch (control)
|
switch (control)
|
||||||
{
|
{
|
||||||
//case TEXTBOX: break; // TODO: Consider multi-line text?
|
|
||||||
//case VALUEBOX: break; // NOTE: ValueBox text value always centered, text padding applies to label
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (GuiGetStyle(control, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING);
|
if (GuiGetStyle(control, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING);
|
||||||
@ -3866,9 +4025,6 @@ static Rectangle GetTextBounds(int control, Rectangle bounds)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW (scrollbar?)
|
|
||||||
// More special cases (label on side): CHECKBOX, SLIDER, VALUEBOX, SPINNER
|
|
||||||
|
|
||||||
return textBounds;
|
return textBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3969,7 +4125,7 @@ static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
Vector2 position = { bounds.x, bounds.y };
|
Vector2 position = { bounds.x, bounds.y };
|
||||||
|
|
||||||
// TODO: We get text size after icon has been processed
|
// NOTE: We get text size after icon has been processed
|
||||||
// WARNING: GetTextWidth() also processes text icon to get width! -> Really needed?
|
// WARNING: GetTextWidth() also processes text icon to get width! -> Really needed?
|
||||||
int textSizeX = GetTextWidth(lines[i]);
|
int textSizeX = GetTextWidth(lines[i]);
|
||||||
|
|
||||||
@ -4051,10 +4207,14 @@ static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_SIZE)*1.5f; // TODO: GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)?
|
// TODO: Allow users to set line spacing for text: GuiSetStyle(TEXTBOX, TEXT_LINES_SPACING, x)
|
||||||
|
posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_SIZE)*1.5f;
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(RAYGUI_DEBUG_TEXT_BOUNDS)
|
||||||
|
GuiDrawRectangle(bounds, 0, WHITE, Fade(RED, 0.4f));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gui draw rectangle using default raygui plain style with borders
|
// Gui draw rectangle using default raygui plain style with borders
|
||||||
@ -4079,7 +4239,7 @@ static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor,
|
|||||||
// Draw tooltip using control bounds
|
// Draw tooltip using control bounds
|
||||||
static void GuiTooltip(Rectangle controlRec)
|
static void GuiTooltip(Rectangle controlRec)
|
||||||
{
|
{
|
||||||
if (!guiLocked && guiTooltip && (guiTooltipPtr != NULL))
|
if (!guiLocked && guiTooltip && (guiTooltipPtr != NULL) && !guiSliderDragging)
|
||||||
{
|
{
|
||||||
Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, GuiGetStyle(DEFAULT, TEXT_SIZE), GuiGetStyle(DEFAULT, TEXT_SPACING));
|
Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, GuiGetStyle(DEFAULT, TEXT_SIZE), GuiGetStyle(DEFAULT, TEXT_SPACING));
|
||||||
|
|
||||||
@ -4108,7 +4268,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
|
|||||||
// 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE
|
// 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE
|
||||||
// NOTE: Those definitions could be externally provided if required
|
// NOTE: Those definitions could be externally provided if required
|
||||||
|
|
||||||
// WARNING: HACK: TODO: Review!
|
// TODO: HACK: GuiTextSplit() - Review how textRows are returned to user
|
||||||
// textRow is an externally provided array of integers that stores row number for every splitted string
|
// textRow is an externally provided array of integers that stores row number for every splitted string
|
||||||
|
|
||||||
#if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS)
|
#if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS)
|
||||||
@ -4347,9 +4507,27 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
|
|||||||
{
|
{
|
||||||
Vector2 mousePoint = GetMousePosition();
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
if (CheckCollisionPointRec(mousePoint, bounds))
|
if (guiSliderDragging) // Keep dragging outside of bounds
|
||||||
|
{
|
||||||
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
|
{
|
||||||
|
if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
|
||||||
|
{
|
||||||
|
if (isVertical) value += (GetMouseDelta().y/(scrollbar.height - slider.height)*valueRange);
|
||||||
|
else value += (GetMouseDelta().x/(scrollbar.width - slider.width)*valueRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guiSliderDragging = false;
|
||||||
|
guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CheckCollisionPointRec(mousePoint, bounds))
|
||||||
{
|
{
|
||||||
state = STATE_FOCUSED;
|
state = STATE_FOCUSED;
|
||||||
|
guiSliderDragging = true;
|
||||||
|
guiSliderActive = bounds; // Store bounds as an identifier when dragging starts
|
||||||
|
|
||||||
// Handle mouse wheel
|
// Handle mouse wheel
|
||||||
int wheel = (int)GetMouseWheelMove();
|
int wheel = (int)GetMouseWheelMove();
|
||||||
@ -4607,34 +4785,38 @@ static int GetCodepointNext(const char *text, int *codepointSize)
|
|||||||
{
|
{
|
||||||
const char *ptr = text;
|
const char *ptr = text;
|
||||||
int codepoint = 0x3f; // Codepoint (defaults to '?')
|
int codepoint = 0x3f; // Codepoint (defaults to '?')
|
||||||
*codepointSize = 0;
|
*codepointSize = 1;
|
||||||
|
|
||||||
// Get current codepoint and bytes processed
|
// Get current codepoint and bytes processed
|
||||||
if (0xf0 == (0xf8 & ptr[0]))
|
if (0xf0 == (0xf8 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 4 byte UTF-8 codepoint
|
// 4 byte UTF-8 codepoint
|
||||||
|
if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
|
||||||
codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
|
codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
|
||||||
*codepointSize = 4;
|
*codepointSize = 4;
|
||||||
}
|
}
|
||||||
else if (0xe0 == (0xf0 & ptr[0]))
|
else if (0xe0 == (0xf0 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 3 byte UTF-8 codepoint */
|
// 3 byte UTF-8 codepoint */
|
||||||
|
if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
|
||||||
codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
|
codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
|
||||||
*codepointSize = 3;
|
*codepointSize = 3;
|
||||||
}
|
}
|
||||||
else if (0xc0 == (0xe0 & ptr[0]))
|
else if (0xc0 == (0xe0 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 2 byte UTF-8 codepoint
|
// 2 byte UTF-8 codepoint
|
||||||
|
if((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks
|
||||||
codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
|
codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
|
||||||
*codepointSize = 2;
|
*codepointSize = 2;
|
||||||
}
|
}
|
||||||
else
|
else if (0x00 == (0x80 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 1 byte UTF-8 codepoint
|
// 1 byte UTF-8 codepoint
|
||||||
codepoint = ptr[0];
|
codepoint = ptr[0];
|
||||||
*codepointSize = 1;
|
*codepointSize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return codepoint;
|
return codepoint;
|
||||||
}
|
}
|
||||||
#endif // RAYGUI_STANDALONE
|
#endif // RAYGUI_STANDALONE
|
||||||
|
|||||||
Reference in New Issue
Block a user