예제 #1
0
        /// <summary>
        /// Gets the cursos position.
        /// </summary>
        /// <returns></returns>
        public Coordinates GetCursorPosition()
        {
            var buffer = GetOutputBuffer();

            ConsoleHostNativeMethods.CONSOLE_SCREEN_BUFFER_INFO info = DotConsoleNative.GetConsoleScreenBufferInfo(buffer);

            return(new Coordinates(info.cursorPosition.X, info.cursorPosition.Y));
        }
예제 #2
0
        /// <summary>
        /// Sets the cursor position.
        /// </summary>
        /// <param name="orgin"></param>
        public void SetCursorPosition(Coordinates orgin)
        {
            var handle = GetOutputBuffer();

            DotConsoleNative.SetConsoleCursorPosition(handle, new ConsoleHostNativeMethods.COORD()
            {
                X = (short)(orgin.X),
                Y = (short)(orgin.Y)
            });
        }
예제 #3
0
        /// <summary>
        /// Gets the output buffer windows as a rectangle.
        /// </summary>
        /// <returns></returns>
        public Region GetOutputBufferWindow()
        {
            var buffer = GetOutputBuffer();

            ConsoleHostNativeMethods.CONSOLE_SCREEN_BUFFER_INFO info = DotConsoleNative.GetConsoleScreenBufferInfo(buffer);

            return(new Region()
            {
                Left = info.window.Left, Top = info.window.Top, Height = info.window.Bottom, Width = info.window.Right
            });
        }
예제 #4
0
        /// <summary>
        /// Gets the output buffer window size.
        /// </summary>
        /// <returns></returns>
        public Coordinates GetOutputBufferWindowSize()
        {
            var buffer = GetOutputBuffer();

            ConsoleHostNativeMethods.CONSOLE_SCREEN_BUFFER_INFO info = DotConsoleNative.GetConsoleScreenBufferInfo(buffer);

            return(new Coordinates()
            {
                X = info.size.X,
                Y = info.size.Y
            });
        }
예제 #5
0
        private void FillBuffer(string text, int row, int col, int colLen)
        {
            //TODO Move this code out of here to ColorMap.
            ConsoleColor foregroundCopy = ConsoleColor.White;
            ConsoleColor backgroundCopy = ConsoleColor.Black;
            bool         fcInMap        = Renderer.ColorMap.TryGetMappedColor(ForegroundColor, out foregroundCopy);
            bool         bcInMap        = Renderer.ColorMap.TryGetMappedColor(BackgroundColor, out backgroundCopy);

            if (fcInMap == false) //add this color to map.
            {
                Renderer.ColorMap.AddColor(ForegroundColor);
                Renderer.ColorMap.TryGetMappedColor(ForegroundColor, out foregroundCopy);
            }

            if (bcInMap == false)
            {
                Renderer.ColorMap.AddColor(BackgroundColor);
                Renderer.ColorMap.TryGetMappedColor(BackgroundColor, out backgroundCopy);
            }

            int textIndex = 0;

            for (int idx = col; idx < col + colLen; idx++)
            {
                if (idx >= Options.BufferSize.X)
                {
                    break;
                }

                //Clear this char
                if (text == null || text.Length == 0)
                {
                    this.contentBuffer.Cells[row, idx].Char       = 0;
                    this.contentBuffer.Cells[row, idx].Attributes = 0;
                }
                else
                {
                    if (textIndex < text.Length)
                    {
                        this.contentBuffer.Cells[row, idx].Char = (ushort)text[textIndex];
                    }

                    this.contentBuffer.Cells[row, idx].Attributes = (ushort)DotConsoleNative.ToNativeConsoleColor(foregroundCopy, backgroundCopy);
                }
                textIndex++;
            }
        }
예제 #6
0
        /// <summary>
        /// Writes lines of text into the output buffer at a specified coordinates.
        /// </summary>
        /// <param name="orgin"></param>
        /// <param name="content"></param>
        public void WriteOutput(Coordinates orgin, string[] content)
        {
            int lineId = 0;
            int charId = 0;

            //Find the widest line and set the OutputCell matrix to such width
            var max = content.Max(x => x.Length);

            CellBuffer buffer = new CellBuffer(content.Length, max);

            foreach (var line in content)
            {
                charId = 0;
                foreach (var c in line)
                {
                    buffer.Cells[lineId, charId].Char       = (ushort)c;
                    buffer.Cells[lineId, charId].Attributes = (ushort)DotConsoleNative.ToNativeConsoleColor(ForegroundColor, BackgroundColor);
                    charId++;
                }
            }

            WriteOutput(orgin, buffer);
        }
예제 #7
0
        /// <summary>
        /// Reads cell matrix form the output buffer using the provided rectangle.
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        public CellBuffer ReadOutput(Region region)
        {
            var handle = GetOutputBuffer();

            //Get len of X coordinate, the plan here is to partition by Y
            var sizeOfX = (region.Width - region.Left + 1) * 4;

            //partition by Y coordinate.
            var partitionY = (int)Math.Ceiling((decimal)(maxBufferSize / sizeOfX));

            int sizeOfY = (region.Height - region.Top);

            //if Y is smaller then the partition by Y then we need
            //to set the partiton size to Y size.
            if (sizeOfY < partitionY)
            {
                partitionY = sizeOfY;
            }

            ConsoleHostNativeMethods.COORD bufferCoord = new ConsoleHostNativeMethods.COORD();
            bufferCoord.X = 0;
            bufferCoord.Y = 0;

            ConsoleHostNativeMethods.COORD bufferSize = new ConsoleHostNativeMethods.COORD();
            bufferSize.X = (short)(region.Width - region.Left);

            CellBuffer cells = new CellBuffer(sizeOfY, bufferSize.X);

            int cursor = 0;
            int i      = 0;

            do
            {
                i += partitionY;

                //the size of the Y coordinate is always the size of the buffer.
                bufferSize.X = (short)(region.Width - region.Left);
                bufferSize.Y = (short)partitionY;

                //If we exceeded the maximum size of the buffer we need to substract to the size of the remaining buffer.
                if (i > sizeOfY)
                {
                    int diff = i - sizeOfY;
                    bufferSize.Y = (short)(partitionY - diff);
                }

                //Fill the buffer part.
                ConsoleHostNativeMethods.SMALL_RECT readRegion = new ConsoleHostNativeMethods.SMALL_RECT();

                readRegion.Left   = (short)region.Left;
                readRegion.Top    = (short)region.Top;
                readRegion.Right  = (short)(region.Left + bufferSize.X);
                readRegion.Bottom = (short)(region.Top + bufferSize.Y);

                ConsoleHostNativeMethods.CHAR_INFO[] buffer = new ConsoleHostNativeMethods.CHAR_INFO[bufferSize.X * bufferSize.Y];
                buffer = DotConsoleNative.ReadConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref readRegion);

                //Fill the output buffer cells.
                int idx = 0;
                for (int k = cursor; k < bufferSize.Y; k++)
                {
                    for (int n = 0; n < bufferSize.X; n++)
                    {
                        cells.Cells[k, n].Attributes = buffer[idx].Attributes;
                        cells.Cells[k, n].Char       = buffer[idx].UnicodeChar;
                        idx++;
                    }
                    cursor = k;
                }
            }while (i < sizeOfY);

            return(cells);
        }
예제 #8
0
        public void WriteOutput(Coordinates orgin, CellBuffer cellBuffer)
        {
            var handle = GetOutputBuffer();

            //Get len of X coordinate, the plan here is to partition by Y
            var sizeOfX = cellBuffer.GetLengthOfX() * 4;

            //partition by Y coordinate.
            int partitionY = (int)Math.Ceiling((decimal)(maxBufferSize / sizeOfX));

            var sizeOfY = cellBuffer.GetLengthOfY();

            //if Y is smaller then the partition by Y then we need
            //to set the partiton size to Y size.
            if (sizeOfY < partitionY)
            {
                partitionY = sizeOfY;
            }

            //Get partitoned buffer size.
            int charBufferSize = (int)(partitionY * cellBuffer.GetLengthOfX());

            int cursor = 0;
            int i      = 0;

            do
            {
                i += partitionY;

                //If we exceeded the maximum size of the buffer we need to substract to the size of the remaining buffer.
                if (i > sizeOfY)
                {
                    int diff = i - sizeOfY;
                    i = i - diff;
                }

                //Fill the buffer part.
                ConsoleHostNativeMethods.CHAR_INFO[] buffer = new ConsoleHostNativeMethods.CHAR_INFO[charBufferSize];
                int idx = 0;
                for (int y = cursor; y < i; y++)
                {
                    for (int x = 0; x < cellBuffer.GetLengthOfX(); x++)
                    {
                        var cellToWrite = cellBuffer[y, x];

                        if (cellToWrite.Attributes == 0)
                        {
                            //Don't set the foreground color for empty cells this will force the ConsoleHost
                            //to do a very expensive calculation for each cell and slow things down.
                            cellToWrite.Attributes = (ushort)DotConsoleNative.ToNativeConsoleColor(0, BackgroundColor);
                        }

                        buffer[idx].Attributes  = cellToWrite.Attributes;
                        buffer[idx].UnicodeChar = cellToWrite.Char;
                        idx++;
                    }
                }

                ConsoleHostNativeMethods.COORD bufferSize = new ConsoleHostNativeMethods.COORD();
                bufferSize.X = (short)cellBuffer.GetLengthOfX();
                bufferSize.Y = (short)partitionY;

                ConsoleHostNativeMethods.COORD bufferCoord = new ConsoleHostNativeMethods.COORD();
                bufferCoord.X = 0;
                bufferCoord.Y = 0;

                ConsoleHostNativeMethods.SMALL_RECT writeRegion = new ConsoleHostNativeMethods.SMALL_RECT();
                writeRegion.Left   = (short)orgin.X;
                writeRegion.Top    = (short)(orgin.Y + cursor);
                writeRegion.Right  = (short)(orgin.X + bufferSize.X);
                writeRegion.Bottom = (short)(orgin.Y + cursor + bufferSize.Y);

                DotConsoleNative.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion);

                cursor = i;
            }while (i < sizeOfY);
        }
예제 #9
0
        /// <summary>
        /// Reads the input from the input buffer.
        /// </summary>
        public ReadRef ReadInput(ReadOptions options)
        {
            var  handle = GetInputBuffer();
            uint read   = 0;

            var readRef = new ReadRef();

            StringBuilder inputBuffer = new StringBuilder(options.InitialContent);

            int currentLength = 0;

            //Save current mode.
            uint currentMode = 0;

            ConsoleHostNativeMethods.GetConsoleMode(handle.DangerousGetHandle(), out currentMode);

            ConsoleModes newMode = (ConsoleModes)currentMode &
                                   ~ConsoleModes.WindowInput &
                                   ~ConsoleModes.MouseInput &
                                   ~ConsoleModes.ProcessedInput;

            ConsoleHostNativeMethods.SetConsoleMode(handle.DangerousGetHandle(), (uint)newMode);
            while (true)
            {
                var inputs = DotConsoleNative.ReadConsoleKeys(handle, 1, out read);

                if (inputs != null && inputs.Length > 0)
                {
                    if (read == 1)
                    {
                        var input = inputs[0];

                        if (input.KeyEvent.repeatCount == 0)
                        {
                            //for some bizzare reson this can return a key or record
                            //but repeat count is zero so we should not process it in any way.
                            //This can happen if we're after mouse inputs such as mouse move.
                            continue;
                        }

                        if (input.KeyEvent.keyDown == true)
                        {
                            if (input.EventType == (ushort)KeyEventType.KEY_EVENT)
                            {
                                if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Return)
                                {
                                    break;
                                }

                                if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Left)
                                {
                                    //set cursor position.
                                    //Should we use the cursor position from renderrer ? or perhaps use
                                    //the one from the output buffer of the console that we're using ?

                                    var currentCursorPosition = parent.GetCursorPosition();
                                    currentCursorPosition.X -= 1;

                                    parent.SetCursorPosition(currentCursorPosition);
                                    parent.SetBufferPosition(currentCursorPosition);
                                }
                                else if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Right)
                                {
                                    //set cursor position.
                                    //Should we use the cursor position from renderrer ? or perhaps use
                                    //the one from the output buffer of the console that we're using ?

                                    var currentCursorPosition = parent.GetCursorPosition();
                                    currentCursorPosition.X += 1;

                                    parent.SetCursorPosition(currentCursorPosition);
                                    parent.SetBufferPosition(currentCursorPosition);
                                }
                                else if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Back)
                                {
                                    var currentCursorPosition = parent.GetCursorPosition();
                                    currentCursorPosition.X -= 1;

                                    inputBuffer.Remove(inputBuffer.Length - 1, 1);
                                    if (options.NoEcho == false)
                                    {
                                        parent.AlterLine(string.Empty, currentCursorPosition.Y, currentCursorPosition.X, 1, options.BackgroundColor, options.ForegroundColor);
                                    }

                                    parent.SetCursorPosition(currentCursorPosition);
                                    parent.SetBufferPosition(currentCursorPosition);
                                }
                                else
                                {
                                    if (options.StopOnUpArrow && input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Up)
                                    {
                                        readRef.IsUpArrow = true;
                                        break;
                                    }
                                    else if (options.StopOnDownArrow && input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Down)
                                    {
                                        readRef.IsDownArrow = true;
                                        break;
                                    }

                                    if (options.StopChars != null)
                                    {
                                        if (options.StopChars.Contains(input.KeyEvent.unicodeChar))
                                        {
                                            readRef.StopChar = (input.KeyEvent.unicodeChar);
                                            break;
                                        }
                                    }

                                    currentLength++;

                                    inputBuffer.Append(input.KeyEvent.unicodeChar);
                                    if (options.NoEcho == false)
                                    {
                                        parent.Write(input.KeyEvent.unicodeChar.ToString(), options.BackgroundColor, options.ForegroundColor, false);
                                    }

                                    //Maximum allowed chars read, break the input loop.
                                    if (options.ReadLength.HasValue && currentLength >= options.ReadLength)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //Restore saved mode.
            ConsoleHostNativeMethods.SetConsoleMode(handle.DangerousGetHandle(), currentMode);

            readRef.ReadInput = inputBuffer.ToString();

            return(readRef);
        }
예제 #10
0
        /// <summary>
        /// Consctructs the Console Color map.
        /// </summary>
        private void ConstructMap()
        {
            ConsoleHostNativeMethods.CONSOLE_SCREEN_BUFFER_INFO_EX screenBufferInfo = DotConsoleNative.GetConsoleScreenBufferInfoExtended(consoleHandle);

            colorMap.Add(ConsoleColor.Black, Convert(screenBufferInfo.black.Color));
            colorMap.Add(ConsoleColor.White, Convert(screenBufferInfo.white.Color));
            colorMap.Add(ConsoleColor.Red, Convert(screenBufferInfo.red.Color));
            colorMap.Add(ConsoleColor.Green, Convert(screenBufferInfo.green.Color));
            colorMap.Add(ConsoleColor.Blue, Convert(screenBufferInfo.blue.Color));
            colorMap.Add(ConsoleColor.Gray, Convert(screenBufferInfo.gray.Color));
            colorMap.Add(ConsoleColor.Cyan, Convert(screenBufferInfo.cyan.Color));
            colorMap.Add(ConsoleColor.Magenta, Convert(screenBufferInfo.magenta.Color));

            colorMap.Add(ConsoleColor.DarkRed, Convert(screenBufferInfo.darkRed.Color));
            colorMap.Add(ConsoleColor.DarkGreen, Convert(screenBufferInfo.darkGreen.Color));
            colorMap.Add(ConsoleColor.DarkBlue, Convert(screenBufferInfo.darkBlue.Color));
            colorMap.Add(ConsoleColor.DarkGray, Convert(screenBufferInfo.darkGray.Color));
            colorMap.Add(ConsoleColor.DarkYellow, Convert(screenBufferInfo.darkYellow.Color));
            colorMap.Add(ConsoleColor.DarkCyan, Convert(screenBufferInfo.darkCyan.Color));
            colorMap.Add(ConsoleColor.DarkMagenta, Convert(screenBufferInfo.darkMagenta.Color));
        }
예제 #11
0
        /// <summary>
        /// Send the updated Color to the console host under the specified ConsoleColor key.
        /// </summary>
        /// <param name="keyColor"></param>
        /// <param name="targetColor"></param>
        private void MapToConsoleHost(ConsoleColor keyColor, Color targetColor)
        {
            ConsoleHostNativeMethods.CONSOLE_SCREEN_BUFFER_INFO_EX screenBufferInfo = DotConsoleNative.GetConsoleScreenBufferInfoExtended(consoleHandle);

            switch (keyColor)
            {
            case ConsoleColor.Black:
                screenBufferInfo.black.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.White:
                screenBufferInfo.white.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.Blue:
                screenBufferInfo.blue.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.Cyan:
                screenBufferInfo.cyan.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.Red:
                screenBufferInfo.red.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.Green:
                screenBufferInfo.green.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.Magenta:
                screenBufferInfo.magenta.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.Gray:
                screenBufferInfo.gray.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.Yellow:
                screenBufferInfo.yellow.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.DarkYellow:
                screenBufferInfo.darkYellow.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.DarkRed:
                screenBufferInfo.darkRed.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.DarkGreen:
                screenBufferInfo.darkGreen.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.DarkBlue:
                screenBufferInfo.darkBlue.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.DarkMagenta:
                screenBufferInfo.darkMagenta.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.DarkGray:
                screenBufferInfo.darkGray.Color = Convert(colorMap[keyColor]);
                break;

            case ConsoleColor.DarkCyan:
                screenBufferInfo.darkCyan.Color = Convert(colorMap[keyColor]);
                break;
            }

            // SUPER WHACKY CODE HERE.
            // WHY???!!!
            // This looks to me like a bug but it's needed since buffer info seems to shrink one line at a time in every direction :|
            screenBufferInfo.window.Bottom++;
            screenBufferInfo.window.Right++;

            DotConsoleNative.SetConsoleScreenBufferInfoExtended(consoleHandle, screenBufferInfo);
        }