Files
PowerToys/src/modules/poweraccent/PowerAccent.Core/PowerAccent.cs
Aaron Junker 5da8809b4e Centralize c# logger (#22760)
* 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>
2023-03-21 10:27:29 +01:00

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;
}
}