Skip to content

Commit

Permalink
Merge pull request #297 from sirdoombox/main
Browse files Browse the repository at this point in the history
Switch old loading style with shader-based approach.
  • Loading branch information
kikipoulet authored Oct 5, 2024
2 parents 4edb09b + bb19c4c commit 62ab2c8
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 178 deletions.
20 changes: 3 additions & 17 deletions SukiUI.Demo/Features/ControlsLibrary/ProgressView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:suki="https://github.com/kikipoulet/SukiUI"
xmlns:controls1="clr-namespace:SukiUI.Demo.Controls"
xmlns:controlsLibrary="clr-namespace:SukiUI.Demo.Features.ControlsLibrary"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Expand Down Expand Up @@ -64,7 +63,8 @@
<suki:GroupBox Header="Wave Progress">
<Grid>
<showMeTheXaml:XamlDisplay VerticalAlignment="Center" UniqueId="WaveProgress">
<suki:WaveProgress IsTextVisible="{Binding IsTextVisible}" Value="{Binding ProgressValue}" />
<suki:WaveProgress IsTextVisible="{Binding IsTextVisible}"
Value="{Binding ProgressValue}" />
</showMeTheXaml:XamlDisplay>
</Grid>
</suki:GroupBox>
Expand Down Expand Up @@ -140,21 +140,7 @@
<suki:Loading />
</showMeTheXaml:XamlDisplay>
<showMeTheXaml:XamlDisplay UniqueId="Loading2">
<suki:Loading Classes="Accent" />
</showMeTheXaml:XamlDisplay>
</StackPanel>
</suki:GroupBox>
</suki:GlassCard>


<suki:GlassCard>
<suki:GroupBox Header="Custom Loading Indicators">
<StackPanel Spacing="15">
<showMeTheXaml:XamlDisplay UniqueId="Loading3">
<controls1:LoadingTest />
</showMeTheXaml:XamlDisplay>
<showMeTheXaml:XamlDisplay UniqueId="Loading4">
<controls1:LoadingTest LoadingStyle="Pellets" />
<suki:Loading LoadingStyle="Pellets" />
</showMeTheXaml:XamlDisplay>
</StackPanel>
</suki:GroupBox>
Expand Down
6 changes: 4 additions & 2 deletions SukiUI.Demo/SukiUI.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Assets\glow.sksl" />
<EmbeddedResource Include="Assets\pellets.sksl" />
<EmbeddedResource Include="Assets\space.sksl" />
<EmbeddedResource Include="Assets\clouds.sksl" />
<EmbeddedResource Include="Assets\weird.sksl" />
Expand All @@ -72,4 +70,8 @@
<ItemGroup>
<EmbeddedResource Include="Features\Effects\shaderart.sksl" />
</ItemGroup>

<ItemGroup>
<Folder Include="Controls\" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
uniform vec3 iForeground;

const float pi = 3.14159265358979323846;

float smoothstep(float a, float b, float x) {
Expand Down Expand Up @@ -65,5 +67,5 @@ vec4 main(vec2 fragCoord) {
float color = smoothstep(pixelSize, 0.0, abs(radius - len) - lineWidth) * fallOff;
color += smoothstep(glowSize * fallOff, 0.0, abs(radius - len) - lineWidth) * fallOff * 0.5;

return vec4(color) * vec4(iAccent, iAlpha);
return vec4(color) * vec4(iForeground, iAlpha);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
uniform vec3 iForeground;

float smoothstep(float a, float b, float x) {
float t = clamp((x - a) / (b - a), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
Expand All @@ -24,5 +26,5 @@ vec4 main(vec2 fragCoord) {
i;
for (i = 0.; i < 1.; i += .5)
d = min(A(p * D(mix(-.5, .625, fract(T / 2. + i)) - .125 * T), .0625), d); // distance to shorter arcs ("pellets")
return vec4(smoothstep(.01, .0, d)) * vec4(iAccent, iAlpha);
return vec4(smoothstep(.01, .0, d)) * vec4(iForeground, iAlpha);
}
102 changes: 0 additions & 102 deletions SukiUI/Controls/Loading.axaml

This file was deleted.

32 changes: 0 additions & 32 deletions SukiUI/Controls/Loading.axaml.cs

This file was deleted.

55 changes: 44 additions & 11 deletions SukiUI.Demo/Controls/LoadingTest.cs → SukiUI/Controls/Loading.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,74 @@
using System.Collections.Generic;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Media;
using Avalonia.Media.Immutable;
using SkiaSharp;
using SukiUI.Extensions;
using SukiUI.Utilities.Effects;

namespace SukiUI.Demo.Controls
namespace SukiUI.Controls
{
public class LoadingTest : Control
public class Loading : Control
{
public static readonly StyledProperty<LoadingStyle> LoadingStyleProperty =
AvaloniaProperty.Register<LoadingTest, LoadingStyle>(nameof(LoadingStyle));
public static readonly StyledProperty<LoadingStyle> LoadingStyleProperty =
AvaloniaProperty.Register<Loading, LoadingStyle>(nameof(LoadingStyle), defaultValue: LoadingStyle.Glow);

public LoadingStyle LoadingStyle
{
get => GetValue(LoadingStyleProperty);
set => SetValue(LoadingStyleProperty, value);
}

public static readonly StyledProperty<IBrush?> ForegroundProperty =
AvaloniaProperty.Register<Loading, IBrush?>(nameof(Foreground));

public IBrush? Foreground
{
get => GetValue(ForegroundProperty);
set => SetValue(ForegroundProperty, value);
}

private static readonly IReadOnlyDictionary<LoadingStyle, SukiEffect> Effects =
new Dictionary<LoadingStyle, SukiEffect>()
{
{ LoadingStyle.Glow, SukiEffect.FromEmbeddedResource("glow") },
{ LoadingStyle.Pellets, SukiEffect.FromEmbeddedResource("pellets") }
{ LoadingStyle.Pellets, SukiEffect.FromEmbeddedResource("pellets") },
};

private readonly LoadingEffectDraw _draw;

public LoadingTest()
public Loading()
{
Width = 50;
Height = 50;
_draw = new LoadingEffectDraw(Bounds);
}

public override void Render(DrawingContext context)
{
_draw.Bounds = Bounds;
_draw.Effect = Effects[LoadingStyle];
if (Foreground is null)
this[!ForegroundProperty] = new DynamicResourceExtension("SukiPrimaryColor");
if (Foreground is ImmutableSolidColorBrush brush)
brush.Color.ToFloatArrayNonAlloc(_draw.Color);
context.Custom(_draw);
}


protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property != ForegroundProperty) return;
if (Foreground is ImmutableSolidColorBrush brush)
brush.Color.ToFloatArrayNonAlloc(_draw.Color);
}

public class LoadingEffectDraw : EffectDrawBase
{
public float[] Color { get; } = { 1.0f, 0f, 0f };

public LoadingEffectDraw(Rect bounds) : base(bounds)
{
AnimationEnabled = true;
Expand All @@ -51,19 +77,26 @@ public LoadingEffectDraw(Rect bounds) : base(bounds)

protected override void Render(SKCanvas canvas, SKRect rect)
{
canvas.Scale(1,-1);
canvas.Scale(1, -1);
canvas.Translate(0, (float)-Bounds.Height);
using var mainShaderPaint = new SKPaint();

if (Effect is not null)
{
using var shader = EffectWithUniforms();
using var shader = EffectWithCustomUniforms(effect => new SKRuntimeEffectUniforms(effect)
{
{ "iForeground", Color }
});
mainShaderPaint.Shader = shader;
canvas.DrawRect(rect, mainShaderPaint);
}

canvas.Restore();
}

// I'm not really sure how to render this properly in software fallback scenarios.
// This is likely to cause issues with the previewer.
// Might be worth just drawing a circle or something...
protected override void RenderSoftware(SKCanvas canvas, SKRect rect)
{
throw new System.NotImplementedException();
Expand Down
19 changes: 19 additions & 0 deletions SukiUI/Extensions/ColorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,23 @@ public static Color WithAlpha(this Color c, byte alpha) =>

public static Color WithAlpha(this Color c, double alpha) =>
WithAlpha(c, (byte)(255 * alpha));

/// <summary>
/// Used primarily for SukiEffect runtime effect uniforms, converts a standard Color to an RGB float array in the range 0-1
/// </summary>
public static float[] ToFloatArray(this Color c) =>
new[] { c.R / 255f, c.G / 255f, c.B / 255f };

/// <summary>
/// Used primarily for SukiEffect runtime effect uniforms, converts a standard Color to an RGB float array in the range 0-1.
/// Allows recycling of an array for performance.
/// </summary>
/// <param name="c"></param>
/// <param name="array"></param>
public static void ToFloatArrayNonAlloc(this Color c, float[] array)
{
array[0] = c.R / 255f;
array[1] = c.G / 255f;
array[2] = c.B / 255f;
}
}
2 changes: 2 additions & 0 deletions SukiUI/SukiUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
<EmbeddedResource Include="Content\Shaders\Background\flat.sksl" />
<EmbeddedResource Include="Content\Shaders\Background\bubble.sksl" />
<EmbeddedResource Include="Content\Shaders\Background\waves.sksl" />
<EmbeddedResource Include="Content\Shaders\Loading\glow.sksl" />
<EmbeddedResource Include="Content\Shaders\Loading\pellets.sksl" />
<None Remove="Content\Shaders\Background\gradient.sksl" />
<EmbeddedResource Include="Content\Shaders\Background\gradient.sksl" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions SukiUI/Theme/Button.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<DoubleTransition Property="Width" Duration="0:0:0.3" />
</Transitions>
</Viewbox.Transitions>
<controls:Loading Foreground="{DynamicResource SukiText}" />
<controls:Loading LoadingStyle="Pellets" Foreground="{DynamicResource SukiText}" />
</Viewbox>
<ContentPresenter HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Expand Down Expand Up @@ -269,7 +269,7 @@
</Style>

<Style Selector="^ /template/ controls|Loading">
<Setter Property="Foreground" Value="White" />
<Setter Property="Foreground" Value="{DynamicResource SukiText}" />
</Style>
<Style Selector="^ /template/ ContentPresenter">
<Setter Property="Foreground" Value="White" />
Expand Down
Loading

0 comments on commit 62ab2c8

Please sign in to comment.