A game framework written with osu! in mind.
at master 103 lines 3.7 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using osu.Framework.Allocation; 6using osu.Framework.Bindables; 7using osu.Framework.Graphics.Shaders; 8using osu.Framework.Graphics.Textures; 9using osu.Framework.Graphics.Transforms; 10 11namespace osu.Framework.Graphics.UserInterface 12{ 13 public class CircularProgress : Drawable, ITexturedShaderDrawable, IHasCurrentValue<double> 14 { 15 private readonly BindableWithCurrent<double> current = new BindableWithCurrent<double>(); 16 17 public Bindable<double> Current 18 { 19 get => current.Current; 20 set => current.Current = value; 21 } 22 23 public CircularProgress() 24 { 25 Current.ValueChanged += newValue => Invalidate(Invalidation.DrawNode); 26 } 27 28 public IShader RoundedTextureShader { get; private set; } 29 public IShader TextureShader { get; private set; } 30 31 #region Disposal 32 33 protected override void Dispose(bool isDisposing) 34 { 35 texture?.Dispose(); 36 texture = null; 37 38 base.Dispose(isDisposing); 39 } 40 41 #endregion 42 43 protected override DrawNode CreateDrawNode() => new CircularProgressDrawNode(this); 44 45 public TransformSequence<CircularProgress> FillTo(double newValue, double duration = 0, Easing easing = Easing.None) 46 => FillTo(newValue, duration, new DefaultEasingFunction(easing)); 47 48 public TransformSequence<CircularProgress> FillTo<TEasing>(double newValue, double duration, in TEasing easing) 49 where TEasing : IEasingFunction 50 => this.TransformBindableTo(Current, newValue, duration, easing); 51 52 [BackgroundDependencyLoader] 53 private void load(ShaderManager shaders) 54 { 55 RoundedTextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); 56 TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); 57 } 58 59 private Texture texture = Texture.WhitePixel; 60 61 public Texture Texture 62 { 63 get => texture; 64 set 65 { 66 if (value == texture) 67 return; 68 69 texture?.Dispose(); 70 texture = value; 71 72 Invalidate(Invalidation.DrawNode); 73 } 74 } 75 76 private float innerRadius = 1; 77 78 /// <summary> 79 /// The inner fill radius, relative to the <see cref="Drawable.DrawSize"/> of the <see cref="CircularProgress"/>. 80 /// The value range is 0 to 1 where 0 is invisible and 1 is completely filled. 81 /// The entire texture still fills the disk without cropping it. 82 /// </summary> 83 public float InnerRadius 84 { 85 get => innerRadius; 86 set 87 { 88 innerRadius = Math.Clamp(value, 0, 1); 89 Invalidate(Invalidation.DrawNode); 90 } 91 } 92 } 93 94 public static class CircularProgressTransformSequenceExtensions 95 { 96 public static TransformSequence<CircularProgress> FillTo(this TransformSequence<CircularProgress> t, double newValue, double duration = 0, Easing easing = Easing.None) 97 => t.FillTo(newValue, duration, new DefaultEasingFunction(easing)); 98 99 public static TransformSequence<CircularProgress> FillTo<TEasing>(this TransformSequence<CircularProgress> t, double newValue, double duration, TEasing easing) 100 where TEasing : IEasingFunction 101 => t.Append(cp => cp.FillTo(newValue, duration, easing)); 102 } 103}