public string Start() { using (var scope = new ConsoleScope()) { var result = ""; while (true) { scope.Render(Template, new TemplateModel { Message = _message, InputLength = result.Length }); var keyInfo = scope.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) { if (scope.Validate(result, _validators)) { break; } result = ""; } else if (keyInfo.Key == ConsoleKey.Backspace) { if (result.Length == 0) { scope.Beep(); } else { result = result.Remove(result.Length - 1, 1); } } else if (!char.IsControl(keyInfo.KeyChar)) { result += keyInfo.KeyChar; } } return(result); } }
public T Start() { using (var scope = new ConsoleScope(false)) { var options = _baseOptions; var filteredOptions = _baseOptions; int selectedIndex = FindDefaultIndex(options, _defaultValue); var filter = ""; var prevFilter = ""; int prevPage = -1; var pageCount = (options.Count - 1) / _pageSize + 1; // Only resolve the page number when the option is neither 0 nor negative. int currentPage = (selectedIndex == 0 || selectedIndex == -1) ? 0 : GetPageFromIndex(options, selectedIndex); while (true) { if (filter != prevFilter) { filteredOptions = _baseOptions.Where(x => _filtering(filter, x.Value)) .ToArray(); prevFilter = filter; currentPage = 0; prevPage = -1; pageCount = (filteredOptions.Count - 1) / _pageSize + 1; } if (currentPage != prevPage) { options = filteredOptions.Skip(currentPage * _pageSize) .Take(_pageSize) .ToArray(); // Initially, we need to check for the default index. After moving the page or default index this becomes irrelevant. selectedIndex = prevPage == -1 && selectedIndex != -1 ? FindDefaultIndex(options, _baseOptions[selectedIndex].Item) : 0; prevPage = currentPage; } scope.Render(Template, new TemplateModel { Message = _message, Filter = filter, SelectedIndex = selectedIndex, Options = options }); var keyInfo = scope.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) { if (selectedIndex != -1) { break; } scope.SetError(new ValidationError("Value is required")); } else if (keyInfo.Key == ConsoleKey.UpArrow) { if (selectedIndex <= 0) { selectedIndex = options.Count - 1; } else { selectedIndex--; } } else if (keyInfo.Key == ConsoleKey.DownArrow) { if (selectedIndex >= options.Count - 1) { selectedIndex = 0; } else { selectedIndex++; } } else if (keyInfo.Key == ConsoleKey.LeftArrow) { if (currentPage <= 0) { currentPage = pageCount - 1; } else { currentPage--; } } else if (keyInfo.Key == ConsoleKey.RightArrow) { if (currentPage >= pageCount - 1) { currentPage = 0; } else { currentPage++; } } else if (keyInfo.Key == ConsoleKey.Backspace) { if (filter.Length == 0) { scope.Beep(); } else { filter = filter.Remove(filter.Length - 1, 1); } } else if (!char.IsControl(keyInfo.KeyChar)) { filter += keyInfo.KeyChar; } } scope.Render(FinishTemplate, new FinishTemplateModel { Message = _message, SelectedIndex = selectedIndex, Options = options }); return(options[selectedIndex].Item); } }
public T Start() { using (var scope = new ConsoleScope(false)) { var options = _baseOptions; var filteredOptions = _baseOptions; var selectedIndex = FindDefaultIndex(options, _defaultValue); var filter = ""; var prevFilter = ""; var currentPage = 0; var prevPage = -1; var pageCount = (options.Count - 1) / _pageSize + 1; while (true) { if (filter != prevFilter) { filteredOptions = _baseOptions.Where(x => _filtering(filter, x.Value)) .ToArray(); prevFilter = filter; currentPage = 0; prevPage = -1; pageCount = (filteredOptions.Count - 1) / _pageSize + 1; } if (currentPage != prevPage) { options = filteredOptions.Skip(currentPage * _pageSize) .Take(_pageSize) .ToArray(); prevPage = currentPage; selectedIndex = -1; } scope.Render(Template, new TemplateModel { Message = _message, Filter = filter, SelectedIndex = selectedIndex, Options = options }); var keyInfo = scope.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) { if (selectedIndex != -1) { break; } scope.SetError(new ValidationError("Value is required")); } else if (keyInfo.Key == ConsoleKey.UpArrow) { if (selectedIndex <= 0) { selectedIndex = options.Count - 1; } else { selectedIndex--; } } else if (keyInfo.Key == ConsoleKey.DownArrow) { if (selectedIndex >= options.Count - 1) { selectedIndex = 0; } else { selectedIndex++; } } else if (keyInfo.Key == ConsoleKey.LeftArrow) { if (currentPage <= 0) { currentPage = pageCount - 1; } else { currentPage--; } } else if (keyInfo.Key == ConsoleKey.RightArrow) { if (currentPage >= pageCount - 1) { currentPage = 0; } else { currentPage++; } } else if (keyInfo.Key == ConsoleKey.Backspace) { if (filter.Length == 0) { scope.Beep(); } else { filter = filter.Remove(filter.Length - 1, 1); } } else if (!char.IsControl(keyInfo.KeyChar)) { filter += keyInfo.KeyChar; } } scope.Render(FinishTemplate, new FinishTemplateModel { Message = _message, SelectedIndex = selectedIndex, Options = options }); return(options[selectedIndex].Item); } }
public IEnumerable <T> Start() { using (var scope = new ConsoleScope(false)) { // Defaults ICollection <Option> selectedOptions = new List <Option>(); IReadOnlyList <Option> _options = _baseOptions, filteredOptions = _baseOptions; int currentIndex = 0; string filter = "", prevFilter = ""; int prevPage = -1, pageCount = (_options.Count - 1) / _pageSize + 1; int currentPage = 0; while (true) { if (filter != prevFilter) { filteredOptions = _baseOptions.Where(x => _filtering(filter, x.Value)) .ToArray(); prevFilter = filter; currentPage = 0; prevPage = -1; pageCount = (filteredOptions.Count - 1) / _pageSize + 1; } if (currentPage != prevPage) { _options = (filteredOptions).Skip(currentPage * _pageSize) .Take(_pageSize) .ToArray(); currentIndex = 0; prevPage = currentPage; } scope.Render(Template, new TemplateModel { Message = _message, Filter = filter, SelectedOptions = selectedOptions, Options = _options, CurrentIndex = currentIndex }); var keyInfo = scope.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) { // Prevents selecting when filter does not match any items if (_options.Count == 0) { continue; } Option currentOption = _options[currentIndex]; if (!selectedOptions.Contains(currentOption)) { selectedOptions.Add(_options[currentIndex]); } else { selectedOptions.Remove(currentOption); } // If we have reached the limit, determine which items should not be selected anymore if (_limit == selectedOptions.Count) { _disabledByLimit = _baseOptions.Where(o => !selectedOptions.Contains(o)).ToList(); _showConfirm = true; } else { _showConfirm = selectedOptions.Count >= _min; if (_disabledByLimit.Count > 0) { _showConfirm = false; _disabledByLimit = new List <Option>(); } } } else if (keyInfo.Key == ConsoleKey.LeftArrow) { if (currentPage <= 0) { currentPage = pageCount - 1; } else { currentPage--; } } else if (keyInfo.Key == ConsoleKey.RightArrow) { if (currentPage >= pageCount - 1) { currentPage = 0; } else { currentPage++; } } else if (keyInfo.Key == ConsoleKey.Backspace) { if (filter.Length == 0) { scope.Beep(); } else { filter = filter.Remove(filter.Length - 1, 1); } } else if (!char.IsControl(keyInfo.KeyChar)) { filter += keyInfo.KeyChar; } else if (keyInfo.Key == ConsoleKey.Tab) { if (selectedOptions.Count > 0 && selectedOptions.Count >= _min) { break; } scope.SetError(new ValidationError($"A minimum selection of {(_min > -1 ? _min : 1)} items is required")); } else if (keyInfo.Key == ConsoleKey.UpArrow) { if (_options.All(o => _disabledByLimit.Contains(o))) { continue; } currentIndex = (currentIndex <= 0) ? _baseOptions.Count - 1 : currentIndex -= 1; while (!_baseOptions[currentIndex].Enabled || _disabledByLimit.Contains(_baseOptions[currentIndex])) { currentIndex = (currentIndex <= 0) ? _options.Count - 1 : currentIndex -= 1; } ; } else if (keyInfo.Key == ConsoleKey.DownArrow) { if (_options.All(o => _disabledByLimit.Contains(o))) { continue; } currentIndex = (currentIndex >= _options.Count - 1) ? 0 : currentIndex += 1; while (!_options[currentIndex].Enabled || _disabledByLimit.Contains(_options[currentIndex])) { currentIndex = currentIndex >= _options.Count - 1 ? 0 : currentIndex += 1; } ; } } scope.Render(FinishTemplate, new FinishTemplateModel { Message = _message, SelectedOptions = selectedOptions, Options = _options, CurrentIndex = currentIndex }); return(_baseOptions.Where(o => selectedOptions.Contains(o)).Select(x => x.Item)); } }