VOID_WindowModule: Added cache-skipping option for decorated windows.
VOID_WindowModule: Added cache-skipping option for decorated windows.

--- a/API/VOID_Module.cs
+++ b/API/VOID_Module.cs
@@ -142,15 +142,6 @@
 		{
 			get
 			{
-
-				Tools.PostDebugMessage(
-					this,
-					"Checking if scene is valid: LoadedScene={0}, ValidScenes={1}, inValidScene={2}",
-					Enum.GetName(typeof(GameScenes), HighLogic.LoadedScene),
-					string.Join(", ", this.ValidScenes.Select(s => Enum.GetName(typeof(GameScenes), s)).ToArray()),
-					this.ValidScenes.Contains(HighLogic.LoadedScene)
-				);
-
 				return this.ValidScenes.Contains(HighLogic.LoadedScene);
 			}
 		}
@@ -199,15 +190,6 @@
 		{
 			get
 			{
-
-				Tools.PostDebugMessage(
-					this,
-					"Checking if mode is valid: CurrentGame.Mode={0}, ValidModes={1}, inValidGame={2}",
-					Enum.GetName(typeof(Game.Modes), HighLogic.CurrentGame.Mode),
-					string.Join(", ", this.ValidModes.Select(m => Enum.GetName(typeof(Game.Modes), m)).ToArray()),
-					this.ValidModes.Contains(HighLogic.CurrentGame.Mode)
-				);
-
 				return this.ValidModes.Contains(HighLogic.CurrentGame.Mode);
 			}
 		}
@@ -425,6 +407,10 @@
 
 	public abstract class VOID_WindowModule : VOID_Module
 	{
+		protected static GUIContent closeButton;
+
+		protected static Dictionary<int, Action<int>> DecoratedWindows;
+
 		[AVOID_SaveValue("WindowPos")]
 		protected Rect WindowPos;
 		protected float defWidth;
@@ -432,6 +418,18 @@
 
 		protected string inputLockName;
 
+		protected virtual Action<int> DecoratedWindow
+		{
+			get
+			{
+				return VOID_WindowModule.DecorateWindow(
+					this.ModuleWindow,
+					this.WindowPos,
+					(bool active) => { this.toggleActive = active; }
+				);
+			}
+		}
+
 		public VOID_WindowModule() : base()
 		{
 			this.defWidth = 250f;
@@ -453,7 +451,7 @@
 			_Pos = GUILayout.Window(
 				this.core.windowID,
 				_Pos,
-				VOID_Tools.GetWindowHandler(this.ModuleWindow),
+				VOID_Tools.GetWindowHandler(this.DecoratedWindow),
 				this.Name,
 				GUILayout.Width(this.defWidth),
 				GUILayout.Height(this.defHeight),
@@ -520,6 +518,70 @@
 				this.core.configDirty = true;
 			}
 		}
+
+		public static Action<int> DecorateWindow(Action<int> func, Rect windowRect, Callback<bool> callBack, bool useCache)
+		{
+			if (DecoratedWindows == null)
+			{
+				DecoratedWindows = new Dictionary<int, Action<int>>();
+			}
+
+			int hashCode = func.GetHashCode();
+
+			if (!useCache || !DecoratedWindows.ContainsKey(hashCode))
+			{
+				DecoratedWindows[hashCode] = delegate(int id)
+				{
+					func(id);
+
+					if (closeButton == null)
+					{
+						closeButton = new GUIContent("X");
+					}
+
+					Rect closeRect = GUILayoutUtility.GetRect(
+						closeButton,
+						VOID_Data.Core.Skin.button,
+						GUILayout.ExpandWidth(false)
+					);
+
+					closeRect.x = windowRect.width - closeRect.width - VOID_Data.Core.Skin.button.margin.right;
+					closeRect.y = VOID_Data.Core.Skin.button.margin.top;
+
+					GUI.Button(closeRect, closeButton, VOID_Data.Core.Skin.button);
+
+					if (Event.current.type == EventType.repaint && Input.GetMouseButtonUp(0))
+					{
+						if (closeRect.Contains(Event.current.mousePosition))
+						{
+							callBack(false);
+						}
+					}
+				};
+			}
+
+			return DecoratedWindows[hashCode];
+		}
+
+		public static Action<int> DecorateWindow(Action<int> func, Rect windowRect, Callback<bool> callBack)
+		{
+			return DecorateWindow(func, windowRect, callBack, true);
+		}
+
+		public static void UncacheWindow(Action<int> func)
+		{
+			if (DecoratedWindows != null)
+			{
+				int hashCode = func.GetHashCode();
+
+				if (DecoratedWindows.ContainsKey(hashCode))
+				{
+					VOID_Tools.UncacheWindow(DecoratedWindows[hashCode]);
+
+					DecoratedWindows.Remove(hashCode);
+				}
+			}
+		}
 	}
 }
 

--- a/Tools/VOID_Tools.cs
+++ b/Tools/VOID_Tools.cs
@@ -363,6 +363,19 @@
 			}
 
 			return functionCache[hashCode];
+		}
+
+		public static void UncacheWindow(Action<int> func)
+		{
+			if (functionCache != null)
+			{
+				int hashCode = func.GetHashCode();
+
+				if (functionCache.ContainsKey(hashCode))
+				{
+					functionCache.Remove(hashCode);
+				}
+			}
 		}
 
 		/// <summary>

--- a/VOIDCore_Generic.cs
+++ b/VOIDCore_Generic.cs
@@ -392,7 +392,12 @@
 				_mainWindowPos = GUILayout.Window(
 					this.windowID,
 					_mainWindowPos,
-					VOID_Tools.GetWindowHandler(this.VOIDMainWindow),
+					VOID_Tools.GetWindowHandler(
+						VOID_WindowModule.DecorateWindow(
+							this.VOIDMainWindow,
+							_mainWindowPos,
+							(bool active) => { this.mainGuiMinimized = !active; }
+						)),
 					string.Join(" ", new string[] { this.VoidName, this.VoidVersion }),
 					GUILayout.Width(250f),
 					GUILayout.Height(50f),
@@ -422,7 +427,11 @@
 				_configWindowPos = GUILayout.Window(
 					this.windowID,
 					_configWindowPos,
-					VOID_Tools.GetWindowHandler(this.VOIDConfigWindow),
+					VOID_Tools.GetWindowHandler(VOID_WindowModule.DecorateWindow(
+						this.VOIDConfigWindow,
+						_configWindowPos,
+						(bool active) => { this.configWindowMinimized = !active; }
+					)),
 					string.Join(" ", new string[] { this.VoidName, "Configuration" }),
 					GUILayout.Width(250),
 					GUILayout.Height(50)