iNNOKENTIY21
Silver Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Код: class Menu { #region Params [int] $Left = 4 [int] $Top = 2 [int] $Width = 30 [int] $Height = 10 [int] $Current = 0 [int] $ViewStart = 0 [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string[]] $Items $Selected = [System.Collections.Generic.List[int]]::new() $Background = [ConsoleColor]::Black $Foreground = [ConsoleColor]::Gray $CurrentBackground = [ConsoleColor]::DarkGray $CurrentForeground = [ConsoleColor]::White $SelectedBackground = [ConsoleColor]::DarkBlue $SelectedForeground = [ConsoleColor]::Yellow $Operations = @{ [ConsoleKey]::UpArrow = { $this.MoveUp() } [ConsoleKey]::DownArrow = { $this.MoveDown() } [ConsoleKey]::Spacebar = { $this.Select() } [ConsoleKey]::Enter = { $this.Finish() } [ConsoleKey]::Escape = { $this.Cancel() } } hidden [bool] $CanContinue = $true hidden [bool] $BackupCursorVisible = [Console]::CursorVisible #endregion Menu() {} Menu ([string[]] $items) { $this.Items = $items } [Collections.Generic.List[int]] Run() { [Console]::CursorVisible = $false while ($this.CanContinue) { $this.Draw() [ConsoleKeyInfo] $keyInfo = [Console]::ReadKey($true) if ($this.Operations.ContainsKey($keyInfo.Key)) { $this.Operations[$keyInfo.Key].Invoke() } } [Console]::ResetColor() [Console]::CursorVisible = $this.BackupCursorVisible return $this.Selected } hidden [void] Cancel() { $this.Selected.Clear(); $this.CanContinue = $false } hidden [void] Finish() { if ($this.Selected.Count -gt 0) { $this.CanContinue = $false } } hidden [void] Select() { if ($this.Selected -Contains $this.Current) { $this.Selected.Remove($this.Current) } else { $this.Selected.Add($this.Current) } } hidden [void] MoveDown() { if ($this.Current -lt ($this.Items.Count - 1)) { $this.Current++ } if ($this.Current -ge $this.Height -and $this.ViewStart -lt ($this.Items.Count - $this.Height)) { $this.ViewStart++ } } hidden [void] MoveUp() { if ($this.Current -gt 0) { $this.Current-- } if ($this.Current -lt ($this.Items.Length - $this.Height) -and $this.ViewStart -gt 0) { $this.ViewStart-- } } hidden [void] Draw() { if ($this.Items.Count -gt $this.Height) { $h = $this.Height } else { $h = $this.Items.Count } for ([int] $i = 0; $i -lt $h; $i++) { [Console]::SetCursorPosition($this.Left, $this.Top + $i) [Console]::BackgroundColor = $this.Background [Console]::ForegroundColor = $this.Foreground [string] $item = $this.Items[$this.ViewStart + $i] [string] $checkbox = "[ ] " [string] $cursor = " " [string] $spaces = "" [int] $lineLength = $item.Length + $checkbox.Length + $cursor.Length [int] $spacesCount = $this.Width - $lineLength if ($this.Selected -Contains ($this.ViewStart + $i)) { [Console]::BackgroundColor = $this.SelectedBackground [Console]::ForegroundColor = $this.SelectedForeground $checkbox = "[*] " } if ($this.ViewStart + $i -eq $this.Current) { [Console]::BackgroundColor = $this.CurrentBackground [Console]::ForegroundColor = $this.CurrentForeground $cursor = "> " } if ($lineLength -lt $this.Width) { $spaces = [string]::new(' ', $spacesCount) } if ($lineLength -gt $this.Width) { [int] $w = $this.Width - $checkbox.Length - $cursor.Length $item = $item.Substring(0, $w) } [Console]::Write($checkbox + $cursor + $item + $spaces) } } } function MenuDemo([IO.DirectoryInfo] $dir = $PWD.Path) { cls [Console]::WriteLine("Демка, только вывод, что Вы выбрали (мультивыбор). Текущий каталог: $dir") $Items = Get-ChildItem $dir -Force $menu = [Menu]@{ Items = $Items Top = 3 Height = 5 } [Console]::SetCursorPosition(0, [Console]::WindowHeight - $menu.Top - 1) [Console]::WriteLine("Стрелки вверх/вниз - перемещение; Spacebar - выбор; Enter - завершить выбор; ESC - отмена") $menu.Width = ([Console]::WindowWidth - $menu.Left) $menu.Operations += @{ [ConsoleKey]::R = { [Console]::ResetColor() cls [Console]::WriteLine("Демка, только вывод, что Вы выбрали (мультивыбор). Текущий каталог: $dir") [Console]::SetCursorPosition(0, [Console]::WindowHeight - $this.top - 1) [Console]::WriteLine("Стрелки вверх/вниз - перемещение; Spacebar - выбор; Enter - завершить выбор; ESC - отмена") $this.Width = ([Console]::WindowWidth - $this.Left) $this.Draw() } } if ($null -eq $menu) { throw $Error[0] } $result = $menu.Run() if ($result.Count -gt 0) { [Console]::Write("`nВы выбрали (индекс): ") [Console]::Write(($result -join "; ")) [Console]::Write("`nВы выбрали: ") @(foreach ($i in $result) { $Items[$i] }) -join "; " } pause # cls } MenuDemo |
|