Skip to content

Commit 7673b63

Browse files
committed
Updated to rounded rectangular style
1 parent 162b779 commit 7673b63

1 file changed

Lines changed: 111 additions & 71 deletions

File tree

‎FluentFlyoutWPF/Classes/Visualizer.cs‎

Lines changed: 111 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33

44
using FluentFlyout.Classes.Settings;
55
using FluentFlyout.Classes.Utils;
6+
using Microsoft.Win32;
67
using NAudio.CoreAudioApi;
78
using NAudio.Dsp;
89
using NAudio.Wave;
9-
using Microsoft.Win32;
10-
using System.Threading;
1110
using System.Windows;
1211
using System.Windows.Media;
1312
using System.Windows.Media.Imaging;
@@ -465,7 +464,7 @@ private void UpdateBitmap()
465464

466465
private unsafe void DrawBars(int stride, Span<byte> buffer)
467466
{
468-
// Resolve brush once (avoid repeated lookups)
467+
// Resolve brush once
469468
SolidColorBrush brush = BitmapHelper.SavedDominantColors.Count > 0
470469
? BitmapHelper.SavedDominantColors.Last()
471470
: (SolidColorBrush)Application.Current.TryFindResource("MicaWPF.Brushes.SystemAccentColorTertiary");
@@ -479,124 +478,165 @@ private unsafe void DrawBars(int stride, Span<byte> buffer)
479478

480479
int centerY = ImageHeight / 2;
481480

482-
// Layout calculation (float-based to avoid spacing drift)
483-
float totalSpacing = (BarCount - 1) * BarSpacing;
484-
float exactBarWidth = (ImageWidth - totalSpacing) / (float)BarCount;
485-
float totalBarsWidth = BarCount * exactBarWidth + totalSpacing;
486-
float offsetX = (ImageWidth - totalBarsWidth) * 0.5f;
481+
// Horizontal layout
482+
ComputeLayout(ImageWidth, BarCount, BarSpacing,
483+
out int barWidth,
484+
out int offsetX);
485+
486+
// Radius
487+
float baseRadius = GetCornerRadius();
488+
489+
// AA constants
490+
const float aa = 1.25f;
491+
float invAA = 1f / aa;
487492

488493
for (int i = 0; i < BarCount; i++)
489494
{
490-
// Normalize and scale height
491-
float normalizedValue = Math.Clamp(_barValues[i], 0f, 1f);
492-
int barHeight = Math.Max((int)(normalizedValue * ImageHeight), barBaseline);
495+
int barX = offsetX + i * (barWidth + BarSpacing);
493496

494-
// Compute precise X bounds (prevents cumulative rounding errors)
495-
ComputeBarBounds(i, exactBarWidth, offsetX, out int barX, out int barWidth);
497+
int barHeight = GetBarHeight(_barValues[i], barBaseline);
496498

497-
if (barWidth <= 0)
499+
if (barHeight <= 0)
498500
continue;
499501

500-
// Compute vertical bounds
501-
ComputeBarVertical(centeredBars, centerY, barHeight, out int barY, out int barEndY);
502+
ComputeVertical(centeredBars, centerY, barHeight, out int barY, out int barEndY);
502503

503-
// Precompute geometry
504-
float radius = MathF.Min(barWidth, barHeight) * 0.5f;
504+
// Clamp radius per bar
505+
float radius = ClampRadius(baseRadius, barWidth, barHeight);
506+
float radiusSq = radius * radius;
505507

506-
var geom = new BarGeometry(barX, barWidth, barY, barEndY, radius);
508+
RasterizeBar(
509+
buffer, stride,
510+
barX, barWidth,
511+
barY, barEndY,
512+
centeredBars,
513+
radius, radiusSq, invAA,
514+
b, g, r);
515+
}
516+
}
507517

508-
// Precompute SDF constants
509-
float aa = 1.25f;
510-
float invAA = 1f / aa;
511-
float radiusSq = radius * radius;
518+
private static void ComputeLayout(
519+
int imageWidth,
520+
int barCount,
521+
int spacing,
522+
out int barWidth,
523+
out int offsetX)
524+
{
525+
int totalSpacing = (barCount - 1) * spacing;
526+
527+
int availableWidth = imageWidth - totalSpacing - 1;
528+
529+
barWidth = availableWidth / barCount;
530+
531+
int usedWidth = barWidth * barCount + totalSpacing;
532+
533+
// Center safely
534+
offsetX = (imageWidth - usedWidth) >> 1;
535+
}
512536

513-
// Rasterize
514-
RasterizeBar(buffer, stride, geom, centeredBars, b, g, r, invAA, radiusSq);
537+
private void ComputeVertical(bool centered, int centerY, int height, out int y, out int endY)
538+
{
539+
if (centered)
540+
{
541+
int half = height >> 1; // faster than /2
542+
y = centerY - half;
543+
endY = centerY + half;
515544
}
545+
else
546+
{
547+
y = ImageHeight - height;
548+
endY = ImageHeight;
549+
}
550+
}
551+
552+
private int GetBarHeight(float value, int baseline)
553+
{
554+
return Math.Max((int)(Math.Clamp(value, 0f, 1f) * ImageHeight), baseline);
555+
}
556+
private static float GetCornerRadius()
557+
{
558+
return 6f / MathF.Max(1f, SettingsManager.Current.TaskbarVisualizerBarCount / 10f);
559+
}
560+
561+
private static float ClampRadius(float r, int width, int height)
562+
{
563+
float max = MathF.Min(width, height) * 0.5f;
564+
return r > max ? max : r;
516565
}
517566

518567
private unsafe void RasterizeBar(
519568
Span<byte> buffer,
520569
int stride,
521-
BarGeometry g,
570+
int barX,
571+
int barWidth,
572+
int barY,
573+
int barEndY,
522574
bool centeredBars,
523-
byte b, byte gr, byte r,
575+
float radius,
576+
float radiusSq,
524577
float invAA,
525-
float radiusSq)
578+
byte b, byte g, byte r)
526579
{
527-
for (int y = (int)g.Top; y < g.Bottom && y < ImageHeight && y >= 0; y++)
580+
float left = barX;
581+
float right = barX + barWidth;
582+
float top = barY;
583+
float bottom = barEndY;
584+
585+
float innerLeft = left + radius;
586+
float innerRight = right - radius;
587+
float innerTop = top + radius;
588+
float innerBottom = bottom - radius;
589+
590+
for (int y = barY; y < barEndY && y < ImageHeight && y >= 0; y++)
528591
{
529592
int row = y * stride;
530593

531-
for (int x = (int)g.Left; x < g.Right && x < ImageWidth; x++)
594+
for (int x = barX; x < barX + barWidth && x < ImageWidth; x++)
532595
{
533-
int index = row + x * 4;
596+
int index = row + (x << 2); // x * 4 (bitshift faster)
534597
if (index + 3 >= buffer.Length)
535598
continue;
536599

537-
// Fast path: center rectangle
538-
if (x >= g.InnerLeft && x <= g.InnerRight)
600+
// CENTER
601+
if (x >= innerLeft && x <= innerRight)
539602
{
540-
WritePixel(buffer, index, b, gr, r, 255);
603+
WritePixel(buffer, index, b, g, r, 255);
541604
continue;
542605
}
543606

544-
// Fast path: vertical sides (no AA)
545-
if (y >= g.InnerTop && y <= g.InnerBottom)
607+
// SIDES
608+
if (y >= innerTop && y <= innerBottom)
546609
{
547-
WritePixel(buffer, index, b, gr, r, 255);
610+
WritePixel(buffer, index, b, g, r, 255);
548611
continue;
549612
}
550613

551-
// Flat bottom if not centered
552-
if (!centeredBars && y >= g.InnerBottom)
614+
// FLAT BOTTOM
615+
if (!centeredBars && y >= innerBottom)
553616
{
554-
WritePixel(buffer, index, b, gr, r, 255);
617+
WritePixel(buffer, index, b, g, r, 255);
555618
continue;
556619
}
557620

558-
// Rounded caps only
559-
float cx = x < g.InnerLeft ? g.InnerLeft : (x > g.InnerRight ? g.InnerRight : x);
560-
float cy = y < g.InnerTop ? g.InnerTop : (y > g.InnerBottom ? g.InnerBottom : y);
621+
// CORNERS
622+
float cx = x < innerLeft ? innerLeft : (x > innerRight ? innerRight : x);
623+
float cy = y < innerTop ? innerTop : (y > innerBottom ? innerBottom : y);
561624

562625
float dx = x - cx;
563626
float dy = y - cy;
564627

565628
float distSq = dx * dx + dy * dy;
566-
float sdf = (distSq - radiusSq) / (2f * MathF.Sqrt(radiusSq)); // radius = sqrt(radiusSq)
629+
float sdf = (distSq - radiusSq) / (2f * radius);
567630

568-
float alpha = Math.Clamp(0.5f - sdf * invAA, 0f, 1f);
631+
float alpha = 0.5f - sdf * invAA;
569632

570633
if (alpha <= 0f)
571634
continue;
572635

573-
WritePixel(buffer, index, b, gr, r, (byte)(255 * alpha));
574-
}
575-
}
576-
}
577-
578-
private void ComputeBarBounds(int i, float width, float offsetX, out int x, out int barWidth)
579-
{
580-
float fx = offsetX + i * (width + BarSpacing);
581-
float fxNext = fx + width;
582-
583-
x = (int)MathF.Round(fx);
584-
int right = (int)MathF.Round(fxNext);
585-
barWidth = right - x;
586-
}
636+
if (alpha > 1f) alpha = 1f;
587637

588-
private void ComputeBarVertical(bool centered, int centerY, int height, out int y, out int endY)
589-
{
590-
if (centered)
591-
{
592-
int half = height / 2;
593-
y = centerY - half;
594-
endY = centerY + half;
595-
}
596-
else
597-
{
598-
y = ImageHeight - height;
599-
endY = ImageHeight;
638+
WritePixel(buffer, index, b, g, r, (byte)(255 * alpha));
639+
}
600640
}
601641
}
602642

0 commit comments

Comments
 (0)