diff --git a/lib/raylib-4.5.0_win64_msvc16/include/raygui.h b/lib/raylib-4.5.0_win64_msvc16/include/raygui.h index 98de9d8..623115f 100644 --- a/lib/raylib-4.5.0_win64_msvc16/include/raygui.h +++ b/lib/raylib-4.5.0_win64_msvc16/include/raygui.h @@ -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: * raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also @@ -26,7 +26,7 @@ * NOTES: * - WARNING: GuiLoadStyle() and GuiLoadStyle{Custom}() functions, allocate memory for * 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). * - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions * @@ -141,9 +141,6 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 4.1-dev (2024) Current dev version... -* ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes -* * 4.0 (12-Sep-2023) ADDED: GuiToggleSlider() * ADDED: GuiColorPickerHSV() and GuiColorPanelHSV() * ADDED: Multiple new icons, mostly compiler related @@ -317,9 +314,9 @@ #define RAYGUI_H #define RAYGUI_VERSION_MAJOR 4 -#define RAYGUI_VERSION_MINOR 1 +#define RAYGUI_VERSION_MINOR 0 #define RAYGUI_VERSION_PATCH 0 -#define RAYGUI_VERSION "4.1-dev" +#define RAYGUI_VERSION "4.0" #if !defined(RAYGUI_STANDALONE) #include "raylib.h" @@ -444,6 +441,7 @@ } Font; #endif + // Style property // NOTE: Used when exporting style as code for convenience 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 // should be configured by user as needed while defining the UI layout + // Gui extended properties depend on control // NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties) //---------------------------------------------------------------------------------- @@ -563,12 +562,12 @@ typedef enum { TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding) TEXT_WRAP_MODE // Text wrap-mode inside text bounds //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; // Other possible text properties: // TEXT_WEIGHT // Normal, Italic, Bold -> Requires specific font change -// TEXT_INDENT // Text indentation -> Now using TEXT_PADDING... +// TEXT_INDENT // Text indentation -> Now using TEXT_PADDING... // Label //typedef enum { } GuiLabelProperty; @@ -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 #endif + // Controls //---------------------------------------------------------------------------------------------------------- // 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 // 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 GuiLabelButton(Rectangle bounds, const char *text); // Label button control, returns true when clicked -RAYGUIAPI int GuiToggle(Rectangle bounds, const char *text, bool *active); // Toggle Button control -RAYGUIAPI int GuiToggleGroup(Rectangle bounds, const char *text, int *active); // Toggle Group control -RAYGUIAPI int GuiToggleSlider(Rectangle bounds, const char *text, int *active); // Toggle Slider control +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, returns true when active +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, returns true when clicked 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 GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner 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, 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 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 GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider Bar control -RAYGUIAPI int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Progress Bar 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, returns selected value +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 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 -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 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 @@ -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 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 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_CUSTOM_ICONS) @@ -971,9 +972,9 @@ typedef enum { ICON_FOLDER = 217, ICON_FILE = 218, ICON_SAND_TIMER = 219, - ICON_WARNING = 220, - ICON_HELP_BOX = 221, - ICON_INFO_BOX = 222, + ICON_220 = 220, + ICON_221 = 221, + ICON_222 = 222, ICON_223 = 223, ICON_224 = 224, 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 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE 0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER - 0x01800000, 0x02400240, 0x05a00420, 0x09900990, 0x11881188, 0x21842004, 0x40024182, 0x00003ffc, // ICON_WARNING - 0x7ffe0000, 0x4ff24002, 0x4c324ff2, 0x4f824c02, 0x41824f82, 0x41824002, 0x40024182, 0x00007ffe, // ICON_HELP_BOX - 0x7ffe0000, 0x41824002, 0x40024182, 0x41824182, 0x41824182, 0x41824182, 0x40024182, 0x00007ffe, // ICON_INFO_BOX + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_220 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_221 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_222 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_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 }; -// 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; #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 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 Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds rectangle, used as an unique identifier +static bool guiSliderDragging = false; // Gui slider drag state (no inputs processed except dragged slider) +static Rectangle guiSliderActive = { 0 }; // Gui slider active bounds rectangle, used as an unique identifier static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() //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; } - // 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_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_HEIGHT 40 - #define RAYGUI_MIN_MOUSE_WHEEL_SPEED 20 int result = 0; GuiState state = guiState; + float mouseWheelSpeed = 20.0f; // Default movement speed with mouse wheel Rectangle temp = { 0 }; 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 - if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH; - if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT; + // NOTE: If content >>> bounds, size could be very small or even 0 + 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) *view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? @@ -1866,14 +1873,9 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector #endif 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 - if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x; - else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll + if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed; + 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 - 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 GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider); @@ -1957,7 +1959,7 @@ int GuiButton(Rectangle bounds, const char *text) // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -1995,7 +1997,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -2018,7 +2020,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) return pressed; } -// Toggle Button control +// Toggle Button control, returns true when active int GuiToggle(Rectangle bounds, const char *text, bool *active) { int result = 0; @@ -2029,7 +2031,7 @@ int GuiToggle(Rectangle bounds, const char *text, bool *active) // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -2066,7 +2068,7 @@ int GuiToggle(Rectangle bounds, const char *text, bool *active) return result; } -// Toggle Group control +// Toggle Group control, returns toggled button codepointIndex int GuiToggleGroup(Rectangle bounds, const char *text, int *active) { #if !defined(RAYGUI_TOGGLEGROUP_MAX_ITEMS) @@ -2115,7 +2117,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active) return result; } -// Toggle Slider control extended +// Toggle Slider control extended, returns true when clicked int GuiToggleSlider(Rectangle bounds, const char *text, int *active) { int result = 0; @@ -2209,7 +2211,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -2254,7 +2256,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) return result; } -// Combo Box control +// Combo Box control, returns selected item codepointIndex int GuiComboBox(Rectangle bounds, const char *text, int *active) { int result = 0; @@ -2277,7 +2279,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -2339,7 +2341,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -2438,7 +2440,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Text Box control // 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) #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 !GuiGetStyle(TEXTBOX, TEXT_READONLY) && // TextBox not on read-only mode !guiLocked && // Gui not locked - !guiControlExclusiveMode && // No gui slider on dragging + !guiSliderDragging && // No gui slider on dragging (wrapMode == TEXT_WRAP_NONE)) // No wrap mode { 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 // 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 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 // 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; @@ -2734,7 +2736,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode) GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP); // 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_WRAP_MODE, TEXT_WRAP_NONE); @@ -2769,7 +2771,7 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -2844,7 +2846,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -2888,13 +2890,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in //if (*value > maxValue) *value = maxValue; //else if (*value < minValue) *value = minValue; - if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) - { - if (*value > maxValue) *value = maxValue; - else if (*value < minValue) *value = minValue; - - result = 1; - } + if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) result = 1; } 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 result = 0; + float oldValue = *value; GuiState state = guiState; float temp = (maxValue - minValue)/2.0f; 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), 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 //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { 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 (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + if (CHECK_BOUNDS_ID(bounds, guiSliderActive)) { state = STATE_PRESSED; + // 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 { - guiControlExclusiveMode = false; - guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + guiSliderDragging = false; + guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; } } else if (CheckCollisionPointRec(mousePoint, bounds)) @@ -2976,13 +2986,16 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { state = STATE_PRESSED; - guiControlExclusiveMode = true; - guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + guiSliderDragging = true; + guiSliderActive = bounds; // Store bounds as an identifier when dragging starts if (!CheckCollisionPointRec(mousePoint, slider)) { // 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; @@ -2993,22 +3006,17 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, } // Control value change check - if (oldValue == *value) result = 0; + if(oldValue == *value) result = 0; else result = 1; - // Slider bar limits check - int sliderValue = (int)(((*value - minValue)/(maxValue - minValue))*(bounds.width - sliderWidth - GuiGetStyle(SLIDER, BORDER_WIDTH))); + // Bar limits check 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); 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 { - slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH); - slider.width = (float)sliderValue; 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 //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -3230,7 +3238,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -3345,32 +3353,83 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd return result; } -// Color Panel control - Color (RGBA) variant. +// Color Panel control int GuiColorPanel(Rectangle bounds, const char *text, Color *color) { 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 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. - // This is necessary, because the Color->HSV->Color conversion has precision errors. - // Thus the assignment from HSV to Color should only be made, if the HSV has a new user-entered value. - // Otherwise GuiColorPanel would often modify it's color without user input. - // TODO: GuiColorPanelHSV could return 1 if the slider was dragged, to simplify this check. - if (hsv.x != prevHsv.x || hsv.y != prevHsv.y || hsv.z != prevHsv.z) + Vector3 maxHue = { 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 }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { - Vector3 rgb = ConvertHSVtoRGB(hsv); + Vector2 mousePoint = GetMousePosition(); - // NOTE: Vector3ToColor() only available on raylib 1.8.1 - *color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x), - (unsigned char)(255.0f*rgb.y), - (unsigned char)(255.0f*rgb.z), - color->a }; + 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); + + // NOTE: Vector3ToColor() only available on raylib 1.8.1 + *color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x), + (unsigned char)(255.0f*rgb.y), + (unsigned char)(255.0f*rgb.z), + (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; } @@ -3392,11 +3451,11 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) { 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 (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + if (CHECK_BOUNDS_ID(bounds, guiSliderActive)) { state = STATE_PRESSED; @@ -3407,8 +3466,8 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) } else { - guiControlExclusiveMode = false; - guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + guiSliderDragging = false; + guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; } } 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)) { state = STATE_PRESSED; - guiControlExclusiveMode = true; - guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + guiSliderDragging = true; + guiSliderActive = bounds; // Store bounds as an identifier when dragging starts *alpha = (mousePoint.x - bounds.x)/bounds.width; if (*alpha <= 0.0f) *alpha = 0.0f; @@ -3478,11 +3537,11 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) { 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 (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + if (CHECK_BOUNDS_ID(bounds, guiSliderActive)) { state = STATE_PRESSED; @@ -3493,8 +3552,8 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) } else { - guiControlExclusiveMode = false; - guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + guiSliderDragging = false; + guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; } } 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)) { state = STATE_PRESSED; - guiControlExclusiveMode = true; - guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + guiSliderDragging = true; + guiSliderActive = bounds; // Store bounds as an identifier when dragging starts *hue = (mousePoint.y - bounds.y)*360/bounds.height; 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 GuiColorBarHue(Rectangle bounds, float value) // 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 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 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 }); GuiColorBarHue(boundsHue, NULL, &hsv.x); @@ -3611,7 +3668,8 @@ int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) 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 result = 0; @@ -3632,47 +3690,15 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); - if (guiControlExclusiveMode) // Allows to keep dragging outside of 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 (CheckCollisionPointRec(mousePoint, bounds)) { if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { state = STATE_PRESSED; - guiControlExclusiveMode = true; - guiControlExclusiveRec = bounds; pickerSelector = mousePoint; // Calculate color from picker @@ -3734,9 +3760,9 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons int textWidth = GetTextWidth(message) + 2; 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.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; // Draw control @@ -3879,7 +3905,7 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { if (CheckCollisionPointRec(mousePoint, bounds)) { @@ -3928,6 +3954,7 @@ void GuiDisableTooltip(void) { guiTooltip = false; } // Set tooltip string void GuiSetTooltip(const char *tooltip) { guiTooltipPtr = tooltip; } + //---------------------------------------------------------------------------------- // Styles loading functions //---------------------------------------------------------------------------------- @@ -3940,7 +3967,6 @@ void GuiLoadStyle(const char *fileName) #define MAX_LINE_BUFFER_SIZE 256 bool tryBinary = false; - if (!guiStyleLoaded) GuiLoadStyleDefault(); // Try reading the files as text file first 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 //--------------------------------------------------------------------------------- Vector2 textBoundsPosition = { textBounds.x, textBounds.y }; - float textBoundsWidthOffset = 0.0f; // NOTE: We get text size after icon has been processed // 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; } - if (textSizeX > textBounds.width && (lines[i] != NULL) && (lines[i][0] != '\0')) textBoundsPosition.x = textBounds.x; - switch (alignmentVertical) { // 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 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); - textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); + textBoundsPosition.x += (RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); } #endif // 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++){ } float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize; - int lastSpaceIndex = 0; - bool tempWrapCharMode = false; - int textOffsetY = 0; float textOffsetX = 0.0f; float glyphWidth = 0; - - int ellipsisWidth = GetTextWidth("..."); - bool overflowReached = false; for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize) { int codepoint = GetCodepointNext(&lines[i][c], &codepointSize); @@ -4823,51 +4839,36 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) // 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 - // Get glyph width to check if it goes out of bounds - if (guiFont.glyphs[index].advanceX == 0) glyphWidth = ((float)guiFont.recs[index].width*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 + // 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 + if (guiFont.glyphs[index].advanceX == 0) glyphWidth = ((float)guiFont.recs[index].width*scaleFactor); + else glyphWidth = (float)guiFont.glyphs[index].advanceX*scaleFactor; + // 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; 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) { - if (codepoint == 32) lastSpaceIndex = c; - // Get width to next space in line int nextSpaceIndex = 0; float nextSpaceWidth = GetNextSpaceWidth(lines[i] + c, &nextSpaceIndex); - int nextSpaceIndex2 = 0; - 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) + if ((textOffsetX + nextSpaceWidth) > textBounds.width) { textOffsetX = 0.0f; 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 @@ -4880,23 +4881,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C if (wrapMode == TEXT_WRAP_NONE) { // Draw only required text glyphs fitting the textBounds.width - if (textSizeX > textBounds.width) - { - 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 + if (textOffsetX <= (textBounds.width - glyphWidth)) { 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 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)); @@ -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 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 < minValue) value = minValue; - int valueRange = maxValue - minValue; - if (valueRange <= 0) valueRange = 1; - + const int valueRange = maxValue - minValue; 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 arrowUpLeft = RAYGUI_CLITERAL(Rectangle){ @@ -5223,13 +5205,13 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) { Vector2 mousePoint = GetMousePosition(); - if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + if (guiSliderDragging) // Keep dragging outside of bounds { if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && !CheckCollisionPointRec(mousePoint, arrowUpLeft) && !CheckCollisionPointRec(mousePoint, arrowDownRight)) { - if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + if (CHECK_BOUNDS_ID(bounds, guiSliderActive)) { state = STATE_PRESSED; @@ -5239,8 +5221,8 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) } else { - guiControlExclusiveMode = false; - guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + guiSliderDragging = false; + guiSliderActive = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; } } else if (CheckCollisionPointRec(mousePoint, bounds)) @@ -5254,8 +5236,8 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) // Handle mouse button down if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { - guiControlExclusiveMode = true; - guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + guiSliderDragging = true; + guiSliderActive = bounds; // Store bounds as an identifier when dragging starts // Check arrows click if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); @@ -5508,21 +5490,21 @@ static int GetCodepointNext(const char *text, int *codepointSize) if (0xf0 == (0xf8 & ptr[0])) { // 4 byte UTF-8 codepoint - if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]); *codepointSize = 4; } else if (0xe0 == (0xf0 & ptr[0])) { // 3 byte UTF-8 codepoint */ - if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]); *codepointSize = 3; } else if (0xc0 == (0xe0 & ptr[0])) { // 2 byte UTF-8 codepoint - if ((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks + if((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]); *codepointSize = 2; } @@ -5533,6 +5515,7 @@ static int GetCodepointNext(const char *text, int *codepointSize) *codepointSize = 1; } + return codepoint; } #endif // RAYGUI_STANDALONE diff --git a/src/main.c b/src/main.c index 996d3d1..ecbdf6e 100644 --- a/src/main.c +++ b/src/main.c @@ -7,8 +7,15 @@ #include "shaders.h" #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 #include #endif @@ -200,7 +207,7 @@ Vector3 NearestPointOnLine(Vector3 p1, float numer,denom; const float EPS = 0.001; - Vector3 zeroV; + p13.x = p1.x - p3.x; p13.y = p1.y - p3.y; @@ -209,12 +216,12 @@ Vector3 NearestPointOnLine(Vector3 p1, p43.y = p4.y - p3.y; p43.z = p4.z - p3.z; 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.y = p2.y - p1.y; p21.z = p2.z - p1.z; 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; 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; if (fabs(denom) < EPS) - return zeroV; + return (Vector3) { 0 }; numer = d1343 * d4321 - d1321 * d4343; mua = numer / denom; @@ -280,7 +287,7 @@ int GuiFloatValueBox(Rectangle bounds, const char *text, float *value, float min // Update control //-------------------------------------------------------------------- - if ((state != STATE_DISABLED) && !guiLocked) + if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) { Vector2 mousePoint = GetMousePosition(); @@ -591,7 +598,6 @@ void add_shape(void) { #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, ...) { @@ -605,11 +611,7 @@ void append_format(char** data, int* size, int* capacity, _Printf_format_string_ va_end(arg_ptr); } #else -#define MIN(x,y) ({ \ - __typeof(x) xv = (x);\ - __typeof(y) yv = (y); \ - xv < yv ? xv : yv;\ - }) + __attribute__((format(printf, 4, 5))) void append_format(char **data, int *size, int *capacity, const char *format, ...) { @@ -1500,7 +1502,7 @@ int main(void){ static Vector2 mouseDownPosition; if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) mouseDownPosition = GetMousePosition(); - if (fabsf(GetMouseWheelMove()) > 0.01 && mouseAction == CONTROL_NONE ) { + if (fabsf(GetMouseWheelMove()) > 0.01 && !guiSliderDragging && mouseAction == CONTROL_NONE ) { Vector2 delta = GetMouseWheelMoveV(); if (IsKeyDown(KEY_LEFT_ALT)) { @@ -1915,7 +1917,7 @@ int main(void){ 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 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]; const char *text = TextFormat("%c Shape %i", s->subtract ? '-' : '+', i+1);