Instantly share code, notes, and snippets.
Created
April 8, 2019 17:18
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save purplemonkeymad/98ee05f4701246b454b16ab9ff542d98 to your computer and use it in GitHub Desktop.
Arrow key menu.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Draw-Menu { | |
| [CmdletBinding()] | |
| param ( | |
| [Parameter(Mandatory=$true)] | |
| [pscustomobject]$menuState | |
| ) | |
| begin { | |
| } | |
| process { | |
| if ($menuState.Items.count -eq 0){ | |
| return | |
| } | |
| # start draw | |
| [System.Console]::CursorTop = $menuState.CursorTop | |
| [System.Console]::CursorLeft = 0 # start on the left | |
| Write-Verbose ([System.Console]::CursorTop) | |
| $row = 1 | |
| $column = 1 | |
| $index = 0 | |
| foreach ($item in $menuState.Items){ | |
| if ($index -eq $menuState.Selected){ | |
| Write-Host -BackgroundColor ([system.console]::ForegroundColor) -ForegroundColor ([System.Console]::BackgroundColor) -NoNewline ( | |
| $item.PadRight($menuState.ColumnWidth) | |
| ) | |
| } else { | |
| Write-Host -BackgroundColor ([system.console]::BackgroundColor) -ForegroundColor ([System.Console]::ForegroundColor) -NoNewline ( | |
| $item.PadRight($menuState.ColumnWidth) | |
| ) | |
| } | |
| $column++ | |
| $index++ | |
| if ($column -gt $menuState.Columns){ | |
| $row++ | |
| $column = 1 | |
| Write-Host '' | |
| } | |
| } | |
| Write-Verbose ([System.Console]::CursorTop) | |
| } | |
| end { | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Show-ChoiceConsoleMenu { | |
| [CmdletBinding()] | |
| param ( | |
| [String[]]$ItemList | |
| ) | |
| begin { | |
| # create a state object with defaults | |
| $MenuState = New-Object pscustomobject -Property @{ | |
| CursorTop = [System.Console]::CursorTop | |
| Selected = 0 | |
| Columns = 1 | |
| ColumnWidth = [System.Console]::BufferWidth # default | |
| Items = $ItemList | |
| Rows = 0 #never used but might be nice to have | |
| } | |
| # calculate display grid. | |
| $ItemMaxLength = 0 | |
| foreach ( $Item in $ItemList){ | |
| $ItemMaxLength = [math]::Max($Item.length,$ItemMaxLength) | |
| } | |
| $ItemMaxLength++ # create a single char buffer between columns | |
| if ($ItemMaxLength -lt [System.Console]::BufferWidth){ | |
| $MenuState.ColumnWidth = $ItemMaxLength | |
| } | |
| $MenuState.Columns = [int]([Math]::Max( | |
| [Math]::Floor( ( [System.Console]::BufferWidth / $ItemMaxLength ) ) | |
| , 1 ) ) | |
| $MenuState.Rows = [int][Math]::Ceiling( ($ItemList.Count / $MenuState.Columns) ) | |
| if ( [System.Console]::CursorTop + $MenuState.Rows -ge [System.Console]::BufferHeight ) { | |
| if ((Read-Host "No enough buffer to show menu, clear screen? (Y/n)") -match '[nN][oO]?'){ | |
| Write-Warning "Console Buffer full, menu will act funny." | |
| } else { | |
| Clear-Host | |
| } | |
| $MenuState.Cursortop = [System.Console]::CursorTop | |
| } | |
| } | |
| process { | |
| # main iteraction loop | |
| [System.console]::CursorVisible=$false | |
| do { | |
| Draw-Menu $MenuState | |
| Write-Verbose $MenuState.Selected | |
| $CursorBottom = [System.Console]::CursorTop | |
| $MenuKey = [System.Console]::ReadKey($true) | |
| $MenuState = Update-MenuStateByKey -MenuState $MenuState -Key $MenuKey.Key | |
| } while ($MenuKey.Key -ne [System.ConsoleKey]::Enter -and $MenuKey.Key -ne [System.ConsoleKey]::Escape) | |
| # clear menu | |
| $RowsToClear = $CursorBottom - $MenuState.CursorTop +1 | |
| [System.Console]::CursorTop = $MenuState.CursorTop | |
| [System.Console]::CursorLeft = 0 | |
| for ($ClearRow=0;$ClearRow -lt $RowsToClear;$ClearRow++){ | |
| Write-Host (''.PadRight( [System.Console]::BufferWidth, [char]160 ) ) #nbsp | |
| } | |
| # move cursor back to top, to stop big gap | |
| [System.Console]::CursorTop = $MenuState.CursorTop | |
| [System.console]::CursorVisible=$true | |
| } | |
| end { | |
| if ($MenuKey.Key -eq [System.ConsoleKey]::Enter) { | |
| return $ItemList[$MenuState.Selected] | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Update-MenuStateByKey { | |
| [CmdletBinding()] | |
| param ( | |
| [pscustomobject]$MenuState, | |
| [System.ConsoleKey]$Key | |
| ) | |
| begin { | |
| } | |
| process { | |
| Write-Verbose $Key | |
| switch ($Key){ | |
| ([System.ConsoleKey]::RightArrow) { | |
| $MenuState.Selected = $MenuState.Selected + 1 | |
| } | |
| ([System.ConsoleKey]::LeftArrow) { | |
| $MenuState.Selected = $MenuState.Selected - 1 | |
| } | |
| ([System.ConsoleKey]::UpArrow) { | |
| $MenuState.Selected = $MenuState.Selected - $MenuState.Columns | |
| } | |
| ([System.ConsoleKey]::DownArrow) { | |
| $MenuState.Selected = $MenuState.Selected + $MenuState.Columns | |
| } | |
| } | |
| # now do some bad value correcting | |
| if ($MenuState.Selected -gt ($MenuState.Items.Count -1 )){ | |
| $MenuState.Selected = $MenuState.Items.Count -1 #count is 1 indexed | |
| } | |
| if ($MenuState.Selected -lt 0){ | |
| $MenuState.Selected = 0 | |
| } | |
| } | |
| end { | |
| return $MenuState | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment