// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Emergent Game Technologies and may not // be copied or disclosed except in accordance with the terms of that // agreement. // // Copyright (c) 1996-2007 Emergent Game Technologies. // All Rights Reserved. // // Emergent Game Technologies, Chapel Hill, North Carolina 27517 // http://www.emergent.net using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; using Emergent.Gamebryo.SceneDesigner.Framework; using Emergent.Gamebryo.SceneDesigner.PluginAPI; using Emergent.Gamebryo.SceneDesigner.PluginAPI.StandardServices; using Emergent.Gamebryo.SceneDesigner.StdPluginsCs.Dialogs; using Emergent.Gamebryo.SceneDesigner.StdPluginsCs.Utility; namespace Emergent.Gamebryo.SceneDesigner.StdPluginsCs.Panels { public class ComponentPanel : Form , ICommandPanel { #region Private Data private IComponentService m_componentService; private IUICommandService m_uiCommandService; private ICommandService m_commandService; MComponent m_selectedComponent; #endregion private System.Windows.Forms.Label m_lblPropertySets; private System.Windows.Forms.ComboBox m_cbPropertySets; private System.Windows.Forms.Label m_lblProperties; private System.Windows.Forms.PropertyGrid m_gridProperties; private System.Windows.Forms.Button m_btnAddProperty; private System.Windows.Forms.Label m_lblDummy; private System.Windows.Forms.Button m_btnCreateNewComponent; private System.Windows.Forms.Button m_btnEditProperty; private System.Windows.Forms.Button m_btnDeleteProperty; private System.ComponentModel.IContainer components = null; public ComponentPanel() { // This call is required by the Windows Form Designer. InitializeComponent(); UICommandService.BindCommands(this); } class ComponentWrapper { public MComponent Component; public override string ToString() { return Component.Name; } } private IComponentService ComponentService { get { if (m_componentService == null) { ServiceProvider sp = ServiceProvider.Instance; m_componentService = sp.GetService(typeof(IComponentService)) as IComponentService; } return m_componentService; } } private IUICommandService UICommandService { get { if (m_uiCommandService == null) { ServiceProvider sp = ServiceProvider.Instance; m_uiCommandService = sp.GetService(typeof(IUICommandService)) as IUICommandService; } return m_uiCommandService; } } private ICommandService CommandService { get { if (m_commandService == null) { ServiceProvider sp = ServiceProvider.Instance; m_commandService = sp.GetService(typeof(ICommandService)) as ICommandService; } return m_commandService; } } private MFramework FW { get { return MFramework.Instance; } } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region 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(ComponentPanel)); this.m_lblPropertySets = new System.Windows.Forms.Label(); this.m_cbPropertySets = new System.Windows.Forms.ComboBox(); this.m_lblProperties = new System.Windows.Forms.Label(); this.m_gridProperties = new System.Windows.Forms.PropertyGrid(); this.m_btnAddProperty = new System.Windows.Forms.Button(); this.m_btnCreateNewComponent = new System.Windows.Forms.Button(); this.m_lblDummy = new System.Windows.Forms.Label(); this.m_btnEditProperty = new System.Windows.Forms.Button(); this.m_btnDeleteProperty = new System.Windows.Forms.Button(); this.SuspendLayout(); // // m_lblPropertySets // this.m_lblPropertySets.AutoSize = true; this.m_lblPropertySets.Location = new System.Drawing.Point(10, 9); this.m_lblPropertySets.Name = "m_lblPropertySets"; this.m_lblPropertySets.Size = new System.Drawing.Size(119, 12); this.m_lblPropertySets.TabIndex = 0; this.m_lblPropertySets.Text = "Selected Component:"; // // m_cbPropertySets // this.m_cbPropertySets.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.m_cbPropertySets.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cbPropertySets.Location = new System.Drawing.Point(10, 34); this.m_cbPropertySets.Name = "m_cbPropertySets"; this.m_cbPropertySets.Size = new System.Drawing.Size(324, 20); this.m_cbPropertySets.Sorted = true; this.m_cbPropertySets.TabIndex = 1; this.m_cbPropertySets.SelectionChangeCommitted += new System.EventHandler(this.m_cbPropertySets_SelectionChangeCommitted); this.m_cbPropertySets.SelectedIndexChanged += new System.EventHandler(this.m_cbPropertySets_SelectedIndexChanged); // // m_lblProperties // this.m_lblProperties.AutoSize = true; this.m_lblProperties.Location = new System.Drawing.Point(10, 69); this.m_lblProperties.Name = "m_lblProperties"; this.m_lblProperties.Size = new System.Drawing.Size(71, 12); this.m_lblProperties.TabIndex = 2; this.m_lblProperties.Text = "Properties:"; // // m_gridProperties // this.m_gridProperties.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_gridProperties.LineColor = System.Drawing.SystemColors.ScrollBar; this.m_gridProperties.Location = new System.Drawing.Point(10, 86); this.m_gridProperties.Name = "m_gridProperties"; this.m_gridProperties.PropertySort = System.Windows.Forms.PropertySort.Alphabetical; this.m_gridProperties.Size = new System.Drawing.Size(324, 223); this.m_gridProperties.TabIndex = 3; this.m_gridProperties.ToolbarVisible = false; // // m_btnAddProperty // this.m_btnAddProperty.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.m_btnAddProperty.FlatStyle = System.Windows.Forms.FlatStyle.System; this.m_btnAddProperty.Location = new System.Drawing.Point(10, 318); this.m_btnAddProperty.Name = "m_btnAddProperty"; this.m_btnAddProperty.Size = new System.Drawing.Size(48, 24); this.m_btnAddProperty.TabIndex = 4; this.m_btnAddProperty.Text = "Add"; this.m_btnAddProperty.Click += new System.EventHandler(this.m_btnAddProperty_Click); // // m_btnCreateNewComponent // this.m_btnCreateNewComponent.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.m_btnCreateNewComponent.FlatStyle = System.Windows.Forms.FlatStyle.System; this.m_btnCreateNewComponent.Location = new System.Drawing.Point(219, 318); this.m_btnCreateNewComponent.Name = "m_btnCreateNewComponent"; this.m_btnCreateNewComponent.Size = new System.Drawing.Size(115, 24); this.m_btnCreateNewComponent.TabIndex = 7; this.m_btnCreateNewComponent.Text = "New Component"; this.m_btnCreateNewComponent.Click += new System.EventHandler(this.m_btnCreateNewComponent_Click); // // m_lblDummy // this.m_lblDummy.Location = new System.Drawing.Point(307, 233); this.m_lblDummy.Name = "m_lblDummy"; this.m_lblDummy.Size = new System.Drawing.Size(10, 8); this.m_lblDummy.TabIndex = 8; // // m_btnEditProperty // this.m_btnEditProperty.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.m_btnEditProperty.FlatStyle = System.Windows.Forms.FlatStyle.System; this.m_btnEditProperty.Location = new System.Drawing.Point(67, 318); this.m_btnEditProperty.Name = "m_btnEditProperty"; this.m_btnEditProperty.Size = new System.Drawing.Size(48, 24); this.m_btnEditProperty.TabIndex = 5; this.m_btnEditProperty.Text = "Edit"; this.m_btnEditProperty.Click += new System.EventHandler(this.m_btnEditProperty_Click); // // m_btnDeleteProperty // this.m_btnDeleteProperty.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.m_btnDeleteProperty.FlatStyle = System.Windows.Forms.FlatStyle.System; this.m_btnDeleteProperty.Location = new System.Drawing.Point(125, 318); this.m_btnDeleteProperty.Name = "m_btnDeleteProperty"; this.m_btnDeleteProperty.Size = new System.Drawing.Size(57, 24); this.m_btnDeleteProperty.TabIndex = 6; this.m_btnDeleteProperty.Text = "Delete"; this.m_btnDeleteProperty.Click += new System.EventHandler(this.m_btnDeleteProperty_Click); // // ComponentPanel // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.AutoScroll = true; this.ClientSize = new System.Drawing.Size(344, 350); this.Controls.Add(this.m_btnDeleteProperty); this.Controls.Add(this.m_btnEditProperty); this.Controls.Add(this.m_btnCreateNewComponent); this.Controls.Add(this.m_btnAddProperty); this.Controls.Add(this.m_gridProperties); this.Controls.Add(this.m_lblProperties); this.Controls.Add(this.m_lblPropertySets); this.Controls.Add(this.m_cbPropertySets); this.Controls.Add(this.m_lblDummy); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "ComponentPanel"; this.Text = "Components"; this.Load += new System.EventHandler(this.ComponentPanel_Load); this.ResumeLayout(false); this.PerformLayout(); } private void m_cbPropertySets_SelectionChangeCommitted(object sender, System.EventArgs e) { } private void m_cbPropertySets_SelectedIndexChanged(object sender, System.EventArgs e) { ComponentWrapper wrapper = m_cbPropertySets.Items[ m_cbPropertySets.SelectedIndex] as ComponentWrapper; m_gridProperties.SelectedObject = wrapper.Component; m_selectedComponent = wrapper.Component; } #endregion #region Winforms Handlers private void m_btnAddProperty_Click(object sender, System.EventArgs e) { AddPropertyDlg pmDialog = new AddPropertyDlg(); if (pmDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { ComponentWrapper pmWrapper = m_cbPropertySets.Items[ m_cbPropertySets.SelectedIndex] as ComponentWrapper; MComponent pmComponent = pmWrapper.Component; bool bCanAdd = ComponentPropertyUtilities.CanAddProperty( pmDialog.NewPropertyName, pmComponent); if (bCanAdd) { CommandService.BeginUndoFrame(string.Format( "Add \"{0}\" property to \"{1}\" component", pmDialog.NewPropertyName, pmComponent.Name)); pmComponent.AddProperty(pmDialog.NewPropertyName, pmDialog.NewPropertyName, pmDialog.NewPropertyType.PrimitiveType, pmDialog.NewPropertyType.Name, pmDialog.Collection, pmDialog.NewPropertyDescription, true); RefreshDropDown(); UpdatePalettesOnAddProperty(pmComponent, pmDialog.NewPropertyName); CommandService.EndUndoFrame(true); } else { MessageBox.Show("The property cannot be added because " + "doing so would\nconflict with existing entities " + "or palettes.", "Error Adding Property", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } private void m_btnEditProperty_Click(object sender, System.EventArgs e) { MEntityPropertyDescriptor pmDescriptor = null; if (m_gridProperties.SelectedGridItem != null) { pmDescriptor = m_gridProperties.SelectedGridItem .PropertyDescriptor as MEntityPropertyDescriptor; } if (pmDescriptor == null) { return; } string strPropertyName = pmDescriptor.PropertyName; PropertyType pmPropertyType = m_selectedComponent.GetPropertyType( strPropertyName); Debug.Assert(pmPropertyType != null, "Property type not found!"); bool bIsCollection = m_selectedComponent.IsCollection( strPropertyName); string strDescription = m_selectedComponent.GetDescription( strPropertyName); AddPropertyDlg pmDialog = new AddPropertyDlg(); pmDialog.NewPropertyName = strPropertyName; pmDialog.NewPropertyType = pmPropertyType; pmDialog.Collection = bIsCollection; pmDialog.NewPropertyDescription = strDescription; pmDialog.Text = "Edit Property"; pmDialog.Undoable = false; if (pmDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { ComponentWrapper pmWrapper = m_cbPropertySets.Items[ m_cbPropertySets.SelectedIndex] as ComponentWrapper; string strComponentName = pmWrapper.ToString(); MComponent pmComponent = pmWrapper.Component; if (!strPropertyName.Equals(pmDialog.NewPropertyName)) { // We are changing the name; check for conflicts. bool bCanAdd = ComponentPropertyUtilities.CanAddProperty( pmDialog.NewPropertyName, pmComponent); bool bCanRemove = ComponentPropertyUtilities .CanRemoveProperty(strPropertyName, pmComponent); if (!bCanRemove) { MessageBox.Show("The property cannot be renamed " + "because existing\nentities or palettes " + "depend on it.", "Error Renaming Property", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (!bCanAdd) { MessageBox.Show("The property cannot be renamed " + "because it would\nconflict with existing " + "entities or palettes", "Error Renaming Property", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } // Begin undo frame. CommandService.BeginUndoFrame(string.Format( "Change \"{0}\" property in \"{1}\" component", pmDialog.NewPropertyName, strComponentName)); // Backup old property values. uint uiOldCount = pmComponent.GetElementCount( strPropertyName); object[] amOldValues = new object[uiOldCount]; for (uint ui = 0; ui < uiOldCount; ui++) { amOldValues[ui] = pmComponent.GetPropertyData( strPropertyName, ui); } // Clear old property values (to support undo). for (uint ui = uiOldCount; ui > 0; ui--) { pmComponent.SetPropertyData(strPropertyName, null, ui - 1, true); } // Remove old property. pmComponent.RemoveProperty(strPropertyName, true); // Add new property. pmComponent.AddProperty(pmDialog.NewPropertyName, pmDialog.NewPropertyName, pmDialog.NewPropertyType.PrimitiveType, pmDialog.NewPropertyType.Name, pmDialog.Collection, pmDialog.NewPropertyDescription, true); // Restore property values. if (pmPropertyType == pmDialog.NewPropertyType) { // Always set value at index 0. pmComponent.SetPropertyData(pmDialog.NewPropertyName, amOldValues[0], 0, true); // Only set remaining values if the new property is a // collection. if (pmDialog.Collection) { for (uint ui = 1; ui < uiOldCount; ui++) { pmComponent.SetPropertyData( pmDialog.NewPropertyName, amOldValues[ui], ui, true); } } } // Propagate changes to palettes. UpdatePalettesOnReplaceProperty(pmComponent, strPropertyName, pmDialog.NewPropertyName); // End undo frame. This command is intentionally not undoable // and will clear the undo stack after being issued. This is // because of too many problems encountered when trying to // undo this operation. CommandService.EndUndoFrame(false); CommandService.ClearUndoAndRedoStacks(); RefreshDropDown(); } } private void m_btnDeleteProperty_Click(object sender, System.EventArgs e) { MEntityPropertyDescriptor pmDescriptor = null; if (m_gridProperties.SelectedGridItem != null) { pmDescriptor = m_gridProperties.SelectedGridItem .PropertyDescriptor as MEntityPropertyDescriptor; } if (pmDescriptor == null) { return; } string strPropertyName = pmDescriptor.PropertyName; ComponentWrapper pmWrapper = m_cbPropertySets.Items[ m_cbPropertySets.SelectedIndex] as ComponentWrapper; bool bCanRemove = ComponentPropertyUtilities.CanRemoveProperty( strPropertyName, pmWrapper.Component); if (bCanRemove) { if (MessageBox.Show("Are you sure you wish to delete the \"" + strPropertyName + "\" property?", "Delete Property Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { CommandService.BeginUndoFrame(string.Format( "Delete \"{0}\" property in \"{1}\" component", strPropertyName, pmWrapper.Component.Name)); pmWrapper.Component.RemoveProperty(strPropertyName, true); UpdatePalettesOnRemoveProperty(pmWrapper.Component, strPropertyName); RefreshDropDown(); CommandService.EndUndoFrame(true); } } else { MessageBox.Show( "The property cannot be removed because existing\n" + "entities or palettes depend on it.", "Error Deleting Property", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void m_btnCreateNewComponent_Click(object sender, System.EventArgs e) { AddNewComponentDlg dlg = new AddNewComponentDlg( ComponentService.GetComponentNames()); if (dlg.ShowDialog() == DialogResult.OK) { MComponent component = MComponent.CreateGeneralComponent( dlg.NewComponentName); ComponentService.RegisterComponent(component); m_selectedComponent = component; RefreshDropDown(); } } private void ComponentPanel_Load(object sender, System.EventArgs e) { RefreshDropDown(); } #endregion #region Helper Methods private void UpdatePalettesOnAddProperty(MComponent component, string propertyName) { MPalette[] palettes = FW.PaletteManager.GetPalettes(); MScene[] affectedScenes = new MScene[] {FW.Scene}; foreach (MPalette palette in palettes) { palette.AddComponentPropertyToEntities(component, propertyName, affectedScenes); } } private void UpdatePalettesOnRemoveProperty(MComponent component, string propertyName) { MPalette[] palettes = FW.PaletteManager.GetPalettes(); MScene[] affectedScenes = new MScene[] {FW.Scene}; foreach (MPalette palette in palettes) { palette.RemoveComponentPropertyFromEntities(component, propertyName, affectedScenes); } } private void UpdatePalettesOnReplaceProperty(MComponent component, string oldPropertyName, string newPropertyName) { MPalette[] palettes = FW.PaletteManager.GetPalettes(); MScene[] affectedScenes = new MScene[] { FW.Scene }; foreach (MPalette palette in palettes) { palette.ReplaceComponentPropertyOnEntities(component, oldPropertyName, newPropertyName, affectedScenes); } } private void RefreshDropDown() { m_cbPropertySets.Items.Clear(); MComponent[] components = ComponentService.GetAllComponents(); foreach (MComponent component in components) { ComponentWrapper wrapper = new ComponentWrapper(); wrapper.Component = component; int index = m_cbPropertySets.Items.Add(wrapper); if (m_selectedComponent != null) { if (component.TemplateID.Equals( m_selectedComponent.TemplateID)) { m_cbPropertySets.SelectedIndex = index; } } } } [UICommandHandler("Idle")] private void OnIdle(object sender, EventArgs args) { bool propertiesCanBeEdited = m_selectedComponent != null && m_selectedComponent.IsAddOrRemovePropertySupported(); bool subItemSelected = m_gridProperties.SelectedGridItem != null && m_gridProperties.SelectedGridItem.Parent != null; m_btnAddProperty.Enabled = propertiesCanBeEdited; m_btnEditProperty.Enabled = propertiesCanBeEdited && subItemSelected; m_btnDeleteProperty.Enabled = propertiesCanBeEdited && subItemSelected; } #endregion #region ICommandPanel Members public void RegisterEventHandlers() { FW.EventManager.ComponentPropertyAdded += new MEventManager.__Delegate_ComponentPropertyAdded( EventManager_ComponentPropertyAdded); FW.EventManager.ComponentPropertyRemoved += new MEventManager.__Delegate_ComponentPropertyRemoved( EventManager_ComponentPropertyRemoved); FW.EventManager.ComponentPropertyChanged += new MEventManager.__Delegate_ComponentPropertyChanged( EventManager_ComponentPropertyChanged); FW.EventManager.ComponentServiceChanged += new MEventManager.__Delegate_ComponentServiceChanged( EventManager_ComponentServiceChanged); FW.EventManager.LongOperationCompleted += new MEventManager.__Delegate_LongOperationCompleted( EventManager_LongOperationCompleted); } #endregion #region Event Handlers private bool m_bRefreshGrid = false; private void RefreshGrid() { if (FW.PerformingLongOperation) { m_bRefreshGrid = true; } else { m_gridProperties.Refresh(); } } private void EventManager_ComponentPropertyAdded( MComponent pmComponent, string strPropertyName, bool bInBatch) { if (pmComponent == m_selectedComponent) { RefreshGrid(); } } private void EventManager_ComponentPropertyRemoved( MComponent pmComponent, string strPropertyName, bool bInBatch) { if (pmComponent == m_selectedComponent) { RefreshGrid(); } } private void EventManager_ComponentPropertyChanged( MComponent pmComponent, string strPropertyName, uint uiPropertyIndex, bool bInBatch) { if (pmComponent == m_selectedComponent) { RefreshGrid(); } } private void EventManager_ComponentServiceChanged( MComponent pmComponent) { if (!this.IsDisposed || !this.Disposing) { RefreshDropDown(); RefreshGrid(); } } private void EventManager_LongOperationCompleted() { if (m_bRefreshGrid) { m_gridProperties.Refresh(); } m_bRefreshGrid = false; } #endregion } }