Overhauled Flight Engineer
Overhauled Flight Engineer

--- a/KerbalEngineer.sln
+++ b/KerbalEngineer.sln
@@ -1,21 +1,23 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KerbalEngineer", "KerbalEngineer\KerbalEngineer.csproj", "{39806613-E0B7-46E0-89A6-A569EC538CBB}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+

+Microsoft Visual Studio Solution File, Format Version 12.00

+# Visual Studio 2013

+VisualStudioVersion = 12.0.30110.0

+MinimumVisualStudioVersion = 10.0.40219.1

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KerbalEngineer", "KerbalEngineer\KerbalEngineer.csproj", "{39806613-E0B7-46E0-89A6-A569EC538CBB}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Any CPU = Debug|Any CPU

+		Release|Any CPU = Release|Any CPU

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{39806613-E0B7-46E0-89A6-A569EC538CBB}.Release|Any CPU.Build.0 = Release|Any CPU

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

 

--- a/KerbalEngineer/BuildEngineer/BuildAdvanced.cs
+++ /dev/null
@@ -1,565 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.Linq;

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Settings;

-using KerbalEngineer.Simulation;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.BuildEngineer

-{

-    [KSPAddon(KSPAddon.Startup.EditorAny, false)]

-    public class BuildAdvanced : MonoBehaviour

-    {

-        #region Instance

-

-        /// <summary>

-        ///     Gets the current instance if started or returns null.

-        /// </summary>

-        public static BuildAdvanced Instance { get; private set; }

-

-        #endregion

-

-        #region Fields

-

-        private readonly int windowId = EngineerGlobals.GetNextWindowId();

-

-        private bool hasChanged;

-        private bool isEditorLocked;

-        private int numberOfStages;

-        private Rect windowPosition = new Rect(265.0f, 45.0f, 0, 0);

-

-        #region Styles

-

-        private GUIStyle areaBodiesStyle;

-        private GUIStyle areaStyle;

-        private GUIStyle buttonStyle;

-        private GUIStyle infoStyle;

-        private GUIStyle titleStyle;

-        private GUIStyle windowStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Properties

-

-        private bool compactMode;

-        private bool showAllStages;

-        private bool showReferenceBodies;

-        private bool useAtmosphericDetails;

-        private bool visible;

-

-        /// <summary>

-        ///     Gets and sets whether the display is enabled.

-        /// </summary>

-        public bool Visible

-        {

-            get { return this.visible; }

-            set { this.visible = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether to show in compact mode.

-        /// </summary>

-        public bool CompactMode

-        {

-            get { return this.compactMode; }

-            set { this.compactMode = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether to show all stages.

-        /// </summary>

-        public bool ShowAllStages

-        {

-            get { return this.showAllStages; }

-            set { this.showAllStages = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether to use atmospheric details.

-        /// </summary>

-        public bool UseAtmosphericDetails

-        {

-            get { return this.useAtmosphericDetails; }

-            set { this.useAtmosphericDetails = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether to show the reference body selection.

-        /// </summary>

-        public bool ShowReferenceBodies

-        {

-            get { return this.showReferenceBodies; }

-            set { this.showReferenceBodies = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        private void Awake()

-        {

-            Instance = this;

-            this.Load();

-        }

-

-        private void Start()

-        {

-            this.InitialiseStyles();

-            RenderingManager.AddToPostDrawQueue(0, this.OnDraw);

-        }

-

-        /// <summary>

-        ///     Initialises all the styles that are required.

-        /// </summary>

-        private void InitialiseStyles()

-        {

-            this.areaBodiesStyle = new GUIStyle(HighLogic.Skin.box);

-

-            this.windowStyle = new GUIStyle(HighLogic.Skin.window)

-            {

-                alignment = TextAnchor.UpperLeft

-            };

-

-            this.areaStyle = new GUIStyle(HighLogic.Skin.box)

-            {

-                padding = new RectOffset(0, 0, 9, 0)

-            };

-

-            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                alignment = TextAnchor.MiddleCenter

-            };

-

-            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                alignment = TextAnchor.MiddleCenter,

-                stretchWidth = true

-            };

-

-            this.infoStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                alignment = TextAnchor.MiddleCenter,

-                stretchWidth = true

-            };

-        }

-

-        #endregion

-

-        #region Update and Drawing

-

-        private void Update()

-        {

-            try

-            {

-                if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.Count <= 0)

-                {

-                    return;

-                }

-

-                // Configure the simulation parameters based on the selected reference body.

-                SimulationManager.Gravity = CelestialBodies.Instance.SelectedBodyInfo.Gravity;

-                if (this.useAtmosphericDetails)

-                {

-                    SimulationManager.Atmosphere = CelestialBodies.Instance.SelectedBodyInfo.Atmosphere * 0.01d;

-                }

-                else

-                {

-                    SimulationManager.Atmosphere = 0;

-                }

-

-                SimulationManager.TryStartSimulation();

-            }

-            catch

-            {

-                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

-            }

-        }

-

-        private void OnDraw()

-        {

-            try

-            {

-                if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.Count <= 0)

-                {

-                    return;

-                }

-

-                SimulationManager.RequestSimulation();

-

-                // Change the window title based on whether in compact mode or not.

-                string title;

-                if (!this.compactMode)

-                {

-                    title = "KERBAL ENGINEER REDUX " + EngineerGlobals.AssemblyVersion;

-                }

-                else

-                {

-                    title = "K.E.R. " + EngineerGlobals.AssemblyVersion;

-                }

-

-                // Reset the window size when the staging or something else has changed.

-                int stageCount = SimulationManager.Stages.Count(stage => this.showAllStages || stage.DeltaV > 0);

-                if (this.hasChanged || stageCount != this.numberOfStages)

-                {

-                    this.hasChanged = false;

-                    this.numberOfStages = stageCount;

-

-                    this.windowPosition.width = 0;

-                    this.windowPosition.height = 0;

-                }

-

-                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, title, this.windowStyle).ClampToScreen();

-

-                // Check editor lock to manage click-through.

-                this.CheckEditorLock();

-            }

-            catch

-            {

-                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

-            }

-        }

-

-        /// <summary>

-        ///     Checks whether the editor should be locked to stop click-through.

-        /// </summary>

-        private void CheckEditorLock()

-        {

-            if (this.windowPosition.MouseIsOver())

-            {

-                EditorLogic.fetch.State = EditorLogic.EditorState.GUI_SELECTED;

-                this.isEditorLocked = true;

-            }

-            else if (!this.windowPosition.MouseIsOver() && this.isEditorLocked)

-            {

-                EditorLogic.fetch.State = EditorLogic.EditorState.PAD_UNSELECTED;

-                this.isEditorLocked = false;

-            }

-        }

-

-        /// <summary>

-        ///     Draws the OnGUI window.

-        /// </summary>

-        private void Window(int windowId)

-        {

-            // Draw the compact mode toggle.

-            if (GUI.Toggle(new Rect(this.windowPosition.width - 70.0f, 5.0f, 65.0f, 20.0f), this.compactMode, "COMPACT", this.buttonStyle) != this.compactMode)

-            {

-                this.hasChanged = true;

-                this.compactMode = !this.compactMode;

-            }

-

-            // When not in compact mode draw the 'All Stages' and 'Atmospheric' toggles.

-            if (!this.compactMode)

-            {

-                if (GUI.Toggle(new Rect(this.windowPosition.width - 153.0f, 5.0f, 80.0f, 20.0f), this.showAllStages, "ALL STAGES", this.buttonStyle) != this.showAllStages)

-                {

-                    this.hasChanged = true;

-                    this.showAllStages = !this.showAllStages;

-                }

-

-                this.useAtmosphericDetails = GUI.Toggle(new Rect(this.windowPosition.width - 251.0f, 5.0f, 95.0f, 20.0f), this.useAtmosphericDetails, "ATMOSPHERIC", this.buttonStyle);

-

-                if (GUI.Toggle(new Rect(this.windowPosition.width - 379.0f, 5.0f, 125.0f, 20.0f), this.showReferenceBodies, "REFERENCE BODIES", this.buttonStyle) != this.showReferenceBodies)

-                {

-                    this.hasChanged = true;

-                    this.showReferenceBodies = !this.showReferenceBodies;

-                }

-            }

-

-            // Draw the main informational display box.

-

-            if (!this.compactMode)

-            {

-                GUILayout.BeginHorizontal(this.areaStyle);

-                this.DrawStageNumbers();

-                this.DrawPartCount();

-                this.DrawCost();

-                this.DrawMass();

-                this.DrawIsp();

-                this.DrawThrust();

-                this.DrawTwr();

-                this.DrawDeltaV();

-                this.DrawBurnTime();

-                GUILayout.EndHorizontal();

-

-                if (this.showReferenceBodies)

-                {

-                    GUILayout.BeginVertical(this.areaBodiesStyle);

-                    this.DrawReferenceBodies();

-                    GUILayout.EndVertical();

-                }

-            }

-            else // Draw only a few details when in compact mode.

-            {

-                GUILayout.BeginHorizontal(this.areaStyle);

-                this.DrawStageNumbers();

-                this.DrawTwr();

-                this.DrawDeltaV();

-                GUILayout.EndHorizontal();

-            }

-

-            GUI.DragWindow();

-        }

-

-        /// <summary>

-        ///     Draws all the reference bodies.

-        /// </summary>

-        private void DrawReferenceBodies()

-        {

-            var index = 0;

-

-            foreach (var bodyName in CelestialBodies.Instance.BodyList.Keys)

-            {

-                if (index % 8 == 0)

-                {

-                    if (index > 0)

-                    {

-                        GUILayout.EndHorizontal();

-                    }

-                    GUILayout.BeginHorizontal();

-                }

-                if (GUILayout.Toggle(CelestialBodies.Instance.SelectedBodyName == bodyName, bodyName, this.buttonStyle))

-                {

-                    CelestialBodies.Instance.SelectedBodyName = bodyName;

-                }

-                index++;

-            }

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws the stage number column.

-        /// </summary>

-        private void DrawStageNumbers()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(30.0f));

-            GUILayout.Label(string.Empty, this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label("S" + stage.Number, this.titleStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Draws the part count column.

-        /// </summary>

-        private void DrawPartCount()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(50.0f));

-            GUILayout.Label("PARTS", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.PartCount.ToString("N0"), this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Draws the cost column.

-        /// </summary>

-        private void DrawCost()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(100.0f));

-            GUILayout.Label("COST", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.Cost.ToString("N0") + " / " + stage.TotalCost.ToString("N0"), this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Draws the mass column.

-        /// </summary>

-        private void DrawMass()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(100.0f));

-            GUILayout.Label("MASS", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.Mass.ToMass(false) + " / " + stage.TotalMass.ToMass(), this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Draws the specific impluse column.

-        /// </summary>

-        private void DrawIsp()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(50.0f));

-            GUILayout.Label("ISP", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.Isp.ToString("F1") + "s", this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Draws the thrust column.

-        /// </summary>

-        private void DrawThrust()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(75.0f));

-            GUILayout.Label("THRUST", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.Thrust.ToForce(), this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Drwas the thrust to weight ratio column.

-        /// </summary>

-        private void DrawTwr()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(50.0f));

-            GUILayout.Label("TWR", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.ThrustToWeight.ToString("F2"), this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Draws the deltaV column.

-        /// </summary>

-        private void DrawDeltaV()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(100.0f));

-            GUILayout.Label("DELTA-V", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.DeltaV.ToString("N0") + " / " + stage.InverseTotalDeltaV.ToString("N0") + "m/s", this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        /// <summary>

-        ///     Draws the burn time column.

-        /// </summary>

-        private void DrawBurnTime()

-        {

-            GUILayout.BeginVertical(GUILayout.Width(75.0f));

-            GUILayout.Label("BURN", this.titleStyle);

-            foreach (var stage in SimulationManager.Stages)

-            {

-                if (this.showAllStages || stage.DeltaV > 0)

-                {

-                    GUILayout.Label(stage.Time.ToTime(), this.infoStyle);

-                }

-            }

-            GUILayout.EndVertical();

-        }

-

-        #endregion

-

-        #region Save and Load

-

-        /// <summary>

-        ///     Saves the settings when this object is destroyed.

-        /// </summary>

-        private void OnDestroy()

-        {

-            try

-            {

-                var list = new SettingList();

-                list.AddSetting("visible", this.visible);

-                list.AddSetting("x", this.windowPosition.x);

-                list.AddSetting("y", this.windowPosition.y);

-                list.AddSetting("compact", this.compactMode);

-                list.AddSetting("all_stages", this.showAllStages);

-                list.AddSetting("atmosphere", this.useAtmosphericDetails);

-                list.AddSetting("bodies", this.showReferenceBodies);

-                list.AddSetting("selected_body", CelestialBodies.Instance.SelectedBodyName);

-                SettingList.SaveToFile(EngineerGlobals.AssemblyPath + "Settings/BuildAdvanced", list);

-

-                print("[KerbalEngineer/BuildAdvanced]: Successfully saved settings.");

-            }

-            catch

-            {

-                print("[KerbalEngineer/BuildAdvanced]: Failed to save settings.");

-            }

-        }

-

-        /// <summary>

-        ///     Loads the settings when this object is created.

-        /// </summary>

-        private void Load()

-        {

-            try

-            {

-                var list = SettingList.CreateFromFile(EngineerGlobals.AssemblyPath + "Settings/BuildAdvanced");

-                this.visible = (bool)list.GetSetting("visible", this.visible);

-                this.windowPosition.x = (float)list.GetSetting("x", this.windowPosition.x);

-                this.windowPosition.y = (float)list.GetSetting("y", this.windowPosition.y);

-                this.compactMode = (bool)list.GetSetting("compact", this.compactMode);

-                this.showAllStages = (bool)list.GetSetting("all_stages", this.showAllStages);

-                this.useAtmosphericDetails = (bool)list.GetSetting("atmosphere", this.useAtmosphericDetails);

-                this.showReferenceBodies = (bool)list.GetSetting("bodies", this.showReferenceBodies);

-                CelestialBodies.Instance.SelectedBodyName = (string)list.GetSetting("selected_body", "Kerbin");

-

-                print("[KerbalEngineer/BuildAdvanced]: Successfully loaded settings.");

-            }

-            catch

-            {

-                print("[KerbalEngineer/BuildAdvanced]: Failed to load settings.");

-            }

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/BuildEngineer/BuildButton.cs
+++ /dev/null
@@ -1,188 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.IO;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.BuildEngineer

-{

-    [KSPAddon(KSPAddon.Startup.EditorAny, false)]

-    public class BuildButton : MonoBehaviour

-    {

-        #region Fields

-

-        private readonly Texture2D down = new Texture2D(50, 45, TextureFormat.RGBA32, false);

-        private readonly Texture2D hover = new Texture2D(50, 45, TextureFormat.RGBA32, false);

-        private readonly Texture2D locked = new Texture2D(50, 45, TextureFormat.RGBA32, false);

-        private readonly Texture2D normal = new Texture2D(50, 45, TextureFormat.RGBA32, false);

-

-        private bool clicked;

-        private Rect position = new Rect(Screen.width * 0.5f - 300.0f, 0, 50.0f, 45.0f);

-

-        #region Styles

-

-        private GUIStyle tooltipInfoStyle;

-        private GUIStyle tooltipTitleStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Initialisation

-

-        private void Start()

-        {

-            // Load the button textures directly from the PNG files. (Would of used GameDatabase but it compresses them so it looks shit!)

-            this.normal.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Normal.png"));

-            this.hover.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Hover.png"));

-            this.down.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Down.png"));

-            this.locked.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Locked.png"));

-

-            this.InitialiseStyles();

-            RenderingManager.AddToPostDrawQueue(0, this.OnDraw);

-        }

-

-        /// <summary>

-        ///     Initialises all of the GUI styles that are required.

-        /// </summary>

-        private void InitialiseStyles()

-        {

-            this.tooltipTitleStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 13,

-                fontStyle = FontStyle.Bold

-            };

-

-            this.tooltipInfoStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                fontSize = 11,

-                fontStyle = FontStyle.Bold

-            };

-        }

-

-        #endregion

-

-        #region Update and Drawing

-

-        private void Update()

-        {

-            if (Input.GetKeyDown(KeyCode.Backslash))

-            {

-                LeftClick();

-            }

-        }

-

-        private void OnDraw()

-        {

-            if (EditorLogic.fetch.ship.Count > 0)

-            {

-                if (this.clicked) // Button has been clicked whilst being hovered.

-                {

-                    GUI.DrawTexture(this.position, this.down);

-

-                    if (this.position.Contains(Event.current.mousePosition)) // Mouse is hovering over the button.

-                    {

-                        this.DrawToolTip();

-

-                        if (Mouse.Left.GetButtonUp()) // The mouse up event has been triggered whilst over the button.

-                        {

-                            this.clicked = false;

-                            LeftClick();

-                        }

-                        else if (Mouse.Right.GetButtonUp())

-                        {

-                            this.clicked = false;

-                            RightClick();

-                        }

-                    }

-                }

-                else // The button is not registering as being clicked.

-                {

-                    if (this.position.Contains(Event.current.mousePosition)) // Mouse is hovering over the button.

-                    {

-                        // If the left mouse button has just been pressed, see the button as being clicked.

-                        if (!this.clicked && (Mouse.Left.GetButtonDown() || Mouse.Right.GetButtonDown()))

-                        {

-                            this.clicked = true;

-                        }

-

-                        if (this.clicked) // The button has just been clicked.

-                        {

-                            GUI.DrawTexture(this.position, this.down);

-                        }

-                        else if (!Mouse.Left.GetButton() && !Mouse.Right.GetButton()) // Mouse button is not down and is just hovering.

-                        {

-                            GUI.DrawTexture(this.position, this.hover);

-                            this.DrawToolTip();

-                        }

-                        else // Mouse button is down but no click was registered over the button.

-                        {

-                            GUI.DrawTexture(this.position, this.normal);

-                        }

-                    }

-                    else // The mouse is not being hovered.

-                    {

-                        GUI.DrawTexture(this.position, this.normal);

-                    }

-                }

-

-                // Check for an unclick event whilst the mouse is not hovering.

-                if (this.clicked && (Mouse.Left.GetButtonUp() || Mouse.Right.GetButtonUp()))

-                {

-                    this.clicked = false;

-                }

-            }

-            else // The editor is set as being locked.

-            {

-                GUI.DrawTexture(this.position, this.locked);

-            }

-        }

-

-        /// <summary>

-        ///     Draws the tooltop next to the mouse cursor.

-        /// </summary>

-        private void DrawToolTip()

-        {

-            GUI.Label(new Rect(Event.current.mousePosition.x + 16.0f, Event.current.mousePosition.y, 500.0f, 25.0f), "Kerbal Engineer Redux", this.tooltipTitleStyle);

-            GUI.Label(new Rect(Event.current.mousePosition.x + 16.0f, Event.current.mousePosition.y + 16.0f, 500.0f, 25.0f), "[Left Click / Backslash] Advanced - [Right Click] Overlay", this.tooltipInfoStyle);

-        }

-

-        #endregion

-

-        #region Static Methods

-

-        /// <summary>

-        ///     Runs when the button is clicked with the left mouse button.

-        /// </summary>

-        public static void LeftClick()

-        {

-            if (BuildAdvanced.Instance != null)

-            {

-                BuildAdvanced.Instance.Visible = !BuildAdvanced.Instance.Visible;

-            }

-        }

-

-        /// <summary>

-        ///     Runs when the button is clicked with the right mouse button.

-        /// </summary>

-        private static void RightClick()

-        {

-            if (BuildOverlay.Instance != null)

-            {

-                BuildOverlay.Instance.Visible = !BuildOverlay.Instance.Visible;

-            }

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/BuildEngineer/BuildOverlay.cs
+++ /dev/null
@@ -1,442 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.Diagnostics;

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Settings;

-using KerbalEngineer.Simulation;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.BuildEngineer

-{

-    [KSPAddon(KSPAddon.Startup.EditorAny, false)]

-    public class BuildOverlay : MonoBehaviour

-    {

-        #region Instance

-

-        /// <summary>

-        ///     Gets the current instance if started or returns null.

-        /// </summary>

-        public static BuildOverlay Instance { get; private set; }

-

-        #endregion

-

-        #region Fields

-

-        private readonly Stopwatch tooltipInfoTimer = new Stopwatch();

-        private readonly int windowId = EngineerGlobals.GetNextWindowId();

-        private Part selectedPart;

-        private Rect windowPosition = new Rect(265.0f, 0, 0, 0);

-

-        #region Styles

-

-        private GUIStyle infoStyle;

-        private GUIStyle titleStyle;

-        private GUIStyle tooltipInfoStyle;

-        private GUIStyle tooltipTitleStyle;

-        private GUIStyle windowStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Properties

-

-        private float tooltipInfoDelay = 0.5f;

-        private bool visible;

-

-        public float TooltipInfoDelay

-        {

-            get { return this.tooltipInfoDelay; }

-            set { this.tooltipInfoDelay = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether the display is enabled.

-        /// </summary>

-        public bool Visible

-        {

-            get { return this.visible; }

-            set { this.visible = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        private void Awake()

-        {

-            Instance = this;

-            this.Load();

-        }

-

-        private void Start()

-        {

-            this.InitialiseStyles();

-            RenderingManager.AddToPostDrawQueue(0, this.OnDraw);

-        }

-

-        private void InitialiseStyles()

-        {

-            this.windowStyle = new GUIStyle(GUIStyle.none)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset()

-            };

-

-            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                margin = new RectOffset(),

-                padding = new RectOffset(),

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-

-            this.infoStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset(),

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-

-            this.tooltipTitleStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-

-            this.tooltipInfoStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-        }

-

-        #endregion

-

-        #region Update and Drawing

-

-        private void Update()

-        {

-            try

-            {

-                if (EditorLogic.fetch == null || EditorLogic.SortedShipList.Count <= 0)

-                {

-                    return;

-                }

-

-                // Configure the simulation parameters based on the selected reference body.

-                SimulationManager.Gravity = CelestialBodies.Instance.SelectedBodyInfo.Gravity;

-

-                if (BuildAdvanced.Instance.UseAtmosphericDetails)

-                {

-                    SimulationManager.Atmosphere = CelestialBodies.Instance.SelectedBodyInfo.Atmosphere * 0.01d;

-                }

-                else

-                {

-                    SimulationManager.Atmosphere = 0;

-                }

-

-                SimulationManager.TryStartSimulation();

-            }

-            catch

-            {

-                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

-            }

-        }

-

-        private void OnDraw()

-        {

-            try

-            {

-                if (!this.visible || EditorLogic.fetch == null || EditorLogic.SortedShipList.Count <= 0 || EditorLogic.fetch.editorScreen != EditorLogic.EditorScreen.Parts)

-                {

-                    return;

-                }

-

-                SimulationManager.RequestSimulation();

-

-                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty, this.windowStyle);

-

-                // Check and set that the window is at the bottom of the screen.

-                if (this.windowPosition.y + this.windowPosition.height != Screen.height - 5.0f)

-                {

-                    this.windowPosition.y = Screen.height - this.windowPosition.height - 5.0f;

-                }

-

-                // Find if a part is selected or being hovered over.

-                if (EditorLogic.SelectedPart != null)

-                {

-                    // Do not allow the extended information to be shown.

-                    if (this.selectedPart != null)

-                    {

-                        this.selectedPart = null;

-                        this.tooltipInfoTimer.Reset();

-                    }

-

-                    this.DrawTooltip(EditorLogic.SelectedPart);

-                }

-                else

-                {

-                    var isPartSelected = false;

-                    foreach (var part in EditorLogic.SortedShipList)

-                    {

-                        if (part.stackIcon.highlightIcon)

-                        {

-                            // Start the extended information timer.

-                            if (part != this.selectedPart)

-                            {

-                                this.selectedPart = part;

-                                this.tooltipInfoTimer.Reset();

-                                this.tooltipInfoTimer.Start();

-                            }

-                            isPartSelected = true;

-

-                            this.DrawTooltip(part);

-                            break;

-                        }

-                    }

-

-                    // If no part is being hovered over we must reset the extended information timer.

-                    if (!isPartSelected && this.selectedPart != null)

-                    {

-                        this.selectedPart = null;

-                        this.tooltipInfoTimer.Reset();

-                    }

-                }

-            }

-            catch

-            {

-                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

-            }

-        }

-

-        private void Window(int windowId)

-        {

-            GUILayout.BeginHorizontal();

-

-            // Titles

-            GUILayout.BeginVertical(GUILayout.Width(75.0f));

-            GUILayout.Label("Parts:", this.titleStyle);

-            GUILayout.Label("Delta-V:", this.titleStyle);

-            GUILayout.Label("TWR:", this.titleStyle);

-            GUILayout.EndVertical();

-

-            // Details

-            GUILayout.BeginVertical(GUILayout.Width(100.0f));

-            GUILayout.Label(SimulationManager.LastStage.PartCount.ToString("N0"), this.infoStyle);

-            GUILayout.Label(SimulationManager.LastStage.TotalDeltaV.ToString("N0") + " m/s", this.infoStyle);

-            GUILayout.Label(SimulationManager.LastStage.ThrustToWeight.ToString("F2"), this.infoStyle);

-            GUILayout.EndVertical();

-

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws the tooltip details of the selected/highlighted part.

-        /// </summary>

-        private void DrawTooltip(Part part)

-        {

-            // Tooltip title (name of part).

-            var content = new GUIContent(part.partInfo.title);

-            var size = this.tooltipTitleStyle.CalcSize(content);

-            var position = new Rect(Event.current.mousePosition.x + 16.0f, Event.current.mousePosition.y, size.x, size.y).ClampInsideScreen();

-

-            if (position.x < Event.current.mousePosition.x + 16.0f)

-            {

-                position.y += 16.0f;

-            }

-            GUI.Label(position, content, this.tooltipTitleStyle);

-

-            // After hovering for a period of time, show extended information.

-            if (this.tooltipInfoTimer.Elapsed.TotalSeconds >= this.tooltipInfoDelay)

-            {

-                // Stop the timer as it is no longer needed.

-                if (this.tooltipInfoTimer.IsRunning)

-                {

-                    this.tooltipInfoTimer.Stop();

-                }

-

-                // Show the dry mass of the part if applicable.

-                if (part.physicalSignificance == Part.PhysicalSignificance.FULL)

-                {

-                    this.DrawTooltipInfo(ref position, "Dry Mass: " + part.GetDryMass().ToMass());

-                }

-

-                // Show resources contained within the part.

-                if (part.ContainsResources())

-                {

-                    // Show the wet mass of the part if applicable.

-                    if (part.GetResourceMass() > 0)

-                    {

-                        this.DrawTooltipInfo(ref position, "Wet Mass: " + part.GetWetMass().ToMass());

-                    }

-

-                    // List all the resources contained within the part.

-                    foreach (PartResource resource in part.Resources)

-                    {

-                        if (resource.GetDensity() > 0)

-                        {

-                            this.DrawTooltipInfo(ref position, resource.info.name + ": " + resource.GetMass().ToMass() + " (" + resource.amount + ")");

-                        }

-                        else

-                        {

-                            this.DrawTooltipInfo(ref position, resource.info.name + ": " + resource.amount);

-                        }

-                    }

-                }

-

-                // Show details for engines.

-                if (part.IsEngine())

-                {

-                    this.DrawTooltipInfo(ref position, "Maximum Thrust: " + part.GetMaxThrust().ToForce());

-                    this.DrawTooltipInfo(ref position, "Specific Impulse: " + part.GetSpecificImpulse(1f) + " / " + part.GetSpecificImpulse(0f) + "s");

-

-                    // Thrust vectoring.

-                    if (part.HasModule("ModuleGimbal"))

-                    {

-                        this.DrawTooltipInfo(ref position, "Thrust Vectoring Enabled");

-                    }

-

-                    // Contains alternator.

-                    if (part.HasModule("ModuleAlternator"))

-                    {

-                        this.DrawTooltipInfo(ref position, "Contains Alternator");

-                    }

-                }

-

-                // Show details for RCS.

-                if (part.IsRcsModule())

-                {

-                    var moduleRcs = part.GetModuleRcs();

-                    this.DrawTooltipInfo(ref position, "Thrust Power: " + moduleRcs.thrusterPower.ToDouble().ToForce());

-                    this.DrawTooltipInfo(ref position, "Specific Impulse: " + moduleRcs.atmosphereCurve.Evaluate(1f) + " / " + moduleRcs.atmosphereCurve.Evaluate(0f) + "s");

-                }

-

-                // Show details for solar panels.

-                if (part.IsSolarPanel())

-                {

-                    this.DrawTooltipInfo(ref position, "Charge Rate: " + part.GetModuleDeployableSolarPanel().chargeRate.ToDouble().ToRate());

-                }

-

-                // Show details for generators.

-                if (part.IsGenerator())

-                {

-                    foreach (var resource in part.GetModuleGenerator().inputList)

-                    {

-                        this.DrawTooltipInfo(ref position, "Input: " + resource.name + " (" + resource.rate.ToDouble().ToRate() + ")");

-                    }

-

-                    foreach (var resource in part.GetModuleGenerator().outputList)

-                    {

-                        this.DrawTooltipInfo(ref position, "Output: " + resource.name + " (" + resource.rate.ToDouble().ToRate() + ")");

-                    }

-                }

-

-                // Show details for parachutes.

-                if (part.IsParachute())

-                {

-                    var module = part.GetModuleParachute();

-                    this.DrawTooltipInfo(ref position, "Semi Deployed Drag: " + module.semiDeployedDrag);

-                    this.DrawTooltipInfo(ref position, "Fully Deployed Drag: " + module.fullyDeployedDrag);

-                    this.DrawTooltipInfo(ref position, "Deployment Altitude: " + module.deployAltitude.ToDouble().ToDistance());

-                }

-

-                // Contains stability augmentation system.

-                if (part.HasModule("ModuleSAS"))

-                {

-                    this.DrawTooltipInfo(ref position, "Contains SAS");

-                }

-

-                // Contains reaction wheels.

-                if (part.HasModule("ModuleReactionWheel"))

-                {

-                    this.DrawTooltipInfo(ref position, "Contains Reaction Wheels");

-                }

-

-                // Show if the part has an animation that can only be used once.

-                if (part.HasOneShotAnimation())

-                {

-                    this.DrawTooltipInfo(ref position, "Single Activation Only");

-                }

-            }

-        }

-

-        /// <summary>

-        ///     Draws a line of extended information below the previous.

-        /// </summary>

-        private void DrawTooltipInfo(ref Rect position, string value)

-        {

-            var content = new GUIContent(value);

-            var size = this.tooltipInfoStyle.CalcSize(content);

-

-            position.y += 16.0f;

-            position.width = size.x;

-            position.height = size.y;

-            GUI.Label(position, content, this.tooltipInfoStyle);

-        }

-

-        #endregion

-

-        #region Save and Load

-

-        /// <summary>

-        ///     Saves the settings when this object is destroyed.

-        /// </summary>

-        private void OnDestroy()

-        {

-            try

-            {

-                var list = new SettingList();

-                list.AddSetting("visible", this.visible);

-                SettingList.SaveToFile(EngineerGlobals.AssemblyPath + "Settings/BuildOverlay", list);

-

-                print("[KerbalEngineer/BuildOverlay]: Successfully saved settings.");

-            }

-            catch

-            {

-                print("[KerbalEngineer/BuildOverlay]: Failed to save settings.");

-            }

-        }

-

-        /// <summary>

-        ///     Loads the settings when this object is created.

-        /// </summary>

-        private void Load()

-        {

-            try

-            {

-                var list = SettingList.CreateFromFile(EngineerGlobals.AssemblyPath + "Settings/BuildOverlay");

-                this.visible = (bool) list.GetSetting("visible", this.visible);

-

-                print("[KerbalEngineer/BuildOverlay]: Successfully loaded settings.");

-            }

-            catch

-            {

-                print("[KerbalEngineer/BuildOverlay]: Failed to load settigns.");

-            }

-        }

-

-        #endregion

-    }

-}
+

--- /dev/null
+++ b/KerbalEngineer/Editor/BuildAdvanced.cs
@@ -1,1 +1,560 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Linq;

+

+using KerbalEngineer.Extensions;

+using KerbalEngineer.Settings;

+using KerbalEngineer.Simulation;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Editor

+{

+    [KSPAddon(KSPAddon.Startup.EditorAny, false)]

+    public class BuildAdvanced : MonoBehaviour

+    {

+        #region Instance

+

+        /// <summary>

+        ///     Gets the current instance if started or returns null.

+        /// </summary>

+        public static BuildAdvanced Instance { get; private set; }

+

+        #endregion

+

+        #region Fields

+

+        private readonly int windowId = EngineerGlobals.GetNextWindowId();

+

+        private bool hasChanged;

+        private bool isEditorLocked;

+        private int numberOfStages;

+        private Rect windowPosition = new Rect(265.0f, 45.0f, 0, 0);

+

+        #region Styles

+

+        private GUIStyle areaBodiesStyle;

+        private GUIStyle areaStyle;

+        private GUIStyle buttonStyle;

+        private GUIStyle infoStyle;

+        private GUIStyle titleStyle;

+        private GUIStyle windowStyle;

+

+        #endregion

+

+        #endregion

+

+        #region Properties

+

+        private bool compactMode;

+        private bool showAllStages;

+        private bool showReferenceBodies;

+        private bool useAtmosphericDetails;

+        private bool visible;

+

+        /// <summary>

+        ///     Gets and sets whether the display is enabled.

+        /// </summary>

+        public bool Visible

+        {

+            get { return this.visible; }

+            set { this.visible = value; }

+        }

+

+        /// <summary>

+        ///     Gets and sets whether to show in compact mode.

+        /// </summary>

+        public bool CompactMode

+        {

+            get { return this.compactMode; }

+            set { this.compactMode = value; }

+        }

+

+        /// <summary>

+        ///     Gets and sets whether to show all stages.

+        /// </summary>

+        public bool ShowAllStages

+        {

+            get { return this.showAllStages; }

+            set { this.showAllStages = value; }

+        }

+

+        /// <summary>

+        ///     Gets and sets whether to use atmospheric details.

+        /// </summary>

+        public bool UseAtmosphericDetails

+        {

+            get { return this.useAtmosphericDetails; }

+            set { this.useAtmosphericDetails = value; }

+        }

+

+        /// <summary>

+        ///     Gets and sets whether to show the reference body selection.

+        /// </summary>

+        public bool ShowReferenceBodies

+        {

+            get { return this.showReferenceBodies; }

+            set { this.showReferenceBodies = value; }

+        }

+

+        #endregion

+

+        #region Initialisation

+

+        private void Awake()

+        {

+            Instance = this;

+            this.Load();

+        }

+

+        private void Start()

+        {

+            this.InitialiseStyles();

+            RenderingManager.AddToPostDrawQueue(0, this.OnDraw);

+        }

+

+        /// <summary>

+        ///     Initialises all the styles that are required.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.areaBodiesStyle = new GUIStyle(HighLogic.Skin.box);

+

+            this.windowStyle = new GUIStyle(HighLogic.Skin.window)

+            {

+                alignment = TextAnchor.UpperLeft

+            };

+

+            this.areaStyle = new GUIStyle(HighLogic.Skin.box)

+            {

+                padding = new RectOffset(0, 0, 9, 0)

+            };

+

+            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                alignment = TextAnchor.MiddleCenter

+            };

+

+            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                alignment = TextAnchor.MiddleCenter,

+                stretchWidth = true

+            };

+

+            this.infoStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                alignment = TextAnchor.MiddleCenter,

+                stretchWidth = true

+            };

+        }

+

+        #endregion

+

+        #region Update and Drawing

+

+        private void Update()

+        {

+            try

+            {

+                if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.Count <= 0)

+                {

+                    return;

+                }

+

+                // Configure the simulation parameters based on the selected reference body.

+                SimulationManager.Gravity = CelestialBodies.Instance.SelectedBodyInfo.Gravity;

+                if (this.useAtmosphericDetails)

+                {

+                    SimulationManager.Atmosphere = CelestialBodies.Instance.SelectedBodyInfo.Atmosphere * 0.01d;

+                }

+                else

+                {

+                    SimulationManager.Atmosphere = 0;

+                }

+

+                SimulationManager.TryStartSimulation();

+            }

+            catch

+            {

+                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

+            }

+        }

+

+        private void OnDraw()

+        {

+            try

+            {

+                if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.Count <= 0)

+                {

+                    return;

+                }

+

+                SimulationManager.RequestSimulation();

+

+                // Change the window title based on whether in compact mode or not.

+                string title;

+                if (!this.compactMode)

+                {

+                    title = "KERBAL ENGINEER REDUX " + EngineerGlobals.AssemblyVersion;

+                }

+                else

+                {

+                    title = "K.E.R. " + EngineerGlobals.AssemblyVersion;

+                }

+

+                // Reset the window size when the staging or something else has changed.

+                int stageCount = SimulationManager.Stages.Count(stage => this.showAllStages || stage.DeltaV > 0);

+                if (this.hasChanged || stageCount != this.numberOfStages)

+                {

+                    this.hasChanged = false;

+                    this.numberOfStages = stageCount;

+

+                    this.windowPosition.width = 0;

+                    this.windowPosition.height = 0;

+                }

+

+                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, title, this.windowStyle).ClampToScreen();

+

+                // Check editor lock to manage click-through.

+                this.CheckEditorLock();

+            }

+            catch

+            {

+                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

+            }

+        }

+

+        /// <summary>

+        ///     Checks whether the editor should be locked to stop click-through.

+        /// </summary>

+        private void CheckEditorLock()

+        {

+            if (this.windowPosition.MouseIsOver())

+            {

+                EditorLogic.fetch.State = EditorLogic.EditorState.GUI_SELECTED;

+                this.isEditorLocked = true;

+            }

+            else if (!this.windowPosition.MouseIsOver() && this.isEditorLocked)

+            {

+                EditorLogic.fetch.State = EditorLogic.EditorState.PAD_UNSELECTED;

+                this.isEditorLocked = false;

+            }

+        }

+

+        /// <summary>

+        ///     Draws the OnGUI window.

+        /// </summary>

+        private void Window(int windowId)

+        {

+            // Draw the compact mode toggle.

+            if (GUI.Toggle(new Rect(this.windowPosition.width - 70.0f, 5.0f, 65.0f, 20.0f), this.compactMode, "COMPACT", this.buttonStyle) != this.compactMode)

+            {

+                this.hasChanged = true;

+                this.compactMode = !this.compactMode;

+            }

+

+            // When not in compact mode draw the 'All Stages' and 'Atmospheric' toggles.

+            if (!this.compactMode)

+            {

+                if (GUI.Toggle(new Rect(this.windowPosition.width - 153.0f, 5.0f, 80.0f, 20.0f), this.showAllStages, "ALL STAGES", this.buttonStyle) != this.showAllStages)

+                {

+                    this.hasChanged = true;

+                    this.showAllStages = !this.showAllStages;

+                }

+

+                this.useAtmosphericDetails = GUI.Toggle(new Rect(this.windowPosition.width - 251.0f, 5.0f, 95.0f, 20.0f), this.useAtmosphericDetails, "ATMOSPHERIC", this.buttonStyle);

+

+                if (GUI.Toggle(new Rect(this.windowPosition.width - 379.0f, 5.0f, 125.0f, 20.0f), this.showReferenceBodies, "REFERENCE BODIES", this.buttonStyle) != this.showReferenceBodies)

+                {

+                    this.hasChanged = true;

+                    this.showReferenceBodies = !this.showReferenceBodies;

+                }

+            }

+

+            // Draw the main informational display box.

+

+            if (!this.compactMode)

+            {

+                GUILayout.BeginHorizontal(this.areaStyle);

+                this.DrawStageNumbers();

+                this.DrawPartCount();

+                this.DrawCost();

+                this.DrawMass();

+                this.DrawIsp();

+                this.DrawThrust();

+                this.DrawTwr();

+                this.DrawDeltaV();

+                this.DrawBurnTime();

+                GUILayout.EndHorizontal();

+

+                if (this.showReferenceBodies)

+                {

+                    GUILayout.BeginVertical(this.areaBodiesStyle);

+                    this.DrawReferenceBodies();

+                    GUILayout.EndVertical();

+                }

+            }

+            else // Draw only a few details when in compact mode.

+            {

+                GUILayout.BeginHorizontal(this.areaStyle);

+                this.DrawStageNumbers();

+                this.DrawTwr();

+                this.DrawDeltaV();

+                GUILayout.EndHorizontal();

+            }

+

+            GUI.DragWindow();

+        }

+

+        /// <summary>

+        ///     Draws all the reference bodies.

+        /// </summary>

+        private void DrawReferenceBodies()

+        {

+            var index = 0;

+

+            foreach (var bodyName in CelestialBodies.Instance.BodyList.Keys)

+            {

+                if (index % 8 == 0)

+                {

+                    if (index > 0)

+                    {

+                        GUILayout.EndHorizontal();

+                    }

+                    GUILayout.BeginHorizontal();

+                }

+                if (GUILayout.Toggle(CelestialBodies.Instance.SelectedBodyName == bodyName, bodyName, this.buttonStyle))

+                {

+                    CelestialBodies.Instance.SelectedBodyName = bodyName;

+                }

+                index++;

+            }

+            GUILayout.EndHorizontal();

+        }

+

+        /// <summary>

+        ///     Draws the stage number column.

+        /// </summary>

+        private void DrawStageNumbers()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(30.0f));

+            GUILayout.Label(string.Empty, this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label("S" + stage.Number, this.titleStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Draws the part count column.

+        /// </summary>

+        private void DrawPartCount()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(50.0f));

+            GUILayout.Label("PARTS", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.PartCount.ToString("N0"), this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Draws the cost column.

+        /// </summary>

+        private void DrawCost()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(100.0f));

+            GUILayout.Label("COST", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.Cost.ToString("N0") + " / " + stage.TotalCost.ToString("N0"), this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Draws the mass column.

+        /// </summary>

+        private void DrawMass()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(100.0f));

+            GUILayout.Label("MASS", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.Mass.ToMass(false) + " / " + stage.TotalMass.ToMass(), this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Draws the specific impluse column.

+        /// </summary>

+        private void DrawIsp()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(50.0f));

+            GUILayout.Label("ISP", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.Isp.ToString("F1") + "s", this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Draws the thrust column.

+        /// </summary>

+        private void DrawThrust()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(75.0f));

+            GUILayout.Label("THRUST", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.Thrust.ToForce(), this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Drwas the thrust to weight ratio column.

+        /// </summary>

+        private void DrawTwr()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(50.0f));

+            GUILayout.Label("TWR", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.ThrustToWeight.ToString("F2"), this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Draws the deltaV column.

+        /// </summary>

+        private void DrawDeltaV()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(100.0f));

+            GUILayout.Label("DELTA-V", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.DeltaV.ToString("N0") + " / " + stage.InverseTotalDeltaV.ToString("N0") + "m/s", this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        /// <summary>

+        ///     Draws the burn time column.

+        /// </summary>

+        private void DrawBurnTime()

+        {

+            GUILayout.BeginVertical(GUILayout.Width(75.0f));

+            GUILayout.Label("BURN", this.titleStyle);

+            foreach (var stage in SimulationManager.Stages)

+            {

+                if (this.showAllStages || stage.DeltaV > 0)

+                {

+                    GUILayout.Label(stage.Time.ToTime(), this.infoStyle);

+                }

+            }

+            GUILayout.EndVertical();

+        }

+

+        #endregion

+

+        #region Save and Load

+

+        /// <summary>

+        ///     Saves the settings when this object is destroyed.

+        /// </summary>

+        private void OnDestroy()

+        {

+            try

+            {

+                var handler = new SettingHandler();

+                handler.Set("visible", this.visible);

+                handler.Set("windowPositionX", this.windowPosition.x);

+                handler.Set("windowPositionY", this.windowPosition.y);

+                handler.Set("compactMode", this.compactMode);

+                handler.Set("showAllStages", this.showAllStages);

+                handler.Set("useAtmosphericDetails", this.useAtmosphericDetails);

+                handler.Set("showReferenceBodies", this.showReferenceBodies);

+                handler.Set("selectedBodyName", CelestialBodies.Instance.SelectedBodyName);

+                handler.Save("BuildAdvanced.xml");

+            }

+            catch

+            {

+                print("[KerbalEngineer]: Failed to save BuildAdvanced settings.");

+            }

+        }

+

+        /// <summary>

+        ///     Loads the settings when this object is created.

+        /// </summary>

+        private void Load()

+        {

+            try

+            {

+                var handler = SettingHandler.Load("BuildAdvanced.xml");

+                handler.Get("visible", ref this.visible);

+                this.windowPosition.x = handler.Get("windowPositionX", this.windowPosition.x);

+                this.windowPosition.y = handler.Get("windowPositionY", this.windowPosition.y);

+                handler.Get("compactMode", ref this.compactMode);

+                handler.Get("showAllStages", ref this.showAllStages);

+                handler.Get("useAtmosphericDetails", ref this.useAtmosphericDetails);

+                CelestialBodies.Instance.SelectedBodyName = handler.Get("selectedBodyName", CelestialBodies.Instance.SelectedBodyName);

+            }

+            catch

+            {

+                print("[KerbalEngineer/BuildAdvanced]: Failed to load BuildAdvanced settings.");

+            }

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Editor/BuildButton.cs
@@ -1,1 +1,188 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.IO;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Editor

+{

+    [KSPAddon(KSPAddon.Startup.EditorAny, false)]

+    public class BuildButton : MonoBehaviour

+    {

+        #region Fields

+

+        private readonly Texture2D down = new Texture2D(50, 45, TextureFormat.RGBA32, false);

+        private readonly Texture2D hover = new Texture2D(50, 45, TextureFormat.RGBA32, false);

+        private readonly Texture2D locked = new Texture2D(50, 45, TextureFormat.RGBA32, false);

+        private readonly Texture2D normal = new Texture2D(50, 45, TextureFormat.RGBA32, false);

+

+        private bool clicked;

+        private Rect position = new Rect(Screen.width * 0.5f - 300.0f, 0, 50.0f, 45.0f);

+

+        #region Styles

+

+        private GUIStyle tooltipInfoStyle;

+        private GUIStyle tooltipTitleStyle;

+

+        #endregion

+

+        #endregion

+

+        #region Initialisation

+

+        private void Start()

+        {

+            // Load the button textures directly from the PNG files. (Would of used GameDatabase but it compresses them so it looks shit!)

+            this.normal.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Normal.png"));

+            this.hover.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Hover.png"));

+            this.down.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Down.png"));

+            this.locked.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/BuildButton/Locked.png"));

+

+            this.InitialiseStyles();

+            RenderingManager.AddToPostDrawQueue(0, this.OnDraw);

+        }

+

+        /// <summary>

+        ///     Initialises all of the GUI styles that are required.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.tooltipTitleStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                fontSize = 13,

+                fontStyle = FontStyle.Bold

+            };

+

+            this.tooltipInfoStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                fontSize = 11,

+                fontStyle = FontStyle.Bold

+            };

+        }

+

+        #endregion

+

+        #region Update and Drawing

+

+        private void Update()

+        {

+            if (Input.GetKeyDown(KeyCode.Backslash))

+            {

+                LeftClick();

+            }

+        }

+

+        private void OnDraw()

+        {

+            if (EditorLogic.fetch.ship.Count > 0)

+            {

+                if (this.clicked) // Button has been clicked whilst being hovered.

+                {

+                    GUI.DrawTexture(this.position, this.down);

+

+                    if (this.position.Contains(Event.current.mousePosition)) // Mouse is hovering over the button.

+                    {

+                        this.DrawToolTip();

+

+                        if (Mouse.Left.GetButtonUp()) // The mouse up event has been triggered whilst over the button.

+                        {

+                            this.clicked = false;

+                            LeftClick();

+                        }

+                        else if (Mouse.Right.GetButtonUp())

+                        {

+                            this.clicked = false;

+                            RightClick();

+                        }

+                    }

+                }

+                else // The button is not registering as being clicked.

+                {

+                    if (this.position.Contains(Event.current.mousePosition)) // Mouse is hovering over the button.

+                    {

+                        // If the left mouse button has just been pressed, see the button as being clicked.

+                        if (!this.clicked && (Mouse.Left.GetButtonDown() || Mouse.Right.GetButtonDown()))

+                        {

+                            this.clicked = true;

+                        }

+

+                        if (this.clicked) // The button has just been clicked.

+                        {

+                            GUI.DrawTexture(this.position, this.down);

+                        }

+                        else if (!Mouse.Left.GetButton() && !Mouse.Right.GetButton()) // Mouse button is not down and is just hovering.

+                        {

+                            GUI.DrawTexture(this.position, this.hover);

+                            this.DrawToolTip();

+                        }

+                        else // Mouse button is down but no click was registered over the button.

+                        {

+                            GUI.DrawTexture(this.position, this.normal);

+                        }

+                    }

+                    else // The mouse is not being hovered.

+                    {

+                        GUI.DrawTexture(this.position, this.normal);

+                    }

+                }

+

+                // Check for an unclick event whilst the mouse is not hovering.

+                if (this.clicked && (Mouse.Left.GetButtonUp() || Mouse.Right.GetButtonUp()))

+                {

+                    this.clicked = false;

+                }

+            }

+            else // The editor is set as being locked.

+            {

+                GUI.DrawTexture(this.position, this.locked);

+            }

+        }

+

+        /// <summary>

+        ///     Draws the tooltop next to the mouse cursor.

+        /// </summary>

+        private void DrawToolTip()

+        {

+            GUI.Label(new Rect(Event.current.mousePosition.x + 16.0f, Event.current.mousePosition.y, 500.0f, 25.0f), "Kerbal Engineer Redux", this.tooltipTitleStyle);

+            GUI.Label(new Rect(Event.current.mousePosition.x + 16.0f, Event.current.mousePosition.y + 16.0f, 500.0f, 25.0f), "[Left Click / Backslash] Advanced - [Right Click] Overlay", this.tooltipInfoStyle);

+        }

+

+        #endregion

+

+        #region Static Methods

+

+        /// <summary>

+        ///     Runs when the button is clicked with the left mouse button.

+        /// </summary>

+        public static void LeftClick()

+        {

+            if (BuildAdvanced.Instance != null)

+            {

+                BuildAdvanced.Instance.Visible = !BuildAdvanced.Instance.Visible;

+            }

+        }

+

+        /// <summary>

+        ///     Runs when the button is clicked with the right mouse button.

+        /// </summary>

+        private static void RightClick()

+        {

+            if (BuildOverlay.Instance != null)

+            {

+                BuildOverlay.Instance.Visible = !BuildOverlay.Instance.Visible;

+            }

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Editor/BuildOverlay.cs
@@ -1,1 +1,438 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Diagnostics;

+

+using KerbalEngineer.Extensions;

+using KerbalEngineer.Settings;

+using KerbalEngineer.Simulation;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Editor

+{

+    [KSPAddon(KSPAddon.Startup.EditorAny, false)]

+    public class BuildOverlay : MonoBehaviour

+    {

+        #region Instance

+

+        /// <summary>

+        ///     Gets the current instance if started or returns null.

+        /// </summary>

+        public static BuildOverlay Instance { get; private set; }

+

+        #endregion

+

+        #region Fields

+

+        private readonly Stopwatch tooltipInfoTimer = new Stopwatch();

+        private readonly int windowId = EngineerGlobals.GetNextWindowId();

+        private Part selectedPart;

+        private Rect windowPosition = new Rect(265.0f, 0, 0, 0);

+

+        #endregion

+

+        #region Constructors

+

+        private void Awake()

+        {

+            Instance = this;

+        }

+

+        private void Start()

+        {

+            this.InitialiseStyles();

+            this.Load();

+            RenderingManager.AddToPostDrawQueue(0, this.OnDraw);

+        }

+

+        #endregion

+

+        #region Properties

+

+        private float tooltipInfoDelay = 0.5f;

+        private bool visible;

+

+        public float TooltipInfoDelay

+        {

+            get { return this.tooltipInfoDelay; }

+            set { this.tooltipInfoDelay = value; }

+        }

+

+        /// <summary>

+        ///     Gets and sets whether the display is enabled.

+        /// </summary>

+        public bool Visible

+        {

+            get { return this.visible; }

+            set { this.visible = value; }

+        }

+

+        #endregion

+

+        #region GUIStyles

+

+        private GUIStyle infoStyle;

+        private GUIStyle titleStyle;

+        private GUIStyle tooltipInfoStyle;

+        private GUIStyle tooltipTitleStyle;

+        private GUIStyle windowStyle;

+

+        private void InitialiseStyles()

+        {

+            this.windowStyle = new GUIStyle(GUIStyle.none)

+            {

+                margin = new RectOffset(),

+                padding = new RectOffset()

+            };

+

+            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                stretchWidth = true

+            };

+

+            this.infoStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                stretchWidth = true

+            };

+

+            this.tooltipTitleStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                stretchWidth = true

+            };

+

+            this.tooltipInfoStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                stretchWidth = true

+            };

+        }

+

+        #endregion

+

+        #region Update and Drawing

+

+        private void Update()

+        {

+            try

+            {

+                if (EditorLogic.fetch == null || EditorLogic.SortedShipList.Count <= 0)

+                {

+                    return;

+                }

+

+                // Configure the simulation parameters based on the selected reference body.

+                SimulationManager.Gravity = CelestialBodies.Instance.SelectedBodyInfo.Gravity;

+

+                if (BuildAdvanced.Instance.UseAtmosphericDetails)

+                {

+                    SimulationManager.Atmosphere = CelestialBodies.Instance.SelectedBodyInfo.Atmosphere * 0.01d;

+                }

+                else

+                {

+                    SimulationManager.Atmosphere = 0;

+                }

+

+                SimulationManager.TryStartSimulation();

+            }

+            catch

+            {

+                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

+            }

+        }

+

+        private void OnDraw()

+        {

+            try

+            {

+                if (!this.visible || EditorLogic.fetch == null || EditorLogic.SortedShipList.Count <= 0 || EditorLogic.fetch.editorScreen != EditorLogic.EditorScreen.Parts)

+                {

+                    return;

+                }

+

+                SimulationManager.RequestSimulation();

+

+                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty, this.windowStyle);

+

+                // Check and set that the window is at the bottom of the screen.

+                if (this.windowPosition.y + this.windowPosition.height != Screen.height - 5.0f)

+                {

+                    this.windowPosition.y = Screen.height - this.windowPosition.height - 5.0f;

+                }

+

+                // Find if a part is selected or being hovered over.

+                if (EditorLogic.SelectedPart != null)

+                {

+                    // Do not allow the extended information to be shown.

+                    if (this.selectedPart != null)

+                    {

+                        this.selectedPart = null;

+                        this.tooltipInfoTimer.Reset();

+                    }

+

+                    this.DrawTooltip(EditorLogic.SelectedPart);

+                }

+                else

+                {

+                    var isPartSelected = false;

+                    foreach (var part in EditorLogic.SortedShipList)

+                    {

+                        if (part.stackIcon.highlightIcon)

+                        {

+                            // Start the extended information timer.

+                            if (part != this.selectedPart)

+                            {

+                                this.selectedPart = part;

+                                this.tooltipInfoTimer.Reset();

+                                this.tooltipInfoTimer.Start();

+                            }

+                            isPartSelected = true;

+

+                            this.DrawTooltip(part);

+                            break;

+                        }

+                    }

+

+                    // If no part is being hovered over we must reset the extended information timer.

+                    if (!isPartSelected && this.selectedPart != null)

+                    {

+                        this.selectedPart = null;

+                        this.tooltipInfoTimer.Reset();

+                    }

+                }

+            }

+            catch

+            {

+                /* A null reference exception is thrown when checking if EditorLogic.fetch != null??? */

+            }

+        }

+

+        private void Window(int windowId)

+        {

+            GUILayout.BeginHorizontal();

+

+            // Titles

+            GUILayout.BeginVertical(GUILayout.Width(75.0f));

+            GUILayout.Label("Parts:", this.titleStyle);

+            GUILayout.Label("Delta-V:", this.titleStyle);

+            GUILayout.Label("TWR:", this.titleStyle);

+            GUILayout.EndVertical();

+

+            // Details

+            GUILayout.BeginVertical(GUILayout.Width(100.0f));

+            GUILayout.Label(SimulationManager.LastStage.PartCount.ToString("N0"), this.infoStyle);

+            GUILayout.Label(SimulationManager.LastStage.TotalDeltaV.ToString("N0") + " m/s", this.infoStyle);

+            GUILayout.Label(SimulationManager.LastStage.ThrustToWeight.ToString("F2"), this.infoStyle);

+            GUILayout.EndVertical();

+

+            GUILayout.EndHorizontal();

+        }

+

+        /// <summary>

+        ///     Draws the tooltip details of the selected/highlighted part.

+        /// </summary>

+        private void DrawTooltip(Part part)

+        {

+            // Tooltip title (name of part).

+            var content = new GUIContent(part.partInfo.title);

+            var size = this.tooltipTitleStyle.CalcSize(content);

+            var position = new Rect(Event.current.mousePosition.x + 16.0f, Event.current.mousePosition.y, size.x, size.y).ClampInsideScreen();

+

+            if (position.x < Event.current.mousePosition.x + 16.0f)

+            {

+                position.y += 16.0f;

+            }

+            GUI.Label(position, content, this.tooltipTitleStyle);

+

+            // After hovering for a period of time, show extended information.

+            if (this.tooltipInfoTimer.Elapsed.TotalSeconds >= this.tooltipInfoDelay)

+            {

+                // Stop the timer as it is no longer needed.

+                if (this.tooltipInfoTimer.IsRunning)

+                {

+                    this.tooltipInfoTimer.Stop();

+                }

+

+                // Show the dry mass of the part if applicable.

+                if (part.physicalSignificance == Part.PhysicalSignificance.FULL)

+                {

+                    this.DrawTooltipInfo(ref position, "Dry Mass: " + part.GetDryMass().ToMass());

+                }

+

+                // Show resources contained within the part.

+                if (part.ContainsResources())

+                {

+                    // Show the wet mass of the part if applicable.

+                    if (part.GetResourceMass() > 0)

+                    {

+                        this.DrawTooltipInfo(ref position, "Wet Mass: " + part.GetWetMass().ToMass());

+                    }

+

+                    // List all the resources contained within the part.

+                    foreach (PartResource resource in part.Resources)

+                    {

+                        if (resource.GetDensity() > 0)

+                        {

+                            this.DrawTooltipInfo(ref position, resource.info.name + ": " + resource.GetMass().ToMass() + " (" + resource.amount + ")");

+                        }

+                        else

+                        {

+                            this.DrawTooltipInfo(ref position, resource.info.name + ": " + resource.amount);

+                        }

+                    }

+                }

+

+                // Show details for engines.

+                if (part.IsEngine())

+                {

+                    this.DrawTooltipInfo(ref position, "Maximum Thrust: " + part.GetMaxThrust().ToForce());

+                    this.DrawTooltipInfo(ref position, "Specific Impulse: " + part.GetSpecificImpulse(1f) + " / " + part.GetSpecificImpulse(0f) + "s");

+

+                    // Thrust vectoring.

+                    if (part.HasModule("ModuleGimbal"))

+                    {

+                        this.DrawTooltipInfo(ref position, "Thrust Vectoring Enabled");

+                    }

+

+                    // Contains alternator.

+                    if (part.HasModule("ModuleAlternator"))

+                    {

+                        this.DrawTooltipInfo(ref position, "Contains Alternator");

+                    }

+                }

+

+                // Show details for RCS.

+                if (part.IsRcsModule())

+                {

+                    var moduleRcs = part.GetModuleRcs();

+                    this.DrawTooltipInfo(ref position, "Thrust Power: " + moduleRcs.thrusterPower.ToDouble().ToForce());

+                    this.DrawTooltipInfo(ref position, "Specific Impulse: " + moduleRcs.atmosphereCurve.Evaluate(1f) + " / " + moduleRcs.atmosphereCurve.Evaluate(0f) + "s");

+                }

+

+                // Show details for solar panels.

+                if (part.IsSolarPanel())

+                {

+                    this.DrawTooltipInfo(ref position, "Charge Rate: " + part.GetModuleDeployableSolarPanel().chargeRate.ToDouble().ToRate());

+                }

+

+                // Show details for generators.

+                if (part.IsGenerator())

+                {

+                    foreach (var resource in part.GetModuleGenerator().inputList)

+                    {

+                        this.DrawTooltipInfo(ref position, "Input: " + resource.name + " (" + resource.rate.ToDouble().ToRate() + ")");

+                    }

+

+                    foreach (var resource in part.GetModuleGenerator().outputList)

+                    {

+                        this.DrawTooltipInfo(ref position, "Output: " + resource.name + " (" + resource.rate.ToDouble().ToRate() + ")");

+                    }

+                }

+

+                // Show details for parachutes.

+                if (part.IsParachute())

+                {

+                    var module = part.GetModuleParachute();

+                    this.DrawTooltipInfo(ref position, "Semi Deployed Drag: " + module.semiDeployedDrag);

+                    this.DrawTooltipInfo(ref position, "Fully Deployed Drag: " + module.fullyDeployedDrag);

+                    this.DrawTooltipInfo(ref position, "Deployment Altitude: " + module.deployAltitude.ToDouble().ToDistance());

+                }

+

+                // Contains stability augmentation system.

+                if (part.HasModule("ModuleSAS"))

+                {

+                    this.DrawTooltipInfo(ref position, "Contains SAS");

+                }

+

+                // Contains reaction wheels.

+                if (part.HasModule("ModuleReactionWheel"))

+                {

+                    this.DrawTooltipInfo(ref position, "Contains Reaction Wheels");

+                }

+

+                // Show if the part has an animation that can only be used once.

+                if (part.HasOneShotAnimation())

+                {

+                    this.DrawTooltipInfo(ref position, "Single Activation Only");

+                }

+            }

+        }

+

+        /// <summary>

+        ///     Draws a line of extended information below the previous.

+        /// </summary>

+        private void DrawTooltipInfo(ref Rect position, string value)

+        {

+            var content = new GUIContent(value);

+            var size = this.tooltipInfoStyle.CalcSize(content);

+

+            position.y += 16.0f;

+            position.width = size.x;

+            position.height = size.y;

+            GUI.Label(position, content, this.tooltipInfoStyle);

+        }

+

+        #endregion

+

+        #region Save and Load

+

+        /// <summary>

+        ///     Saves the settings when this object is destroyed.

+        /// </summary>

+        private void OnDestroy()

+        {

+            try

+            {

+                var handler = new SettingHandler();

+                handler.Set("visible", this.visible);

+                handler.Save("BuildOverlay.xml");

+            }

+            catch

+            {

+                print("[KerbalEngineer]: Failed to save BuildOverlay settings.");

+            }

+        }

+

+        /// <summary>

+        ///     Loads the settings when this object is created.

+        /// </summary>

+        private void Load()

+        {

+            try

+            {

+                var handler = SettingHandler.Load("BuildOverlay.xml");

+                handler.Get("visible", ref this.visible);

+            }

+            catch

+            {

+                print("[KerbalEngineer]: Failed to load BuildOverlay settings.");

+            }

+        }

+

+        #endregion

+    }

+}

--- a/KerbalEngineer/EngineerGlobals.cs
+++ b/KerbalEngineer/EngineerGlobals.cs
@@ -19,6 +19,11 @@
         ///     Current version of the Kerbal Engineer assembly.

         /// </summary>

         public const string AssemblyVersion = "1.0.0.0";

+

+        /// <summary>

+        ///     Current version of Kerbal Engineer Redux.

+        /// </summary>

+        public const string PrettyVersion = "1.0";

 

         #endregion

 


--- /dev/null
+++ b/KerbalEngineer/Flight/ActionMenu.cs
@@ -1,1 +1,237 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Collections.Generic;

+

+using KerbalEngineer.Flight.Sections;

+using KerbalEngineer.Settings;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Flight

+{

+    /// <summary>

+    ///     Graphical controller for section interaction in the form of a menu system.

+    /// </summary>

+    public class ActionMenu : MonoBehaviour

+    {

+        #region Constants

+

+        private const float ScrollSpeed = 2.0f;

+

+        #endregion

+

+        #region Fields

+

+        private bool isOpen = true;

+        private int numberOfSections;

+        private float scrollPercent;

+        private int windowId;

+        private Rect windowPosition = new Rect((Screen.width * 0.25f) - 100.0f, 0, 200.0f, 0);

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Initialises object's state on creation.

+        /// </summary>

+        private void Start()

+        {

+            this.windowId = this.GetHashCode();

+            this.InitialiseStyles();

+            this.Load();

+            RenderingManager.AddToPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+

+        #region GUIStyles

+

+        private GUIStyle boxStyle;

+        private GUIStyle buttonStyle;

+        private GUIStyle windowStyle;

+

+        /// <summary>

+        ///     Initialises all the styles required for this object.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.windowStyle = new GUIStyle();

+

+            this.boxStyle = new GUIStyle(HighLogic.Skin.window)

+            {

+                margin = new RectOffset(),

+                padding = new RectOffset(3, 3, 3, 3)

+            };

+

+            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleCenter,

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                fixedHeight = 20.0f,

+            };

+        }

+

+        #endregion

+

+        #region Drawing

+

+        /// <summary>

+        ///     Called to draw the menu when the UI is enabled.

+        /// </summary>

+        private void Draw()

+        {

+            if (this.numberOfSections != SectionLibrary.Instance.NumberOfSections)

+            {

+                this.numberOfSections = SectionLibrary.Instance.NumberOfSections;

+                this.windowPosition.height = 0;

+            }

+            this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty, this.windowStyle);

+            this.ScrollMechanism();

+        }

+

+        /// <summary>

+        ///     Draws the menu window.

+        /// </summary>

+        private void Window(int windowId)

+        {

+            GUILayout.BeginVertical(this.boxStyle);

+

+            this.DrawControlBarButton();

+            this.DrawSections(SectionLibrary.Instance.StockSections);

+            this.DrawSections(SectionLibrary.Instance.CustomSections);

+            this.DrawNewButton();

+

+            GUILayout.EndVertical();

+

+            if (GUILayout.Button("FLIGHT ENGINEER", this.buttonStyle))

+            {

+                this.isOpen = !this.isOpen;

+            }

+        }

+

+        /// <summary>

+        ///     Draws and performs the control bar button action.

+        /// </summary>

+        private void DrawControlBarButton()

+        {

+            if (GUILayout.Toggle(DisplayStack.Instance.ShowControlBar, "CONTROL BAR", this.buttonStyle) != DisplayStack.Instance.ShowControlBar)

+            {

+                DisplayStack.Instance.ShowControlBar = !DisplayStack.Instance.ShowControlBar;

+                DisplayStack.Instance.RequestResize();

+            }

+        }

+

+        /// <summary>

+        ///     Draws an action list for the supplied sections.

+        /// </summary>

+        private void DrawSections(IEnumerable<SectionModule> sections)

+        {

+            foreach (var section in sections)

+            {

+                GUILayout.BeginHorizontal();

+                section.IsVisible = GUILayout.Toggle(section.IsVisible, section.Name.ToUpper(), this.buttonStyle);

+                section.IsEditorVisible = GUILayout.Toggle(section.IsEditorVisible, "EDIT", this.buttonStyle, GUILayout.Width(50.0f));

+                GUILayout.EndHorizontal();

+            }

+        }

+

+        /// <summary>

+        ///     Draws and performs the new section button action.

+        /// </summary>

+        private void DrawNewButton()

+        {

+            GUILayout.BeginHorizontal();

+            GUILayout.FlexibleSpace();

+            if (GUILayout.Button("NEW", this.buttonStyle, GUILayout.Width(50.0f)))

+            {

+                SectionLibrary.Instance.CustomSections.Add(new SectionModule

+                {

+                    Name = "Custom " + (SectionLibrary.Instance.CustomSections.Count + 1),

+                    Abbreviation = "CUST " + (SectionLibrary.Instance.CustomSections.Count + 1),

+                    IsVisible = true,

+                    IsCustom = true,

+                    IsEditorVisible = true

+                });

+            }

+            GUILayout.EndHorizontal();

+        }

+

+        /// <summary>

+        ///     Controls the dynamics of the scrolling mechanism.

+        /// </summary>

+        private void ScrollMechanism()

+        {

+            if (this.isOpen && this.windowPosition.y != 0)

+            {

+                this.scrollPercent += Time.deltaTime * ScrollSpeed;

+                this.windowPosition.y = Mathf.Lerp(this.windowPosition.y, 0, this.scrollPercent);

+            }

+            else if (!this.isOpen && this.windowPosition.y != 20.0f - this.windowPosition.height)

+            {

+                this.scrollPercent += Time.deltaTime * ScrollSpeed;

+                this.windowPosition.y = Mathf.Lerp(this.windowPosition.y, 20.0f - this.windowPosition.height, this.scrollPercent);

+            }

+            else

+            {

+                this.scrollPercent = 0;

+            }

+        }

+

+        #endregion

+

+        #region Destruction

+

+        /// <summary>

+        ///     Runs when the object is destroyed.

+        /// </summary>

+        private void OnDestroy()

+        {

+            this.Save();

+

+            RenderingManager.RemoveFromPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+

+        #region Saving and Loading

+

+        /// <summary>

+        ///     Saves the menu's state.

+        /// </summary>

+        private void Save()

+        {

+            var handler = new SettingHandler();

+            handler.Set("isOpen", this.isOpen);

+            handler.Set("windowPositionY", this.windowPosition.y);

+            handler.Set("windowPositionHeight", this.windowPosition.height);

+            handler.Save("ActionMenu.xml");

+        }

+

+        /// <summary>

+        ///     Loads the menu's state.

+        /// </summary>

+        private void Load()

+        {

+            var handler = SettingHandler.Load("ActionMenu.xml");

+            handler.Get("isOpen", ref this.isOpen);

+            this.windowPosition.y = handler.Get("windowPositionY", this.windowPosition.y);

+            this.windowPosition.height = handler.Get("windowPositionHeight", this.windowPosition.height);

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/DisplayStack.cs
@@ -1,1 +1,270 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Collections.Generic;

+

+using KerbalEngineer.Extensions;

+using KerbalEngineer.Flight.Sections;

+using KerbalEngineer.Settings;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Flight

+{

+    /// <summary>

+    ///     Graphical controller for displaying stacked sections.

+    /// </summary>

+    public class DisplayStack : MonoBehaviour

+    {

+        #region Instance

+

+        /// <summary>

+        ///     Gets the current instance of the DisplayStack.

+        /// </summary>

+        public static DisplayStack Instance { get; private set; }

+

+        #endregion

+

+        #region Fields

+

+        private int numberOfStackSections;

+        private bool resizeRequested;

+        private int windowId;

+        private Rect windowPosition = new Rect(Screen.width - 275.0f, 50.0f, 250.0f, 0);

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Sets the instance to this object.

+        /// </summary>

+        private void Awake()

+        {

+            Instance = this;

+        }

+

+        /// <summary>

+        ///     Initialises the object's state on creation.

+        /// </summary>

+        private void Start()

+        {

+            this.windowId = this.GetHashCode();

+            this.InitialiseStyles();

+            this.Load();

+

+            RenderingManager.AddToPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+

+        #region Properties

+

+        private bool showControlBar = true;

+

+        /// <summary>

+        ///     Gets and sets the visibility of the control bar.

+        /// </summary>

+        public bool ShowControlBar

+        {

+            get { return this.showControlBar; }

+            set { this.showControlBar = value; }

+        }

+

+        #endregion

+

+        #region GUIStyles

+

+        private GUIStyle buttonStyle;

+        private GUIStyle titleStyle;

+        private GUIStyle windowStyle;

+

+        /// <summary>

+        ///     Initialises all the styles required for this object.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.windowStyle = new GUIStyle(HighLogic.Skin.window)

+            {

+                margin = new RectOffset(),

+                padding = new RectOffset(5, 5, 0, 5)

+            };

+

+            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                margin = new RectOffset(0, 0, 5, 3),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleCenter,

+                fontSize = 13,

+                fontStyle = FontStyle.Bold,

+                stretchWidth = true

+            };

+

+            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleCenter,

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                fixedWidth = 60.0f,

+                fixedHeight = 25.0f,

+            };

+        }

+

+        #endregion

+

+        #region Drawing

+

+        /// <summary>

+        ///     Called to draw the display stack when the UI is enabled.

+        /// </summary>

+        private void Draw()

+        {

+            if (this.resizeRequested || this.numberOfStackSections != SectionLibrary.Instance.NumberOfStackSections)

+            {

+                this.numberOfStackSections = SectionLibrary.Instance.NumberOfStackSections;

+                this.windowPosition.height = 0;

+                this.resizeRequested = false;

+            }

+

+            if (SectionLibrary.Instance.NumberOfStackSections > 0 || this.ShowControlBar)

+            {

+                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty, this.windowStyle).ClampToScreen();

+            }

+        }

+

+        /// <summary>

+        ///     Draws the display stack window.

+        /// </summary>

+        private void Window(int windowId)

+        {

+            if (this.ShowControlBar)

+            {

+                this.DrawControlBar();

+            }

+

+            if (SectionLibrary.Instance.NumberOfStackSections > 0)

+            {

+                this.DrawSections(SectionLibrary.Instance.StockSections);

+                this.DrawSections(SectionLibrary.Instance.CustomSections);

+            }

+

+            GUI.DragWindow();

+        }

+

+        /// <summary>

+        ///     Draws the control bar.

+        /// </summary>

+        private void DrawControlBar()

+        {

+            GUILayout.Label("FLIGHT ENGINEER " + EngineerGlobals.PrettyVersion, this.titleStyle);

+

+            this.DrawControlBarButtons(SectionLibrary.Instance.StockSections);

+            this.DrawControlBarButtons(SectionLibrary.Instance.CustomSections);

+        }

+

+        /// <summary>

+        ///     Draws a button list for a set of sections.

+        /// </summary>

+        private void DrawControlBarButtons(IEnumerable<SectionModule> sections)

+        {

+            var index = 0;

+            foreach (var section in sections)

+            {

+                if (index % 4 == 0)

+                {

+                    if (index > 0)

+                    {

+                        GUILayout.EndHorizontal();

+                    }

+                    GUILayout.BeginHorizontal();

+                }

+                section.IsVisible = GUILayout.Toggle(section.IsVisible, section.Abbreviation.ToUpper(), this.buttonStyle);

+                index++;

+            }

+            if (index > 0)

+            {

+                GUILayout.EndHorizontal();

+            }

+        }

+

+        /// <summary>

+        ///     Draws a list of sections.

+        /// </summary>

+        private void DrawSections(IEnumerable<SectionModule> sections)

+        {

+            foreach (var section in sections)

+            {

+                if (!section.IsFloating)

+                {

+                    section.Draw();

+                }

+            }

+        }

+

+        #endregion

+

+        #region Destruction

+

+        /// <summary>

+        ///     Runs when the object is destroyed.

+        /// </summary>

+        private void OnDestroy()

+        {

+            this.Save();

+

+            RenderingManager.RemoveFromPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+

+        #region Saving and Loading

+

+        /// <summary>

+        ///     Saves the stack's state.

+        /// </summary>

+        private void Save()

+        {

+            var handler = new SettingHandler();

+            handler.Set("showControlBar", this.ShowControlBar);

+            handler.Set("windowPositionX", this.windowPosition.x);

+            handler.Set("windowPositionY", this.windowPosition.y);

+            handler.Save("DisplayStack.xml");

+        }

+

+        /// <summary>

+        ///     Load the stack's state.

+        /// </summary>

+        private void Load()

+        {

+            var handler = SettingHandler.Load("DisplayStack.xml");

+            this.ShowControlBar = handler.Get("showControlBar", this.ShowControlBar);

+            this.windowPosition.x = handler.Get("windowPositionX", this.windowPosition.x);

+            this.windowPosition.y = handler.Get("windowPositionY", this.windowPosition.y);

+        }

+

+        #endregion

+

+        #region Methods

+

+        /// <summary>

+        ///     Request that the display stack's size is reset in the next draw call.

+        /// </summary>

+        public void RequestResize()

+        {

+            this.resizeRequested = true;

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/FlightEngineerCore.cs
@@ -1,1 +1,156 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Collections.Generic;

+

+using KerbalEngineer.Flight.Sections;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Flight

+{

+    /// <summary>

+    ///     Core management system for the Flight Engineer.

+    /// </summary>

+    public sealed class FlightEngineerCore : MonoBehaviour

+    {

+        #region Instance

+

+        /// <summary>

+        ///     Gets the current instance of FlightEngineerCore.

+        /// </summary>

+        public static FlightEngineerCore Instance { get; private set; }

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Create base Flight Engineer child objects.

+        /// </summary>

+        private void Awake()

+        {

+            Instance = this;

+

+            this.ActionMenu = this.gameObject.AddComponent<ActionMenu>();

+            this.DisplayStack = this.gameObject.AddComponent<DisplayStack>();

+            this.SectionWindows = new List<SectionWindow>();

+            this.SectionEditors = new List<SectionEditor>();

+        }

+

+        /// <summary>

+        ///     Initialises the object's state on creation.

+        /// </summary>

+        private void Start()

+        {

+            SectionLibrary.Instance.Load();

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the ActionMenu object.

+        /// </summary>

+        public ActionMenu ActionMenu { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the DisplayStack object.

+        /// </summary>

+        public DisplayStack DisplayStack { get; set; }

+

+        /// <summary>

+        ///     Gets the section windows for floating sections.

+        /// </summary>

+        public List<SectionWindow> SectionWindows { get; private set; }

+

+        /// <summary>

+        ///     Gets the editor windows for sections with open editors.

+        /// </summary>

+        public List<SectionEditor> SectionEditors { get; private set; }

+

+        #endregion

+

+        #region Updating

+

+        /// <summary>

+        ///     Update all required Flight Engineer objects.

+        /// </summary>

+        private void Update()

+        {

+            SectionLibrary.Instance.Update();

+        }

+

+        #endregion

+

+        #region Destruction

+

+        /// <summary>

+        ///     Force the destruction of child objects on core destruction.

+        /// </summary>

+        private void OnDestroy()

+        {

+            SectionLibrary.Instance.Save();

+

+            foreach (var window in this.SectionWindows)

+            {

+                print("[FlightEngineer]: Destroying Floating Window for " + window.ParentSection.Name);

+                Destroy(window);

+            }

+

+            foreach (var editor in this.SectionEditors)

+            {

+                print("[FlightEngineer]: Destroying Editor Window for " + editor.ParentSection.Name);

+                Destroy(editor);

+            }

+

+            if (this.ActionMenu != null)

+            {

+                print("[FlightEngineer]: Destroying ActionMenu");

+                DestroyImmediate(this.ActionMenu);

+            }

+

+            if (this.DisplayStack != null)

+            {

+                print("[FlightEngineer]: Destroying DisplayStack");

+                DestroyImmediate(this.DisplayStack);

+            }

+        }

+

+        #endregion

+

+        #region Methods

+

+        /// <summary>

+        ///     Creates a section window, adds it to the FlightEngineerCore and returns a reference to it.

+        /// </summary>

+        public SectionWindow AddSectionWindow(SectionModule section)

+        {

+            var window = this.gameObject.AddComponent<SectionWindow>();

+            window.ParentSection = section;

+            window.WindowPosition = new Rect(section.FloatingPositionX, section.FloatingPositionY, 0, 0);

+            this.SectionWindows.Add(window);

+            return window;

+        }

+

+        /// <summary>

+        ///     Creates a section editor, adds it to the FlightEngineerCore and returns a reference to it.

+        /// </summary>

+        public SectionEditor AddSectionEditor(SectionModule section)

+        {

+            var editor = this.gameObject.AddComponent<SectionEditor>();

+            editor.ParentSection = section;

+            editor.WindowPosition = new Rect(section.EditorPositionX, section.EditorPositionY, SectionEditor.Width, SectionEditor.Height);

+            this.SectionEditors.Add(editor);

+            return editor;

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/FlightEngineerModule.cs
@@ -1,1 +1,74 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Linq;

+

+using KerbalEngineer.Flight.Readouts;

+

+#endregion

+

+namespace KerbalEngineer.Flight

+{

+    /// <summary>

+    ///     Module that can be attached to parts, giving them FlightEngineerCore management.

+    /// </summary>

+    public sealed class FlightEngineerModule : PartModule

+    {

+        #region Fields

+

+        /// <summary>

+        ///     Contains the current FlightEngineerCore through the lifespan of this part.

+        /// </summary>

+        private FlightEngineerCore flightEngineerCore;

+

+        #endregion

+

+        #region Updating

+

+        /// <summary>

+        ///     Logic to create and destroy the FlightEngineerCore.

+        /// </summary>

+        private void Update()

+        {

+            if (!HighLogic.LoadedSceneIsFlight)

+            {

+                return;

+            }

+

+            if (this.vessel == FlightGlobals.ActiveVessel)

+            {

+                // Checks for an existing instance of FlightEngineerCore, and if this part is the first part containing FlightEngineerModule within the vessel.

+                if (this.flightEngineerCore == null && this.part == this.vessel.parts.FirstOrDefault(p => p.Modules.Contains("FlightEngineerModule")))

+                {

+                    ReadoutLibrary.Instance.Reset();

+                    this.flightEngineerCore = this.gameObject.AddComponent<FlightEngineerCore>();

+                }

+            }

+            else if (this.flightEngineerCore != null)

+            {

+                // Using DestroyImmediate to force early destruction and keep saving/loading in synch when switching vessels.

+                DestroyImmediate(this.flightEngineerCore);

+            }

+        }

+

+        #endregion

+

+        #region Destruction

+

+        /// <summary>

+        ///     Force the destruction of the FlightEngineerCore on part destruction.

+        /// </summary>

+        private void OnDestroy()

+        {

+            if (this.flightEngineerCore != null)

+            {

+                DestroyImmediate(this.flightEngineerCore);

+            }

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ApoapsisHeight.cs
@@ -1,1 +1,21 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class ApoapsisHeight : ReadoutModule

+    {

+        public ApoapsisHeight()

+        {

+            this.Name = "Apoapsis Height";

+            this.Category = ReadoutCategory.Orbital;

+            this.HelpMessage = "Shows the vessel's <b><i>apoapsis height</i></b> relative to sea level.";

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.ApA.ToString("N0") + "m");

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/Eccentricity.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class Eccentricity : ReadoutModule

+    {

+        public Eccentricity()

+        {

+            this.Name = "Eccentricity";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.eccentricity.ToAngle());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/Inclination.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class Inclination : ReadoutModule

+    {

+        public Inclination()

+        {

+            this.Name = "Inclination";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.inclination.ToAngle());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/LongitudeOfAscendingNode.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class LongitudeOfAscendingNode : ReadoutModule

+    {

+        public LongitudeOfAscendingNode()

+        {

+            this.Name = "Longitude of AN";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.LAN.ToAngle());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/LongitudeOfPeriapsis.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class LongitudeOfPeriapsis : ReadoutModule

+    {

+        public LongitudeOfPeriapsis()

+        {

+            this.Name = "Longitude of Pe";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine((FlightGlobals.ActiveVessel.orbit.LAN + FlightGlobals.ActiveVessel.orbit.argumentOfPeriapsis).ToAngle());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/OrbitalPeriod.cs
@@ -1,1 +1,25 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class OrbitalPeriod : ReadoutModule

+    {

+        public OrbitalPeriod()

+        {

+            this.Name = "Orbital Period";

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.period.ToTime());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/PeriapsisHeight.cs
@@ -1,1 +1,21 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class PeriapsisHeight : ReadoutModule

+    {

+        public PeriapsisHeight()

+        {

+            this.Name = "Periapsis Height";

+            this.Category = ReadoutCategory.Orbital;

+            this.HelpMessage = "Shows the vessel's <b><i>periapsis height</i></b> relative to sea level.";

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.PeA.ToString("N0") + "m");

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/SemiMajorAxis.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class SemiMajorAxis : ReadoutModule

+    {

+        public SemiMajorAxis()

+        {

+            this.Name = "Semi-Major Axis";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.semiMajorAxis.ToDistance());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/SemiMinorAxis.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class SemiMinorAxis : ReadoutModule

+    {

+        public SemiMinorAxis()

+        {

+            this.Name = "Semi-Minor Axis";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.semiMinorAxis.ToDistance());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/TimeToApoapsis.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class TimeToApoapsis : ReadoutModule

+    {

+        public TimeToApoapsis()

+        {

+            this.Name = "Time to Apoapsis";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.timeToAp.ToTime());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/TimeToPeriapsis.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Orbital

+{

+    public class TimeToPeriapsis : ReadoutModule

+    {

+        public TimeToPeriapsis()

+        {

+            this.Name = "Time to Periapsis";

+            this.Category = ReadoutCategory.Orbital;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.timeToPe.ToTime());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/ReadoutCategory.cs
@@ -1,1 +1,19 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+namespace KerbalEngineer.Flight.Readouts

+{

+    /// <summary>

+    ///     Enumeration of categories that a readout module can associate with.

+    /// </summary>

+    public enum ReadoutCategory

+    {

+        None = 0,

+        Orbital = 1,

+        Surface = 2,

+        Vessel = 4,

+        Rendezvous = 8,

+        Misc = 16

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
@@ -1,1 +1,113 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Collections.Generic;

+using System.Linq;

+

+using KerbalEngineer.Flight.Readouts.Orbital;

+using KerbalEngineer.Flight.Readouts.Surface;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts

+{

+    public class ReadoutLibrary

+    {

+        #region Instance

+

+        private static readonly ReadoutLibrary instance = new ReadoutLibrary();

+

+        /// <summary>

+        ///     Gets the current instance of the readout library.

+        /// </summary>

+        public static ReadoutLibrary Instance

+        {

+            get { return instance; }

+        }

+

+        #endregion

+

+        #region Fields

+

+        private List<ReadoutModule> readoutModules = new List<ReadoutModule>();

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Sets up and populates the readout library with the stock readouts.

+        /// </summary>

+        private ReadoutLibrary()

+        {

+            this.readoutModules.Add(new ApoapsisHeight());

+            this.readoutModules.Add(new PeriapsisHeight());

+            this.readoutModules.Add(new TimeToApoapsis());

+            this.readoutModules.Add(new TimeToPeriapsis());

+            this.readoutModules.Add(new Inclination());

+            this.readoutModules.Add(new Eccentricity());

+            this.readoutModules.Add(new OrbitalPeriod());

+            this.readoutModules.Add(new LongitudeOfAscendingNode());

+            this.readoutModules.Add(new LongitudeOfPeriapsis());

+            this.readoutModules.Add(new SemiMajorAxis());

+            this.readoutModules.Add(new SemiMinorAxis());

+

+            this.readoutModules.Add(new AltitudeSeaLevel());

+            this.readoutModules.Add(new AltitudeTerrain());

+            this.readoutModules.Add(new VerticalSpeed());

+            this.readoutModules.Add(new HorizontalSpeed());

+            this.readoutModules.Add(new Longitude());

+            this.readoutModules.Add(new Latitude());

+            this.readoutModules.Add(new GeeForce());

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the available readout modules.

+        /// </summary>

+        public List<ReadoutModule> ReadoutModules

+        {

+            get { return this.readoutModules; }

+            set { this.readoutModules = value; }

+        }

+

+        #endregion

+

+        #region Methods

+

+        /// <summary>

+        ///     Gets a readout module with the specified name or class name. (Returns null if not found.)

+        /// </summary>

+        public ReadoutModule GetReadoutModule(string name)

+        {

+            return this.readoutModules.FirstOrDefault(r => r.Name == name || r.GetType().Name == name);

+        }

+

+        /// <summary>

+        ///     Gets a list of readout modules which are associated with the specified category.

+        /// </summary>

+        public List<ReadoutModule> GetCategory(ReadoutCategory category)

+        {

+            return this.readoutModules.Where(r => r.Category == category).ToList();

+        }

+

+        /// <summary>

+        ///     Resets all the readout modules.

+        /// </summary>

+        public void Reset()

+        {

+            foreach (var readout in this.readoutModules)

+            {

+                readout.Reset();

+            }

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/ReadoutModule.cs
@@ -1,1 +1,161 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts

+{

+    public abstract class ReadoutModule

+    {

+        #region Constructors

+

+        /// <summary>

+        ///     Creates a new readout module.

+        /// </summary>

+        protected ReadoutModule()

+        {

+            this.InitialiseStyles();

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the readout name.

+        /// </summary>

+        public string Name { get; set; }

+

+        public string HelpMessage { get; set; }

+

+        public bool ShowHelp { get; set; }

+

+        /// <summary>

+        ///     Gets ans sets the readout category.

+        /// </summary>

+        public ReadoutCategory Category { get; set; }

+

+        /// <summary>

+        ///     Gets the width of the content. (Sum of NameStyle + ValueStyle widths.)

+        /// </summary>

+        public float ContentWidth

+        {

+            get { return this.NameStyle.fixedWidth + this.ValueStyle.fixedWidth; }

+        }

+

+        #endregion

+

+        #region GUIStyles

+

+        /// <summary>

+        ///     Gets and sets the name style.

+        /// </summary>

+        public GUIStyle NameStyle { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the value style.

+        /// </summary>

+        public GUIStyle ValueStyle { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the button style.

+        /// </summary>

+        public GUIStyle ButtonStyle { get; set; }

+

+        /// <summary>

+        ///     Initialises all the styles required for this object.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.NameStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleLeft,

+                fontSize = 11,

+                fontStyle = FontStyle.Bold,

+                fixedWidth = 110.0f,

+                fixedHeight = 20.0f

+            };

+

+            this.ValueStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleRight,

+                fontSize = 11,

+                fontStyle = FontStyle.Normal,

+                fixedWidth = 110.0f,

+                fixedHeight = 20.0f

+            };

+

+            this.ButtonStyle = new GUIStyle(HighLogic.Skin.button)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                fontSize = 11,

+                fixedHeight = 20.0f

+            };

+        }

+

+        #endregion

+

+        #region Public Methods

+

+        /// <summary>

+        ///     Draws a single data line.

+        /// </summary>

+        protected void DrawLine(string name, string value)

+        {

+            GUILayout.BeginHorizontal();

+            GUILayout.Label(name, this.NameStyle);

+            GUILayout.Label(value, this.ValueStyle);

+            GUILayout.EndHorizontal();

+        }

+

+        /// <summary>

+        ///     Draws a single data line.

+        /// </summary>

+        protected void DrawLine(string value)

+        {

+            GUILayout.BeginHorizontal();

+            GUILayout.Label(this.Name, this.NameStyle);

+            GUILayout.Label(value, this.ValueStyle);

+            GUILayout.EndHorizontal();

+        }

+

+        #endregion

+

+        #region Virtual Methods

+

+        /// <summary>

+        ///     Called on each update frame where the readout is visible.

+        /// </summary>

+        public virtual void Update() { }

+

+        /// <summary>

+        ///     Called when a readout is asked to draw its self.

+        /// </summary>

+        public virtual void Draw() { }

+

+        /// <summary>

+        ///     Called when the active vessel changes.

+        /// </summary>

+        public virtual void Reset() { }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Surface/AltitudeSeaLevel.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Surface

+{

+    public class AltitudeSeaLevel : ReadoutModule

+    {

+        public AltitudeSeaLevel()

+        {

+            this.Name = "Altitude (Sea Level)";

+            this.Category = ReadoutCategory.Surface;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.altitude.ToDistance());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Surface/AltitudeTerrain.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Surface

+{

+    public class AltitudeTerrain : ReadoutModule

+    {

+        public AltitudeTerrain()

+        {

+            this.Name = "Altitude (Terrain)";

+            this.Category = ReadoutCategory.Surface;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.terrainAltitude.ToDistance());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Surface/GeeForce.cs
@@ -1,1 +1,31 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+namespace KerbalEngineer.Flight.Readouts.Surface

+{

+    public class GeeForce : ReadoutModule

+    {

+        private double maxGeeForce;

+

+        public GeeForce()

+        {

+            this.Name = "G-Force";

+            this.Category = ReadoutCategory.Surface;

+        }

+

+        public override void Draw()

+        {

+            if (FlightGlobals.ActiveVessel.geeForce > this.maxGeeForce)

+            {

+                this.maxGeeForce = FlightGlobals.ActiveVessel.geeForce;

+            }

+            this.DrawLine(FlightGlobals.ActiveVessel.geeForce.ToString("F3") + " / " + this.maxGeeForce.ToString("F3"));

+        }

+

+        public override void Reset()

+        {

+            this.maxGeeForce = 0;

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Surface/HorizontalSpeed.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Surface

+{

+    public class HorizontalSpeed : ReadoutModule

+    {

+        public HorizontalSpeed()

+        {

+            this.Name = "Horizontal Speed";

+            this.Category = ReadoutCategory.Surface;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.horizontalSrfSpeed.ToSpeed());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Surface/Latitude.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Surface

+{

+    public class Latitude : ReadoutModule

+    {

+        public Latitude()

+        {

+            this.Name = "Latitude";

+            this.Category = ReadoutCategory.Surface;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.latitude.ToAngle());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Surface/Longitude.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Surface

+{

+    public class Longitude : ReadoutModule

+    {

+        public Longitude()

+        {

+            this.Name = "Longitude";

+            this.Category = ReadoutCategory.Surface;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.longitude.ToAngle());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Surface/VerticalSpeed.cs
@@ -1,1 +1,26 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Readouts.Surface

+{

+    public class VerticalSpeed : ReadoutModule

+    {

+        public VerticalSpeed()

+        {

+            this.Name = "Vertical Speed";

+            this.Category = ReadoutCategory.Surface;

+        }

+

+        public override void Draw()

+        {

+            this.DrawLine(FlightGlobals.ActiveVessel.verticalSpeed.ToSpeed());

+        }

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Sections/SectionEditor.cs
@@ -1,1 +1,379 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+using KerbalEngineer.Flight.Readouts;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Sections

+{

+    public class SectionEditor : MonoBehaviour

+    {

+        #region Constants

+

+        public const float Width = 500.0f;

+        public const float Height = 500.0f;

+

+        #endregion

+

+        #region Fields

+

+        private Vector2 scrollPositionAvailable;

+        private Vector2 scrollPositionInstalled;

+        private ReadoutCategory selectedCategory = ReadoutCategory.Orbital;

+        private int windowId;

+        private Rect windowPosition;

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Initialises the object's state on creation.

+        /// </summary>

+        private void Start()

+        {

+            this.windowId = this.GetHashCode();

+            this.InitialiseStyles();

+            RenderingManager.AddToPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the parent section for the section editor.

+        /// </summary>

+        public SectionModule ParentSection { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the window position.

+        /// </summary>

+        public Rect WindowPosition

+        {

+            get { return this.windowPosition; }

+            set { this.windowPosition = value; }

+        }

+

+        #endregion

+

+        #region GUIStyles

+

+        private GUIStyle categoryButtonStyle;

+        private GUIStyle helpBoxStyle;

+        private GUIStyle helpTextStyle;

+        private GUIStyle panelTitleStyle;

+        private GUIStyle readoutButtonStyle;

+        private GUIStyle readoutNameStyle;

+        private GUIStyle textStyle;

+        private GUIStyle windowStyle;

+

+        /// <summary>

+        ///     Initialises all the styles required for this object.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.windowStyle = new GUIStyle(HighLogic.Skin.window);

+

+            this.categoryButtonStyle = new GUIStyle(HighLogic.Skin.button)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                alignment = TextAnchor.MiddleCenter,

+                fontSize = 12,

+                fontStyle = FontStyle.Bold,

+                fixedHeight = 30.0f,

+            };

+

+            this.panelTitleStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleLeft,

+                fontSize = 12,

+                fontStyle = FontStyle.Bold,

+                fixedHeight = 30.0f,

+                stretchWidth = true

+            };

+

+            this.textStyle = new GUIStyle(HighLogic.Skin.textField)

+            {

+                margin = new RectOffset(3, 3, 3, 3),

+                alignment = TextAnchor.MiddleLeft,

+                stretchWidth = true,

+                stretchHeight = true

+            };

+

+            this.readoutNameStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(10, 0, 0, 0),

+                alignment = TextAnchor.MiddleLeft,

+                fontSize = 12,

+                fontStyle = FontStyle.Bold,

+                stretchWidth = true,

+                stretchHeight = true

+            };

+

+            this.readoutButtonStyle = new GUIStyle(HighLogic.Skin.button)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(2, 2, 2, 2),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleCenter,

+                fontSize = 12,

+                fontStyle = FontStyle.Bold,

+                stretchHeight = true

+            };

+

+            this.helpBoxStyle = new GUIStyle(HighLogic.Skin.box)

+            {

+                margin = new RectOffset(2, 2, 2, 10),

+                padding = new RectOffset(10, 10, 10, 10)

+            };

+

+            this.helpTextStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.yellow

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleLeft,

+                fontSize = 13,

+                fontStyle = FontStyle.Normal,

+                stretchWidth = true,

+                richText = true

+            };

+        }

+

+        #endregion

+

+        #region Drawing

+

+        /// <summary>

+        ///     Called to draw the editor when the UI is enabled.

+        /// </summary>

+        private void Draw()

+        {

+            this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, "EDIT SECTION - " + this.ParentSection.Name.ToUpper(), this.windowStyle).ClampToScreen();

+            this.ParentSection.EditorPositionX = this.windowPosition.x;

+            this.ParentSection.EditorPositionY = this.windowPosition.y;

+        }

+

+        /// <summary>

+        ///     Draws the editor window.

+        /// </summary>

+        private void Window(int windowId)

+        {

+            this.DrawCustomOptions();

+            this.DrawCategorySelector();

+            this.DrawAvailableReadouts();

+            GUILayout.Space(5.0f);

+            this.DrawInstalledReadouts();

+

+            if (GUILayout.Button("CLOSE EDITOR", this.categoryButtonStyle))

+            {

+                this.ParentSection.IsEditorVisible = false;

+            }

+

+            GUI.DragWindow();

+        }

+

+        /// <summary>

+        ///     Draws the options for editing custom sections.

+        /// </summary>

+        private void DrawCustomOptions()

+        {

+            if (!this.ParentSection.IsCustom)

+            {

+                return;

+            }

+

+            GUILayout.BeginHorizontal(GUILayout.Height(25.0f));

+            this.ParentSection.Name = GUILayout.TextField(this.ParentSection.Name, this.textStyle);

+            this.ParentSection.Abbreviation = GUILayout.TextField(this.ParentSection.Abbreviation, this.textStyle, GUILayout.Width(75.0f));

+            if (GUILayout.Button("DELETE SECTION", this.readoutButtonStyle, GUILayout.Width(125.0f)))

+            {

+                this.ParentSection.IsFloating = false;

+                this.ParentSection.IsEditorVisible = false;

+                SectionLibrary.Instance.CustomSections.Remove(this.ParentSection);

+                DisplayStack.Instance.RequestResize();

+            }

+            GUILayout.EndHorizontal();

+        }

+

+        /// <summary>

+        ///     Draws the category selection list.

+        /// </summary>

+        private void DrawCategorySelector()

+        {

+            GUILayout.BeginHorizontal();

+            var isSelected = this.selectedCategory == ReadoutCategory.Orbital;

+            if (GUILayout.Toggle(isSelected, ReadoutCategory.Orbital.ToString().ToUpper(), this.categoryButtonStyle, GUILayout.Width(100.0f)) && !isSelected)

+            {

+                this.selectedCategory = ReadoutCategory.Orbital;

+            }

+

+            isSelected = this.selectedCategory == ReadoutCategory.Surface;

+            if (GUILayout.Toggle(isSelected, ReadoutCategory.Surface.ToString().ToUpper(), this.categoryButtonStyle, GUILayout.Width(100.0f)) && !isSelected)

+            {

+                this.selectedCategory = ReadoutCategory.Surface;

+            }

+

+            isSelected = this.selectedCategory == ReadoutCategory.Vessel;

+            if (GUILayout.Toggle(isSelected, ReadoutCategory.Vessel.ToString().ToUpper(), this.categoryButtonStyle, GUILayout.Width(100.0f)) && !isSelected)

+            {

+                this.selectedCategory = ReadoutCategory.Vessel;

+            }

+

+            isSelected = this.selectedCategory == ReadoutCategory.Rendezvous;

+            if (GUILayout.Toggle(isSelected, ReadoutCategory.Rendezvous.ToString().ToUpper(), this.categoryButtonStyle, GUILayout.Width(100.0f)) && !isSelected)

+            {

+                this.selectedCategory = ReadoutCategory.Rendezvous;

+            }

+

+            isSelected = this.selectedCategory == ReadoutCategory.Misc;

+            if (GUILayout.Toggle(isSelected, ReadoutCategory.Misc.ToString().ToUpper(), this.categoryButtonStyle) && !isSelected)

+            {

+                this.selectedCategory = ReadoutCategory.Misc;

+            }

+            GUILayout.EndHorizontal();

+        }

+

+        /// <summary>

+        ///     Draws the available readouts panel.

+        /// </summary>

+        private void DrawAvailableReadouts()

+        {

+            GUI.skin = HighLogic.Skin;

+            this.scrollPositionAvailable = GUILayout.BeginScrollView(this.scrollPositionAvailable, false, true, GUILayout.Height(200.0f));

+            GUI.skin = null;

+

+            GUILayout.Label("AVAILABLE", this.panelTitleStyle);

+

+            foreach (var readout in ReadoutLibrary.Instance.GetCategory(this.selectedCategory))

+            {

+                if (!this.ParentSection.ReadoutModules.Contains(readout))

+                {

+                    GUILayout.BeginHorizontal(GUILayout.Height(30.0f));

+                    GUILayout.Label(readout.Name, this.readoutNameStyle);

+                    readout.ShowHelp = GUILayout.Toggle(readout.ShowHelp, "?", this.readoutButtonStyle, GUILayout.Width(30.0f));

+                    if (GUILayout.Button("INSTALL", this.readoutButtonStyle, GUILayout.Width(125.0f)))

+                    {

+                        this.ParentSection.ReadoutModules.Add(readout);

+                    }

+                    GUILayout.EndHorizontal();

+

+                    this.ShowHelpMessage(readout);

+                }

+            }

+

+            GUILayout.EndScrollView();

+        }

+

+        /// <summary>

+        ///     Draws the installed readouts panel.

+        /// </summary>

+        private void DrawInstalledReadouts()

+        {

+            GUI.skin = HighLogic.Skin;

+            this.scrollPositionInstalled = GUILayout.BeginScrollView(this.scrollPositionInstalled, false, true);

+            GUI.skin = null;

+

+            GUILayout.Label("INSTALLED", this.panelTitleStyle);

+            ReadoutModule removeReadout = null;

+            foreach (var readout in this.ParentSection.ReadoutModules)

+            {

+                GUILayout.BeginHorizontal(GUILayout.Height(30.0f));

+                GUILayout.Label(readout.Name, this.readoutNameStyle);

+                if (GUILayout.Button("▲", this.readoutButtonStyle, GUILayout.Width(30.0f)))

+                {

+                    var index = this.ParentSection.ReadoutModules.IndexOf(readout);

+                    if (index > 0)

+                    {

+                        this.ParentSection.ReadoutModules[index] = this.ParentSection.ReadoutModules[index - 1];

+                        this.ParentSection.ReadoutModules[index - 1] = readout;

+                    }

+                }

+                if (GUILayout.Button("▼", this.readoutButtonStyle, GUILayout.Width(30.0f)))

+                {

+                    var index = this.ParentSection.ReadoutModules.IndexOf(readout);

+                    if (index < this.ParentSection.ReadoutModules.Count - 1)

+                    {

+                        this.ParentSection.ReadoutModules[index] = this.ParentSection.ReadoutModules[index + 1];

+                        this.ParentSection.ReadoutModules[index + 1] = readout;

+                    }

+                }

+                readout.ShowHelp = GUILayout.Toggle(readout.ShowHelp, "?", this.readoutButtonStyle, GUILayout.Width(30.0f));

+                if (GUILayout.Button("REMOVE", this.readoutButtonStyle, GUILayout.Width(125.0f)))

+                {

+                    removeReadout = readout;

+                }

+                GUILayout.EndHorizontal();

+

+                this.ShowHelpMessage(readout);

+            }

+

+            GUILayout.EndScrollView();

+

+            if (removeReadout != null)

+            {

+                this.ParentSection.ReadoutModules.Remove(removeReadout);

+            }

+        }

+

+        private void ShowHelpMessage(ReadoutModule readout)

+        {

+            if (readout.ShowHelp)

+            {

+                GUILayout.BeginVertical(this.helpBoxStyle);

+                if (readout.HelpMessage != null && readout.HelpMessage.Length > 0)

+                {

+                    GUILayout.Label(readout.HelpMessage, this.helpTextStyle);

+                }

+                else

+                {

+                    GUILayout.Label("Sorry, no help information has been provided for this readout module.", this.helpTextStyle);

+                }

+

+                GUILayout.EndVertical();

+            }

+        }

+

+        #endregion

+

+        #region Destruction

+

+        /// <summary>

+        ///     Runs when the object is destroyed.

+        /// </summary>

+        private void OnDestroy()

+        {

+            RenderingManager.RemoveFromPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Sections/SectionLibrary.cs
@@ -1,1 +1,211 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Collections.Generic;

+using System.Linq;

+

+using KerbalEngineer.Flight.Readouts;

+using KerbalEngineer.Settings;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Sections

+{

+    public class SectionLibrary

+    {

+        #region Instance

+

+        private static readonly SectionLibrary instance = new SectionLibrary();

+

+        /// <summary>

+        ///     Gets the current instance of the section library.

+        /// </summary>

+        public static SectionLibrary Instance

+        {

+            get { return instance; }

+        }

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Sets up and populates the library with the stock sections on creation.

+        /// </summary>

+        private SectionLibrary()

+        {

+            this.StockSections = new List<SectionModule>();

+            this.CustomSections = new List<SectionModule>();

+

+            this.StockSections.Add(new SectionModule

+            {

+                Name = "ORBITAL",

+                Abbreviation = "ORBT",

+                ReadoutModules = ReadoutLibrary.Instance.GetCategory(ReadoutCategory.Orbital)

+            });

+

+            this.StockSections.Add(new SectionModule

+            {

+                Name = "SURFACE",

+                Abbreviation = "SURF",

+                ReadoutModules = ReadoutLibrary.Instance.GetCategory(ReadoutCategory.Surface)

+            });

+

+            this.StockSections.Add(new SectionModule

+            {

+                Name = "VESSEL",

+                Abbreviation = "VESL",

+                ReadoutModules = ReadoutLibrary.Instance.GetCategory(ReadoutCategory.Vessel)

+            });

+

+            this.StockSections.Add(new SectionModule

+            {

+                Name = "RENDEZVOUS",

+                Abbreviation = "RDZV",

+                ReadoutModules = ReadoutLibrary.Instance.GetCategory(ReadoutCategory.Rendezvous)

+            });

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets a list of stock sections

+        /// </summary>

+        public List<SectionModule> StockSections { get; set; }

+

+        /// <summary>

+        ///     Gets and sets a list of custom sections.

+        /// </summary>

+        public List<SectionModule> CustomSections { get; set; }

+

+        /// <summary>

+        ///     Gets the number of sections that are being drawn on the display stack.

+        /// </summary>

+        public int NumberOfStackSections { get; private set; }

+

+        /// <summary>

+        ///     Gets the number of total sections that are stored in the library.

+        /// </summary>

+        public int NumberOfSections { get; private set; }

+

+        #endregion

+

+        #region Updating

+

+        /// <summary>

+        ///     Update all of the sections and process section counts.

+        /// </summary>

+        public void Update()

+        {

+            this.NumberOfStackSections = 0;

+            this.NumberOfSections = 0;

+

+            this.UpdateSections(this.StockSections);

+            this.UpdateSections(this.CustomSections);

+        }

+

+        /// <summary>

+        ///     Updates a list of sections and increments the section counts.

+        /// </summary>

+        private void UpdateSections(IEnumerable<SectionModule> sections)

+        {

+            foreach (var section in sections)

+            {

+                if (section.IsVisible)

+                {

+                    if (!section.IsFloating)

+                    {

+                        this.NumberOfStackSections++;

+                    }

+                    section.Update();

+                }

+

+                this.NumberOfSections++;

+            }

+        }

+

+        #endregion

+

+        #region Saving and Loading

+

+        /// <summary>

+        ///     Saves the state of all the stored sections.

+        /// </summary>

+        public void Save()

+        {

+            var handler = new SettingHandler();

+            handler.Set("StockSections", this.StockSections);

+            handler.Set("CustomSections", this.CustomSections);

+            handler.Save("SectionLibrary.xml");

+        }

+

+        /// <summary>

+        ///     Loads the state of all stored sections.

+        /// </summary>

+        public void Load()

+        {

+            var handler = SettingHandler.Load("SectionLibrary.xml", new[] {typeof(List<SectionModule>)});

+            this.StockSections = handler.Get("StockSections", this.StockSections);

+            this.CustomSections = handler.Get("CustomSections", this.CustomSections);

+        }

+

+        #endregion

+

+        #region Methods

+

+        /// <summary>

+        ///     Gets a section that has the specified name.

+        /// </summary>

+        public SectionModule GetSection(string name)

+        {

+            return this.GetStockSection(name) ?? this.GetCustomSection(name);

+        }

+

+        /// <summary>

+        ///     Gets a stock section that has the specified name.

+        /// </summary>

+        public SectionModule GetStockSection(string name)

+        {

+            return this.StockSections.FirstOrDefault(s => s.Name == name);

+        }

+

+        /// <summary>

+        ///     Gets a custom section that has the specified name.

+        /// </summary>

+        public SectionModule GetCustomSection(string name)

+        {

+            return this.CustomSections.FirstOrDefault(s => s.Name == name);

+        }

+

+        /// <summary>

+        ///     Removes a section with the specified name.

+        /// </summary>

+        public bool RemoveSection(string name)

+        {

+            return this.RemoveStockSection(name) || this.RemoveCustomSection(name);

+        }

+

+        /// <summary>

+        ///     Removes as stock section with the specified name.

+        /// </summary>

+        public bool RemoveStockSection(string name)

+        {

+            return this.StockSections.Remove(this.GetStockSection(name));

+        }

+

+        /// <summary>

+        ///     Removes a custom section witht he specified name.

+        /// </summary>

+        public bool RemoveCustomSection(string name)

+        {

+            return this.CustomSections.Remove(this.GetCustomSection(name));

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Sections/SectionModule.cs
@@ -1,1 +1,288 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System.Collections.Generic;

+using System.Linq;

+using System.Xml.Serialization;

+

+using KerbalEngineer.Flight.Readouts;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Sections

+{

+    /// <summary>

+    ///     Object for management and display of readout modules.

+    /// </summary>

+    public class SectionModule

+    {

+        #region Fields

+

+        private SectionEditor editor;

+        private int numberOfReadouts;

+        private SectionWindow window;

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Creates a new section module.

+        /// </summary>

+        public SectionModule()

+        {

+            this.FloatingPositionX = Screen.width * 0.5f - 125.0f;

+            this.FloatingPositionY = 100.0f;

+            this.EditorPositionX = Screen.width * 0.5f - SectionEditor.Width * 0.5f;

+            this.EditorPositionY = Screen.height * 0.5f - SectionEditor.Height * 0.5f;

+            this.ReadoutModules = new List<ReadoutModule>();

+            this.InitialiseStyles();

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the name of the section.

+        /// </summary>

+        public string Name { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the abbreviation of the section.

+        /// </summary>

+        public string Abbreviation { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the visibility of the section.

+        /// </summary>

+        public bool IsVisible { get; set; }

+

+        /// <summary>

+        ///     Gets and sets whether the section is custom.

+        /// </summary>

+        public bool IsCustom { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the X position of the floating window. (Only used for serialisation.)

+        /// </summary>

+        public float FloatingPositionX { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the Y position of the floating window. (Only used for serialisation.)

+        /// </summary>

+        public float FloatingPositionY { get; set; }

+

+        /// <summary>

+        ///     Gets and sets whether the section is in a floating state.

+        /// </summary>

+        public bool IsFloating

+        {

+            get { return this.window != null; }

+            set

+            {

+                if (value && this.window == null)

+                {

+                    this.window = FlightEngineerCore.Instance.AddSectionWindow(this);

+                }

+                else if (!value && this.window != null)

+                {

+                    Object.Destroy(this.window);

+                }

+            }

+        }

+

+        /// <summary>

+        ///     Gets and sets the X position of the editor window. (Only used for serialisation.)

+        /// </summary>

+        public float EditorPositionX { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the Y position of the editor window. (Only used for serialisation.)

+        /// </summary>

+        public float EditorPositionY { get; set; }

+

+        /// <summary>

+        ///     Gets and sets whether the section editor is visible.

+        /// </summary>

+        public bool IsEditorVisible

+        {

+            get { return this.editor != null; }

+            set

+            {

+                if (value && this.editor == null)

+                {

+                    this.editor = FlightEngineerCore.Instance.AddSectionEditor(this);

+                }

+                else if (!value && this.editor != null)

+                {

+                    Object.Destroy(this.editor);

+                }

+            }

+        }

+

+        /// <summary>

+        ///     Gets and sets the names of the installed readout modules. (Only used with serialisation.)

+        /// </summary>

+        public string[] ReadoutModuleNames

+        {

+            get { return this.ReadoutModules.Select(r => r.GetType().Name).ToArray(); }

+            set { this.ReadoutModules = value.Select(n => ReadoutLibrary.Instance.GetReadoutModule(n)).ToList(); }

+        }

+

+        /// <summary>

+        ///     Gets and sets the list of readout modules.

+        /// </summary>

+        [XmlIgnore] public List<ReadoutModule> ReadoutModules { get; set; }

+

+        #endregion

+

+        #region GUIStyles

+

+        private GUIStyle boxStyle;

+        private GUIStyle buttonStyle;

+        private GUIStyle messageStyle;

+        private GUIStyle titleStyle;

+

+        /// <summary>

+        ///     Initialises all the styles required for this object.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.boxStyle = new GUIStyle(HighLogic.Skin.box)

+            {

+                margin = new RectOffset(),

+                padding = new RectOffset(10, 10, 5, 5)

+            };

+

+            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(2, 0, 5, 2),

+                fontStyle = FontStyle.Bold,

+                stretchWidth = true

+            };

+

+            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(0, 0, 5, 3),

+                padding = new RectOffset(),

+                fontSize = 10,

+                stretchHeight = true

+            };

+

+            this.messageStyle = new GUIStyle(HighLogic.Skin.label)

+            {

+                normal =

+                {

+                    textColor = Color.white

+                },

+                margin = new RectOffset(),

+                padding = new RectOffset(),

+                alignment = TextAnchor.MiddleCenter,

+                fontSize = 12,

+                fontStyle = FontStyle.Bold,

+                fixedWidth = 220.0f,

+                fixedHeight = 20.0f

+            };

+        }

+

+        #endregion

+

+        #region Updating

+

+        /// <summary>

+        ///     Updates all of the internal readout modules.

+        /// </summary>

+        public void Update()

+        {

+            if (!this.IsVisible)

+            {

+                return;

+            }

+

+            foreach (var readout in this.ReadoutModules)

+            {

+                readout.Update();

+            }

+

+            if (this.numberOfReadouts != this.ReadoutModules.Count)

+            {

+                this.numberOfReadouts = this.ReadoutModules.Count;

+                if (!this.IsFloating)

+                {

+                    DisplayStack.Instance.RequestResize();

+                }

+                else

+                {

+                    this.window.RequestResize();

+                }

+            }

+        }

+

+        #endregion

+

+        #region Drawing

+

+        /// <summary>

+        ///     Draws the section and all of the internal readout modules.

+        /// </summary>

+        public void Draw()

+        {

+            if (!this.IsVisible)

+            {

+                return;

+            }

+

+            this.DrawSectionTitleBar();

+            this.DrawReadoutModules();

+        }

+

+        /// <summary>

+        ///     Draws the section title and action buttons.

+        /// </summary>

+        private void DrawSectionTitleBar()

+        {

+            GUILayout.BeginHorizontal();

+            GUILayout.Label(this.Name.ToUpper(), this.titleStyle);

+            this.IsEditorVisible = GUILayout.Toggle(this.IsEditorVisible, "EDIT", this.buttonStyle, GUILayout.Width(60.0f));

+            this.IsFloating = GUILayout.Toggle(this.IsFloating, "FLOAT", this.buttonStyle, GUILayout.Width(60.0f));

+            GUILayout.EndHorizontal();

+        }

+

+        /// <summary>

+        ///     Draws all the readout modules.

+        /// </summary>

+        private void DrawReadoutModules()

+        {

+            GUILayout.BeginVertical(this.boxStyle);

+            if (this.ReadoutModules.Count > 0)

+            {

+                foreach (var readout in this.ReadoutModules)

+                {

+                    readout.Draw();

+                }

+            }

+            else

+            {

+                GUILayout.Label("No readouts are installed.", this.messageStyle);

+            }

+            GUILayout.EndVertical();

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Sections/SectionWindow.cs
@@ -1,1 +1,131 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using KerbalEngineer.Extensions;

+

+using UnityEngine;

+

+#endregion

+

+namespace KerbalEngineer.Flight.Sections

+{

+    public class SectionWindow : MonoBehaviour

+    {

+        #region Fields

+

+        private bool resizeRequested;

+        private int windowId;

+        private Rect windowPosition;

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Initialises the object's state on creation.

+        /// </summary>

+        private void Start()

+        {

+            this.windowId = this.GetHashCode();

+            this.InitialiseStyles();

+            RenderingManager.AddToPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the parent section for the floating section window.

+        /// </summary>

+        public SectionModule ParentSection { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the window position.

+        /// </summary>

+        public Rect WindowPosition

+        {

+            get { return this.windowPosition; }

+            set { this.windowPosition = value; }

+        }

+

+        #endregion

+

+        #region GUIStyles

+

+        private GUIStyle windowStyle;

+

+        /// <summary>

+        ///     Initialises all the styles required for this object.

+        /// </summary>

+        private void InitialiseStyles()

+        {

+            this.windowStyle = new GUIStyle(HighLogic.Skin.window)

+            {

+                margin = new RectOffset(),

+                padding = new RectOffset(5, 5, 0, 5)

+            };

+        }

+

+        #endregion

+

+        #region Drawing

+

+        /// <summary>

+        ///     Called to draw the floating section window when the UI is enabled.

+        /// </summary>

+        private void Draw()

+        {

+            if (this.ParentSection != null && this.ParentSection.IsVisible)

+            {

+                if (this.resizeRequested)

+                {

+                    this.windowPosition.height = 0;

+                    this.resizeRequested = false;

+                }

+                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty, this.windowStyle).ClampToScreen();

+                this.ParentSection.FloatingPositionX = this.windowPosition.x;

+                this.ParentSection.FloatingPositionY = this.windowPosition.y;

+            }

+        }

+

+        /// <summary>

+        ///     Draws the floating section window.

+        /// </summary>

+        private void Window(int windowId)

+        {

+            this.ParentSection.Draw();

+

+            GUI.DragWindow();

+        }

+

+        #endregion

+

+        #region Destruction

+

+        /// <summary>

+        ///     Runs when the object is destroyed.

+        /// </summary>

+        private void OnDestroy()

+        {

+            RenderingManager.RemoveFromPostDrawQueue(0, this.Draw);

+        }

+

+        #endregion

+

+        #region Methods

+

+        /// <summary>

+        ///     Request that the floating section window's size is reset in the next draw call.

+        /// </summary>

+        public void RequestResize()

+        {

+            this.resizeRequested = true;

+        }

+

+        #endregion

+    }

+}

--- a/KerbalEngineer/FlightEngineer/EditDisplay.cs
+++ /dev/null
@@ -1,408 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.IO;

-

-using KerbalEngineer.Extensions;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class EditDisplay : MonoBehaviour

-    {

-        #region Fields

-

-        private readonly int windowId = EngineerGlobals.GetNextWindowId();

-

-        private Vector2 scrollAvailablePosition = Vector2.zero;

-        private Vector2 scrollInstalledPosition = Vector2.zero;

-        private ReadoutCategory selectedCategory = ReadoutCategory.None;

-        private Rect windowPosition = new Rect(Screen.width * 0.5f - 250.0f, Screen.height * 0.5f - 250.0f, 500.0f, 500.0f);

-

-        #region Styles

-

-        private GUIStyle buttonStyle;

-        private GUIStyle customControlBarStyle;

-        private GUIStyle labelStyle;

-        private GUIStyle rowStyle;

-        private GUIStyle textStyle;

-        private GUIStyle titleStyle;

-        private GUIStyle windowStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Properties

-

-        private Section section;

-        private bool visible;

-

-        /// <summary>

-        ///     Gets and sets the visibility of the window.

-        /// </summary>

-        public bool Visible

-        {

-            get { return this.visible; }

-            set { this.visible = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the parent section.

-        /// </summary>

-        public Section Section

-        {

-            get { return this.section; }

-            set { this.section = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        private void Start()

-        {

-            this.InitialiseStyles();

-        }

-

-        /// <summary>

-        ///     Initialises the GUI styles upon request.

-        /// </summary>

-        private void InitialiseStyles()

-        {

-            this.windowStyle = new GUIStyle(HighLogic.Skin.window);

-

-            this.customControlBarStyle = new GUIStyle

-            {

-                fixedHeight = 25.0f

-            };

-

-            this.rowStyle = new GUIStyle

-            {

-                margin = new RectOffset(5, 5, 5, 5),

-                fixedHeight = 25.0f

-            };

-

-            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                stretchHeight = true

-            };

-

-            this.textStyle = new GUIStyle(HighLogic.Skin.textField)

-            {

-                alignment = TextAnchor.MiddleLeft,

-                fontSize = 12,

-                stretchWidth = true,

-                stretchHeight = true

-            };

-

-            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                alignment = TextAnchor.MiddleLeft,

-                fontSize = 12,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-

-            this.labelStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                alignment = TextAnchor.MiddleLeft,

-                fontSize = 12,

-                fontStyle = FontStyle.Bold,

-                stretchHeight = true,

-                stretchWidth = true

-            };

-        }

-

-        #endregion

-

-        #region Drawing

-

-        /// <summary>

-        ///     Runs when the object is called to draw.

-        /// </summary>

-        public void Draw()

-        {

-            if (this.visible)

-            {

-                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, "EDIT SECTION - " + this.section.Title.ToUpper(), this.windowStyle).ClampToScreen();

-            }

-        }

-

-        private void Window(int windowId)

-        {

-            // Selected category has not been selected.

-            if (this.selectedCategory == ReadoutCategory.None)

-            {

-                // Set selected category to first category.

-                if (this.section.Categories.Count > 0)

-                {

-                    this.selectedCategory = this.section.Categories[0];

-                }

-            }

-

-            // Show user controls if the section was user created.

-            if (this.section.IsUser)

-            {

-                this.UserControls();

-            }

-

-            // Show categories selection if there is more than one.

-            if (this.section.Categories.Count > 1)

-            {

-                this.Categories();

-            }

-

-            this.Available(this.selectedCategory);

-            this.Installed();

-

-            // Detach and close buttons.

-            GUILayout.BeginHorizontal(GUILayout.Height(30.0f));

-            if (GUILayout.Toggle(this.section.Window.Visible, "DETACH INTO WINDOW", this.buttonStyle, GUILayout.Width(150.0f)) != this.section.Window.Visible)

-            {

-                this.section.Window.Visible = !this.section.Window.Visible;

-                FlightDisplay.Instance.RequireResize = true;

-            }

-            if (GUILayout.Button("CLOSE EDITOR", this.buttonStyle))

-            {

-                this.visible = false;

-            }

-            GUILayout.EndHorizontal();

-

-            GUI.DragWindow();

-        }

-

-        /// <summary>

-        ///     Draws the user section controls.

-        /// </summary>

-        private void UserControls()

-        {

-            GUILayout.BeginHorizontal(this.customControlBarStyle);

-

-            GUILayout.BeginVertical(GUILayout.Width(50.0f));

-            GUILayout.Label("TITLE - ", this.labelStyle);

-            GUILayout.EndVertical();

-

-            // Title text box.

-            GUILayout.BeginVertical();

-            this.section.Title = GUILayout.TextField(this.section.Title, this.textStyle);

-            GUILayout.EndVertical();

-

-            // Delete button and handling.

-            GUILayout.BeginVertical(GUILayout.Width(100.0f));

-            if (GUILayout.Button("DELETE", this.buttonStyle))

-            {

-                // Remove objects from lists and render queues.

-                SectionList.Instance.UserSections.Remove(this.section);

-                FlightController.Instance.RequireResize = true;

-                if (this.section.Visible)

-                {

-                    FlightDisplay.Instance.RequireResize = true;

-                }

-                RenderingManager.RemoveFromPostDrawQueue(0, this.Draw);

-                RenderingManager.RemoveFromPostDrawQueue(0, this.section.Window.Draw);

-

-                // Delete the settings file.

-                if (File.Exists(EngineerGlobals.AssemblyPath + "Settings/Sections/" + this.section.FileName))

-                {

-                    File.Delete(EngineerGlobals.AssemblyPath + "Settings/Sections/" + this.section.FileName);

-                }

-

-                // Set MonoBehaviour objects to be destroyed.

-                Destroy(this.section.Window);

-                Destroy(this);

-

-                print("[KerbalEngineer]: Deleted " + this.section.Title + " section.");

-            }

-            GUILayout.EndVertical();

-

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws the available categories selection.

-        /// </summary>

-        private void Categories()

-        {

-            GUILayout.BeginHorizontal(GUILayout.Height(30.0f));

-            foreach (var category in this.section.Categories)

-            {

-                var isSelected = this.selectedCategory == category;

-                if (GUILayout.Toggle(isSelected, category.ToString().ToUpper(), this.buttonStyle) && !isSelected)

-                {

-                    this.selectedCategory = category;

-                }

-            }

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws the available readouts panel.

-        /// </summary>

-        private void Available(ReadoutCategory category)

-        {

-            GUI.skin = HighLogic.Skin;

-            this.scrollAvailablePosition = GUILayout.BeginScrollView(this.scrollAvailablePosition, false, true, GUILayout.Height(150f));

-            GUI.skin = null;

-

-            // Panel title.

-            GUILayout.Label("AVAILABLE", this.titleStyle);

-

-            GUILayout.BeginVertical();

-            var count = 0;

-            foreach (var readout in ReadoutList.Instance.GetCategory(category))

-            {

-                // Readout is already installed.

-                if (this.section.Readouts.Contains(readout))

-                {

-                    continue;

-                }

-

-                count++;

-

-                GUILayout.BeginHorizontal(this.rowStyle);

-

-                // Readout name.

-                GUILayout.BeginVertical();

-                GUILayout.Label(readout.Name, this.labelStyle);

-                GUILayout.EndVertical();

-

-                // Info button.

-                GUILayout.BeginVertical(GUILayout.Width(30.0f));

-                if (GUILayout.Button("?", this.buttonStyle))

-                {

-                    InfoDisplay.Instance.Readout = readout;

-                    InfoDisplay.Instance.Visible = true;

-                }

-                GUILayout.EndVertical();

-

-                // Install button

-                GUILayout.BeginVertical(GUILayout.Width(100.0f));

-                if (GUILayout.Button("INSTALL", this.buttonStyle))

-                {

-                    this.section.Readouts.Add(readout);

-                }

-                GUILayout.EndVertical();

-

-                GUILayout.EndHorizontal();

-            }

-

-            // Panel is void of readouts.

-            if (count == 0)

-            {

-                GUILayout.BeginHorizontal(this.rowStyle);

-                GUILayout.Label("All readouts are installed!", this.labelStyle);

-                GUILayout.EndHorizontal();

-            }

-

-            GUILayout.EndVertical();

-            GUILayout.EndScrollView();

-

-            // Insert space between available and installed panels.

-            GUILayout.Space(5f);

-        }

-

-        /// <summary>

-        ///     Draws the installed readouts panel.

-        /// </summary>

-        private void Installed()

-        {

-            GUI.skin = HighLogic.Skin;

-            this.scrollInstalledPosition = GUILayout.BeginScrollView(this.scrollInstalledPosition, false, true);

-            GUI.skin = null;

-

-            // Panel title

-            GUILayout.Label("INSTALLED", this.titleStyle);

-

-            GUILayout.BeginVertical();

-            foreach (var readout in this.section.Readouts)

-            {

-                GUILayout.BeginHorizontal(this.rowStyle);

-

-                // Readout name.

-                GUILayout.BeginVertical();

-                GUILayout.Label(readout.Name, this.labelStyle);

-                GUILayout.EndVertical();

-

-                // Move position up button.

-                GUILayout.BeginVertical(GUILayout.Width(30.0f));

-                if (GUILayout.Button("▲", this.buttonStyle))

-                {

-                    var index = this.section.Readouts.IndexOf(readout);

-                    if (index > 0)

-                    {

-                        this.section.Readouts[index] = this.section.Readouts[index - 1];

-                        this.section.Readouts[index - 1] = readout;

-                    }

-                }

-                GUILayout.EndVertical();

-

-                // Move position down button.

-                GUILayout.BeginVertical(GUILayout.Width(30.0f));

-                if (GUILayout.Button("▼", this.buttonStyle))

-                {

-                    var index = this.section.Readouts.IndexOf(readout);

-                    if (index < this.section.Readouts.Count - 1)

-                    {

-                        this.section.Readouts[index] = this.section.Readouts[index + 1];

-                        this.section.Readouts[index + 1] = readout;

-                    }

-                }

-                GUILayout.EndVertical();

-

-                // Info button.

-                GUILayout.BeginVertical(GUILayout.Width(30.0f));

-                if (GUILayout.Button("?", this.buttonStyle))

-                {

-                    InfoDisplay.Instance.Readout = readout;

-                    InfoDisplay.Instance.Visible = true;

-                }

-                GUILayout.EndVertical();

-

-                // Remove button.

-                GUILayout.BeginVertical(GUILayout.Width(100.0f));

-                if (GUILayout.Button("REMOVE", this.buttonStyle))

-                {

-                    this.section.Readouts.Remove(readout);

-                    FlightDisplay.Instance.RequireResize = true;

-                }

-                GUILayout.EndVertical();

-

-                GUILayout.EndHorizontal();

-            }

-

-            // Panel is void of readouts.

-            if (this.section.Readouts.Count == 0)

-            {

-                GUILayout.BeginHorizontal(this.rowStyle);

-                GUILayout.Label("No readouts are installed!", this.labelStyle);

-                GUILayout.EndHorizontal();

-            }

-

-            GUILayout.EndVertical();

-            GUILayout.EndScrollView();

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/FlightController.cs
+++ /dev/null
@@ -1,303 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.IO;

-

-using KerbalEngineer.Settings;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class FlightController

-    {

-        #region Instance

-

-        private static FlightController _instance;

-

-        /// <summary>

-        ///     Gets the current instance of the flight controller.

-        /// </summary>

-        public static FlightController Instance

-        {

-            get { return _instance ?? (_instance = new FlightController()); }

-        }

-

-        #endregion

-

-        #region Fields

-

-        private readonly Texture2D closedDown = new Texture2D(100, 17, TextureFormat.RGBA32, false);

-        private readonly Texture2D closedHover = new Texture2D(100, 17, TextureFormat.RGBA32, false);

-        private readonly Texture2D closedNormal = new Texture2D(100, 17, TextureFormat.RGBA32, false);

-        private readonly Texture2D openDown = new Texture2D(100, 17, TextureFormat.RGBA32, false);

-        private readonly Texture2D openHover = new Texture2D(100, 17, TextureFormat.RGBA32, false);

-        private readonly Texture2D openNormal = new Texture2D(100, 17, TextureFormat.RGBA32, false);

-        private readonly int windowId = EngineerGlobals.GetNextWindowId();

-

-        private bool clicked;

-        private Rect handlePosition = new Rect(Screen.width * 0.5f + 200.0f, 0, 100.0f, 17.0f);

-        private bool open;

-        private float openAmount;

-        private Rect windowPosition = new Rect(Screen.width * 0.5f + 150.0f, 0, 200.0f, 0);

-

-        #region Styles

-

-        private GUIStyle buttonStyle;

-        private GUIStyle windowStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Properties

-

-        private bool requireResize;

-

-        /// <summary>

-        ///     Gets and sets whether the display requires a resize.

-        /// </summary>

-        public bool RequireResize

-        {

-            get { return this.requireResize; }

-            set { this.requireResize = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        private FlightController()

-        {

-            // Load textures directly from the PNG files. (Would of used GameDatabase but it compresses them so it looks shit!)

-            this.closedNormal.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/FlightButton/ClosedNormal.png"));

-            this.closedHover.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/FlightButton/ClosedHover.png"));

-            this.closedDown.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/FlightButton/ClosedDown.png"));

-            this.openNormal.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/FlightButton/OpenNormal.png"));

-            this.openHover.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/FlightButton/OpenHover.png"));

-            this.openDown.LoadImage(File.ReadAllBytes(EngineerGlobals.AssemblyPath + "GUI/FlightButton/OpenDown.png"));

-

-            this.InitialiseStyles();

-        }

-

-        private void InitialiseStyles()

-        {

-            this.windowStyle = new GUIStyle(HighLogic.Skin.window)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset(3, 3, 3, 3),

-                fixedWidth = this.windowPosition.width

-            };

-

-            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                margin = new RectOffset(),

-                fixedHeight = 20.0f,

-                fontSize = 11,

-                fontStyle = FontStyle.Bold

-            };

-        }

-

-        #endregion

-

-        #region Update and Drawing

-

-        public void Update()

-        {

-            // Controls the sliding animation.

-            if (this.open && this.openAmount < 1f) // Opening

-            {

-                this.openAmount += ((10.0f * (1.0f - this.openAmount)) + 0.5f) * Time.deltaTime;

-

-                if (this.openAmount > 1.0f)

-                {

-                    this.openAmount = 1.0f;

-                }

-            }

-            else if (!this.open && this.openAmount > 0f) // Closing

-            {

-                this.openAmount -= ((10.0f * this.openAmount) + 0.5f) * Time.deltaTime;

-

-                if (this.openAmount < 0)

-                {

-                    this.openAmount = 0;

-                }

-            }

-

-            // Set the sliding positions.

-            this.windowPosition.y = -this.windowPosition.height * (1.0f - this.openAmount);

-            this.handlePosition.y = this.windowPosition.y + this.windowPosition.height;

-        }

-

-        public void Draw()

-        {

-            // Handle window resizing if something has changed within the GUI.

-            if (this.requireResize)

-            {

-                this.requireResize = false;

-                this.windowPosition.height = 0;

-            }

-

-            this.DrawButton();

-

-            if (this.windowPosition.y + this.windowPosition.height > 0 || this.windowPosition.height == 0)

-            {

-                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty, this.windowStyle);

-            }

-        }

-

-        private void Window(int windowId)

-        {

-            // Control bar toggle.

-            FlightDisplay.Instance.ControlBar = GUILayout.Toggle(FlightDisplay.Instance.ControlBar, "CONTROL BAR", this.buttonStyle);

-

-            GUILayout.BeginHorizontal(); // Begin fixed sections.

-

-            // Draw fixed section display toggles.

-            GUILayout.BeginVertical();

-            foreach (var section in SectionList.Instance.FixedSections)

-            {

-                section.Visible = GUILayout.Toggle(section.Visible, section.Title.ToUpper(), this.buttonStyle);

-            }

-            GUILayout.EndVertical();

-

-            // Draw fixed section edit toggles.

-            GUILayout.BeginVertical(GUILayout.Width(50.0f));

-            foreach (var section in SectionList.Instance.FixedSections)

-            {

-                section.EditDisplay.Visible = GUILayout.Toggle(section.EditDisplay.Visible, "EDIT", this.buttonStyle);

-            }

-            GUILayout.EndVertical();

-

-            GUILayout.EndHorizontal(); // End fixed sections.

-            GUILayout.BeginHorizontal(); // Begin user sections.

-

-            // Draw user section display toggles.

-            GUILayout.BeginVertical();

-            foreach (var section in SectionList.Instance.UserSections)

-            {

-                section.Visible = GUILayout.Toggle(section.Visible, section.Title.ToUpper(), this.buttonStyle);

-            }

-            GUILayout.EndVertical();

-

-            // Draw user section edit toggles.

-            GUILayout.BeginVertical(GUILayout.Width(50f));

-            foreach (var section in SectionList.Instance.UserSections)

-            {

-                section.EditDisplay.Visible = GUILayout.Toggle(section.EditDisplay.Visible, "EDIT", this.buttonStyle);

-            }

-            GUILayout.EndVertical();

-

-            GUILayout.EndHorizontal(); // End user sections.

-

-            // New custom user section button.

-            if (GUILayout.Button("NEW USER SECTION", this.buttonStyle))

-            {

-                SectionList.Instance.UserSections.Add(new Section(true));

-            }

-        }

-

-        private void DrawButton()

-        {

-            if (this.clicked) // Button has been clicked whilst being hovered.

-            {

-                GUI.DrawTexture(this.handlePosition, this.open ? this.openDown : this.closedDown);

-

-                if (this.handlePosition.Contains(Event.current.mousePosition)) // Mouse is hovering over the button.

-                {

-                    if (Mouse.Left.GetButtonUp()) // The mouse up event has been triggered whilst over the button.

-                    {

-                        this.clicked = false;

-                        this.open = !this.open;

-                    }

-                }

-            }

-            else // The button is not registering as being clicked.

-            {

-                if (this.handlePosition.Contains(Event.current.mousePosition)) // Mouse is hovering over the button.

-                {

-                    // If the left mouse button has just been pressed, see the button as being clicked.

-                    if (!this.clicked && (Mouse.Left.GetButtonDown()))

-                    {

-                        this.clicked = true;

-                    }

-

-                    if (this.clicked) // The button has just been clicked.

-                    {

-                        GUI.DrawTexture(this.handlePosition, this.open ? this.openDown : this.closedDown);

-                    }

-                    else if (!Mouse.Left.GetButton()) // Mouse button is not down and is just hovering.

-                    {

-                        GUI.DrawTexture(this.handlePosition, this.open ? this.openHover : this.closedHover);

-                    }

-                    else // Mouse button is down but no click was registered over the button.

-                    {

-                        GUI.DrawTexture(this.handlePosition, this.open ? this.openNormal : this.closedNormal);

-                    }

-                }

-                else // The mouse is not being hovered.

-                {

-                    GUI.DrawTexture(this.handlePosition, this.open ? this.openNormal : this.closedNormal);

-                }

-            }

-

-            // Check for an unclick event whilst the mouse is not hovering.

-            if (this.clicked && (Mouse.Left.GetButtonUp()))

-            {

-                this.clicked = false;

-            }

-        }

-

-        #endregion

-

-        #region Save and Load

-

-        /// <summary>

-        ///     Saves the settings associated with the flight controller.

-        /// </summary>

-        public void Save()

-        {

-            try

-            {

-                var list = new SettingList();

-                list.AddSetting("open", this.open);

-                SettingList.SaveToFile(EngineerGlobals.AssemblyPath + "Settings/FlightController", list);

-

-                MonoBehaviour.print("[KerbalEngineer/FlightController]: Successfully saved settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightController]: Failed to save settings.");

-            }

-        }

-

-        /// <summary>

-        ///     Loads the settings associated with the flight controller.

-        /// </summary>

-        public void Load()

-        {

-            try

-            {

-                var list = SettingList.CreateFromFile(EngineerGlobals.AssemblyPath + "Settings/FlightController");

-                this.open = (bool)list.GetSetting("open", this.open);

-

-                MonoBehaviour.print("[KerbalEngineer/FlightController]: Successfully loaded settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightController]: Failed to load settings.");

-            }

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/FlightDisplay.cs
+++ /dev/null
@@ -1,228 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Settings;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class FlightDisplay

-    {

-        #region Instance

-

-        private static FlightDisplay _instance;

-

-        /// <summary>

-        ///     Gets the current instance of the flight display.

-        /// </summary>

-        public static FlightDisplay Instance

-        {

-            get { return _instance ?? (_instance = new FlightDisplay()); }

-        }

-

-        #endregion

-

-        #region Fields

-

-        private readonly int windowId = EngineerGlobals.GetNextWindowId();

-

-        #region Styles

-

-        private GUIStyle buttonStyle;

-        private GUIStyle titleStyle;

-        private GUIStyle windowStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Properties

-

-        private bool controlBar = true;

-        private bool requireResize;

-        private Rect windowPosition = new Rect(Screen.width * 0.5f - 125.0f, 100.0f, 250.0f, 0);

-

-        /// <summary>

-        ///     Gets and sets the window position.

-        /// </summary>

-        public Rect WindowPosition

-        {

-            get { return this.windowPosition; }

-            set { this.windowPosition = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether the window requires a resize.

-        /// </summary>

-        public bool RequireResize

-        {

-            get { return this.requireResize; }

-            set { this.requireResize = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the visibility of the control bar.

-        /// </summary>

-        public bool ControlBar

-        {

-            get { return this.controlBar; }

-            set

-            {

-                if (this.controlBar && !value)

-                {

-                    this.requireResize = true;

-                }

-

-                this.controlBar = value;

-            }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        public FlightDisplay()

-        {

-            this.InitialiseStyles();

-        }

-

-        private void InitialiseStyles()

-        {

-            this.windowStyle = new GUIStyle(HighLogic.Skin.window)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset(5, 5, 3, 5),

-                fixedWidth = 270.0f

-            };

-

-            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 11,

-                fontStyle = FontStyle.Bold

-            };

-

-            this.titleStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                alignment = TextAnchor.MiddleCenter,

-                fontSize = 13,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-        }

-

-        #endregion

-

-        #region Update and Drawing

-

-        public void Update() { }

-

-        public void Draw()

-        {

-            if ((SectionList.Instance.HasVisibleSections && SectionList.Instance.HasAttachedSections) || this.controlBar)

-            {

-                // Handle window resizing if something has changed within the GUI.

-                if (this.requireResize)

-                {

-                    this.requireResize = false;

-                    this.windowPosition.width = 0;

-                    this.windowPosition.height = 0;

-                }

-

-                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty, this.windowStyle).ClampToScreen();

-            }

-        }

-

-        private void Window(int windowId)

-        {

-            // Draw control bar.

-            if (this.controlBar)

-            {

-                GUILayout.Label("FLIGHT ENGINEER " + EngineerGlobals.AssemblyVersion, this.titleStyle);

-                GUILayout.BeginHorizontal();

-                foreach (var section in SectionList.Instance.FixedSections)

-                {

-                    section.Visible = GUILayout.Toggle(section.Visible, section.ShortTitle, this.buttonStyle, GUILayout.Height(25.0f));

-                }

-                GUILayout.EndHorizontal();

-            }

-

-            // Draw all visible fixed sections.

-            foreach (var section in SectionList.Instance.FixedSections)

-            {

-                if (section.Visible && !section.Window.Visible)

-                {

-                    section.Draw();

-                }

-            }

-

-            // Draw all visible user sections.

-            foreach (var section in SectionList.Instance.UserSections)

-            {

-                if (section.Visible && !section.Window.Visible)

-                {

-                    section.Draw();

-                }

-            }

-

-            GUI.DragWindow();

-        }

-

-        #endregion

-

-        #region Save and Load

-

-        /// <summary>

-        ///     Saves the settings associated with the flight display.

-        /// </summary>

-        public void Save()

-        {

-            try

-            {

-                var list = new SettingList();

-                list.AddSetting("x", this.windowPosition.x);

-                list.AddSetting("y", this.windowPosition.y);

-                list.AddSetting("controlBar", this.controlBar);

-                SettingList.SaveToFile(EngineerGlobals.AssemblyPath + "Settings/FlightDisplay", list);

-

-                MonoBehaviour.print("[KerbalEngineer/FlightDisplay]: Successfully saved settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightDisplay]: Failed to save settings.");

-            }

-        }

-

-        /// <summary>

-        ///     Loads the settings associated with the flight display.

-        /// </summary>

-        public void Load()

-        {

-            try

-            {

-                var list = SettingList.CreateFromFile(EngineerGlobals.AssemblyPath + "Settings/FlightDisplay");

-                this.windowPosition.x = (float)list.GetSetting("x", this.windowPosition.x);

-                this.windowPosition.y = (float)list.GetSetting("y", this.windowPosition.y);

-                this.controlBar = (bool)list.GetSetting("controlBar", this.controlBar);

-

-                MonoBehaviour.print("[KerbalEngineer/FlightDisplay]: Successfully loaded settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightDisplay]: Failed to load settings.");

-            }

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/FlightEngineer.cs
+++ /dev/null
@@ -1,92 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class FlightEngineer : PartModule

-    {

-        #region Initialisation

-

-        public void Start()

-        {

-            if (HighLogic.LoadedSceneIsFlight)

-            {

-                RenderingManager.AddToPostDrawQueue(0, this.OnDraw);

-            }

-        }

-

-        #endregion

-

-        #region Update and Drawing

-

-        public void Update()

-        {

-            if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel == this.vessel && this.part.IsPrimary(this.vessel.parts, this))

-            {

-                SectionList.Instance.Update();

-                FlightController.Instance.Update();

-                FlightDisplay.Instance.Update();

-            }

-        }

-

-        public void OnDraw()

-        {

-            if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel == this.vessel && this.part.IsPrimary(this.vessel.parts, this))

-            {

-                FlightController.Instance.Draw();

-                FlightDisplay.Instance.Draw();

-            }

-        }

-

-        #endregion

-

-        #region Save and Load

-

-        /// <summary>

-        ///     Saves the settings when the module is told to save.

-        /// </summary>

-        public override void OnSave(ConfigNode node)

-        {

-            if (!HighLogic.LoadedSceneIsFlight)

-            {

-                return;

-            }

-

-            try

-            {

-                SectionList.Instance.Save();

-                FlightController.Instance.Save();

-                FlightDisplay.Instance.Save();

-            }

-            catch { }

-        }

-

-        /// <summary>

-        ///     Loads the settings when the module is told to load.

-        /// </summary>

-        public override void OnLoad(ConfigNode node)

-        {

-            if (!HighLogic.LoadedSceneIsFlight)

-            {

-                return;

-            }

-

-            try

-            {

-                SectionList.Instance.Load();

-                FlightController.Instance.Load();

-                FlightDisplay.Instance.Load();

-            }

-            catch { }

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/InfoDisplay.cs
+++ /dev/null
@@ -1,159 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class InfoDisplay : MonoBehaviour

-    {

-        #region Instance

-

-        private static InfoDisplay _instance;

-

-        /// <summary>

-        ///     Gets the current instance of the InfoDisplay object.

-        /// </summary>

-        public static InfoDisplay Instance

-        {

-            get { return _instance ?? (_instance = HighLogic.fetch.gameObject.AddComponent<InfoDisplay>()); }

-        }

-

-        #endregion

-

-        #region Fields

-

-        private readonly int windowId = EngineerGlobals.GetNextWindowId();

-

-        private Vector2 scrollPosition = Vector2.zero;

-        private Rect windowPosition = new Rect(Screen.width * 0.5f - 150.0f, Screen.height * 0.5f - 100.0f, 300.0f, 200.0f);

-

-        #region Styles

-

-        private GUIStyle buttonStyle;

-        private GUIStyle infoStyle;

-        private GUIStyle labelStyle;

-        private GUIStyle windowStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Properties

-

-        private Readout readout;

-        private bool visible;

-

-        /// <summary>

-        ///     Gets and sets whether the display is visible.

-        /// </summary>

-        public bool Visible

-        {

-            get { return this.visible; }

-            set { this.visible = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the information to be displayed.

-        /// </summary>

-        public Readout Readout

-        {

-            get { return this.readout; }

-            set { this.readout = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        // Runs when the object is created.

-        private void Start()

-        {

-            this.InitialiseStyles();

-            RenderingManager.AddToPostDrawQueue(0, this.Draw);

-        }

-

-        // Initialises the gui styles upon request.

-        private void InitialiseStyles()

-        {

-            this.windowStyle = new GUIStyle(HighLogic.Skin.window);

-

-            this.infoStyle = new GUIStyle

-            {

-                margin = new RectOffset(5, 5, 5, 5)

-            };

-

-            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 11,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-

-            this.labelStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                alignment = TextAnchor.MiddleLeft,

-                fontSize = 12,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-        }

-

-        #endregion

-

-        #region Drawing

-

-        /// <summary>

-        ///     Runs when the object is called to draw.

-        /// </summary>

-        private void Draw()

-        {

-            if (this.visible)

-            {

-                this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, "READOUT INFORMATION", this.windowStyle).ClampToScreen();

-            }

-        }

-

-        private void Window(int windowId)

-        {

-            GUI.skin = HighLogic.Skin;

-            this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, false, true);

-            GUI.skin = null;

-

-            if (this.readout != null)

-            {

-                GUILayout.Label(this.readout.Name, this.labelStyle);

-

-                GUILayout.BeginHorizontal(this.infoStyle);

-                GUILayout.Label(this.readout.Description, this.labelStyle);

-                GUILayout.EndHorizontal();

-            }

-

-            GUILayout.EndScrollView();

-

-            if (GUILayout.Button("CLOSE", this.buttonStyle))

-            {

-                this.visible = false;

-            }

-

-            GUI.DragWindow();

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/ApoapsisHeight.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class ApoapsisHeight : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Apoapsis Height";

-            this.Description = "Shows the apoapsis height from sea level.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.ApA.ToDistance());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/Eccentricity.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class Eccentricity : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Eccentricity";

-            this.Description = "Shows your current eccentricity.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.eccentricity.ToAngle());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/Inclination.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class Inclination : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Inclination";

-            this.Description = "Shows your current inclination.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.inclination.ToAngle());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/LongitudeOfAN.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class LongitudeOfAN : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Longitude of AN";

-            this.Description = "Shows your longitude of the ascending node.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.LAN.ToAngle());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/LongitudeOfPe.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class LongitudeOfPe : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Longitude of Pe";

-            this.Description = "Shows your longitude of the periapsis.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine((FlightGlobals.ActiveVessel.orbit.LAN + FlightGlobals.ActiveVessel.orbit.argumentOfPeriapsis).ToAngle());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/OrbitalPeriod.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class OrbitalPeriod : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Orbital Period";

-            this.Description = "Shows your orbital period.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.period.ToTime());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/PeriapsisHeight.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class PeriapsisHeight : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Periapsis Height";

-            this.Description = "Shows the periapsis height from sea level.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.PeA.ToDistance());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/SemiMajorAxis.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class SemiMajorAxis : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Semi-major Axis";

-            this.Description = "Shows your semi-major axis.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.semiMajorAxis.ToDistance());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/SemiMinorAxis.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class SemiMinorAxis : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Semi-minor Axis";

-            this.Description = "Shows your semi-minor axis.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.semiMinorAxis.ToDistance());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/TimeToApoapsis.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class TimeToApoapsis : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Time to Apoapsis";

-            this.Description = "Shows the time to apoapsis.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.timeToAp.ToTime());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Orbital/TimeToPeriapsis.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Orbital

-{

-    public class TimeToPeriapsis : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Time to Periapsis";

-            this.Description = "Shows the time to periapsis.";

-            this.Category = ReadoutCategory.Orbital;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.orbit.timeToPe.ToTime());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Readout.cs
+++ /dev/null
@@ -1,198 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public enum ReadoutCategory

-    {

-        None,

-        Orbital,

-        Surface,

-        Vessel,

-        Rendezvous,

-        Misc

-    }

-

-    public abstract class Readout

-    {

-        #region Static Properties

-

-        private static float _nameWidth = 125.0f;

-        private static float _dataWidth = 125.0f;

-

-        /// <summary>

-        ///     Width of the name column.

-        /// </summary>

-        public static float NameWidth

-        {

-            get { return _nameWidth; }

-            set { _nameWidth = value; }

-        }

-

-        /// <summary>

-        ///     Width of the data column.

-        /// </summary>

-        public static float DataWidth

-        {

-            get { return _dataWidth; }

-            set { _dataWidth = value; }

-        }

-

-        #endregion

-

-        #region Properties

-

-        private ReadoutCategory category = ReadoutCategory.Misc;

-        private string description = string.Empty;

-        private string name = string.Empty;

-

-        /// <summary>

-        ///     Gets the GUIStyle for the readout name.

-        /// </summary>

-        protected GUIStyle NameStyle { get; private set; }

-

-        /// <summary>

-        ///     Gets the GUIStyle for the readout data.

-        /// </summary>

-        protected GUIStyle DataStyle { get; private set; }

-

-        /// <summary>

-        ///     Gets the GUIStyle for readout messages.

-        /// </summary>

-        protected GUIStyle MsgStyle { get; private set; }

-

-        /// <summary>

-        ///     Gets the readout name.

-        /// </summary>

-        public string Name

-        {

-            get { return this.name; }

-            protected set { this.name = value; }

-        }

-

-        /// <summary>

-        ///     Gets the readout description.

-        /// </summary>

-        public string Description

-        {

-            get { return this.description; }

-            protected set { this.description = value; }

-        }

-

-        /// <summary>

-        ///     Gets the category in which the readout is contained.

-        /// </summary>

-        public ReadoutCategory Category

-        {

-            get { return this.category; }

-            protected set { this.category = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        protected Readout()

-        {

-            this.InitialiseStyles();

-            this.Initialise();

-        }

-

-        private void InitialiseStyles()

-        {

-            this.NameStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                margin = new RectOffset(),

-                padding = new RectOffset(3, 3, 3, 3),

-                fontSize = 12,

-                fontStyle = FontStyle.Bold,

-                alignment = TextAnchor.MiddleLeft,

-                stretchWidth = true

-            };

-

-            this.DataStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset(3, 3, 3, 3),

-                fontSize = 12,

-                fontStyle = FontStyle.Normal,

-                alignment = TextAnchor.MiddleRight,

-                stretchWidth = true

-            };

-

-            this.MsgStyle = new GUIStyle(this.NameStyle)

-            {

-                alignment = TextAnchor.MiddleCenter

-            };

-        }

-

-        protected virtual void Initialise() { }

-

-        #endregion

-

-        #region Update and Draw

-

-        public virtual void Update() { }

-

-        public virtual void Draw() { }

-

-        /// <summary>

-        ///     Draws a single line readout using the provided data.

-        /// </summary>

-        protected void DrawLine(string data)

-        {

-            GUILayout.BeginHorizontal();

-

-            GUILayout.BeginVertical(GUILayout.Width(_nameWidth));

-            GUILayout.Label(this.Name, this.NameStyle);

-            GUILayout.EndVertical();

-

-            GUILayout.BeginVertical(GUILayout.Width(_dataWidth));

-            GUILayout.Label(data, this.DataStyle);

-            GUILayout.EndVertical();

-

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws a single line readout using the provided name and data.

-        /// </summary>

-        protected void DrawLine(string name, string data)

-        {

-            GUILayout.BeginHorizontal();

-

-            GUILayout.BeginVertical(GUILayout.Width(_nameWidth));

-            GUILayout.Label(name, this.NameStyle);

-            GUILayout.EndVertical();

-

-            GUILayout.BeginVertical(GUILayout.Width(_dataWidth));

-            GUILayout.Label(data, this.DataStyle);

-            GUILayout.EndVertical();

-

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws a single line message that is centred.

-        /// </summary>

-        protected void DrawMessageLine(string message)

-        {

-            GUILayout.BeginHorizontal();

-            GUILayout.Label(message, this.MsgStyle);

-            GUILayout.EndHorizontal();

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/ReadoutList.cs
+++ /dev/null
@@ -1,108 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.Collections.Generic;

-using System.Linq;

-

-using KerbalEngineer.FlightEngineer.Orbital;

-using KerbalEngineer.FlightEngineer.Rendezvous;

-using KerbalEngineer.FlightEngineer.Surface;

-using KerbalEngineer.FlightEngineer.Vessel;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class ReadoutList

-    {

-        #region Instance

-

-        private static ReadoutList _instance;

-

-        /// <summary>

-        ///     Gets the current instance of the readout list.

-        /// </summary>

-        public static ReadoutList Instance

-        {

-            get { return _instance ?? (_instance = new ReadoutList()); }

-        }

-

-        #endregion

-

-        #region Properties

-

-        private List<Readout> readouts = new List<Readout>();

-

-        /// <summary>

-        ///     Gets and sets the available readouts.

-        /// </summary>

-        public List<Readout> Readouts

-        {

-            get { return this.readouts; }

-            set { this.readouts = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        private ReadoutList()

-        {

-            this.readouts.Add(new ApoapsisHeight());

-            this.readouts.Add(new PeriapsisHeight());

-            this.readouts.Add(new TimeToApoapsis());

-            this.readouts.Add(new TimeToPeriapsis());

-            this.readouts.Add(new Inclination());

-            this.readouts.Add(new Eccentricity());

-            this.readouts.Add(new OrbitalPeriod());

-            this.readouts.Add(new LongitudeOfAN());

-            this.readouts.Add(new LongitudeOfPe());

-            this.readouts.Add(new SemiMajorAxis());

-            this.readouts.Add(new SemiMinorAxis());

-

-            this.readouts.Add(new AltitudeSeaLevel());

-            this.readouts.Add(new AltitudeTerrain());

-            this.readouts.Add(new VerticalSpeed());

-            this.readouts.Add(new HorizontalSpeed());

-            this.readouts.Add(new Longitude());

-            this.readouts.Add(new Latitude());

-            this.readouts.Add(new TerminalVelocity());

-            this.readouts.Add(new AtmosEfficiency());

-

-            this.readouts.Add(new DeltaVStaged());

-            this.readouts.Add(new DeltaVTotal());

-            this.readouts.Add(new SpecificImpulse());

-            this.readouts.Add(new TotalMass());

-            this.readouts.Add(new ThrustTotal());

-            this.readouts.Add(new ThrustActual());

-            this.readouts.Add(new ThrustToWeight());

-

-            this.readouts.Add(new TargetSelector());

-        }

-

-        #endregion

-

-        #region Methods

-

-        /// <summary>

-        ///     Gets a readout matching the name provided.

-        /// </summary>

-        public Readout GetReadout(string name)

-        {

-            return this.readouts.FirstOrDefault(readout => readout.Name == name);

-        }

-

-        /// <summary>

-        ///     Gets a list of readouts based on the category provided.

-        /// </summary>

-        public List<Readout> GetCategory(ReadoutCategory category)

-        {

-            return this.readouts.Where(readout => readout.Category == category).ToList();

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Rendezvous/TargetSelector.cs
+++ /dev/null
@@ -1,388 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Rendezvous

-{

-    public class TargetSelector : Readout

-    {

-        #region Fields

-

-        private string searchQuery = string.Empty;

-        private string searchText = string.Empty;

-        private int targetCount;

-        private float typeButtonWidth;

-        private bool typeIsBody;

-        private bool usingSearch;

-        private VesselType vesselType = VesselType.Unknown;

-

-        #region Styles

-

-        private GUIStyle buttonStyle;

-        private GUIStyle searchStyle;

-

-        #endregion

-

-        #endregion

-

-        #region Initialisation

-

-        protected override void Initialise()

-        {

-            this.Name = "Target Selector";

-            this.Description = "A tool to allow easy browsing, searching and selection of targets.";

-            this.Category = ReadoutCategory.Rendezvous;

-            this.InitialiseStyles();

-        }

-

-        private void InitialiseStyles()

-        {

-            this.buttonStyle = new GUIStyle(HighLogic.Skin.button)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                margin = new RectOffset(),

-                padding = new RectOffset(5, 5, 5, 5),

-                fontSize = 11,

-                fontStyle = FontStyle.Bold

-            };

-

-            this.searchStyle = new GUIStyle(HighLogic.Skin.textField)

-            {

-                stretchHeight = true

-            };

-

-            this.typeButtonWidth = Mathf.Round((NameWidth + DataWidth) * 0.5f);

-        }

-

-        #endregion

-

-        #region Drawing

-

-        /// <summary>

-        ///     Draws the target selector structure.

-        /// </summary>

-        public override void Draw()

-        {

-            if (FlightGlobals.fetch.VesselTarget == null)

-            {

-                if (this.vesselType == VesselType.Unknown && !this.typeIsBody)

-                {

-                    this.DrawSearch();

-                    if (this.searchQuery.Length == 0)

-                    {

-                        this.DrawTypes();

-                    }

-                    else

-                    {

-                        this.DrawTargetList();

-                    }

-                }

-                else

-                {

-                    this.DrawBackToTypes();

-                    this.DrawTargetList();

-                }

-            }

-            else

-            {

-                this.DrawTarget();

-            }

-        }

-

-        /// <summary>

-        ///     Draws the search bar.

-        /// </summary>

-        private void DrawSearch()

-        {

-            GUILayout.BeginHorizontal(GUILayout.Height(30.0f));

-            GUILayout.BeginVertical(GUILayout.Width(75.0f));

-            GUILayout.Label("SEARCH:", this.NameStyle, GUILayout.ExpandHeight(true));

-            GUILayout.EndVertical();

-            GUILayout.BeginVertical();

-

-            this.searchText = GUILayout.TextField(this.searchText, this.searchStyle);

-

-            if (this.searchText.Length > 0 || this.searchQuery.Length > 0)

-            {

-                this.searchQuery = this.searchText.ToLower();

-

-                if (!this.usingSearch)

-                {

-                    this.usingSearch = true;

-                    FlightDisplay.Instance.RequireResize = true;

-                }

-            }

-            else if (this.usingSearch)

-            {

-                this.usingSearch = false;

-            }

-

-            GUILayout.EndVertical();

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws the button list of target types.

-        /// </summary>

-        private void DrawTypes()

-        {

-            GUILayout.BeginHorizontal();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Celestial Bodies", this.buttonStyle))

-            {

-                this.SetTypeAsBody();

-            }

-            GUILayout.EndVertical();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Debris", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Debris);

-            }

-            GUILayout.EndVertical();

-            GUILayout.EndHorizontal();

-            GUILayout.BeginHorizontal();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Probes", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Probe);

-            }

-            GUILayout.EndVertical();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Rovers", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Rover);

-            }

-            GUILayout.EndVertical();

-            GUILayout.EndHorizontal();

-            GUILayout.BeginHorizontal();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Landers", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Lander);

-            }

-            GUILayout.EndVertical();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Ships", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Ship);

-            }

-            GUILayout.EndVertical();

-            GUILayout.EndHorizontal();

-            GUILayout.BeginHorizontal();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Stations", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Station);

-            }

-            GUILayout.EndVertical();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Bases", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Base);

-            }

-            GUILayout.EndVertical();

-            GUILayout.EndHorizontal();

-            GUILayout.BeginHorizontal();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("EVAs", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.EVA);

-            }

-            GUILayout.EndVertical();

-            GUILayout.BeginVertical(GUILayout.Width(this.typeButtonWidth));

-            if (GUILayout.Button("Flags", this.buttonStyle))

-            {

-                this.SetTypeAs(VesselType.Flag);

-            }

-            GUILayout.EndVertical();

-            GUILayout.EndHorizontal();

-        }

-

-        /// <summary>

-        ///     Draws the target information when selected.

-        /// </summary>

-        private void DrawTarget()

-        {

-            if (GUILayout.Button("Go Back to Target Selection", this.buttonStyle))

-            {

-                FlightGlobals.fetch.SetVesselTarget(null);

-                FlightDisplay.Instance.RequireResize = true;

-            }

-

-            GUILayout.Space(3f);

-

-            this.DrawLine("Selected Target", FlightGlobals.fetch.VesselTarget.GetName());

-        }

-

-        /// <summary>

-        ///     Draws the back to types button.

-        /// </summary>

-        private void DrawBackToTypes()

-        {

-            if (GUILayout.Button("Go Back to Type Selection", this.buttonStyle))

-            {

-                this.typeIsBody = false;

-                this.vesselType = VesselType.Unknown;

-                FlightDisplay.Instance.RequireResize = true;

-            }

-

-            GUILayout.Space(3f);

-        }

-

-        /// <summary>

-        ///     Draws the target list.

-        /// </summary>

-        private void DrawTargetList()

-        {

-            var count = 0;

-

-            if (this.searchQuery.Length == 0)

-            {

-                if (this.typeIsBody)

-                {

-                    count += this.DrawMoons();

-                    count += this.DrawPlanets();

-                }

-                else

-                {

-                    count += this.DrawVessels();

-                }

-            }

-            else

-            {

-                count += this.DrawVessels();

-                count += this.DrawMoons();

-                count += this.DrawPlanets();

-            }

-

-            if (count == 0)

-            {

-                this.DrawMessageLine("No targets found!");

-            }

-

-            if (count != this.targetCount)

-            {

-                this.targetCount = count;

-                FlightDisplay.Instance.RequireResize = true;

-            }

-        }

-

-        /// <summary>

-        ///     Draws targetable moons.

-        /// </summary>

-        private int DrawMoons()

-        {

-            var count = 0;

-

-            foreach (var body in FlightGlobals.Bodies)

-            {

-                if (FlightGlobals.ActiveVessel.mainBody != body.referenceBody || body == Planetarium.fetch.Sun)

-                {

-                    continue;

-                }

-

-                if (this.searchQuery.Length > 0 && !body.bodyName.ToLower().Contains(this.searchQuery))

-                {

-                    continue;

-                }

-

-                count++;

-                if (GUILayout.Button(body.bodyName, this.buttonStyle))

-                {

-                    this.SetTargetAs(body);

-                }

-            }

-            return count;

-        }

-

-        /// <summary>

-        ///     Draws the targetable planets.

-        /// </summary>

-        private int DrawPlanets()

-        {

-            var count = 0;

-            foreach (var body in FlightGlobals.Bodies)

-            {

-                if (FlightGlobals.ActiveVessel.mainBody.referenceBody != body.referenceBody || body == Planetarium.fetch.Sun || body == FlightGlobals.ActiveVessel.mainBody)

-                {

-                    continue;

-                }

-

-                if (this.searchQuery.Length > 0 && !body.bodyName.ToLower().Contains(this.searchQuery))

-                {

-                    continue;

-                }

-

-                count++;

-                if (GUILayout.Button(body.GetName(), this.buttonStyle))

-                {

-                    this.SetTargetAs(body);

-                }

-            }

-            return count;

-        }

-

-        /// <summary>

-        ///     Draws targetable vessels.

-        /// </summary>

-        private int DrawVessels()

-        {

-            var count = 0;

-            foreach (var vessel in FlightGlobals.Vessels)

-            {

-                if (vessel == FlightGlobals.ActiveVessel || vessel.vesselType != this.vesselType)

-                {

-                    continue;

-                }

-

-                if (this.searchQuery.Length == 0)

-                {

-                    count++;

-

-                    if (GUILayout.Button(vessel.GetName(), this.buttonStyle))

-                    {

-                        this.SetTargetAs(vessel);

-                    }

-                }

-                else if (vessel.vesselName.ToLower().Contains(this.searchQuery))

-                {

-                    count++;

-                    if (GUILayout.Button(vessel.GetName(), this.buttonStyle))

-                    {

-                        this.SetTargetAs(vessel);

-                    }

-                }

-            }

-            return count;

-        }

-

-        private void SetTypeAs(VesselType vesselType)

-        {

-            this.vesselType = vesselType;

-            SectionList.Instance.RequestResize();

-        }

-

-        private void SetTypeAsBody()

-        {

-            this.typeIsBody = true;

-            SectionList.Instance.RequestResize();

-        }

-

-        private void SetTargetAs(ITargetable target)

-        {

-            FlightGlobals.fetch.SetVesselTarget(target);

-            SectionList.Instance.RequestResize();

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Section.cs
+++ /dev/null
@@ -1,308 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.Collections.Generic;

-using System.IO;

-using System.Linq;

-

-using KerbalEngineer.Settings;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class Section

-    {

-        #region Properties

-

-        private readonly EditDisplay editDisplay;

-        private readonly SectionWindow window;

-

-        private List<ReadoutCategory> categories = new List<ReadoutCategory>();

-        private string fileName = string.Empty;

-        private List<Readout> readouts = new List<Readout>();

-        private string shortTitle = string.Empty;

-        private string title = string.Empty;

-        private bool visible;

-

-        /// <summary>

-        ///     Gets the GUIStyle for the section title.

-        /// </summary>

-        protected GUIStyle TitleStyle { get; private set; }

-

-        /// <summary>

-        ///     Gets the GUIStyle for the section area.

-        /// </summary>

-        protected GUIStyle AreaStyle { get; private set; }

-

-        /// <summary>

-        ///     Gets the GUIStyle for section message labels.

-        /// </summary>

-        protected GUIStyle LabelStyle { get; private set; }

-

-        /// <summary>

-        ///     Gets and sets the readouts to be displayed.

-        /// </summary>

-        public List<Readout> Readouts

-        {

-            get { return this.readouts; }

-            set { this.readouts = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether the section is visible.

-        /// </summary>

-        public bool Visible

-        {

-            get { return this.visible; }

-            set

-            {

-                if (this.visible != value)

-                {

-                    FlightDisplay.Instance.RequireResize = true;

-                }

-

-                this.visible = value;

-            }

-        }

-

-        /// <summary>

-        ///     Gets and sets the section title.

-        /// </summary>

-        public string Title

-        {

-            get { return this.title; }

-            set { this.title = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the section short title.

-        /// </summary>

-        public string ShortTitle

-        {

-            get { return this.shortTitle; }

-            set { this.shortTitle = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the filename of the section.

-        /// </summary>

-        public string FileName

-        {

-            get { return this.fileName; }

-            set { this.fileName = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether the section was user created.

-        /// </summary>

-        public bool IsUser { get; set; }

-

-        /// <summary>

-        ///     Gets the edit display associated with the section.

-        /// </summary>

-        public EditDisplay EditDisplay

-        {

-            get { return this.editDisplay; }

-        }

-

-        /// <summary>

-        ///     Gets the section window object.

-        /// </summary>

-        public SectionWindow Window

-        {

-            get { return this.window; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the categories associated with the section.

-        /// </summary>

-        public List<ReadoutCategory> Categories

-        {

-            get { return this.categories; }

-            set { this.categories = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        public Section(bool isUserSection = false, bool isNewSection = true)

-        {

-            this.IsUser = false;

-            this.editDisplay = HighLogic.fetch.gameObject.AddComponent<EditDisplay>();

-            this.editDisplay.Section = this;

-            RenderingManager.AddToPostDrawQueue(0, this.editDisplay.Draw);

-

-            this.window = HighLogic.fetch.gameObject.AddComponent<SectionWindow>();

-            this.window.Section = this;

-            RenderingManager.AddToPostDrawQueue(0, this.window.Draw);

-

-            if (isUserSection)

-            {

-                this.IsUser = true;

-

-                this.Title = "Custom " + (SectionList.Instance.UserSections.Count + 1);

-                this.Categories.Add(ReadoutCategory.Orbital);

-                this.Categories.Add(ReadoutCategory.Surface);

-                this.Categories.Add(ReadoutCategory.Vessel);

-                this.Categories.Add(ReadoutCategory.Rendezvous);

-                this.Categories.Add(ReadoutCategory.Misc);

-                this.Visible = true;

-

-                if (isNewSection)

-                {

-                    this.editDisplay.Visible = true;

-                }

-            }

-

-            this.InitialiseStyles();

-        }

-

-        private void InitialiseStyles()

-        {

-            this.TitleStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset(3, 3, 3, 3),

-                normal =

-                {

-                    textColor = Color.white

-                },

-                fontSize = 13,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-

-            this.AreaStyle = new GUIStyle(HighLogic.Skin.box)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset(5, 5, 5, 5)

-            };

-

-            this.LabelStyle = new GUIStyle(HighLogic.Skin.label)

-            {

-                normal =

-                {

-                    textColor = Color.white

-                },

-                margin = new RectOffset(),

-                padding = new RectOffset(3, 3, 3, 3),

-                alignment = TextAnchor.MiddleCenter,

-                fontSize = 12,

-                fontStyle = FontStyle.Bold,

-                stretchWidth = true

-            };

-        }

-

-        #endregion

-

-        #region Update and Draw

-

-        public void Update()

-        {

-            foreach (var readout in this.readouts)

-            {

-                readout.Update();

-            }

-        }

-

-        public void Draw()

-        {

-            GUILayout.Label(this.title.ToUpper(), this.TitleStyle);

-            GUILayout.BeginVertical(this.AreaStyle);

-            if (this.readouts.Count > 0)

-            {

-                foreach (var readout in this.readouts)

-                {

-                    readout.Draw();

-                }

-            }

-            else

-            {

-                GUILayout.BeginHorizontal(GUILayout.Width(Readout.NameWidth + Readout.DataWidth));

-                GUILayout.Label("No readouts installed!", this.LabelStyle);

-                GUILayout.EndHorizontal();

-            }

-            GUILayout.EndVertical();

-        }

-

-        #endregion

-

-        #region Save and Load

-

-        /// <summary>

-        ///     Saves the settings associated with this section.

-        /// </summary>

-        public void Save()

-        {

-            if (this.title != this.fileName)

-            {

-                if (File.Exists(EngineerGlobals.AssemblyPath + "Settings/Sections/" + this.fileName))

-                {

-                    File.Delete(EngineerGlobals.AssemblyPath + "Settings/Sections/" + this.fileName);

-                }

-            }

-

-            this.fileName = this.title;

-

-            var readoutNames = this.readouts.Select(readout => readout.Name).ToList();

-

-            try

-            {

-                var list = new SettingList();

-                list.AddSetting("visible", this.visible);

-                list.AddSetting("windowed", this.window.Visible);

-                list.AddSetting("x", this.window.PosX);

-                list.AddSetting("y", this.window.PosY);

-                list.AddSetting("categories", this.categories);

-                list.AddSetting("readouts", readoutNames);

-                SettingList.SaveToFile(EngineerGlobals.AssemblyPath + "Settings/Sections/" + this.fileName, list);

-

-                MonoBehaviour.print("[KerbalEngineer/FlightSection/" + this.title + "]: Successfully saved settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightSection/" + this.title + "]: Failed to save settings.");

-            }

-        }

-

-        /// <summary>

-        ///     Loads the settings associated with this section.

-        /// </summary>

-        public void Load()

-        {

-            this.fileName = this.title;

-

-            try

-            {

-                var list = SettingList.CreateFromFile(EngineerGlobals.AssemblyPath + "Settings/Sections/" + this.fileName);

-                this.visible = (bool)list.GetSetting("visible", this.visible);

-                this.window.Visible = (bool)list.GetSetting("windowed", this.window.Visible);

-                this.window.PosX = (float)list.GetSetting("x", this.window.PosX);

-                this.window.PosY = (float)list.GetSetting("y", this.window.PosY);

-                this.categories = list.GetSetting("categories", this.categories) as List<ReadoutCategory>;

-

-                this.readouts.Clear();

-                var readoutNames = list.GetSetting("readouts", new List<string>()) as List<string>;

-                foreach (var name in readoutNames)

-                {

-                    this.Readouts.Add(ReadoutList.Instance.GetReadout(name));

-                }

-

-                MonoBehaviour.print("[KerbalEngineer/FlightSection/" + this.title + "]: Successfully loaded settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightSection/" + this.title + "]: Failed to load settings.");

-            }

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/SectionList.cs
+++ /dev/null
@@ -1,356 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System.Collections.Generic;

-using System.Linq;

-

-using KerbalEngineer.FlightEngineer.Surface;

-using KerbalEngineer.Settings;

-using KerbalEngineer.Simulation;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class SectionList

-    {

-        #region Static Fields

-

-        private static bool _hasLoadedSections;

-

-        #endregion

-

-        #region Instance

-

-        private static SectionList _instance;

-

-        /// <summary>

-        ///     Gets the current instance of the section list.

-        /// </summary>

-        public static SectionList Instance

-        {

-            get { return _instance ?? (_instance = new SectionList()); }

-        }

-

-        #endregion

-

-        #region Properties

-

-        private List<Section> fixedSections = new List<Section>();

-        private bool hasAttachedSections;

-        private bool hasVisibleSections;

-        private bool requireResize;

-

-        private List<Section> userSections = new List<Section>();

-

-        /// <summary>

-        ///     Gets and sets the available fixed sections.

-        /// </summary>

-        public List<Section> FixedSections

-        {

-            get { return this.fixedSections; }

-            set { this.fixedSections = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the available user sections.

-        /// </summary>

-        public List<Section> UserSections

-        {

-            get { return this.userSections; }

-            set { this.userSections = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether to resize all displays.

-        /// </summary>

-        public bool ResizeRequested

-        {

-            get { return this.requireResize; }

-        }

-

-        /// <summary>

-        ///     Gets whether there are visible sections.

-        /// </summary>

-        public bool HasVisibleSections

-        {

-            get { return this.hasVisibleSections; }

-        }

-

-        /// <summary>

-        ///     Gets whether there are attached sections.

-        /// </summary>

-        public bool HasAttachedSections

-        {

-            get { return this.hasAttachedSections; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        private SectionList()

-        {

-            this.fixedSections.Add(new Section

-            {

-                Title = "Orbital",

-                Readouts = ReadoutList.Instance.GetCategory(ReadoutCategory.Orbital),

-                Categories = new List<ReadoutCategory>

-                {

-                    ReadoutCategory.Orbital

-                },

-                ShortTitle = "ORBT"

-            });

-

-            this.fixedSections.Add(new Section

-            {

-                Title = "Surface",

-                Readouts = ReadoutList.Instance.GetCategory(ReadoutCategory.Surface),

-                Categories = new List<ReadoutCategory>

-                {

-                    ReadoutCategory.Surface

-                },

-                ShortTitle = "SURF"

-            });

-

-            this.fixedSections.Add(new Section

-            {

-                Title = "Vessel",

-                Readouts = ReadoutList.Instance.GetCategory(ReadoutCategory.Vessel),

-                Categories = new List<ReadoutCategory>

-                {

-                    ReadoutCategory.Vessel

-                },

-                ShortTitle = "VESL"

-            });

-

-            this.fixedSections.Add(new Section

-            {

-                Title = "Rendezvous",

-                Readouts = ReadoutList.Instance.GetCategory(ReadoutCategory.Rendezvous),

-                Categories = new List<ReadoutCategory>

-                {

-                    ReadoutCategory.Rendezvous

-                },

-                ShortTitle = "RDZV"

-            });

-        }

-

-        #endregion

-

-        #region Public Methods

-

-        /// <summary>

-        ///     Gets the fixed section with the provided name.

-        /// </summary>

-        public Section GetFixedSection(string name)

-        {

-            return this.fixedSections.FirstOrDefault(section => section.Title == name);

-        }

-

-        /// <summary>

-        ///     Gets the user section with the provided name.

-        /// </summary>

-        public Section GetUserSection(string name)

-        {

-            return this.userSections.FirstOrDefault(section => section.Title == name);

-        }

-

-        public void RequestResize()

-        {

-            this.requireResize = true;

-        }

-

-        #endregion

-

-        #region Update

-

-        public void Update()

-        {

-            if (_hasLoadedSections)

-            {

-                _hasLoadedSections = false;

-            }

-

-            // If a resize is required propagate it to the handling objects.

-            if (this.requireResize)

-            {

-                this.requireResize = false;

-                FlightDisplay.Instance.RequireResize = true;

-

-                foreach (var section in this.fixedSections)

-                {

-                    section.Window.RequireResize = true;

-                }

-

-                foreach (var section in this.userSections)

-                {

-                    section.Window.RequireResize = true;

-                }

-            }

-

-            this.hasVisibleSections = false;

-            this.hasAttachedSections = false;

-

-            // Update all visible fixed sections.

-            foreach (var section in this.fixedSections)

-            {

-                if (!section.Visible)

-                {

-                    continue;

-                }

-

-                if (!this.hasVisibleSections)

-                {

-                    this.hasVisibleSections = true;

-                }

-                if (!section.Window.Visible && !this.hasAttachedSections)

-                {

-                    this.hasAttachedSections = true;

-                }

-                section.Update();

-            }

-

-            // Update all visible user sections.

-            foreach (var section in this.userSections)

-            {

-                if (!section.Visible)

-                {

-                    continue;

-                }

-

-                if (!this.hasVisibleSections)

-                {

-                    this.hasVisibleSections = true;

-                }

-                if (!section.Window.Visible && !this.hasAttachedSections)

-                {

-                    this.hasAttachedSections = true;

-                }

-                section.Update();

-            }

-

-            AtmosphericDetails.Instance.Update();

-            SimulationManager.Gravity = FlightGlobals.getGeeForceAtPosition(FlightGlobals.ActiveVessel.GetWorldPos3D()).magnitude;

-            SimulationManager.Atmosphere = FlightGlobals.getAtmDensity(FlightGlobals.ActiveVessel.staticPressure);

-            SimulationManager.TryStartSimulation();

-        }

-

-        #endregion

-

-        #region Save and Load

-

-        /// <summary>

-        ///     Saves the settings associated with the section list.

-        /// </summary>

-        public void Save()

-        {

-            var fixedSectionNames = new List<string>();

-            var userSectionNames = new List<string>();

-

-            foreach (var section in this.fixedSections)

-            {

-                fixedSectionNames.Add(section.Title);

-                section.Save();

-            }

-

-            foreach (var section in this.userSections)

-            {

-                userSectionNames.Add(section.Title);

-                section.Save();

-            }

-

-            try

-            {

-                var list = new SettingList();

-                list.AddSetting("fixed_sections", fixedSectionNames);

-                list.AddSetting("user_sections", userSectionNames);

-                SettingList.SaveToFile(EngineerGlobals.AssemblyPath + "Settings/FlightSections", list);

-

-                MonoBehaviour.print("[KerbalEngineer/FlightSections]: Successfully saved settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightSections]: Failed to save settings.");

-            }

-        }

-

-        /// <summary>

-        ///     Loads the settings associated with the section list.

-        /// </summary>

-        public void Load()

-        {

-            try

-            {

-                if (_hasLoadedSections)

-                {

-                    return;

-                }

-

-                _hasLoadedSections = true;

-

-                var list = SettingList.CreateFromFile(EngineerGlobals.AssemblyPath + "Settings/FlightSections");

-

-                var fixedSectionNames = list.GetSetting("fixed_sections", new List<string>()) as List<string>;

-                var userSectionNames = list.GetSetting("user_sections", new List<string>()) as List<string>;

-

-                // Load fixed sections.

-                foreach (var name in fixedSectionNames)

-                {

-                    var section = this.GetFixedSection(name);

-

-                    if (section == null)

-                    {

-                        section = new Section(true, false)

-                        {

-                            Title = name

-                        };

-                        this.fixedSections.Add(section);

-                    }

-                    else

-                    {

-                        RenderingManager.AddToPostDrawQueue(0, section.Window.Draw);

-                        RenderingManager.AddToPostDrawQueue(0, section.EditDisplay.Draw);

-                    }

-

-                    section.Load();

-                }

-

-                // Load user sections.

-                foreach (var name in userSectionNames)

-                {

-                    var section = this.GetUserSection(name);

-

-                    if (section == null)

-                    {

-                        section = new Section(true, false)

-                        {

-                            Title = name

-                        };

-                        this.userSections.Add(section);

-                    }

-                    else

-                    {

-                        RenderingManager.AddToPostDrawQueue(0, section.Window.Draw);

-                        RenderingManager.AddToPostDrawQueue(0, section.EditDisplay.Draw);

-                    }

-

-                    section.Load();

-                }

-

-                MonoBehaviour.print("[KerbalEngineer/FlightSections]: Successfully loaded settings.");

-            }

-            catch

-            {

-                MonoBehaviour.print("[KerbalEngineer/FlightSections]: Failed to load settings.");

-            }

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/SectionWindow.cs
+++ /dev/null
@@ -1,127 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-using UnityEngine;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer

-{

-    public class SectionWindow : MonoBehaviour

-    {

-        #region Fields

-

-        private readonly int windowId = EngineerGlobals.GetNextWindowId();

-        private Rect position = new Rect(Screen.width * 0.5f - 125.0f, 100.0f, 250.0f, 0);

-        private GUIStyle windowStyle;

-

-        #endregion

-

-        #region Properties

-

-        private bool requireResize;

-        private Section section;

-        private bool visible;

-

-        /// <summary>

-        ///     Gets and sets the X position of the window.

-        /// </summary>

-        public float PosX

-        {

-            get { return this.position.x; }

-            set { this.position.x = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the Y position of the window.

-        /// </summary>

-        public float PosY

-        {

-            get { return this.position.y; }

-            set { this.position.y = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the visibility of the window.

-        /// </summary>

-        public bool Visible

-        {

-            get { return this.visible; }

-            set { this.visible = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets the parent section.

-        /// </summary>

-        public Section Section

-        {

-            get { return this.section; }

-            set { this.section = value; }

-        }

-

-        /// <summary>

-        ///     Gets and sets whether the window requires a resize.

-        /// </summary>

-        public bool RequireResize

-        {

-            get { return this.requireResize; }

-            set { this.requireResize = value; }

-        }

-

-        #endregion

-

-        #region Initialisation

-

-        private void Start()

-        {

-            this.InitialiseStyles();

-        }

-

-        private void InitialiseStyles()

-        {

-            this.windowStyle = new GUIStyle(HighLogic.Skin.window)

-            {

-                margin = new RectOffset(),

-                padding = new RectOffset(5, 5, 3, 5),

-                fixedWidth = 270.0f

-            };

-        }

-

-        #endregion

-

-        #region Update and Drawing

-

-        private void Update() { }

-

-        public void Draw()

-        {

-            if (!this.section.Visible || !this.visible)

-            {

-                return;

-            }

-

-            // Handle window resizing if something has changed within the GUI.

-            if (this.requireResize)

-            {

-                this.requireResize = false;

-                this.position.width = 0;

-                this.position.height = 0;

-            }

-

-            this.position = GUILayout.Window(this.windowId, this.position, this.Window, string.Empty, this.windowStyle).ClampToScreen();

-        }

-

-        private void Window(int windowId)

-        {

-            this.section.Draw();

-            GUI.DragWindow();

-        }

-

-        #endregion

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/AltitudeSeaLevel.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class AltitudeSeaLevel : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Altitude (Sea Level)";

-            this.Description = "Shows your altitude relative to sea level.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.altitude.ToDistance());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/AltitudeTerrain.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class AltitudeTerrain : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Altitude (Terrain)";

-            this.Description = "Shows your altitude above the terrain.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine((FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.terrainAltitude).ToDistance());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/AtmosEfficiency.cs
+++ /dev/null
@@ -1,47 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class AtmosEfficiency : Readout

-    {

-        private bool visible;

-

-        protected override void Initialise()

-        {

-            this.Name = "Atmos. Efficiency";

-            this.Description = "The difference between current and terminal velocity.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Update()

-        {

-            if (FlightGlobals.ActiveVessel.atmDensity > 0)

-            {

-                AtmosphericDetails.Instance.RequestUpdate();

-            }

-        }

-

-        public override void Draw()

-        {

-            if (FlightGlobals.ActiveVessel.atmDensity > 0)

-            {

-                if (!this.visible)

-                {

-                    this.visible = true;

-                }

-

-                this.DrawLine(AtmosphericDetails.Instance.Efficiency.ToString("0.00"));

-            }

-            else

-            {

-                if (this.visible)

-                {

-                    this.visible = false;

-                    SectionList.Instance.RequestResize();

-                }

-            }

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/AtmosphericDetails.cs
+++ /dev/null
@@ -1,99 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using System;

-using System.Linq;

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class AtmosphericDetails

-    {

-        #region Instance

-

-        private static AtmosphericDetails _instance;

-

-        /// <summary>

-        ///     Gets the current instance of atmospheric details.

-        /// </summary>

-        public static AtmosphericDetails Instance

-        {

-            get { return _instance ?? (_instance = new AtmosphericDetails()); }

-        }

-

-        #endregion

-

-        #region Fields

-

-        private bool updateRequested;

-

-        #endregion

-

-        #region Properties

-

-        private double efficiency;

-        private double terminalVelocity;

-

-        /// <summary>

-        ///     Gets whether an update has been requested.

-        /// </summary>

-        public bool UpdateRequested

-        {

-            get { return this.updateRequested; }

-        }

-

-        /// <summary>

-        ///     Gets the terminal velocity of the active vessel.

-        /// </summary>

-        public double TerminalVelocity

-        {

-            get { return this.terminalVelocity; }

-        }

-

-        /// <summary>

-        ///     Gets the difference between current velocity and terminal velocity.

-        /// </summary>

-        public double Efficiency

-        {

-            get { return this.efficiency; }

-        }

-

-        #endregion

-

-        /// <summary>

-        /// Updated the details by recalculating if requested.

-        /// </summary>

-        public void Update()

-        {

-            if (!this.updateRequested)

-            {

-                return;

-            }

-

-            this.updateRequested = false;

-

-            var mass = FlightGlobals.ActiveVessel.parts.Sum(p => p.GetWetMass());

-            var drag = FlightGlobals.ActiveVessel.parts.Sum(p => p.GetWetMass() * p.maximum_drag);

-            var grav = FlightGlobals.getGeeForceAtPosition(FlightGlobals.ActiveVessel.CoM).magnitude;

-            var atmo = FlightGlobals.ActiveVessel.atmDensity;

-            var coef = FlightGlobals.DragMultiplier;

-

-            this.terminalVelocity = Math.Sqrt((2 * mass * grav) / (atmo * drag * coef));

-            this.efficiency = FlightGlobals.ActiveVessel.srf_velocity.magnitude / this.terminalVelocity;

-        }

-

-        /// <summary>

-        /// Request an update to recalculate the details.

-        /// </summary>

-        public void RequestUpdate()

-        {

-            this.updateRequested = true;

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/Horizontal Speed.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class HorizontalSpeed : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Horizontal Speed";

-            this.Description = "Shows your horizontal speed.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.horizontalSrfSpeed.ToSpeed());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/Latitude.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class Latitude : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Latitude";

-            this.Description = "Shows your angle of latitude.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.latitude.ToAngle());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/Longitude.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class Longitude : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Longitude";

-            this.Description = "Shows your angle of longitude.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.longitude.ToAngle());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/TerminalVelocity.cs
+++ /dev/null
@@ -1,53 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class TerminalVelocity : Readout

-    {

-        private bool visible;

-

-        protected override void Initialise()

-        {

-            this.Name = "Terminal Velocity";

-            this.Description = "Shows your terminal velocity in atmosphere.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Update()

-        {

-            if (FlightGlobals.ActiveVessel.atmDensity > 0)

-            {

-                AtmosphericDetails.Instance.RequestUpdate();

-            }

-        }

-

-        public override void Draw()

-        {

-            if (FlightGlobals.ActiveVessel.atmDensity > 0)

-            {

-                if (!this.visible)

-                {

-                    this.visible = true;

-                }

-

-                this.DrawLine(AtmosphericDetails.Instance.TerminalVelocity.ToSpeed());

-            }

-            else

-            {

-                if (this.visible)

-                {

-                    this.visible = false;

-                    SectionList.Instance.RequestResize();

-                }

-            }

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Surface/VerticalSpeed.cs
+++ /dev/null
@@ -1,27 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Surface

-{

-    public class VerticalSpeed : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Vertical Speed";

-            this.Description = "Shows your vertical speed.";

-            this.Category = ReadoutCategory.Surface;

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(FlightGlobals.ActiveVessel.verticalSpeed.ToSpeed());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Vessel/DeltaVStaged.cs
+++ /dev/null
@@ -1,52 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Simulation;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Vessel

-{

-    public class DeltaVStaged : Readout

-    {

-        private int stageCount;

-

-        protected override void Initialise()

-        {

-            this.Name = "DeltaV Staged";

-            this.Description = "Shows the deltaV for each stage.";

-            this.Category = ReadoutCategory.Vessel;

-        }

-

-        public override void Update()

-        {

-            SimulationManager.RequestSimulation();

-        }

-

-        public override void Draw()

-        {

-            var stageCount = 0;

-

-            for (var i = SimulationManager.Stages.Length - 1; i > -1; i--)

-            {

-                var stage = SimulationManager.Stages[i];

-                if (stage.Thrust > 0)

-                {

-                    stageCount++;

-                    this.DrawLine("DeltaV (S" + stage.Number + ")", stage.DeltaV.ToString("N0") + "m/s");

-                }

-            }

-

-            if (stageCount < this.stageCount)

-            {

-                SectionList.Instance.RequestResize();

-            }

-

-            this.stageCount = stageCount;

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Vessel/DeltaVTotal.cs
+++ /dev/null
@@ -1,33 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Simulation;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Vessel

-{

-    public class DeltaVTotal : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "DeltaV Total";

-            this.Description = "Shows the total deltaV for the vessel.";

-            this.Category = ReadoutCategory.Vessel;

-        }

-

-        public override void Update()

-        {

-            SimulationManager.RequestSimulation();

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(SimulationManager.LastStage.TotalDeltaV.ToString("N0") + "m/s");

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Vessel/SpecificImpulse.cs
+++ /dev/null
@@ -1,32 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Simulation;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Vessel

-{

-    public class SpecificImpulse : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Specific Impulse";

-            this.Description = "Shows the specific impulse.";

-            this.Category = ReadoutCategory.Vessel;

-        }

-

-        public override void Update()

-        {

-            SimulationManager.RequestSimulation();;

-        }

-

-        public override void Draw()

-        {          

-            this.DrawLine(SimulationManager.LastStage.Isp.ToString("F1") + "s");

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Vessel/ThrustActual.cs
+++ /dev/null
@@ -1,33 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Simulation;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Vessel

-{

-    public class ThrustActual : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Thrust (Actual)";

-            this.Description = "Shows the actual vessel thrust.";

-            this.Category = ReadoutCategory.Vessel;

-        }

-

-        public override void Update()

-        {

-            SimulationManager.RequestSimulation();

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(SimulationManager.LastStage.ActualThrust.ToForce());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Vessel/ThrustToWeight.cs
+++ /dev/null
@@ -1,32 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Simulation;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Vessel

-{

-    public class ThrustToWeight : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "TWR";

-            this.Description = "Shows the vessel thrust to weight ratio.";

-            this.Category = ReadoutCategory.Vessel;

-        }

-

-        public override void Update()

-        {

-            SimulationManager.RequestSimulation();

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(SimulationManager.LastStage.ThrustToWeight.ToString("0.00"));

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Vessel/ThrustTotal.cs
+++ /dev/null
@@ -1,33 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Simulation;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Vessel

-{

-    public class ThrustTotal : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Thrust (Total)";

-            this.Description = "Shows the vessel thrust.";

-            this.Category = ReadoutCategory.Vessel;

-        }

-

-        public override void Update()

-        {

-            SimulationManager.RequestSimulation();

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(SimulationManager.LastStage.Thrust.ToForce());

-        }

-    }

-}
+

--- a/KerbalEngineer/FlightEngineer/Vessel/TotalMass.cs
+++ /dev/null
@@ -1,33 +1,1 @@
-// Project:	KerbalEngineer

-// Author:	CYBUTEK

-// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

-

-#region Using Directives

-

-using KerbalEngineer.Extensions;

-using KerbalEngineer.Simulation;

-

-#endregion

-

-namespace KerbalEngineer.FlightEngineer.Vessel

-{

-    public class TotalMass : Readout

-    {

-        protected override void Initialise()

-        {

-            this.Name = "Total Mass";

-            this.Description = "Shows the total mass for the vessel.";

-            this.Category = ReadoutCategory.Vessel;

-        }

-

-        public override void Update()

-        {

-            SimulationManager.RequestSimulation();

-        }

-

-        public override void Draw()

-        {

-            this.DrawLine(SimulationManager.LastStage.TotalMass.ToMass());

-        }

-    }

-}
+

--- a/KerbalEngineer/KerbalEngineer.csproj
+++ b/KerbalEngineer/KerbalEngineer.csproj
@@ -38,21 +38,23 @@
       <HintPath>..\Game\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>

       <Private>False</Private>

     </Reference>

-    <Reference Include="System" />

-    <Reference Include="System.Core" />

-    <Reference Include="System.Xml.Linq" />

-    <Reference Include="System.Data.DataSetExtensions" />

-    <Reference Include="System.Data" />

-    <Reference Include="System.Xml" />

+    <Reference Include="System">

+      <HintPath>..\Game\KSP_Data\Managed\System.dll</HintPath>

+      <Private>False</Private>

+    </Reference>

+    <Reference Include="System.Xml">

+      <HintPath>..\Game\KSP_Data\Managed\System.Xml.dll</HintPath>

+      <Private>False</Private>

+    </Reference>

     <Reference Include="UnityEngine">

       <HintPath>..\Game\KSP_Data\Managed\UnityEngine.dll</HintPath>

       <Private>False</Private>

     </Reference>

   </ItemGroup>

   <ItemGroup>

-    <Compile Include="BuildEngineer\BuildButton.cs" />

-    <Compile Include="BuildEngineer\BuildAdvanced.cs" />

-    <Compile Include="BuildEngineer\BuildOverlay.cs" />

+    <Compile Include="Editor\BuildAdvanced.cs" />

+    <Compile Include="Editor\BuildButton.cs" />

+    <Compile Include="Editor\BuildOverlay.cs" />

     <Compile Include="CelestialBodies.cs" />

     <Compile Include="EngineerGlobals.cs" />

     <Compile Include="Extensions\DoubleExtensions.cs" />

@@ -60,48 +62,39 @@
     <Compile Include="Extensions\PartExtensions.cs" />

     <Compile Include="Extensions\PartResourceExtensions.cs" />

     <Compile Include="Extensions\RectExtensions.cs" />

-    <Compile Include="FlightEngineer\InfoDisplay.cs" />

-    <Compile Include="FlightEngineer\EditDisplay.cs" />

-    <Compile Include="FlightEngineer\FlightController.cs" />

-    <Compile Include="FlightEngineer\FlightDisplay.cs" />

-    <Compile Include="FlightEngineer\FlightEngineer.cs" />

-    <Compile Include="FlightEngineer\Orbital\SemiMinorAxis.cs" />

-    <Compile Include="FlightEngineer\Orbital\SemiMajorAxis.cs" />

-    <Compile Include="FlightEngineer\Orbital\LongitudeOfPe.cs" />

-    <Compile Include="FlightEngineer\Orbital\LongitudeOfAN.cs" />

-    <Compile Include="FlightEngineer\Orbital\OrbitalPeriod.cs" />

-    <Compile Include="FlightEngineer\Orbital\Eccentricity.cs" />

-    <Compile Include="FlightEngineer\Orbital\Inclination.cs" />

-    <Compile Include="FlightEngineer\Orbital\TimeToPeriapsis.cs" />

-    <Compile Include="FlightEngineer\Orbital\PeriapsisHeight.cs" />

-    <Compile Include="FlightEngineer\Orbital\TimeToApoapsis.cs" />

-    <Compile Include="FlightEngineer\ReadoutList.cs" />

-    <Compile Include="FlightEngineer\Rendezvous\TargetSelector.cs" />

-    <Compile Include="FlightEngineer\SectionList.cs" />

-    <Compile Include="FlightEngineer\Orbital\ApoapsisHeight.cs" />

-    <Compile Include="FlightEngineer\Readout.cs" />

-    <Compile Include="FlightEngineer\Section.cs" />

-    <Compile Include="FlightEngineer\SectionWindow.cs" />

-    <Compile Include="FlightEngineer\Surface\AltitudeSeaLevel.cs" />

-    <Compile Include="FlightEngineer\Surface\AltitudeTerrain.cs" />

-    <Compile Include="FlightEngineer\Surface\AtmosphericDetails.cs" />

-    <Compile Include="FlightEngineer\Surface\AtmosEfficiency.cs" />

-    <Compile Include="FlightEngineer\Surface\TerminalVelocity.cs" />

-    <Compile Include="FlightEngineer\Surface\Latitude.cs" />

-    <Compile Include="FlightEngineer\Surface\Longitude.cs" />

-    <Compile Include="FlightEngineer\Surface\Horizontal Speed.cs" />

-    <Compile Include="FlightEngineer\Surface\VerticalSpeed.cs" />

-    <Compile Include="FlightEngineer\Vessel\ThrustActual.cs" />

-    <Compile Include="FlightEngineer\Vessel\ThrustToWeight.cs" />

-    <Compile Include="FlightEngineer\Vessel\ThrustTotal.cs" />

-    <Compile Include="FlightEngineer\Vessel\TotalMass.cs" />

-    <Compile Include="FlightEngineer\Vessel\SpecificImpulse.cs" />

-    <Compile Include="FlightEngineer\Vessel\DeltaVTotal.cs" />

-    <Compile Include="FlightEngineer\Vessel\DeltaVStaged.cs" />

+    <Compile Include="Flight\ActionMenu.cs" />

+    <Compile Include="Flight\DisplayStack.cs" />

+    <Compile Include="Flight\FlightEngineerCore.cs" />

+    <Compile Include="Flight\FlightEngineerModule.cs" />

+    <Compile Include="Flight\Readouts\Orbital\ApoapsisHeight.cs" />

+    <Compile Include="Flight\Readouts\Orbital\Eccentricity.cs" />

+    <Compile Include="Flight\Readouts\Orbital\Inclination.cs" />

+    <Compile Include="Flight\Readouts\Orbital\LongitudeOfAscendingNode.cs" />

+    <Compile Include="Flight\Readouts\Orbital\LongitudeOfPeriapsis.cs" />

+    <Compile Include="Flight\Readouts\Orbital\OrbitalPeriod.cs" />

+    <Compile Include="Flight\Readouts\Orbital\PeriapsisHeight.cs" />

+    <Compile Include="Flight\Readouts\Orbital\SemiMajorAxis.cs" />

+    <Compile Include="Flight\Readouts\Orbital\SemiMinorAxis.cs" />

+    <Compile Include="Flight\Readouts\Orbital\TimeToApoapsis.cs" />

+    <Compile Include="Flight\Readouts\Orbital\TimeToPeriapsis.cs" />

+    <Compile Include="Flight\Readouts\ReadoutCategory.cs" />

+    <Compile Include="Flight\Readouts\ReadoutLibrary.cs" />

+    <Compile Include="Flight\Readouts\ReadoutModule.cs" />

+    <Compile Include="Flight\Readouts\Surface\AltitudeSeaLevel.cs" />

+    <Compile Include="Flight\Readouts\Surface\AltitudeTerrain.cs" />

+    <Compile Include="Flight\Readouts\Surface\GeeForce.cs" />

+    <Compile Include="Flight\Readouts\Surface\HorizontalSpeed.cs" />

+    <Compile Include="Flight\Readouts\Surface\Latitude.cs" />

+    <Compile Include="Flight\Readouts\Surface\Longitude.cs" />

+    <Compile Include="Flight\Readouts\Surface\VerticalSpeed.cs" />

+    <Compile Include="Flight\Sections\SectionEditor.cs" />

+    <Compile Include="Flight\Sections\SectionLibrary.cs" />

+    <Compile Include="Flight\Sections\SectionModule.cs" />

+    <Compile Include="Flight\Sections\SectionWindow.cs" />

     <Compile Include="LogMsg.cs" />

     <Compile Include="Properties\AssemblyInfo.cs" />

-    <Compile Include="Settings\Setting.cs" />

-    <Compile Include="Settings\SettingList.cs" />

+    <Compile Include="Settings\SettingHandler.cs" />

+    <Compile Include="Settings\SettingItem.cs" />

     <Compile Include="Simulation\AttachNodeSim.cs" />

     <Compile Include="Simulation\EngineSim.cs" />

     <Compile Include="Simulation\PartSim.cs" />

@@ -112,7 +105,8 @@
     <Compile Include="TapeDriveAnimator.cs" />

   </ItemGroup>

   <ItemGroup>

-    <Folder Include="FlightEngineer\Misc\" />

+    <Folder Include="Flight\Readouts\Rendezvous\" />

+    <Folder Include="Flight\Readouts\Vessel\" />

   </ItemGroup>

   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

   <PropertyGroup>


--- a/KerbalEngineer/Settings/Setting.cs
+++ /dev/null
@@ -1,37 +1,1 @@
-// Name:    Kerbal Engineer Redux
-// Author:  CYBUTEK
-// License: Attribution-NonCommercial-ShareAlike 3.0 Unported
 
-using System;
-
-namespace KerbalEngineer.Settings
-{
-    [Serializable]
-    public class Setting
-    {
-        #region Properties
-
-        /// <summary>
-        /// Gets and sets the name of the setting.
-        /// </summary>
-        public string Name { get; set; }
-
-        /// <summary>
-        /// Gets and sets the setting's value object.
-        /// </summary>
-        public object Value { get; set; }
-
-        #endregion
-
-        #region Initialisation
-
-        public Setting(string name, object value)
-        {
-            this.Name = name;
-            this.Value = value;
-        }
-
-        #endregion
-    }
-}
-

--- /dev/null
+++ b/KerbalEngineer/Settings/SettingHandler.cs
@@ -1,1 +1,197 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+using System;

+using System.Collections.Generic;

+using System.IO;

+using System.Linq;

+using System.Xml.Serialization;

+

+#endregion

+

+namespace KerbalEngineer.Settings

+{

+    /// <summary>

+    ///     Handles the management of setting items.

+    /// </summary>

+    public class SettingHandler

+    {

+        #region Static Fields

+

+        /// <summary>

+        ///     Stores the root settings directory for where all files will be saved.

+        /// </summary>

+        private static string settingsDirectory;

+

+        #endregion

+

+        #region Constructors

+

+        /// <summary>

+        ///     Sets the root settings directory if statically loaded.

+        /// </summary>

+        static SettingHandler()

+        {

+            if (settingsDirectory == null)

+            {

+                settingsDirectory = Path.Combine(EngineerGlobals.AssemblyPath, "Settings");

+            }

+        }

+

+        /// <summary>

+        ///     Creates an empty handler for managing setting items.

+        /// </summary>

+        public SettingHandler()

+        {

+            if (settingsDirectory == null)

+            {

+                settingsDirectory = Path.Combine(EngineerGlobals.AssemblyPath, "Settings");

+            }

+

+            this.Items = new List<SettingItem>();

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the list of items.

+        /// </summary>

+        public List<SettingItem> Items { get; set; }

+

+        #endregion

+

+        #region Get Methods

+

+        /// <summary>

+        ///     Gets a setting object from its name or returns the default object.

+        /// </summary>

+        public T Get<T>(string name, T defaultObject)

+        {

+            foreach (var item in this.Items)

+            {

+                if (item.Name == name)

+                {

+                    return (T)Convert.ChangeType(item.Value, typeof(T));

+                }

+            }

+            return defaultObject;

+        }

+

+        /// <summary>

+        ///     Gets a setting object from its name and inputs it into the output object.  Returns true if a setting was found,

+        ///     false if not.

+        /// </summary>

+        public bool Get<T>(string name, ref T outputObject)

+        {

+            foreach (var item in this.Items)

+            {

+                if (item.Name == name)

+                {

+                    outputObject = (T)Convert.ChangeType(item.Value, typeof(T));

+                    return true;

+                }

+            }

+            return false;

+        }

+

+        #endregion

+

+        #region Set Methods

+

+        /// <summary>

+        ///     Sets a setting object from its name or creates one if it does not already exist.

+        /// </summary>

+        public void Set(string name, object value)

+        {

+            foreach (var item in this.Items)

+            {

+                if (item.Name == name)

+                {

+                    item.Value = value;

+                    return;

+                }

+            }

+            this.Items.Add(new SettingItem(name, value));

+        }

+

+        #endregion

+

+        #region Saving

+

+        /// <summary>

+        ///     Saves all the items in the handler into the specified file.

+        /// </summary>

+        public void Save(string fileName)

+        {

+            fileName = Path.Combine(settingsDirectory, fileName);

+

+            this.Serialise(fileName);

+        }

+

+        /// <summary>

+        ///     Serialises all the items into an xml file.

+        /// </summary>

+        private void Serialise(string fileName)

+        {

+            this.CreateDirectory(fileName);

+            using (var stream = new FileStream(fileName, FileMode.Create))

+            {

+                new XmlSerializer(typeof(List<SettingItem>), this.Items.Select(s => s.Value.GetType()).ToArray()).Serialize(stream, this.Items);

+                stream.Close();

+            }

+        }

+

+        /// <summary>

+        ///     Creates a directory if it does not already exist.

+        /// </summary>

+        private void CreateDirectory(string fileName)

+        {

+            var filePath = new FileInfo(fileName).DirectoryName;

+            if (!Directory.Exists(filePath))

+            {

+                Directory.CreateDirectory(filePath);

+            }

+        }

+

+        #endregion

+

+        #region Loading

+

+        /// <summary>

+        ///     Returns a SettingHandler object created from the specified file. (Optional extra types are required for

+        ///     non-primitive items.)

+        /// </summary>

+        public static SettingHandler Load(string fileName, Type[] extraTypes = null)

+        {

+            fileName = Path.Combine(settingsDirectory, fileName);

+

+            return Deserialise(fileName, extraTypes);

+        }

+

+        /// <summary>

+        ///     Returns a SettingHandler object containing items deserialized from the specified file.

+        /// </summary>

+        private static SettingHandler Deserialise(string fileName, Type[] extraTypes)

+        {

+            if (!File.Exists(fileName))

+            {

+                return new SettingHandler();

+            }

+

+            var handler = new SettingHandler();

+            using (var stream = new FileStream(fileName, FileMode.Open))

+            {

+                handler.Items = new XmlSerializer(typeof(List<SettingItem>), extraTypes).Deserialize(stream) as List<SettingItem>;

+                stream.Close();

+            }

+            return handler;

+        }

+

+        #endregion

+    }

+}

--- /dev/null
+++ b/KerbalEngineer/Settings/SettingItem.cs
@@ -1,1 +1,48 @@
-
+// Project:	KerbalEngineer

+// Author:	CYBUTEK

+// License:	Attribution-NonCommercial-ShareAlike 3.0 Unported

+

+#region Using Directives

+

+#endregion

+

+namespace KerbalEngineer.Settings

+{

+    /// <summary>

+    ///     A serialisable object for storing an item's name and value.

+    /// </summary>

+    public class SettingItem

+    {

+        #region Constructors

+

+        /// <summary>

+        ///     Creates and empty item object.

+        /// </summary>

+        public SettingItem() { }

+

+        /// <summary>

+        ///     Creates an item object containing a name and value.

+        /// </summary>

+        public SettingItem(string name, object value)

+        {

+            this.Name = name;

+            this.Value = value;

+        }

+

+        #endregion

+

+        #region Properties

+

+        /// <summary>

+        ///     Gets and sets the name of the item.

+        /// </summary>

+        public string Name { get; set; }

+

+        /// <summary>

+        ///     Gets and sets the object value of the item.

+        /// </summary>

+        public object Value { get; set; }

+

+        #endregion

+    }

+}

--- a/KerbalEngineer/Settings/SettingList.cs
+++ /dev/null
@@ -1,99 +1,1 @@
-// Name:    Kerbal Engineer Redux
-// Author:  CYBUTEK
-// License: Attribution-NonCommercial-ShareAlike 3.0 Unported
 
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.Serialization.Formatters.Binary;
-
-namespace KerbalEngineer.Settings
-{
-    [Serializable]
-    public class SettingList
-    {
-        #region Fields
-
-        private List<Setting> _settings = new List<Setting>();
-
-        #endregion
-
-        #region Public Methods
-
-        /// <summary>
-        /// Add a setting into this settings list.
-        /// </summary>
-        public void AddSetting(string name, object value)
-        {
-            foreach (Setting setting in _settings)
-            {
-                if (setting.Name == name)
-                {
-                    setting.Value = value;
-                    return;
-                }
-            }
-
-            _settings.Add(new Setting(name, value));
-        }
-
-        /// <summary>
-        /// Gets a setting value from this settings list, or returns the default value.
-        /// </summary>
-        public object GetSetting(string name, object defaultValue)
-        {
-            foreach (Setting setting in _settings)
-            {
-                if (setting.Name == name)
-                    return setting.Value;
-            }
-
-            AddSetting(name, defaultValue);
-            return defaultValue;
-        }
-
-        #endregion
-
-        #region Static Methods
-
-        /// <summary>
-        /// Creates a settings list from an existing file, or returns a blank settings list object.
-        /// </summary>
-        public static SettingList CreateFromFile(string filename)
-        {
-            if (File.Exists(filename))
-            {
-                try
-                {
-                    FileStream stream = File.OpenRead(filename);
-                    SettingList list = new BinaryFormatter().Deserialize(stream) as SettingList;
-                    stream.Close();
-                    return list;
-                }
-                catch { throw new Exception("Could not load settings from file."); }
-            }
-
-            return new SettingList();
-        }
-
-        /// <summary>
-        /// Saves a settings list to a file.
-        /// </summary>
-        public static void SaveToFile(string filename, SettingList settingList)
-        {
-            if (!Directory.Exists(new FileInfo(filename).DirectoryName))
-                Directory.CreateDirectory(new FileInfo(filename).DirectoryName);
-
-            try
-            {
-                FileStream stream = File.OpenWrite(filename);
-                new BinaryFormatter().Serialize(stream, settingList);
-                stream.Close();
-            }
-            catch { throw new Exception("Could not save settings to file."); }
-        }
-
-        #endregion
-    }
-}
-

 Binary files a/Output/KerbalEngineer/Engineer7500/model.mu and /dev/null differ
--- a/Output/KerbalEngineer/Engineer7500/part.cfg
+++ /dev/null
@@ -1,78 +1,1 @@
-PART
-{
-	// --- general parameters ---
-	name = Engineer7500
-	module = Part
-	author = CYBUTEK (Code) || Keptin (Part)
-	
-	// --- asset parameters ---
-	mesh = model.mu
-	texture = model000.mbm
-	rescaleFactor = 0.8
-	
-	// --- editor parameters ---
-	TechRequired = start
-	entryCost = 0
-	cost = 500
-	category = Science
-	subcategory = 0
-	title = ER-7500 Computer Flight Unit
-	manufacturer = CYBUTEK Solutions Ltd.
-	description = The ER-7500 goes back to roots with the Kerbal Engineering System.  This unit has been proven to be at least 1x10^-5 times faster than a standard hard drive.
 
-	// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision
-	attachRules = 0,1,0,1,1
-	
-	// --- node definitions ---
-	// definition format is Position X, Position Y, Position Z, Up X, Up Y, Up Z
-	node_attach = 0.0, 0.0, 0.0, 1.0, 0.0, 0.0
-	
-	// --- standard part parameters ---
-	mass = 0.000001
-	dragModelType = override
-	maximum_drag = 0
-	minimum_drag = 0
-	angularDrag = 0
-	crashTolerance = 15
-	maxTemp = 3400
-	
-	MODULE
-	{
-		name = FlightEngineer
-	}
-	
-	MODULE
-	{
-		name = TapeDriveAnimator
-		
-		UseBakedAnimation = false
-		
-		MinReelSpeed = -30
-		MaxReelSpeed = 30
-		SpeedStopZone = 10
-		SpeedDeadZone = 2.5
-		SpeedChangeAmount = 30
-		MinRepeatTime = 1
-		MaxRepeatTime = 6
-		RepeatTimeDenominator = 8
-		
-		Reel1 = geo_reel1
-		Reel2 = geo_reel2
-		Reel1SpeedRatio = 1
-		Reel2SpeedRatio = 0.75	
-		
-		Lights1 = geo_buttonSet1
-		Lights2 = geo_buttonSet2
-		Lights3 = geo_buttonSet3
-		Lights4 = geo_buttonSet4
-		Lights5 = geo_buttonSet5
-		Lights6 = geo_buttonSet6
-		
-		Lights1Speed = 0
-		Lights2Speed = -2.5
-		Lights3Speed = 2.5
-		Lights4Speed = 10
-		Lights5Speed = -15
-		Lights6Speed = 17.5
-	}
-}

 Binary files a/Output/KerbalEngineer/Engineer7500/textures/model000.mbm and /dev/null differ
 Binary files a/Output/KerbalEngineer/KerbalEngineer.dll and b/Output/KerbalEngineer/KerbalEngineer.dll differ
 Binary files /dev/null and b/Output/KerbalEngineer/Parts/Engineer7500/model.mu differ
--- /dev/null
+++ b/Output/KerbalEngineer/Parts/Engineer7500/part.cfg
@@ -1,1 +1,78 @@
+PART
+{
+	// --- general parameters ---
+	name = Engineer7500
+	module = Part
+	author = CYBUTEK (Code) || Keptin (Part)
+	
+	// --- asset parameters ---
+	mesh = model.mu
+	texture = model000.mbm
+	rescaleFactor = 0.8
+	
+	// --- editor parameters ---
+	TechRequired = start
+	entryCost = 0
+	cost = 500
+	category = Science
+	subcategory = 0
+	title = ER-7500 Computer Flight Unit
+	manufacturer = CYBUTEK Solutions Ltd.
+	description = The ER-7500 goes back to roots with the Kerbal Engineering System.  This unit has been proven to be at least 1x10^-5 times faster than a standard hard drive.
 
+	// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision
+	attachRules = 0,1,0,1,1
+	
+	// --- node definitions ---
+	// definition format is Position X, Position Y, Position Z, Up X, Up Y, Up Z
+	node_attach = 0.0, 0.0, 0.0, 1.0, 0.0, 0.0
+	
+	// --- standard part parameters ---
+	mass = 0.000001
+	dragModelType = override
+	maximum_drag = 0
+	minimum_drag = 0
+	angularDrag = 0
+	crashTolerance = 15
+	maxTemp = 3400
+	
+	MODULE
+	{
+		name = FlightEngineerModule
+	}
+	
+	MODULE
+	{
+		name = TapeDriveAnimator
+		
+		UseBakedAnimation = false
+		
+		MinReelSpeed = -30
+		MaxReelSpeed = 30
+		SpeedStopZone = 10
+		SpeedDeadZone = 2.5
+		SpeedChangeAmount = 30
+		MinRepeatTime = 1
+		MaxRepeatTime = 6
+		RepeatTimeDenominator = 8
+		
+		Reel1 = geo_reel1
+		Reel2 = geo_reel2
+		Reel1SpeedRatio = 1
+		Reel2SpeedRatio = 0.75	
+		
+		Lights1 = geo_buttonSet1
+		Lights2 = geo_buttonSet2
+		Lights3 = geo_buttonSet3
+		Lights4 = geo_buttonSet4
+		Lights5 = geo_buttonSet5
+		Lights6 = geo_buttonSet6
+		
+		Lights1Speed = 0
+		Lights2Speed = -2.5
+		Lights3Speed = 2.5
+		Lights4Speed = 10
+		Lights5Speed = -15
+		Lights6Speed = 17.5
+	}
+}

 Binary files /dev/null and b/Output/KerbalEngineer/Parts/Engineer7500/textures/model000.mbm differ