// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT #if !ANDROID using System; using System.Collections.Generic; using OpenTK.Input; namespace ClassicalSharp.Hotkeys { /// Maintains the list of hotkeys defined by the client and by SetTextHotkey packets. public sealed class HotkeyList { public List Hotkeys = new List(); /// Creates or updates an existing hotkey with the given baseKey and modifier flags. public void AddHotkey( Key baseKey, byte flags, string text, bool more ) { if( !UpdateExistingHotkey( baseKey, flags, text, more ) ) AddNewHotkey( baseKey, flags, text, more ); } /// Removes an existing hotkey with the given baseKey and modifier flags. /// Whether a hotkey with the given baseKey and modifier flags was found /// and subsequently removed. public bool RemoveHotkey( Key baseKey, byte flags ) { for( int i = 0; i < Hotkeys.Count; i++ ) { Hotkey hKey = Hotkeys[i]; if( hKey.BaseKey == baseKey && hKey.Flags == flags ) { Hotkeys.RemoveAt( i ); return true; } } return false; } bool UpdateExistingHotkey( Key baseKey, byte flags, string text, bool more ) { for( int i = 0; i < Hotkeys.Count; i++ ) { Hotkey hKey = Hotkeys[i]; if( hKey.BaseKey == baseKey && hKey.Flags == flags ) { hKey.Text = text; hKey.StaysOpen = more; Hotkeys[i] = hKey; return true; } } return false; } void AddNewHotkey( Key baseKey, byte flags, string text, bool more ) { Hotkey hotkey; hotkey.BaseKey = baseKey; hotkey.Flags = flags; hotkey.Text = text; hotkey.StaysOpen = more; Hotkeys.Add( hotkey ); // sort so that hotkeys with largest modifiers are first Hotkeys.Sort( (a, b) => b.Flags.CompareTo( a.Flags ) ); } /// Determines whether a hotkey is active based on the given key, /// and the currently active control, alt, and shift modifiers public bool IsHotkey( Key key, KeyboardDevice keyboard, out string text, out bool moreInput ) { byte flags = 0; if( keyboard[Key.ControlLeft] || keyboard[Key.ControlRight] ) flags |= 1; if( keyboard[Key.ShiftLeft] || keyboard[Key.ShiftRight] ) flags |= 2; if( keyboard[Key.AltLeft] || keyboard[Key.AltRight] ) flags |= 4; for( int i = 0; i < Hotkeys.Count; i++ ) { Hotkey hKey = Hotkeys[i]; if( (hKey.Flags & flags) == hKey.Flags && hKey.BaseKey == key ) { text = hKey.Text; moreInput = hKey.StaysOpen; return true; } } text = null; moreInput = false; return false; } const string prefix = "hotkey-"; public void LoadSavedHotkeys() { foreach( var pair in Options.OptionsSet ) { if( !Utils.CaselessStarts( pair.Key, prefix ) ) continue; int keySplit = pair.Key.IndexOf( '&', prefix.Length ); if( keySplit < 0 ) { Utils.LogDebug( "Hotkey {0} has an invalid key", pair.Key ); continue; } string strKey = pair.Key.Substring( prefix.Length, keySplit - prefix.Length ); string strFlags = pair.Key.Substring( keySplit + 1, pair.Key.Length - keySplit - 1 ); int valueSplit = pair.Value.IndexOf( '&', 0 ); if( valueSplit < 0 ) { Utils.LogDebug( "Hotkey {0} has an invalid value", pair.Key ); continue; } string strMoreInput = pair.Value.Substring( 0, valueSplit - 0 ); string strText = pair.Value.Substring( valueSplit + 1, pair.Value.Length - valueSplit - 1 ); // Then try to parse the key and value Key key; byte flags; bool moreInput; if( !Utils.TryParseEnum( strKey, Key.Unknown, out key ) || !Byte.TryParse( strFlags, out flags ) || !Boolean.TryParse( strMoreInput, out moreInput ) || strText.Length == 0 ) { Utils.LogDebug( "Hotkey {0} has invalid arguments", pair.Key ); continue; } AddHotkey( key, flags, strText, moreInput ); } } public void UserRemovedHotkey( Key baseKey, byte flags ) { string key = "hotkey-" + baseKey + "&" + flags; Options.Set( key, null ); } public void UserAddedHotkey( Key baseKey, byte flags, bool moreInput, string text ) { string key = "hotkey-" + baseKey + "&" + flags; string value = moreInput + "&" + text; Options.Set( key, value ); } } public struct Hotkey { public Key BaseKey; public byte Flags; // ctrl 1, shift 2, alt 4 public bool StaysOpen; // whether the user is able to enter further input public string Text; // contents to copy directly into the input bar } } #endif