CircularIndicatorWidget displays circular progress indicators with customizable arc direction, thickness, and appearance.
Basic Usage
#include <fern/fern.hpp>
using namespace Fern;
auto indicator = CircularIndicator(CircularIndicatorConfig(100, 100, 50)
.value(75.0f)
.range(0.0f, 100.0f));
indicator->onValueChanged.connect([](float value) {
std::cout << "Progress: " << value << "%" << std::endl;
});
Constructor
Configuration object containing position, radius, value range, and style
CircularIndicatorConfig
Configure circular indicator properties:
CircularIndicatorConfig(int x, int y, int radius = 50)
Configuration Methods
CircularIndicatorConfig& range(float minValue, float maxValue) // Set value range
CircularIndicatorConfig& value(float value) // Set current value
CircularIndicatorConfig& radius(int r) // Set radius
CircularIndicatorConfig& style(const CircularIndicatorStyle& s) // Set style
CircularIndicatorStyle
Customize circular indicator appearance:
Color Methods
CircularIndicatorStyle& backgroundColor(uint32_t color) // Background arc color
CircularIndicatorStyle& fillColor(uint32_t color) // Progress arc color
CircularIndicatorStyle& borderColor(uint32_t color) // Border color
CircularIndicatorStyle& textColor(uint32_t color) // Percentage text color
Arc Configuration
CircularIndicatorStyle& thickness(int thick) // Arc thickness in pixels
CircularIndicatorStyle& clockwise(bool cw) // Direction of progress
CircularIndicatorStyle& startAngle(float angle) // Starting angle in degrees
Display Methods
CircularIndicatorStyle& borderWidth(int width)
CircularIndicatorStyle& showPercentage(bool show) // Show percentage text
CircularIndicatorStyle& fontSize(int size)
CircularIndicatorStyle& useBitmapFont()
CircularIndicatorStyle& useTTFFont(const std::string& fontName)
Signals
Emitted when the progress value changes
Emitted when progress reaches 100%
Methods
Value Management
void setValue(float value)
float getValue() const
void setRange(float minValue, float maxValue)
float getPercentage() const
Examples
Basic Circular Indicator
auto indicator = CircularIndicator(CircularIndicatorConfig(100, 100, 40)
.value(75.0f)
.range(0.0f, 100.0f));
indicator->onValueChanged.connect([](float value) {
std::cout << "Progress: " << value << "%" << std::endl;
});
Loading Indicator
auto loading = CircularIndicator(CircularIndicatorConfig(150, 150, 35)
.value(60.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.backgroundColor(Colors::DarkGray)
.fillColor(Colors::Blue)
.thickness(8)
.showPercentage(true)
.startAngle(-90)));
loading->onComplete.connect([]() {
std::cout << "Loading completed!" << std::endl;
});
Custom Styled Indicator
auto indicator = CircularIndicator(CircularIndicatorConfig(100, 100, 50)
.value(45.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.backgroundColor(0xFF2C3E50) // Dark blue-gray
.fillColor(0xFF3498DB) // Bright blue
.borderColor(0xFF34495E) // Darker border
.borderWidth(3)
.thickness(10)
.showPercentage(true)
.textColor(0xFFFFFFFF)
.fontSize(2)
.clockwise(true)
.startAngle(-90.0f)));
Counter-Clockwise Indicator
auto ccwIndicator = CircularIndicator(CircularIndicatorConfig(100, 100, 35)
.value(60.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.fillColor(Colors::Red)
.clockwise(false) // Counter-clockwise
.startAngle(-90.0f)));
System Resource Monitoring
auto cpuIndicator = CircularIndicator(CircularIndicatorConfig(100, 100, 30)
.value(45.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.backgroundColor(Colors::DarkGray)
.fillColor(Colors::Blue)
.thickness(6)
.showPercentage(true)
.fontSize(1)));
auto memoryIndicator = CircularIndicator(CircularIndicatorConfig(200, 100, 30)
.value(67.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.backgroundColor(Colors::DarkGray)
.fillColor(Colors::Orange)
.thickness(6)
.showPercentage(true)
.fontSize(1)));
auto diskIndicator = CircularIndicator(CircularIndicatorConfig(300, 100, 30)
.value(32.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.backgroundColor(Colors::DarkGray)
.fillColor(Colors::Green)
.thickness(6)
.showPercentage(true)
.fontSize(1)));
Battery Level Indicator
auto battery = CircularIndicator(CircularIndicatorConfig(100, 100, 25)
.value(65.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.fillColor(Colors::Green)));
battery->onValueChanged.connect([](float level) {
if (level < 20.0f) {
std::cout << "Battery low: " << level << "%" << std::endl;
}
});
Experience/Level Indicator
auto xpIndicator = CircularIndicator(CircularIndicatorConfig(100, 100, 45)
.value(75.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.backgroundColor(0xFF4A4A4A) // Dark gray
.fillColor(0xFFFFD700) // Gold
.borderColor(0xFF8B4513) // Brown
.borderWidth(2)
.thickness(8)
.showPercentage(true)));
xpIndicator->onComplete.connect([]() {
std::cout << "Level up!" << std::endl;
});
Skill Indicators
std::vector<std::string> skills = {"Strength", "Agility", "Intelligence", "Wisdom"};
std::vector<float> skillValues = {72.0f, 58.0f, 91.0f, 45.0f};
std::vector<uint32_t> skillColors = {
Colors::Red,
Colors::Green,
Colors::Blue,
Colors::Purple
};
for (int i = 0; i < skills.size(); ++i) {
auto skill = CircularIndicator(CircularIndicatorConfig(100 + i * 80, 100, 25)
.value(skillValues[i])
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.fillColor(skillColors[i])
.thickness(4)
.showPercentage(true)
.fontSize(1)));
skill->onValueChanged.connect([skills, i](float value) {
std::cout << skills[i] << ": " << value << "%" << std::endl;
});
}
Status Indicators
// Success (100%)
auto success = CircularIndicator(CircularIndicatorConfig(100, 100, 25)
.value(100.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.fillColor(Colors::Green)
.showPercentage(false)));
// Warning (60%)
auto warning = CircularIndicator(CircularIndicatorConfig(150, 100, 25)
.value(60.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.fillColor(Colors::Yellow)
.showPercentage(false)));
// Error (25%)
auto error = CircularIndicator(CircularIndicatorConfig(200, 100, 25)
.value(25.0f)
.range(0.0f, 100.0f)
.style(CircularIndicatorStyle()
.fillColor(Colors::Red)
.showPercentage(false)));
Circular Indicator Presets
The CircularIndicatorPresets namespace provides common configurations:
// Default circular indicator
auto default = CircularIndicator(CircularIndicatorPresets::Default(100, 100));
// Loading indicator
auto loading = CircularIndicator(CircularIndicatorPresets::Loading(100, 100, 40));
// Health indicator
auto health = CircularIndicator(CircularIndicatorPresets::Health(100, 100, 30));
// Battery indicator
auto battery = CircularIndicator(CircularIndicatorPresets::Battery(100, 100, 25));
Complete Example
From examples/cpp/new/circular_indicator_widget_example.cpp:
#include <fern/fern.hpp>
using namespace Fern;
void setupUI() {
auto loadingIndicator = CircularIndicator(
CircularIndicatorPresets::Loading(100, 100, 35));
loadingIndicator->setValue(60.0f);
loadingIndicator->onValueChanged.connect([](float progress) {
std::cout << "Loading: " << progress << "%" << std::endl;
});
loadingIndicator->onComplete.connect([]() {
std::cout << "Loading completed!" << std::endl;
});
auto batteryIndicator = CircularIndicator(
CircularIndicatorPresets::Battery(250, 100, 25));
batteryIndicator->setValue(65.0f);
batteryIndicator->onValueChanged.connect([](float level) {
if (level < 20.0f) {
std::cout << "Battery low: " << level << "%" << std::endl;
}
});
}
Animating Progress
static std::shared_ptr<CircularIndicatorWidget> indicator;
static float progress = 0.0f;
void setupUI() {
indicator = CircularIndicator(CircularIndicatorConfig(200, 200, 60)
.value(0.0f));
}
void draw() {
Draw::fill(Colors::DarkBlue);
// Update progress
progress += 0.5f;
if (progress > 100.0f) progress = 0.0f;
indicator->setValue(progress);
}
Start Angle Reference
-90° or 270° - Top (12 o’clock)
0° - Right (3 o’clock)
90° - Bottom (6 o’clock)
180° - Left (9 o’clock)
Use Cases
- Loading indicators - Application or content loading
- System monitoring - CPU, memory, disk, network usage
- Game mechanics - Health, mana, experience
- Battery indicators - Device battery level
- Skill displays - Character attributes, skill levels
- Status indicators - Compact success/warning/error states
See Also