Instantly share code, notes, and snippets.
Last active
August 19, 2019 17:48
-
Star
(3)
3
You must be signed in to star a gist -
Fork
(1)
1
You must be signed in to fork a gist
-
Save QuietusPlus/59d8612ec13ea929704542eb0bd8d52c to your computer and use it in GitHub Desktop.
This file contains 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
<# | |
NOTICE | |
Write-Menu has been moved to it's own repository located at: | |
https://github.com/QuietusPlus/Write-Menu | |
#> | |
function Write-Menu { | |
<# | |
.NOTES | |
Write-Menu (v1.0) | |
by QuietusPlus | |
LICENSE: This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. | |
Based on "Simple Textbased Powershell Menu" by Michael Albert [info@michlstechblog.info] | |
.SYNOPSIS | |
Outputs a command-line menu, which can be navigated using the keyboard. | |
.DESCRIPTION | |
Outputs a command-line menu, which can be navigated using the keyboard. | |
Controls Description | |
-------- ----------- | |
Arrow Up + Down Change selection | |
Arrow Left + Right Switch pages | |
Enter Confirm selection | |
Escape Exit menu | |
.PARAMETER Items | |
Menu entries. | |
.PARAMETER Title | |
Title shown at the top. | |
.PARAMETER Page | |
Page to display. | |
.EXAMPLE | |
PS > $choice = Write-Menu -Title 'Test Menu' -Entries @('Test Object 1', 'Test Object 2', 'Test Object 3', 'Test Object 4') | |
Menu Title | |
Menu Option 1 | |
Menu Option 2 | |
Menu Option 3 | |
Menu Option 4 | |
Page 1 / 1 | |
.LINK | |
https://github.com/QuietusPlus/Write-Menu | |
#> | |
[CmdletBinding()] | |
<# | |
Parameters | |
#> | |
param ( | |
[Parameter(ValueFromPipeline = $true)] | |
[Alias('Items')] | |
$Entries, | |
[Parameter(ValueFromPipelineByPropertyName = $true)] | |
[Alias('Name')] | |
$Title, | |
[Parameter(ValueFromPipelineByPropertyName = $true)] | |
[System.Int16]$Page | |
) | |
# Clear screen | |
Clear-Host | |
# Check if parameters have been passed | |
if ($Entries -like $null) { return } | |
if ($Page -like $null) { $Page = 0 } | |
if ($Title -notlike $null) { | |
[System.Console]::WriteLine("`n " + $Title + "`n") # Display title | |
$pageListSize = ($host.UI.RawUI.WindowSize.Height - 7) # Set menu height | |
} else { | |
[System.Console]::WriteLine('') # Skip title display | |
$pageListSize = ($host.UI.RawUI.WindowSize.Height - 5) # Set menu height | |
} | |
<# | |
Colours | |
#> | |
$colorForegroundSaved = [System.Console]::ForegroundColor; $colorBackgroundSaved = [System.Console]::BackgroundColor # Save original colours | |
$colorForeground = $colorForegroundSaved; $colorBackground = $colorBackgroundSaved # Set colours, modify this to change colours | |
$colorForegroundSelected = $colorBackground; $colorBackgroundSelected = $colorForeground # Set inverted colours | |
<# | |
Initialisation | |
#> | |
# Amount of entries in total | |
$entriesTotal = $Entries.Length | |
# First entry of page (location within entire array) | |
$pageFirstEntry = ($pageListSize * $Page) | |
# Total pages | |
$pageTotal = [math]::Ceiling((($entriesTotal - $pageListSize) / $pageListSize)) | |
# Amount of entries on last page | |
if ($Page -eq $pageTotal) { $pageEntriesCount = ($entriesTotal - ($pageListSize * $pageTotal)) | |
# Amount of entries on fully populated page | |
} else { $pageEntriesCount = $pageListSize } | |
# Position within console | |
$positionCurrent = 0 | |
$positionSelected = 0 | |
$positionTotal = 0 | |
$positionTop = [System.Console]::CursorTop | |
# Get entries for current page | |
$pageEntries = @() | |
foreach ($i in 0..$pageListSize) { | |
$pageEntries += $Entries[($pageFirstEntry + $i)] | |
} | |
<# | |
Write Page | |
#> | |
do { | |
$menuLoop = $true | |
[System.Console]::CursorTop = ($positionTop - $positionTotal) | |
for ($positionCurrent = 0; $positionCurrent -le ($pageEntriesCount - 1); $positionCurrent++) { | |
# Replace previous line | |
[System.Console]::Write("`r") | |
# If selected, invert colours | |
if ($positionCurrent -eq $positionSelected) { [System.Console]::BackgroundColor = $colorBackgroundSelected; [System.Console]::ForegroundColor = $colorForegroundSelected } | |
# Write entry | |
[System.Console]::Write(' ' + $pageEntries[$positionCurrent] + ' ') | |
# Reset colours | |
[System.Console]::BackgroundColor = $colorBackground; [System.Console]::ForegroundColor = $colorForeground | |
# Empty line | |
[System.Console]::WriteLine('') | |
} | |
# Write page indicator | |
[System.Console]::WriteLine("`n Page $($Page + 1) / $($pageTotal + 1)`n") | |
<# | |
User Input | |
#> | |
# Read key input | |
$menuInput = [System.Console]::ReadKey($true) | |
# Arrow down | |
if (($menuInput.Key -eq 'DownArrow') -and ($positionSelected -lt ($pageEntriesCount - 1))) { $positionSelected++ | |
# Arrow up | |
} elseif (($menuInput.Key -eq 'UpArrow') -and ($positionSelected -gt 0)) { $positionSelected-- | |
# Enter | |
} elseif ($menuInput.Key -eq 'Enter') { $menuLoop = $false | |
# Escape | |
} elseif ($menuInput.Key -eq 'Escape') { $menuLoop = $false | |
# Arrow left | |
} elseif ($menuInput.Key -eq 'LeftArrow') { if ($Page -ne 0) { $Page--; $menuLoop = $false } | |
# Arrow right | |
} elseif ($menuInput.Key -eq 'RightArrow') { if ($Page -ne $pageTotal) { $Page++; $menuLoop = $false } } | |
} while ($menuLoop) | |
# Finish operations for pressed key | |
if ($menuInput.Key -eq 'Escape') { | |
Clear-Host; return | |
} elseif ($menuInput.Key -eq 'Enter') { | |
Clear-Host; return ($pageEntries[$positionSelected]) | |
} elseif (($menuInput.Key -eq 'LeftArrow') -or ($menuInput.Key -eq 'RightArrow')) { | |
Clear-Host | |
if ($Title -notlike $null) { # Check if title has previously been passed | |
Write-Menu -Entries $Entries -Page $Page -Title $Title | |
} else { # If not, skip title | |
Write-Menu -Entries $Entries -Page $Page | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
NOTICE
Write-Menu has been moved to it's own repository, which means this gist will no longer be updated!
Please use/visit https://github.com/QuietusPlus/Write-Menu instead...