mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
* Initial commit * Changed some loggers (WIP) * ColorPicker * Add version to all logs * FancyZones * push * PowerOCR and Measuretool * Settings * Hosts + Fix settings * Fix some using statements * FileLocksmith * Fix awake * Fixed Hosts logger * Fix spelling * Remove added submodule * Fiy FileLocksmith and PowerAccent * Fix PowerAccent * Test * Changed logger locic and added ColorPicker * Fixed package * Add documentation * Add locallow capability to Logger and add FancyZones * Fixed FancyZones and added FileLocksmith * Add Hosts * Fixed spelling mistakes * Add MeasureTool * Add MouseJump * Add PowerOCR * Add PowerAccent * Add monaco * Add Settings * Fixed Monaco * Update installer * Update doc/devdocs/logging.md Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> * Update doc/devdocs/logging.md Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> * Update doc/devdocs/logging.md Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> * Update logging.md * Fix unneccesairy includes. --------- Co-authored-by: Dustin L. Howett <dustin@howett.net> Co-authored-by: Stefan Markovic <stefan@janeasystems.com> Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com>
344 lines
10 KiB
C#
344 lines
10 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using System.Unicode;
|
|
using System.Windows;
|
|
using ManagedCommon;
|
|
using PowerAccent.Core.Services;
|
|
using PowerAccent.Core.Tools;
|
|
using PowerToys.PowerAccentKeyboardService;
|
|
|
|
namespace PowerAccent.Core;
|
|
|
|
public class PowerAccent : IDisposable
|
|
{
|
|
private readonly SettingsService _settingService;
|
|
|
|
// Keys that show a description (like dashes) when ShowCharacterInfoSetting is 1
|
|
private readonly LetterKey[] _letterKeysShowingDescription = new LetterKey[] { LetterKey.VK_O };
|
|
|
|
private bool _visible;
|
|
private string[] _characters = Array.Empty<string>();
|
|
private string[] _characterDescriptions = Array.Empty<string>();
|
|
private int _selectedIndex = -1;
|
|
private bool _showUnicodeDescription;
|
|
|
|
public LetterKey[] LetterKeysShowingDescription => _letterKeysShowingDescription;
|
|
|
|
public bool ShowUnicodeDescription => _showUnicodeDescription;
|
|
|
|
public string[] CharacterDescriptions => _characterDescriptions;
|
|
|
|
public event Action<bool, string[]> OnChangeDisplay;
|
|
|
|
public event Action<int, string> OnSelectCharacter;
|
|
|
|
private readonly KeyboardListener _keyboardListener;
|
|
|
|
private readonly CharactersUsageInfo _usageInfo;
|
|
|
|
public PowerAccent()
|
|
{
|
|
Logger.InitializeLogger("\\QuickAccent\\Logs");
|
|
|
|
LoadUnicodeInfoCache();
|
|
|
|
_keyboardListener = new KeyboardListener();
|
|
_keyboardListener.InitHook();
|
|
_settingService = new SettingsService(_keyboardListener);
|
|
_usageInfo = new CharactersUsageInfo();
|
|
|
|
SetEvents();
|
|
}
|
|
|
|
private void LoadUnicodeInfoCache()
|
|
{
|
|
UnicodeInfo.GetCharInfo(0);
|
|
}
|
|
|
|
private void SetEvents()
|
|
{
|
|
_keyboardListener.SetShowToolbarEvent(new PowerToys.PowerAccentKeyboardService.ShowToolbar((LetterKey letterKey) =>
|
|
{
|
|
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
|
{
|
|
ShowToolbar(letterKey);
|
|
});
|
|
}));
|
|
|
|
_keyboardListener.SetHideToolbarEvent(new PowerToys.PowerAccentKeyboardService.HideToolbar((InputType inputType) =>
|
|
{
|
|
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
|
{
|
|
SendInputAndHideToolbar(inputType);
|
|
});
|
|
}));
|
|
|
|
_keyboardListener.SetNextCharEvent(new PowerToys.PowerAccentKeyboardService.NextChar((TriggerKey triggerKey, bool shiftPressed) =>
|
|
{
|
|
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
|
{
|
|
ProcessNextChar(triggerKey, shiftPressed);
|
|
});
|
|
}));
|
|
|
|
_keyboardListener.SetIsLanguageLetterDelegate(new PowerToys.PowerAccentKeyboardService.IsLanguageLetter((LetterKey letterKey, out bool result) =>
|
|
{
|
|
result = Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang).Length > 0;
|
|
}));
|
|
}
|
|
|
|
private void ShowToolbar(LetterKey letterKey)
|
|
{
|
|
_visible = true;
|
|
|
|
_characters = GetCharacters(letterKey);
|
|
_characterDescriptions = GetCharacterDescriptions(_characters);
|
|
_showUnicodeDescription = _settingService.ShowUnicodeDescription;
|
|
|
|
Task.Delay(_settingService.InputTime).ContinueWith(
|
|
t =>
|
|
{
|
|
if (_visible)
|
|
{
|
|
OnChangeDisplay?.Invoke(true, _characters);
|
|
}
|
|
},
|
|
TaskScheduler.FromCurrentSynchronizationContext());
|
|
}
|
|
|
|
private string[] GetCharacters(LetterKey letterKey)
|
|
{
|
|
var characters = Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang);
|
|
if (_settingService.SortByUsageFrequency)
|
|
{
|
|
characters = characters.OrderByDescending(character => _usageInfo.GetUsageFrequency(character))
|
|
.ThenByDescending(character => _usageInfo.GetLastUsageTimestamp(character)).
|
|
ToArray<string>();
|
|
}
|
|
else if (!_usageInfo.Empty())
|
|
{
|
|
_usageInfo.Clear();
|
|
}
|
|
|
|
if (WindowsFunctions.IsCapsLockState() || WindowsFunctions.IsShiftState())
|
|
{
|
|
return ToUpper(characters);
|
|
}
|
|
|
|
return characters;
|
|
}
|
|
|
|
private string GetCharacterDescription(string character)
|
|
{
|
|
List<UnicodeCharInfo> unicodeList = new List<UnicodeCharInfo>();
|
|
foreach (var codePoint in character.AsCodePointEnumerable())
|
|
{
|
|
unicodeList.Add(UnicodeInfo.GetCharInfo(codePoint));
|
|
}
|
|
|
|
if (unicodeList.Count == 0)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
var description = new StringBuilder();
|
|
if (unicodeList.Count == 1)
|
|
{
|
|
var unicode = unicodeList.First();
|
|
var charUnicodeNumber = unicode.CodePoint.ToString("X4", CultureInfo.InvariantCulture);
|
|
description.AppendFormat(CultureInfo.InvariantCulture, "(U+{0}) {1} ", charUnicodeNumber, unicode.Name);
|
|
|
|
return description.ToString();
|
|
}
|
|
|
|
var displayTextAndCodes = new StringBuilder();
|
|
var names = new StringBuilder();
|
|
foreach (var unicode in unicodeList)
|
|
{
|
|
var charUnicodeNumber = unicode.CodePoint.ToString("X4", CultureInfo.InvariantCulture);
|
|
if (displayTextAndCodes.Length > 0)
|
|
{
|
|
displayTextAndCodes.Append(" - ");
|
|
}
|
|
|
|
displayTextAndCodes.AppendFormat(CultureInfo.InvariantCulture, "{0}: (U+{1})", unicode.GetDisplayText(), charUnicodeNumber);
|
|
|
|
if (names.Length > 0)
|
|
{
|
|
names.Append(", ");
|
|
}
|
|
|
|
names.Append(unicode.Name);
|
|
}
|
|
|
|
description.Append(displayTextAndCodes);
|
|
description.Append(": ");
|
|
description.Append(names);
|
|
|
|
return description.ToString();
|
|
}
|
|
|
|
private string[] GetCharacterDescriptions(string[] characters)
|
|
{
|
|
string[] charInfoCollection = Array.Empty<string>();
|
|
foreach (string character in characters)
|
|
{
|
|
charInfoCollection = charInfoCollection.Append<string>(GetCharacterDescription(character)).ToArray<string>();
|
|
}
|
|
|
|
return charInfoCollection;
|
|
}
|
|
|
|
private void SendInputAndHideToolbar(InputType inputType)
|
|
{
|
|
switch (inputType)
|
|
{
|
|
case InputType.Space:
|
|
{
|
|
WindowsFunctions.Insert(" ");
|
|
break;
|
|
}
|
|
|
|
case InputType.Char:
|
|
{
|
|
if (_selectedIndex != -1)
|
|
{
|
|
WindowsFunctions.Insert(_characters[_selectedIndex], true);
|
|
|
|
if (_settingService.SortByUsageFrequency)
|
|
{
|
|
_usageInfo.IncrementUsageFrequency(_characters[_selectedIndex]);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
OnChangeDisplay?.Invoke(false, null);
|
|
_selectedIndex = -1;
|
|
_visible = false;
|
|
}
|
|
|
|
private void ProcessNextChar(TriggerKey triggerKey, bool shiftPressed)
|
|
{
|
|
if (_visible && _selectedIndex == -1)
|
|
{
|
|
if (triggerKey == TriggerKey.Left)
|
|
{
|
|
_selectedIndex = (_characters.Length / 2) - 1;
|
|
}
|
|
|
|
if (triggerKey == TriggerKey.Right)
|
|
{
|
|
_selectedIndex = _characters.Length / 2;
|
|
}
|
|
|
|
if (triggerKey == TriggerKey.Space || _settingService.StartSelectionFromTheLeft)
|
|
{
|
|
_selectedIndex = 0;
|
|
}
|
|
|
|
if (_selectedIndex < 0)
|
|
{
|
|
_selectedIndex = 0;
|
|
}
|
|
|
|
if (_selectedIndex > _characters.Length - 1)
|
|
{
|
|
_selectedIndex = _characters.Length - 1;
|
|
}
|
|
|
|
OnSelectCharacter?.Invoke(_selectedIndex, _characters[_selectedIndex]);
|
|
return;
|
|
}
|
|
|
|
if (triggerKey == TriggerKey.Space)
|
|
{
|
|
if (shiftPressed)
|
|
{
|
|
if (_selectedIndex == 0)
|
|
{
|
|
_selectedIndex = _characters.Length - 1;
|
|
}
|
|
else
|
|
{
|
|
--_selectedIndex;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_selectedIndex < _characters.Length - 1)
|
|
{
|
|
++_selectedIndex;
|
|
}
|
|
else
|
|
{
|
|
_selectedIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (triggerKey == TriggerKey.Left)
|
|
{
|
|
--_selectedIndex;
|
|
}
|
|
|
|
if (triggerKey == TriggerKey.Right)
|
|
{
|
|
++_selectedIndex;
|
|
}
|
|
|
|
// Wrap around at beginning and end of _selectedIndex range
|
|
if (_selectedIndex < 0)
|
|
{
|
|
_selectedIndex = _characters.Length - 1;
|
|
}
|
|
|
|
if (_selectedIndex > _characters.Length - 1)
|
|
{
|
|
_selectedIndex = 0;
|
|
}
|
|
|
|
OnSelectCharacter?.Invoke(_selectedIndex, _characters[_selectedIndex]);
|
|
}
|
|
|
|
public Point GetDisplayCoordinates(Size window)
|
|
{
|
|
(Point Location, Size Size, double Dpi) activeDisplay = WindowsFunctions.GetActiveDisplay();
|
|
double primaryDPI = Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;
|
|
Rect screen = new Rect(activeDisplay.Location, activeDisplay.Size) / primaryDPI;
|
|
Position position = _settingService.Position;
|
|
|
|
/* Debug.WriteLine("Dpi: " + activeDisplay.Dpi); */
|
|
|
|
return Calculation.GetRawCoordinatesFromPosition(position, screen, window);
|
|
}
|
|
|
|
public Position GetToolbarPosition()
|
|
{
|
|
return _settingService.Position;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_keyboardListener.UnInitHook();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public static string[] ToUpper(string[] array)
|
|
{
|
|
string[] result = new string[array.Length];
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
result[i] = array[i].Contains('ß') ? "ẞ" : array[i].ToUpper(System.Globalization.CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|