//
// Kerbal Engineer Redux
//
// Copyright (C) 2014 CYBUTEK
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
#region Using Directives
using System;
using KerbalEngineer.Extensions;
using KerbalEngineer.Flight.Presets;
using KerbalEngineer.Flight.Readouts;
using KerbalEngineer.UIControls;
using UnityEngine;
#endregion
namespace KerbalEngineer.Flight.Sections
{
public class SectionEditor : MonoBehaviour
{
#region Constants
public const float Height = 500.0f;
public const float Width = 500.0f;
#endregion
#region Fields
private GUIStyle categoryButtonActiveStyle;
private GUIStyle categoryButtonStyle;
private DropDown categoryList;
private GUIStyle categoryTitleButtonStyle;
private GUIStyle helpBoxStyle;
private GUIStyle helpTextStyle;
private GUIStyle panelTitleStyle;
private Rect position;
private DropDown presetList;
private GUIStyle readoutButtonStyle;
private GUIStyle readoutNameStyle;
private Vector2 scrollPositionAvailable;
private Vector2 scrollPositionInstalled;
private GUIStyle textStyle;
private GUIStyle windowStyle;
#endregion
#region Properties
///
/// Gets and sets the parent section for the section editor.
///
public SectionModule ParentSection { get; set; }
///
/// Gets and sets the window position.
///
public Rect Position
{
get { return this.position; }
set { this.position = value; }
}
#endregion
#region Methods: protected
protected void Awake()
{
try
{
this.categoryList = this.gameObject.AddComponent();
this.categoryList.DrawCallback = this.DrawCategories;
this.presetList = this.gameObject.AddComponent();
this.presetList.DrawCallback = this.DrawPresets;
}
catch (Exception ex)
{
Logger.Exception(ex);
}
}
///
/// Runs when the object is destroyed.
///
protected void OnDestroy()
{
try
{
RenderingManager.RemoveFromPostDrawQueue(0, this.Draw);
}
catch (Exception ex)
{
Logger.Exception(ex);
}
}
///
/// Initialises the object's state on creation.
///
protected void Start()
{
try
{
this.InitialiseStyles();
//ReadoutCategory.Selected = ReadoutCategory.GetCategory("Orbital");
RenderingManager.AddToPostDrawQueue(0, this.Draw);
}
catch (Exception ex)
{
Logger.Exception(ex);
}
}
#endregion
#region Methods: private
///
/// Called to draw the editor when the UI is enabled.
///
private void Draw()
{
this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "EDIT SECTION - " + this.ParentSection.Name.ToUpper(), this.windowStyle).ClampToScreen();
this.ParentSection.EditorPositionX = this.position.x;
this.ParentSection.EditorPositionY = this.position.y;
}
///
/// Draws the available readouts panel.
///
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.GetCategory(ReadoutCategory.Selected))
{
if (!this.ParentSection.ReadoutModules.Contains(readout) || readout.Cloneable)
{
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();
}
///
/// Draws the categories list drop down UI.
///
private void DrawCategories()
{
foreach (var category in ReadoutCategory.Categories)
{
var description = category.Description;
if (description.Length > 50)
{
description = description.Substring(0, 50 - 1) + "...";
}
if (GUILayout.Button("" + category.Name.ToUpper() + "" + (string.IsNullOrEmpty(category.Description) ? string.Empty : "\n" + description + ""), category == ReadoutCategory.Selected ? this.categoryButtonActiveStyle : this.categoryButtonStyle))
{
ReadoutCategory.Selected = category;
this.categoryList.enabled = false;
}
}
}
///
/// Draws the readoutCategories selection list.
///
private void DrawCategorySelector()
{
this.categoryList.enabled = GUILayout.Toggle(this.categoryList.enabled, "▼ SELECTED CATEGORY: " + ReadoutCategory.Selected.ToString().ToUpper() + " ▼", this.categoryTitleButtonStyle);
if (Event.current.type == EventType.repaint)
{
this.categoryList.SetPosition(GUILayoutUtility.GetLastRect().Translate(this.position));
}
}
///
/// Draws the options for editing custom sections.
///
private void DrawCustomOptions()
{
GUILayout.BeginHorizontal(GUILayout.Height(25.0f));
this.ParentSection.Name = GUILayout.TextField(this.ParentSection.Name, this.textStyle);
var isShowingInControlBar = !string.IsNullOrEmpty(this.ParentSection.Abbreviation);
this.ParentSection.Abbreviation = GUILayout.TextField(this.ParentSection.Abbreviation, this.textStyle, GUILayout.Width(75.0f));
if (this.ParentSection.IsCustom)
{
if (isShowingInControlBar && string.IsNullOrEmpty(this.ParentSection.Abbreviation))
{
DisplayStack.Instance.RequestResize();
}
if (this.ParentSection.IsHud = GUILayout.Toggle(this.ParentSection.IsHud, "HUD", this.readoutButtonStyle, GUILayout.Width(50.0f)))
{
this.ParentSection.IsHudBackground = GUILayout.Toggle(this.ParentSection.IsHudBackground, "BG", this.readoutButtonStyle, GUILayout.Width(50.0f));
}
if (GUILayout.Button("DELETE SECTION", this.readoutButtonStyle, GUILayout.Width(150.0f)))
{
this.ParentSection.IsFloating = false;
this.ParentSection.IsEditorVisible = false;
SectionLibrary.CustomSections.Remove(this.ParentSection);
DisplayStack.Instance.RequestResize();
}
}
GUILayout.EndHorizontal();
}
///
/// Draws the installed readouts panel.
///
private void DrawInstalledReadouts()
{
GUI.skin = HighLogic.Skin;
this.scrollPositionInstalled = GUILayout.BeginScrollView(this.scrollPositionInstalled, false, true);
GUI.skin = null;
GUILayout.Label("INSTALLED", this.panelTitleStyle);
var removeReadout = false;
var removeReadoutIndex = 0;
for (var i = 0; i < this.ParentSection.ReadoutModules.Count; i++)
{
var readout = this.ParentSection.ReadoutModules[i];
GUILayout.BeginHorizontal(GUILayout.Height(30.0f));
GUILayout.Label(readout.Name, this.readoutNameStyle);
if (GUILayout.Button("▲", this.readoutButtonStyle, GUILayout.Width(30.0f)))
{
if (i > 0)
{
this.ParentSection.ReadoutModules[i] = this.ParentSection.ReadoutModules[i - 1];
this.ParentSection.ReadoutModules[i - 1] = readout;
}
}
if (GUILayout.Button("▼", this.readoutButtonStyle, GUILayout.Width(30.0f)))
{
if (i < this.ParentSection.ReadoutModules.Count - 1)
{
this.ParentSection.ReadoutModules[i] = this.ParentSection.ReadoutModules[i + 1];
this.ParentSection.ReadoutModules[i + 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 = true;
removeReadoutIndex = i;
}
GUILayout.EndHorizontal();
this.ShowHelpMessage(readout);
}
GUILayout.EndScrollView();
if (removeReadout)
{
this.ParentSection.ReadoutModules.RemoveAt(removeReadoutIndex);
}
}
private void DrawPresetButton(Preset preset)
{
if (!GUILayout.Button("" + preset.Name.ToUpper() + "", this.categoryButtonStyle))
{
return;
}
this.ParentSection.Name = preset.Name;
this.ParentSection.Abbreviation = preset.Abbreviation;
this.ParentSection.ReadoutModuleNames = preset.ReadoutNames;
this.ParentSection.IsHud = preset.IsHud;
this.ParentSection.IsHudBackground = preset.IsHudBackground;
this.presetList.enabled = false;
}
private void DrawPresetSaveButton()
{
if (!GUILayout.Button("SAVE PRESET", this.categoryButtonStyle))
{
return;
}
this.SavePreset(PresetLibrary.Presets.Find(p => String.Equals(p.Name, this.ParentSection.Name, StringComparison.CurrentCultureIgnoreCase)));
}
///
/// Draws the presetsList selection list.
///
private void DrawPresetSelector()
{
this.presetList.enabled = GUILayout.Toggle(this.presetList.enabled, "▼ PRESETS ▼", this.categoryTitleButtonStyle, GUILayout.Width(150.0f));
if (Event.current.type == EventType.repaint)
{
this.presetList.SetPosition(GUILayoutUtility.GetLastRect().Translate(this.position));
}
}
///
/// Draws the preset list drop down UI.
///
private void DrawPresets()
{
Preset removePreset = null;
foreach (var preset in PresetLibrary.Presets)
{
GUILayout.BeginHorizontal();
this.DrawPresetButton(preset);
if (GUILayout.Button("X", this.categoryButtonStyle, GUILayout.Width(30.0f)))
{
removePreset = preset;
}
GUILayout.EndHorizontal();
}
if (removePreset != null && PresetLibrary.Remove(removePreset))
{
this.presetList.Resize = true;
}
this.DrawPresetSaveButton();
}
///
/// Initialises all the styles required for this object.
///
private void InitialiseStyles()
{
this.windowStyle = new GUIStyle(HighLogic.Skin.window);
this.categoryButtonStyle = new GUIStyle(HighLogic.Skin.button)
{
normal =
{
textColor = Color.white
},
margin = new RectOffset(0, 0, 2, 0),
padding = new RectOffset(5, 5, 5, 5),
alignment = TextAnchor.MiddleCenter,
fontSize = 12,
fontStyle = FontStyle.Normal,
richText = true
};
this.categoryButtonActiveStyle = new GUIStyle(this.categoryButtonStyle)
{
normal = this.categoryButtonStyle.onNormal,
hover = this.categoryButtonStyle.onHover
};
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
};
this.categoryTitleButtonStyle = new GUIStyle(this.readoutButtonStyle)
{
fixedHeight = 30.0f,
stretchHeight = false
};
}
private void SavePreset(Preset preset)
{
if (preset == null)
{
preset = new Preset();
}
preset.Name = this.ParentSection.Name;
preset.Abbreviation = this.ParentSection.Abbreviation;
preset.ReadoutNames = this.ParentSection.ReadoutModuleNames;
preset.IsHud = this.ParentSection.IsHud;
preset.IsHudBackground = this.ParentSection.IsHudBackground;
PresetLibrary.Save(preset);
}
private void ShowHelpMessage(ReadoutModule readout)
{
if (!readout.ShowHelp)
{
return;
}
GUILayout.BeginVertical(this.helpBoxStyle);
GUILayout.Label(!String.IsNullOrEmpty(readout.HelpString) ? readout.HelpString : "Sorry, no help information has been provided for this readout module.", this.helpTextStyle);
GUILayout.EndVertical();
}
///
/// Draws the editor window.
///
private void Window(int windowId)
{
try
{
this.DrawCustomOptions();
GUILayout.BeginHorizontal();
this.DrawCategorySelector();
this.DrawPresetSelector();
GUILayout.EndHorizontal();
this.DrawAvailableReadouts();
GUILayout.Space(5.0f);
this.DrawInstalledReadouts();
if (GUILayout.Button("CLOSE EDITOR", this.categoryTitleButtonStyle))
{
this.ParentSection.IsEditorVisible = false;
}
GUI.DragWindow();
}
catch (Exception ex)
{
Logger.Exception(ex);
}
}
#endregion
}
}