diff third_party/raylib/include/raygui.h @ 112:d6d578b49a19

[PostDog] Got CRUD working.
author June Park <parkjune1995@gmail.com>
date Sun, 04 Jan 2026 11:38:44 -0800
parents 48f260576059
children e2a73e64e8e6
line wrap: on
line diff
--- a/third_party/raylib/include/raygui.h	Sun Jan 04 06:39:16 2026 -0800
+++ b/third_party/raylib/include/raygui.h	Sun Jan 04 11:38:44 2026 -0800
@@ -738,6 +738,7 @@
 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 void JUNE_DrawRectangleLinesNoBottom(Rectangle rect, float thickness, Color color);
 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 GuiCheckBox(Rectangle bounds, const char *text, bool *checked);                          // Check Box control, returns true when active
@@ -2093,7 +2094,31 @@
     //--------------------------------------------------------------------
     if (state == STATE_NORMAL)
     {
-        GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, ((*active)? BORDER_COLOR_PRESSED : (BORDER + state*3)))), GetColor(GuiGetStyle(TOGGLE, ((*active)? BASE_COLOR_PRESSED : (BASE + state*3)))));
+        if (*active)
+        {
+          Rectangle tmp = bounds;
+          tmp.height += GuiGetStyle(TOGGLE, BORDER_WIDTH); 
+          GuiDrawRectangle(
+              tmp, 
+              0, 
+              GetColor(GuiGetStyle(TOGGLE, ((*active)? BORDER_COLOR_PRESSED : (BORDER + state*3)))), 
+              GetColor(GuiGetStyle(TOGGLE, ((*active)? BASE_COLOR_PRESSED : (BASE + state*3))))
+          );
+          JUNE_DrawRectangleLinesNoBottom(
+              bounds, 
+              GuiGetStyle(TOGGLE, BORDER_WIDTH),
+              GetColor(GuiGetStyle(TOGGLE, BORDER_COLOR_PRESSED))
+          );
+        }
+        else
+        {
+          GuiDrawRectangle(
+              bounds, 
+              GuiGetStyle(TOGGLE, BORDER_WIDTH), 
+              GetColor(GuiGetStyle(TOGGLE, ((*active)? BORDER_COLOR_PRESSED : (BORDER + state*3)))), 
+              GetColor(GuiGetStyle(TOGGLE, ((*active)? BASE_COLOR_PRESSED : (BASE + state*3))))
+            );
+        }
         GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, ((*active)? TEXT_COLOR_PRESSED : (TEXT + state*3)))));
     }
     else
@@ -2102,7 +2127,9 @@
         GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, TEXT + state*3)));
     }
 
-    if (state == STATE_FOCUSED) GuiTooltip(bounds);
+    if (state == STATE_FOCUSED) {
+      GuiTooltip(bounds);
+    }
     //--------------------------------------------------------------------
 
     return result;
@@ -2923,7 +2950,6 @@
     return result;      // Mouse button pressed: result = 1
 }
 
-/*
 // 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)
@@ -2943,7 +2969,6 @@
 
     return pressed;
 }
-*/
 
 // Spinner control, returns selected value
 int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode)
@@ -6031,21 +6056,55 @@
     int result = 0;
     GuiState state = guiState;
 
-    bool multiline = true;
+    bool multiline = true; // TODO: Consider multiline text input
     int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE);
 
     Rectangle textBounds = GetTextBounds(TEXTBOX, bounds);
     int textLength = (text != NULL)? (int)strlen(text) : 0; // Get current text length
     int thisCursorIndex = textBoxCursorIndex;
     if (thisCursorIndex > textLength) thisCursorIndex = textLength;
-    int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex);
+
+    // Calculate cursor position for multiline
+    int cursorLine = 0;  // Current line number (0-based)
+    int lineStart = 0;   // Start index of current line
+
+    if (multiline)
+    {
+        for (int i = 0; i < thisCursorIndex; i++)
+        {
+            if (text[i] == '\n')
+            {
+                cursorLine++;
+                lineStart = i + 1;
+            }
+        }
+    }
+
+    // Calculate horizontal position within current line
+    char lineText[1024] = { 0 };
+    int lineTextLen = 0;
+    if (multiline)
+    {
+        // Extract current line text up to cursor
+        int i = lineStart;
+        while (i < thisCursorIndex && text[i] != '\n' && lineTextLen < 1023)
+        {
+            lineText[lineTextLen++] = text[i++];
+        }
+        lineText[lineTextLen] = '\0';
+    }
+
+    int textWidth = multiline ? GuiGetTextWidth(lineText) : (GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex));
     int textIndexOffset = 0; // Text index offset to start drawing in the box
 
+    // Line height for multiline (matches GuiDrawText line spacing)
+    int lineHeight = GuiGetStyle(DEFAULT, TEXT_SIZE);
+
     // Cursor rectangle
-    // NOTE: Position X value should be updated
+    // NOTE: Position X and Y values updated for multiline support
     Rectangle cursor = {
         textBounds.x + textWidth + GuiGetStyle(DEFAULT, TEXT_SPACING),
-        textBounds.y + GuiGetStyle(DEFAULT, TEXT_SIZE),
+        multiline ? (textBounds.y + cursorLine * lineHeight) : (textBounds.y + textBounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)),
         2,
         (float)GuiGetStyle(DEFAULT, TEXT_SIZE)
     };
@@ -6343,6 +6402,66 @@
                 textBoxCursorIndex += nextCodepointSize;
             }
 
+            // Vertical cursor movement for multiline
+            if (multiline && (IsKeyPressed(KEY_UP) || (IsKeyDown(KEY_UP) && autoCursorShouldTrigger)))
+            {
+                // Find start of current line
+                int currentLineStart = textBoxCursorIndex;
+                while (currentLineStart > 0 && text[currentLineStart - 1] != '\n') currentLineStart--;
+
+                // Calculate horizontal position in current line
+                int horizontalPos = textBoxCursorIndex - currentLineStart;
+
+                // Find start of previous line
+                if (currentLineStart > 0)
+                {
+                    int prevLineEnd = currentLineStart - 1; // Skip the newline
+                    int prevLineStart = prevLineEnd;
+                    while (prevLineStart > 0 && text[prevLineStart - 1] != '\n') prevLineStart--;
+
+                    // Move to same horizontal position on previous line (or end of line if shorter)
+                    int prevLineLength = prevLineEnd - prevLineStart;
+                    int targetPos = (horizontalPos < prevLineLength) ? horizontalPos : prevLineLength;
+                    textBoxCursorIndex = prevLineStart + targetPos;
+                }
+                else
+                {
+                    // Already on first line, move to start
+                    textBoxCursorIndex = 0;
+                }
+            }
+            else if (multiline && (IsKeyPressed(KEY_DOWN) || (IsKeyDown(KEY_DOWN) && autoCursorShouldTrigger)))
+            {
+                // Find start of current line
+                int currentLineStart = textBoxCursorIndex;
+                while (currentLineStart > 0 && text[currentLineStart - 1] != '\n') currentLineStart--;
+
+                // Calculate horizontal position in current line
+                int horizontalPos = textBoxCursorIndex - currentLineStart;
+
+                // Find end of current line
+                int currentLineEnd = textBoxCursorIndex;
+                while (currentLineEnd < textLength && text[currentLineEnd] != '\n') currentLineEnd++;
+
+                // Find next line
+                if (currentLineEnd < textLength)
+                {
+                    int nextLineStart = currentLineEnd + 1; // Skip the newline
+                    int nextLineEnd = nextLineStart;
+                    while (nextLineEnd < textLength && text[nextLineEnd] != '\n') nextLineEnd++;
+
+                    // Move to same horizontal position on next line (or end of line if shorter)
+                    int nextLineLength = nextLineEnd - nextLineStart;
+                    int targetPos = (horizontalPos < nextLineLength) ? horizontalPos : nextLineLength;
+                    textBoxCursorIndex = nextLineStart + targetPos;
+                }
+                else
+                {
+                    // Already on last line, move to end
+                    textBoxCursorIndex = textLength;
+                }
+            }
+
             // Move cursor position with mouse
             if (CheckCollisionPointRec(mousePosition, textBounds))     // Mouse hover text
             {
@@ -6364,6 +6483,24 @@
                     {
                         mouseCursor.x = textBounds.x + widthToMouseX;
                         mouseCursorIndex = i;
+                        printf("before: %i\n", mouseCursorIndex);
+                        break;
+                    }
+
+                    if (mousePosition.y >= textBounds.y  && mousePosition.y <= textBounds.height)
+                    {
+                        mouseCursor.y = mousePosition.y;
+                        mouseCursorIndex = i;
+                        int number_of_n = (int)(mousePosition.y / lineHeight);
+                        for (int i = 0; i < textSize; i++)
+                        {
+                            if (text[i] == '\n')
+                            {
+                                number_of_n--;
+                                if (number_of_n == 0)
+                                  mouseCursorIndex += i;
+                            }
+                        }
                         break;
                     }
 
@@ -6387,11 +6524,38 @@
             }
             else mouseCursor.x = -1;
 
-            // Recalculate cursor position.y depending on textBoxCursorIndex
-            cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING);
-            if (multiline) {
-              const char **lines = GetTextLines(text, &cursor.y);
-              printf("Cursor: %f", cursor.y);
+            // Recalculate cursor position for multiline
+            if (multiline)
+            {
+                // Recalculate cursor line and position
+                int newCursorLine = 0;
+                int newLineStart = 0;
+
+                for (int i = 0; i < textBoxCursorIndex; i++)
+                {
+                    if (text[i] == '\n')
+                    {
+                        newCursorLine++;
+                        newLineStart = i + 1;
+                    }
+                }
+
+                // Extract current line text up to cursor
+                char currentLineText[1024] = { 0 };
+                int currentLineLen = 0;
+                int i = newLineStart;
+                while (i < textBoxCursorIndex && text[i] != '\n' && currentLineLen < 1023)
+                {
+                    currentLineText[currentLineLen++] = text[i++];
+                }
+                currentLineText[currentLineLen] = '\0';
+
+                cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GuiGetTextWidth(currentLineText) + GuiGetStyle(DEFAULT, TEXT_SPACING);
+                cursor.y = textBounds.y + (newCursorLine * lineHeight * 1.5);
+            }
+            else
+            {
+                cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING);
             }
 
             // Finish text editing on ENTER or mouse click outside bounds
@@ -6432,18 +6596,15 @@
     }
     else GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), BLANK);
 
-
-
+    // Draw text considering index offset if required
+    // NOTE: Text index offset depends on cursor position
+    // Set vertical alignment to top for multiline
     int prevVerticalAlignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL);
     if (multiline) GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP);
 
-    // Draw text considering index offset if required
-    // NOTE: Text index offset depends on cursor position
-    GuiDrawText(
-        text + textIndexOffset,
-        textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))));
-
-    // RESET 
+    GuiDrawText(text + textIndexOffset, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))));
+
+    // Restore previous vertical alignment
     if (multiline) GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, prevVerticalAlignment);
 
     // Draw cursor
@@ -6453,7 +6614,7 @@
         GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)));
 
         // Draw mouse position cursor (if required)
-        if (mouseCursor.x >= 0) GuiDrawRectangle(mouseCursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)));
+        // if (mouseCursor.x >= 0) GuiDrawRectangle(mouseCursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)));
     }
     else if (state == STATE_FOCUSED) GuiTooltip(bounds);
     //--------------------------------------------------------------------
@@ -6461,5 +6622,15 @@
     return result;      // Mouse button pressed: result = 1
 }
 
+void JUNE_DrawRectangleLinesNoBottom(Rectangle rect, float thickness, Color color) {
+    Vector2 topLeft     = { rect.x, rect.y };
+    Vector2 topRight    = { rect.x + rect.width, rect.y };
+    Vector2 bottomLeft  = { rect.x, rect.y + rect.height };
+    Vector2 bottomRight = { rect.x + rect.width, rect.y + rect.height };
+
+    DrawLineEx(topLeft, topRight, thickness, color);
+    DrawLineEx(topLeft, bottomLeft, thickness, color);
+    DrawLineEx(topRight, bottomRight, thickness, color);
+}
 
 #endif      // RAYGUI_IMPLEMENTnk_command_bufferATION