using System;
using System.Diagnostics;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Emergent.Gamebryo.SceneDesigner.GUI.Utility;
using Emergent.Gamebryo.SceneDesigner.PluginAPI;
using Emergent.Gamebryo.SceneDesigner.PluginAPI.StandardServices;
using Message = Emergent.Gamebryo.SceneDesigner.PluginAPI.Message;
namespace Emergent.Gamebryo.SceneDesigner.GUI
{
///
/// Summary description for OptionsDlg.
///
public class OptionsDlg : System.Windows.Forms.Form
{
private System.Windows.Forms.Button m_btnOk;
private System.Windows.Forms.Button m_btnCancel;
private System.Windows.Forms.Panel m_pnlMainPanel;
private System.Windows.Forms.TreeView m_tvCategories;
private IOptionsService m_optionsService;
private ISettingsService m_settingsService;
private System.Windows.Forms.Panel m_pnlSettingsControlHolder;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
#region Private Data
private Control m_currentControlObject;
private SettingsCategory[] m_eCategories;
#endregion
public OptionsDlg()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}
public void SetCategories(SettingsCategory[] categories)
{
m_eCategories = categories;
}
private IOptionsService OptionsService
{
get
{
if (m_optionsService == null)
{
ServiceProvider sp = ServiceProvider.Instance;
m_optionsService = sp.GetService(typeof(IOptionsService))
as IOptionsService;
}
return m_optionsService;
}
}
private ISettingsService SettingsService
{
get
{
if (m_settingsService == null)
{
ServiceProvider sp = ServiceProvider.Instance;
m_settingsService = sp.GetService(typeof(ISettingsService))
as ISettingsService;
}
return m_settingsService;
}
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OptionsDlg));
this.m_btnOk = new System.Windows.Forms.Button();
this.m_btnCancel = new System.Windows.Forms.Button();
this.m_pnlMainPanel = new System.Windows.Forms.Panel();
this.m_pnlSettingsControlHolder = new System.Windows.Forms.Panel();
this.m_tvCategories = new System.Windows.Forms.TreeView();
this.m_pnlMainPanel.SuspendLayout();
this.SuspendLayout();
//
// m_btnOk
//
this.m_btnOk.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.m_btnOk.DialogResult = System.Windows.Forms.DialogResult.OK;
this.m_btnOk.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.m_btnOk.Location = new System.Drawing.Point(204, 321);
this.m_btnOk.Name = "m_btnOk";
this.m_btnOk.Size = new System.Drawing.Size(90, 25);
this.m_btnOk.TabIndex = 1;
this.m_btnOk.Text = "OK";
this.m_btnOk.Click += new System.EventHandler(this.m_btnOk_Click);
//
// m_btnCancel
//
this.m_btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.m_btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.m_btnCancel.Location = new System.Drawing.Point(309, 321);
this.m_btnCancel.Name = "m_btnCancel";
this.m_btnCancel.Size = new System.Drawing.Size(90, 25);
this.m_btnCancel.TabIndex = 2;
this.m_btnCancel.Text = "Cancel";
//
// m_pnlMainPanel
//
this.m_pnlMainPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.m_pnlMainPanel.BackColor = System.Drawing.SystemColors.Control;
this.m_pnlMainPanel.Controls.Add(this.m_pnlSettingsControlHolder);
this.m_pnlMainPanel.Controls.Add(this.m_tvCategories);
this.m_pnlMainPanel.Location = new System.Drawing.Point(0, 0);
this.m_pnlMainPanel.Name = "m_pnlMainPanel";
this.m_pnlMainPanel.Size = new System.Drawing.Size(598, 321);
this.m_pnlMainPanel.TabIndex = 0;
//
// m_pnlSettingsControlHolder
//
this.m_pnlSettingsControlHolder.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.m_pnlSettingsControlHolder.BackColor = System.Drawing.Color.Lavender;
this.m_pnlSettingsControlHolder.Location = new System.Drawing.Point(230, 9);
this.m_pnlSettingsControlHolder.Name = "m_pnlSettingsControlHolder";
this.m_pnlSettingsControlHolder.Size = new System.Drawing.Size(335, 303);
this.m_pnlSettingsControlHolder.TabIndex = 1;
//
// m_tvCategories
//
this.m_tvCategories.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.m_tvCategories.HideSelection = false;
this.m_tvCategories.Location = new System.Drawing.Point(10, 9);
this.m_tvCategories.Name = "m_tvCategories";
this.m_tvCategories.Size = new System.Drawing.Size(211, 303);
this.m_tvCategories.Sorted = true;
this.m_tvCategories.TabIndex = 0;
this.m_tvCategories.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.m_tvCategories_AfterSelect);
//
// OptionsDlg
//
this.AcceptButton = this.m_btnOk;
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.CancelButton = this.m_btnCancel;
this.ClientSize = new System.Drawing.Size(584, 358);
this.Controls.Add(this.m_pnlMainPanel);
this.Controls.Add(this.m_btnCancel);
this.Controls.Add(this.m_btnOk);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(499, 293);
this.Name = "OptionsDlg";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Options";
this.Load += new System.EventHandler(this.OptionsDlg_Load);
this.m_pnlMainPanel.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
#region Winforms handlers
private void OptionsDlg_Load(object sender, System.EventArgs e)
{
Debug.Assert(m_eCategories != null);
ArrayList options = new ArrayList();
foreach (SettingsCategory category in m_eCategories)
{
options.AddRange(
OptionsService.GetOptions(category));
}
foreach(string option in options)
{
string categoryPart = OptionUtilities.StripOption(option);
BuildFullNode(categoryPart);
}
if (m_tvCategories.Nodes.Count > 0)
{
TreeNode firstNode = m_tvCategories.Nodes[0];
m_tvCategories.SelectedNode = firstNode;
}
}
private void m_tvCategories_AfterSelect(object sender,
System.Windows.Forms.TreeViewEventArgs e)
{
if (e.Node.Tag == null)
{
string category = GetCategoryNameFromNode(e.Node);
object optionObject = BuildOptionObject(category);
InitOptionObject(optionObject, category);
Control optionControl = CreateOptionControl();
optionControl.Dock = DockStyle.Fill;
PropertyGrid optionGrid = optionControl as PropertyGrid;
optionGrid.ToolbarVisible = false;
if ( optionGrid != null)
{
optionGrid.SelectedObject = optionObject;
}
e.Node.Tag = optionControl;
}
this.SuspendLayout();
if (m_currentControlObject != null)
{
m_pnlSettingsControlHolder.Controls.Remove(m_currentControlObject);
}
m_pnlSettingsControlHolder.Controls.Add(e.Node.Tag as Control);
m_currentControlObject = e.Node.Tag as Control;
this.ResumeLayout();
}
private void m_btnOk_Click(object sender, System.EventArgs e)
{
//Traverse tree
TreeNodeCollection currentNode = m_tvCategories.Nodes;
PersistNodes(currentNode);
}
#endregion
#region Private Helpers
private void InitOptionObject(object obj, string category)
{
ArrayList options = GetOptionsList(category);
foreach (string option in options)
{
object settingsObject =
OptionsService.GetSettingsObject(option);
object newObject = OptionUtilities.DeepCopy(settingsObject);
OptionUtilities.SetProperty(obj, option, newObject);
}
}
private object BuildOptionObject(string category)
{
ArrayList options = GetOptionsList(category);
TypeBuilder tb = OptionUtilities.GetTypeBuilder();
foreach (string option in options)
{
object settingsObject =
OptionsService.GetSettingsObject(option);
if (settingsObject == null)
{
IMessageService messageService =
ServiceProvider.Instance.GetService(
typeof(IMessageService)) as IMessageService;
Message message = new Message();
message.m_strText = "Invalid option";
string settingName =
OptionsService.GetSettingsName(option);
SettingsCategory settingStore =
OptionsService.GetSettingsCategory(option);
message.m_strDetails =
string.Format(
"The option {0} is mapped to non-existent setting {1}"
+ Environment.NewLine
+ "In the settings store: {2}", option, settingName,
settingStore);
messageService.AddMessage(MessageChannelType.Errors,
message);
}
else
{
OptionUtilities.AddProperty(option,
OptionUtilities.StripCategories(option),
settingsObject.GetType(), tb);
}
}
// optionsControl
Type myType = tb.CreateType();
object optionObject = Activator.CreateInstance(myType);
return optionObject;
}
Control CreateOptionControl()
{
return new PropertyGrid();
}
private TreeNode BuildFullNode(string nodeName)
{
TreeNodeCollection currentNodes = m_tvCategories.Nodes;
string[] categories = nodeName.Split('.');
TreeNode node = null;
foreach (string categoryName in categories)
{
node = FindNode(categoryName, currentNodes);
if (node == null)
{
node = currentNodes.Add(categoryName);
}
currentNodes = node.Nodes;
}
return node;
}
private static string GetCategoryNameFromNode(TreeNode node)
{
StringBuilder builder = new StringBuilder(node.Text);
TreeNode parent = node.Parent;
while(parent != null)
{
builder.Insert(0, '.');
builder.Insert(0, parent.Text);
parent = parent.Parent;
}
return builder.ToString();
}
private static TreeNode FindNode(string name, TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
if (node.Text.Equals(name))
{
return node;
}
}
return null;
}
private void PersistNodes(TreeNodeCollection nodes)
{
ArrayList nodeList = new ArrayList();
foreach(TreeNode node in nodes)
{
nodeList.Add(node);
}
PersistNodes(nodeList);
}
private void PersistNodes(ArrayList nodes)
{
ArrayList subNodes = new ArrayList();
foreach (TreeNode node in nodes)
{
if (node.Tag != null)
{
PropertyGrid grid = node.Tag as PropertyGrid;
if (grid != null)
{
object optionObject = grid.SelectedObject;
if (optionObject != null)
{
SaveOptions(optionObject);
}
}
}
if (node.Nodes != null && node.Nodes.Count > 0)
{
subNodes.AddRange(node.Nodes);
}
}
if (subNodes.Count > 0)
{
PersistNodes(subNodes);
}
}
private void SaveOptions(object optionObject)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(optionObject);
foreach (PropertyDescriptor property in properties)
{
string optionName = property.Name;
object value = property.GetValue(optionObject);
string settingName =
OptionsService.GetSettingsName(optionName);
SettingsCategory category =
OptionsService.GetSettingsCategory(optionName);
SettingsService.SetSettingsObject(settingName, value,
category);
}
}
private ArrayList GetOptionsList(string category)
{
Debug.Assert(m_eCategories != null);
ArrayList filteredOptions = new ArrayList();
foreach (SettingsCategory settingsCategory in m_eCategories)
{
filteredOptions.AddRange(
OptionsService.GetOptions(category, settingsCategory));
}
return filteredOptions;
}
#endregion
}
}