@@ -9,182 +9,29 @@ namespace Flow.Launcher.Infrastructure.Hotkey
99{
1010 public record struct HotkeyModel
1111 {
12- public bool LeftAlt { get ; set ; }
13- public bool LeftShift { get ; set ; }
14- public bool LWin { get ; set ; }
15- public bool LeftCtrl { get ; set ; }
16- public bool RightAlt { get ; set ; }
17- public bool RightShift { get ; set ; }
18- public bool RWin { get ; set ; }
19- public bool RightCtrl { get ; set ; }
20-
2112 public string HotkeyRaw { get ; set ; } = string . Empty ;
2213 public string PreviousHotkey { get ; set ; } = string . Empty ;
2314
24- public Key CharKey { get ; set ; } = Key . None ;
25-
26- private static readonly Dictionary < Key , string > specialSymbolDictionary = new Dictionary < Key , string >
27- {
28- { Key . Space , "Space" } , { Key . Oem3 , "~" }
29- } ;
30-
31- public ModifierKeys ModifierKeys
32- {
33- get
34- {
35- ModifierKeys modifierKeys = ModifierKeys . None ;
36- if ( LeftAlt || RightAlt )
37- {
38- modifierKeys |= ModifierKeys . Alt ;
39- }
40-
41- if ( LeftShift || RightShift )
42- {
43- modifierKeys |= ModifierKeys . Shift ;
44- }
45-
46- if ( LWin || RWin )
47- {
48- modifierKeys |= ModifierKeys . Windows ;
49- }
50-
51- if ( LeftCtrl || RightCtrl )
52- {
53- modifierKeys |= ModifierKeys . Control ;
54- }
55-
56- return modifierKeys ;
57- }
58- }
59-
60- // Used for WPF control only
61- public void SetHotkeyFromString ( string hotkeyString )
62- {
63- Clear ( ) ;
64- Parse ( hotkeyString ) ;
65- HotkeyRaw = FromWPFKeysToString ( ) ;
66- }
67-
68- internal void SetHotkeyFromWPFControl ( SpecialKeyState specialKeyState , Key key )
69- {
70- LeftAlt = specialKeyState . LeftAltPressed ;
71- LeftShift = specialKeyState . LeftShiftPressed ;
72- LWin = specialKeyState . LWinPressed ;
73- LeftCtrl = specialKeyState . LeftCtrlPressed ;
74- RightAlt = specialKeyState . RightAltPressed ;
75- RightShift = specialKeyState . RightShiftPressed ;
76- RWin = specialKeyState . RWinPressed ;
77- RightCtrl = specialKeyState . RightCtrlPressed ;
78- CharKey = key ;
79- HotkeyRaw = FromWPFKeysToString ( ) ;
80- PreviousHotkey = string . Empty ;
81- }
82-
15+ // HotkeyRaw always be without spaces round '+'. WPF Control hotkey string saved to settings will contain spaces.
8316 public HotkeyModel ( string hotkey )
8417 {
85- SetHotkeyFromString ( hotkey ) ;
18+ HotkeyRaw = ToHotkeyRawString ( hotkey ) ;
8619 }
8720
88- // Use for ChefKeys only
8921 internal void AddString ( string key )
9022 {
9123 HotkeyRaw = string . IsNullOrEmpty ( HotkeyRaw ) ? key : HotkeyRaw + "+" + key ;
92- Parse ( HotkeyRaw ) ;
9324 }
9425
26+ // Display in the form of WPF Control i.e. simplified text e.g. LeftAlt -> Alt
27+ public IEnumerable < string > EnumerateDisplayKeys ( ) => ! string . IsNullOrEmpty ( HotkeyRaw ) ? ToWPFHotkeyString ( ) . Split ( " + " ) : Array . Empty < string > ( ) ;
28+
9529 internal string GetLastKeySet ( ) => ! string . IsNullOrEmpty ( HotkeyRaw ) ? HotkeyRaw . Split ( '+' ) . Last ( ) : string . Empty ;
9630
9731 internal void Clear ( )
9832 {
99- LeftAlt = false ;
100- LeftShift = false ;
101- LWin = false ;
102- LeftCtrl = false ;
103- RightAlt = false ;
104- RightShift = false ;
105- RWin = false ;
106- RightCtrl = false ;
10733 HotkeyRaw = string . Empty ;
10834 PreviousHotkey = string . Empty ;
109- CharKey = Key . None ;
110- }
111-
112- private void Parse ( string hotkeyString )
113- {
114- if ( string . IsNullOrEmpty ( hotkeyString ) )
115- {
116- return ;
117- }
118-
119- List < string > keys = hotkeyString . Split ( '+' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries ) . ToList ( ) ;
120- if ( keys . Contains ( "Alt" ) || keys . Contains ( "LeftAlt" ) )
121- {
122- LeftAlt = true ;
123- keys . Remove ( "Alt" ) ;
124- keys . Remove ( "LeftAlt" ) ;
125- }
126- if ( keys . Contains ( "RightAlt" ) )
127- {
128- RightAlt = true ;
129- keys . Remove ( "RightAlt" ) ;
130- }
131-
132- if ( keys . Contains ( "Shift" ) || keys . Contains ( "LeftShift" ) )
133- {
134- LeftShift = true ;
135- keys . Remove ( "Shift" ) ;
136- keys . Remove ( "LeftShift" ) ;
137- }
138- if ( keys . Contains ( "RightShift" ) )
139- {
140- RightShift = true ;
141- keys . Remove ( "RightShift" ) ;
142- }
143-
144- if ( keys . Contains ( "Win" ) || keys . Contains ( "LWin" ) )
145- {
146- LWin = true ;
147- keys . Remove ( "Win" ) ;
148- keys . Remove ( "LWin" ) ;
149- }
150- if ( keys . Contains ( "RWin" ) )
151- {
152- RWin = true ;
153- keys . Remove ( "RWin" ) ;
154- }
155-
156- if ( keys . Contains ( "Ctrl" ) || keys . Contains ( "LeftCtrl" ) )
157- {
158- LeftCtrl = true ;
159- keys . Remove ( "Ctrl" ) ;
160- keys . Remove ( "LeftCtrl" ) ;
161- }
162- if ( keys . Contains ( "RightCtrl" ) )
163- {
164- RightCtrl = true ;
165- keys . Remove ( "RightCtrl" ) ;
166- }
167-
168- if ( keys . Count == 1 )
169- {
170- string charKey = keys [ 0 ] ;
171- KeyValuePair < Key , string > ? specialSymbolPair =
172- specialSymbolDictionary . FirstOrDefault ( pair => pair . Value == charKey ) ;
173- if ( specialSymbolPair . Value . Value != null )
174- {
175- CharKey = specialSymbolPair . Value . Key ;
176- }
177- else
178- {
179- try
180- {
181- CharKey = ( Key ) Enum . Parse ( typeof ( Key ) , charKey ) ;
182- }
183- catch ( ArgumentException )
184- {
185- }
186- }
187- }
18835 }
18936
19037 // WPF Control hotkey form i.e. simplified text e.g. LeftAlt+X -> Alt + X, includes space around '+'
@@ -221,59 +68,46 @@ public readonly string ToWPFHotkeyString()
22168 return hotkey ;
22269 }
22370
224- // Display in the form of WPF Control i.e. simplified text e.g. LeftAlt -> Alt
225- public IEnumerable < string > EnumerateDisplayKeys ( ) => ! string . IsNullOrEmpty ( HotkeyRaw ) ? ToWPFHotkeyString ( ) . Split ( " + " ) : Array . Empty < string > ( ) ;
226-
227- public string FromWPFKeysToString ( ) => string . Join ( "+" , EnumerateWPFKeys ( ) ) ;
228-
229- public IEnumerable < string > EnumerateWPFKeys ( )
71+ // Converts any WPF Control hotkey e.g. Alt + X -> LeftAlt+X
72+ public readonly string ToHotkeyRawString ( string wpfHotkey )
23073 {
231- if ( LeftCtrl && CharKey is not Key . LeftCtrl )
232- {
233- yield return "LeftCtrl" ;
234- }
235-
236- if ( LeftAlt && CharKey is not Key . LeftAlt )
237- {
238- yield return "LeftAlt" ;
239- }
74+ var hotkey = string . Empty ;
24075
241- if ( LeftShift && CharKey is not Key . LeftShift )
76+ foreach ( var key in wpfHotkey . Split ( '+' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries ) )
24277 {
243- yield return "LeftShift" ;
244- }
78+ if ( ! string . IsNullOrEmpty ( hotkey ) )
79+ hotkey += "+" ;
24580
246- if ( LWin && CharKey is not Key . LWin )
247- {
248- yield return "LWin" ;
249- }
250- if ( RightCtrl && CharKey is not Key . RightCtrl )
251- {
252- yield return "RightCtrl" ;
253- }
81+ switch ( key )
82+ {
83+ case "Ctrl" :
84+ hotkey += "LeftCtrl" ;
85+ break ;
86+ case "Alt" :
87+ hotkey += "LeftAlt" ;
88+ break ;
89+ case "Shift" :
90+ hotkey += "LeftShift" ;
91+ break ;
92+ case "Win" :
93+ hotkey += "LWin" ;
94+ break ;
25495
255- if ( RightAlt && CharKey is not Key . RightAlt )
256- {
257- yield return "RightAlt" ;
96+ default :
97+ hotkey += key ;
98+ break ;
99+ }
258100 }
259101
260- if ( RightShift && CharKey is not Key . RightShift )
261- {
262- yield return "RightShift" ;
263- }
102+ return hotkey ;
103+ }
264104
265- if ( RWin && CharKey is not Key . RWin )
266- {
267- yield return "RWin" ;
268- }
105+ public bool Alt { get ; set ; }
106+ public bool Shift { get ; set ; }
107+ public bool Win { get ; set ; }
108+ public bool Ctrl { get ; set ; }
269109
270- if ( CharKey != Key . None )
271- {
272- yield return specialSymbolDictionary . TryGetValue ( CharKey , out var value )
273- ? value
274- : CharKey . ToString ( ) ;
275- }
276- }
110+ public Key CharKey { get ; set ; } = Key . None ;
277111
278112 /// <summary>
279113 /// Validate hotkey for WPF control only
@@ -321,6 +155,103 @@ public bool ValidateForWpf(bool validateKeyGestrue = false)
321155 }
322156 }
323157
158+ private void Parse ( string hotkeyString )
159+ {
160+ if ( string . IsNullOrEmpty ( hotkeyString ) )
161+ {
162+ return ;
163+ }
164+
165+ List < string > keys = hotkeyString . Split ( '+' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries ) . ToList ( ) ;
166+
167+ if ( keys . Contains ( "Alt" ) || keys . Contains ( "LeftAlt" ) || keys . Contains ( "RightAlt" ) )
168+ {
169+ Alt = true ;
170+ keys . Remove ( "Alt" ) ;
171+ keys . Remove ( "LeftAlt" ) ;
172+ keys . Remove ( "RightAlt" ) ;
173+ }
174+
175+ if ( keys . Contains ( "Shift" ) || keys . Contains ( "LeftShift" ) || keys . Contains ( "RightShift" ) )
176+ {
177+ Shift = true ;
178+ keys . Remove ( "Shift" ) ;
179+ keys . Remove ( "LeftShift" ) ;
180+ keys . Remove ( "RightShift" ) ;
181+ }
182+
183+ if ( keys . Contains ( "Win" ) || keys . Contains ( "LWin" ) || keys . Contains ( "RWin" ) )
184+ {
185+ Win = true ;
186+ keys . Remove ( "Win" ) ;
187+ keys . Remove ( "LWin" ) ;
188+ keys . Remove ( "RWin" ) ;
189+ }
190+
191+ if ( keys . Contains ( "Ctrl" ) || keys . Contains ( "LeftCtrl" ) || keys . Contains ( "RightCtrl" ) )
192+ {
193+ Ctrl = true ;
194+ keys . Remove ( "Ctrl" ) ;
195+ keys . Remove ( "LeftCtrl" ) ;
196+ keys . Remove ( "RightCtrl" ) ;
197+ }
198+
199+ if ( keys . Count == 1 )
200+ {
201+ string charKey = keys [ 0 ] ;
202+ KeyValuePair < Key , string > ? specialSymbolPair =
203+ specialSymbolDictionary . FirstOrDefault ( pair => pair . Value == charKey ) ;
204+ if ( specialSymbolPair . Value . Value != null )
205+ {
206+ CharKey = specialSymbolPair . Value . Key ;
207+ }
208+ else
209+ {
210+ try
211+ {
212+ CharKey = ( Key ) Enum . Parse ( typeof ( Key ) , charKey ) ;
213+ }
214+ catch ( ArgumentException )
215+ {
216+ }
217+ }
218+ }
219+ }
220+
221+ private static readonly Dictionary < Key , string > specialSymbolDictionary = new Dictionary < Key , string >
222+ {
223+ { Key . Space , "Space" } , { Key . Oem3 , "~" }
224+ } ;
225+
226+ public ModifierKeys ModifierKeys
227+ {
228+ get
229+ {
230+ ModifierKeys modifierKeys = ModifierKeys . None ;
231+ if ( Alt )
232+ {
233+ modifierKeys |= ModifierKeys . Alt ;
234+ }
235+
236+ if ( Shift )
237+ {
238+ modifierKeys |= ModifierKeys . Shift ;
239+ }
240+
241+ if ( Win )
242+ {
243+ modifierKeys |= ModifierKeys . Windows ;
244+ }
245+
246+ if ( Ctrl )
247+ {
248+ modifierKeys |= ModifierKeys . Control ;
249+ }
250+
251+ return modifierKeys ;
252+ }
253+ }
254+
324255 private static bool IsPrintableCharacter ( Key key )
325256 {
326257 // https://stackoverflow.com/questions/11881199/identify-if-a-event-key-is-text-not-only-alphanumeric
@@ -349,7 +280,7 @@ private static bool IsPrintableCharacter(Key key)
349280
350281 public override int GetHashCode ( )
351282 {
352- return HashCode . Combine ( ModifierKeys , CharKey ) ;
283+ return HotkeyRaw . GetHashCode ( ) ;
353284 }
354285 }
355286}
0 commit comments