From 1d418853c9d8f0f4e11483e5552f6aae7808be3b Mon Sep 17 00:00:00 2001 From: Leonmmcoset Date: Tue, 31 Mar 2026 22:19:53 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BuildTime.txt | 2 +- GitCommit.txt | 2 +- Gui/Apps/UILibGallery.cs | 28 +++++++++- Gui/UILib/ProgressBar.cs | 113 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 Gui/UILib/ProgressBar.cs diff --git a/BuildTime.txt b/BuildTime.txt index 7026fe9..713a8d4 100644 --- a/BuildTime.txt +++ b/BuildTime.txt @@ -1 +1 @@ -2026-03-29 21:37:22 \ No newline at end of file +2026-03-31 22:16:42 \ No newline at end of file diff --git a/GitCommit.txt b/GitCommit.txt index 0fd38ad..d2000ac 100644 --- a/GitCommit.txt +++ b/GitCommit.txt @@ -1 +1 @@ -d8cdc9d \ No newline at end of file +cd2e1e5 \ No newline at end of file diff --git a/Gui/Apps/UILibGallery.cs b/Gui/Apps/UILibGallery.cs index 5787936..8125e23 100644 --- a/Gui/Apps/UILibGallery.cs +++ b/Gui/Apps/UILibGallery.cs @@ -190,16 +190,40 @@ namespace CMLeonOS.Gui.Apps private void ShowProgressDemo() { ClearPreview(); - SetHeader("ProgressRing", "Animated busy indicator for indeterminate loading states."); + SetHeader("Progress", "ProgressRing for indeterminate state and ProgressBar for determinate tasks."); ProgressRing ring = new ProgressRing(previewHost, 24, 24, 56, 56); ring.Active = true; AddDemo(ring); - TextBlock hint = new TextBlock(previewHost, 100, 38, 320, 24); + TextBlock hint = new TextBlock(previewHost, 100, 20, 380, 24); hint.Text = "ProgressRing keeps animating while Active=true."; hint.Foreground = UITheme.TextSecondary; AddDemo(hint); + + ProgressBar bar = new ProgressBar(previewHost, 100, 56, 320, 24); + bar.Minimum = 0; + bar.Maximum = 100; + bar.Value = 36; + AddDemo(bar); + + Button minus = new Button(previewHost, 100, 90, 28, 24); + minus.Text = "-"; + minus.OnClick = (_, _) => + { + bar.Value -= 10f; + SetHeader("Progress", "ProgressBar: " + ((int)(bar.GetPercent() * 100f)).ToString() + "%"); + }; + AddDemo(minus); + + Button plus = new Button(previewHost, 136, 90, 28, 24); + plus.Text = "+"; + plus.OnClick = (_, _) => + { + bar.Value += 10f; + SetHeader("Progress", "ProgressBar: " + ((int)(bar.GetPercent() * 100f)).ToString() + "%"); + }; + AddDemo(plus); } private void ShowTableDemo() diff --git a/Gui/UILib/ProgressBar.cs b/Gui/UILib/ProgressBar.cs new file mode 100644 index 0000000..37e915c --- /dev/null +++ b/Gui/UILib/ProgressBar.cs @@ -0,0 +1,113 @@ +using System; +using System.Drawing; + +namespace CMLeonOS.Gui.UILib +{ + internal class ProgressBar : Control + { + public ProgressBar(Window parent, int x, int y, int width, int height) : base(parent, x, y, width, height) + { + } + + private float _minimum = 0f; + internal float Minimum + { + get { return _minimum; } + set + { + _minimum = value; + if (_maximum < _minimum) _maximum = _minimum; + if (_value < _minimum) _value = _minimum; + Render(); + } + } + + private float _maximum = 100f; + internal float Maximum + { + get { return _maximum; } + set + { + _maximum = Math.Max(value, _minimum); + if (_value > _maximum) _value = _maximum; + Render(); + } + } + + private float _value = 0f; + internal float Value + { + get { return _value; } + set + { + float clamped = Math.Max(_minimum, Math.Min(_maximum, value)); + if (Math.Abs(clamped - _value) < 0.0001f) return; + _value = clamped; + Render(); + } + } + + private Color _background = UITheme.SurfaceMuted; + internal Color Background + { + get { return _background; } + set { _background = value; Render(); } + } + + private Color _foreground = UITheme.Accent; + internal Color Foreground + { + get { return _foreground; } + set { _foreground = value; Render(); } + } + + private Color _border = UITheme.SurfaceBorder; + internal Color Border + { + get { return _border; } + set { _border = value; Render(); } + } + + internal bool ShowPercentageText { get; set; } = true; + + internal float GetPercent() + { + float range = _maximum - _minimum; + if (range <= 0.0001f) return 1f; + return (_value - _minimum) / range; + } + + internal override void Render() + { + Clear(UITheme.Surface); + + int innerW = Math.Max(0, Width - 2); + int innerH = Math.Max(0, Height - 2); + DrawFilledRectangle(1, 1, innerW, innerH, Background); + + float percent = Math.Max(0f, Math.Min(1f, GetPercent())); + int fillWidth = (int)(innerW * percent); + if (fillWidth > 0) + { + DrawFilledRectangle(1, 1, fillWidth, innerH, Foreground); + DrawHorizontalLine(Math.Max(0, fillWidth - 1), 1, 1, Color.FromArgb( + Math.Min(255, Foreground.R + 20), + Math.Min(255, Foreground.G + 20), + Math.Min(255, Foreground.B + 20))); + } + + DrawRectangle(0, 0, Width, Height, Border); + + if (ShowPercentageText) + { + string text = ((int)(percent * 100f)).ToString() + "%"; + int textX = (Width / 2) - (text.Length * 4); + int textY = (Height / 2) - 8; + Color textColor = percent > 0.45f ? Color.White : UITheme.TextPrimary; + DrawString(text, textColor, textX, textY); + } + + WM.Update(this); + } + } +}