Bläddra i källkod

Update shapes_pie_chart.c

Ray 2 månader sedan
förälder
incheckning
ffc405325f
1 ändrade filer med 111 tillägg och 127 borttagningar
  1. 111 127
      examples/shapes/shapes_pie_chart.c

+ 111 - 127
examples/shapes/shapes_pie_chart.c

@@ -22,6 +22,8 @@
 #define RAYGUI_IMPLEMENTATION
 #include "raygui.h"
 
+#define MAX_PIE_SLICES  10       // Max pie slices
+
 //------------------------------------------------------------------------------------
 // Program main entry point
 //------------------------------------------------------------------------------------
@@ -34,15 +36,14 @@ int main(void)
 
     InitWindow(screenWidth, screenHeight, "raylib [shapes] example - pie chart");
 
-    #define MAX_SLICES 10
     int sliceCount = 7;
     float donutInnerRadius = 25.0f;
-    float values[MAX_SLICES] = {300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f}; //initial slice values
-    char labels[MAX_SLICES][32];
-    bool editingLabel[MAX_SLICES] = {false};
+    float values[MAX_PIE_SLICES] = { 300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f }; // Initial slice values
+    char labels[MAX_PIE_SLICES][32] = { 0 };
+    bool editingLabel[MAX_PIE_SLICES] = { 0 };
 
-    for (int i = 0; i < MAX_SLICES; i++)
-        snprintf(labels[i], 32, "Slice %i", i + 1);
+    for (int i = 0; i < MAX_PIE_SLICES; i++)
+        snprintf(labels[i], 32, "Slice %02i", i + 1);
 
     bool showValues = true;
     bool showPercentages = false;
@@ -50,7 +51,32 @@ int main(void)
     int hoveredSlice = -1;
     Rectangle scrollPanelBounds = {0};
     Vector2 scrollContentOffset = {0};
-    Rectangle view = {0};
+    Rectangle view = { 0 };
+
+    // UI layout parameters
+    const int panelWidth = 270;
+    const int panelMargin = 5;
+
+    // UI Panel top-left anchor
+    const Vector2 panelPos = {
+        (float)screenWidth  - panelMargin - panelWidth,
+        (float)panelMargin
+    };
+
+    // UI Panel rectangle
+    const Rectangle panelRect = {
+        panelPos.x, panelPos.y,
+        (float)panelWidth,
+        (float)screenHeight - 2.0f*panelMargin 
+    };
+
+    // Pie chart geometry
+    const Rectangle canvas = { 0, 0, panelPos.x, (float)screenHeight };
+    const Vector2 center = { canvas.width/2.0f, canvas.height/2.0f};
+    const float radius = 205.0f;
+
+    // Total value for percentage calculations
+    float totalValue = 0.0f;
 
     SetTargetFPS(60);
     //--------------------------------------------------------------------------------------
@@ -60,32 +86,9 @@ int main(void)
     {
         // Update
         //----------------------------------------------------------------------------------
-        //UI layout parameters
-        const int panelWidth = 270;
-        const int panelMargin = 5;
-
-        // UI Panel top-left anchor
-        const Vector2 panelPos = {
-            (float)screenWidth  - panelMargin - panelWidth,
-            (float)panelMargin
-        };
-
-        // UI Panel rectangle
-        const Rectangle panelRect = {
-            panelPos.x, panelPos.y,
-            (float)panelWidth,
-            (float)screenHeight - 2.0f*panelMargin 
-        };
-
-        // Pie chart geometry
-        const Rectangle canvas = { 0, 0, panelPos.x, (float)screenHeight };
-        const Vector2 center = {canvas.width / 2.0f, canvas.height / 2.0f};
-        const float radius = 205.0f;
-
         // Calculate total value for percentage calculations
-        float totalValue = 0.0f;
-        for (int i = 0; i < sliceCount; i++)
-            totalValue += values[i];
+        totalValue = 0.0f;
+        for (int i = 0; i < sliceCount; i++) totalValue += values[i];
 
         // Check for mouse hover over slices
         hoveredSlice = -1; // Reset hovered slice
@@ -94,23 +97,24 @@ int main(void)
         {
             float dx = mousePos.x - center.x;
             float dy = mousePos.y - center.y;
-            float distance = sqrtf(dx * dx + dy * dy);
+            float distance = sqrtf(dx*dx + dy*dy);
 
             if (distance <= radius) // Inside the pie radius
             {
-                float angle = atan2f(dy, dx) * RAD2DEG;
-                if (angle < 0)
-                    angle += 360;
+                float angle = atan2f(dy, dx)*RAD2DEG;
+                if (angle < 0) angle += 360;
 
                 float currentAngle = 0.0f;
                 for (int i = 0; i < sliceCount; i++)
                 {
-                    float sweep = (totalValue > 0) ? (values[i] / totalValue) * 360.0f : 0.0f;
-                    if (angle >= currentAngle && angle < (currentAngle + sweep))
+                    float sweep = (totalValue > 0)? (values[i]/totalValue)*360.0f : 0.0f;
+                    
+                    if ((angle >= currentAngle) && (angle < (currentAngle + sweep)))
                     {
                         hoveredSlice = i;
                         break;
                     }
+                    
                     currentAngle += sweep;
                 }
             }
@@ -120,116 +124,96 @@ int main(void)
         // Draw
         //----------------------------------------------------------------------------------
         BeginDrawing();
-        ClearBackground(RAYWHITE);
+            ClearBackground(RAYWHITE);
 
-        // Draw the pie chart on the canvas
-        //------------------------------------------------------------------------------
-        float startAngle = 0.0f;
-        for (int i = 0; i < sliceCount; i++)
-        {
-            float sweepAngle = (totalValue > 0) ? (values[i] / totalValue) * 360.0f : 0.0f;
-            float midAngle = startAngle + sweepAngle / 2.0f; // Middle angle for label positioning
+            // Draw the pie chart on the canvas
+            float startAngle = 0.0f;
+            for (int i = 0; i < sliceCount; i++)
+            {
+                float sweepAngle = (totalValue > 0)? (values[i]/totalValue)*360.0f : 0.0f;
+                float midAngle = startAngle + sweepAngle/2.0f; // Middle angle for label positioning
 
-            Color color = ColorFromHSV((float)i / sliceCount * 360.0f, 0.75f, 0.9f);
-            float currentRadius = radius;
+                Color color = ColorFromHSV((float)i/sliceCount*360.0f, 0.75f, 0.9f);
+                float currentRadius = radius;
 
-            // Make the hovered slice pop out by adding 5 pixels to its radius
-            if (i == hoveredSlice)
-                currentRadius += 5.0f;
+                // Make the hovered slice pop out by adding 5 pixels to its radius
+                if (i == hoveredSlice) currentRadius += 20.0f;
 
-            // Draw the pie slice using raylib's DrawCircleSector function
-            DrawCircleSector(center, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
+                // Draw the pie slice using raylib's DrawCircleSector function
+                DrawCircleSector(center, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
 
-            // Draw the label for the current slice
-            if (values[i] > 0)
-            {
-                char labelText[64];
-                if (showValues && showPercentages)
-                    snprintf(labelText, 64, "%.1f (%.0f%%)", values[i], (values[i] / totalValue) * 100.0f);
-                else if (showValues)
-                    snprintf(labelText, 64, "%.1f", values[i]);
-                else if (showPercentages)
-                    snprintf(labelText, 64, "%.0f%%", (values[i] / totalValue) * 100.0f);
-                else
-                    labelText[0] = '\0';
-
-                Vector2 textSize = MeasureTextEx(GetFontDefault(), labelText, 18, 1);
-                float labelRadius = radius * 0.7f;
-                Vector2 labelPos = {
-                    center.x + cosf(midAngle * DEG2RAD) * labelRadius - textSize.x / 2,
-                    center.y + sinf(midAngle * DEG2RAD) * labelRadius - textSize.y / 2};
-                DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 18, WHITE);
-            }
+                // Draw the label for the current slice
+                if (values[i] > 0)
+                {
+                    char labelText[64] = { 0 };
+                    if (showValues && showPercentages) snprintf(labelText, 64, "%.1f (%.0f%%)", values[i], (values[i]/totalValue)*100.0f);
+                    else if (showValues) snprintf(labelText, 64, "%.1f", values[i]);
+                    else if (showPercentages) snprintf(labelText, 64, "%.0f%%", (values[i]/totalValue)*100.0f);
+                    else labelText[0] = '\0';
+
+                    Vector2 textSize = MeasureTextEx(GetFontDefault(), labelText, 20, 1);
+                    float labelRadius = radius*0.7f;
+                    Vector2 labelPos = { center.x + cosf(midAngle*DEG2RAD)*labelRadius - textSize.x/2.0f,
+                        center.y + sinf(midAngle*DEG2RAD)*labelRadius - textSize.y/2.0f };
+                    DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 20, WHITE);
+                }
 
-            if(showDonut)
-            {
                 // Draw inner circle to create donut effect
-                DrawCircle(center.x, center.y, donutInnerRadius, RAYWHITE);
-            }
-
-            startAngle += sweepAngle;
-        }
-        //------------------------------------------------------------------------------
-
-        // UI control panel
-        //------------------------------------------------------------------------------
-        DrawRectangleRec(panelRect, Fade(LIGHTGRAY, 0.5f));
-        DrawRectangleLinesEx(panelRect, 1.0f, GRAY);
+                // TODO: This is a hacky solution, better use DrawRing()
+                if (showDonut) DrawCircle(center.x, center.y, donutInnerRadius, RAYWHITE);
 
-        int currentY = (int)panelPos.y + 12; // Start a bit lower for margin
+                startAngle += sweepAngle;
+            }
 
-        GuiSpinner((Rectangle){ panelPos.x + 95, (float)currentY, 125, 25 }, "Slices ", &sliceCount, 1, MAX_SLICES, false);
-        currentY += 40;
+            // UI control panel
+            DrawRectangleRec(panelRect, Fade(LIGHTGRAY, 0.5f));
+            DrawRectangleLinesEx(panelRect, 1.0f, GRAY);
 
-        GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Values", &showValues);
-        currentY += 30;
+            GuiSpinner((Rectangle){ panelPos.x + 95, (float)panelPos.y + 12, 125, 25 }, "Slices ", &sliceCount, 1, MAX_PIE_SLICES, false);
+            GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 40, 20, 20 }, "Show Values", &showValues);
+            GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 70, 20, 20 }, "Show Percentages", &showPercentages);
+            GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 100, 20, 20 }, "Make Donut", &showDonut);
 
-        GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Percentages", &showPercentages);
-        currentY += 30;
+            if (showDonut) GuiDisable();
+            GuiSliderBar((Rectangle){ panelPos.x + 80, (float)panelPos.y + 12 + 130, panelRect.width - 100, 30 },
+                            "Inner Radius", NULL, &donutInnerRadius, 5.0f, radius - 10.0f);
+            GuiEnable();
 
-        GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Make Donut", &showDonut);
-        currentY += 30;
+            GuiLine((Rectangle){ panelPos.x + 10, (float)panelPos.y + 12 + 170, panelRect.width - 20, 1 }, NULL);
 
-        if(showDonut)
-        {
-            GuiSliderBar((Rectangle){ panelPos.x + 80, (float)currentY, panelRect.width - 100, 30 },
-                         "Inner Radius", NULL, &donutInnerRadius, 5.0f, radius - 10.0f);
-            currentY += 40;
-        }
+            // Scrollable area for slice editors
+            scrollPanelBounds = (Rectangle){ 
+                panelPos.x + panelMargin, 
+                (float)panelPos.y + 12 + 190, 
+                panelRect.width - panelMargin*2, 
+                panelRect.y + panelRect.height - panelPos.y + 12 + 190 - panelMargin 
+            };
+            int contentHeight = sliceCount*35;
 
-        GuiLine((Rectangle){ panelPos.x + 10, (float)currentY, panelRect.width - 20, 1 }, NULL);
-        currentY += 20;
+            GuiScrollPanel(scrollPanelBounds, NULL,
+                (Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
+                &scrollContentOffset, &view);
 
-        
+            const float contentX = view.x + scrollContentOffset.x; // Left of content
+            const float contentY = view.y + scrollContentOffset.y; // Top of content
 
-        // Scrollable area for slice editors
-        scrollPanelBounds = (Rectangle){ panelPos.x+panelMargin, (float)currentY, panelRect.width-panelMargin*2, panelRect.y + panelRect.height - currentY - panelMargin };
-        int contentHeight = sliceCount * 35;
+            BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height);
 
-        GuiScrollPanel(scrollPanelBounds, NULL,
-                       (Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
-                       &scrollContentOffset, &view);
-
-        const float contentX = view.x + scrollContentOffset.x; // left of content
-        const float contentY = view.y + scrollContentOffset.y; // top of content
+                for (int i = 0; i < sliceCount; i++)
+                {
+                    const int rowY = (int)(contentY + 5 + i*35);
 
-        BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height);
-        for (int i = 0; i < sliceCount; i++)
-        {
-            const int rowY = (int)(contentY + 5 + i * 35);
+                    // Color indicator
+                    Color color = ColorFromHSV((float)i/sliceCount*360.0f, 0.75f, 0.9f);
+                    DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
 
-            // Color indicator
-            Color color = ColorFromHSV((float)i / sliceCount * 360.0f, 0.75f, 0.9f);
-            DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
+                    // Label textbox
+                    if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, labels[i], 32, editingLabel[i])) editingLabel[i] = !editingLabel[i];
 
-            // Label textbox
-            if (GuiTextBox((Rectangle){contentX + 45, (float)rowY, 75, 30}, labels[i], 32, editingLabel[i]))
-                editingLabel[i] = !editingLabel[i];
+                    GuiSliderBar((Rectangle){ contentX + 130, (float)rowY, 110, 30 }, NULL, NULL, &values[i], 0.0f, 1000.0f);
+                }
 
-            GuiSliderBar((Rectangle){contentX + 130, (float)rowY, 110, 30},
-                         NULL, NULL, &values[i], 0.0f, 1000.0f);
-        }
-        EndScissorMode();
+            EndScissorMode();
 
         EndDrawing();
         //----------------------------------------------------------------------------------