2022-08-26 18:01:50 +02:00
|
|
|
|
// 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.
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
using System.Windows;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
using PowerAccent.Core.Services;
|
|
|
|
|
|
using PowerAccent.Core.Tools;
|
2022-09-09 13:27:56 +02:00
|
|
|
|
using PowerToys.PowerAccentKeyboardService;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
|
|
|
|
|
namespace PowerAccent.Core;
|
|
|
|
|
|
|
|
|
|
|
|
public class PowerAccent : IDisposable
|
|
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
private readonly SettingsService _settingService;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
|
|
|
|
|
private bool _visible;
|
|
|
|
|
|
private char[] _characters = Array.Empty<char>();
|
|
|
|
|
|
private int _selectedIndex = -1;
|
|
|
|
|
|
|
|
|
|
|
|
public event Action<bool, char[]> OnChangeDisplay;
|
|
|
|
|
|
|
|
|
|
|
|
public event Action<int, char> OnSelectCharacter;
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
private KeyboardListener _keyboardListener;
|
|
|
|
|
|
|
2022-08-26 18:01:50 +02:00
|
|
|
|
public PowerAccent()
|
|
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_keyboardListener = new KeyboardListener();
|
|
|
|
|
|
_keyboardListener.InitHook();
|
|
|
|
|
|
_settingService = new SettingsService(_keyboardListener);
|
|
|
|
|
|
|
|
|
|
|
|
SetEvents();
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
private void SetEvents()
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_keyboardListener.SetShowToolbarEvent(new PowerToys.PowerAccentKeyboardService.ShowToolbar((LetterKey letterKey) =>
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
Application.Current.Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ShowToolbar(letterKey);
|
|
|
|
|
|
});
|
|
|
|
|
|
}));
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_keyboardListener.SetHideToolbarEvent(new PowerToys.PowerAccentKeyboardService.HideToolbar((InputType inputType) =>
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
Application.Current.Dispatcher.Invoke(() =>
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
SendInputAndHideToolbar(inputType);
|
|
|
|
|
|
});
|
|
|
|
|
|
}));
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_keyboardListener.SetNextCharEvent(new PowerToys.PowerAccentKeyboardService.NextChar((TriggerKey triggerKey) =>
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
Application.Current.Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ProcessNextChar(triggerKey);
|
|
|
|
|
|
});
|
|
|
|
|
|
}));
|
2022-09-29 16:28:14 +02:00
|
|
|
|
|
|
|
|
|
|
_keyboardListener.SetIsLanguageLetterDelegate(new PowerToys.PowerAccentKeyboardService.IsLanguageLetter((LetterKey letterKey, out bool result) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
result = Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang).Length > 0;
|
|
|
|
|
|
}));
|
2022-09-09 13:27:56 +02:00
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
private void ShowToolbar(LetterKey letterKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
_visible = true;
|
2022-09-29 16:28:14 +02:00
|
|
|
|
_characters = (WindowsFunctions.IsCapsLockState() || WindowsFunctions.IsShiftState()) ? ToUpper(Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang)) : Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang);
|
2022-09-09 13:27:56 +02:00
|
|
|
|
Task.Delay(_settingService.InputTime).ContinueWith(
|
|
|
|
|
|
t =>
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (_visible)
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
OnChangeDisplay?.Invoke(true, _characters);
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
2022-09-09 13:27:56 +02:00
|
|
|
|
}, TaskScheduler.FromCurrentSynchronizationContext());
|
|
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
private void SendInputAndHideToolbar(InputType inputType)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (inputType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case InputType.Space:
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
WindowsFunctions.Insert(' ');
|
|
|
|
|
|
break;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
case InputType.Char:
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (_selectedIndex != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
WindowsFunctions.Insert(_characters[_selectedIndex], true);
|
|
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
break;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
2022-09-09 13:27:56 +02:00
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
OnChangeDisplay?.Invoke(false, null);
|
|
|
|
|
|
_selectedIndex = -1;
|
|
|
|
|
|
_visible = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ProcessNextChar(TriggerKey triggerKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_visible && _selectedIndex == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (triggerKey == TriggerKey.Left)
|
|
|
|
|
|
{
|
|
|
|
|
|
_selectedIndex = (_characters.Length / 2) - 1;
|
|
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (triggerKey == TriggerKey.Right)
|
|
|
|
|
|
{
|
|
|
|
|
|
_selectedIndex = _characters.Length / 2;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (triggerKey == TriggerKey.Space)
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_selectedIndex = 0;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (_selectedIndex < 0)
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_selectedIndex = 0;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (_selectedIndex > _characters.Length - 1)
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_selectedIndex = _characters.Length - 1;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OnSelectCharacter?.Invoke(_selectedIndex, _characters[_selectedIndex]);
|
2022-09-09 13:27:56 +02:00
|
|
|
|
return;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (triggerKey == TriggerKey.Space)
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
if (_selectedIndex < _characters.Length - 1)
|
2022-08-26 18:01:50 +02:00
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
++_selectedIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_selectedIndex = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-28 21:36:52 +10:00
|
|
|
|
if (triggerKey == TriggerKey.Left)
|
2022-09-09 13:27:56 +02:00
|
|
|
|
{
|
|
|
|
|
|
--_selectedIndex;
|
|
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
|
2022-09-28 21:36:52 +10:00
|
|
|
|
if (triggerKey == TriggerKey.Right)
|
2022-09-09 13:27:56 +02:00
|
|
|
|
{
|
|
|
|
|
|
++_selectedIndex;
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-28 21:36:52 +10:00
|
|
|
|
// Wrap around at beginning and end of _selectedIndex range
|
|
|
|
|
|
if (_selectedIndex < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
_selectedIndex = _characters.Length - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_selectedIndex > _characters.Length - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
_selectedIndex = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 13:27:56 +02:00
|
|
|
|
OnSelectCharacter?.Invoke(_selectedIndex, _characters[_selectedIndex]);
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Point GetDisplayCoordinates(Size window)
|
|
|
|
|
|
{
|
2022-09-16 11:54:58 +03:00
|
|
|
|
(Point Location, Size Size, double Dpi) activeDisplay = WindowsFunctions.GetActiveDisplay();
|
2022-08-26 18:01:50 +02:00
|
|
|
|
Rect screen = new Rect(activeDisplay.Location, activeDisplay.Size) / activeDisplay.Dpi;
|
|
|
|
|
|
Position position = _settingService.Position;
|
|
|
|
|
|
|
|
|
|
|
|
/* Debug.WriteLine("Dpi: " + activeDisplay.Dpi); */
|
|
|
|
|
|
|
|
|
|
|
|
return Calculation.GetRawCoordinatesFromPosition(position, screen, window);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
2022-09-09 13:27:56 +02:00
|
|
|
|
_keyboardListener.UnInitHook();
|
2022-08-26 18:01:50 +02:00
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static char[] ToUpper(char[] array)
|
|
|
|
|
|
{
|
|
|
|
|
|
char[] result = new char[array.Length];
|
|
|
|
|
|
for (int i = 0; i < array.Length; i++)
|
|
|
|
|
|
{
|
2022-09-20 19:15:29 +02:00
|
|
|
|
if (array[i] == 'ß')
|
|
|
|
|
|
{
|
|
|
|
|
|
result[i] = 'ẞ';
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
result[i] = char.ToUpper(array[i], System.Globalization.CultureInfo.InvariantCulture);
|
|
|
|
|
|
}
|
2022-08-26 18:01:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|