namespace SRDebugger.Editor { using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; #if !DISABLE_SRDEBUGGER using SRDebugger.Internal; #endif using SRF; using UnityEditor; using UnityEditorInternal; using UnityEngine; class SRDebuggerSettingsWindow : EditorWindow { [MenuItem(SRDebugEditorPaths.SettingsMenuItemPath)] public static void Open() { GetWindowWithRect(new Rect(0, 0, 449, 520), true, "SRDebugger - Settings", true); } #if DISABLE_SRDEBUGGER private bool _isWorking; private void OnGUI() { SRDebugEditor.DrawDisabledWindowGui(ref _isWorking); } #else private enum ProfilerAlignment { TopLeft = 0, TopRight = 1, BottomLeft = 2, BottomRight = 3 } private enum OptionsAlignment { TopLeft = 0, TopRight = 1, BottomLeft = 2, BottomRight = 3, TopCenter = 6, BottomCenter = 7 } private string _currentEntryCode; private bool _enableTabChange = true; private Tabs _selectedTab; private bool _showBugReportSignupForm; private string[] _tabs = Enum.GetNames(typeof (Tabs)).Select(s => s.Replace('_', ' ')).ToArray(); [NonSerialized] private bool _hasError; [NonSerialized] private string _error; private bool _isAppearing = true; private void Reset() { if (_isAppearing) { return; } SRInternalEditorUtil.EditorSettings.ClearCache(); _hasError = false; } private bool SettingsReady(out Settings settings) { if (!_hasError) { string message; SRInternalEditorUtil.SettingsResult result = SRInternalEditorUtil.EditorSettings.TryGetOrCreate(out settings, out message); switch (result) { case SRInternalEditorUtil.SettingsResult.Loaded: { // Perform on-load logic _currentEntryCode = GetEntryCodeString(settings); if (string.IsNullOrEmpty(settings.ApiKey)) { _showBugReportSignupForm = true; } return true; } case SRInternalEditorUtil.SettingsResult.Cache: { return true; } case SRInternalEditorUtil.SettingsResult.Waiting: { EditorGUILayout.Space(); GUILayout.Label(message); return false; } case SRInternalEditorUtil.SettingsResult.Error: { _error = message; _hasError = true; break; } } } // Display Error UI settings = null; EditorGUILayout.Space(); GUILayout.Label("An error has occurred while loading settings."); EditorGUILayout.Space(); GUILayout.Label("Message: ", EditorStyles.boldLabel); GUILayout.Label(_error, SRInternalEditorUtil.Styles.ParagraphLabel); EditorGUILayout.Space(); if (GUILayout.Button("Open Integrity Checker")) { SRIntegrityCheckWindow.Open(); } if (GUILayout.Button("Retry")) { Reset(); Repaint(); } return false; } private void OnGUI() { _isAppearing = false; // Draw header area SRInternalEditorUtil.BeginDrawBackground(); SRInternalEditorUtil.DrawLogo(SRInternalEditorUtil.GetLogo()); SRInternalEditorUtil.EndDrawBackground(); // Draw header/content divider EditorGUILayout.BeginVertical(SRInternalEditorUtil.Styles.SettingsHeaderBoxStyle); EditorGUILayout.EndVertical(); Settings settings; if (!SettingsReady(out settings)) { return; } // Draw tab buttons var rect = EditorGUILayout.BeginVertical(GUI.skin.box); --rect.width; var height = 18; EditorGUI.BeginChangeCheck(); EditorGUI.BeginDisabledGroup(!_enableTabChange); for (var i = 0; i < _tabs.Length; ++i) { var xStart = Mathf.RoundToInt(i*rect.width/_tabs.Length); var xEnd = Mathf.RoundToInt((i + 1)*rect.width/_tabs.Length); var pos = new Rect(rect.x + xStart, rect.y, xEnd - xStart, height); if (GUI.Toggle(pos, (int) _selectedTab == i, new GUIContent(_tabs[i]), EditorStyles.toolbarButton)) { _selectedTab = (Tabs) i; } } GUILayoutUtility.GetRect(10f, height); EditorGUI.EndDisabledGroup(); if (EditorGUI.EndChangeCheck()) { _scrollPosition = Vector2.zero; GUIUtility.keyboardControl = 0; } // Draw selected tab switch (_selectedTab) { case Tabs.General: DrawTabGeneral(settings); break; case Tabs.Layout: DrawTabLayout(settings); break; case Tabs.Bug_Reporter: DrawTabBugReporter(settings); break; case Tabs.Shortcuts: DrawTabShortcuts(settings); break; case Tabs.Advanced: DrawTabAdvanced(settings); break; } EditorGUILayout.EndVertical(); // Display rating prompt and link buttons EditorGUILayout.LabelField(SRDebugEditorStrings.Current.SettingsRateBoxContents, EditorStyles.miniLabel); SRInternalEditorUtil.DrawFooterLayout(position.width); if (GUI.changed) { EditorUtility.SetDirty(settings); } } private enum Tabs { General, Layout, Bug_Reporter, Shortcuts, Advanced } #region Tabs private void DrawTabGeneral(Settings settings) { GUILayout.Label("Loading", SRInternalEditorUtil.Styles.InspectorHeaderStyle); EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); if (GUILayout.Toggle(!settings.IsEnabled, "Disabled", SRInternalEditorUtil.Styles.RadioButton)) { settings.IsEnabled = false; } GUILayout.Label("Do not load SRDebugger until a manual call to SRDebug.Init().", SRInternalEditorUtil.Styles.RadioButtonDescription); var msg = "Automatic (recommended)"; if (GUILayout.Toggle(settings.IsEnabled, msg, SRInternalEditorUtil.Styles.RadioButton)) { settings.IsEnabled = true; } GUILayout.Label("SRDebugger loads automatically when your game starts.", SRInternalEditorUtil.Styles.RadioButtonDescription); EditorGUILayout.EndVertical(); GUILayout.Label("Panel Access", SRInternalEditorUtil.Styles.InspectorHeaderStyle); EditorGUILayout.HelpBox("Configure trigger location in the layout tab.", MessageType.None, true); settings.EnableTrigger = (Settings.TriggerEnableModes) EditorGUILayout.EnumPopup(new GUIContent("Trigger Mode"), settings.EnableTrigger); EditorGUI.BeginDisabledGroup(settings.EnableTrigger == Settings.TriggerEnableModes.Off); settings.TriggerBehaviour = (Settings.TriggerBehaviours) EditorGUILayout.EnumPopup(new GUIContent("Trigger Behaviour"), settings.TriggerBehaviour); settings.ErrorNotification = EditorGUILayout.Toggle( new GUIContent("Error Notification", "Display a notification on the panel trigger when an error is printed to the log."), settings.ErrorNotification); EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); settings.DefaultTab = (DefaultTabs) EditorGUILayout.EnumPopup( new GUIContent("Default Tab", SRDebugEditorStrings.Current.SettingsDefaultTabTooltip), settings.DefaultTab); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); settings.RequireCode = EditorGUILayout.Toggle(new GUIContent("Require Entry Code"), settings.RequireCode); EditorGUI.BeginDisabledGroup(!settings.RequireCode); settings.RequireEntryCodeEveryTime = EditorGUILayout.Toggle(new GUIContent("...Every Time", "Require the user to enter the PIN every time they access the debug panel."), settings.RequireEntryCodeEveryTime); EditorGUILayout.EndHorizontal(); var newCode = EditorGUILayout.TextField("Entry Code", _currentEntryCode); if (newCode != _currentEntryCode) { // Strip out alpha numeric chars newCode = new string(newCode.Where(char.IsDigit).ToArray()); // Max length = 4 newCode = newCode.Substring(0, Mathf.Min(4, newCode.Length)); if (newCode.Length == 4) { UpdateEntryCode(settings, newCode); } } EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); settings.AutomaticallyShowCursor = EditorGUILayout.Toggle( new GUIContent("Show Cursor", "Automatically set the cursor to visible when the debug panel is opened, and revert when closed."), settings.AutomaticallyShowCursor); // Expand content area to fit all available space GUILayout.FlexibleSpace(); } private void DrawTabLayout(Settings settings) { GUILayout.Label("Pinned Tool Positions", SRInternalEditorUtil.Styles.HeaderLabel); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); var rect = GUILayoutUtility.GetRect(360, 210); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); SRInternalEditorUtil.DrawLayoutPreview(rect, settings); EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); GUILayout.Label("Console", SRInternalEditorUtil.Styles.InspectorHeaderStyle); settings.ConsoleAlignment = (ConsoleAlignment) EditorGUILayout.EnumPopup(settings.ConsoleAlignment); EditorGUILayout.EndVertical(); } { EditorGUI.BeginDisabledGroup(settings.EnableTrigger == Settings.TriggerEnableModes.Off); EditorGUILayout.BeginVertical(); GUILayout.Label("Entry Trigger", SRInternalEditorUtil.Styles.InspectorHeaderStyle); settings.TriggerPosition = (PinAlignment) EditorGUILayout.EnumPopup(settings.TriggerPosition); EditorGUILayout.EndVertical(); EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); GUILayout.Label("Profiler", SRInternalEditorUtil.Styles.InspectorHeaderStyle); settings.ProfilerAlignment = (PinAlignment) EditorGUILayout.EnumPopup((ProfilerAlignment)settings.ProfilerAlignment); EditorGUILayout.EndVertical(); } { EditorGUILayout.BeginVertical(); GUILayout.Label("Options", SRInternalEditorUtil.Styles.InspectorHeaderStyle); settings.OptionsAlignment = (PinAlignment) EditorGUILayout.EnumPopup((OptionsAlignment)settings.OptionsAlignment); EditorGUILayout.EndVertical(); } EditorGUILayout.EndHorizontal(); // Expand content area to fit all available space GUILayout.FlexibleSpace(); } private bool _enableButton; private void DrawTabBugReporter(Settings settings) { if (_showBugReportSignupForm) { DrawBugReportSignupForm(settings); return; } GUILayout.Label("Bug Reporter", SRInternalEditorUtil.Styles.HeaderLabel); EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(settings.ApiKey)); settings.EnableBugReporter = EditorGUILayout.Toggle("Enable Bug Reporter", settings.EnableBugReporter); settings.EnableBugReportScreenshot = EditorGUILayout.Toggle("Take Screenshot", settings.EnableBugReportScreenshot); EditorGUI.EndDisabledGroup(); EditorGUILayout.BeginHorizontal(); settings.ApiKey = EditorGUILayout.TextField("API Key", settings.ApiKey); if (GUILayout.Button("Verify", GUILayout.ExpandWidth(false))) { EditorUtility.DisplayDialog("Verify API Key", ApiSignup.Verify(settings.ApiKey), "OK"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); GUILayout.Label( "If you need to change your account email address, or have any other questions or concerns, please email us at contact@stompyrobot.uk.", SRInternalEditorUtil.Styles.ParagraphLabel); GUILayout.FlexibleSpace(); if (!string.IsNullOrEmpty(settings.ApiKey)) { GUILayout.Label("Reset", SRInternalEditorUtil.Styles.InspectorHeaderStyle); GUILayout.Label("Click the button below to clear the API key and show the signup form.", SRInternalEditorUtil.Styles.ParagraphLabel); EditorGUILayout.BeginHorizontal(); _enableButton = EditorGUILayout.Toggle("Enable Button", _enableButton, GUILayout.ExpandWidth(false)); EditorGUI.BeginDisabledGroup(!_enableButton); if (GUILayout.Button("Reset")) { settings.ApiKey = null; settings.EnableBugReporter = false; _enableButton = false; _showBugReportSignupForm = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); } else { if (GUILayout.Button("Show Signup Form")) { _showBugReportSignupForm = true; } } } private string _invoiceNumber; private string _emailAddress; private bool _agreeLegal; private string _errorMessage; private void DrawBugReportSignupForm(Settings settings) { var isWeb = false; #if UNITY_WEBPLAYER EditorGUILayout.HelpBox("Signup form is not available when build target is Web Player.", MessageType.Error); isWeb = true; #endif EditorGUI.BeginDisabledGroup(isWeb || !_enableTabChange); GUILayout.Label("Signup Form", SRInternalEditorUtil.Styles.HeaderLabel); GUILayout.Label( "SRDebugger requires a free API key to enable the bug reporter system. This form will acquire one for you.", SRInternalEditorUtil.Styles.ParagraphLabel); if ( SRInternalEditorUtil.ClickableLabel( "Already got an API key? Click here.".Fmt(SRInternalEditorUtil.Styles.LinkColour), SRInternalEditorUtil.Styles.RichTextLabel)) { _showBugReportSignupForm = false; Repaint(); } EditorGUILayout.Space(); GUILayout.Label("Invoice/Order Number", EditorStyles.boldLabel); GUILayout.Label( "Enter the order number from your Asset Store purchase email.", EditorStyles.miniLabel); _invoiceNumber = EditorGUILayout.TextField(_invoiceNumber); EditorGUILayout.Space(); GUILayout.Label("Email Address", EditorStyles.boldLabel); GUILayout.Label( "Provide an email address where the bug reports should be sent.", EditorStyles.miniLabel); _emailAddress = EditorGUILayout.TextField(_emailAddress); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); if (SRInternalEditorUtil.ClickableLabel( "I agree to the terms and conditions.".Fmt(SRInternalEditorUtil.Styles.LinkColour), SRInternalEditorUtil.Styles.RichTextLabel)) { ApiSignupTermsWindow.Open(); } _agreeLegal = EditorGUILayout.Toggle(_agreeLegal); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); var isEnabled = !string.IsNullOrEmpty(_invoiceNumber) && !string.IsNullOrEmpty(_emailAddress) && _agreeLegal; EditorGUI.BeginDisabledGroup(!isEnabled); if (GUILayout.Button("Submit")) { _errorMessage = null; _enableTabChange = false; EditorApplication.delayCall += () => { ApiSignup.SignUp(_emailAddress, _invoiceNumber, (success, key, email, error) => OnSignupResult(success, key, email, error, settings)); Repaint(); }; } EditorGUI.EndDisabledGroup(); if (!string.IsNullOrEmpty(_errorMessage)) { EditorGUILayout.HelpBox(_errorMessage, MessageType.Error, true); } GUILayout.FlexibleSpace(); GUILayout.Label("Having trouble? Please email contact@stompyrobot.uk for assistance.", EditorStyles.miniLabel); EditorGUI.EndDisabledGroup(); } private void OnSignupResult(bool didSucceed, string apiKey, string email, string error, Settings settings) { _enableTabChange = true; _selectedTab = Tabs.Bug_Reporter; if (!didSucceed) { _errorMessage = error; return; } settings.ApiKey = apiKey; settings.EnableBugReporter = true; EditorUtility.DisplayDialog("SRDebugger API", "API key has been created successfully. An email has been sent to your email address ({0}) with a verification link. You must verify your email before you can receive any bug reports." .Fmt(email), "OK"); _showBugReportSignupForm = false; } private ReorderableList _keyboardShortcutList; private Vector2 _scrollPosition; private void DrawTabShortcuts(Settings settings) { if (_keyboardShortcutList == null) { _keyboardShortcutList = new ReorderableList((IList) settings.KeyboardShortcuts, typeof (Settings.KeyboardShortcut), false, true, true, true); _keyboardShortcutList.drawHeaderCallback = DrawKeyboardListHeaderCallback; _keyboardShortcutList.drawElementCallback = DrawKeyboardListItemCallback; _keyboardShortcutList.onAddCallback += OnAddKeyboardListCallback; _keyboardShortcutList.onRemoveCallback += OnRemoveKeyboardListCallback; } EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); settings.EnableKeyboardShortcuts = EditorGUILayout.Toggle( new GUIContent("Enable", SRDebugEditorStrings.Current.SettingsKeyboardShortcutsTooltip), settings.EnableKeyboardShortcuts); EditorGUI.BeginDisabledGroup(!settings.EnableKeyboardShortcuts); settings.KeyboardEscapeClose = EditorGUILayout.Toggle( new GUIContent("Close on Esc", SRDebugEditorStrings.Current.SettingsCloseOnEscapeTooltip), settings.KeyboardEscapeClose); EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); var dupe = DetectDuplicateKeyboardShortcuts(settings); if (dupe != null) { var shortcut = ""; if (dupe.Control) { shortcut += "Ctrl"; } if (dupe.Shift) { if (shortcut.Length > 0) { shortcut += "-"; } shortcut += "Shift"; } if (dupe.Alt) { if (shortcut.Length > 0) { shortcut += "-"; } shortcut += "Alt"; } if (shortcut.Length > 0) { shortcut += "-"; } shortcut += dupe.Key; EditorGUILayout.HelpBox( "Duplicate shortcut ({0}). Only one shortcut per key is supported.".Fmt(shortcut), MessageType.Warning); } _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, false, false, GUILayout.Width(position.width - 11)); EditorGUILayout.BeginVertical(GUILayout.Width(position.width - 30)); _keyboardShortcutList.DoLayoutList(); GUILayout.FlexibleSpace(); EditorGUILayout.EndVertical(); EditorGUILayout.EndScrollView(); EditorGUI.EndDisabledGroup(); } private void DrawTabAdvanced(Settings settings) { _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, false, true); GUILayout.Label("Console", SRInternalEditorUtil.Styles.InspectorHeaderStyle); settings.CollapseDuplicateLogEntries = EditorGUILayout.Toggle( new GUIContent("Collapse Log Entries", "Collapse duplicate log entries into single log."), settings.CollapseDuplicateLogEntries); settings.RichTextInConsole = EditorGUILayout.Toggle( new GUIContent("Rich Text in Console", "Parse rich text tags in console log entries."), settings.RichTextInConsole); settings.MaximumConsoleEntries = EditorGUILayout.IntSlider( new GUIContent("Max Console Entries", "The maximum size of the console buffer. Higher values may cause performance issues on slower devices."), settings.MaximumConsoleEntries, 100, 6000); EditorGUILayout.Separator(); GUILayout.Label("Display", SRInternalEditorUtil.Styles.InspectorHeaderStyle); settings.EnableBackgroundTransparency = EditorGUILayout.Toggle(new GUIContent("Transparent Background"), settings.EnableBackgroundTransparency); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(new GUIContent("Layer", "The layer the debug panel UI will be drawn to")); settings.DebugLayer = EditorGUILayout.LayerField(settings.DebugLayer); EditorGUILayout.EndHorizontal(); settings.UseDebugCamera = EditorGUILayout.Toggle( new GUIContent("Use Debug Camera", SRDebugEditorStrings.Current.SettingsDebugCameraTooltip), settings.UseDebugCamera); EditorGUI.BeginDisabledGroup(!settings.UseDebugCamera); settings.DebugCameraDepth = EditorGUILayout.Slider(new GUIContent("Debug Camera Depth"), settings.DebugCameraDepth, -100, 100); EditorGUI.EndDisabledGroup(); settings.UIScale = EditorGUILayout.Slider(new GUIContent("UI Scale"), settings.UIScale, 1f, 3f); EditorGUILayout.Separator(); GUILayout.Label("Enabled Tabs", SRInternalEditorUtil.Styles.InspectorHeaderStyle); GUILayout.Label(SRDebugEditorStrings.Current.SettingsEnabledTabsDescription, EditorStyles.wordWrappedLabel); EditorGUILayout.Space(); var disabledTabs = settings.DisabledTabs.ToList(); var tabNames = Enum.GetNames(typeof (DefaultTabs)); var tabValues = Enum.GetValues(typeof (DefaultTabs)); EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); var changed = false; for (var i = 0; i < tabNames.Length; i++) { var tabName = tabNames[i]; var tabValue = (DefaultTabs) (tabValues.GetValue(i)); if (tabName == "BugReporter") { continue; } if (tabName == "SystemInformation") { tabName = "System Information"; } EditorGUILayout.BeginHorizontal(); var isEnabled = !disabledTabs.Contains(tabValue); var isNowEnabled = EditorGUILayout.ToggleLeft(tabName, isEnabled, SRInternalEditorUtil.Styles.LeftToggleButton); if (isEnabled && !isNowEnabled) { disabledTabs.Add(tabValue); changed = true; } else if (!isEnabled && isNowEnabled) { disabledTabs.Remove(tabValue); changed = true; } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); if (changed) { settings.DisabledTabs = disabledTabs; } GUILayout.Label("Other", SRInternalEditorUtil.Styles.InspectorHeaderStyle); settings.EnableEventSystemGeneration = EditorGUILayout.Toggle( new GUIContent("Automatic Event System", "Automatically create a UGUI EventSystem if none is found in the scene."), settings.EnableEventSystemGeneration); #if ENABLE_INPUT_SYSTEM && ENABLE_LEGACY_INPUT_MANAGER using (new EditorGUI.DisabledScope(!Settings.Instance.EnableEventSystemGeneration)) { Settings.Instance.UIInputMode = (Settings.UIModes) EditorGUILayout.EnumPopup(new GUIContent("Input Mode"), Settings.Instance.UIInputMode); } #endif settings.UnloadOnClose = EditorGUILayout.Toggle( new GUIContent("Unload When Closed", "Unload the debug panel from the scene when it is closed."), settings.UnloadOnClose); EditorGUILayout.HelpBox( "The panel loads again automatically when opened. You can always unload the panel by holding down the close button.", MessageType.Info); EditorGUILayout.Separator(); if (GUILayout.Button("Run Migrations")) { Migrations.RunMigrations(true); } EditorGUILayout.Separator(); GUILayout.Label("Disable SRDebugger (beta)", SRInternalEditorUtil.Styles.InspectorHeaderStyle); GUILayout.Label("Disabling will exclude any SRDebugger assets and scripts from your game.", SRInternalEditorUtil.Styles.ParagraphLabel); EditorGUILayout.HelpBox("This is an experimental feature. Please make sure your project is backed up via source control.", MessageType.Warning); GUILayout.Label("• " + SRDebugEditor.DisableSRDebuggerCompileDefine + " compiler define will be added to all build configurations.", SRInternalEditorUtil.Styles.ListBulletPoint); GUILayout.Label("• Some SRDebugger folders will be renamed to prevent Unity from importing them.", SRInternalEditorUtil.Styles.ListBulletPoint); GUILayout.Label("• Any code that interacts with SRDebugger (e.g. SROptions or SRDebug API) should use the `#if !"+ SRDebugEditor.DisableSRDebuggerCompileDefine + "` preprocessor directive.", SRInternalEditorUtil.Styles.ListBulletPoint); GUILayout.Label("• You can enable SRDebugger again at any time.", SRInternalEditorUtil.Styles.ListBulletPoint); if (GUILayout.Button("Disable SRDebugger")) { EditorApplication.delayCall += () => { SRDebugEditor.SetEnabled(false); Reset(); }; } EditorGUILayout.EndScrollView(); } #endregion #region Entry Code Utility private string GetEntryCodeString(Settings settings) { var entryCode = settings.EntryCode; if (entryCode.Count == 0) { settings.EntryCode = new[] {0, 0, 0, 0}; } var code = ""; for (var i = 0; i < entryCode.Count; i++) { code += entryCode[i]; } return code; } private void UpdateEntryCode(Settings settings, string str) { var newCode = new List(); for (var i = 0; i < str.Length; i++) { newCode.Add(int.Parse(str[i].ToString(), NumberStyles.Integer)); } settings.EntryCode = newCode; _currentEntryCode = GetEntryCodeString(settings); } #endregion #region Keyboard Shortcut Utility private Settings.KeyboardShortcut DetectDuplicateKeyboardShortcuts(Settings settings) { var s = settings.KeyboardShortcuts; return s.FirstOrDefault( shortcut => s.Any( p => p != shortcut && p.Shift == shortcut.Shift && p.Control == shortcut.Control && p.Alt == shortcut.Alt && p.Key == shortcut.Key)); } private void DrawKeyboardListHeaderCallback(Rect rect) { EditorGUI.LabelField(rect, "Keyboard Shortcuts"); } private void DrawKeyboardListItemCallback(Rect rect, int index, bool isActive, bool isFocused) { Settings settings; if (!SettingsReady(out settings)) { return; } var item = settings.KeyboardShortcuts[index]; rect.y += 2; var buttonWidth = 40; var padding = 5; item.Control = GUI.Toggle(new Rect(rect.x, rect.y, buttonWidth, EditorGUIUtility.singleLineHeight), item.Control, "Ctrl", "Button"); rect.x += buttonWidth + padding; rect.width -= buttonWidth + padding; item.Alt = GUI.Toggle(new Rect(rect.x, rect.y, buttonWidth, EditorGUIUtility.singleLineHeight), item.Alt, "Alt", "Button"); rect.x += buttonWidth + padding; rect.width -= buttonWidth + padding; item.Shift = GUI.Toggle(new Rect(rect.x, rect.y, buttonWidth, EditorGUIUtility.singleLineHeight), item.Shift, "Shift", "Button"); rect.x += buttonWidth + padding; rect.width -= buttonWidth + padding; item.Key = (KeyCode) EditorGUI.EnumPopup(new Rect(rect.x, rect.y, 80, EditorGUIUtility.singleLineHeight), item.Key); rect.x += 80 + padding; rect.width -= 80 + padding; item.Action = (Settings.ShortcutActions) EditorGUI.EnumPopup(new Rect(rect.x, rect.y, rect.width - 4, EditorGUIUtility.singleLineHeight), item.Action); } private void OnAddKeyboardListCallback(ReorderableList list) { Settings settings; if (!SettingsReady(out settings)) { return; } var shortcuts = settings.KeyboardShortcuts.ToList(); shortcuts.Add(new Settings.KeyboardShortcut()); settings.KeyboardShortcuts = shortcuts; list.list = (IList) settings.KeyboardShortcuts; } private void OnRemoveKeyboardListCallback(ReorderableList list) { Settings settings; if (!SettingsReady(out settings)) { return; } var shortcuts = settings.KeyboardShortcuts.ToList(); shortcuts.RemoveAt(list.index); settings.KeyboardShortcuts = shortcuts; list.list = (IList) settings.KeyboardShortcuts; } #endregion #endif } }