Compare commits

...

4 Commits

Author SHA1 Message Date
Rose 5627ce61cd
Merge d5dadec229 into ddba1319de 2024-05-03 21:38:11 +01:00
flowerpewpew d5dadec229 Fix !guiSliderDragging && 2024-05-03 21:34:05 +01:00
flowerpewpew 1bcd3d67ac Downgrade raygui to 4.0 2024-05-03 21:32:45 +01:00
flowerpewpew cf0ec5561c Relative paths 2024-05-03 21:20:44 +01:00
4 changed files with 258 additions and 242 deletions

31
ShapeUpWin.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34003.232
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShapeUp", "ShapeUpWin.vcxproj", "{01B70E71-8A13-4D13-858E-3DED3F60BDF5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Debug|x64.ActiveCfg = Debug|x64
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Debug|x64.Build.0 = Debug|x64
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Debug|x86.ActiveCfg = Debug|Win32
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Debug|x86.Build.0 = Debug|Win32
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Release|x64.ActiveCfg = Release|x64
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Release|x64.Build.0 = Release|x64
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Release|x86.ActiveCfg = Release|Win32
{01B70E71-8A13-4D13-858E-3DED3F60BDF5}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {52BEAE79-1465-452D-A62E-A0523CBC029A}
EndGlobalSection
EndGlobal

View File

@ -71,7 +71,7 @@
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Users\rosie\source\repos\ShapeUpWin\ShapeUpWin\lib\raylib-4.5.0_win64_msvc16\include</IncludePath> <IncludePath>$(VC_IncludePath);$(ProjectDir)\lib\raylib-4.5.0_win64_msvc16\include</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
@ -111,7 +111,7 @@
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\rosie\source\repos\ShapeUpWin\ShapeUpWin\lib\raylib-4.5.0_win64_msvc16\lib</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(ProjectDir)\lib\raylib-4.5.0_win64_msvc16\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>raylib.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>

View File

@ -1,6 +1,6 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raygui v4.1-dev - A simple and easy-to-use immediate-mode gui library * raygui v4.0 - 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
@ -26,7 +26,7 @@
* NOTES: * NOTES:
* - WARNING: GuiLoadStyle() and GuiLoadStyle{Custom}() functions, allocate memory for * - WARNING: GuiLoadStyle() and GuiLoadStyle{Custom}() functions, allocate memory for
* font atlas recs and glyphs, freeing that memory is (usually) up to the user, * font atlas recs and glyphs, freeing that memory is (usually) up to the user,
* no unload function is explicitly provided... but note that GuiLoadStyleDefault() unloads * no unload function is explicitly provided... but note that GuiLoadStyleDefaulf() unloads
* by default any previously loaded font (texture, recs, glyphs). * by default any previously loaded font (texture, recs, glyphs).
* - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions * - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions
* *
@ -141,9 +141,6 @@
* Draw text bounds rectangles for debug * Draw text bounds rectangles for debug
* *
* VERSIONS HISTORY: * VERSIONS HISTORY:
* 4.1-dev (2024) Current dev version...
* ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes
*
* 4.0 (12-Sep-2023) ADDED: GuiToggleSlider() * 4.0 (12-Sep-2023) ADDED: GuiToggleSlider()
* ADDED: GuiColorPickerHSV() and GuiColorPanelHSV() * ADDED: GuiColorPickerHSV() and GuiColorPanelHSV()
* ADDED: Multiple new icons, mostly compiler related * ADDED: Multiple new icons, mostly compiler related
@ -317,9 +314,9 @@
#define RAYGUI_H #define RAYGUI_H
#define RAYGUI_VERSION_MAJOR 4 #define RAYGUI_VERSION_MAJOR 4
#define RAYGUI_VERSION_MINOR 1 #define RAYGUI_VERSION_MINOR 0
#define RAYGUI_VERSION_PATCH 0 #define RAYGUI_VERSION_PATCH 0
#define RAYGUI_VERSION "4.1-dev" #define RAYGUI_VERSION "4.0"
#if !defined(RAYGUI_STANDALONE) #if !defined(RAYGUI_STANDALONE)
#include "raylib.h" #include "raylib.h"
@ -444,6 +441,7 @@
} Font; } Font;
#endif #endif
// Style property // Style property
// NOTE: Used when exporting style as code for convenience // NOTE: Used when exporting style as code for convenience
typedef struct GuiStyleProp { typedef struct GuiStyleProp {
@ -548,6 +546,7 @@ typedef enum {
// TEXT_SIZE, TEXT_SPACING, TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE are global and // TEXT_SIZE, TEXT_SPACING, TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE are global and
// should be configured by user as needed while defining the UI layout // should be configured by user as needed while defining the UI layout
// Gui extended properties depend on control // Gui extended properties depend on control
// NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties) // NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -563,7 +562,7 @@ typedef enum {
TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding) TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding)
TEXT_WRAP_MODE // Text wrap-mode inside text bounds TEXT_WRAP_MODE // Text wrap-mode inside text bounds
//TEXT_DECORATION // Text decoration: 0-None, 1-Underline, 2-Line-through, 3-Overline //TEXT_DECORATION // Text decoration: 0-None, 1-Underline, 2-Line-through, 3-Overline
//TEXT_DECORATION_THICK // Text decoration line thickness //TEXT_DECORATION_THICK // Text decoration line thikness
} GuiDefaultProperty; } GuiDefaultProperty;
// Other possible text properties: // Other possible text properties:
@ -699,6 +698,7 @@ RAYGUIAPI char **GuiLoadIcons(const char *fileName, bool loadIconsName); // Load
RAYGUIAPI void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color); // Draw icon using pixel size at specified position RAYGUIAPI void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color); // Draw icon using pixel size at specified position
#endif #endif
// Controls // Controls
//---------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------
// Container/separator controls, useful for controls organization // Container/separator controls, useful for controls organization
@ -710,29 +710,29 @@ RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *act
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
// Basic controls set // Basic controls set
RAYGUIAPI int GuiLabel(Rectangle bounds, const char *text); // Label control RAYGUIAPI int GuiLabel(Rectangle bounds, const char *text); // Label control, shows text
RAYGUIAPI int GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked RAYGUIAPI int GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked
RAYGUIAPI int GuiLabelButton(Rectangle bounds, const char *text); // Label button control, returns true when clicked RAYGUIAPI int GuiLabelButton(Rectangle bounds, const char *text); // Label button control, show true when clicked
RAYGUIAPI int GuiToggle(Rectangle bounds, const char *text, bool *active); // Toggle Button control RAYGUIAPI int 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 RAYGUIAPI int GuiToggleGroup(Rectangle bounds, const char *text, int *active); // Toggle Group control, returns active toggle index
RAYGUIAPI int GuiToggleSlider(Rectangle bounds, const char *text, int *active); // Toggle Slider control RAYGUIAPI int GuiToggleSlider(Rectangle bounds, const char *text, int *active); // Toggle Slider control, returns true when clicked
RAYGUIAPI int GuiCheckBox(Rectangle bounds, const char *text, bool *checked); // Check Box control, returns true when active RAYGUIAPI int 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 RAYGUIAPI int GuiComboBox(Rectangle bounds, const char *text, int *active); // Combo Box control, returns selected item index
RAYGUIAPI int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control RAYGUIAPI int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control, returns selected item
RAYGUIAPI int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control RAYGUIAPI int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control, returns selected value
RAYGUIAPI int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers RAYGUIAPI int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers
RAYGUIAPI int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text RAYGUIAPI int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text
RAYGUIAPI int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider control RAYGUIAPI int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider control, returns selected value
RAYGUIAPI int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider Bar control RAYGUIAPI int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider Bar control, returns selected value
RAYGUIAPI int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Progress Bar control RAYGUIAPI int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Progress Bar control, shows current progress value
RAYGUIAPI int GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text RAYGUIAPI int GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text
RAYGUIAPI int GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders RAYGUIAPI int GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders
RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell); // Grid control RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell); // Grid control, returns mouse cell position
// Advance controls set // Advance controls set
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View 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 *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // 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 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, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
@ -741,9 +741,10 @@ RAYGUIAPI int GuiColorPanel(Rectangle bounds, const char *text, Color *color);
RAYGUIAPI int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha); // Color Bar Alpha control RAYGUIAPI int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha); // Color Bar Alpha control
RAYGUIAPI int GuiColorBarHue(Rectangle bounds, const char *text, float *value); // Color Bar Hue control RAYGUIAPI int GuiColorBarHue(Rectangle bounds, const char *text, float *value); // Color Bar Hue control
RAYGUIAPI int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Picker control that avoids conversion to RGB on each call (multiple color controls) RAYGUIAPI int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Picker control that avoids conversion to RGB on each call (multiple color controls)
RAYGUIAPI int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Panel control that updates Hue-Saturation-Value color value, used by GuiColorPickerHSV() RAYGUIAPI int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Panel control that returns HSV color value, used by GuiColorPickerHSV()
//---------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------
#if !defined(RAYGUI_NO_ICONS) #if !defined(RAYGUI_NO_ICONS)
#if !defined(RAYGUI_CUSTOM_ICONS) #if !defined(RAYGUI_CUSTOM_ICONS)
@ -971,9 +972,9 @@ typedef enum {
ICON_FOLDER = 217, ICON_FOLDER = 217,
ICON_FILE = 218, ICON_FILE = 218,
ICON_SAND_TIMER = 219, ICON_SAND_TIMER = 219,
ICON_WARNING = 220, ICON_220 = 220,
ICON_HELP_BOX = 221, ICON_221 = 221,
ICON_INFO_BOX = 222, ICON_222 = 222,
ICON_223 = 223, ICON_223 = 223,
ICON_224 = 224, ICON_224 = 224,
ICON_225 = 225, ICON_225 = 225,
@ -1289,9 +1290,9 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] =
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
0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER 0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER
0x01800000, 0x02400240, 0x05a00420, 0x09900990, 0x11881188, 0x21842004, 0x40024182, 0x00003ffc, // ICON_WARNING 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_220
0x7ffe0000, 0x4ff24002, 0x4c324ff2, 0x4f824c02, 0x41824f82, 0x41824002, 0x40024182, 0x00007ffe, // ICON_HELP_BOX 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_221
0x7ffe0000, 0x41824002, 0x40024182, 0x41824182, 0x41824182, 0x41824182, 0x40024182, 0x00007ffe, // ICON_INFO_BOX 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_222
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_223
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_224
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_225 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_225
@ -1327,7 +1328,7 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] =
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_255 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_255
}; };
// NOTE: A pointer to current icons array should be defined // NOTE: We keep a pointer to the icons array, useful to point to other sets if required
static unsigned int *guiIconsPtr = guiIcons; static unsigned int *guiIconsPtr = guiIcons;
#endif // !RAYGUI_NO_ICONS && !RAYGUI_CUSTOM_ICONS #endif // !RAYGUI_NO_ICONS && !RAYGUI_CUSTOM_ICONS
@ -1362,8 +1363,8 @@ 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 bool guiControlExclusiveMode = false; // Gui control exclusive mode (no inputs processed except current control) static bool guiSliderDragging = false; // Gui slider drag state (no inputs processed except dragged slider)
static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds rectangle, used as an unique identifier static Rectangle guiSliderActive = { 0 }; // Gui slider active bounds rectangle, used as an unique identifier
static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() static 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
@ -1743,9 +1744,6 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
if (toggle) *active = i; if (toggle) *active = i;
} }
// Close tab with middle mouse button pressed
if (CheckCollisionPointRec(GetMousePosition(), tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i;
GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding);
GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment);
@ -1777,10 +1775,10 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector
{ {
#define RAYGUI_MIN_SCROLLBAR_WIDTH 40 #define RAYGUI_MIN_SCROLLBAR_WIDTH 40
#define RAYGUI_MIN_SCROLLBAR_HEIGHT 40 #define RAYGUI_MIN_SCROLLBAR_HEIGHT 40
#define RAYGUI_MIN_MOUSE_WHEEL_SPEED 20
int result = 0; int result = 0;
GuiState state = guiState; GuiState state = guiState;
float mouseWheelSpeed = 20.0f; // Default movement speed with mouse wheel
Rectangle temp = { 0 }; Rectangle temp = { 0 };
if (view == NULL) view = &temp; if (view == NULL) view = &temp;
@ -1822,8 +1820,17 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector
}; };
// Make sure scroll bars have a minimum width/height // Make sure scroll bars have a minimum width/height
if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH; // NOTE: If content >>> bounds, size could be very small or even 0
if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT; if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH)
{
horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH;
mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.height vs bounds.height
}
if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT)
{
verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT;
mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.width vs bounds.width
}
// Calculate view area (area without the scrollbars) // Calculate view area (area without the scrollbars)
*view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? *view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)?
@ -1866,14 +1873,9 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector
#endif #endif
float wheelMove = GetMouseWheelMove(); float wheelMove = GetMouseWheelMove();
// Set scrolling speed with mouse wheel based on ratio between bounds and content
Vector2 mouseWheelSpeed = { content.width / bounds.width, content.height / bounds.height };
if (mouseWheelSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED;
if (mouseWheelSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED;
// Horizontal and vertical scrolling with mouse wheel // Horizontal and vertical scrolling with mouse wheel
if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x; if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed;
else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll else scrollPos.y += wheelMove*mouseWheelSpeed; // Vertical scroll
} }
} }
@ -1919,7 +1921,7 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector
} }
// Draw scrollbar lines depending on current state // Draw scrollbar lines depending on current state
GuiDrawRectangle(bounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + (state*3))), BLANK); GuiDrawRectangle(bounds, GuiGetStyle(DEFAULT, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + (state*3))), BLANK);
// Set scrollbar slider size back to the way it was before // Set scrollbar slider size back to the way it was before
GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider); GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider);
@ -1957,7 +1959,7 @@ int GuiButton(Rectangle bounds, const char *text)
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -1995,7 +1997,7 @@ int GuiLabelButton(Rectangle bounds, const char *text)
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -2018,7 +2020,7 @@ int GuiLabelButton(Rectangle bounds, const char *text)
return pressed; return pressed;
} }
// Toggle Button control // Toggle Button control, returns true when active
int GuiToggle(Rectangle bounds, const char *text, bool *active) int GuiToggle(Rectangle bounds, const char *text, bool *active)
{ {
int result = 0; int result = 0;
@ -2029,7 +2031,7 @@ int GuiToggle(Rectangle bounds, const char *text, bool *active)
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -2066,7 +2068,7 @@ int GuiToggle(Rectangle bounds, const char *text, bool *active)
return result; return result;
} }
// Toggle Group control // Toggle Group control, returns toggled button codepointIndex
int GuiToggleGroup(Rectangle bounds, const char *text, int *active) int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
{ {
#if !defined(RAYGUI_TOGGLEGROUP_MAX_ITEMS) #if !defined(RAYGUI_TOGGLEGROUP_MAX_ITEMS)
@ -2115,7 +2117,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
return result; return result;
} }
// Toggle Slider control extended // Toggle Slider control extended, returns true when clicked
int GuiToggleSlider(Rectangle bounds, const char *text, int *active) int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
{ {
int result = 0; int result = 0;
@ -2209,7 +2211,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked)
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -2254,7 +2256,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked)
return result; return result;
} }
// Combo Box control // Combo Box control, returns selected item codepointIndex
int GuiComboBox(Rectangle bounds, const char *text, int *active) int GuiComboBox(Rectangle bounds, const char *text, int *active)
{ {
int result = 0; int result = 0;
@ -2277,7 +2279,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -2339,7 +2341,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -2438,7 +2440,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
// Text Box control // Text Box control
// NOTE: Returns true on ENTER pressed (useful for data validation) // NOTE: Returns true on ENTER pressed (useful for data validation)
int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
{ {
#if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)
#define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement
@ -2494,7 +2496,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
if ((state != STATE_DISABLED) && // Control not disabled if ((state != STATE_DISABLED) && // Control not disabled
!GuiGetStyle(TEXTBOX, TEXT_READONLY) && // TextBox not on read-only mode !GuiGetStyle(TEXTBOX, TEXT_READONLY) && // TextBox not on read-only mode
!guiLocked && // Gui not locked !guiLocked && // Gui not locked
!guiControlExclusiveMode && // No gui slider on dragging !guiSliderDragging && // No gui slider on dragging
(wrapMode == TEXT_WRAP_NONE)) // No wrap mode (wrapMode == TEXT_WRAP_NONE)) // No wrap mode
{ {
Vector2 mousePosition = GetMousePosition(); Vector2 mousePosition = GetMousePosition();
@ -2527,7 +2529,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
// Add codepoint to text, at current cursor position // Add codepoint to text, at current cursor position
// NOTE: Make sure we do not overflow buffer size // NOTE: Make sure we do not overflow buffer size
if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize)) if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < bufferSize))
{ {
// Move forward data from cursor position // Move forward data from cursor position
for (int i = (textLength + codepointSize); i > textBoxCursorIndex; i--) text[i] = text[i - codepointSize]; for (int i = (textLength + codepointSize); i > textBoxCursorIndex; i--) text[i] = text[i - codepointSize];
@ -2725,7 +2727,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
/* /*
// Text Box control with multiple lines and word-wrap // Text Box control with multiple lines and word-wrap
// NOTE: This text-box is readonly, no editing supported by default // NOTE: This text-box is readonly, no editing supported by default
bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode) bool GuiTextBoxMulti(Rectangle bounds, char *text, int bufferSize, bool editMode)
{ {
bool pressed = false; bool pressed = false;
@ -2734,7 +2736,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP); GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP);
// TODO: Implement methods to calculate cursor position properly // TODO: Implement methods to calculate cursor position properly
pressed = GuiTextBox(bounds, text, textSize, editMode); pressed = GuiTextBox(bounds, text, bufferSize, editMode);
GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE);
GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE); GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE);
@ -2769,7 +2771,7 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -2844,7 +2846,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -2888,13 +2890,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
//if (*value > maxValue) *value = maxValue; //if (*value > maxValue) *value = maxValue;
//else if (*value < minValue) *value = minValue; //else if (*value < minValue) *value = minValue;
if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) result = 1;
{
if (*value > maxValue) *value = maxValue;
else if (*value < minValue) *value = minValue;
result = 1;
}
} }
else else
{ {
@ -2939,36 +2935,50 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth) int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth)
{ {
int result = 0; int result = 0;
float oldValue = *value;
GuiState state = guiState; GuiState state = guiState;
float temp = (maxValue - minValue)/2.0f; float temp = (maxValue - minValue)/2.0f;
if (value == NULL) value = &temp; if (value == NULL) value = &temp;
float oldValue = *value;
int sliderValue = (int)(((*value - minValue)/(maxValue - minValue))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH)));
Rectangle slider = { bounds.x, bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING), Rectangle slider = { bounds.x, bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING),
0, bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) }; 0, bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) };
if (sliderWidth > 0) // Slider
{
slider.x += (sliderValue - sliderWidth/2);
slider.width = (float)sliderWidth;
}
else if (sliderWidth == 0) // SliderBar
{
slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH);
slider.width = (float)sliderValue;
}
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked) if ((state != STATE_DISABLED) && !guiLocked)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds if (guiSliderDragging) // Keep dragging outside of bounds
{ {
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{ {
if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
{ {
state = STATE_PRESSED; state = STATE_PRESSED;
// Get equivalent value and slider position from mousePosition.x // Get equivalent value and slider position from mousePosition.x
*value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width-sliderWidth)) + minValue; *value = ((maxValue - minValue)*(mousePoint.x - (float)(bounds.x + sliderWidth/2)))/(float)(bounds.width - sliderWidth) + minValue;
} }
} }
else else
{ {
guiControlExclusiveMode = false; guiSliderDragging = false;
guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
} }
} }
else if (CheckCollisionPointRec(mousePoint, bounds)) else if (CheckCollisionPointRec(mousePoint, bounds))
@ -2976,13 +2986,16 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight,
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{ {
state = STATE_PRESSED; state = STATE_PRESSED;
guiControlExclusiveMode = true; guiSliderDragging = true;
guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts guiSliderActive = bounds; // Store bounds as an identifier when dragging starts
if (!CheckCollisionPointRec(mousePoint, slider)) if (!CheckCollisionPointRec(mousePoint, slider))
{ {
// Get equivalent value and slider position from mousePosition.x // Get equivalent value and slider position from mousePosition.x
*value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width-sliderWidth)) + minValue; *value = ((maxValue - minValue)*(mousePoint.x - (float)(bounds.x + sliderWidth/2)))/(float)(bounds.width - sliderWidth) + minValue;
if (sliderWidth > 0) slider.x = mousePoint.x - slider.width/2; // Slider
else if (sliderWidth == 0) slider.width = (float)sliderValue; // SliderBar
} }
} }
else state = STATE_FOCUSED; else state = STATE_FOCUSED;
@ -2996,19 +3009,14 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight,
if(oldValue == *value) result = 0; if(oldValue == *value) result = 0;
else result = 1; else result = 1;
// Slider bar limits check // Bar limits check
int sliderValue = (int)(((*value - minValue)/(maxValue - minValue))*(bounds.width - sliderWidth - GuiGetStyle(SLIDER, BORDER_WIDTH)));
if (sliderWidth > 0) // Slider if (sliderWidth > 0) // Slider
{ {
slider.x += sliderValue;
slider.width = (float)sliderWidth;
if (slider.x <= (bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH))) slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH); if (slider.x <= (bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH))) slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH);
else if ((slider.x + slider.width) >= (bounds.x + bounds.width)) slider.x = bounds.x + bounds.width - slider.width - GuiGetStyle(SLIDER, BORDER_WIDTH); else if ((slider.x + slider.width) >= (bounds.x + bounds.width)) slider.x = bounds.x + bounds.width - slider.width - GuiGetStyle(SLIDER, BORDER_WIDTH);
} }
else if (sliderWidth == 0) // SliderBar else if (sliderWidth == 0) // SliderBar
{ {
slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH);
slider.width = (float)sliderValue;
if (slider.width > bounds.width) slider.width = bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH); if (slider.width > bounds.width) slider.width = bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH);
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -3163,7 +3171,7 @@ int GuiDummyRec(Rectangle bounds, const char *text)
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -3230,7 +3238,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -3345,32 +3353,83 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd
return result; return result;
} }
// Color Panel control - Color (RGBA) variant. // Color Panel control
int GuiColorPanel(Rectangle bounds, const char *text, Color *color) int GuiColorPanel(Rectangle bounds, const char *text, Color *color)
{ {
int result = 0; int result = 0;
GuiState state = guiState;
Vector2 pickerSelector = { 0 };
const Color colWhite = { 255, 255, 255, 255 };
const Color colBlack = { 0, 0, 0, 255 };
Vector3 vcolor = { (float)color->r/255.0f, (float)color->g/255.0f, (float)color->b/255.0f }; Vector3 vcolor = { (float)color->r/255.0f, (float)color->g/255.0f, (float)color->b/255.0f };
Vector3 hsv = ConvertRGBtoHSV(vcolor); Vector3 hsv = ConvertRGBtoHSV(vcolor);
Vector3 prevHsv = hsv; // workaround to see if GuiColorPanelHSV modifies the hsv.
GuiColorPanelHSV(bounds, text, &hsv); pickerSelector.x = bounds.x + (float)hsv.y*bounds.width; // HSV: Saturation
pickerSelector.y = bounds.y + (1.0f - (float)hsv.z)*bounds.height; // HSV: Value
// Check if the hsv was changed, only then change the color. Vector3 maxHue = { hsv.x, 1.0f, 1.0f };
// This is necessary, because the Color->HSV->Color conversion has precision errors. Vector3 rgbHue = ConvertHSVtoRGB(maxHue);
// Thus the assignment from HSV to Color should only be made, if the HSV has a new user-entered value. Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x),
// Otherwise GuiColorPanel would often modify it's color without user input. (unsigned char)(255.0f*rgbHue.y),
// TODO: GuiColorPanelHSV could return 1 if the slider was dragged, to simplify this check. (unsigned char)(255.0f*rgbHue.z), 255 };
if (hsv.x != prevHsv.x || hsv.y != prevHsv.y || hsv.z != prevHsv.z)
// Update control
//--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition();
if (CheckCollisionPointRec(mousePoint, bounds))
{
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{
state = STATE_PRESSED;
pickerSelector = mousePoint;
// Calculate color from picker
Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y };
colorPick.x /= (float)bounds.width; // Get normalized value on x
colorPick.y /= (float)bounds.height; // Get normalized value on y
hsv.y = colorPick.x;
hsv.z = 1.0f - colorPick.y;
Vector3 rgb = ConvertHSVtoRGB(hsv); Vector3 rgb = ConvertHSVtoRGB(hsv);
// NOTE: Vector3ToColor() only available on raylib 1.8.1 // NOTE: Vector3ToColor() only available on raylib 1.8.1
*color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x), *color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x),
(unsigned char)(255.0f*rgb.y), (unsigned char)(255.0f*rgb.y),
(unsigned char)(255.0f*rgb.z), (unsigned char)(255.0f*rgb.z),
color->a }; (unsigned char)(255.0f*(float)color->a/255.0f) };
} }
else state = STATE_FOCUSED;
}
}
//--------------------------------------------------------------------
// Draw control
//--------------------------------------------------------------------
if (state != STATE_DISABLED)
{
DrawRectangleGradientEx(bounds, Fade(colWhite, guiAlpha), Fade(colWhite, guiAlpha), Fade(maxHueCol, guiAlpha), Fade(maxHueCol, guiAlpha));
DrawRectangleGradientEx(bounds, Fade(colBlack, 0), Fade(colBlack, guiAlpha), Fade(colBlack, guiAlpha), Fade(colBlack, 0));
// Draw color picker: selector
Rectangle selector = { pickerSelector.x - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, pickerSelector.y - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE), (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE) };
GuiDrawRectangle(selector, 0, BLANK, colWhite);
}
else
{
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, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK);
//--------------------------------------------------------------------
return result; return result;
} }
@ -3392,11 +3451,11 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds if (guiSliderDragging) // Keep dragging outside of bounds
{ {
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{ {
if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
{ {
state = STATE_PRESSED; state = STATE_PRESSED;
@ -3407,8 +3466,8 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha)
} }
else else
{ {
guiControlExclusiveMode = false; guiSliderDragging = false;
guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
} }
} }
else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector))
@ -3416,8 +3475,8 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha)
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{ {
state = STATE_PRESSED; state = STATE_PRESSED;
guiControlExclusiveMode = true; guiSliderDragging = true;
guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts 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;
@ -3478,11 +3537,11 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds if (guiSliderDragging) // Keep dragging outside of bounds
{ {
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{ {
if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
{ {
state = STATE_PRESSED; state = STATE_PRESSED;
@ -3493,8 +3552,8 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue)
} }
else else
{ {
guiControlExclusiveMode = false; guiSliderDragging = false;
guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
} }
} }
else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector))
@ -3502,8 +3561,8 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue)
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{ {
state = STATE_PRESSED; state = STATE_PRESSED;
guiControlExclusiveMode = true; guiSliderDragging = true;
guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts 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;
@ -3556,7 +3615,6 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue)
// float GuiColorBarAlpha(Rectangle bounds, float alpha) // float GuiColorBarAlpha(Rectangle bounds, float alpha)
// float GuiColorBarHue(Rectangle bounds, float value) // float GuiColorBarHue(Rectangle bounds, float value)
// NOTE: bounds define GuiColorPanel() size // NOTE: bounds define GuiColorPanel() size
// NOTE: this picker converts RGB to HSV, which can cause the Hue control to jump. If you have this problem, consider using the HSV variant instead
int GuiColorPicker(Rectangle bounds, const char *text, Color *color) int GuiColorPicker(Rectangle bounds, const char *text, Color *color)
{ {
int result = 0; int result = 0;
@ -3569,7 +3627,6 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *color)
Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height }; Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height };
//Rectangle boundsAlpha = { bounds.x, bounds.y + bounds.height + GuiGetStyle(COLORPICKER, BARS_PADDING), bounds.width, GuiGetStyle(COLORPICKER, BARS_THICK) }; //Rectangle boundsAlpha = { bounds.x, bounds.y + bounds.height + GuiGetStyle(COLORPICKER, BARS_PADDING), bounds.width, GuiGetStyle(COLORPICKER, BARS_THICK) };
// NOTE: this conversion can cause low hue-resolution, if the r, g and b value are very similar, which causes the hue bar to shift around when only the GuiColorPanel is used.
Vector3 hsv = ConvertRGBtoHSV(RAYGUI_CLITERAL(Vector3){ (*color).r/255.0f, (*color).g/255.0f, (*color).b/255.0f }); Vector3 hsv = ConvertRGBtoHSV(RAYGUI_CLITERAL(Vector3){ (*color).r/255.0f, (*color).g/255.0f, (*color).b/255.0f });
GuiColorBarHue(boundsHue, NULL, &hsv.x); GuiColorBarHue(boundsHue, NULL, &hsv.x);
@ -3611,7 +3668,8 @@ int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv)
return result; return result;
} }
// Color Panel control - HSV variant // Color Panel control, returns HSV color value in *colorHsv.
// Used by GuiColorPickerHSV()
int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv)
{ {
int result = 0; int result = 0;
@ -3632,47 +3690,15 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv)
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds if (CheckCollisionPointRec(mousePoint, bounds))
{
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
{
if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec))
{
pickerSelector = mousePoint;
if (pickerSelector.x < bounds.x) pickerSelector.x = bounds.x;
if (pickerSelector.x > bounds.x + bounds.width) pickerSelector.x = bounds.x + bounds.width;
if (pickerSelector.y < bounds.y) pickerSelector.y = bounds.y;
if (pickerSelector.y > bounds.y + bounds.height) pickerSelector.y = bounds.y + bounds.height;
// Calculate color from picker
Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y };
colorPick.x /= (float)bounds.width; // Get normalized value on x
colorPick.y /= (float)bounds.height; // Get normalized value on y
colorHsv->y = colorPick.x;
colorHsv->z = 1.0f - colorPick.y;
}
}
else
{
guiControlExclusiveMode = false;
guiControlExclusiveRec = 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;
guiControlExclusiveMode = true;
guiControlExclusiveRec = bounds;
pickerSelector = mousePoint; pickerSelector = mousePoint;
// Calculate color from picker // Calculate color from picker
@ -3734,9 +3760,9 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
int textWidth = GetTextWidth(message) + 2; int textWidth = GetTextWidth(message) + 2;
Rectangle textBounds = { 0 }; Rectangle textBounds = { 0 };
textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; textBounds.x = bounds.x + bounds.width/2 - textWidth/2;
textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + RAYGUI_MESSAGEBOX_BUTTON_PADDING; textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
textBounds.width = bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*2; textBounds.width = (float)textWidth;
textBounds.height = bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 3*RAYGUI_MESSAGEBOX_BUTTON_PADDING - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; textBounds.height = bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 3*RAYGUI_MESSAGEBOX_BUTTON_PADDING - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT;
// Draw control // Draw control
@ -3879,7 +3905,7 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
if (CheckCollisionPointRec(mousePoint, bounds)) if (CheckCollisionPointRec(mousePoint, bounds))
{ {
@ -3928,6 +3954,7 @@ void GuiDisableTooltip(void) { guiTooltip = false; }
// Set tooltip string // Set tooltip string
void GuiSetTooltip(const char *tooltip) { guiTooltipPtr = tooltip; } void GuiSetTooltip(const char *tooltip) { guiTooltipPtr = tooltip; }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Styles loading functions // Styles loading functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -3940,7 +3967,6 @@ void GuiLoadStyle(const char *fileName)
#define MAX_LINE_BUFFER_SIZE 256 #define MAX_LINE_BUFFER_SIZE 256
bool tryBinary = false; bool tryBinary = false;
if (!guiStyleLoaded) GuiLoadStyleDefault();
// Try reading the files as text file first // Try reading the files as text file first
FILE *rgsFile = fopen(fileName, "rt"); FILE *rgsFile = fopen(fileName, "rt");
@ -4747,7 +4773,6 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
// Get text position depending on alignment and iconId // Get text position depending on alignment and iconId
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
Vector2 textBoundsPosition = { textBounds.x, textBounds.y }; Vector2 textBoundsPosition = { textBounds.x, textBounds.y };
float textBoundsWidthOffset = 0.0f;
// NOTE: 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?
@ -4773,8 +4798,6 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
default: break; default: break;
} }
if (textSizeX > textBounds.width && (lines[i] != NULL) && (lines[i][0] != '\0')) textBoundsPosition.x = textBounds.x;
switch (alignmentVertical) switch (alignmentVertical)
{ {
// Only valid in case of wordWrap = 0; // Only valid in case of wordWrap = 0;
@ -4797,8 +4820,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
{ {
// NOTE: We consider icon height, probably different than text size // NOTE: We consider icon height, probably different than text size
GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint); GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint);
textBoundsPosition.x += (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); textBoundsPosition.x += (RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING);
textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING);
} }
#endif #endif
// Get size in bytes of text, // Get size in bytes of text,
@ -4807,15 +4829,9 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
for (int c = 0; (lines[i][c] != '\0') && (lines[i][c] != '\n') && (lines[i][c] != '\r'); c++, lineSize++){ } for (int c = 0; (lines[i][c] != '\0') && (lines[i][c] != '\n') && (lines[i][c] != '\r'); c++, lineSize++){ }
float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize; float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize;
int lastSpaceIndex = 0;
bool tempWrapCharMode = false;
int textOffsetY = 0; int textOffsetY = 0;
float textOffsetX = 0.0f; float textOffsetX = 0.0f;
float glyphWidth = 0; float glyphWidth = 0;
int ellipsisWidth = GetTextWidth("...");
bool overflowReached = false;
for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize) for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize)
{ {
int codepoint = GetCodepointNext(&lines[i][c], &codepointSize); int codepoint = GetCodepointNext(&lines[i][c], &codepointSize);
@ -4825,49 +4841,34 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
// but we need to draw all of the bad bytes using the '?' symbol moving one byte // but we need to draw all of the bad bytes using the '?' symbol moving one byte
if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size
// Wrap mode text measuring to space to validate if it can be drawn or
// a new line is required
if (wrapMode == TEXT_WRAP_CHAR)
{
// Get glyph width to check if it goes out of bounds // Get glyph width to check if it goes out of bounds
if (guiFont.glyphs[index].advanceX == 0) glyphWidth = ((float)guiFont.recs[index].width*scaleFactor); if (guiFont.glyphs[index].advanceX == 0) glyphWidth = ((float)guiFont.recs[index].width*scaleFactor);
else glyphWidth = (float)guiFont.glyphs[index].advanceX*scaleFactor; else glyphWidth = (float)guiFont.glyphs[index].advanceX*scaleFactor;
// Wrap mode text measuring, to validate if
// it can be drawn or a new line is required
if (wrapMode == TEXT_WRAP_CHAR)
{
// Jump to next line if current character reach end of the box limits // Jump to next line if current character reach end of the box limits
if ((textOffsetX + glyphWidth) > textBounds.width - textBoundsWidthOffset) if ((textOffsetX + glyphWidth) > textBounds.width)
{ {
textOffsetX = 0.0f; textOffsetX = 0.0f;
textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING);
if (tempWrapCharMode) // Wrap at char level when too long words
{
wrapMode = TEXT_WRAP_WORD;
tempWrapCharMode = false;
}
} }
} }
else if (wrapMode == TEXT_WRAP_WORD) else if (wrapMode == TEXT_WRAP_WORD)
{ {
if (codepoint == 32) lastSpaceIndex = c;
// Get width to next space in line // Get width to next space in line
int nextSpaceIndex = 0; int nextSpaceIndex = 0;
float nextSpaceWidth = GetNextSpaceWidth(lines[i] + c, &nextSpaceIndex); float nextSpaceWidth = GetNextSpaceWidth(lines[i] + c, &nextSpaceIndex);
int nextSpaceIndex2 = 0; if ((textOffsetX + nextSpaceWidth) > textBounds.width)
float nextWordSize = GetNextSpaceWidth(lines[i] + lastSpaceIndex + 1, &nextSpaceIndex2);
if (nextWordSize > textBounds.width - textBoundsWidthOffset)
{
// Considering the case the next word is longer than bounds
tempWrapCharMode = true;
wrapMode = TEXT_WRAP_CHAR;
}
else if ((textOffsetX + nextSpaceWidth) > textBounds.width - textBoundsWidthOffset)
{ {
textOffsetX = 0.0f; textOffsetX = 0.0f;
textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING);
} }
// TODO: Consider case: (nextSpaceWidth >= textBounds.width)
} }
if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint
@ -4880,23 +4881,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
if (wrapMode == TEXT_WRAP_NONE) if (wrapMode == TEXT_WRAP_NONE)
{ {
// Draw only required text glyphs fitting the textBounds.width // Draw only required text glyphs fitting the textBounds.width
if (textSizeX > textBounds.width) if (textOffsetX <= (textBounds.width - glyphWidth))
{
if (textOffsetX <= (textBounds.width - glyphWidth - textBoundsWidthOffset - ellipsisWidth))
{
DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
}
else if (!overflowReached)
{
overflowReached = true;
for (int j = 0; j < ellipsisWidth; j += ellipsisWidth/3)
{
DrawTextCodepoint(guiFont, '.', RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX + j, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
}
}
}
else
{ {
DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
} }
@ -4952,7 +4937,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) && !guiControlExclusiveMode) if (!guiLocked && guiTooltip && (guiTooltipPtr != NULL) && !guiSliderDragging)
{ {
Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
@ -5018,7 +5003,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
buffer[i] = '\0'; // Set an end of string at this point buffer[i] = '\0'; // Set an end of string at this point
counter++; counter++;
if (counter > RAYGUI_TEXTSPLIT_MAX_ITEMS) break; if (counter == RAYGUI_TEXTSPLIT_MAX_ITEMS) break;
} }
} }
@ -5178,11 +5163,8 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
if (value > maxValue) value = maxValue; if (value > maxValue) value = maxValue;
if (value < minValue) value = minValue; if (value < minValue) value = minValue;
int valueRange = maxValue - minValue; const int valueRange = maxValue - minValue;
if (valueRange <= 0) valueRange = 1;
int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);
if (sliderSize < 1) sliderSize = 1; // TODO: Consider a minimum slider size
// Calculate rectangles for all of the components // Calculate rectangles for all of the components
arrowUpLeft = RAYGUI_CLITERAL(Rectangle){ arrowUpLeft = RAYGUI_CLITERAL(Rectangle){
@ -5223,13 +5205,13 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds if (guiSliderDragging) // Keep dragging outside of bounds
{ {
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) &&
!CheckCollisionPointRec(mousePoint, arrowUpLeft) && !CheckCollisionPointRec(mousePoint, arrowUpLeft) &&
!CheckCollisionPointRec(mousePoint, arrowDownRight)) !CheckCollisionPointRec(mousePoint, arrowDownRight))
{ {
if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) if (CHECK_BOUNDS_ID(bounds, guiSliderActive))
{ {
state = STATE_PRESSED; state = STATE_PRESSED;
@ -5239,8 +5221,8 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
} }
else else
{ {
guiControlExclusiveMode = false; guiSliderDragging = false;
guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
} }
} }
else if (CheckCollisionPointRec(mousePoint, bounds)) else if (CheckCollisionPointRec(mousePoint, bounds))
@ -5254,8 +5236,8 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
// Handle mouse button down // Handle mouse button down
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
{ {
guiControlExclusiveMode = true; guiSliderDragging = true;
guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts guiSliderActive = bounds; // Store bounds as an identifier when dragging starts
// Check arrows click // Check arrows click
if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
@ -5533,6 +5515,7 @@ static int GetCodepointNext(const char *text, int *codepointSize)
*codepointSize = 1; *codepointSize = 1;
} }
return codepoint; return codepoint;
} }
#endif // RAYGUI_STANDALONE #endif // RAYGUI_STANDALONE

View File

@ -7,8 +7,15 @@
#include "shaders.h" #include "shaders.h"
#define DEMO_VIDEO_FEATURES 0 #define DEMO_VIDEO_FEATURES 0
#ifdef _MSC_VER
#define MIN __min
#else
#define MIN(x,y) ({ \
__typeof(x) xv = (x);\
__typeof(y) yv = (y); \
xv < yv ? xv : yv;\
})
#endif
#ifdef PLATFORM_WEB #ifdef PLATFORM_WEB
#include <emscripten.h> #include <emscripten.h>
#endif #endif
@ -200,7 +207,7 @@ Vector3 NearestPointOnLine(Vector3 p1,
float numer,denom; float numer,denom;
const float EPS = 0.001; const float EPS = 0.001;
Vector3 zeroV;
p13.x = p1.x - p3.x; p13.x = p1.x - p3.x;
p13.y = p1.y - p3.y; p13.y = p1.y - p3.y;
@ -209,12 +216,12 @@ Vector3 NearestPointOnLine(Vector3 p1,
p43.y = p4.y - p3.y; p43.y = p4.y - p3.y;
p43.z = p4.z - p3.z; p43.z = p4.z - p3.z;
if (fabs(p43.x) < EPS && fabs(p43.y) < EPS && fabs(p43.z) < EPS) if (fabs(p43.x) < EPS && fabs(p43.y) < EPS && fabs(p43.z) < EPS)
return zeroV; return (Vector3) { 0 };
p21.x = p2.x - p1.x; p21.x = p2.x - p1.x;
p21.y = p2.y - p1.y; p21.y = p2.y - p1.y;
p21.z = p2.z - p1.z; p21.z = p2.z - p1.z;
if (fabs(p21.x) < EPS && fabs(p21.y) < EPS && fabs(p21.z) < EPS) if (fabs(p21.x) < EPS && fabs(p21.y) < EPS && fabs(p21.z) < EPS)
return zeroV; return (Vector3) { 0 };
d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z; d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z;
d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z; d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z;
@ -224,7 +231,7 @@ Vector3 NearestPointOnLine(Vector3 p1,
denom = d2121 * d4343 - d4321 * d4321; denom = d2121 * d4343 - d4321 * d4321;
if (fabs(denom) < EPS) if (fabs(denom) < EPS)
return zeroV; return (Vector3) { 0 };
numer = d1343 * d4321 - d1321 * d4343; numer = d1343 * d4321 - d1321 * d4343;
mua = numer / denom; mua = numer / denom;
@ -280,7 +287,7 @@ int GuiFloatValueBox(Rectangle bounds, const char *text, float *value, float min
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked) if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
{ {
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
@ -591,7 +598,6 @@ void add_shape(void) {
#ifdef _MSC_VER #ifdef _MSC_VER
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
void append_format(char** data, int* size, int* capacity, _Printf_format_string_ const char* format, ...) { void append_format(char** data, int* size, int* capacity, _Printf_format_string_ const char* format, ...) {
@ -605,11 +611,7 @@ void append_format(char** data, int* size, int* capacity, _Printf_format_string_
va_end(arg_ptr); va_end(arg_ptr);
} }
#else #else
#define MIN(x,y) ({ \
__typeof(x) xv = (x);\
__typeof(y) yv = (y); \
xv < yv ? xv : yv;\
})
__attribute__((format(printf, 4, 5))) __attribute__((format(printf, 4, 5)))
void append_format(char **data, int *size, int *capacity, const char *format, ...) { void append_format(char **data, int *size, int *capacity, const char *format, ...) {
@ -1514,7 +1516,7 @@ int main(void){
#endif #endif
UpdateCameraPro(&camera, (Vector3){0, -delta.x/10, 0}, Vector3Zero(), 0); UpdateCameraPro(&camera, (Vector3){0, -delta.x/10, 0}, Vector3Zero(), 0);
} }
} else if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && mouseAction == CONTROL_NONE && Vector2Distance(mouseDownPosition, GetMousePosition()) > 1) { } else if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && !guiSliderDragging && mouseAction == CONTROL_NONE && Vector2Distance(mouseDownPosition, GetMousePosition()) > 1) {
mouseAction = CONTROL_ROTATE_CAMERA; mouseAction = CONTROL_ROTATE_CAMERA;
} }
@ -1915,7 +1917,7 @@ int main(void){
BeginScissorMode((int)view_area.x, (int)view_area.y, (int)view_area.width, (int)view_area.height); { BeginScissorMode((int)view_area.x, (int)view_area.y, (int)view_area.width, (int)view_area.height); {
const int first_visible = (int)floorf(-scroll_offset.y / row_height); const int first_visible = (int)floorf(-scroll_offset.y / row_height);
const int last_visible = first_visible + (int)ceilf(view_area.height / row_height); const int last_visible = first_visible + (int)ceilf(view_area.height / row_height);
for (int i=first_visible; i < __min(last_visible+1,num_spheres); i++) { for (int i=first_visible; i < MIN(last_visible+1,num_spheres); i++) {
Sphere *s = &spheres[i]; Sphere *s = &spheres[i];
const char *text = TextFormat("%c Shape %i", s->subtract ? '-' : '+', i+1); const char *text = TextFormat("%c Shape %i", s->subtract ? '-' : '+', i+1);