classes.ps1
enum alignment { Left = 0 Right Center } class column { [string]$FieldName [string]$Label [int]$Width #Percentage [alignment]$Align = [alignment]::Left column( [string]$FieldName, [string]$Label, [int]$Width ) { $this.FieldName = $FieldName $this.Label = $Label $this.Width = $Width } column( [string]$FieldName, [string]$Label, [int]$Width, [alignment]$Align ) { $this.FieldName = $FieldName $this.Label = $Label $this.Width = $Width $this.Align = $Align } } class package { [string]$Name [string]$Id [string[]]$AvailableVersions [string]$Source [bool]$IsUpdateAvailable [string]$InstalledVersion [string]$Available package( [string]$Name, [string]$Id, [string[]]$AvailableVersions, [string]$Source, [bool]$IsUpdateAvailable, [string]$InstalledVersion ) { $this.Name = $Name $this.Id = $Id $this.AvailableVersions = $AvailableVersions $this.Source = $Source $this.IsUpdateAvailable = $IsUpdateAvailable $this.InstalledVersion = $InstalledVersion $this.Available = $AvailableVersions[0] } package( [string]$Name, [string]$Id, [string]$InstalledVersion ) { $this.Name = $Name $this.Id = $Id $this.InstalledVersion = $InstalledVersion } package( [string]$Name, [string]$Id, [string]$InstalledVersion, [string]$Available ) { $this.Name = $Name $this.Id = $Id $this.InstalledVersion = $InstalledVersion $this.Available = $Available } } class Spinner { [hashtable]$Spinner [System.Collections.Hashtable]$statedata $runspace [powershell]$session [Int32]$X = $Host.UI.RawUI.CursorPosition.X [Int32]$Y = $Host.UI.RawUI.CursorPosition.Y [bool]$running = $false [Int32]$width = $Host.UI.RawUI.BufferSize.Width $Spinners = @{ "Circle" = @{ "Frames" = @("◜", "◠", "◝", "◞", "◡", "◟") "Sleep" = 50 } "Dots" = @{ "Frames" = @("⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷", "⣿") "Sleep" = 50 } "Line" = @{ "Frames" = @("▰▱▱▱▱▱▱", "▰▰▱▱▱▱▱", "▰▰▰▱▱▱▱", "▰▰▰▰▱▱▱", "▰▰▰▰▰▱▱", "▰▰▰▰▰▰▱", "▰▰▰▰▰▰▰", "▰▱▱▱▱▱▱") "Sleep" = 50 } "Square" = @{ "Frames" = @("⣾⣿", "⣽⣿", "⣻⣿", "⢿⣿", "⡿⣿", "⣟⣿", "⣯⣿", "⣷⣿", "⣿⣾", "⣿⣽", "⣿⣻", "⣿⢿", "⣿⡿", "⣿⣟", "⣿⣯", "⣿⣷") "Sleep" = 50 } "Bubble" = @{ "Frames" = @("......", "o.....", "Oo....", "oOo...", ".oOo..", "..oOo.", "...oOo", "....oO", ".....o", "....oO", "...oOo", "..oOo.", ".oOo..", "oOo...", "Oo....", "o.....", "......") "Sleep" = 50 } "Arrow" = @{ "Frames" = @("≻ ", " ≻ ", " ≻ ", " ≻ ", " ≻", " ≺", " ≺ ", " ≺ ", " ≺ ", "≺ ") "Sleep" = 50 } "Pulse" = @{ "Frames" = @("◾", "◾", "◼️", "◼️", "⬛", "⬛", "◼️", "◼️") "Sleep" = 50 } } Spinner( [string]$type = "Dots" ) { $this.Spinner = $this.Spinners[$type] } Spinner( [string]$type = "Dots", [int]$X, [int]$Y ) { $this.Spinner = $this.Spinners[$type] $this.X = $X $this.Y = $Y } [void] Start( [string]$label = "Loading..." ) { $this.running = $true $this.statedata = [System.Collections.Hashtable]::Synchronized([System.Collections.Hashtable]::new()) $this.runspace = [runspacefactory]::CreateRunspace() $this.statedata.offset = ($this.Spinner.Frames | Measure-Object -Property Length -Maximum).Maximum $ThemedFrames = @() $this.Spinner.Frames | ForEach-Object { $ThemedFrames += gum style $_ --foreground $($Theme["brightPurple"]) } $this.statedata.Frames = $ThemedFrames $this.statedata.Sleep = $this.Spinner.Sleep $this.statedata.label = $label $this.statedata.X = $this.X $this.statedata.Y = $this.Y $this.runspace.Open() $this.Runspace.SessionStateProxy.SetVariable("StateData", $this.StateData) $sb = { [System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8 [system.Console]::CursorVisible = $false $X = $StateData.X $Y = $StateData.Y $Frames = $statedata.Frames $i = 0 while ($true) { [System.Console]::setcursorposition($X, $Y) # $text = "$([char]27)[35m$([char]27)[50m$($Frames[$i])$([char]27)[0m" $text = $Frames[$i] [system.console]::write($text) [System.Console]::setcursorposition(($X + $statedata.offset) + 1, $Y) [system.console]::write($statedata.label) $i = ($i + 1) % $Frames.Length Start-Sleep -Milliseconds $Statedata.Sleep } } $this.session = [powershell]::create() $null = $this.session.AddScript($sb) $this.session.Runspace = $this.runspace $null = $this.session.BeginInvoke() } [void] SetLabel( [string]$label ) { [System.Console]::setcursorposition(($this.X + $this.statedata.offset) + 1, $this.Y) [system.console]::write("".PadLeft($this.statedata.label.Length, " ")) $this.statedata.label = $label # Redraw the label to avoid flickering [System.Console]::setcursorposition(($this.X + $this.statedata.offset) + 1, $this.Y) [system.console]::write($label) } [void] Stop() { if ($this.running -eq $true) { [System.Console]::setcursorposition(0, $this.Y) [system.console]::write("".PadLeft($this.Width, " ")) $this.running = $false $this.session.Stop() $this.runspace.Close() $this.runspace.Dispose() [System.Console]::setcursorposition($this.X, $this.Y) [system.Console]::CursorVisible = $true } } } $Theme = @{ "background" = "#272935" "black" = "#272935" "blue" = "#BD93F9" "brightBlack" = "#555555" "brightBlue" = "#BD93F9" "brightCyan" = "#8BE9FD" "brightGreen" = "#50FA7B" "brightPurple" = "#FF79C6" "brightRed" = "#FF5555" "brightWhite" = "#FFFFFF" "brightYellow" = "#F1FA8C" "cyan" = "#6272A4" "foreground" = "#F8F8F2" "green" = "#50FA7B" "purple" = "#6272A4" "red" = "#FF5555" "white" = "#F8F8F2" "yellow" = "#FFB86C" } |