|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Immutable;
using WindowsInput;
using WindowsInput.Native;
namespace Roslyn.VisualStudio.IntegrationTests.InProcess
{
internal readonly struct InputKey
{
public readonly ImmutableArray<VirtualKeyCode> Modifiers;
public readonly VirtualKeyCode VirtualKeyCode;
public readonly char? Character;
public readonly string? Text;
public InputKey(VirtualKeyCode virtualKeyCode, ImmutableArray<VirtualKeyCode> modifiers)
{
Modifiers = modifiers;
VirtualKeyCode = virtualKeyCode;
Character = null;
Text = null;
}
public InputKey(char character)
{
Modifiers = ImmutableArray<VirtualKeyCode>.Empty;
VirtualKeyCode = 0;
Character = character;
Text = null;
}
public InputKey(string text)
{
Modifiers = ImmutableArray<VirtualKeyCode>.Empty;
VirtualKeyCode = 0;
Character = null;
Text = text;
}
public static implicit operator InputKey(char character)
=> new(character);
public static implicit operator InputKey(string text)
=> new(text);
public static implicit operator InputKey(VirtualKeyCode virtualKeyCode)
=> new(virtualKeyCode, ImmutableArray<VirtualKeyCode>.Empty);
public static implicit operator InputKey((VirtualKeyCode virtualKeyCode, VirtualKeyCode modifier) modifiedKey)
=> new(modifiedKey.virtualKeyCode, ImmutableArray.Create(modifiedKey.modifier));
public void Apply(IInputSimulator simulator)
{
if (Character is { } c)
{
if (c == '\n')
simulator.Keyboard.KeyPress(VirtualKeyCode.RETURN);
else if (c == '\t')
simulator.Keyboard.KeyPress(VirtualKeyCode.TAB);
else
simulator.Keyboard.TextEntry(c);
return;
}
else if (Text is not null)
{
var offset = 0;
while (offset < Text.Length)
{
if (Text[offset] == '\r' && offset < Text.Length - 1 && Text[offset + 1] == '\n')
{
// Treat \r\n as a single RETURN character
offset++;
continue;
}
else if (Text[offset] == '\n')
{
simulator.Keyboard.KeyPress(VirtualKeyCode.RETURN);
offset++;
continue;
}
else if (Text[offset] == '\t')
{
simulator.Keyboard.KeyPress(VirtualKeyCode.TAB);
offset++;
continue;
}
else
{
var nextSpecial = Text.IndexOfAny(new[] { '\r', '\n', '\t' }, offset);
var endOfCurrentSegment = nextSpecial < 0 ? Text.Length : nextSpecial;
simulator.Keyboard.TextEntry(Text[offset..endOfCurrentSegment]);
offset = endOfCurrentSegment;
}
}
return;
}
if (Modifiers.IsEmpty)
{
simulator.Keyboard.KeyPress(VirtualKeyCode);
}
else
{
simulator.Keyboard.ModifiedKeyStroke(Modifiers, VirtualKeyCode);
}
}
}
}
|