From e731cc04c1edd7772a11dd7b380ee08e7bf696dd Mon Sep 17 00:00:00 2001 From: Aaron Junker Date: Fri, 2 Dec 2022 15:45:49 +0100 Subject: [PATCH] [QuickAccent] Add description of current selected letter (#20587) * Adding unicode names and adjusting UI (WIP) * Added changing letter names * Add optioins to hide description (WIP) * WIP * Change to binding property * Adress PR comments * Set TextBlock in border * * Added to settings * Fixed string showing/not showing one time after switching character * Removed unneccessairy command in SettingsService.cs * Moved showdescription enum to settings.ui * Adding Fluent design :) * Fix merge errors * Center list * Fixed code not working. Accepted some code style changes. * Merge main in branch #2 * [Quick Accent] support unicode description for UTF-16 surrogate pairs * [Quick Accent] fix check-spelling-bot errors * [check-spelling] accept LANGID as correct word * [Quick Accent] fix delay when calling ShowToolbar for the first time * [Quick Accent] use toggle switch to turn off/on Unicode description * [Quick Accent] fix after merge * [Quick Accent] add UnicodeInformation.dll to installer Co-authored-by: Niels Laute --- .github/actions/spell-check/expect.txt | 1 + installer/PowerToysSetup/Product.wxs | 2 +- .../poweraccent/PowerAccent.Core/Languages.cs | 907 +++++++----------- .../PowerAccent.Core/PowerAccent.Core.csproj | 4 +- .../PowerAccent.Core/PowerAccent.cs | 111 ++- .../Services/SettingsService.cs | 18 + .../poweraccent/PowerAccent.UI/App.xaml.cs | 3 +- .../PowerAccent.UI/PowerAccent.UI.csproj | 2 + .../poweraccent/PowerAccent.UI/Selector.xaml | 182 ++-- .../PowerAccent.UI/Selector.xaml.cs | 35 +- .../poweraccent/PowerAccent/Program.cs | 4 +- .../PowerAccentProperties.cs | 4 + .../Settings.UI/Strings/en-us/Resources.resw | 3 + .../ViewModels/PowerAccentViewModel.cs | 18 + .../Settings.UI/Views/PowerAccentPage.xaml | 3 + 15 files changed, 635 insertions(+), 662 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index e7287a7d84..12a7f39afd 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -864,6 +864,7 @@ Kyrgyzstan Kyzylorda LAlt Lambson +LANGID langword Lastdevice Laute diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index edfc2d0f42..2a96496591 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -139,7 +139,7 @@ - + GetDefaultLetterKeyALL(letter), // ALL + Language.CA => GetDefaultLetterKeyCA(letter), // Catalan + Language.CUR => GetDefaultLetterKeyCUR(letter), // Currency + Language.CY => GetDefaultLetterKeyCY(letter), // Welsh + Language.CZ => GetDefaultLetterKeyCZ(letter), // Czech + Language.GA => GetDefaultLetterKeyGA(letter), // Gaeilge (Irish Gaelic) + Language.GD => GetDefaultLetterKeyGD(letter), // Gàidhlig (Scottish Gaelic) + Language.DE => GetDefaultLetterKeyDE(letter), // German + Language.FR => GetDefaultLetterKeyFR(letter), // French + Language.HR => GetDefaultLetterKeyHR(letter), // Croatian + Language.HU => GetDefaultLetterKeyHU(letter), // Hungarian + Language.IS => GetDefaultLetterKeyIS(letter), // Iceland + Language.IT => GetDefaultLetterKeyIT(letter), // Italian + Language.KU => GetDefaultLetterKeyKU(letter), // Kurdish + Language.MI => GetDefaultLetterKeyMI(letter), // Maori + Language.NL => GetDefaultLetterKeyNL(letter), // Dutch + Language.PI => GetDefaultLetterKeyPI(letter), // Pinyin + Language.PL => GetDefaultLetterKeyPL(letter), // Polish + Language.PT => GetDefaultLetterKeyPT(letter), // Portuguese + Language.RO => GetDefaultLetterKeyRO(letter), // Romanian + Language.SK => GetDefaultLetterKeySK(letter), // Slovak + Language.SP => GetDefaultLetterKeySP(letter), // Spain + Language.SR => GetDefaultLetterKeySR(letter), // Serbian + Language.SV => GetDefaultLetterKeySV(letter), // Swedish + Language.TK => GetDefaultLetterKeyTK(letter), // Turkish + _ => throw new ArgumentException("The language {0} is not know in this context", lang.ToString()), + }; } // All private static string[] GetDefaultLetterKeyALL(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_0: - return new string[] { "₀", "⁰" }; - case LetterKey.VK_1: - return new string[] { "₁", "¹" }; - case LetterKey.VK_2: - return new string[] { "₂", "²" }; - case LetterKey.VK_3: - return new string[] { "₃", "³" }; - case LetterKey.VK_4: - return new string[] { "₄", "⁴" }; - case LetterKey.VK_5: - return new string[] { "₅", "⁵" }; - case LetterKey.VK_6: - return new string[] { "₆", "⁶" }; - case LetterKey.VK_7: - return new string[] { "₇", "⁷" }; - case LetterKey.VK_8: - return new string[] { "₈", "⁸" }; - case LetterKey.VK_9: - return new string[] { "₉", "⁹" }; - case LetterKey.VK_A: - return new string[] { "á", "à", "ä", "â", "ă", "å", "α", "ā", "ą", "ȧ", "ã", "æ" }; - case LetterKey.VK_B: - return new string[] { "ḃ", "β" }; - case LetterKey.VK_C: - return new string[] { "ç", "ć", "ĉ", "č", "ċ", "¢", "χ" }; - case LetterKey.VK_D: - return new string[] { "ď", "ḋ", "đ", "δ", "ð" }; - case LetterKey.VK_E: - return new string[] { "é", "è", "ê", "ë", "ě", "ē", "ę", "ė", "ε", "η", "€" }; - case LetterKey.VK_F: - return new string[] { "ƒ", "ḟ" }; - case LetterKey.VK_G: - return new string[] { "ğ", "ģ", "ǧ", "ġ", "ĝ", "ǥ", "γ" }; - case LetterKey.VK_H: - return new string[] { "ḣ", "ĥ", "ħ" }; - case LetterKey.VK_I: - return new string[] { "ï", "î", "í", "ì", "ī", "į", "i", "ı", "İ", "ι" }; - case LetterKey.VK_J: - return new string[] { "ĵ" }; - case LetterKey.VK_K: - return new string[] { "ķ", "ǩ", "κ" }; - case LetterKey.VK_L: - return new string[] { "ĺ", "ľ", "ļ", "ł", "₺", "λ" }; - case LetterKey.VK_M: - return new string[] { "ṁ", "μ" }; - case LetterKey.VK_N: - return new string[] { "ñ", "ń", "ŋ", "ň", "ņ", "ṅ", "ⁿ", "ν" }; - case LetterKey.VK_O: - return new string[] { "ô", "ó", "ö", "ő", "ò", "ō", "ȯ", "ø", "õ", "œ", "ω", "ο" }; - case LetterKey.VK_P: - return new string[] { "ṗ", "₽", "π", "φ", "ψ" }; - case LetterKey.VK_R: - return new string[] { "ŕ", "ř", "ṙ", "₹", "ρ" }; - case LetterKey.VK_S: - return new string[] { "ś", "ş", "š", "ș", "ṡ", "ŝ", "ß", "σ", "$" }; - case LetterKey.VK_T: - return new string[] { "ţ", "ť", "ț", "ṫ", "ŧ", "θ", "τ", "þ" }; - case LetterKey.VK_U: - return new string[] { "û", "ú", "ü", "ŭ", "ű", "ù", "ů", "ū", "ų", "υ" }; - case LetterKey.VK_W: - return new string[] { "ẇ", "ŵ", "₩" }; - case LetterKey.VK_X: - return new string[] { "ẋ", "ξ" }; - case LetterKey.VK_Y: - return new string[] { "ÿ", "ŷ", "ý", "ẏ" }; - case LetterKey.VK_Z: - return new string[] { "ź", "ž", "ż", "ʒ", "ǯ", "ζ" }; - case LetterKey.VK_COMMA: - return new string[] { "¿", "¡", "∙", "₋", "⁻", "–", "≤", "≥", "≠", "≈", "≙", "±", "₊", "⁺" }; - } - - return Array.Empty(); + LetterKey.VK_0 => new string[] { "₀", "⁰" }, + LetterKey.VK_1 => new string[] { "₁", "¹" }, + LetterKey.VK_2 => new string[] { "₂", "²" }, + LetterKey.VK_3 => new string[] { "₃", "³" }, + LetterKey.VK_4 => new string[] { "₄", "⁴" }, + LetterKey.VK_5 => new string[] { "₅", "⁵" }, + LetterKey.VK_6 => new string[] { "₆", "⁶" }, + LetterKey.VK_7 => new string[] { "₇", "⁷" }, + LetterKey.VK_8 => new string[] { "₈", "⁸" }, + LetterKey.VK_9 => new string[] { "₉", "⁹" }, + LetterKey.VK_A => new string[] { "á", "à", "ä", "â", "ă", "å", "α", "ā", "ą", "ȧ", "ã", "æ" }, + LetterKey.VK_B => new string[] { "ḃ", "β" }, + LetterKey.VK_C => new string[] { "ç", "ć", "ĉ", "č", "ċ", "¢", "χ" }, + LetterKey.VK_D => new string[] { "ď", "ḋ", "đ", "δ", "ð" }, + LetterKey.VK_E => new string[] { "é", "è", "ê", "ë", "ě", "ē", "ę", "ė", "ε", "η", "€" }, + LetterKey.VK_F => new string[] { "ƒ", "ḟ" }, + LetterKey.VK_G => new string[] { "ğ", "ģ", "ǧ", "ġ", "ĝ", "ǥ", "γ" }, + LetterKey.VK_H => new string[] { "ḣ", "ĥ", "ħ" }, + LetterKey.VK_I => new string[] { "ï", "î", "í", "ì", "ī", "į", "i", "ı", "İ", "ι" }, + LetterKey.VK_J => new string[] { "ĵ" }, + LetterKey.VK_K => new string[] { "ķ", "ǩ", "κ" }, + LetterKey.VK_L => new string[] { "ĺ", "ľ", "ļ", "ł", "₺", "λ" }, + LetterKey.VK_M => new string[] { "ṁ", "μ" }, + LetterKey.VK_N => new string[] { "ñ", "ń", "ŋ", "ň", "ņ", "ṅ", "ⁿ", "ν" }, + LetterKey.VK_O => new string[] { "ô", "ó", "ö", "ő", "ò", "ō", "ȯ", "ø", "õ", "œ", "ω", "ο" }, + LetterKey.VK_P => new string[] { "ṗ", "₽", "π", "φ", "ψ" }, + LetterKey.VK_R => new string[] { "ŕ", "ř", "ṙ", "₹", "ρ" }, + LetterKey.VK_S => new string[] { "ś", "ş", "š", "ș", "ṡ", "ŝ", "ß", "σ", "$" }, + LetterKey.VK_T => new string[] { "ţ", "ť", "ț", "ṫ", "ŧ", "θ", "τ", "þ" }, + LetterKey.VK_U => new string[] { "û", "ú", "ü", "ŭ", "ű", "ù", "ů", "ū", "ų", "υ" }, + LetterKey.VK_W => new string[] { "ẇ", "ŵ", "₩" }, + LetterKey.VK_X => new string[] { "ẋ", "ξ" }, + LetterKey.VK_Y => new string[] { "ÿ", "ŷ", "ý", "ẏ" }, + LetterKey.VK_Z => new string[] { "ź", "ž", "ż", "ʒ", "ǯ", "ζ" }, + LetterKey.VK_COMMA => new string[] { "¿", "¡", "∙", "₋", "⁻", "–", "≤", "≥", "≠", "≈", "≙", "±", "₊", "⁺" }, + _ => Array.Empty(), + }; } // Currencies (source: https://www.eurochange.co.uk/travel-money/world-currency-abbreviations-symbols-and-codes-travel-money) private static string[] GetDefaultLetterKeyCUR(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_B: - return new string[] { "฿", "в" }; - case LetterKey.VK_C: - return new string[] { "¢", "₡", "č" }; - case LetterKey.VK_D: - return new string[] { "₫" }; - case LetterKey.VK_E: - return new string[] { "€" }; - case LetterKey.VK_F: - return new string[] { "ƒ" }; - case LetterKey.VK_H: - return new string[] { "₴" }; - case LetterKey.VK_K: - return new string[] { "₭" }; - case LetterKey.VK_L: - return new string[] { "ł" }; - case LetterKey.VK_N: - return new string[] { "л" }; - case LetterKey.VK_M: - return new string[] { "₼" }; - case LetterKey.VK_P: - return new string[] { "£", "₽" }; - case LetterKey.VK_R: - return new string[] { "₹", "៛", "﷼" }; - case LetterKey.VK_S: - return new string[] { "$", "₪" }; - case LetterKey.VK_T: - return new string[] { "₮", "₺" }; - case LetterKey.VK_W: - return new string[] { "₩" }; - case LetterKey.VK_Y: - return new string[] { "¥" }; - case LetterKey.VK_Z: - return new string[] { "z" }; - } - - return Array.Empty(); + LetterKey.VK_B => new string[] { "฿", "в" }, + LetterKey.VK_C => new string[] { "¢", "₡", "č" }, + LetterKey.VK_D => new string[] { "₫" }, + LetterKey.VK_E => new string[] { "€" }, + LetterKey.VK_F => new string[] { "ƒ" }, + LetterKey.VK_H => new string[] { "₴" }, + LetterKey.VK_K => new string[] { "₭" }, + LetterKey.VK_L => new string[] { "ł" }, + LetterKey.VK_N => new string[] { "л" }, + LetterKey.VK_M => new string[] { "₼" }, + LetterKey.VK_P => new string[] { "£", "₽" }, + LetterKey.VK_R => new string[] { "₹", "៛", "﷼" }, + LetterKey.VK_S => new string[] { "$", "₪" }, + LetterKey.VK_T => new string[] { "₮", "₺" }, + LetterKey.VK_W => new string[] { "₩" }, + LetterKey.VK_Y => new string[] { "¥" }, + LetterKey.VK_Z => new string[] { "z" }, + _ => Array.Empty(), + }; } // Croatian private static string[] GetDefaultLetterKeyHR(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_C: - return new string[] { "ć", "č" }; - case LetterKey.VK_D: - return new string[] { "đ" }; - case LetterKey.VK_S: - return new string[] { "š" }; - case LetterKey.VK_Z: - return new string[] { "ž" }; - } - - return Array.Empty(); + LetterKey.VK_C => new string[] { "ć", "č" }, + LetterKey.VK_D => new string[] { "đ" }, + LetterKey.VK_S => new string[] { "š" }, + LetterKey.VK_Z => new string[] { "ž" }, + _ => Array.Empty(), + }; } // French private static string[] GetDefaultLetterKeyFR(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "à", "â", "á", "ä", "ã", "æ" }; - case LetterKey.VK_C: - return new string[] { "ç" }; - case LetterKey.VK_E: - return new string[] { "é", "è", "ê", "ë", "€" }; - case LetterKey.VK_I: - return new string[] { "î", "ï", "í", "ì" }; - case LetterKey.VK_O: - return new string[] { "ô", "ö", "ó", "ò", "õ", "œ" }; - case LetterKey.VK_U: - return new string[] { "û", "ù", "ü", "ú" }; - case LetterKey.VK_Y: - return new string[] { "ÿ", "ý" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "à", "â", "á", "ä", "ã", "æ" }, + LetterKey.VK_C => new string[] { "ç" }, + LetterKey.VK_E => new string[] { "é", "è", "ê", "ë", "€" }, + LetterKey.VK_I => new string[] { "î", "ï", "í", "ì" }, + LetterKey.VK_O => new string[] { "ô", "ö", "ó", "ò", "õ", "œ" }, + LetterKey.VK_U => new string[] { "û", "ù", "ü", "ú" }, + LetterKey.VK_Y => new string[] { "ÿ", "ý" }, + _ => Array.Empty(), + }; } // Iceland private static string[] GetDefaultLetterKeyIS(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "á", "æ" }; - case LetterKey.VK_D: - return new string[] { "ð" }; - case LetterKey.VK_E: - return new string[] { "é" }; - case LetterKey.VK_O: - return new string[] { "ó", "ö" }; - case LetterKey.VK_U: - return new string[] { "ú" }; - case LetterKey.VK_Y: - return new string[] { "ý" }; - case LetterKey.VK_T: - return new string[] { "þ" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "á", "æ" }, + LetterKey.VK_D => new string[] { "ð" }, + LetterKey.VK_E => new string[] { "é" }, + LetterKey.VK_O => new string[] { "ó", "ö" }, + LetterKey.VK_U => new string[] { "ú" }, + LetterKey.VK_Y => new string[] { "ý" }, + LetterKey.VK_T => new string[] { "þ" }, + _ => Array.Empty(), + }; } // Spain private static string[] GetDefaultLetterKeySP(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "á" }; - case LetterKey.VK_E: - return new string[] { "é", "€" }; - case LetterKey.VK_I: - return new string[] { "í" }; - case LetterKey.VK_N: - return new string[] { "ñ" }; - case LetterKey.VK_O: - return new string[] { "ó" }; - case LetterKey.VK_U: - return new string[] { "ú", "ü" }; - case LetterKey.VK_COMMA: - return new string[] { "¿", "?" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "á" }, + LetterKey.VK_E => new string[] { "é", "€" }, + LetterKey.VK_I => new string[] { "í" }, + LetterKey.VK_N => new string[] { "ñ" }, + LetterKey.VK_O => new string[] { "ó" }, + LetterKey.VK_U => new string[] { "ú", "ü" }, + LetterKey.VK_COMMA => new string[] { "¿", "?" }, + _ => Array.Empty(), + }; } - // Catalan + // Catalan private static string[] GetDefaultLetterKeyCA(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "à", "á" }; - case LetterKey.VK_C: - return new string[] { "ç" }; - case LetterKey.VK_E: - return new string[] { "è", "é", "€" }; - case LetterKey.VK_I: - return new string[] { "ì", "í", "ï" }; - case LetterKey.VK_N: - return new string[] { "ñ" }; - case LetterKey.VK_O: - return new string[] { "ò", "ó" }; - case LetterKey.VK_U: - return new string[] { "ù", "ú", "ü" }; - case LetterKey.VK_L: - return new string[] { "·" }; - case LetterKey.VK_COMMA: - return new string[] { "¿", "?" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "à", "á" }, + LetterKey.VK_C => new string[] { "ç" }, + LetterKey.VK_E => new string[] { "è", "é", "€" }, + LetterKey.VK_I => new string[] { "ì", "í", "ï" }, + LetterKey.VK_N => new string[] { "ñ" }, + LetterKey.VK_O => new string[] { "ò", "ó" }, + LetterKey.VK_U => new string[] { "ù", "ú", "ü" }, + LetterKey.VK_L => new string[] { "·" }, + LetterKey.VK_COMMA => new string[] { "¿", "?" }, + _ => Array.Empty(), + }; } // Maori private static string[] GetDefaultLetterKeyMI(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "ā" }; - case LetterKey.VK_E: - return new string[] { "ē" }; - case LetterKey.VK_I: - return new string[] { "ī" }; - case LetterKey.VK_O: - return new string[] { "ō" }; - case LetterKey.VK_S: - return new string[] { "$" }; - case LetterKey.VK_U: - return new string[] { "ū" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "ā" }, + LetterKey.VK_E => new string[] { "ē" }, + LetterKey.VK_I => new string[] { "ī" }, + LetterKey.VK_O => new string[] { "ō" }, + LetterKey.VK_S => new string[] { "$" }, + LetterKey.VK_U => new string[] { "ū" }, + _ => Array.Empty(), + }; } // Dutch private static string[] GetDefaultLetterKeyNL(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "á", "à", "ä" }; - case LetterKey.VK_C: - return new string[] { "ç" }; - case LetterKey.VK_E: - return new string[] { "é", "è", "ë", "ê", "€" }; - case LetterKey.VK_I: - return new string[] { "í", "ï", "î" }; - case LetterKey.VK_N: - return new string[] { "ñ" }; - case LetterKey.VK_O: - return new string[] { "ó", "ö", "ô" }; - case LetterKey.VK_U: - return new string[] { "ú", "ü", "û" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "á", "à", "ä" }, + LetterKey.VK_C => new string[] { "ç" }, + LetterKey.VK_E => new string[] { "é", "è", "ë", "ê", "€" }, + LetterKey.VK_I => new string[] { "í", "ï", "î" }, + LetterKey.VK_N => new string[] { "ñ" }, + LetterKey.VK_O => new string[] { "ó", "ö", "ô" }, + LetterKey.VK_U => new string[] { "ú", "ü", "û" }, + _ => Array.Empty(), + }; } // Pinyin private static string[] GetDefaultLetterKeyPI(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "ā", "á", "ǎ", "à", "a", "ɑ̄", "ɑ́", "ɑ̌", "ɑ̀" }; - case LetterKey.VK_C: - return new string[] { "ĉ", "c" }; - case LetterKey.VK_E: - return new string[] { "ē", "é", "ě", "è", "e" }; - case LetterKey.VK_I: - return new string[] { "ī", "í", "ǐ", "ì", "i" }; - case LetterKey.VK_M: - return new string[] { "m̄", "ḿ", "m̌", "m̀", "m" }; - case LetterKey.VK_N: - return new string[] { "n̄", "ń", "ň", "ǹ", "n", "ŋ", "ŋ̄", "ŋ́", "ŋ̌", "ŋ̀" }; - case LetterKey.VK_O: - return new string[] { "ō", "ó", "ǒ", "ò", "o" }; - case LetterKey.VK_S: - return new string[] { "ŝ", "s" }; - case LetterKey.VK_U: - return new string[] { "ū", "ú", "ǔ", "ù", "u" }; - case LetterKey.VK_V: - return new string[] { "ǖ", "ǘ", "ǚ", "ǜ", "ü" }; - case LetterKey.VK_Y: - return new string[] { "¥", "y" }; - case LetterKey.VK_Z: - return new string[] { "ẑ", "z" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "ā", "á", "ǎ", "à", "a", "ɑ̄", "ɑ́", "ɑ̌", "ɑ̀" }, + LetterKey.VK_C => new string[] { "ĉ", "c" }, + LetterKey.VK_E => new string[] { "ē", "é", "ě", "è", "e" }, + LetterKey.VK_I => new string[] { "ī", "í", "ǐ", "ì", "i" }, + LetterKey.VK_M => new string[] { "m̄", "ḿ", "m̌", "m̀", "m" }, + LetterKey.VK_N => new string[] { "n̄", "ń", "ň", "ǹ", "n", "ŋ", "ŋ̄", "ŋ́", "ŋ̌", "ŋ̀" }, + LetterKey.VK_O => new string[] { "ō", "ó", "ǒ", "ò", "o" }, + LetterKey.VK_S => new string[] { "ŝ", "s" }, + LetterKey.VK_U => new string[] { "ū", "ú", "ǔ", "ù", "u" }, + LetterKey.VK_V => new string[] { "ǖ", "ǘ", "ǚ", "ǜ", "ü" }, + LetterKey.VK_Y => new string[] { "¥", "y" }, + LetterKey.VK_Z => new string[] { "ẑ", "z" }, + _ => Array.Empty(), + }; } // Turkish private static string[] GetDefaultLetterKeyTK(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "â" }; - case LetterKey.VK_C: - return new string[] { "ç" }; - case LetterKey.VK_E: - return new string[] { "ë", "€" }; - case LetterKey.VK_G: - return new string[] { "ğ" }; - case LetterKey.VK_I: - return new string[] { "ı", "İ", "î", }; - case LetterKey.VK_O: - return new string[] { "ö", "ô" }; - case LetterKey.VK_S: - return new string[] { "ş" }; - case LetterKey.VK_T: - return new string[] { "₺" }; - case LetterKey.VK_U: - return new string[] { "ü", "û" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "â" }, + LetterKey.VK_C => new string[] { "ç" }, + LetterKey.VK_E => new string[] { "ë", "€" }, + LetterKey.VK_G => new string[] { "ğ" }, + LetterKey.VK_I => new string[] { "ı", "İ", "î", }, + LetterKey.VK_O => new string[] { "ö", "ô" }, + LetterKey.VK_S => new string[] { "ş" }, + LetterKey.VK_T => new string[] { "₺" }, + LetterKey.VK_U => new string[] { "ü", "û" }, + _ => Array.Empty(), + }; } // Polish private static string[] GetDefaultLetterKeyPL(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "ą" }; - case LetterKey.VK_C: - return new string[] { "ć" }; - case LetterKey.VK_E: - return new string[] { "ę", "€" }; - case LetterKey.VK_L: - return new string[] { "ł" }; - case LetterKey.VK_N: - return new string[] { "ń" }; - case LetterKey.VK_O: - return new string[] { "ó" }; - case LetterKey.VK_S: - return new string[] { "ś" }; - case LetterKey.VK_Z: - return new string[] { "ż", "ź" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "ą" }, + LetterKey.VK_C => new string[] { "ć" }, + LetterKey.VK_E => new string[] { "ę", "€" }, + LetterKey.VK_L => new string[] { "ł" }, + LetterKey.VK_N => new string[] { "ń" }, + LetterKey.VK_O => new string[] { "ó" }, + LetterKey.VK_S => new string[] { "ś" }, + LetterKey.VK_Z => new string[] { "ż", "ź" }, + _ => Array.Empty(), + }; } // Portuguese private static string[] GetDefaultLetterKeyPT(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_0: - return new string[] { "₀", "⁰" }; - case LetterKey.VK_1: - return new string[] { "₁", "¹" }; - case LetterKey.VK_2: - return new string[] { "₂", "²" }; - case LetterKey.VK_3: - return new string[] { "₃", "³" }; - case LetterKey.VK_4: - return new string[] { "₄", "⁴" }; - case LetterKey.VK_5: - return new string[] { "₅", "⁵" }; - case LetterKey.VK_6: - return new string[] { "₆", "⁶" }; - case LetterKey.VK_7: - return new string[] { "₇", "⁷" }; - case LetterKey.VK_8: - return new string[] { "₈", "⁸" }; - case LetterKey.VK_9: - return new string[] { "₉", "⁹" }; - case LetterKey.VK_A: - return new string[] { "á", "à", "â", "ã" }; - case LetterKey.VK_C: - return new string[] { "ç" }; - case LetterKey.VK_E: - return new string[] { "é", "ê", "€" }; - case LetterKey.VK_I: - return new string[] { "í" }; - case LetterKey.VK_O: - return new string[] { "ô", "ó", "õ" }; - case LetterKey.VK_P: - return new string[] { "π" }; - case LetterKey.VK_S: - return new string[] { "$" }; - case LetterKey.VK_U: - return new string[] { "ú" }; - case LetterKey.VK_COMMA: - return new string[] { "≤", "≥", "≠", "≈", "≙", "±", "₊", "⁺" }; - } - - return Array.Empty(); + LetterKey.VK_0 => new string[] { "₀", "⁰" }, + LetterKey.VK_1 => new string[] { "₁", "¹" }, + LetterKey.VK_2 => new string[] { "₂", "²" }, + LetterKey.VK_3 => new string[] { "₃", "³" }, + LetterKey.VK_4 => new string[] { "₄", "⁴" }, + LetterKey.VK_5 => new string[] { "₅", "⁵" }, + LetterKey.VK_6 => new string[] { "₆", "⁶" }, + LetterKey.VK_7 => new string[] { "₇", "⁷" }, + LetterKey.VK_8 => new string[] { "₈", "⁸" }, + LetterKey.VK_9 => new string[] { "₉", "⁹" }, + LetterKey.VK_A => new string[] { "á", "à", "â", "ã" }, + LetterKey.VK_C => new string[] { "ç" }, + LetterKey.VK_E => new string[] { "é", "ê", "€" }, + LetterKey.VK_I => new string[] { "í" }, + LetterKey.VK_O => new string[] { "ô", "ó", "õ" }, + LetterKey.VK_P => new string[] { "π" }, + LetterKey.VK_S => new string[] { "$" }, + LetterKey.VK_U => new string[] { "ú" }, + LetterKey.VK_COMMA => new string[] { "≤", "≥", "≠", "≈", "≙", "±", "₊", "⁺" }, + _ => Array.Empty(), + }; } // Slovak private static string[] GetDefaultLetterKeySK(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "á", "ä" }; - case LetterKey.VK_C: - return new string[] { "č" }; - case LetterKey.VK_D: - return new string[] { "ď" }; - case LetterKey.VK_E: - return new string[] { "é", "€" }; - case LetterKey.VK_I: - return new string[] { "í" }; - case LetterKey.VK_L: - return new string[] { "ľ", "ĺ" }; - case LetterKey.VK_N: - return new string[] { "ň" }; - case LetterKey.VK_O: - return new string[] { "ó", "ô" }; - case LetterKey.VK_R: - return new string[] { "ŕ" }; - case LetterKey.VK_S: - return new string[] { "š" }; - case LetterKey.VK_T: - return new string[] { "ť" }; - case LetterKey.VK_U: - return new string[] { "ú" }; - case LetterKey.VK_Y: - return new string[] { "ý" }; - case LetterKey.VK_Z: - return new string[] { "ž" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "á", "ä" }, + LetterKey.VK_C => new string[] { "č" }, + LetterKey.VK_D => new string[] { "ď" }, + LetterKey.VK_E => new string[] { "é", "€" }, + LetterKey.VK_I => new string[] { "í" }, + LetterKey.VK_L => new string[] { "ľ", "ĺ" }, + LetterKey.VK_N => new string[] { "ň" }, + LetterKey.VK_O => new string[] { "ó", "ô" }, + LetterKey.VK_R => new string[] { "ŕ" }, + LetterKey.VK_S => new string[] { "š" }, + LetterKey.VK_T => new string[] { "ť" }, + LetterKey.VK_U => new string[] { "ú" }, + LetterKey.VK_Y => new string[] { "ý" }, + LetterKey.VK_Z => new string[] { "ž" }, + _ => Array.Empty(), + }; } // Gaeilge (Irish language) private static string[] GetDefaultLetterKeyGA(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "á" }; - case LetterKey.VK_E: - return new string[] { "é" }; - case LetterKey.VK_I: - return new string[] { "í" }; - case LetterKey.VK_O: - return new string[] { "ó" }; - case LetterKey.VK_U: - return new string[] { "ú" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "á" }, + LetterKey.VK_E => new string[] { "é" }, + LetterKey.VK_I => new string[] { "í" }, + LetterKey.VK_O => new string[] { "ó" }, + LetterKey.VK_U => new string[] { "ú" }, + _ => Array.Empty(), + }; } // Gàidhlig (Scottish Gaelic) private static string[] GetDefaultLetterKeyGD(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "à" }; - case LetterKey.VK_E: - return new string[] { "è" }; - case LetterKey.VK_I: - return new string[] { "ì" }; - case LetterKey.VK_O: - return new string[] { "ò" }; - case LetterKey.VK_U: - return new string[] { "ù" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "à" }, + LetterKey.VK_E => new string[] { "è" }, + LetterKey.VK_I => new string[] { "ì" }, + LetterKey.VK_O => new string[] { "ò" }, + LetterKey.VK_U => new string[] { "ù" }, + _ => Array.Empty(), + }; } // Czech private static string[] GetDefaultLetterKeyCZ(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "á" }; - case LetterKey.VK_C: - return new string[] { "č" }; - case LetterKey.VK_D: - return new string[] { "ď" }; - case LetterKey.VK_E: - return new string[] { "ě", "é" }; - case LetterKey.VK_I: - return new string[] { "í" }; - case LetterKey.VK_N: - return new string[] { "ň" }; - case LetterKey.VK_O: - return new string[] { "ó" }; - case LetterKey.VK_R: - return new string[] { "ř" }; - case LetterKey.VK_S: - return new string[] { "š" }; - case LetterKey.VK_T: - return new string[] { "ť" }; - case LetterKey.VK_U: - return new string[] { "ů", "ú" }; - case LetterKey.VK_Y: - return new string[] { "ý" }; - case LetterKey.VK_Z: - return new string[] { "ž" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "á" }, + LetterKey.VK_C => new string[] { "č" }, + LetterKey.VK_D => new string[] { "ď" }, + LetterKey.VK_E => new string[] { "ě", "é" }, + LetterKey.VK_I => new string[] { "í" }, + LetterKey.VK_N => new string[] { "ň" }, + LetterKey.VK_O => new string[] { "ó" }, + LetterKey.VK_R => new string[] { "ř" }, + LetterKey.VK_S => new string[] { "š" }, + LetterKey.VK_T => new string[] { "ť" }, + LetterKey.VK_U => new string[] { "ů", "ú" }, + LetterKey.VK_Y => new string[] { "ý" }, + LetterKey.VK_Z => new string[] { "ž" }, + _ => Array.Empty(), + }; } // German private static string[] GetDefaultLetterKeyDE(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "ä" }; - case LetterKey.VK_E: - return new string[] { "€" }; - case LetterKey.VK_O: - return new string[] { "ö" }; - case LetterKey.VK_S: - return new string[] { "ß" }; - case LetterKey.VK_U: - return new string[] { "ü" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "ä" }, + LetterKey.VK_E => new string[] { "€" }, + LetterKey.VK_O => new string[] { "ö" }, + LetterKey.VK_S => new string[] { "ß" }, + LetterKey.VK_U => new string[] { "ü" }, + _ => Array.Empty(), + }; } // Hungarian private static string[] GetDefaultLetterKeyHU(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "á" }; - case LetterKey.VK_E: - return new string[] { "é" }; - case LetterKey.VK_I: - return new string[] { "í" }; - case LetterKey.VK_O: - return new string[] { "ó", "ő", "ö" }; - case LetterKey.VK_U: - return new string[] { "ú", "ű", "ü" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "á" }, + LetterKey.VK_E => new string[] { "é" }, + LetterKey.VK_I => new string[] { "í" }, + LetterKey.VK_O => new string[] { "ó", "ő", "ö" }, + LetterKey.VK_U => new string[] { "ú", "ű", "ü" }, + _ => Array.Empty(), + }; } // Romanian private static string[] GetDefaultLetterKeyRO(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "ă", "â" }; - case LetterKey.VK_I: - return new string[] { "î" }; - case LetterKey.VK_S: - return new string[] { "ș" }; - case LetterKey.VK_T: - return new string[] { "ț" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "ă", "â" }, + LetterKey.VK_I => new string[] { "î" }, + LetterKey.VK_S => new string[] { "ș" }, + LetterKey.VK_T => new string[] { "ț" }, + _ => Array.Empty(), + }; } // Italian private static string[] GetDefaultLetterKeyIT(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "à" }; - case LetterKey.VK_E: - return new string[] { "è", "é", "€" }; - case LetterKey.VK_I: - return new string[] { "ì", "í" }; - case LetterKey.VK_O: - return new string[] { "ò", "ó" }; - case LetterKey.VK_U: - return new string[] { "ù", "ú" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "à" }, + LetterKey.VK_E => new string[] { "è", "é", "€" }, + LetterKey.VK_I => new string[] { "ì", "í" }, + LetterKey.VK_O => new string[] { "ò", "ó" }, + LetterKey.VK_U => new string[] { "ù", "ú" }, + _ => Array.Empty(), + }; } // Kurdish private static string[] GetDefaultLetterKeyKU(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_C: - return new string[] { "ç" }; - case LetterKey.VK_E: - return new string[] { "ê", "€" }; - case LetterKey.VK_I: - return new string[] { "î" }; - case LetterKey.VK_O: - return new string[] { "ö", "ô" }; - case LetterKey.VK_L: - return new string[] { "ł" }; - case LetterKey.VK_N: - return new string[] { "ň" }; - case LetterKey.VK_R: - return new string[] { "ř" }; - case LetterKey.VK_S: - return new string[] { "ş" }; - case LetterKey.VK_U: - return new string[] { "û", "ü" }; - } - - return Array.Empty(); + LetterKey.VK_C => new string[] { "ç" }, + LetterKey.VK_E => new string[] { "ê", "€" }, + LetterKey.VK_I => new string[] { "î" }, + LetterKey.VK_O => new string[] { "ö", "ô" }, + LetterKey.VK_L => new string[] { "ł" }, + LetterKey.VK_N => new string[] { "ň" }, + LetterKey.VK_R => new string[] { "ř" }, + LetterKey.VK_S => new string[] { "ş" }, + LetterKey.VK_U => new string[] { "û", "ü" }, + _ => Array.Empty(), + }; } // Welsh private static string[] GetDefaultLetterKeyCY(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "â" }; - case LetterKey.VK_E: - return new string[] { "ê" }; - case LetterKey.VK_I: - return new string[] { "î" }; - case LetterKey.VK_O: - return new string[] { "ô" }; - case LetterKey.VK_U: - return new string[] { "û" }; - case LetterKey.VK_Y: - return new string[] { "ŷ" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "â" }, + LetterKey.VK_E => new string[] { "ê" }, + LetterKey.VK_I => new string[] { "î" }, + LetterKey.VK_O => new string[] { "ô" }, + LetterKey.VK_U => new string[] { "û" }, + LetterKey.VK_Y => new string[] { "ŷ" }, + _ => Array.Empty(), + }; } // Swedish private static string[] GetDefaultLetterKeySV(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_A: - return new string[] { "å", "ä" }; - case LetterKey.VK_O: - return new string[] { "ö" }; - } - - return Array.Empty(); + LetterKey.VK_A => new string[] { "å", "ä" }, + LetterKey.VK_O => new string[] { "ö" }, + _ => Array.Empty(), + }; } // Serbian private static string[] GetDefaultLetterKeySR(LetterKey letter) { - switch (letter) + return letter switch { - case LetterKey.VK_C: - return new string[] { "ć", "č" }; - case LetterKey.VK_D: - return new string[] { "đ" }; - case LetterKey.VK_S: - return new string[] { "š" }; - case LetterKey.VK_Z: - return new string[] { "ž" }; - } - - return Array.Empty(); + LetterKey.VK_C => new string[] { "ć", "č" }, + LetterKey.VK_D => new string[] { "đ" }, + LetterKey.VK_S => new string[] { "š" }, + LetterKey.VK_Z => new string[] { "ž" }, + _ => Array.Empty(), + }; } } } diff --git a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj index e1b9fe8311..338a68c9c3 100644 --- a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj +++ b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj @@ -17,12 +17,14 @@ + + - + diff --git a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.cs b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.cs index d1a0e912a8..b189298ec1 100644 --- a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.cs +++ b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.cs @@ -2,6 +2,9 @@ // 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 PowerAccent.Core.Services; using PowerAccent.Core.Tools; @@ -13,20 +16,31 @@ 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(); - + private string[] _characterDescriptions = Array.Empty(); private int _selectedIndex = -1; + private bool _showUnicodeDescription; + + public LetterKey[] LetterKeysShowingDescription => _letterKeysShowingDescription; + + public bool ShowUnicodeDescription => _showUnicodeDescription; + + public string[] CharacterDescriptions => _characterDescriptions; public event Action OnChangeDisplay; public event Action OnSelectCharacter; - private KeyboardListener _keyboardListener; + private readonly KeyboardListener _keyboardListener; public PowerAccent() { + LoadUnicodeInfoCache(); + _keyboardListener = new KeyboardListener(); _keyboardListener.InitHook(); _settingService = new SettingsService(_keyboardListener); @@ -34,6 +48,11 @@ public class PowerAccent : IDisposable SetEvents(); } + private void LoadUnicodeInfoCache() + { + UnicodeInfo.GetCharInfo(0); + } + private void SetEvents() { _keyboardListener.SetShowToolbarEvent(new PowerToys.PowerAccentKeyboardService.ShowToolbar((LetterKey letterKey) => @@ -70,14 +89,79 @@ public class PowerAccent : IDisposable { _visible = true; _characters = (WindowsFunctions.IsCapsLockState() || WindowsFunctions.IsShiftState()) ? ToUpper(Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang)) : Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang); + _characterDescriptions = GetCharacterDescriptions(_characters); + + _showUnicodeDescription = _settingService.ShowUnicodeDescription; + Task.Delay(_settingService.InputTime).ContinueWith( - t => + t => + { + if (_visible) { - if (_visible) - { - OnChangeDisplay?.Invoke(true, _characters); - } - }, TaskScheduler.FromCurrentSynchronizationContext()); + OnChangeDisplay?.Invoke(true, _characters); + } + }, TaskScheduler.FromCurrentSynchronizationContext()); + } + + private string GetCharacterDescription(string character) + { + List unicodeList = new List(); + 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(); + foreach (string character in characters) + { + charInfoCollection = charInfoCollection.Append(GetCharacterDescription(character)).ToArray(); + } + + return charInfoCollection; } private void SendInputAndHideToolbar(InputType inputType) @@ -212,14 +296,7 @@ public class PowerAccent : IDisposable string[] result = new string[array.Length]; for (int i = 0; i < array.Length; i++) { - if (array[i].Contains('ß')) - { - result[i] = "ẞ"; - } - else - { - result[i] = array[i].ToUpper(System.Globalization.CultureInfo.InvariantCulture); - } + result[i] = array[i].Contains('ß') ? "ẞ" : array[i].ToUpper(System.Globalization.CultureInfo.InvariantCulture); } return result; diff --git a/src/modules/poweraccent/PowerAccent.Core/Services/SettingsService.cs b/src/modules/poweraccent/PowerAccent.Core/Services/SettingsService.cs index 8376352e08..619a4433b8 100644 --- a/src/modules/poweraccent/PowerAccent.Core/Services/SettingsService.cs +++ b/src/modules/poweraccent/PowerAccent.Core/Services/SettingsService.cs @@ -10,6 +10,7 @@ using Microsoft.PowerToys.Settings.UI.Library.Utilities; using PowerToys.PowerAccentKeyboardService; using System.IO.Abstractions; using System.Text.Json; +using static Vanara.PInvoke.LANGID; public class SettingsService { @@ -91,6 +92,8 @@ public class SettingsService Position = Position.Center; break; } + + ShowUnicodeDescription = settings.Properties.ShowUnicodeDescription; } } catch (Exception ex) @@ -175,6 +178,21 @@ public class SettingsService _selectedLang = value; } } + + private bool _showUnicodeDescription; + + public bool ShowUnicodeDescription + { + get + { + return _showUnicodeDescription; + } + + set + { + _showUnicodeDescription = value; + } + } } public enum Position diff --git a/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs b/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs index 1dd34da316..7bdade3e0c 100644 --- a/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs +++ b/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs @@ -17,9 +17,8 @@ namespace PowerAccent.UI protected override void OnStartup(StartupEventArgs e) { const string appName = "QuickAccent"; - bool createdNew; - _mutex = new Mutex(true, appName, out createdNew); + _mutex = new Mutex(true, appName, out bool createdNew); if (!createdNew) { diff --git a/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj b/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj index 0c9de1d7f7..e1ca4058b4 100644 --- a/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj +++ b/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj @@ -29,7 +29,9 @@ + + diff --git a/src/modules/poweraccent/PowerAccent.UI/Selector.xaml b/src/modules/poweraccent/PowerAccent.UI/Selector.xaml index f91e41ac2c..83fd174741 100644 --- a/src/modules/poweraccent/PowerAccent.UI/Selector.xaml +++ b/src/modules/poweraccent/PowerAccent.UI/Selector.xaml @@ -3,72 +3,138 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="clr-namespace:PowerAccent" + xmlns:local="clr-namespace:PowerAccent.UI" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="MainWindow" - Width="50" - Height="50" + Height="120" + MinWidth="600" + AllowsTransparency="True" + Background="Transparent" + DataContext="{Binding RelativeSource={RelativeSource Self}}" ResizeMode="NoResize" ShowInTaskbar="False" SizeToContent="WidthAndHeight" Visibility="Collapsed" WindowStyle="None" mc:Ignorable="d"> - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + CornerRadius="8"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/poweraccent/PowerAccent.UI/Selector.xaml.cs b/src/modules/poweraccent/PowerAccent.UI/Selector.xaml.cs index ebef1609e4..197733493c 100644 --- a/src/modules/poweraccent/PowerAccent.UI/Selector.xaml.cs +++ b/src/modules/poweraccent/PowerAccent.UI/Selector.xaml.cs @@ -3,15 +3,39 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Unicode; using System.Windows; +using PowerToys.PowerAccentKeyboardService; using Point = PowerAccent.Core.Point; using Size = PowerAccent.Core.Size; namespace PowerAccent.UI; -public partial class Selector : Window, IDisposable +public partial class Selector : Window, IDisposable, INotifyPropertyChanged { - private Core.PowerAccent _powerAccent = new Core.PowerAccent(); + private readonly Core.PowerAccent _powerAccent = new (); + + private Visibility _characterNameVisibility = Visibility.Visible; + + public event PropertyChangedEventHandler PropertyChanged; + + public Visibility CharacterNameVisibility + { + get + { + return _characterNameVisibility; + } + + set + { + _characterNameVisibility = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CharacterNameVisibility))); + } + } public Selector() { @@ -31,11 +55,16 @@ public partial class Selector : Window, IDisposable private void PowerAccent_OnSelectionCharacter(int index, string character) { characters.SelectedIndex = index; + + characterName.Text = _powerAccent.CharacterDescriptions[index]; } private void PowerAccent_OnChangeDisplay(bool isActive, string[] chars) { + CharacterNameVisibility = _powerAccent.ShowUnicodeDescription ? Visibility.Visible : Visibility.Collapsed; + this.Visibility = isActive ? Visibility.Visible : Visibility.Collapsed; + if (isActive) { characters.ItemsSource = chars; @@ -52,7 +81,7 @@ public partial class Selector : Window, IDisposable private void CenterWindow() { UpdateLayout(); - Size window = new Size(((System.Windows.Controls.Panel)Application.Current.MainWindow.Content).ActualWidth, ((System.Windows.Controls.Panel)Application.Current.MainWindow.Content).ActualHeight); + Size window = new (((System.Windows.Controls.Panel)Application.Current.MainWindow.Content).ActualWidth, ((System.Windows.Controls.Panel)Application.Current.MainWindow.Content).ActualHeight); Point position = _powerAccent.GetDisplayCoordinates(window); this.Left = position.X; this.Top = position.Y; diff --git a/src/modules/poweraccent/PowerAccent/Program.cs b/src/modules/poweraccent/PowerAccent/Program.cs index 28f2712146..13e783a4f6 100644 --- a/src/modules/poweraccent/PowerAccent/Program.cs +++ b/src/modules/poweraccent/PowerAccent/Program.cs @@ -17,11 +17,11 @@ namespace PowerAccent; internal static class Program { + private static readonly CancellationTokenSource _tokenSource = new (); private const string PROGRAM_NAME = "QuickAccent"; private const string PROGRAM_APP_NAME = "PowerToys.PowerAccent"; private static App _application; private static int _powerToysRunnerPid; - private static CancellationTokenSource _tokenSource = new CancellationTokenSource(); [STAThread] public static void Main(string[] args) @@ -55,7 +55,7 @@ internal static class Program Task.Run( () => { - EventWaitHandle eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.PowerAccentExitEvent()); + EventWaitHandle eventHandle = new (false, EventResetMode.AutoReset, Constants.PowerAccentExitEvent()); if (eventHandle.WaitOne()) { Terminate(); diff --git a/src/settings-ui/Settings.UI.Library/PowerAccentProperties.cs b/src/settings-ui/Settings.UI.Library/PowerAccentProperties.cs index 0b1e76d4bc..c838c851f2 100644 --- a/src/settings-ui/Settings.UI.Library/PowerAccentProperties.cs +++ b/src/settings-ui/Settings.UI.Library/PowerAccentProperties.cs @@ -24,6 +24,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library [JsonPropertyName("excluded_apps")] public StringProperty ExcludedApps { get; set; } + [JsonPropertyName("show_description")] + public bool ShowUnicodeDescription { get; set; } + public PowerAccentProperties() { ActivationKey = PowerAccentActivationKey.Both; @@ -31,6 +34,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library InputTime = new IntProperty(200); SelectedLang = "ALL"; ExcludedApps = new StringProperty(); + ShowUnicodeDescription = false; } } } diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index cd2e188d6c..c9a1b1e0db 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -2525,6 +2525,9 @@ Activate by holding the key for the character you want to add an accent to, then The continuous capture mode will consume more resources when in use. Also, measurements will be excluded from screenshots and screen capture. pointer as in mouse pointer. Resources refer to things like CPU, GPU, RAM + + Show the Unicode code and name of the currently selected character + Disable when Game Mode is On diff --git a/src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs index f2adc823d6..1ce6fa197e 100644 --- a/src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs @@ -237,6 +237,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public bool ShowUnicodeDescription + { + get + { + return _powerAccentSettings.Properties.ShowUnicodeDescription; + } + + set + { + if (value != _powerAccentSettings.Properties.ShowUnicodeDescription) + { + _powerAccentSettings.Properties.ShowUnicodeDescription = value; + OnPropertyChanged(nameof(ShowUnicodeDescription)); + RaisePropertyChanged(); + } + } + } + private void RaisePropertyChanged([CallerMemberName] string propertyName = null) { // Notify UI of property change diff --git a/src/settings-ui/Settings.UI/Views/PowerAccentPage.xaml b/src/settings-ui/Settings.UI/Views/PowerAccentPage.xaml index 37c4452f2f..7cd4c4d75d 100644 --- a/src/settings-ui/Settings.UI/Views/PowerAccentPage.xaml +++ b/src/settings-ui/Settings.UI/Views/PowerAccentPage.xaml @@ -110,6 +110,9 @@ + + +