ps/Modules/Cole.PowerShell.Developer/Public/Show-Box.ps1
2023-05-30 22:51:22 -07:00

720 lines
30 KiB
PowerShell

function Show-Box {
<#
.SYNOPSIS
Creates a box on screen using similar syntax to CSS
Margin and Padding can be input as in CSS with values in [Top Right Bottom Left] form, where the values for top and bottom are whole numbers only, and for left and right can be percents or integers
Using the more specific values of MarginTop, PaddingLeft, etc, will override the generic Margin or Padding properties specifiers.
When Border is specified, it will apply to all non-overridden values as appropriate.
Specifity overrides generic.
#>
param (
[Parameter(Mandatory = $false)]
[string[]]$TextContent,
[Parameter(Mandatory = $false)]
[string[]]$TitleText,
[Parameter(Mandatory = $false)]
[string]$Width = '100%',
[Parameter(Mandatory = $false)]
[string]$Padding = 1,
[Parameter(Mandatory = $false)]
[string]$Margin = 0,
[Parameter(Mandatory = $false)]
[string]$MarginLeft = $null,
[Parameter(Mandatory = $false)]
[string]$MarginRight = $null,
[Parameter(Mandatory = $false)]
[string]$MarginTop = $null,
[Parameter(Mandatory = $false)]
[string]$MarginBottom = $null,
[Parameter(Mandatory = $false)]
[string]$PaddingLeft = $null,
[Parameter(Mandatory = $false)]
[string]$PaddingRight = $null,
[Parameter(Mandatory = $false)]
[string]$PaddingTop = $null,
[Parameter(Mandatory = $false)]
[string]$PaddingBottom = $null,
[Parameter(Mandatory = $false)]
[ValidateSet('Thin','Thick','Line','Bold','Dotted','Dashed','DottedBold','BoldDashed','Wide','ExtraWide','Double','WideBold','ExtraWideBold','Wavy','None')]
[string]$Border = 'Line',
[Parameter(Mandatory = $false)]
[ValidateSet('Thin','Thick','Line','Bold','Dotted','Dashed','DottedBold','BoldDashed','Wide','ExtraWide','Double','WideBold','ExtraWideBold','Wavy','None')]
[string]$BorderTop,
[Parameter(Mandatory = $false)]
[ValidateSet('Thin','Thick','Line','Bold','Dotted','Dashed','DottedBold','BoldDashed','Wide','ExtraWide','Double','WideBold','ExtraWideBold','Wavy','None')]
[string]$BorderLeft,
[Parameter(Mandatory = $false)]
[ValidateSet('Thin','Thick','Line','Bold','Dotted','Dashed','DottedBold','BoldDashed','Wide','ExtraWide','Double','WideBold','ExtraWideBold','Wavy','None')]
[string]$BorderRight,
[Parameter(Mandatory = $false)]
[ValidateSet('Thin','Thick','Line','Bold','Dotted','Dashed','DottedBold','BoldDashed','Wide','ExtraWide','Double','WideBold','ExtraWideBold','Wavy','None')]
[string]$BorderBottom,
[Parameter(Mandatory = $false)]
[ValidateSet('Black','Blue','Cyan','DarkGray','Green','LightBlue','LightCyan','LightGray','LightGreen','LightMagenta','LightRed','LightYellow','Magenta','Red','White','Yellow','Default')]
[string]$BorderColor = 'Default',
[Parameter(Mandatory = $false)]
[ValidateSet('Black','Blue','Cyan','DarkGray','Green','LightBlue','LightCyan','LightGray','LightGreen','LightMagenta','LightRed','LightYellow','Magenta','Red','White','Yellow','Default')]
[string]$BorderColorTop,
[Parameter(Mandatory = $false)]
[ValidateSet('Black','Blue','Cyan','DarkGray','Green','LightBlue','LightCyan','LightGray','LightGreen','LightMagenta','LightRed','LightYellow','Magenta','Red','White','Yellow','Default')]
[string]$BorderColorLeft,
[Parameter(Mandatory = $false)]
[ValidateSet('Black','Blue','Cyan','DarkGray','Green','LightBlue','LightCyan','LightGray','LightGreen','LightMagenta','LightRed','LightYellow','Magenta','Red','White','Yellow','Default')]
[string]$BorderColorRight,
[Parameter(Mandatory = $false)]
[ValidateSet('Black','Blue','Cyan','DarkGray','Green','LightBlue','LightCyan','LightGray','LightGreen','LightMagenta','LightRed','LightYellow','Magenta','Red','White','Yellow','Default')]
[string]$BorderColorBottom,
[Parameter(Mandatory = $false)]
[ValidateSet('Black','Blue','Cyan','DarkGray','Green','LightBlue','LightCyan','LightGray','LightGreen','LightMagenta','LightRed','LightYellow','Magenta','Red','White','Yellow','Default')]
[string]$TextColor = 'Default',
[Parameter(Mandatory = $false)]
[ValidateSet('Black','Blue','Cyan','DarkGray','Green','LightBlue','LightCyan','LightGray','LightGreen','LightMagenta','LightRed','LightYellow','Magenta','Red','White','Yellow','Default')]
[string]$BackgroundColor = 'Default',
[switch]$UseCornerRadius,
[switch]$Center,
[Parameter(Mandatory = $false)]
[ValidateSet('Left','Center','Right','Justify')]
[string]$TextAlignment = 'Left',
[switch]$TextTruncate
)
$logLead = Get-LogLeadName
$isNumberRegex = "^\d+$"
$isPercentRegex = "^\d+%$"
$screenWidth = Get-ConsoleDisplayWidth
$borderWidthCount = 0
$ResetColor = $PSStyle.Reset
if ($Center) {
# Center flag overrides textAlignment
$TextAlignment = 'Center'
}
if ($TextColor -eq 'Default') {
$_textColor = $ResetColor
} else {
$_textColor = $PSStyle.ForegroundColor.$TextColor
}
if ($BackgroundColor -eq 'Default') {
$_backgroundColor = $ResetColor
} else {
$_backgroundColor = $PSStyle.BackgroundColor.$BackgroundColor
}
#region calculate border colors
if ([string]::IsNullOrWhiteSpace($BorderColorTop)) {
$BorderColorTop = $BorderColor
}
if ([string]::IsNullOrWhiteSpace($BorderColorLeft)) {
$BorderColorLeft = $BorderColor
}
if ([string]::IsNullOrWhiteSpace($BorderColorRight)) {
$BorderColorRight = $BorderColor
}
if ([string]::IsNullOrWhiteSpace($BorderColorBottom)) {
$BorderColorBottom = $BorderColor
}
if ($BorderColorTop -eq 'Default') {
$_borderColorTop = $ResetColor
} else {
$_borderColorTop = $PSStyle.ForegroundColor.$BorderColorTop
}
if ($BorderColorLeft -eq 'Default') {
$_borderColorLeft = $ResetColor
} else {
$_borderColorLeft = $PSStyle.ForegroundColor.$BorderColorLeft
}
if ($BorderColorRight -eq 'Default') {
$_borderColorRight = $ResetColor
} else {
$_borderColorRight = $PSStyle.ForegroundColor.$BorderColorRight
}
if ($BorderColorBottom -eq 'Default') {
$_borderColorBottom = $ResetColor
} else {
$_borderColorBottom = $PSStyle.ForegroundColor.$BorderColorBottom
}
#endregion calculate border colors
#region calculate borders
if ([string]::IsNullOrWhiteSpace($BorderTop)) {
$BorderTop = $Border
}
if ([string]::IsNullOrWhiteSpace($BorderLeft)) {
$BorderLeft = $Border
}
if ([string]::IsNullOrWhiteSpace($BorderRight)) {
$BorderRight = $Border
}
if ([string]::IsNullOrWhiteSpace($BorderBottom)) {
$BorderBottom = $Border
}
$boldLeft = $BorderLeft.EndsWith('Bold')
$boldRight = $BorderRight.EndsWith('Bold')
$boldTop = $BorderTop.EndsWith('Bold')
$boldBottom = $BorderBottom.EndsWith('Bold')
$doubleLeft = $BorderLeft -eq 'Double'
$doubleRight = $BorderRight -eq 'Double'
$doubleTop = $BorderTop -eq 'Double'
$doubleBottom = $BorderBottom -eq 'Double'
$lineLeft = !$boldLeft -and !$doubleLeft
$lineRight = !$boldRight -and !$doubleRight
$lineTop = !$boldTop -and !$doubleTop
$lineBottom = !$boldBottom -and !$doubleBottom
$noneLeft = $BorderLeft -eq 'None'
$noneRight = $BorderRight -eq 'None'
$noneTop = $BorderTop -eq 'None'
$noneBottom = $BorderBottom -eq 'None'
$leftBottomCorner = ""
$leftTopCorner = ""
$rightTopCorner = ""
$rightBottomCorner = ""
if ($noneLeft -and $noneBottom) {
$leftBottomCorner = ""
} elseif ($lineLeft -and $boldBottom) {
$leftBottomCorner = $PSBox.Corner.BottomLeft.BoldHorizontal
} elseif ($boldLeft -and $lineBottom) {
$leftBottomCorner = $PSBox.Corner.BottomLeft.BoldVertical
} elseif ($boldLeft -and $boldBottom) {
$leftBottomCorner = $PSBox.Corner.BottomLeft.Bold
} elseif ($lineLeft -and $doubleBottom) {
$leftBottomCorner = $PSBox.Corner.BottomLeft.DoubleHorizontal
} elseif ($doubleLeft -and $lineBottom) {
$leftBottomCorner = $PSBox.Corner.BottomLeft.DoubleVertical
} elseif ($doubleLeft -and $doubleBottom) {
$leftBottomCorner = $PSBox.Corner.BottomLeft.Double
} else {
$leftBottomCorner = $PSBox.Corner.BottomLeft.Line
}
if ($noneRight -and $noneBottom) {
$rightBottomCorner = ""
} elseif ($lineRight -and $boldBottom) {
$rightBottomCorner = $PSBox.Corner.BottomRight.BoldHorizontal
} elseif ($boldRight -and $lineBottom) {
$rightBottomCorner = $PSBox.Corner.BottomRight.BoldVertical
} elseif ($boldRight -and $boldBottom) {
$rightBottomCorner = $PSBox.Corner.BottomRight.Bold
} elseif ($lineRight -and $doubleBottom) {
$rightBottomCorner = $PSBox.Corner.BottomRight.DoubleHorizontal
} elseif ($doubleRight -and $lineBottom) {
$rightBottomCorner = $PSBox.Corner.BottomRight.DoubleVertical
} elseif ($doubleRight -and $doubleBottom) {
$rightBottomCorner = $PSBox.Corner.BottomRight.Double
} else {
$rightBottomCorner = $PSBox.Corner.BottomRight.Line
}
if ($noneLeft -and $noneTop) {
$leftTopCorner = ""
} elseif ($lineLeft -and $boldTop) {
$leftTopCorner = $PSBox.Corner.TopLeft.BoldHorizontal
} elseif ($boldLeft -and $lineTop) {
$leftTopCorner = $PSBox.Corner.TopLeft.BoldVertical
} elseif ($boldLeft -and $boldTop) {
$leftTopCorner = $PSBox.Corner.TopLeft.Bold
} elseif ($lineLeft -and $doubleTop) {
$leftTopCorner = $PSBox.Corner.TopLeft.DoubleHorizontal
} elseif ($doubleLeft -and $lineTop) {
$leftTopCorner = $PSBox.Corner.TopLeft.DoubleVertical
} elseif ($doubleLeft -and $doubleTop) {
$leftTopCorner = $PSBox.Corner.TopLeft.Double
} else {
$leftTopCorner = $PSBox.Corner.TopLeft.Line
}
if ($noneRight -and $noneTop) {
$rightTopCorner = ""
} elseif ($lineRight -and $boldTop) {
$rightTopCorner = $PSBox.Corner.TopRight.BoldHorizontal
} elseif ($boldRight -and $lineTop) {
$rightTopCorner = $PSBox.Corner.TopRight.BoldVertical
} elseif ($boldRight -and $boldTop) {
$rightTopCorner = $PSBox.Corner.TopRight.Bold
} elseif ($lineRight -and $doubleTop) {
$rightTopCorner = $PSBox.Corner.TopRight.DoubleHorizontal
} elseif ($doubleRight -and $lineTop) {
$rightTopCorner = $PSBox.Corner.TopRight.DoubleVertical
} elseif ($doubleRight -and $doubleTop) {
$rightTopCorner = $PSBox.Corner.TopRight.Double
} else {
# always curve down
$rightTopCorner = $PSBox.Corner.TopRight.Line
}
# TODO: Make the adjoining lines always transition from thin to thick where possible
if ($UseCornerRadius) {
$leftBottomCorner = $PSBox.Corner.BottomLeft.Round
$leftTopCorner = $PSBox.Corner.TopLeft.Round
$rightTopCorner = $PSBox.Corner.TopRight.Round
$rightBottomCorner = $PSBox.Corner.BottomRight.Round
}
$topBorderCharacters = switch ($BorderTop) {
'Thin' { $PSBox.Horizontal.Line }
'Line' { $PSBox.Horizontal.Line }
'Thick' { $PSBox.Horizontal.Bold }
'Bold' { $PSBox.Horizontal.Bold }
'Dotted' { $PSBox.Horizontal.DashedNarrow }
'Dashed' { $PSBox.Horizontal.Dashed }
'DottedBold' { $PSBox.Horizontal.BoldDashedNarrow }
'BoldDashed' { $PSBox.Horizontal.BoldDashed }
'Wide' { $PSBox.Horizontal.DashedWide }
'ExtraWide' { $PSBox.Horizontal.LeftHalf,$PSBox.Horizontal.RightHalf }
'Double' { $PSBox.Horizontal.Double }
'WideBold' { $PSBox.Horizontal.BoldDashedWide }
'ExtraWideBold' { $PSBox.Horizontal.BoldLeftHalf,$PSBox.Horizontal.BoldRightHalf }
'Wavy' { $PSBox.Horizontal.BoldRightThinLeft }
'None' { "" }
}
$bottomBorderCharacters = switch ($BorderBottom) {
'Thin' { $PSBox.Horizontal.Line }
'Line' { $PSBox.Horizontal.Line }
'Thick' { $PSBox.Horizontal.Bold }
'Bold' { $PSBox.Horizontal.Bold }
'Dotted' { $PSBox.Horizontal.DashedNarrow }
'Dashed' { $PSBox.Horizontal.Dashed }
'DottedBold' { $PSBox.Horizontal.BoldDashedNarrow }
'BoldDashed' { $PSBox.Horizontal.BoldDashed }
'Wide' { $PSBox.Horizontal.DashedWide }
'ExtraWide' { $PSBox.Horizontal.LeftHalf,$PSBox.Horizontal.RightHalf }
'Double' { $PSBox.Horizontal.Double }
'WideBold' { $PSBox.Horizontal.BoldDashedWide }
'ExtraWideBold' { $PSBox.Horizontal.BoldLeftHalf,$PSBox.Horizontal.BoldRightHalf }
'Wavy' { $PSBox.Horizontal.BoldRightThinLeft }
'None' { "" }
}
$leftBorderCharacters = switch ($BorderLeft) {
'Thin' { $PSBox.Vertical.Line }
'Line' { $PSBox.Vertical.Line }
'Thick' { $PSBox.Vertical.Bold }
'Bold' { $PSBox.Vertical.Bold }
'Dotted' { $PSBox.Vertical.DashedNarrow }
'Dashed' { $PSBox.Vertical.Dashed }
'DottedBold' { $PSBox.Vertical.BoldDashedNarrow }
'BoldDashed' { $PSBox.Vertical.BoldDashed }
'Wide' { $PSBox.Vertical.DashedWide }
'ExtraWide' { $PSBox.Vertical.DashedWide }
'Double' { $PSBox.Vertical.Double }
'WideBold' { $PSBox.Vertical.BoldDashedWide }
'ExtraWideBold' { $PSBox.Vertical.Bold }
'Wavy' { $PSBox.Vertical.BoldBottomThinTop }
'None' { "" }
}
$rightBorderCharacters = switch ($BorderRight) {
'Thin' { $PSBox.Vertical.Line }
'Line' { $PSBox.Vertical.Line }
'Thick' { $PSBox.Vertical.Bold }
'Bold' { $PSBox.Vertical.Bold }
'Dotted' { $PSBox.Vertical.DashedNarrow }
'Dashed' { $PSBox.Vertical.Dashed }
'DottedBold' { $PSBox.Vertical.BoldDashedNarrow }
'BoldDashed' { $PSBox.Vertical.BoldDashed }
'Wide' { $PSBox.Vertical.DashedWide }
'ExtraWide' { $PSBox.Vertical.DashedWide }
'Double' { $PSBox.Vertical.Double }
'WideBold' { $PSBox.Vertical.BoldDashedWide }
'ExtraWideBold' { $PSBox.Vertical.Bold }
'Wavy' { $PSBox.Vertical.BoldBottomThinTop }
'None' { "" }
}
if (![string]::IsNullOrWhiteSpace($leftBorderCharacters)) {
$borderWidthCount += 1
}
if (![string]::IsNullOrWhiteSpace($rightBorderCharacters)) {
$borderWidthCount += 1
}
$screenWidth = $screenWidth - $borderWidthCount # account for the vertical bars themselves
#endregion calculate borders
#region calculate margins
$Margin = "$Margin".Trim()
$marginIsNumber = $Margin -match $isNumberRegex
$marginSplits = ($Margin -split '\s+')
$marginHasFourParts = $marginSplits.Count -eq 4
$marginHasTwoParts = $marginSplits.Count -eq 2
if ($marginSplits.Count -gt 1) {
if ($marginHasFourParts) {
$_marginTop = $marginSplits[0]
$_marginRight = $marginSplits[1]
$_marginBottom = $marginSplits[2]
$_marginLeft = $marginSplits[3]
} elseif ($marginHasTwoParts) {
$_marginTop = $marginSplits[0]
$_marginRight = $marginSplits[1]
$_marginBottom = $marginSplits[0]
$_marginLeft = $marginSplits[1]
} else {
throw "$logLead : Margin should be specified in four parts, representing in-order [Top Right Bottom Left], or in two parts [vertical horizontal]"
}
} else {
# There's only one value, so we can just assign it to the internals before it gets overwritten
$_marginTop = $Margin
$_marginBottom = $Margin
$_marginRight = $Margin
$_marginLeft = $Margin
}
if (![string]::IsNullOrWhiteSpace("$MarginTop")) {
$_marginTop = $MarginTop
}
if (![string]::IsNullOrWhiteSpace("$MarginRight")) {
$_marginRight = $MarginRight
}
if (![string]::IsNullOrWhiteSpace("$MarginBottom")) {
Write-Host "setting margin bottom to $MarginBottom"
$_marginBottom = $MarginBottom
}
if (![string]::IsNullOrWhiteSpace("$MarginLeft")) {
$_marginLeft = $MarginLeft
}
#region calculate top margin
if ($null -ne $_marginTop) {
if ($_marginTop -notmatch $isNumberRegex) {
throw "$logLead : Margin Top should be a whole number, not a percent or non-numeric value"
} else {
$_marginTop = [int]$_marginTop
}
} else {
$_marginTop = 0
}
#endregion calculate top margin
#region calculate right margin
if ($null -ne $_marginRight) {
$_marginRightIsNumber = $_marginRight -match $isNumberRegex
$_marginRightIsPercent = $_marginRight -match $isPercentRegex
if (!$_marginRightIsNumber -and !$_marginRightIsPercent) {
throw "$logLead : Right margin should be specified as a percent or a whole number"
}
if ($_marginRightIsNumber) {
$_marginRight = [int]$_marginRight
}
if ($_marginRightIsPercent) {
$_marginRight = [System.Math]::Round((([int]($_marginRight.Substring(0,$_marginRight.Length - 1)) * $screenWidth )/ 100.0))
}
} else {
$_marginRight = 0
}
#endregion calculate right margin
#region calculate bottom margin
if ($null -ne $_marginBottom) {
if ($_marginBottom -notmatch $isNumberRegex) {
throw "$logLead : Margin bottom should be a whole number, not a percent or non-numeric value"
} else {
$_marginBottom = [int]$_marginBottom
}
} else {
$_marginBottom = 0
}
#endregion calculate bottom margin
#region calculate left margin
if ($null -ne $_marginLeft) {
$_marginLeftIsNumber = $_marginLeft -match $isNumberRegex
$_marginLeftIsPercent = $_marginLeft -match $isPercentRegex
if (!$_marginLeftIsNumber -and !$_marginLeftIsPercent) {
throw "$logLead : Left margin should be specified as a percent or a whole number"
}
if ($_marginLeftIsNumber) {
$_marginLeft = [int]$_marginLeft
}
if ($_marginLeftIsPercent) {
$_marginLeft = [System.Math]::Round((([int]($_marginLeft.Substring(0,$_marginLeft.Length - 1)) * $screenWidth )/ 100.0))
}
} else {
$_marginLeft = 0
}
#endregion calculate left margin
#endregion calculate margins
#region calculate paddings
$Padding = "$Padding".Trim()
$paddingIsNumber = $Padding -match $isNumberRegex
$paddingSplits = ($Padding -split '\s+')
$paddingHasFourParts = $paddingSplits.Count -eq 4
$paddingHasTwoParts = $paddingSplits.Count -eq 2
if ($paddingSplits.Count -gt 1) {
if ($paddingHasFourParts) {
$_paddingTop = $paddingSplits[0]
$_paddingRight = $paddingSplits[1]
$_paddingBottom = $paddingSplits[2]
$_paddingLeft = $paddingSplits[3]
} elseif ($paddingHasTwoParts) {
$_paddingTop = $paddingSplits[0]
$_paddingRight = $paddingSplits[1]
$_paddingBottom = $paddingSplits[0]
$_paddingLeft = $paddingSplits[1]
} else {
throw "$logLead : Padding should be specified in four parts, representing in-order [Top Right Bottom Left], or in two parts [vertical horizontal]"
}
} else {
# There's only one value, so we can just assign it to the internals before it gets overwritten
$_paddingTop = $Padding
$_paddingBottom = $Padding
$_paddingRight = $Padding
$_paddingLeft = $Padding
}
if (![string]::IsNullOrWhiteSpace("$PaddingTop")) {
$_paddingTop = $PaddingTop
}
if (![string]::IsNullOrWhiteSpace("$PaddingRight")) {
$_paddingRight = $PaddingRight
}
if (![string]::IsNullOrWhiteSpace("$PaddingBottom")) {
$_paddingBottom = $PaddingBottom
}
if (![string]::IsNullOrWhiteSpace("$PaddingLeft")) {
$_paddingLeft = $PaddingLeft
}
#region calculate box width
$boxWidth = $screenWidth - $_marginLeft - $_marginRight
$widthIsNumber = $Width -match $isNumberRegex
$widthIsPercent = $Width -match $isPercentRegex
if ($widthIsNumber) {
$boxWidth = [int]$Width
if ($boxWidth -gt $screenWidth) {
$boxWidth = $screenWidth
}
}
if ($widthIsPercent) {
$boxWidth = [System.Math]::Round((([int]($Width.Substring(0,$Width.Length - 1)) * $boxWidth )/ 100.0))
}
if (!$widthIsNumber -and !$widthIsPercent) {
throw "$logLead : Width parameter must be an int or a percent expressed as an integer and percent sign. Examples: 10, 25%, 100"
}
#endregion calculate box width
#region calculate top padding
if ($null -ne $_paddingTop) {
if ($_paddingTop -notmatch $isNumberRegex) {
throw "$logLead : Padding Top should be a whole number, not a percent or non-numeric value"
} else {
$_paddingTop = [int]$_paddingTop
}
} else {
$_paddingTop = 0
}
#endregion calculate top padding
#region calculate right padding
if ($null -ne $_paddingRight) {
$_paddingRightIsNumber = $_paddingRight -match $isNumberRegex
$_paddingRightIsPercent = $_paddingRight -match $isPercentRegex
if (!$_paddingRightIsNumber -and !$_paddingRightIsPercent) {
throw "$logLead : Right padding should be specified as a percent or a whole number"
}
if ($_paddingRightIsNumber) {
$_paddingRight = [int]$_paddingRight
}
if ($_paddingRightIsPercent) {
$_paddingRight = [System.Math]::Round((([int]($_paddingRight.Substring(0,$_paddingRight.Length - 1)) * $boxWidth )/ 100.0))
}
} else {
$_paddingRight = 0
}
#endregion calculate right padding
#region calculate bottom padding
if ($null -ne $_paddingBottom) {
if ($_paddingBottom -notmatch $isNumberRegex) {
throw "$logLead : Padding bottom should be a whole number, not a percent or non-numeric value"
} else {
$_paddingBottom = [int]$_paddingBottom
}
} else {
$_paddingBottom = 0
}
#endregion calculate bottom padding
#region calculate left padding
if ($null -ne $_paddingLeft) {
$_paddingLeftIsNumber = $_paddingLeft -match $isNumberRegex
$_paddingLeftIsPercent = $_paddingLeft -match $isPercentRegex
if (!$_paddingLeftIsNumber -and !$_paddingLeftIsPercent) {
throw "$logLead : Left padding should be specified as a percent or a whole number"
}
if ($_paddingLeftIsNumber) {
$_paddingLeft = [int]$_paddingLeft
}
if ($_paddingLeftIsPercent) {
$_paddingLeft = [System.Math]::Round((([int]($_paddingLeft.Substring(0,$_paddingLeft.Length - 1)) * $boxWidth )/ 100.0))
}
} else {
$_paddingLeft = 0
}
#endregion calculate left padding
#endregion calculate paddings
#region calculate content width
$TextContentWidth = $boxWidth - $_paddingLeft - $_paddingRight
if ($TextContentWidth -lt 5) {
throw "$logLead : The calculated contentWidth is too narrow. Make your width larger, or your padding smaller"
}
#endregion calculate content width
$leftMargin = "".PadRight($_marginLeft)
$leftPadding = "".PadRight($_paddingLeft)
$rightMargin = "".PadRight($_marginRight)
$rightPadding = "".PadRight($_paddingRight)
$output = @()
$paddingLine = "".PadRight($TextContentWidth, ' ')
$topLine = ($topBorderCharacters * $boxWidth)
$bottomLine = ($bottomBorderCharacters * $boxWidth)
$TextContentRows = @()
if ($TextTruncate) {
foreach ($row in $TextContent) {
$TextContentRows += $row.PadRight($TextContentWidth).Substring(0,$TextContentWidth)
}
} else {
for ($i = 0; $i -lt $TextContent.Count; $i++) {
$row = $TextContent[$i]
$paddedLine = "".PadRight($TextContentWidth - (Remove-TextStyle -Text $row).Length, ' ')
$paddedLine = "$row$paddedLine"
while ($row.Length -gt $TextContentWidth) {
$reWidth = [Math]::Min($row.Length,$TextContentWidth) -1
$lastSpace = $row.Substring(0,$reWidth).LastIndexOf(' ')
if ($lastSpace -eq -1) {
# No spaces in $TextContentWidth of space, so just chop it off at $TextContentWidth
$TextContentRows += $row.Substring(0, $reWidth)
$row = $row.Substring($reWidth)
} else {
$TextContentRows += $row.Substring(0, $lastSpace).Trim()
$row = $row.Substring($lastSpace).Trim()
}
}
$TextContentRows += $row
}
}
for ($i = 0; $i -lt $_marginTop; $i++) {
$output += ""
}
# draw top line
$output += "$leftMargin$_borderColorTop$leftTopCorner$topLine$rightTopCorner$ResetColor$rightMargin"
if ($TitleText.Count -gt 0) {
foreach ($titleLine in $TitleText) {
$paddedLine = ""
if ($TextAlignment -eq 'Left') {
$paddedLine = "".PadRight($TextContentWidth - (Remove-TextStyle -Text $titleLine).Length, ' ')
$paddedLine = "$titleLine$paddedLine"
} elseif ($TextAlignment -eq 'Center') {
$rowLength = (Remove-TextStyle -Text $titleLine).Length
$rowDifference = $TextContentWidth - $rowLength
$rowLead = [Math]::Floor($rowDifference / 2)
$rowTrail = $rowDifference - $rowLead
$prefix = "".PadRight($rowLead)
$suffix = "".PadRight($rowTrail)
$paddedLine = "$prefix$row$suffix"
} elseif ($TextAlignment -eq 'Right') {
$paddedLine = "".PadRight($TextContentWidth - (Remove-TextStyle -Text $titleLine).Length, ' ')
$paddedLine = "$paddedLine$titleLine"
} else {
# Justify text
$paddedLine = Format-TextJustified -MaxWidth $TextContentWidth -Words $TitleText
}
$output += "$leftMargin$_borderColorLeft$leftBorderCharacters$ResetColor$_backgroundColor$leftPadding$ResetColor$_backgroundColor$_textColor$($PSStyle.Bold)$paddedLine$ResetColor$_backgroundColor$rightPadding$ResetColor$_borderColorRight$rightBorderCharacters$ResetColor$rightMargin"
}
$lineWidth = $boxWidth
if (![string]::IsNullOrWhiteSpace($leftBorderCharacters)) {
$lineWidth += 1
}
if (![string]::IsNullOrWhiteSpace($rightBorderCharacters)) {
$lineWidth += 1
}
$lineStyle = @{
WithEndcaps = $true
Color = $BorderColorTop
Width = $lineWidth
WithBoldEndcaps = $BorderTop -contains 'Bold'
Style = $BorderTop
}
$output += Show-Line -WithEndcaps -Color $BorderColorTop -Width $lineWidth -WithBoldEndcaps
}
# render paddingTop
for ($i = 0; $i -lt $_paddingTop; $i++) {
$output += "$leftMargin$_borderColorLeft$leftBorderCharacters$ResetColor$_backgroundColor$leftPadding$paddingLine$rightPadding$ResetColor$_borderColorRight$rightBorderCharacters$ResetColor$rightMargin"
}
# render content
<#
foreach ($row in $TextContentRows) {
$paddedLine = ""
if ($TextAlignment -eq 'Left') {
$paddedLine = "".PadRight($TextContentWidth - (Remove-TextStyle -Text $titleLine).Length, ' ')
$paddedLine = "$row$paddedLine"
} elseif ($TextAlignment -eq 'Center') {
$rowLength = (Remove-TextStyle -Text $row).Length
$rowDifference = $TextContentWidth - $rowLength
$rowLead = [Math]::Floor($rowDifference / 2)
$rowTrail = $rowDifference - $rowLead
$prefix = "".PadRight($rowLead)
$suffix = "".PadRight($rowTrail)
$paddedLine = "$prefix$row$suffix"
} elseif ($TextAlignment -eq 'Right') {
$paddedLine = "".PadRight($TextContentWidth - (Remove-TextStyle -Text $titleLine).Length, ' ')
$paddedLine = "$paddedLine$row"
} else {
# Justify text
$paddedLine = Format-TextJustified -MaxWidth $TextContentWidth -Words $row
}
$output += "$leftMargin$_borderColorLeft$leftBorderCharacters$ResetColor$_backgroundColor$leftPadding$ResetColor$_backgroundColor$_textColor$paddedLine$ResetColor$_backgroundColor$rightPadding$ResetColor$_borderColorRight$rightBorderCharacters$ResetColor$rightMargin"
}
#>
foreach ($row in $contentRows) {
$paddedLine = ""
if ($TextAlignment -eq 'Left') {
$paddedLine = $row.PadRight($contentWidth, ' ')
} elseif ($TextAlignment -eq 'Center') {
$rowLength = $row.Length
$rowDifference = $contentWidth - $row.Length
$rowLead = [Math]::Floor($rowDifference / 2)
$rowTrail = $rowDifference - $rowLead
$prefix = "".PadRight($rowLead)
$suffix = "".PadRight($rowTrail)
$paddedLine = "$prefix$row$suffix"
} elseif ($TextAlignment -eq 'Right') {
$paddedLine = $row.PadLeft($contentWidth, ' ')
} else {
# Justify text
$paddedLine = Format-TextJustified -MaxWidth $contentWidth -Words $row
}
$output += "$leftMargin$_borderColorLeft$leftBorderCharacters$ResetColor$_backgroundColor$leftPadding$ResetColor$_backgroundColor$_textColor$paddedLine$ResetColor$_backgroundColor$rightPadding$ResetColor$_borderColorRight$rightBorderCharacters$ResetColor$rightMargin"
}
# render paddingBottom
for ($i = 0; $i -lt $_paddingBottom; $i++) {
$output += "$leftMargin$_borderColorLeft$leftBorderCharacters$ResetColor$_backgroundColor$leftPadding$paddingLine$rightPadding$ResetColor$_borderColorRight$rightBorderCharacters$ResetColor$rightMargin"
}
# draw bottom line
$output += "$leftMargin$_borderColorBottom$leftBottomCorner$bottomLine$rightBottomCorner$ResetColor$rightMargin"
for ($i = 0; $i -lt $_marginBottom; $i++) {
$output += ""
}
$output
}