From b038cc94de1da24602d3bb7df0f866f8a7c8da7c Mon Sep 17 00:00:00 2001 From: Timothy Schoen Date: Sun, 16 Feb 2025 00:10:07 +0100 Subject: [PATCH] Nicer looking spinner --- Source/Dialogs/Deken.h | 2 +- Source/Heavy/ExportingProgressView.h | 4 ++-- Source/Heavy/Toolchain.h | 2 +- Source/LookAndFeel.cpp | 32 ++++++++++++++++++++++++++++ Source/LookAndFeel.h | 2 ++ 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Source/Dialogs/Deken.h b/Source/Dialogs/Deken.h index 13b03c766..eefbee869 100644 --- a/Source/Dialogs/Deken.h +++ b/Source/Dialogs/Deken.h @@ -802,7 +802,7 @@ class Deken final : public Component ListBox listBox; BouncingViewport viewport; std::unique_ptr headerWarning; - int const headerHeight = 40; + int const headerHeight = ProjectInfo::isStandalone ? 0 : 40; }; // List component to list packages diff --git a/Source/Heavy/ExportingProgressView.h b/Source/Heavy/ExportingProgressView.h index 5e92c05da..7e5f6e90a 100644 --- a/Source/Heavy/ExportingProgressView.h +++ b/Source/Heavy/ExportingProgressView.h @@ -149,11 +149,11 @@ class ExportingProgressView final : public Component if (state == Exporting) { Fonts::drawStyledText(g, "Exporting...", 0, 25, getWidth(), 40, findColour(PlugDataColour::panelTextColourId), Bold, 32, Justification::centred); - getLookAndFeel().drawSpinningWaitAnimation(g, findColour(PlugDataColour::panelTextColourId), getWidth() / 2 - 16, getHeight() / 2 + 135, 32, 32); + getLookAndFeel().drawSpinningWaitAnimation(g, findColour(PlugDataColour::panelTextColourId), getWidth() / 2 - 16, getHeight() / 2 + 118, 32, 32); } else if (state == Flashing) { Fonts::drawStyledText(g, "Flashing...", 0, 25, getWidth(), 40, findColour(PlugDataColour::panelTextColourId), Bold, 32, Justification::centred); - getLookAndFeel().drawSpinningWaitAnimation(g, findColour(PlugDataColour::panelTextColourId), getWidth() / 2 - 16, getHeight() / 2 + 135, 32, 32); + getLookAndFeel().drawSpinningWaitAnimation(g, findColour(PlugDataColour::panelTextColourId), getWidth() / 2 - 16, getHeight() / 2 + 118, 32, 32); } else if (state == Success) { Fonts::drawStyledText(g, "Export successful", 0, 25, getWidth(), 40, findColour(PlugDataColour::panelTextColourId), Bold, 32, Justification::centred); diff --git a/Source/Heavy/Toolchain.h b/Source/Heavy/Toolchain.h index 20144333e..446917032 100644 --- a/Source/Heavy/Toolchain.h +++ b/Source/Heavy/Toolchain.h @@ -202,7 +202,7 @@ class ToolchainInstaller final : public Component } if (isTimerRunning()) { - getLookAndFeel().drawSpinningWaitAnimation(g, findColour(PlugDataColour::panelTextColourId), getWidth() / 2 - 16, getHeight() / 2 + 135, 32, 32); + getLookAndFeel().drawSpinningWaitAnimation(g, findColour(PlugDataColour::panelTextColourId), getWidth() / 2 - 16, getHeight() / 2 + 118, 32, 32); } } diff --git a/Source/LookAndFeel.cpp b/Source/LookAndFeel.cpp index 98bacafd9..62ee30966 100644 --- a/Source/LookAndFeel.cpp +++ b/Source/LookAndFeel.cpp @@ -542,6 +542,38 @@ void PlugDataLook::drawTextEditorOutline(Graphics& g, int const width, int const } } +void PlugDataLook::drawSpinningWaitAnimation(Graphics& g, const Colour& colour, int x, int y, int w, int h) +{ + const float radius = (float) jmin(w, h) * 0.4f; + const float thickness = radius * 0.3f; + const float cx = (float)x + (float)w * 0.5f; + const float cy = (float)y + (float)h * 0.5f; + + // Compute animation progress + const double animationTime = Time::getMillisecondCounterHiRes() / 1000.0; + const double progress = fmod(animationTime, 2.0); // Loops every 2 seconds + + // Adwaita-style arc calculation + const float minArcLength = MathConstants::pi * 0.2f; // Shortest segment + const float maxArcLength = MathConstants::pi * 0.8f; // Longest segment + const float startAngle = MathConstants::twoPi * progress; // Rotating angle + const float t = (sinf(progress * MathConstants::pi) + 1.0f) / 2.0f; // Smooth curve + const float arcLength = minArcLength + t * (maxArcLength - minArcLength); + const float endAngle = startAngle + arcLength; + + // Draw background circle + g.setColour(colour.withAlpha(0.1f)); + g.drawEllipse(cx - radius, cy - radius, radius * 2.0f, radius * 2.0f, thickness); + + Path p; + p.addCentredArc(cx, cy, radius, radius, 0.0f, startAngle, endAngle, true); + + // Draw moving arc + g.setColour(colour); + g.strokePath(p, PathStrokeType(thickness, PathStrokeType::curved, PathStrokeType::rounded)); + +} + void PlugDataLook::drawCornerResizer(Graphics& g, int const w, int const h, bool const isMouseOver, bool isMouseDragging) { Path triangle; diff --git a/Source/LookAndFeel.h b/Source/LookAndFeel.h index 58f1c50ee..771aa7521 100644 --- a/Source/LookAndFeel.h +++ b/Source/LookAndFeel.h @@ -130,6 +130,8 @@ struct PlugDataLook final : public LookAndFeel_V4 { void drawTextEditorOutline(Graphics& g, int width, int height, TextEditor& textEditor) override; + void drawSpinningWaitAnimation(Graphics& g, const Colour& colour, int x, int y, int w, int h) override; + void drawCornerResizer(Graphics& g, int w, int h, bool isMouseOver, bool isMouseDragging) override; void drawLasso(Graphics& g, Component& lassoComp) override;