using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Xml.Schema;
using System.ComponentModel;
using System.Windows.Forms;
using Emergent.Gamebryo.SceneDesigner.Framework;
using Emergent.Gamebryo.SceneDesigner.PluginAPI;
using Emergent.Gamebryo.SceneDesigner.PluginAPI.StandardServices;
using Emergent.Gamebryo.SceneDesigner.StdPluginsCs.Editors;
using Emergent.Gamebryo.SceneDesigner.StdPluginsCs.Panels;
using Emergent.Gamebryo.SceneDesigner.StdPluginsCs.Services;
using Emergent.Gamebryo.SceneDesigner.StdPluginsCs.TypeConverters;
using Emergent.Gamebryo.SceneDesigner.StdPluginsCs.UIBinding;
namespace Emergent.Gamebryo.SceneDesigner.StdPluginsCs
{
///
/// Summary description for Plugin.
///
public class Plugin : IPlugin
{
#region Private Data
private static readonly string m_menuFileExtension = "menu.xml";
private static readonly string m_toolbarFileExtension = "toolbar.xml";
private static readonly string m_commandFileExtension = "commands.xml";
private static readonly string m_shortcutFileExtension
= "shortcuts.xml";
private static readonly string m_optionsBindingFileExtension
= "optbind.xml";
private static readonly string ms_strPathSettingName =
"External Application Path";
private static readonly string ms_strCommandLineSettingName =
"External Application Command Line";
#endregion
public Plugin()
{
}
public string Name
{
get { throw new NotImplementedException(); }
}
public Version Version
{
get
{ return Assembly.GetExecutingAssembly().GetName().Version; }
}
public Version ExpectedVersion
{
get
{ return new Version(1, 0); }
}
///
/// Called when a Plugin is loaded
///
///
///
public void Load(int toolMajorVersion, int toolMinorVersion)
{
}
///
/// Provides a mechanism to allow packages to report services
///
/// A list of service objects that this package provides
public IService[] GetProvidedServices()
{
IService[] retVal =
new IService[] {new UICommandServiceImpl(),
new OptionsServiceImpl(),
new EntityPathServiceImpl()};
UICommandUtility.Init();
return retVal;
}
///
/// Provides a mechanism for a plugin to interact with services.
///
public void Start()
{
ServiceProvider serviceProvider =
ServiceProvider.Instance;
LoadPanels();
string searchFolderRoot = MFramework.Instance.AppStartupPath;
string[] folders = BuildSubfolderList(searchFolderRoot);
BuildItems(serviceProvider,
new DynamicMenuBuilder(serviceProvider),
BuildFileList(folders, m_menuFileExtension),
BuildSchemaPath(m_menuFileExtension));
BuildItems(serviceProvider,
new DynamicToolbarBuilder(serviceProvider),
BuildFileList(folders, m_toolbarFileExtension),
BuildSchemaPath(m_toolbarFileExtension));
BuildItems(serviceProvider,
new DynamicShortcutBuilder(serviceProvider),
BuildFileList(folders, m_shortcutFileExtension),
BuildSchemaPath(m_shortcutFileExtension));
CommandBindingBuilder bindingBuilder =
new CommandBindingBuilder(serviceProvider);
BuildItems(serviceProvider, bindingBuilder,
BuildFileList(folders, m_commandFileExtension),
null);
BuildItems(serviceProvider, new OptionsBindingsBuilder(),
BuildFileList(folders, m_optionsBindingFileExtension),
BuildSchemaPath(m_optionsBindingFileExtension));
bindingBuilder.BuildFromLoadedAssemblies();
RegisterPropertyTypes();
RegisterExternalApplicationSettings();
}
private void LoadPanels()
{
ServiceProvider serviceProvider =
ServiceProvider.Instance;
ICommandPanelService panelService =
serviceProvider.GetService(typeof(ICommandPanelService))
as ICommandPanelService;
IMessageService messageService =
serviceProvider.GetService(typeof(IMessageService))
as IMessageService;
IUICommandService commandService =
serviceProvider.GetService(typeof(IUICommandService))
as IUICommandService;
panelService.RegisterPanel(new MessagesPanel(commandService,
messageService));
panelService.RegisterPanel(new UndoPanel());
panelService.RegisterPanel(new ComponentPanel());
panelService.RegisterPanel(new EntityTemplatePanel());
panelService.RegisterPanel(new PalettePanel());
panelService.RegisterPanel(new TerrainEditPanel());
panelService.RegisterPanel(new SceneEntityStatisticPanel());
}
private void RegisterPropertyTypes()
{
IPropertyTypeService pmPropertyTypeService =
ServiceProvider.Instance.GetService(
typeof(IPropertyTypeService)) as IPropertyTypeService;
Debug.Assert(pmPropertyTypeService != null, "Property type " +
"service not found!");
pmPropertyTypeService.RegisterType(new PropertyType(
"Color (RGBA)", "Color (RGBA)", typeof(Color), null,
typeof(ColorAConverter)));
pmPropertyTypeService.RegisterType(new PropertyType(
"Entity Pointer", "Entity Pointer", typeof(MEntity),
typeof(EntityPointerEditor), null,
typeof(EntityCollectionEditor)));
}
private void RegisterExternalApplicationSettings()
{
ISettingsService pmSettingsService = ServiceProvider.Instance
.GetService(typeof(ISettingsService)) as ISettingsService;
string strDefaultPath = ConstructSceneAppPath();
pmSettingsService.RegisterSettingsObject(ms_strPathSettingName,
new MFileLocation(strDefaultPath), SettingsCategory.PerUser);
pmSettingsService.RegisterSettingsObject(
ms_strCommandLineSettingName, string.Empty,
SettingsCategory.PerUser);
}
private static string ConstructSceneAppPath()
{
string strSceneAppPath = Application.ExecutablePath;
int iIndex = strSceneAppPath.LastIndexOf('\\');
for (int iCount = 0; iIndex > -1 && iCount < 6; iCount++)
{
strSceneAppPath = strSceneAppPath.Substring(0, iIndex);
iIndex = strSceneAppPath.LastIndexOf('\\');
}
strSceneAppPath += "\\Samples\\FullDemos\\SceneApp\\Win32\\" +
#if VC71
"VC71"
#elif VC80
"VC80"
#endif
+ "\\SceneApp.exe";
return strSceneAppPath;
}
#region UI Command Binding Helpers
private void BuildItems(ServiceProvider provider,
AbstractBuilder builder, FileInfo[] files, string schemaPath
)
{
IMessageService messageService =
provider.GetService(typeof(IMessageService))
as IMessageService;
XmlSchema schema = null;
if (schemaPath != null)
{
try
{
using (FileStream schemaStream = new FileStream(schemaPath,
FileMode.Open, FileAccess.Read))
{
schema = XmlSchema.Read(schemaStream, null);
}
}
catch (FileNotFoundException)
{
messageService.AddMessage(MessageChannelType.General,
string.Format("Schema '{0}' not found",
schemaPath));
}
}
builder.Schema = schema;
foreach(FileInfo file in files)
{
try
{
using (Stream stream =
new FileStream(file.FullName,
FileMode.Open, FileAccess.Read))
{
builder.Build(stream);
}
}
catch (Exception e)
{
PluginAPI.Message message = new PluginAPI.Message();
message.m_strText = "Could not load file: " +
Environment.NewLine + file.FullName;
message.m_strDetails = e.ToString();
messageService.AddMessage(MessageChannelType.Errors,
message);
}
}
}
private string[] BuildSubfolderList(string rootPath)
{
ArrayList directoryNames = new ArrayList();
DirectoryInfo rootInfo = new DirectoryInfo(rootPath);
directoryNames.Add(rootInfo.FullName);
DirectoryInfo[] subFolders = rootInfo.GetDirectories();
foreach (DirectoryInfo di in subFolders)
{
directoryNames.AddRange(BuildSubfolderList(di.FullName));
}
return (string[]) directoryNames.ToArray(typeof(string));
}
private FileInfo[] BuildFileList(string[] folders, string extension)
{
ArrayList fileInfoList = new ArrayList();
foreach (string folder in folders)
{
DirectoryInfo di = new DirectoryInfo(folder);
FileInfo[] files = di.GetFiles("*." + extension);
fileInfoList.AddRange(files);
}
return (FileInfo[]) fileInfoList.ToArray(typeof(FileInfo));
}
private string BuildSchemaPath(string extension)
{
return MFramework.Instance.AppStartupPath +
@"data\" + extension.Replace("xml", "xsd");
}
#endregion
#region UI Command Handlers
[UICommandHandler("CreateCameraFromViewport")]
private static void OnCreateCameraFromViewport(object sender,
EventArgs args)
{
// Take the current viewport camera and clone it
MEntity currentCamera = MFramework.Instance.ViewportManager
.ActiveViewport.CameraEntity;
// Create unique name for the new camera.
string cloneName = currentCamera.Name;
// Search for last space character in proposed name.
int iIndex = currentCamera.Name.LastIndexOf(' ');
if (iIndex == currentCamera.Name.Length - 1)
{
iIndex = currentCamera.Name.LastIndexOf(' ', iIndex - 1);
}
if (iIndex > -1)
{
string strSuffix = currentCamera.Name.Substring(iIndex + 1);
try
{
int iSuffix = Int32.Parse(strSuffix);
cloneName = currentCamera.Name.Substring(0, iIndex);
}
catch (FormatException)
{
// The suffix is not an integer; set the base name to the
// proposed name.
cloneName = currentCamera.Name;
}
}
cloneName = cloneName + " 01";
cloneName = MFramework.Instance.Scene.GetUniqueEntityName(
cloneName);
MEntity clonedCamera = currentCamera.Clone(cloneName, false);
// Add it to the scene
MFramework.Instance.Scene.AddEntity(clonedCamera, true);
// Select the current camera, de-selecting any current selections
ISelectionService selectionService =
ServiceProvider.Instance.GetService(typeof(ISelectionService))
as ISelectionService;
selectionService.ClearSelectedEntities();
selectionService.AddEntityToSelection(clonedCamera);
// Set the viewport to use the newly cloned camera
MFramework.Instance.ViewportManager.ActiveViewport.SetCamera(
clonedCamera, false);
}
[UICommandHandler("LaunchExternalApplication")]
private static void OnLanchExternalApplication(object sender,
EventArgs args)
{
ISettingsService settingService =
ServiceProvider.Instance.GetService(typeof(ISettingsService))
as ISettingsService;
MFileLocation pmFileLocation = (MFileLocation)
settingService.GetSettingsObject(ms_strPathSettingName,
SettingsCategory.PerUser);
string strSceneAppPath = ConstructSceneAppPath();
string strAppPath = string.Empty;
if (pmFileLocation != null)
{
strAppPath = pmFileLocation.Path;
}
if (strAppPath.Equals(string.Empty))
{
strAppPath = strSceneAppPath;
}
string strCommandLine = (string) settingService.GetSettingsObject(
ms_strCommandLineSettingName, SettingsCategory.PerUser);
if (strCommandLine == null)
{
strCommandLine = string.Empty;
}
string strPath = Path.GetTempPath() + "Temp.gsa";
if (!MFramework.Instance.SaveScene(strPath, "GSA"))
{
MessageBox.Show("Cannot save temporary scene file to the " +
"following location:\n\n" + strPath + "\n\nUnable to " +
"launch external application.", "Cannot Save Temporary " +
"Scene File", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string strFilename = "\"" + strPath + "\"";
string strFullCommandLine = " " +
strFilename + " " + strCommandLine;
bool bLaunched = false;
while (!bLaunched)
{
try
{
Process myProcess = new Process();
myProcess.StartInfo.Arguments = strFullCommandLine;
myProcess.StartInfo.FileName = "\"" + strAppPath + "\"";
bLaunched = myProcess.Start();
}
catch (System.Exception)
{
}
if (!bLaunched)
{
if (strAppPath.Equals(strSceneAppPath))
{
MessageBox.Show("Cannot launch SceneApp from its " +
"default path at:\n\n" + strSceneAppPath +
"\n\nPlease check the path and try again.",
"External Application Launch Failure",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (MessageBox.Show("Cannot launch external " +
"application from the following location:\n\n" +
strAppPath + "\n\nwith the following command-line " +
"parameters:\n\n" + strFullCommandLine + "\n\nWould " +
"you like to reset your external application path " +
"to the default and try again?",
"External Application Launch Failure",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
DialogResult.Yes)
{
// Reset app path to default to try again.
strAppPath = strSceneAppPath;
// Reset external application path setting to default.
settingService.SetSettingsObject(ms_strPathSettingName,
new MFileLocation(string.Empty),
SettingsCategory.PerUser);
}
else
{
break;
}
}
}
}
#endregion
[DllInit]
private static void Init()
{
}
[DllShutdown]
private static void Shutdown()
{
}
}
}