summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRay <[email protected]>2021-10-27 11:25:24 +0200
committerRay <[email protected]>2021-10-27 11:25:24 +0200
commitb7240d6a36de08cee6f8e00f213c274ba17205c2 (patch)
treeb84993f74cddc4986da1af758545324e9838a891
parent65076464d536ceb2e3f5475f3637ac0f0e67a7d6 (diff)
downloadraylib-b7240d6a36de08cee6f8e00f213c274ba17205c2.tar.gz
raylib-b7240d6a36de08cee6f8e00f213c274ba17205c2.zip
Update raygui.h
-rw-r--r--src/extras/raygui.h767
1 files changed, 434 insertions, 333 deletions
diff --git a/src/extras/raygui.h b/src/extras/raygui.h
index 3d7ef8d9..da231eb0 100644
--- a/src/extras/raygui.h
+++ b/src/extras/raygui.h
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raygui v3.0-dev - A simple and easy-to-use immediate-mode gui library
+* raygui v3.0 - A simple and easy-to-use immediate-mode gui library
*
* DESCRIPTION:
*
@@ -19,8 +19,6 @@
* - Label
* - Button
* - LabelButton --> Label
-* - ImageButton --> Button
-* - ImageButtonEx --> Button
* - Toggle
* - ToggleGroup --> Toggle
* - CheckBox
@@ -47,6 +45,52 @@
*
* It also provides a set of functions for styling the controls based on its properties (size, color).
*
+*
+* GUI STYLE (guiStyle):
+*
+* raygui uses a global data array for all gui style properties (allocated on data segment by default),
+* when a new style is loaded, it is loaded over the global style... but a default gui style could always be
+* recovered with GuiLoadStyleDefault() function, that overwrites the current style to the default one
+*
+* The global style array size is fixed and depends on the number of controls and properties:
+*
+* static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)];
+*
+* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
+*
+* Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style
+* used for all controls, when any of those base values is set, it is automatically populated to all
+* controls, so, specific control values overwriting generic style should be set after base values.
+*
+* After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those
+* properties are actually common to all controls and can not be overwritten individually (like BASE ones)
+* Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR
+*
+* Custom control properties can be defined using the EXTENDED properties for each independent control.
+*
+* TOOL: rGuiStyler is a visual tool to customize raygui style.
+*
+*
+* GUI ICONS (guiIcons):
+*
+* raygui could use a global array containing icons data (allocated on data segment by default),
+* a custom icons set could be loaded over this array using GuiLoadIcons(), but loaded icons set
+* must be same RICON_SIZE and no more than RICON_MAX_ICONS will be loaded
+*
+* Every icon is codified in binary form, using 1 bit per pixel, so, every 16x16 icon
+* requires 8 integers (16*16/32) to be stored in memory.
+*
+* When the icon is draw, actually one quad per pixel is drawn if the bit for that pixel is set.
+*
+* The global icons array size is fixed and depends on the number of icons and size:
+*
+* static unsigned int guiIcons[RICON_MAX_ICONS*RICON_DATA_ELEMENTS];
+*
+* guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
+*
+* TOOL: rGuiIcons is a visual tool to customize raygui icons.
+*
+*
* CONFIGURATION:
*
* #define RAYGUI_IMPLEMENTATION
@@ -59,43 +103,48 @@
* internally in the library and input management and drawing functions must be provided by
* the user (check library implementation for further details).
*
-* #define RAYGUI_SUPPORT_RICONS
-* Includes embedded ricons data (binary format) and definitions (by default 256 16x16 pixels, 2KB)
+* #define RAYGUI_NO_RICONS
+* Avoid including embedded ricons data (256 icons, 16x16 pixels, 1-bit per pixel, 2KB)
*
-* #define RAYGUI_SUPPORT_CUSTOM_RICONS
-* Includes custom ricons.h header defining a set of custom icons,
+* #define RAYGUI_CUSTOM_RICONS
+* Includes custom ricons.h header defining a set of custom icons,
* this file can be generated using rGuiIcons tool
*
*
* VERSIONS HISTORY:
*
-* 3.0-dev (22-Aug-2021) Integrated ricons data to avoid external file
-* 2.9 (17-Mar-2021) Removed tooltip API
+* 3.0 (xx-Sep-2021) Integrated ricons data to avoid external file
+* REDESIGNED: GuiTextBoxMulti()
+* REMOVED: GuiImageButton*()
+* Multiple minor tweaks and bugs corrected
+* 2.9 (17-Mar-2021) REMOVED: Tooltip API
* 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
* 2.6 (09-Sep-2019) ADDED: GuiTextInputBox()
* REDESIGNED: GuiListView*(), GuiDropdownBox(), GuiSlider*(), GuiProgressBar(), GuiMessageBox()
* REVIEWED: GuiTextBox(), GuiSpinner(), GuiValueBox(), GuiLoadStyle()
* 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
* 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
-* 2.2 (05-Feb-2019) Added GuiScrollBar(), GuiScrollPanel(), reviewed GuiListView(), removed Gui*Ex() controls
-* 2.1 (26-Dec-2018) Redesign of GuiCheckBox(), GuiComboBox(), GuiDropdownBox(), GuiToggleGroup() > Use combined text string
-* Complete redesign of style system (breaking change)
-* 2.0 (08-Nov-2018) Support controls guiLock and custom fonts, reviewed GuiComboBox(), GuiListView()...
-* 1.9 (09-Oct-2018) Controls review: GuiGrid(), GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()...
+* 2.2 (05-Feb-2019) ADDED: GuiScrollBar(), GuiScrollPanel(), reviewed GuiListView(), removed Gui*Ex() controls
+* 2.1 (26-Dec-2018) REDESIGNED: GuiCheckBox(), GuiComboBox(), GuiDropdownBox(), GuiToggleGroup() > Use combined text string
+* REDESIGNED: Style system (breaking change)
+* 2.0 (08-Nov-2018) ADDED: Support controls guiLock and custom fonts
+* REVIEWED: GuiComboBox(), GuiListView()...
+* 1.9 (09-Oct-2018) REVIEWED: GuiGrid(), GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()...
* 1.8 (01-May-2018) Lot of rework and redesign to align with rGuiStyler and rGuiLayout
* 1.5 (21-Jun-2017) Working in an improved styles system
* 1.4 (15-Jun-2017) Rewritten all GUI functions (removed useless ones)
-* 1.3 (12-Jun-2017) Redesigned styles system
+* 1.3 (12-Jun-2017) Complete redesign of style system
* 1.1 (01-Jun-2017) Complete review of the library
* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria.
* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria.
* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria.
*
+*
* CONTRIBUTORS:
*
* Ramon Santamaria: Supervision, review, redesign, update and maintenance
@@ -111,7 +160,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2020 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2021 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -133,30 +182,31 @@
#ifndef RAYGUI_H
#define RAYGUI_H
-#define RAYGUI_VERSION "3.0-dev"
+#define RAYGUI_VERSION "3.0"
#if !defined(RAYGUI_STANDALONE)
#include "raylib.h"
#endif
-#ifndef RAYGUIDEF
- #define RAYGUIDEF // We are building or using rlgl as a static library (or Linux shared library)
-#endif
-
-// Define functions scope to be used internally (static) or externally (extern) to the module including this file
+// Function specifiers in case library is build/used as a shared library (Windows)
+// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
#if defined(_WIN32)
- // Microsoft attibutes to tell compiler that symbols are imported/exported from a .dll
#if defined(BUILD_LIBTYPE_SHARED)
- #define RAYGUIDEF __declspec(dllexport) // We are building raygui as a Win32 shared library (.dll)
+ #define RAYGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
#elif defined(USE_LIBTYPE_SHARED)
- #define RAYGUIDEF __declspec(dllimport) // We are using raygui as a Win32 shared library (.dll)
+ #define RAYGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
#endif
#endif
-#if !defined(RAYGUI_MALLOC) && !defined(RAYGUI_CALLOC) && !defined(RAYGUI_FREE)
- #include <stdlib.h> // Required for: malloc(), calloc(), free()
+// Function specifiers definition
+#ifndef RAYGUIAPI
+ #define RAYGUIAPI // Functions defined as 'extern' by default (implicit specifiers)
#endif
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+
// Allow custom memory allocators
#ifndef RAYGUI_MALLOC
#define RAYGUI_MALLOC(sz) malloc(sz)
@@ -168,6 +218,8 @@
#define RAYGUI_FREE(p) free(p)
#endif
+// TODO: Implement custom TraceLog()
+#define TRACELOG(level, ...) (void)0
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -187,7 +239,7 @@
float y;
} Vector2;
- // Vector3 type
+ // Vector3 type // -- ConvertHSVtoRGB(), ConvertRGBtoHSV()
typedef struct Vector3 {
float x;
float y;
@@ -210,7 +262,7 @@
float height;
} Rectangle;
- // TODO: Texture2D type is very coupled to raylib, mostly required by GuiImageButton()
+ // TODO: Texture2D type is very coupled to raylib, required by Font type
// It should be redesigned to be provided by user
typedef struct Texture2D {
unsigned int id; // OpenGL texture id
@@ -264,16 +316,16 @@ typedef enum {
// Gui controls
typedef enum {
- DEFAULT = 0,
- LABEL, // LABELBUTTON
- BUTTON, // IMAGEBUTTON
- TOGGLE, // TOGGLEGROUP
- SLIDER, // SLIDERBAR
+ DEFAULT = 0, // Generic control -> populates to all controls when set
+ LABEL, // Used also for: LABELBUTTON
+ BUTTON,
+ TOGGLE, // Used also for: TOGGLEGROUP
+ SLIDER, // Used also for: SLIDERBAR
PROGRESSBAR,
CHECKBOX,
COMBOBOX,
DROPDOWNBOX,
- TEXTBOX, // TEXTBOXMULTI
+ TEXTBOX, // Used also for: TEXTBOXMULTI
VALUEBOX,
SPINNER,
LISTVIEW,
@@ -283,6 +335,7 @@ typedef enum {
} GuiControl;
// Gui base properties for every control
+// NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties)
typedef enum {
BORDER_COLOR_NORMAL = 0,
BASE_COLOR_NORMAL,
@@ -303,9 +356,10 @@ typedef enum {
} GuiControlProperty;
// Gui extended properties depend on control
-// NOTE: We reserve a fixed size of additional properties per control
+// NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default 8 properties)
-// DEFAULT properties
+// DEFAULT extended properties
+// NOTE: Those properties are actually common to all controls
typedef enum {
TEXT_SIZE = 16,
TEXT_SPACING,
@@ -319,12 +373,12 @@ typedef enum {
// Button
//typedef enum { } GuiButtonProperty;
-// Toggle / ToggleGroup
+// Toggle/ToggleGroup
typedef enum {
GROUP_PADDING = 16,
} GuiToggleProperty;
-// Slider / SliderBar
+// Slider/SliderBar
typedef enum {
SLIDER_WIDTH = 16,
SLIDER_PADDING
@@ -352,7 +406,7 @@ typedef enum {
DROPDOWN_ITEMS_PADDING
} GuiDropdownBoxProperty;
-// TextBox / TextBoxMulti / ValueBox / Spinner
+// TextBox/TextBoxMulti/ValueBox/Spinner
typedef enum {
TEXT_INNER_PADDING = 16,
TEXT_LINES_PADDING,
@@ -413,86 +467,85 @@ extern "C" { // Prevents name mangling of functions
#endif
// Global gui state control functions
-RAYGUIDEF void GuiEnable(void); // Enable gui controls (global state)
-RAYGUIDEF void GuiDisable(void); // Disable gui controls (global state)
-RAYGUIDEF void GuiLock(void); // Lock gui controls (global state)
-RAYGUIDEF void GuiUnlock(void); // Unlock gui controls (global state)
-RAYGUIDEF void GuiFade(float alpha); // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f
-RAYGUIDEF void GuiSetState(int state); // Set gui state (global state)
-RAYGUIDEF int GuiGetState(void); // Get gui state (global state)
+RAYGUIAPI void GuiEnable(void); // Enable gui controls (global state)
+RAYGUIAPI void GuiDisable(void); // Disable gui controls (global state)
+RAYGUIAPI void GuiLock(void); // Lock gui controls (global state)
+RAYGUIAPI void GuiUnlock(void); // Unlock gui controls (global state)
+RAYGUIAPI bool GuiIsLocked(void); // Check if gui is locked (global state)
+RAYGUIAPI void GuiFade(float alpha); // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f
+RAYGUIAPI void GuiSetState(int state); // Set gui state (global state)
+RAYGUIAPI int GuiGetState(void); // Get gui state (global state)
// Font set/get functions
-RAYGUIDEF void GuiSetFont(Font font); // Set gui custom font (global state)
-RAYGUIDEF Font GuiGetFont(void); // Get gui custom font (global state)
+RAYGUIAPI void GuiSetFont(Font font); // Set gui custom font (global state)
+RAYGUIAPI Font GuiGetFont(void); // Get gui custom font (global state)
// Style set/get functions
-RAYGUIDEF void GuiSetStyle(int control, int property, int value); // Set one style property
-RAYGUIDEF int GuiGetStyle(int control, int property); // Get one style property
+RAYGUIAPI void GuiSetStyle(int control, int property, int value); // Set one style property
+RAYGUIAPI int GuiGetStyle(int control, int property); // Get one style property
// Container/separator controls, useful for controls organization
-RAYGUIDEF bool GuiWindowBox(Rectangle bounds, const char *title); // Window Box control, shows a window that can be closed
-RAYGUIDEF void GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
-RAYGUIDEF void GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
-RAYGUIDEF void GuiPanel(Rectangle bounds); // Panel control, useful to group controls
-RAYGUIDEF Rectangle GuiScrollPanel(Rectangle bounds, Rectangle content, Vector2 *scroll); // Scroll Panel control
+RAYGUIAPI bool GuiWindowBox(Rectangle bounds, const char *title); // Window Box control, shows a window that can be closed
+RAYGUIAPI void GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
+RAYGUIAPI void GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
+RAYGUIAPI void GuiPanel(Rectangle bounds); // Panel control, useful to group controls
+RAYGUIAPI Rectangle GuiScrollPanel(Rectangle bounds, Rectangle content, Vector2 *scroll); // Scroll Panel control
// Basic controls set
-RAYGUIDEF void GuiLabel(Rectangle bounds, const char *text); // Label control, shows text
-RAYGUIDEF bool GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked
-RAYGUIDEF bool GuiLabelButton(Rectangle bounds, const char *text); // Label button control, show true when clicked
-RAYGUIDEF bool GuiImageButton(Rectangle bounds, const char *text, Texture2D texture); // Image button control, returns true when clicked
-RAYGUIDEF bool GuiImageButtonEx(Rectangle bounds, const char *text, Texture2D texture, Rectangle texSource); // Image button extended control, returns true when clicked
-RAYGUIDEF bool GuiToggle(Rectangle bounds, const char *text, bool active); // Toggle Button control, returns true when active
-RAYGUIDEF int GuiToggleGroup(Rectangle bounds, const char *text, int active); // Toggle Group control, returns active toggle index
-RAYGUIDEF bool GuiCheckBox(Rectangle bounds, const char *text, bool checked); // Check Box control, returns true when active
-RAYGUIDEF int GuiComboBox(Rectangle bounds, const char *text, int active); // Combo Box control, returns selected item index
-RAYGUIDEF bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control, returns selected item
-RAYGUIDEF bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control, returns selected value
-RAYGUIDEF bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers
-RAYGUIDEF bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text
-RAYGUIDEF bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control with multiple lines
-RAYGUIDEF float GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Slider control, returns selected value
-RAYGUIDEF float GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Slider Bar control, returns selected value
-RAYGUIDEF float GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Progress Bar control, shows current progress value
-RAYGUIDEF void GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text
-RAYGUIDEF void GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders
-RAYGUIDEF int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue); // Scroll Bar control
-RAYGUIDEF Vector2 GuiGrid(Rectangle bounds, float spacing, int subdivs); // Grid control
+RAYGUIAPI void GuiLabel(Rectangle bounds, const char *text); // Label control, shows text
+RAYGUIAPI bool GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked
+RAYGUIAPI bool GuiLabelButton(Rectangle bounds, const char *text); // Label button control, show true when clicked
+RAYGUIAPI bool GuiToggle(Rectangle bounds, const char *text, bool active); // Toggle Button control, returns true when active
+RAYGUIAPI int GuiToggleGroup(Rectangle bounds, const char *text, int active); // Toggle Group control, returns active toggle index
+RAYGUIAPI bool GuiCheckBox(Rectangle bounds, const char *text, bool checked); // Check Box control, returns true when active
+RAYGUIAPI int GuiComboBox(Rectangle bounds, const char *text, int active); // Combo Box control, returns selected item index
+RAYGUIAPI bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control, returns selected item
+RAYGUIAPI bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control, returns selected value
+RAYGUIAPI bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers
+RAYGUIAPI bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text
+RAYGUIAPI bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control with multiple lines
+RAYGUIAPI float GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Slider control, returns selected value
+RAYGUIAPI float GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Slider Bar control, returns selected value
+RAYGUIAPI float GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Progress Bar control, shows current progress value
+RAYGUIAPI void GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text
+RAYGUIAPI void GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders
+RAYGUIAPI int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue); // Scroll Bar control
+RAYGUIAPI Vector2 GuiGrid(Rectangle bounds, float spacing, int subdivs); // Grid control
// Advance controls set
-RAYGUIDEF int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int active); // List View control, returns selected list item index
-RAYGUIDEF int GuiListViewEx(Rectangle bounds, const char **text, int count, int *focus, int *scrollIndex, int active); // List View with extended parameters
-RAYGUIDEF int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
-RAYGUIDEF int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text); // Text Input Box control, ask for text
-RAYGUIDEF Color GuiColorPicker(Rectangle bounds, Color color); // Color Picker control (multiple color controls)
-RAYGUIDEF Color GuiColorPanel(Rectangle bounds, Color color); // Color Panel control
-RAYGUIDEF float GuiColorBarAlpha(Rectangle bounds, float alpha); // Color Bar Alpha control
-RAYGUIDEF float GuiColorBarHue(Rectangle bounds, float value); // Color Bar Hue control
+RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int active); // List View control, returns selected list item index
+RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *focus, int *scrollIndex, int active); // List View with extended parameters
+RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
+RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text); // Text Input Box control, ask for text
+RAYGUIAPI Color GuiColorPicker(Rectangle bounds, Color color); // Color Picker control (multiple color controls)
+RAYGUIAPI Color GuiColorPanel(Rectangle bounds, Color color); // Color Panel control
+RAYGUIAPI float GuiColorBarAlpha(Rectangle bounds, float alpha); // Color Bar Alpha control
+RAYGUIAPI float GuiColorBarHue(Rectangle bounds, float value); // Color Bar Hue control
// Styles loading functions
-RAYGUIDEF void GuiLoadStyle(const char *fileName); // Load style file over global style variable (.rgs)
-RAYGUIDEF void GuiLoadStyleDefault(void); // Load style default over global style
+RAYGUIAPI void GuiLoadStyle(const char *fileName); // Load style file over global style variable (.rgs)
+RAYGUIAPI void GuiLoadStyleDefault(void); // Load style default over global style
/*
typedef GuiStyle (unsigned int *)
-RAYGUIDEF GuiStyle LoadGuiStyle(const char *fileName); // Load style from file (.rgs)
-RAYGUIDEF void UnloadGuiStyle(GuiStyle style); // Unload style
+RAYGUIAPI GuiStyle LoadGuiStyle(const char *fileName); // Load style from file (.rgs)
+RAYGUIAPI void UnloadGuiStyle(GuiStyle style); // Unload style
*/
-RAYGUIDEF const char *GuiIconText(int iconId, const char *text); // Get text with icon id prepended (if supported)
+RAYGUIAPI const char *GuiIconText(int iconId, const char *text); // Get text with icon id prepended (if supported)
-#if defined(RAYGUI_SUPPORT_RICONS)
+#if !defined(RAYGUI_NO_RICONS)
// Gui icons functionality
-RAYGUIDEF void GuiDrawIcon(int iconId, Vector2 position, int pixelSize, Color color);
+RAYGUIAPI void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color);
-RAYGUIDEF unsigned int *GuiGetIcons(void); // Get full icons data pointer
-RAYGUIDEF unsigned int *GuiGetIconData(int iconId); // Get icon bit data
-RAYGUIDEF void GuiSetIconData(int iconId, unsigned int *data); // Set icon bit data
+RAYGUIAPI unsigned int *GuiGetIcons(void); // Get full icons data pointer
+RAYGUIAPI unsigned int *GuiGetIconData(int iconId); // Get icon bit data
+RAYGUIAPI void GuiSetIconData(int iconId, unsigned int *data); // Set icon bit data
-RAYGUIDEF void GuiSetIconPixel(int iconId, int x, int y); // Set icon pixel value
-RAYGUIDEF void GuiClearIconPixel(int iconId, int x, int y); // Clear icon pixel value
-RAYGUIDEF bool GuiCheckIconPixel(int iconId, int x, int y); // Check icon pixel value
+RAYGUIAPI void GuiSetIconPixel(int iconId, int x, int y); // Set icon pixel value
+RAYGUIAPI void GuiClearIconPixel(int iconId, int x, int y); // Clear icon pixel value
+RAYGUIAPI bool GuiCheckIconPixel(int iconId, int x, int y); // Check icon pixel value
#endif
#if defined(__cplusplus)
@@ -509,27 +562,25 @@ RAYGUIDEF bool GuiCheckIconPixel(int iconId, int x, int y); // Check icon pi
#if defined(RAYGUI_IMPLEMENTATION)
-#include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf()
-#include <string.h> // Required for: strlen() [GuiTextBox()]
+#include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()]
+#include <stdlib.h> // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()]
+#include <string.h> // Required for: strlen() [GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()], memset(), memcpy()
+#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [TextFormat()]
#include <math.h> // Required for: roundf() [GuiColorPicker()]
-#if defined(RAYGUI_STANDALONE)
- #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
-#endif
-
#ifdef __cplusplus
#define RAYGUI_CLITERAL(name) name
#else
#define RAYGUI_CLITERAL(name) (name)
#endif
-#if defined(RAYGUI_SUPPORT_RICONS)
+#if !defined(RAYGUI_NO_RICONS)
-#if defined(RAYGUI_SUPPORT_CUSTOM_RICONS)
+#if defined(RAYGUI_CUSTOM_RICONS)
#define RICONS_IMPLEMENTATION
#include "ricons.h" // External icons data provided, it can be generated with rGuiIcons tool
-
+
#else // Embedded raygui icons, no external file provided
#define RICON_SIZE 16 // Size of icons (squared)
@@ -662,12 +713,12 @@ typedef enum {
RICON_CROSS = 113,
RICON_ARROW_LEFT = 114,
RICON_ARROW_RIGHT = 115,
- RICON_ARROW_BOTTOM = 116,
- RICON_ARROW_TOP = 117,
+ RICON_ARROW_DOWN = 116,
+ RICON_ARROW_UP = 117,
RICON_ARROW_LEFT_FILL = 118,
RICON_ARROW_RIGHT_FILL = 119,
- RICON_ARROW_BOTTOM_FILL = 120,
- RICON_ARROW_TOP_FILL = 121,
+ RICON_ARROW_DOWN_FILL = 120,
+ RICON_ARROW_UP_FILL = 121,
RICON_AUDIO = 122,
RICON_FX = 123,
RICON_WAVE = 124,
@@ -803,11 +854,17 @@ typedef enum {
RICON_254 = 254,
RICON_255 = 255,
} guiIconName;
-
+
//----------------------------------------------------------------------------------
-// Icons data (allocated on memory data section by default)
-// NOTE: A new icon set could be loaded over this array using GuiLoadIcons(),
-// just note that loaded icons set must be same RICON_SIZE
+// Icons data for all gui possible icons (allocated on data segment by default)
+//
+// NOTE 1: Every icon is codified in binary form, using 1 bit per pixel, so,
+// every 16x16 icon requires 8 integers (16*16/32) to be stored
+//
+// NOTE 2: A new icon set could be loaded over this array using GuiLoadIcons(),
+// but loaded icons set must be same RICON_SIZE and no more than RICON_MAX_ICONS
+//
+// guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
//----------------------------------------------------------------------------------
static unsigned int guiIcons[RICON_MAX_ICONS*RICON_DATA_ELEMENTS] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_NONE
@@ -926,12 +983,12 @@ static unsigned int guiIcons[RICON_MAX_ICONS*RICON_DATA_ELEMENTS] = {
0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000, // RICON_CROSS
0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000, // RICON_ARROW_LEFT
0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000, // RICON_ARROW_RIGHT
- 0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // RICON_ARROW_BOTTOM
- 0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // RICON_ARROW_TOP
+ 0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // RICON_ARROW_DOWN
+ 0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // RICON_ARROW_UP
0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000, // RICON_ARROW_LEFT_FILL
0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000, // RICON_ARROW_RIGHT_FILL
- 0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // RICON_ARROW_BOTTOM_FILL
- 0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // RICON_ARROW_TOP_FILL
+ 0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // RICON_ARROW_DOWN_FILL
+ 0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // RICON_ARROW_UP_FILL
0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000, // RICON_AUDIO
0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000, // RICON_FX
0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000, // RICON_WAVE
@@ -1068,22 +1125,18 @@ static unsigned int guiIcons[RICON_MAX_ICONS*RICON_DATA_ELEMENTS] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_255
};
-#endif // RAYGUI_SUPPORT_CUSTOM_RICONS
+#endif // RAYGUI_CUSTOM_RICONS
-#endif // RAYGUI_SUPPORT_RICONS
+#endif // !RAYGUI_NO_RICONS
#ifndef RICON_SIZE
#define RICON_SIZE 0
#endif
#define RAYGUI_MAX_CONTROLS 16 // Maximum number of standard controls
-#define RAYGUI_MAX_PROPS_DEFAULT 16 // Maximum number of standard properties
+#define RAYGUI_MAX_PROPS_BASE 16 // Maximum number of standard properties
#define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties
-// TODO: Avoid animations and time-based states
-// Functions using it: GuiTextBox(), GuiValueBox(), GuiTextBoxMulti()
-//#define TEXTEDIT_CURSOR_BLINK_FRAMES 20 // Text edit controls cursor blink timming
-
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
@@ -1099,11 +1152,20 @@ static Font guiFont = { 0 }; // Gui current font (WARNING: highly cou
static bool guiLocked = false; // Gui lock state (no inputs processed)
static float guiAlpha = 1.0f; // Gui element transpacency on drawing
-// Global gui style array (allocated on data segment by default)
-// NOTE: In raygui we manage a single int array with all the possible style properties.
-// When a new style is loaded, it loads over the global style... but default gui style
-// could always be recovered with GuiLoadStyleDefault()
-static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_DEFAULT + RAYGUI_MAX_PROPS_EXTENDED)] = { 0 };
+//----------------------------------------------------------------------------------
+// Style data array for all gui style properties (allocated on data segment by default)
+//
+// NOTE 1: First set of BASE properties are generic to all controls but could be individually
+// overwritten per control, first set of EXTENDED properties are generic to all controls and
+// can not be overwritten individually but custom EXTENDED properties can be used by control
+//
+// NOTE 2: A new style set could be loaded over this array using GuiLoadStyle(),
+// but default gui style could always be recovered with GuiLoadStyleDefault()
+//
+// guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
+//----------------------------------------------------------------------------------
+static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)] = { 0 };
+
static bool guiStyleLoaded = false; // Style loaded flag for lazy style initialization
//----------------------------------------------------------------------------------
@@ -1126,7 +1188,7 @@ static bool guiStyleLoaded = false; // Style loaded flag for lazy style init
// Input required functions
//-------------------------------------------------------------------------------
static Vector2 GetMousePosition(void);
-static int GetMouseWheelMove(void);
+static float GetMouseWheelMove(void);
static bool IsMouseButtonDown(int button);
static bool IsMouseButtonPressed(int button);
static bool IsMouseButtonReleased(int button);
@@ -1140,22 +1202,20 @@ static int GetCharPressed(void); // -- GuiTextBox(), GuiTextBoxMulti(),
//-------------------------------------------------------------------------------
static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle(), GuiDrawIcon()
-static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker()
-static void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // -- GuiDropdownBox(), GuiScrollBar()
-static void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // -- GuiImageButtonEx()
-
-//static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // -- GuiTextBoxMulti()
+static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker()
//-------------------------------------------------------------------------------
// Text required functions
//-------------------------------------------------------------------------------
+static Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount); // -- GuiLoadStyle()
static Font GetFontDefault(void); // -- GuiLoadStyleDefault()
-static Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // -- GetTextWidth(), GuiTextBoxMulti()
-static void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // -- GuiDrawText()
-
-static Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount); // -- GuiLoadStyle()
+static Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle()
+static void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle()
static char *LoadFileText(const char *fileName); // -- GuiLoadStyle()
static const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle()
+
+static Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // -- GetTextWidth(), GuiTextBoxMulti()
+static void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // -- GuiDrawText()
//-------------------------------------------------------------------------------
// raylib functions already implemented in raygui
@@ -1167,6 +1227,8 @@ 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 GetCodepoint(const char *text, int *bytesProcessed); // 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)
static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2); // Draw rectangle vertical gradient
//-------------------------------------------------------------------------------
@@ -1202,6 +1264,9 @@ void GuiLock(void) { guiLocked = true; }
// Unlock gui global state
void GuiUnlock(void) { guiLocked = false; }
+// Check if gui is locked (global state)
+bool GuiIsLocked(void) { return guiLocked; }
+
// Set gui controls alpha global state
void GuiFade(float alpha)
{
@@ -1243,12 +1308,12 @@ Font GuiGetFont(void)
void GuiSetStyle(int control, int property, int value)
{
if (!guiStyleLoaded) GuiLoadStyleDefault();
- guiStyle[control*(RAYGUI_MAX_PROPS_DEFAULT + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
+ guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
// Default properties are propagated to all controls
- if ((control == 0) && (property < RAYGUI_MAX_PROPS_DEFAULT))
+ if ((control == 0) && (property < RAYGUI_MAX_PROPS_BASE))
{
- for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_DEFAULT + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
+ for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
}
}
@@ -1256,7 +1321,7 @@ void GuiSetStyle(int control, int property, int value)
int GuiGetStyle(int control, int property)
{
if (!guiStyleLoaded) GuiLoadStyleDefault();
- return guiStyle[control*(RAYGUI_MAX_PROPS_DEFAULT + RAYGUI_MAX_PROPS_EXTENDED) + property];
+ return guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property];
}
//----------------------------------------------------------------------------------
@@ -1297,10 +1362,10 @@ bool GuiWindowBox(Rectangle bounds, const char *title)
int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
GuiSetStyle(BUTTON, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
-#if defined(RAYGUI_SUPPORT_RICONS)
- clicked = GuiButton(closeButtonRec, GuiIconText(RICON_CROSS_SMALL, NULL));
-#else
+#if defined(RAYGUI_NO_RICONS)
clicked = GuiButton(closeButtonRec, "x");
+#else
+ clicked = GuiButton(closeButtonRec, GuiIconText(RICON_CROSS_SMALL, NULL));
#endif
GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment);
@@ -1342,7 +1407,7 @@ void GuiLine(Rectangle bounds, const char *text)
else
{
Rectangle textBounds = { 0 };
- textBounds.width = (float)GetTextWidth(text); // TODO: Consider text icon
+ textBounds.width = (float)GetTextWidth(text);
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
textBounds.x = bounds.x + LINE_TEXT_PADDING;
textBounds.y = bounds.y - (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
@@ -1398,7 +1463,6 @@ Rectangle GuiScrollPanel(Rectangle bounds, Rectangle content, Vector2 *scroll)
if (view.width > content.width) view.width = content.width;
if (view.height > content.height) view.height = content.height;
- // TODO: Review!
const float horizontalMin = hasHorizontalScrollBar? ((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH);
const float horizontalMax = hasHorizontalScrollBar? content.width - bounds.width + (float)verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH) - (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)verticalScrollBarWidth : 0) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
const float verticalMin = hasVerticalScrollBar? (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
@@ -1454,7 +1518,7 @@ Rectangle GuiScrollPanel(Rectangle bounds, Rectangle content, Vector2 *scroll)
if (hasHorizontalScrollBar)
{
// Change scrollbar slider size to show the diff in size between the content width and the widget width
- GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.width - 2 * GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth) / (int)content.width) * ((int)bounds.width - 2 * GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)));
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)/(int)content.width)*((int)bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)));
scrollPos.x = (float)-GuiScrollBar(horizontalScrollBar, (int)-scrollPos.x, (int)horizontalMin, (int)horizontalMax);
}
@@ -1462,7 +1526,7 @@ Rectangle GuiScrollPanel(Rectangle bounds, Rectangle content, Vector2 *scroll)
if (hasVerticalScrollBar)
{
// Change scrollbar slider size to show the diff in size between the content height and the widget height
- GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.height - 2 * GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth) / (int)content.height) * ((int)bounds.height - 2 * GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)));
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)/(int)content.height)*((int)bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)));
scrollPos.y = (float)-GuiScrollBar(verticalScrollBar, (int)-scrollPos.y, (int)verticalMin, (int)verticalMax);
}
@@ -1568,45 +1632,6 @@ bool GuiLabelButton(Rectangle bounds, const char *text)
return pressed;
}
-// Image button control, returns true when clicked
-bool GuiImageButton(Rectangle bounds, const char *text, Texture2D texture)
-{
- return GuiImageButtonEx(bounds, text, texture, RAYGUI_CLITERAL(Rectangle){ 0, 0, (float)texture.width, (float)texture.height });
-}
-
-// Image button control, returns true when clicked
-bool GuiImageButtonEx(Rectangle bounds, const char *text, Texture2D texture, Rectangle texSource)
-{
- GuiControlState state = guiState;
- bool clicked = false;
-
- // Update control
- //--------------------------------------------------------------------
- if ((state != GUI_STATE_DISABLED) && !guiLocked)
- {
- Vector2 mousePoint = GetMousePosition();
-
- // Check button state
- if (CheckCollisionPointRec(mousePoint, bounds))
- {
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
- else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) clicked = true;
- else state = GUI_STATE_FOCUSED;
- }
- }
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- GuiDrawRectangle(bounds, GuiGetStyle(BUTTON, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(BUTTON, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(BUTTON, BASE + (state*3))), guiAlpha));
-
- GuiDrawText(text, GetTextBounds(BUTTON, bounds), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(BUTTON, TEXT + (state*3))), guiAlpha));
- if (texture.id > 0) DrawTextureRec(texture, texSource, RAYGUI_CLITERAL(Vector2){ bounds.x + bounds.width/2 - texSource.width/2, bounds.y + bounds.height/2 - texSource.height/2 }, Fade(GetColor(GuiGetStyle(BUTTON, TEXT + (state*3))), guiAlpha));
- //------------------------------------------------------------------
-
- return clicked;
-}
-
// Toggle Button control, returns true when active
bool GuiToggle(Rectangle bounds, const char *text, bool active)
{
@@ -1823,7 +1848,7 @@ bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMo
// Update control
//--------------------------------------------------------------------
- if ((state != GUI_STATE_DISABLED) && !guiLocked && (itemCount > 1))
+ if ((state != GUI_STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1))
{
Vector2 mousePoint = GetMousePosition();
@@ -1904,14 +1929,14 @@ bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMo
}
}
- // TODO: Avoid this function, use icon instead or 'v'
- DrawTriangle(RAYGUI_CLITERAL(Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2 },
- RAYGUI_CLITERAL(Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING) + 5, bounds.y + bounds.height/2 - 2 + 5 },
- RAYGUI_CLITERAL(Vector2){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING) + 10, bounds.y + bounds.height/2 - 2 },
- Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
-
- //GuiDrawText("v", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2, 10, 10 },
- // GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
+ // Draw arrows (using icon if available)
+#if defined(RAYGUI_NO_RICONS)
+ GuiDrawText("v", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2, 10, 10 },
+ GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
+#else
+ GuiDrawText("#120#", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 6, 10, 10 },
+ GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha)); // RICON_ARROW_DOWN_FILL
+#endif
//--------------------------------------------------------------------
*active = itemSelected;
@@ -1932,6 +1957,8 @@ bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
(float)GuiGetStyle(DEFAULT, TEXT_SIZE)*2
};
+ if (cursor.height > bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2;
+
// Update control
//--------------------------------------------------------------------
if ((state != GUI_STATE_DISABLED) && !guiLocked)
@@ -1941,7 +1968,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
if (editMode)
{
state = GUI_STATE_PRESSED;
-
+
int key = GetCharPressed(); // Returns codepoint as Unicode
int keyCount = (int)strlen(text);
@@ -2007,7 +2034,7 @@ bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
else GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), BLANK);
GuiDrawText(text, GetTextBounds(TEXTBOX, bounds), GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
-
+
// Draw cursor
if (editMode) GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
//--------------------------------------------------------------------
@@ -2071,12 +2098,12 @@ bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, in
GuiSetStyle(BUTTON, BORDER_WIDTH, GuiGetStyle(SPINNER, BORDER_WIDTH));
GuiSetStyle(BUTTON, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
-#if defined(RAYGUI_SUPPORT_RICONS)
- if (GuiButton(leftButtonBound, GuiIconText(RICON_ARROW_LEFT_FILL, NULL))) tempValue--;
- if (GuiButton(rightButtonBound, GuiIconText(RICON_ARROW_RIGHT_FILL, NULL))) tempValue++;
-#else
+#if defined(RAYGUI_NO_RICONS)
if (GuiButton(leftButtonBound, "<")) tempValue--;
if (GuiButton(rightButtonBound, ">")) tempValue++;
+#else
+ if (GuiButton(leftButtonBound, GuiIconText(RICON_ARROW_LEFT_FILL, NULL))) tempValue--;
+ if (GuiButton(rightButtonBound, GuiIconText(RICON_ARROW_RIGHT_FILL, NULL))) tempValue++;
#endif
GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign);
@@ -2205,15 +2232,15 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
bool pressed = false;
Rectangle textAreaBounds = {
- bounds.x + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
- bounds.y + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
- bounds.width - 2*GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
- bounds.height - 2*GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING)
+ bounds.x + GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
+ bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
+ bounds.width - 2*(GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING)),
+ bounds.height - 2*(GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING))
};
// Cursor position, [x, y] values should be updated
Rectangle cursor = { 0, -1, 4, (float)GuiGetStyle(DEFAULT, TEXT_SIZE) + 2 };
-
+
float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/(float)guiFont.baseSize; // Character rectangle scaling factor
// Update control
@@ -2227,7 +2254,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
state = GUI_STATE_PRESSED;
// We get an Unicode codepoint
- int codepoint = GetCharPressed();
+ int codepoint = GetCharPressed();
int textLength = (int)strlen(text); // Length in bytes (UTF-8 string)
// Introduce characters
@@ -2264,7 +2291,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
// Remove latest UTF-8 unicode character introduced (n bytes)
int charUTF8Length = 0;
while (((unsigned char)text[textLength - 1 - charUTF8Length] & 0b01000000) == 0) charUTF8Length++;
-
+
textLength -= (charUTF8Length + 1);
text[textLength] = '\0';
}
@@ -2303,18 +2330,18 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
//int lastSpacePos = 0;
//int lastSpaceWidth = 0;
//int lastSpaceCursorPos = 0;
-
+
for (int i = 0, codepointLength = 0; text[i] != '\0'; i += codepointLength)
{
int codepoint = GetCodepoint(text + i, &codepointLength);
- int index = GetGlyphIndex(guiFont, codepoint); // If requested codepoint is not found, we get '?' (0x3f) -> TODO: review that case!
+ int index = GetGlyphIndex(guiFont, codepoint); // If requested codepoint is not found, we get '?' (0x3f)
Rectangle atlasRec = guiFont.recs[index];
- GlyphInfo glyphInfo = guiFont.glyphs[index]; // Glyph measures
-
- if ((codepointLength == 1) && (codepoint == '\n'))
+ GlyphInfo glyphInfo = guiFont.glyphs[index]; // Glyph measures
+
+ if ((codepointLength == 1) && (codepoint == '\n'))
{
- cursorPos.y += (guiFont.baseSize*scaleFactor + GuiGetStyle(TEXTBOX, TEXT_LINES_PADDING)); // Line feed
- cursorPos.x = textAreaBounds.x; // Carriage return
+ cursorPos.y += (guiFont.baseSize*scaleFactor + GuiGetStyle(TEXTBOX, TEXT_LINES_PADDING)); // Line feed
+ cursorPos.x = textAreaBounds.x; // Carriage return
}
else
{
@@ -2323,7 +2350,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
int glyphWidth = 0;
if (glyphInfo.advanceX != 0) glyphWidth += glyphInfo.advanceX;
else glyphWidth += (int)(atlasRec.width + glyphInfo.offsetX);
-
+
// Jump line if the end of the text box area has been reached
if ((cursorPos.x + (glyphWidth*scaleFactor)) > (textAreaBounds.x + textAreaBounds.width))
{
@@ -2334,7 +2361,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
else if (wrapMode == 2)
{
/*
- if ((codepointLength == 1) && (codepoint == ' '))
+ if ((codepointLength == 1) && (codepoint == ' '))
{
lastSpacePos = i;
lastSpaceWidth = 0;
@@ -2349,14 +2376,14 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
}
*/
}
-
+
// Draw current character glyph
DrawTextCodepoint(guiFont, codepoint, cursorPos, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
-
+
int glyphWidth = 0;
if (glyphInfo.advanceX != 0) glyphWidth += glyphInfo.advanceX;
else glyphWidth += (int)(atlasRec.width + glyphInfo.offsetX);
-
+
cursorPos.x += (glyphWidth*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
//if (i > lastSpacePos) lastSpaceWidth += (atlasRec.width + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
}
@@ -2364,7 +2391,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
cursor.x = cursorPos.x;
cursor.y = cursorPos.y;
-
+
// Draw cursor position considering text glyphs
if (editMode) GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
//--------------------------------------------------------------------
@@ -2443,7 +2470,7 @@ float GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight
if (textLeft != NULL)
{
Rectangle textBounds = { 0 };
- textBounds.width = (float)GetTextWidth(textLeft); // TODO: Consider text icon
+ textBounds.width = (float)GetTextWidth(textLeft);
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SLIDER, TEXT_PADDING);
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
@@ -2454,7 +2481,7 @@ float GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight
if (textRight != NULL)
{
Rectangle textBounds = { 0 };
- textBounds.width = (float)GetTextWidth(textRight); // TODO: Consider text icon
+ textBounds.width = (float)GetTextWidth(textRight);
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
textBounds.x = bounds.x + bounds.width + GuiGetStyle(SLIDER, TEXT_PADDING);
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
@@ -2504,7 +2531,7 @@ float GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRig
if (textLeft != NULL)
{
Rectangle textBounds = { 0 };
- textBounds.width = (float)GetTextWidth(textLeft); // TODO: Consider text icon
+ textBounds.width = (float)GetTextWidth(textLeft);
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
textBounds.x = bounds.x - textBounds.width - GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
@@ -2515,7 +2542,7 @@ float GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRig
if (textRight != NULL)
{
Rectangle textBounds = { 0 };
- textBounds.width = (float)GetTextWidth(textRight); // TODO: Consider text icon
+ textBounds.width = (float)GetTextWidth(textRight);
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
textBounds.x = bounds.x + bounds.width + GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
@@ -2568,7 +2595,6 @@ void GuiDummyRec(Rectangle bounds, const char *text)
}
// Scroll Bar control
-// TODO: I feel GuiScrollBar could be simplified...
int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
{
GuiControlState state = guiState;
@@ -2663,45 +2689,20 @@ int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
GuiDrawRectangle(scrollbar, 0, BLANK, Fade(GetColor(GuiGetStyle(BUTTON, BASE_COLOR_NORMAL)), guiAlpha)); // Draw the scrollbar active area background
GuiDrawRectangle(slider, 0, BLANK, Fade(GetColor(GuiGetStyle(SLIDER, BORDER + state*3)), guiAlpha)); // Draw the slider bar
- // Draw arrows
- const int padding = (spinnerSize - GuiGetStyle(SCROLLBAR, ARROWS_SIZE))/2;
- const Vector2 lineCoords[] =
- {
- // Coordinates for < 0,1,2
- { arrowUpLeft.x + padding, arrowUpLeft.y + spinnerSize/2 },
- { arrowUpLeft.x + spinnerSize - padding, arrowUpLeft.y + padding },
- { arrowUpLeft.x + spinnerSize - padding, arrowUpLeft.y + spinnerSize - padding },
-
- // Coordinates for > 3,4,5
- { arrowDownRight.x + padding, arrowDownRight.y + padding },
- { arrowDownRight.x + spinnerSize - padding, arrowDownRight.y + spinnerSize/2 },
- { arrowDownRight.x + padding, arrowDownRight.y + spinnerSize - padding },
-
- // Coordinates for ∧ 6,7,8
- { arrowUpLeft.x + spinnerSize/2, arrowUpLeft.y + padding },
- { arrowUpLeft.x + padding, arrowUpLeft.y + spinnerSize - padding },
- { arrowUpLeft.x + spinnerSize - padding, arrowUpLeft.y + spinnerSize - padding },
-
- // Coordinates for ∨ 9,10,11
- { arrowDownRight.x + padding, arrowDownRight.y + padding },
- { arrowDownRight.x + spinnerSize/2, arrowDownRight.y + spinnerSize - padding },
- { arrowDownRight.x + spinnerSize - padding, arrowDownRight.y + padding }
- };
-
- Color lineColor = Fade(GetColor(GuiGetStyle(BUTTON, TEXT + state*3)), guiAlpha);
-
+ // Draw arrows (using icon if available)
if (GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE))
{
- if (isVertical)
- {
- DrawTriangle(lineCoords[6], lineCoords[7], lineCoords[8], lineColor);
- DrawTriangle(lineCoords[9], lineCoords[10], lineCoords[11], lineColor);
- }
- else
- {
- DrawTriangle(lineCoords[2], lineCoords[1], lineCoords[0], lineColor);
- DrawTriangle(lineCoords[5], lineCoords[4], lineCoords[3], lineColor);
- }
+#if defined(RAYGUI_NO_RICONS)
+ GuiDrawText(isVertical? "^" : "<", RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
+ GuiDrawText(isVertical? "v" : ">", RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
+#else
+ GuiDrawText(isVertical? "#121#" : "#118#", RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3)), guiAlpha)); // RICON_ARROW_UP_FILL / RICON_ARROW_LEFT_FILL
+ GuiDrawText(isVertical? "#120#" : "#119#", RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3)), guiAlpha)); // RICON_ARROW_DOWN_FILL / RICON_ARROW_RIGHT_FILL
+#endif
}
//--------------------------------------------------------------------
@@ -2863,8 +2864,11 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *focus, in
}
// Color Panel control
-Color GuiColorPanelEx(Rectangle bounds, Color color, float hue)
+Color GuiColorPanel(Rectangle bounds, Color color)
{
+ const Color colWhite = { 255, 255, 255, 255 };
+ const Color colBlack = { 0, 0, 0, 255 };
+
GuiControlState state = guiState;
Vector2 pickerSelector = { 0 };
@@ -2874,15 +2878,13 @@ Color GuiColorPanelEx(Rectangle bounds, Color color, float hue)
pickerSelector.x = bounds.x + (float)hsv.y*bounds.width; // HSV: Saturation
pickerSelector.y = bounds.y + (1.0f - (float)hsv.z)*bounds.height; // HSV: Value
+ float hue = -1.0f;
Vector3 maxHue = { hue >= 0.0f ? hue : hsv.x, 1.0f, 1.0f };
Vector3 rgbHue = ConvertHSVtoRGB(maxHue);
Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x),
(unsigned char)(255.0f*rgbHue.y),
(unsigned char)(255.0f*rgbHue.z), 255 };
- const Color colWhite = { 255, 255, 255, 255 };
- const Color colBlack = { 0, 0, 0, 255 };
-
// Update control
//--------------------------------------------------------------------
if ((state != GUI_STATE_DISABLED) && !guiLocked)
@@ -2935,17 +2937,12 @@ Color GuiColorPanelEx(Rectangle bounds, Color color, float hue)
DrawRectangleGradientEx(bounds, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.6f), guiAlpha));
}
- GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
+ GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
//--------------------------------------------------------------------
return color;
}
-Color GuiColorPanel(Rectangle bounds, Color color)
-{
- return GuiColorPanelEx(bounds, color, -1.0f);
-}
-
// Color Bar Alpha control
// NOTE: Returns alpha value normalized [0..1]
float GuiColorBarAlpha(Rectangle bounds, float alpha)
@@ -2953,7 +2950,7 @@ float GuiColorBarAlpha(Rectangle bounds, float alpha)
#define COLORBARALPHA_CHECKED_SIZE 10
GuiControlState state = guiState;
- Rectangle selector = { (float)bounds.x + alpha*bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.y - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT), (float)bounds.height + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2 };
+ Rectangle selector = { (float)bounds.x + alpha*bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.y - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT), (float)bounds.height + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2 };
// Update control
//--------------------------------------------------------------------
@@ -2967,7 +2964,6 @@ float GuiColorBarAlpha(Rectangle bounds, float alpha)
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{
state = GUI_STATE_PRESSED;
- selector.x = mousePoint.x - selector.width/2;
alpha = (mousePoint.x - bounds.x)/bounds.width;
if (alpha <= 0.0f) alpha = 0.0f;
@@ -3001,7 +2997,7 @@ float GuiColorBarAlpha(Rectangle bounds, float alpha)
}
else DrawRectangleGradientEx(bounds, Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
- GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
+ GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
// Draw alpha bar: selector
GuiDrawRectangle(selector, 0, BLANK, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha));
@@ -3011,11 +3007,15 @@ float GuiColorBarAlpha(Rectangle bounds, float alpha)
}
// Color Bar Hue control
-// NOTE: Returns hue value normalized [0..1]
+// Returns hue value normalized [0..1]
+// NOTE: Other similar bars (for reference):
+// Color GuiColorBarSat() [WHITE->color]
+// Color GuiColorBarValue() [BLACK->color], HSV/HSL
+// float GuiColorBarLuminance() [BLACK->WHITE]
float GuiColorBarHue(Rectangle bounds, float hue)
{
GuiControlState state = guiState;
- Rectangle selector = { (float)bounds.x - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.y + hue/360.0f*bounds.height - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2, (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT) };
+ Rectangle selector = { (float)bounds.x - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.y + hue/360.0f*bounds.height - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2, (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT) };
// Update control
//--------------------------------------------------------------------
@@ -3029,7 +3029,6 @@ float GuiColorBarHue(Rectangle bounds, float hue)
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{
state = GUI_STATE_PRESSED;
- selector.y = mousePoint.y - selector.height/2;
hue = (mousePoint.y - bounds.y)*360/bounds.height;
if (hue <= 0.0f) hue = 0.0f;
@@ -3057,16 +3056,16 @@ float GuiColorBarHue(Rectangle bounds, float hue)
if (state != GUI_STATE_DISABLED)
{
// Draw hue bar:color bars
- DrawRectangleGradientV((int)bounds.x + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.y + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (int)bounds.height/6, Fade(RAYGUI_CLITERAL(Color){ 255,0,0,255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255,255,0,255 }, guiAlpha));
- DrawRectangleGradientV((int)bounds.x + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.y + (int)bounds.height/6 + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (int)bounds.height/6, Fade(RAYGUI_CLITERAL(Color){ 255,255,0,255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0,255,0,255 }, guiAlpha));
- DrawRectangleGradientV((int)bounds.x + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.y + 2*((int)bounds.height/6) + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (int)bounds.height/6, Fade(RAYGUI_CLITERAL(Color){ 0,255,0,255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0,255,255,255 }, guiAlpha));
- DrawRectangleGradientV((int)bounds.x + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.y + 3*((int)bounds.height/6) + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (int)bounds.height/6, Fade(RAYGUI_CLITERAL(Color){ 0,255,255,255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0,0,255,255 }, guiAlpha));
- DrawRectangleGradientV((int)bounds.x + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.y + 4*((int)bounds.height/6) + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (int)bounds.height/6, Fade(RAYGUI_CLITERAL(Color){ 0,0,255,255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255,0,255,255 }, guiAlpha));
- DrawRectangleGradientV((int)bounds.x + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.y + 5*((int)bounds.height/6) + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)/2, (int)bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (int)bounds.height/6 - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), Fade(RAYGUI_CLITERAL(Color){ 255,0,255,255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255,0,0,255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y), (int)bounds.width, ceil(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 255, 255, 0, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + bounds.height/6), (int)bounds.width, ceil(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 255, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 0, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 2*(bounds.height/6)), (int)bounds.width, ceil(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 255, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 3*(bounds.height/6)), (int)bounds.width, ceil(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 0, 0, 255, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 4*(bounds.height/6)), (int)bounds.width, ceil(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 0, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 255, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 5*(bounds.height/6)), (int)bounds.width, (int)(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 0, 255 }, guiAlpha));
}
else DrawRectangleGradientV((int)bounds.x, (int)bounds.y, (int)bounds.width, (int)bounds.height, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
- GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
+ GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
// Draw hue bar: selector
GuiDrawRectangle(selector, 0, BLANK, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha));
@@ -3075,10 +3074,6 @@ float GuiColorBarHue(Rectangle bounds, float hue)
return hue;
}
-// TODO: Color GuiColorBarSat() [WHITE->color]
-// TODO: Color GuiColorBarValue() [BLACK->color], HSV / HSL
-// TODO: float GuiColorBarLuminance() [BLACK->WHITE]
-
// Color Picker control
// NOTE: It's divided in multiple controls:
// Color GuiColorPanel(Rectangle bounds, Color color)
@@ -3096,6 +3091,7 @@ Color GuiColorPicker(Rectangle bounds, Color color)
hsv.x = GuiColorBarHue(boundsHue, hsv.x);
//color.a = (unsigned char)(GuiColorBarAlpha(boundsAlpha, (float)color.a/255.0f)*255.0f);
Vector3 rgb = ConvertHSVtoRGB(hsv);
+
color = RAYGUI_CLITERAL(Color){ (unsigned char)roundf(rgb.x*255.0f), (unsigned char)roundf(rgb.y*255.0f), (unsigned char)roundf(rgb.z*255.0f), color.a };
return color;
@@ -3246,8 +3242,8 @@ Vector2 GuiGrid(Rectangle bounds, float spacing, int subdivs)
{
if (CheckCollisionPointRec(mousePoint, bounds))
{
- currentCell.x = (mousePoint.x - bounds.x) / spacing;
- currentCell.y = (mousePoint.y - bounds.y) / spacing;
+ currentCell.x = (mousePoint.x - bounds.x)/spacing;
+ currentCell.y = (mousePoint.y - bounds.y)/spacing;
}
}
//--------------------------------------------------------------------
@@ -3263,15 +3259,15 @@ Vector2 GuiGrid(Rectangle bounds, float spacing, int subdivs)
// Draw vertical grid lines
for (int i = 0; i < linesV; i++)
{
- Rectangle lineV = { bounds.x + spacing * i / subdivs, bounds.y, 1, bounds.height };
- GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA * 4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA));
+ Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height };
+ GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA*4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA));
}
// Draw horizontal grid lines
for (int i = 0; i < linesH; i++)
{
- Rectangle lineH = { bounds.x, bounds.y + spacing * i / subdivs, bounds.width, 1 };
- GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA * 4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA));
+ Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width, 1 };
+ GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA*4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA));
}
}
} break;
@@ -3399,13 +3395,12 @@ void GuiLoadStyle(const char *fileName)
// NOTE: All DEFAULT properties should be defined first in the file
GuiSetStyle(0, (int)propertyId, propertyValue);
- if (propertyId < RAYGUI_MAX_PROPS_DEFAULT) for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) GuiSetStyle(i, (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
- // TODO: Find some mechanism to support it in standalone mode
#if !defined(RAYGUI_STANDALONE)
// Load custom font if available
int fontDataSize = 0;
@@ -3441,7 +3436,7 @@ void GuiLoadStyle(const char *fileName)
font.texture = LoadTextureFromImage(imFont);
- UnloadImage(imFont);
+ RAYGUI_FREE(imFont.data);
}
// Load font recs data
@@ -3557,7 +3552,9 @@ void GuiLoadStyleDefault(void)
// a number that can change between ricon versions
const char *GuiIconText(int iconId, const char *text)
{
-#if defined(RAYGUI_SUPPORT_RICONS)
+#if defined(RAYGUI_NO_RICONS)
+ return NULL;
+#else
static char buffer[1024] = { 0 };
memset(buffer, 0, 1024);
@@ -3573,12 +3570,10 @@ const char *GuiIconText(int iconId, const char *text)
}
return buffer;
-#else
- return NULL;
#endif
}
-#if defined(RAYGUI_SUPPORT_RICONS)
+#if !defined(RAYGUI_NO_RICONS)
// Get full icons data pointer
unsigned int *GuiGetIcons(void) { return guiIcons; }
@@ -3586,7 +3581,7 @@ unsigned int *GuiGetIcons(void) { return guiIcons; }
// Load raygui icons file (.rgi)
// NOTE: In case nameIds are required, they can be requested with loadIconsName,
// they are returned as a guiIconsName[iconCount][RICON_MAX_NAME_LENGTH],
-// guiIconsName[]][] memory should be manually freed!
+// WARNING: guiIconsName[]][] memory should be manually freed!
char **GuiLoadIcons(const char *fileName, bool loadIconsName)
{
// Style File Structure (.rgi)
@@ -3658,7 +3653,7 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName)
}
// Draw selected icon using rectangles pixel-by-pixel
-void GuiDrawIcon(int iconId, Vector2 position, int pixelSize, Color color)
+void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color)
{
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
@@ -3669,7 +3664,7 @@ void GuiDrawIcon(int iconId, Vector2 position, int pixelSize, Color color)
if (BIT_CHECK(guiIcons[iconId*RICON_DATA_ELEMENTS + i], k))
{
#if !defined(RAYGUI_STANDALONE)
- DrawRectangle(position.x + (k%RICON_SIZE)*pixelSize, position.y + y*pixelSize, pixelSize, pixelSize, color);
+ DrawRectangle(posX + (k%RICON_SIZE)*pixelSize, posY + y*pixelSize, pixelSize, pixelSize, color);
#endif
}
@@ -3724,19 +3719,21 @@ bool GuiCheckIconPixel(int iconId, int x, int y)
return (BIT_CHECK(guiIcons[iconId*8 + y/2], x + (y%2*16)));
}
-#endif // RAYGUI_SUPPORT_RICONS
+#endif // !RAYGUI_NO_RICONS
//----------------------------------------------------------------------------------
// Module specific Functions Definition
//----------------------------------------------------------------------------------
// Gui get text width using default font
+// NOTE: Icon is not considered here
static int GetTextWidth(const char *text)
{
Vector2 size = { 0 };
- if ((text != NULL) && (text[0] != '\0')) size = MeasureTextEx(guiFont, text, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
-
- // TODO: Consider text icon width here???
+ if ((text != NULL) && (text[0] != '\0'))
+ {
+ size = MeasureTextEx(guiFont, text, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
+ }
return (int)size.x;
}
@@ -3764,7 +3761,7 @@ static Rectangle GetTextBounds(int control, Rectangle bounds)
}
// TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW (scrollbar?)
- // More special cases (label side): CHECKBOX, SLIDER, VALUEBOX, SPINNER
+ // More special cases (label on side): CHECKBOX, SLIDER, VALUEBOX, SPINNER
return textBounds;
}
@@ -3773,7 +3770,7 @@ static Rectangle GetTextBounds(int control, Rectangle bounds)
// NOTE: We support up to 999 values for iconId
static const char *GetTextIcon(const char *text, int *iconId)
{
-#if defined(RAYGUI_SUPPORT_RICONS)
+#if !defined(RAYGUI_NO_RICONS)
*iconId = -1;
if (text[0] == '#') // Maybe we have an icon!
{
@@ -3791,7 +3788,7 @@ static const char *GetTextIcon(const char *text, int *iconId)
*iconId = TextToInteger(iconValue);
// Move text pointer after icon
- // WARNING: If only icon provided, it could point to EOL character!
+ // WARNING: If only icon provided, it could point to EOL character: '\0'
if (*iconId >= 0) text += (pos + 1);
}
}
@@ -3808,7 +3805,7 @@ static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color
if ((text != NULL) && (text[0] != '\0'))
{
int iconId = 0;
- text = GetTextIcon(text, &iconId); // Check text for icon and move cursor
+ text = GetTextIcon(text, &iconId); // Check text for icon and move cursor
// Get text position depending on alignment and iconId
//---------------------------------------------------------------------------------
@@ -3816,7 +3813,7 @@ static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color
Vector2 position = { bounds.x, bounds.y };
- // NOTE: We get text size after icon been processed
+ // NOTE: We get text size after icon has been processed
int textWidth = GetTextWidth(text);
int textHeight = GuiGetStyle(DEFAULT, TEXT_SIZE);
@@ -3825,10 +3822,10 @@ static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color
{
textWidth += RICON_SIZE;
- // WARNING: If only icon provided, text could be pointing to eof character!
+ // WARNING: If only icon provided, text could be pointing to EOF character: '\0'
if ((text != NULL) && (text[0] != '\0')) textWidth += RICON_TEXT_PADDING;
}
-
+
// Check guiTextAlign global variables
switch (alignment)
{
@@ -3858,11 +3855,11 @@ static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color
// Draw text (with icon if available)
//---------------------------------------------------------------------------------
-#if defined(RAYGUI_SUPPORT_RICONS)
+#if !defined(RAYGUI_NO_RICONS)
if (iconId >= 0)
{
// NOTE: We consider icon height, probably different than text size
- GuiDrawIcon(iconId, RAYGUI_CLITERAL(Vector2){ position.x, bounds.y + bounds.height/2 - RICON_SIZE/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height) }, 1, tint);
+ GuiDrawIcon(iconId, (int)position.x, (int)(bounds.y + bounds.height/2 - RICON_SIZE/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height)), 1, tint);
position.x += (RICON_SIZE + RICON_TEXT_PADDING);
}
#endif
@@ -3888,9 +3885,6 @@ static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor,
DrawRectangle((int)rec.x + (int)rec.width - borderWidth, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, borderColor);
DrawRectangle((int)rec.x, (int)rec.y + (int)rec.height - borderWidth, (int)rec.width, borderWidth, borderColor);
}
-
- // TODO: For n-patch-based style we would need: [state] and maybe [control]
- // In this case all controls drawing logic should be moved to this function... I don't like it...
}
// Split controls text into multiple strings
@@ -3969,7 +3963,7 @@ static Vector3 ConvertRGBtoHSV(Vector3 rgb)
if (delta < 0.00001f)
{
hsv.y = 0.0f;
- hsv.x = 0.0f; // Undefined, maybe NAN?
+ hsv.x = 0.0f; // Undefined, maybe NAN?
return hsv;
}
@@ -3982,7 +3976,7 @@ static Vector3 ConvertRGBtoHSV(Vector3 rgb)
{
// NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined
hsv.y = 0.0f;
- hsv.x = 0.0f; // Undefined, maybe NAN?
+ hsv.x = 0.0f; // Undefined, maybe NAN?
return hsv;
}
@@ -4140,7 +4134,6 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
#define TEXTSPLIT_MAX_TEXT_BUFFER_LENGTH 1024 // Size of static buffer: TextSplit()
#define TEXTSPLIT_MAX_SUBSTRINGS_COUNT 128 // Size of static pointers array: TextSplit()
-
// Split string into multiple strings
const char **TextSplit(const char *text, char delimiter, int *count)
{
@@ -4236,6 +4229,114 @@ static const char *CodepointToUTF8(int codepoint, int *byteSize)
return utf8;
}
+
+// Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found
+// When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned
+// Total number of bytes processed are returned as a parameter
+// NOTE: the standard says U+FFFD should be returned in case of errors
+// but that character is not supported by the default font in raylib
+static int GetCodepoint(const char *text, int *bytesProcessed)
+{
+/*
+ UTF-8 specs from https://www.ietf.org/rfc/rfc3629.txt
+
+ Char. number range | UTF-8 octet sequence
+ (hexadecimal) | (binary)
+ --------------------+---------------------------------------------
+ 0000 0000-0000 007F | 0xxxxxxx
+ 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+ 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+ 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+*/
+ // NOTE: on decode errors we return as soon as possible
+
+ int code = 0x3f; // Codepoint (defaults to '?')
+ int octet = (unsigned char)(text[0]); // The first UTF8 octet
+ *bytesProcessed = 1;
+
+ if (octet <= 0x7f)
+ {
+ // Only one octet (ASCII range x00-7F)
+ code = text[0];
+ }
+ else if ((octet & 0xe0) == 0xc0)
+ {
+ // Two octets
+
+ // [0]xC2-DF [1]UTF8-tail(x80-BF)
+ unsigned char octet1 = text[1];
+
+ if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
+
+ if ((octet >= 0xc2) && (octet <= 0xdf))
+ {
+ code = ((octet & 0x1f) << 6) | (octet1 & 0x3f);
+ *bytesProcessed = 2;
+ }
+ }
+ else if ((octet & 0xf0) == 0xe0)
+ {
+ // Three octets
+ unsigned char octet1 = text[1];
+ unsigned char octet2 = '\0';
+
+ if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
+
+ octet2 = text[2];
+
+ if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
+
+ // [0]xE0 [1]xA0-BF [2]UTF8-tail(x80-BF)
+ // [0]xE1-EC [1]UTF8-tail [2]UTF8-tail(x80-BF)
+ // [0]xED [1]x80-9F [2]UTF8-tail(x80-BF)
+ // [0]xEE-EF [1]UTF8-tail [2]UTF8-tail(x80-BF)
+
+ if (((octet == 0xe0) && !((octet1 >= 0xa0) && (octet1 <= 0xbf))) ||
+ ((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *bytesProcessed = 2; return code; }
+
+ if ((octet >= 0xe0) && (0 <= 0xef))
+ {
+ code = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f);
+ *bytesProcessed = 3;
+ }
+ }
+ else if ((octet & 0xf8) == 0xf0)
+ {
+ // Four octets
+ if (octet > 0xf4) return code;
+
+ unsigned char octet1 = text[1];
+ unsigned char octet2 = '\0';
+ unsigned char octet3 = '\0';
+
+ if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
+
+ octet2 = text[2];
+
+ if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
+
+ octet3 = text[3];
+
+ if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *bytesProcessed = 4; return code; } // Unexpected sequence
+
+ // [0]xF0 [1]x90-BF [2]UTF8-tail [3]UTF8-tail
+ // [0]xF1-F3 [1]UTF8-tail [2]UTF8-tail [3]UTF8-tail
+ // [0]xF4 [1]x80-8F [2]UTF8-tail [3]UTF8-tail
+
+ if (((octet == 0xf0) && !((octet1 >= 0x90) && (octet1 <= 0xbf))) ||
+ ((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *bytesProcessed = 2; return code; } // Unexpected sequence
+
+ if (octet >= 0xf0)
+ {
+ code = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f);
+ *bytesProcessed = 4;
+ }
+ }
+
+ if (code > 0x10ffff) code = 0x3f; // Codepoints after U+10ffff are invalid
+
+ return code;
+}
#endif // RAYGUI_STANDALONE
#endif // RAYGUI_IMPLEMENTATION