public void DrawMenu(Menu previousMenu) { IConsole console = Singleton._console; // Move cursor to the start of the first line after our input. this.Top = Singleton.ConvertOffsetToPoint(Singleton._buffer.Length).Y + 1; EnsureMenuAndInputIsVisible(console, tooltipLineCount: 0); console.CursorVisible = false; console.SaveCursor(); console.SetCursorPosition(0, this.Top); var bufferWidth = console.BufferWidth; var columnWidth = this.ColumnWidth; var items = this.MenuItems; for (var row = 0; row < this.Rows; row++) { var cells = 0; for (var col = 0; col < this.Columns; col++) { var index = row + (this.Rows * col); if (index >= items.Count) { break; } console.Write(GetMenuItem(items[index].ListItemText, columnWidth)); cells += columnWidth; } // Make sure we always write out exactly 1 buffer width to erase anything // from a previous menu. if (cells < bufferWidth) { console.BlankRestOfLine(); } // Explicit newline so consoles see each row as distinct lines. console.Write("\n"); } if (previousMenu != null) { if (Rows < previousMenu.Rows + previousMenu.ToolTipLines) { Singleton.WriteBlankLines(previousMenu.Rows + previousMenu.ToolTipLines - Rows); } } console.RestoreCursor(); console.CursorVisible = true; }
internal override void Clear(bool cursorAtEol) { if (_suggestionText == null) { return; } if (_renderedLength > 0) { // Clear the suggestion only if we actually rendered it. int left, top; int inputLen = _inputText.Length; IConsole console = _singleton._console; if (cursorAtEol) { left = console.CursorLeft; top = console.CursorTop; console.BlankRestOfLine(); } else { Point bufferEndPoint = _singleton.ConvertOffsetToPoint(inputLen); left = bufferEndPoint.X; top = bufferEndPoint.Y; _singleton.WriteBlankRestOfLine(left, top); } int bufferWidth = console.BufferWidth; int columns = LengthInBufferCells(_suggestionText, inputLen, _renderedLength); int remainingLenInCells = bufferWidth - left; columns -= remainingLenInCells; if (columns > 0) { int extra = columns % bufferWidth > 0 ? 1 : 0; int count = columns / bufferWidth + extra; _singleton.WriteBlankLines(top + 1, count); } } Reset(); }
public void DrawMenu(Menu previousMenu, bool menuSelect) { IConsole console = Singleton._console; if (menuSelect) { console.CursorVisible = false; SaveCursor(); } // Move cursor to the start of the first line after our input. var bufferEndPoint = Singleton.ConvertOffsetToPoint(Singleton._buffer.Length); console.SetCursorPosition(bufferEndPoint.X, bufferEndPoint.Y); // Top must be initialized before calling AdjustForPossibleScroll, otherwise // on the last line of the buffer, the scroll operation causes Top to point // past the buffer, which in turn causes the menu to be printed twice. this.Top = bufferEndPoint.Y + 1; AdjustForPossibleScroll(1); MoveCursorDown(1); var bufferWidth = console.BufferWidth; var columnWidth = this.ColumnWidth; var items = this.MenuItems; for (var row = 0; row < this.Rows; row++) { var cells = 0; for (var col = 0; col < this.Columns; col++) { var index = row + (this.Rows * col); if (index >= items.Count) { break; } console.Write(GetMenuItem(items[index].ListItemText, columnWidth)); cells += columnWidth; } // Make sure we always write out exactly 1 buffer width to erase anything // from a previous menu. if (cells < bufferWidth) { // 'BlankRestOfLine' erases rest of the current line, but the cursor is not moved. console.BlankRestOfLine(); } // Explicit newline so consoles see each row as distinct lines, but skip the // last line so we don't scroll. if (row != (this.Rows - 1) || !menuSelect) { AdjustForPossibleScroll(1); MoveCursorDown(1); } } bool extraPreRowsCleared = false; if (previousMenu != null) { if (Rows < previousMenu.Rows + previousMenu.ToolTipLines) { // If the last menu row took the whole buffer width, then the cursor could be pushed to the // beginning of the next line in the legacy console host (NOT in modern terminals such as // Windows Terminal, VSCode Terminal, or virtual-terminal-enabled console host). In such a // case, there is no need to move the cursor to the next line. // // If that is not the case, namely 'CursorLeft != 0', then the rest of the last menu row was // erased, but the cursor was not moved to the next line, so we will move the cursor. if (console.CursorLeft != 0) { // There are lines from the previous rendering that need to be cleared, // so we are sure there is no need to scroll. MoveCursorDown(1); } Singleton.WriteBlankLines(previousMenu.Rows + previousMenu.ToolTipLines - Rows); extraPreRowsCleared = true; } } // if the menu has moved, we need to clear the lines under it if (bufferEndPoint.Y < PreviousTop) { // In either of the following two cases, we will need to move the cursor to the next line: // - if extra rows from previous menu were cleared, then we know the current line was erased // but the cursor was not moved to the next line. // - if 'CursorLeft != 0', then the rest of the last menu row was erased, but the cursor // was not moved to the next line. if (extraPreRowsCleared || console.CursorLeft != 0) { // There are lines from the previous rendering that need to be cleared, // so we are sure there is no need to scroll. MoveCursorDown(1); } Singleton.WriteBlankLines(PreviousTop - bufferEndPoint.Y); } PreviousTop = bufferEndPoint.Y; if (menuSelect) { RestoreCursor(); console.CursorVisible = true; } }
public void DrawMenu(Menu previousMenu, bool menuSelect) { IConsole console = Singleton._console; if (menuSelect) { console.CursorVisible = false; SaveCursor(); } // Move cursor to the start of the first line after our input. var bufferEndPoint = Singleton.ConvertOffsetToPoint(Singleton._buffer.Length); console.SetCursorPosition(bufferEndPoint.X, bufferEndPoint.Y); AdjustForPossibleScroll(1); MoveCursorDown(1); this.Top = bufferEndPoint.Y + 1; var bufferWidth = console.BufferWidth; var columnWidth = this.ColumnWidth; var items = this.MenuItems; for (var row = 0; row < this.Rows; row++) { var cells = 0; for (var col = 0; col < this.Columns; col++) { var index = row + (this.Rows * col); if (index >= items.Count) { break; } console.Write(GetMenuItem(items[index].ListItemText, columnWidth)); cells += columnWidth; } // Make sure we always write out exactly 1 buffer width to erase anything // from a previous menu. if (cells < bufferWidth) { console.BlankRestOfLine(); } // Explicit newline so consoles see each row as distinct lines, but skip the // last line so we don't scroll. if (row != (this.Rows - 1) || !menuSelect) { AdjustForPossibleScroll(1); MoveCursorDown(1); } } if (previousMenu != null) { if (Rows < previousMenu.Rows + previousMenu.ToolTipLines) { Singleton.WriteBlankLines(previousMenu.Rows + previousMenu.ToolTipLines - Rows); } } // if the menu has moved, we need to clear the lines under it if (bufferEndPoint.Y < PreviousTop) { console.BlankRestOfLine(); Singleton.WriteBlankLines(PreviousTop - bufferEndPoint.Y); } PreviousTop = bufferEndPoint.Y; if (menuSelect) { RestoreCursor(); console.CursorVisible = true; } }
public void DrawMenu(Menu previousMenu, bool menuSelect) { IConsole console = Singleton._console; if (menuSelect) { console.CursorVisible = false; SaveCursor(); } // Move cursor to the start of the first line after our input. var bufferEndPoint = Singleton.ConvertOffsetToPoint(Singleton._buffer.Length); console.SetCursorPosition(bufferEndPoint.X, bufferEndPoint.Y); // Top must be initialized before calling AdjustForPossibleScroll, otherwise // on the last line of the buffer, the scroll operation causes Top to point // past the buffer, which in turn causes the menu to be printed twice. this.Top = bufferEndPoint.Y + 1; AdjustForPossibleScroll(1); MoveCursorDown(1); var bufferWidth = console.BufferWidth; var columnWidth = this.ColumnWidth; var items = this.MenuItems; for (var row = 0; row < this.Rows; row++) { var cells = 0; for (var col = 0; col < this.Columns; col++) { var index = row + (this.Rows * col); if (index >= items.Count) { break; } console.Write(GetMenuItem(items[index].ListItemText, columnWidth)); cells += columnWidth; } // Make sure we always write out exactly 1 buffer width to erase anything // from a previous menu. if (cells < bufferWidth) { // 'BlankRestOfLine' erases rest of the current line, but the cursor is not moved. console.BlankRestOfLine(); } // Explicit newline so consoles see each row as distinct lines, but skip the // last line so we don't scroll. if (row != (this.Rows - 1) || !menuSelect) { AdjustForPossibleScroll(1); MoveCursorDown(1); } } if (previousMenu != null) { if (Rows < previousMenu.Rows + previousMenu.ToolTipLines) { // Rest of the current line was erased, but the cursor was not moved to the next line. if (console.CursorLeft != 0) { // There are lines from the previous rendering that need to be cleared, // so we are sure there is no need to scroll. MoveCursorDown(1); } Singleton.WriteBlankLines(previousMenu.Rows + previousMenu.ToolTipLines - Rows); } } // if the menu has moved, we need to clear the lines under it if (bufferEndPoint.Y < PreviousTop) { console.BlankRestOfLine(); Singleton.WriteBlankLines(PreviousTop - bufferEndPoint.Y); } PreviousTop = bufferEndPoint.Y; if (menuSelect) { RestoreCursor(); console.CursorVisible = true; } }