terminal/src/host/ft_uia/Elements/ViewportArea.cs
pi1024e 2872f147f8
Remove unneeded whitespace (#5162)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Every single time a PR is run, there are a bunch of warnings about whitespace in the .cs files, so I ran the code format on those files, without changing their contents, so it won't be flagged anymore.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [X] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [X] Tests added/passed

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ran the code-format utility on the .cs files
2020-03-30 14:33:32 +00:00

239 lines
8.2 KiB
C#

//----------------------------------------------------------------------------------------------------------------------
// <copyright file="ViewportArea.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <summary>Wrapper and helper for instantiating and interacting with the main text region (viewport area) of the console.</summary>
//----------------------------------------------------------------------------------------------------------------------
namespace Conhost.UIA.Tests.Elements
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using OpenQA.Selenium.Appium;
using WEX.Logging.Interop;
using WEX.TestExecution;
using Conhost.UIA.Tests.Common;
using Conhost.UIA.Tests.Common.NativeMethods;
using OpenQA.Selenium;
public class ViewportArea : IDisposable
{
private CmdApp app;
private Point clientTopLeft;
private Size sizeFont;
private ViewportStates state;
public enum ViewportStates
{
Normal,
Mark, // keyboard selection
Select, // mouse selection
Scroll
}
public ViewportArea(CmdApp app)
{
this.app = app;
this.state = ViewportStates.Normal;
this.InitializeFont();
this.InitializeWindow();
}
~ViewportArea()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Don't need to dispose of anything now, but this helps maintain the pattern used by other controls.
}
private void InitializeFont()
{
AutoHelpers.LogInvariant("Initializing font data for viewport area...");
this.sizeFont = new Size();
IntPtr hCon = app.GetStdOutHandle();
Verify.IsNotNull(hCon, "Check that we obtained the console output handle.");
WinCon.CONSOLE_FONT_INFO cfi = new WinCon.CONSOLE_FONT_INFO();
NativeMethods.Win32BoolHelper(WinCon.GetCurrentConsoleFont(hCon, false, out cfi), "Attempt to get current console font.");
this.sizeFont.Width = cfi.dwFontSize.X;
this.sizeFont.Height = cfi.dwFontSize.Y;
AutoHelpers.LogInvariant("Font size is X:{0} Y:{1}", this.sizeFont.Width, this.sizeFont.Height);
}
private void InitializeWindow()
{
AutoHelpers.LogInvariant("Initializing window data for viewport area...");
IntPtr hWnd = app.GetWindowHandle();
User32.RECT lpRect;
User32.GetClientRect(hWnd, out lpRect);
int style = User32.GetWindowLong(hWnd, User32.GWL_STYLE);
int exStyle = User32.GetWindowLong(hWnd, User32.GWL_EXSTYLE);
Verify.IsTrue(User32.AdjustWindowRectEx(ref lpRect, style, false, exStyle));
this.clientTopLeft = new Point();
this.clientTopLeft.X = Math.Abs(lpRect.left);
this.clientTopLeft.Y = Math.Abs(lpRect.top);
AutoHelpers.LogInvariant("Top left corner of client area is at X:{0} Y:{1}", this.clientTopLeft.X, this.clientTopLeft.Y);
}
public void ExitModes()
{
app.UIRoot.SendKeys(Keys.Escape);
this.state = ViewportStates.Normal;
}
public void EnterMode(ViewportStates state)
{
if (state == ViewportStates.Normal)
{
ExitModes();
return;
}
var titleBar = app.UIRoot.FindElementByAccessibilityId("TitleBar");
app.Session.Mouse.ContextClick(titleBar.Coordinates);
Globals.WaitForTimeout();
var contextMenu = app.Session.FindElementByClassName(Globals.PopupMenuClassId);
var editButton = contextMenu.FindElementByName("Edit");
editButton.Click();
Globals.WaitForTimeout();
Globals.WaitForTimeout();
AppiumWebElement subMenuButton;
switch (state)
{
case ViewportStates.Mark:
subMenuButton = app.Session.FindElementByName("Mark");
break;
default:
throw new NotImplementedException(AutoHelpers.FormatInvariant("Set Mode doesn't yet support type of '{0}'", state.ToString()));
}
subMenuButton.Click();
Globals.WaitForTimeout();
this.state = state;
}
// Accepts Point in characters. Will convert to pixels and move to the right location relative to this viewport.
public void MouseMove(Point pt)
{
Log.Comment($"Character position {pt.X}, {pt.Y}");
Point modPoint = pt;
ConvertCharacterOffsetToPixelPosition(ref modPoint);
Log.Comment($"Pixel position {modPoint.X}, {modPoint.Y}");
app.Session.Mouse.MouseMove(app.UIRoot.Coordinates, modPoint.X, modPoint.Y);
}
public void MouseDown()
{
app.Session.Mouse.MouseDown(null);
}
public void MouseUp()
{
app.Session.Mouse.MouseUp(null);
}
private void ConvertCharacterOffsetToPixelPosition(ref Point pt)
{
// Scale by pixel count per character
pt.X *= this.sizeFont.Width;
pt.Y *= this.sizeFont.Height;
// Move it to center of character
pt.X += this.sizeFont.Width / 2;
pt.Y += this.sizeFont.Height / 2;
// Adjust to the top left corner of the client rectangle.
pt.X += this.clientTopLeft.X;
pt.Y += this.clientTopLeft.Y;
}
public WinCon.CHAR_INFO GetCharInfoAt(IntPtr handle, Point pt)
{
Size size = new Size(1, 1);
Rectangle rect = new Rectangle(pt, size);
WinCon.CHAR_INFO[,] data = GetCharInfoInRectangle(handle, rect);
return data[0, 0];
}
public WinCon.CHAR_INFO[,] GetCharInfoInRectangle(IntPtr handle, Rectangle rect)
{
WinCon.SMALL_RECT readRectangle = new WinCon.SMALL_RECT();
readRectangle.Top = (short)rect.Top;
readRectangle.Bottom = (short)(rect.Bottom - 1);
readRectangle.Left = (short)rect.Left;
readRectangle.Right = (short)(rect.Right - 1);
WinCon.COORD dataBufferSize = new WinCon.COORD();
dataBufferSize.X = (short)rect.Width;
dataBufferSize.Y = (short)rect.Height;
WinCon.COORD dataBufferPos = new WinCon.COORD();
dataBufferPos.X = 0;
dataBufferPos.Y = 0;
WinCon.CHAR_INFO[,] data = new WinCon.CHAR_INFO[dataBufferSize.Y, dataBufferSize.X];
NativeMethods.Win32BoolHelper(WinCon.ReadConsoleOutput(handle, data, dataBufferSize, dataBufferPos, ref readRectangle), string.Format("Attempting to read rectangle (L: {0}, T: {1}, R: {2}, B: {3}) from output buffer.", readRectangle.Left, readRectangle.Top, readRectangle.Right, readRectangle.Bottom));
return data;
}
public IEnumerable<string> GetLinesInRectangle(IntPtr handle, Rectangle rect)
{
WinCon.CHAR_INFO[,] data = GetCharInfoInRectangle(handle, rect);
List<string> lines = new List<string>();
for (int row = 0; row < data.GetLength(0); row++)
{
StringBuilder builder = new StringBuilder();
for (int col = 0; col < data.GetLength(1); col++)
{
char z = data[row, col].UnicodeChar;
builder.Append(z);
}
lines.Add(builder.ToString());
}
return lines;
}
}
}