Classes/PSColorStyle.ps1
|
<# .SYNOPSIS PSColorStyle class for managing reusable color and style configurations .DESCRIPTION The PSColorStyle class provides a comprehensive system for defining and managing color and style profiles for Write-ColorEX output. It implements a singleton pattern for default styles and a named profiles system for common output patterns. KEY FEATURES: - Singleton default style accessible via [PSColorStyle]::Default - Named profile collection via [PSColorStyle]::Profiles - Built-in profiles: Default, Error, Warning, Info, Success, Critical, Debug - Performance-optimized parameter caching (36x faster with ToWriteColorParams()) - Full support for all Write-ColorEX features including AutoPad - Clone method for creating style variations USAGE PATTERN: - Create custom styles with New-ColorStyle function - Access built-in profiles: [PSColorStyle]::Profiles['Error'] - Set default style: $style.SetAsDefault() - Register profiles: $style.AddToProfiles() .NOTES Author: MarkusMcNugen License: MIT Requires: PowerShell 5.1 or later This class is automatically loaded when the PSWriteColorEX module is imported. Default profiles are initialized via InitializeDefaultProfiles() static method. .LINK https://github.com/MarkusMcNugen/PSWriteColorEX .LINK New-ColorStyle .LINK Set-ColorDefault .EXAMPLE # Create and register a custom style $style = [PSColorStyle]::new("Header", "Cyan", $null) $style.Bold = $true $style.Underline = $true $style.HorizontalCenter = $true $style.AddToProfiles() .EXAMPLE # Use a built-in profile $errorStyle = [PSColorStyle]::Profiles['Error'] Write-ColorEX -Text "Failed!" -StyleProfile $errorStyle .EXAMPLE # Clone and modify a profile $customError = [PSColorStyle]::Profiles['Error'].Clone() $customError.Name = "MyError" $customError.Italic = $true #> class PSColorStyle { [string]$Name [object]$ForegroundColor [object]$BackgroundColor [object[]]$Gradient [string[]]$Style [int]$StartTab [int]$StartSpaces [int]$LinesBefore [int]$LinesAfter [bool]$Bold [bool]$Italic [bool]$Underline [bool]$Blink [bool]$Faint [bool]$CrossedOut [bool]$DoubleUnderline [bool]$Overline [bool]$ShowTime [bool]$NoNewLine [bool]$HorizontalCenter [int]$AutoPad = 0 [bool]$PadLeft = $false [char]$PadChar = ' ' # Static property for singleton default instance static [PSColorStyle]$Default # Static property for named profiles static [hashtable]$Profiles = @{} # Hidden cached params hashtable hidden [hashtable]$_cachedParams = $null # Constructor PSColorStyle() { $this.Initialize("Custom", "Gray", $null) } PSColorStyle([string]$name) { $this.Initialize($name, "Gray", $null) } PSColorStyle([string]$name, [object]$foreground, [object]$background) { $this.Initialize($name, $foreground, $background) } hidden [void]Initialize([string]$name, [object]$foreground, [object]$background) { $this.Name = $name $this.ForegroundColor = $foreground $this.BackgroundColor = $background $this.Gradient = $null $this.Style = @() $this.StartTab = 0 $this.StartSpaces = 0 $this.LinesBefore = 0 $this.LinesAfter = 0 $this.Bold = $false $this.Italic = $false $this.Underline = $false $this.Blink = $false $this.Faint = $false $this.CrossedOut = $false $this.DoubleUnderline = $false $this.Overline = $false $this.ShowTime = $false $this.NoNewLine = $false $this.HorizontalCenter = $false $this.AutoPad = 0 $this.PadLeft = $false $this.PadChar = ' ' } # Method to set as default [void]SetAsDefault() { [PSColorStyle]::Default = $this } # Method to add to profiles [void]AddToProfiles() { [PSColorStyle]::Profiles[$this.Name] = $this } # Static method to get profile static [PSColorStyle]GetProfile([string]$name) { $styleProfile = [PSColorStyle]::Profiles[$name] if ($styleProfile) { return $styleProfile } return $null } # Static method to initialize default profiles static [void]InitializeDefaultProfiles() { # Default profile $defaultProfile = [PSColorStyle]::new("Default", "Gray", $null) [PSColorStyle]::Default = $defaultProfile [PSColorStyle]::Profiles["Default"] = $defaultProfile # Error profile $errorProfile = [PSColorStyle]::new("Error", "Red", $null) $errorProfile.Bold = $true $errorProfile.AddToProfiles() # Warning profile $warningProfile = [PSColorStyle]::new("Warning", "Yellow", $null) $warningProfile.AddToProfiles() # Info profile $infoProfile = [PSColorStyle]::new("Info", "Cyan", $null) $infoProfile.AddToProfiles() # Success profile $successProfile = [PSColorStyle]::new("Success", "Green", $null) $successProfile.AddToProfiles() # Critical profile $criticalProfile = [PSColorStyle]::new("Critical", "White", "DarkRed") $criticalProfile.Bold = $true $criticalProfile.Blink = $true $criticalProfile.AddToProfiles() # Debug profile $debugProfile = [PSColorStyle]::new("Debug", "DarkGray", $null) $debugProfile.Italic = $true $debugProfile.AddToProfiles() # Pre-warm cache for default profiles (performance optimization) $null = $defaultProfile.ToWriteColorParams() $null = $errorProfile.ToWriteColorParams() $null = $warningProfile.ToWriteColorParams() $null = $infoProfile.ToWriteColorParams() $null = $successProfile.ToWriteColorParams() $null = $criticalProfile.ToWriteColorParams() $null = $debugProfile.ToWriteColorParams() } # Method to apply style to Write-ColorEX parameters (with caching) [hashtable]ToWriteColorParams() { # Return cached params if available if ($null -ne $this._cachedParams) { # Return a shallow copy to prevent external modification return $this._cachedParams.Clone() } # Build params hashtable $params = @{} # Important: If Gradient is present, don't include ForegroundColor (gradient takes precedence) if ($this.Gradient -and $this.Gradient.Count -ge 2) { $params['Gradient'] = $this.Gradient } elseif ($this.ForegroundColor) { $params['Color'] = $this.ForegroundColor } if ($this.BackgroundColor) { $params['BackGroundColor'] = $this.BackgroundColor } if ($this.Style.Count -gt 0) { $params['Style'] = $this.Style } if ($this.StartTab -gt 0) { $params['StartTab'] = $this.StartTab } if ($this.StartSpaces -gt 0) { $params['StartSpaces'] = $this.StartSpaces } if ($this.LinesBefore -gt 0) { $params['LinesBefore'] = $this.LinesBefore } if ($this.LinesAfter -gt 0) { $params['LinesAfter'] = $this.LinesAfter } if ($this.Bold) { $params['Bold'] = $true } if ($this.Italic) { $params['Italic'] = $true } if ($this.Underline) { $params['Underline'] = $true } if ($this.Blink) { $params['Blink'] = $true } if ($this.Faint) { $params['Faint'] = $true } if ($this.CrossedOut) { $params['CrossedOut'] = $true } if ($this.DoubleUnderline) { $params['DoubleUnderline'] = $true } if ($this.Overline) { $params['Overline'] = $true } if ($this.ShowTime) { $params['ShowTime'] = $true } if ($this.NoNewLine) { $params['NoNewLine'] = $true } if ($this.HorizontalCenter) { $params['HorizontalCenter'] = $true } if ($this.AutoPad -gt 0) { $params['AutoPad'] = $this.AutoPad } if ($this.PadLeft) { $params['PadLeft'] = $true } if ($this.PadChar -ne ' ') { $params['PadChar'] = $this.PadChar } # Cache for future calls $this._cachedParams = $params return $params.Clone() } # Method to invalidate cache (call after property changes) hidden [void]InvalidateCache() { $this._cachedParams = $null } # Clone method for creating variations # Note: Explicit property copying ensures compatibility with PowerShell 5.1 [PSColorStyle]Clone() { # Clones should not share cache $newStyle = [PSColorStyle]::new($this.Name + "_Copy", $this.ForegroundColor, $this.BackgroundColor) $newStyle._cachedParams = $null $newStyle.Gradient = $this.Gradient $newStyle.Style = $this.Style $newStyle.StartTab = $this.StartTab $newStyle.StartSpaces = $this.StartSpaces $newStyle.LinesBefore = $this.LinesBefore $newStyle.LinesAfter = $this.LinesAfter $newStyle.Bold = $this.Bold $newStyle.Italic = $this.Italic $newStyle.Underline = $this.Underline $newStyle.Blink = $this.Blink $newStyle.Faint = $this.Faint $newStyle.CrossedOut = $this.CrossedOut $newStyle.DoubleUnderline = $this.DoubleUnderline $newStyle.Overline = $this.Overline $newStyle.ShowTime = $this.ShowTime $newStyle.NoNewLine = $this.NoNewLine $newStyle.HorizontalCenter = $this.HorizontalCenter $newStyle.AutoPad = $this.AutoPad $newStyle.PadLeft = $this.PadLeft $newStyle.PadChar = $this.PadChar return $newStyle } } |