public/controls/Set-UiProgress.ps1
|
function Set-UiProgress { <# .SYNOPSIS Updates a progress bar's value, label, severity tint, or mode. .PARAMETER Variable Name of the progress bar to update. .PARAMETER Value New value. Clamped to the bar's Min/Max. .PARAMETER Increment Add this to the current value. If combined with -Value, adds to that. .PARAMETER Label Replace the label text above the bar (only works if built with -Label). .PARAMETER Severity Re-tint the bar: Info, Success, Warning, Error. .PARAMETER Indeterminate Toggle indeterminate mode on/off. Bar template is fixed at construction, so the first toggle starts the animation cold. Pass -Indeterminate to New-UiProgress up front for cleaner motion. .EXAMPLE Set-UiProgress -Variable 'progress' -Value 50 .EXAMPLE Set-UiProgress -Variable 'files' -Increment 1 -Label "Processed $i of $total" .EXAMPLE Set-UiProgress -Variable 'job' -Severity Error -Label 'Failed' #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Variable, [double]$Value, [double]$Increment, [string]$Label, [ValidateSet('Info', 'Success', 'Warning', 'Error')] [string]$Severity, # Bool can't be null, so PSBoundParameters.ContainsKey() is what tells us whether the caller actually asked to toggle the mode. [bool]$Indeterminate ) $session = Get-UiSession if (!$session) { Write-Verbose "Set-UiProgress: no active session for '$Variable' - update dropped." return } $progress = $session.Variables[$Variable] if (!$progress) { Write-Verbose "Set-UiProgress: control '$Variable' not found in session - update dropped." return } $hasValue = $PSBoundParameters.ContainsKey('Value') $hasIncrement = $PSBoundParameters.ContainsKey('Increment') $hasLabel = $PSBoundParameters.ContainsKey('Label') $hasSeverity = $PSBoundParameters.ContainsKey('Severity') $hasIndeterm = $PSBoundParameters.ContainsKey('Indeterminate') # Nothing to do? Don't bother the dispatcher about it. if (!($hasValue -or $hasIncrement -or $hasLabel -or $hasSeverity -or $hasIndeterm)) { return } Invoke-OnUIThread { if ($hasValue -or $hasIncrement) { # Read $progress.Value here (inside the dispatcher) so -Increment alone sees the latest committed value, not whatever was current when the call queued. Matters when callers fire Set-UiProgress in tight loops. $newValue = if ($hasValue) { $Value } else { $progress.Value } if ($hasIncrement) { $newValue += $Increment } # Clamp so callers don't have to think about it if ($newValue -lt $progress.Minimum) { $newValue = $progress.Minimum } if ($newValue -gt $progress.Maximum) { $newValue = $progress.Maximum } $progress.Value = $newValue } if ($hasSeverity) { # Map severity to brush key for theme-aware tinting $brushKey = Get-SeverityBrushKey -Severity $Severity -UseAccentDefault # Clear local value so the resource binding wins $progress.ClearValue([System.Windows.Controls.Control]::ForegroundProperty) $progress.SetResourceReference([System.Windows.Controls.Control]::ForegroundProperty, $brushKey) } $meta = $progress.Tag if ($meta -is [hashtable]) { if ($hasLabel) { if ($meta.LabelBlock) { $meta.LabelBlock.Text = $Label } else { Write-Verbose "Set-UiProgress: '$Variable' was created without -Label; skipping label update." } } if ($hasSeverity) { $meta.Severity = $Severity $meta.BrushTag = $brushKey } } if ($hasIndeterm) { # See .PARAMETER Indeterminate for the construction-time caveat. $progress.IsIndeterminate = $Indeterminate Write-Verbose "Set-UiProgress: toggled IsIndeterminate=$Indeterminate on '$Variable'." } } } |