diff --git a/README.md b/README.md index 5df9375..814c59e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This is a mod that helps modders mod. - **Yellow event** - event that was recently triggered (< 20 sec) - **Gray event** - event that hasn't triggered for a while (< 60 sec) -![screenshot](https://i.imgur.com/Cb1D1P7.png) +![screenshot](https://i.imgur.com/oCfA2zs.png) ## Installation Extract the contents of the .zip into your KSP2 installation folder. @@ -34,5 +34,8 @@ private void YourMethodThatWillHandleTheEvent(MessageCenterMessage obj) ## Other features - pin events to the top +- ignore events you're not interested in +- log each triggering of an event to the KSP log +- get a list of all events that KSP2 can trigger - customize timings of colors and purges - export list to a JSON file inside mod folder diff --git a/ShowKSP2Events.sln b/ShowKSP2Events.sln index 3b6ff67..5f87592 100644 --- a/ShowKSP2Events.sln +++ b/ShowKSP2Events.sln @@ -11,8 +11,8 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {41FA02E6-F455-4B46-B838-3F5BC5A888E3}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {41FA02E6-F455-4B46-B838-3F5BC5A888E3}.Debug|Any CPU.Build.0 = Release|Any CPU + {41FA02E6-F455-4B46-B838-3F5BC5A888E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41FA02E6-F455-4B46-B838-3F5BC5A888E3}.Debug|Any CPU.Build.0 = Debug|Any CPU {41FA02E6-F455-4B46-B838-3F5BC5A888E3}.Release|Any CPU.ActiveCfg = Release|Any CPU {41FA02E6-F455-4B46-B838-3F5BC5A888E3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/ShowKSP2Events/assets/images/cross.png b/ShowKSP2Events/assets/images/cross.png new file mode 100644 index 0000000..f4a1e63 Binary files /dev/null and b/ShowKSP2Events/assets/images/cross.png differ diff --git a/ShowKSP2Events/assets/images/plus.png b/ShowKSP2Events/assets/images/plus.png new file mode 100644 index 0000000..6ea300a Binary files /dev/null and b/ShowKSP2Events/assets/images/plus.png differ diff --git a/ShowKSP2Events/swinfo.json b/ShowKSP2Events/swinfo.json index 2175ed6..dd1f146 100644 --- a/ShowKSP2Events/swinfo.json +++ b/ShowKSP2Events/swinfo.json @@ -1,22 +1,23 @@ { - "mod_id": "ShowKSP2Events", - "author": "Falki", - "name": "ShowKSP2Events", - "description": "Shows KSP2 events being triggered", - "source": "https://github.com/Falki-git/ShowKSP2Events", - "version": "1.2.0", - "version_check": "https://raw.githubusercontent.com/Falki-git/ShowKSP2Events/master/ShowKSP2Events/swinfo.json", - "dependencies": [ - { - "id": "SpaceWarp", - "version": { - "min": "1.0.1", - "max": "*" - } - } - ], - "ksp2_version": { - "min": "0.1.0", - "max": "*" - } + "spec": "1.3", + "mod_id": "com.github.falki.showksp2events", + "author": "Falki", + "name": "ShowKSP2Events", + "description": "Shows KSP2 events being triggered", + "source": "https://github.com/Falki-git/ShowKSP2Events", + "version": "1.3.0", + "version_check": "https://raw.githubusercontent.com/Falki-git/ShowKSP2Events/master/ShowKSP2Events/swinfo.json", + "dependencies": [ + { + "id": "com.github.x606.spacewarp", + "version": { + "min": "1.0.1", + "max": "*" + } + } + ], + "ksp2_version": { + "min": "0.1.0", + "max": "*" + } } diff --git a/ShowKSP2EventsProject/ExportMessages.cs b/ShowKSP2EventsProject/ExportMessages.cs index 3264529..06b7266 100644 --- a/ShowKSP2EventsProject/ExportMessages.cs +++ b/ShowKSP2EventsProject/ExportMessages.cs @@ -5,31 +5,30 @@ namespace ShowKSP2Events { [JsonObject(MemberSerialization.OptIn)] - internal class ExportMessages + public class ExportMessages { [JsonProperty] - internal string DateTimeCreated; + public string DateTimeCreated; [JsonProperty] - internal List Messages; + public List Messages; private static ManualLogSource _logger = BepInEx.Logging.Logger.CreateLogSource("ShowKSP2Events.ExportMessages"); private static int _fileNumber = 0; private static string _path => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), $"ShowKSP2Events_export({_fileNumber}).json"); - internal ExportMessages(List messages) + public ExportMessages(List messages) { Messages = messages; DateTimeCreated = DateTime.Now.ToString(); } - internal void Export() + public void Export() { try { while (File.Exists(_path)) _fileNumber++; - var data = new SettingsData(); File.WriteAllText(_path, JsonConvert.SerializeObject(this)); _logger.LogInfo("Export successful."); } @@ -38,5 +37,13 @@ internal void Export() _logger.LogError("Error trying to export data. Error description: " + ex); } } + + public void WriteAllToLog() + { + _logger.LogInfo($"Writing all {Messages.Count} messages to log..."); + + foreach (var message in Messages) + _logger.LogInfo($"{message.TypeName}"); + } } } diff --git a/ShowKSP2EventsProject/MessageInfo.cs b/ShowKSP2EventsProject/MessageInfo.cs index 899af56..40e8996 100644 --- a/ShowKSP2EventsProject/MessageInfo.cs +++ b/ShowKSP2EventsProject/MessageInfo.cs @@ -3,19 +3,21 @@ namespace ShowKSP2Events { - internal class MessageInfo + public class MessageInfo { - internal Type Type; + public Type Type; [JsonProperty] - internal string TypeName => Type.Name; + public string TypeName => Type.Name; [JsonProperty] - internal int Hits; - internal double TimeOfLastHit; + public int Hits; + public double TimeOfLastHit; [JsonProperty] - internal string DateTimeOfLastHit; - internal bool IsSticky; - internal bool IsPermaSticky; - internal bool IsStale; - internal bool JustHit => Time.time - TimeOfLastHit < Settings.JustHit; + public string DateTimeOfLastHit; + public bool IsIgnored; + public bool IsLogging; + public bool IsSticky; + public bool IsPermaSticky; + public bool IsStale; + public bool JustHit => Time.time - TimeOfLastHit < Settings.JustHit; } } diff --git a/ShowKSP2EventsProject/MessageListener.cs b/ShowKSP2EventsProject/MessageListener.cs index 6ce1e61..7d75839 100644 --- a/ShowKSP2EventsProject/MessageListener.cs +++ b/ShowKSP2EventsProject/MessageListener.cs @@ -6,11 +6,25 @@ namespace ShowKSP2Events { - internal class MessageListener - { - private ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("ShowKSP2Events.MessageListener"); + public class MessageListener + { + private ManualLogSource _logger = BepInEx.Logging.Logger.CreateLogSource("ShowKSP2Events.MessageListener"); + private static MessageListener _instance; - internal List Messages = new(); + public List Messages = new(); + + public MessageListener () + { } + + public static MessageListener Instance + { + get + { + if (_instance == null) + _instance = new MessageListener(); + return _instance; + } + } internal void InitializeSubscriptions() { @@ -41,11 +55,11 @@ internal void InitializeSubscriptions() } catch (Exception ex) { - Logger.LogError(ex); + _logger.LogError(ex); } } - Logger.LogInfo($"Subscriptions initialized. No. of subscriptions: {Messages.Count}"); + _logger.LogInfo($"Subscriptions initialized. No. of subscriptions: {Messages.Count}"); } private void AddSubscription(Type messageType) @@ -62,6 +76,9 @@ private void MessageReceived(MessageCenterMessage messageReceived) messageInfo.IsSticky = true; messageInfo.IsStale = false; + if (messageInfo.IsLogging) + _logger.LogInfo($"Message {messageInfo.TypeName} triggered at {messageInfo.DateTimeOfLastHit}. Hit number: {messageInfo.Hits}."); + if (!messageInfo.IsPermaSticky && !messageInfo.IsSticky) MoveToBelowLastSticky(messageInfo); } @@ -73,14 +90,14 @@ private void MoveToBelowLastSticky(MessageInfo message) Messages.Insert(lastStickyIndex == -1 ? 0 : lastStickyIndex + 1, message); } - private void MoveToBelowLastPermaSticky(MessageInfo message) + internal void MoveToBelowLastPermaSticky(MessageInfo message) { Messages.Remove(message); int lastPermaStickyIndex = Messages.FindLastIndex(m => m.IsPermaSticky); Messages.Insert(lastPermaStickyIndex == -1 ? 0 : lastPermaStickyIndex + 1, message); } - internal void UnSticky(MessageInfo message) + public void UnSticky(MessageInfo message) { var messageInfo = Messages.Find(m => m.Type == message.Type); messageInfo.IsSticky = false; @@ -111,29 +128,59 @@ internal void CheckStales() } } - internal void OnPermaStickyClicked(Type messageType) + public void OnExportClicked() { - var message = Messages.Find(m => m.Type == messageType); - message.IsPermaSticky = !message.IsPermaSticky; - MoveToBelowLastPermaSticky(message); + var x = new ExportMessages(Messages.FindAll(m => m.Hits > 0)); + x.Export(); + } + + public void OnWriteAllToLogClicked() + { + var x = new ExportMessages(Messages); + x.WriteAllToLog(); } - internal void OnClearClicked() + public void OnClearClicked() { foreach (var message in Messages) { message.Hits = 0; message.TimeOfLastHit = 0; - message.IsPermaSticky = false; message.IsSticky = false; message.IsStale = true; } + + _logger.LogInfo($"Cleared all messages."); } - internal void OnExportClicked() + public void OnPermaStickyClicked(Type messageType) { - var x = new ExportMessages(Messages.FindAll(m => m.Hits > 0)); - x.Export(); + var message = Messages.Find(m => m.Type == messageType); + message.IsPermaSticky = !message.IsPermaSticky; + MoveToBelowLastPermaSticky(message); + Settings.Save(); + _logger.LogInfo($"Toggled pinning for {message.TypeName}."); + } + + public void OnIgnoredClicked(MessageInfo message) + { + message.IsIgnored = true; + _logger.LogInfo($"Message {message.TypeName} ignored."); + Settings.Save(); + } + + public void OnLoggingClicked(MessageInfo message) + { + message.IsLogging = !message.IsLogging; + _logger.LogInfo($"Toggled logging for {message.TypeName}."); + Settings.Save(); + } + + public void OnUnignoreMessageClicked(MessageInfo message) + { + message.IsIgnored = false; + _logger.LogInfo($"Message {message.TypeName} returned to active messages."); + Settings.Save(); } - } + } } diff --git a/ShowKSP2EventsProject/Settings.cs b/ShowKSP2EventsProject/Settings.cs index 760a0c9..60ac445 100644 --- a/ShowKSP2EventsProject/Settings.cs +++ b/ShowKSP2EventsProject/Settings.cs @@ -38,6 +38,25 @@ public static void Load() Settings.DurationTillPruned = data.DurationTillPruned; Settings.JustHit = data.JustHit; + // Load data for messages that have been modified (ignored, logging or stickied) + if (data.SavedMessages.Count() > 0) + { + var savedMessages = MessageListener.Instance.Messages + .FindAll(m => data.SavedMessages.Select(s => s.TypeName).Contains(m.TypeName)); + + foreach (var message in savedMessages) + { + var savedData = data.SavedMessages.Find(s => s.TypeName == message.TypeName); + message.IsIgnored = savedData.IsIgnored; + message.IsLogging = savedData.IsLogging; + if(savedData.IsPermaSticky) + { + message.IsPermaSticky = true; + MessageListener.Instance.MoveToBelowLastPermaSticky(message); + } + } + } + _logger.LogInfo("Settings loaded successfully."); } catch (FileNotFoundException ex) @@ -61,12 +80,42 @@ internal class SettingsData internal float DurationTillPruned; [JsonProperty] internal float JustHit; + [JsonProperty] + internal List SavedMessages; internal SettingsData() { StickyDuration = Settings.StickyDuration; DurationTillPruned = Settings.DurationTillPruned; JustHit = Settings.JustHit; + + var savedMessages = MessageListener.Instance.Messages + .Where(m => m.IsIgnored || m.IsLogging || m.IsPermaSticky); + + if (savedMessages.Count() > 0) + { + SavedMessages = new(); + + foreach (var m in savedMessages) + SavedMessages.Add(new() { + TypeName = m.TypeName, + IsIgnored = m.IsIgnored, + IsLogging = m.IsLogging, + IsPermaSticky = m.IsPermaSticky + }); + } } } + + internal class SettingsMessageData + { + [JsonProperty] + internal string TypeName; + [JsonProperty] + internal bool IsIgnored; + [JsonProperty] + internal bool IsLogging; + [JsonProperty] + internal bool IsPermaSticky; + } } \ No newline at end of file diff --git a/ShowKSP2EventsProject/ShowKSP2Events.cs b/ShowKSP2EventsProject/ShowKSP2Events.cs index 934c3b6..38b345a 100644 --- a/ShowKSP2EventsProject/ShowKSP2Events.cs +++ b/ShowKSP2EventsProject/ShowKSP2Events.cs @@ -23,9 +23,6 @@ public class ShowKSP2Events : BaseSpaceWarpPlugin private const string ToolbarFlightButtonID = "BTN-ShowKSP2EventsFlight"; private const string ToolbarOABButtonID = "BTN-ShowKSP2EventsOAB"; - private MessageListener _messageListener = new(); - private UI _ui = new(); - public override void OnInitialized() { base.OnInitialized(); @@ -51,10 +48,11 @@ public override void OnInitialized() GameObject.Find(ToolbarOABButtonID)?.GetComponent()?.SetValue(isOpen); } ); - Settings.Load(); + Styles.Initialize(); Textures.Initialize(this); - _messageListener.InitializeSubscriptions(); + MessageListener.Instance.InitializeSubscriptions(); + Settings.Load(); } private void OnGUI() @@ -62,19 +60,20 @@ private void OnGUI() GUI.skin = Skins.ConsoleSkin; if (_isWindowOpen) - _ui.DrawMessageListener(_messageListener); + UI.Instance.DrawMessageListener(); } private void Update() { try { - _messageListener.CheckStickies(); - _messageListener.CheckStales(); + MessageListener.Instance.CheckStickies(); + MessageListener.Instance.CheckStales(); } catch (InvalidOperationException ex) when (ex.Message.Contains("Collection was modified")) { // Sometimes update will fail because an event is in the process of modifying the MessageListener.Messages list + // or we're shuffling the list of messages } catch (Exception ex) { diff --git a/ShowKSP2EventsProject/ShowKSP2Events.csproj b/ShowKSP2EventsProject/ShowKSP2Events.csproj index bb72fd5..818c173 100644 --- a/ShowKSP2EventsProject/ShowKSP2Events.csproj +++ b/ShowKSP2EventsProject/ShowKSP2Events.csproj @@ -8,7 +8,7 @@ com.github.falki.showksp2events ShowKSP2Events Shows KSP2 events being triggered - 1.2.0 + 1.3.0 https://api.nuget.org/v3/index.json; https://nuget.bepinex.dev/v3/index.json @@ -29,10 +29,10 @@ - - + + - + diff --git a/ShowKSP2EventsProject/Styles.cs b/ShowKSP2EventsProject/Styles.cs index d1b443a..3931e30 100644 --- a/ShowKSP2EventsProject/Styles.cs +++ b/ShowKSP2EventsProject/Styles.cs @@ -3,26 +3,31 @@ namespace ShowKSP2Events { - internal static class Styles + public static class Styles { - internal static GUISkin SpaceWarpUISkin; - internal static GUIStyle LabelBase; - internal static GUIStyle MessageBase; - internal static GUIStyle MessageNormalColor; - internal static GUIStyle MessageStickyColor; - internal static GUIStyle MessageJustHitColor; - internal static GUIStyle Hits; - internal static GUIStyle PermaSticky; - internal static GUIStyle ExportButton; - internal static GUIStyle SettingsButton; - internal static Color NormalTextColor = Color.grey; - internal static Color StickyTextColor = Color.yellow; - internal static Color JustHitTextColor = Color.white; - internal static int SpacingAfterEntry = -12; - - internal static int SettingsWidth = 300; - - internal static void Initialize() + public static GUISkin SpaceWarpUISkin; + public static GUIStyle LabelBase; + public static GUIStyle MessageBase; + public static GUIStyle MessageNormalColor; + public static GUIStyle MessageStickyColor; + public static GUIStyle MessageJustHitColor; + public static GUIStyle Hits; + public static GUIStyle PermaSticky; + public static GUIStyle ExportButton; + public static GUIStyle SettingsButton; + public static GUIStyle IgnoreButton; + public static GUIStyle LogButtonDisabledButton; + public static GUIStyle LogButtonEnabledButton; + public static GUIStyle LogAllButton; + public static GUIStyle MessageLabel; + public static Color NormalTextColor = Color.grey; + public static Color StickyTextColor = Color.yellow; + public static Color JustHitTextColor = Color.white; + public static int SpacingAfterEntry = -12; + + public static int SettingsWidth = 300; + + public static void Initialize() { SpaceWarpUISkin = Skins.ConsoleSkin; @@ -74,6 +79,37 @@ internal static void Initialize() fixedWidth = 20, padding = new RectOffset(-2, -2, -2, -2) }; + + IgnoreButton = new GUIStyle(SpaceWarpUISkin.button) + { + fixedHeight = 15, + fixedWidth = 15, + padding = new RectOffset(0, 0, 0, 0) + }; + IgnoreButton.normal.background = null; + + LogButtonDisabledButton = new GUIStyle(SpaceWarpUISkin.button) + { + fixedHeight = 15, + fixedWidth = 20, + padding = new RectOffset(-2, -2, -2, -2) + }; + LogButtonDisabledButton.normal.background = null; + LogButtonDisabledButton.normal.textColor = new Color32(80, 80, 80, 255); // Dark gray + + LogButtonEnabledButton = new GUIStyle(LogButtonDisabledButton); + LogButtonEnabledButton.normal.textColor = Color.white; + + LogAllButton = new GUIStyle(SpaceWarpUISkin.button) + { + fixedHeight = 20, + fixedWidth = 50, + padding = new RectOffset(-2, -2, -2, -2) + }; + LogAllButton.normal.background = null; + + MessageLabel = new GUIStyle(SpaceWarpUISkin.label); + MessageLabel.normal.textColor = Color.green; } } } \ No newline at end of file diff --git a/ShowKSP2EventsProject/Textures.cs b/ShowKSP2EventsProject/Textures.cs index afff1b0..e95f6cb 100644 --- a/ShowKSP2EventsProject/Textures.cs +++ b/ShowKSP2EventsProject/Textures.cs @@ -4,19 +4,22 @@ namespace ShowKSP2Events { - internal static class Textures + public static class Textures { private static ShowKSP2Events _plugin; private static readonly ManualLogSource _logger = BepInEx.Logging.Logger.CreateLogSource("ShowKSP2Events.Textures"); - internal static Texture2D PermaStickyActive; - internal static Texture2D PermaStickyInactive; - internal static Texture2D Export; - internal static Texture2D Settings; + public static Texture2D PermaStickyActive; + public static Texture2D PermaStickyInactive; + public static Texture2D Export; + public static Texture2D Settings; + public static Texture2D Cross; + public static Texture2D Plus; - internal static void Initialize(ShowKSP2Events plugin) + public static void Initialize(ShowKSP2Events plugin) { // Icons from https://icons8.com + // Cross/Plus icons from K2D2 mod _plugin = plugin; @@ -24,6 +27,8 @@ internal static void Initialize(ShowKSP2Events plugin) PermaStickyInactive = LoadTexture($"{_plugin.SpaceWarpMetadata.ModID}/images/permasticky_inactive.png"); Export = LoadTexture($"{_plugin.SpaceWarpMetadata.ModID}/images/export-30.png"); Settings = LoadTexture($"{_plugin.SpaceWarpMetadata.ModID}/images/settings-20.png"); + Cross = LoadTexture($"{_plugin.SpaceWarpMetadata.ModID}/images/cross.png"); + Plus = LoadTexture($"{_plugin.SpaceWarpMetadata.ModID}/images/plus.png"); } private static Texture2D LoadTexture(string path) @@ -34,7 +39,7 @@ private static Texture2D LoadTexture(string path) } catch (Exception ex) { - _logger.LogError($"Error loading texture with path: {path}. Full error: \n{ex}"); + _logger.LogError($"Error loading texture with path: {path}. Full error:\n{ex}"); return new Texture2D(20, 20); } } diff --git a/ShowKSP2EventsProject/UI.cs b/ShowKSP2EventsProject/UI.cs index ef0b21e..2e2988f 100644 --- a/ShowKSP2EventsProject/UI.cs +++ b/ShowKSP2EventsProject/UI.cs @@ -4,24 +4,37 @@ namespace ShowKSP2Events { internal class UI { + private static UI _instance; private Rect _windowRect = new Rect(650, 140, 500, 100); private Rect _settingsRect; - private MessageListener _listener; + private string _statusBarMessage; + private float _statusBarMessageTime; private bool _showSettings; private float _justHitTemp; private float _stickyTemp; private float _tillPrunedTemp; - internal void DrawMessageListener(MessageListener listener) + internal UI() + { } + + internal static UI Instance { - _listener = listener; + get + { + if (_instance == null) + _instance = new UI(); + return _instance; + } + } + internal void DrawMessageListener() + { _windowRect = GUILayout.Window( GUIUtility.GetControlID(FocusType.Passive), _windowRect, FillMessageListener, - "// ShowKSP2Events", + " // ShowKSP2Events", GUILayout.Height(0) ); @@ -49,29 +62,69 @@ private void FillMessageListener(int windowID) _showSettings = !_showSettings; } if (GUILayout.Button(Textures.Export, Styles.ExportButton)) - _listener.OnExportClicked(); + { + MessageListener.Instance.OnExportClicked(); + PrintStatusBarMessage("Exported all messages to plugin folder."); + } + if (GUILayout.Button("LogAll", Styles.LogAllButton)) + { + MessageListener.Instance.OnWriteAllToLogClicked(); + PrintStatusBarMessage("All message types written to log."); + } + GUILayout.FlexibleSpace(); if (GUILayout.Button("Clear")) - _listener.OnClearClicked(); + { + MessageListener.Instance.OnClearClicked(); + PrintStatusBarMessage("Cleared all messages."); + } GUILayout.EndHorizontal(); - // Draw each message - foreach (var message in _listener.Messages.Where(m => m.Hits > 0 && !m.IsStale)) + try { - GUILayout.BeginHorizontal(); - if (GUILayout.Button(message.IsPermaSticky ? Textures.PermaStickyActive : Textures.PermaStickyInactive, Styles.PermaSticky)) - _listener.OnPermaStickyClicked(message.Type); - GUILayout.Space(5); - if (message.JustHit) - GUILayout.Label($"{message.Type.Name}: ", Styles.MessageJustHitColor); - else if (message.IsSticky) - GUILayout.Label($"{message.Type.Name}: ", Styles.MessageStickyColor); - else - GUILayout.Label($"{message.Type.Name}: ", Styles.MessageNormalColor); - GUILayout.FlexibleSpace(); - GUILayout.Label(message.Hits.ToString(), Styles.Hits); - GUILayout.EndHorizontal(); + // Draw each message + foreach (var message in MessageListener.Instance.Messages.Where(m => !m.IsIgnored && m.Hits > 0 && !m.IsStale)) + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button(Textures.Cross, Styles.IgnoreButton)) + MessageListener.Instance.OnIgnoredClicked(message); + GUILayout.Space(5); + + if (GUILayout.Button("LOG", message.IsLogging ? Styles.LogButtonEnabledButton : Styles.LogButtonDisabledButton)) + MessageListener.Instance.OnLoggingClicked(message); + GUILayout.Space(5); + + if (GUILayout.Button(message.IsPermaSticky ? Textures.PermaStickyActive : Textures.PermaStickyInactive, Styles.PermaSticky)) + MessageListener.Instance.OnPermaStickyClicked(message.Type); + GUILayout.Space(5); + + if (message.JustHit) + GUILayout.Label($"{message.Type.Name}: ", Styles.MessageJustHitColor); + else if (message.IsSticky) + GUILayout.Label($"{message.Type.Name}: ", Styles.MessageStickyColor); + else + GUILayout.Label($"{message.Type.Name}: ", Styles.MessageNormalColor); + + GUILayout.FlexibleSpace(); + GUILayout.Label(message.Hits.ToString(), Styles.Hits); + GUILayout.EndHorizontal(); + GUILayout.Space(Styles.SpacingAfterEntry); + } + } + catch (InvalidOperationException ex) when (ex.Message.Contains("Collection was modified")) + { + // Sometimes drawing will fail because an event is in the process of modifying the MessageListener.Messages list + // or we're shuffling the list of messages + } + + // Draw status bar message + if (Time.time - _statusBarMessageTime < 2) + { + GUILayout.BeginVertical(); + GUILayout.Label("--"); GUILayout.Space(Styles.SpacingAfterEntry); + GUILayout.Label(_statusBarMessage, Styles.MessageLabel); + GUILayout.EndVertical(); } GUI.DragWindow(new Rect(0, 0, Screen.width, Screen.height)); @@ -96,7 +149,36 @@ private void FillSettings(int windowID) Settings.DurationTillPruned = _tillPrunedTemp; Settings.Save(); _showSettings = false; + PrintStatusBarMessage("Settings saved."); + } + + // Draw ignored messages + var ignoredMessages = MessageListener.Instance.Messages.Where(m => m.IsIgnored); + + if (ignoredMessages.Count() > 0) + { + GUILayout.Space(5); + GUILayout.Label("--"); + GUILayout.Space(Styles.SpacingAfterEntry); + GUILayout.Label("Ignored events:"); + GUILayout.Space(5); + + foreach (var message in ignoredMessages) + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button(Textures.Plus, Styles.IgnoreButton)) + MessageListener.Instance.OnUnignoreMessageClicked(message); + GUILayout.Label(message.TypeName, Styles.LabelBase); + GUILayout.EndHorizontal(); + GUILayout.Space(Styles.SpacingAfterEntry); + } } } + + private void PrintStatusBarMessage(string text) + { + _statusBarMessage = text; + _statusBarMessageTime = Time.time; + } } } diff --git a/ShowKSP2EventsProject/source images/cross.png b/ShowKSP2EventsProject/source images/cross.png new file mode 100644 index 0000000..f4a1e63 Binary files /dev/null and b/ShowKSP2EventsProject/source images/cross.png differ diff --git a/ShowKSP2EventsProject/source images/cross_plus.xcf b/ShowKSP2EventsProject/source images/cross_plus.xcf new file mode 100644 index 0000000..a95968f Binary files /dev/null and b/ShowKSP2EventsProject/source images/cross_plus.xcf differ diff --git a/ShowKSP2EventsProject/source images/export-30.png b/ShowKSP2EventsProject/source images/export-30.png new file mode 100644 index 0000000..bd6eaa2 Binary files /dev/null and b/ShowKSP2EventsProject/source images/export-30.png differ diff --git a/ShowKSP2EventsProject/source images/icon.png b/ShowKSP2EventsProject/source images/icon.png new file mode 100644 index 0000000..10bdefb Binary files /dev/null and b/ShowKSP2EventsProject/source images/icon.png differ diff --git a/ShowKSP2EventsProject/source images/mocks.png b/ShowKSP2EventsProject/source images/mocks.png new file mode 100644 index 0000000..16d64a9 Binary files /dev/null and b/ShowKSP2EventsProject/source images/mocks.png differ diff --git a/ShowKSP2EventsProject/source images/permasticky_active.png b/ShowKSP2EventsProject/source images/permasticky_active.png new file mode 100644 index 0000000..a1e7d51 Binary files /dev/null and b/ShowKSP2EventsProject/source images/permasticky_active.png differ diff --git a/ShowKSP2EventsProject/source images/permasticky_inactive.png b/ShowKSP2EventsProject/source images/permasticky_inactive.png new file mode 100644 index 0000000..e2eb9d5 Binary files /dev/null and b/ShowKSP2EventsProject/source images/permasticky_inactive.png differ diff --git a/ShowKSP2EventsProject/source images/plus.png b/ShowKSP2EventsProject/source images/plus.png new file mode 100644 index 0000000..6ea300a Binary files /dev/null and b/ShowKSP2EventsProject/source images/plus.png differ diff --git a/ShowKSP2EventsProject/source images/settings-20.png b/ShowKSP2EventsProject/source images/settings-20.png new file mode 100644 index 0000000..656d942 Binary files /dev/null and b/ShowKSP2EventsProject/source images/settings-20.png differ