view FrmArmyTree.cs @ 199:f9ef9b2db496

Re #343: Show unit requirement failures * Add missing translation for dialog * Add first pass of showing messages when adding units (needs reworking due to space limitations)
author IBBoard <dev@ibboard.co.uk>
date Sun, 01 May 2011 19:31:26 +0000
parents 417d3f75a752
children 5233147ca7e4 694f23814ec2
line wrap: on
line source

// This file (FrmArmyTree.cs) is a part of the IBBoard.WarFoundry.GUI.WinForms project and is copyright 2009 IBBoard.
//
// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.

using System;
using System.Drawing;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using IBBoard.Commands;
using IBBoard.Lang;
using IBBoard.Windows.Forms.I18N;
using IBBoard.Windows.Forms;
using IBBoard.WarFoundry.API;
using IBBoard.WarFoundry.API.Commands;
using IBBoard.WarFoundry.API.Objects;

namespace IBBoard.WarFoundry.GUI.WinForms
{
	/// <summary>
	/// Summary description for FrmArmyTree.
	/// </summary>
	public class FrmArmyTree : IBBoard.Windows.Forms.IBBForm
	{
		private System.Windows.Forms.TreeView treeView;
		private IContainer components;
		private Dictionary<string, TreeNode> nodes;
		private System.Windows.Forms.ContextMenu contextMenu;
		private IBBMenuItem miDeleteUnit;
		private IBBMenuItem miEditUnit;
		
		private ObjectAddDelegate UnitAddedMethod;
		private ObjectRemoveDelegate UnitRemovedMethod;
		private StringValChangedDelegate UnitNameChangedMethod, ArmyNameChangedMethod, TreeNameChangedMethod;
		private ToolBar toolBar;
		private IBBToolBarButton bttnEdit;
		private IBBToolBarButton bttnDelete;
		private ImageList imageList;
		private CommandStack commandStack;
        public GameSystem CurrentGameSystem
        {
            get { return WarFoundryCore.CurrentGameSystem; }
            set { WarFoundryCore.CurrentGameSystem = value; }
        }

		public FrmArmyTree(CommandStack cmdStack)
		{
			commandStack = cmdStack;
			InitializeComponent();
			UnitAddedMethod = new ObjectAddDelegate(UnitAdded);
			UnitRemovedMethod = new ObjectRemoveDelegate(UnitRemoved);
			UnitNameChangedMethod = new StringValChangedDelegate(UpdateUnitName);
			ArmyNameChangedMethod = new StringValChangedDelegate(UpdateArmyName);
			TreeNameChangedMethod = new StringValChangedDelegate(FrmArmyTree_TreeNameChanged);
			nodes = new Dictionary<string, TreeNode>();
			this.Name = "ArmyTree";			
			WarFoundryCore.ArmyChanged+= new ArmyChangedDelegate(FrmArmyTree_ArmyChanged);
			TranslateForm();
			Translation.TranslationChanged += new MethodInvoker(TranslateForm);
		}

		private void TranslateForm()
		{
			ControlTranslator.TranslateControl(this);

			foreach (Component comp in components.Components)
			{
				ControlTranslator.TranslateComponent(comp);
			}

			foreach (IBBMenuItem mi in contextMenu.MenuItems)
			{
                ControlTranslator.TranslateComponent(mi);
			}
            foreach (TreeNode node in nodes.Values)
            {
                node.Text = CreateNodeName((ICostedWarFoundryObject)node.Tag);
            }
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
			Translation.TranslationChanged -= new MethodInvoker(TranslateForm);
			WarFoundryCore.ArmyChanged -= new ArmyChangedDelegate(FrmArmyTree_ArmyChanged);
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmArmyTree));
            this.contextMenu = new System.Windows.Forms.ContextMenu();
            this.miEditUnit = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miDeleteUnit = new IBBoard.Windows.Forms.IBBMenuItem();
            this.imageList = new System.Windows.Forms.ImageList(this.components);
            this.toolBar = new System.Windows.Forms.ToolBar();
            this.bttnEdit = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.bttnDelete = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.treeView = new System.Windows.Forms.TreeView();
            this.SuspendLayout();
            // 
            // contextMenu
            // 
            this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.miEditUnit,
            this.miDeleteUnit});
            this.contextMenu.Popup += new System.EventHandler(this.contextMenu_Popup);
            // 
            // miEditUnit
            // 
            this.miEditUnit.Index = 0;
            this.miEditUnit.Text = "&edit unit";
            this.miEditUnit.Click += new System.EventHandler(this.miEdit_Click);
            // 
            // miDeleteUnit
            // 
            this.miDeleteUnit.Index = 1;
            this.miDeleteUnit.Text = "&delete unit";
            this.miDeleteUnit.Click += new System.EventHandler(this.miDelete_Click);
            // 
            // imageList
            // 
            this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream")));
            this.imageList.TransparentColor = System.Drawing.Color.Transparent;
            this.imageList.Images.SetKeyName(0, "gtk-edit.png");
            this.imageList.Images.SetKeyName(1, "edit-delete.png");
            // 
            // toolBar
            // 
            this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
            this.bttnEdit,
            this.bttnDelete});
            this.toolBar.ButtonSize = new System.Drawing.Size(16, 16);
            this.toolBar.DropDownArrows = true;
            this.toolBar.ImageList = this.imageList;
            this.toolBar.Location = new System.Drawing.Point(0, 0);
            this.toolBar.Name = "toolBar";
            this.toolBar.ShowToolTips = true;
            this.toolBar.Size = new System.Drawing.Size(240, 28);
            this.toolBar.TabIndex = 3;
            this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
            // 
            // bttnEdit
            // 
            this.bttnEdit.Enabled = false;
            this.bttnEdit.ImageIndex = 0;
            this.bttnEdit.Name = "bttnEdit";
            // 
            // bttnDelete
            // 
            this.bttnDelete.Enabled = false;
            this.bttnDelete.ImageIndex = 1;
            this.bttnDelete.Name = "bttnDelete";
            // 
            // treeView
            // 
            this.treeView.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.treeView.ContextMenu = this.contextMenu;
            this.treeView.FullRowSelect = true;
            this.treeView.Location = new System.Drawing.Point(0, 28);
            this.treeView.Name = "treeView";
            this.treeView.Size = new System.Drawing.Size(240, 250);
            this.treeView.TabIndex = 0;
            this.treeView.DoubleClick += new System.EventHandler(this.treeView_DoubleClick);
            this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
            this.treeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseDown);
            // 
            // FrmArmyTree
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(240, 277);
            this.ControlBox = false;
            this.Controls.Add(this.toolBar);
            this.Controls.Add(this.treeView);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "FrmArmyTree";
            this.Text = "FrmArmyTree";
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion

		private void ClearArmy()
		{
			nodes.Clear();
			treeView.Nodes.Clear();
		}

		private void SetArmy(Army army)
		{
			ClearArmy();

			if (army != null)
			{
				ArmyCategory[] cats = army.Categories;
				TreeNode[] catNodes = new TreeNode[cats.Length];
				Unit[] units;

				for (int i = 0; i < cats.Length; i++)
				{
					ArmyCategory cat = cats[i];
					units = army.GetUnits(cat);
					cat.NameChanged += TreeNameChangedMethod;
					cat.PointsValueChanged += NodePointsValueChanged;
					TreeNode[] unitNodes = new TreeNode[units.Length];
					TreeNode temp;

					for (int j = 0; j < units.Length; j++)
					{
						unitNodes[j] = CreateTreeNode(units[j]);
					}

					temp = new TreeNode(CreateNodeName(cat), unitNodes);
					temp.Tag = cat;
					catNodes[i] = temp;
					nodes[cat.ID] = temp;
				}

				TreeNode root = new TreeNode(CreateNodeName(army), catNodes);
				root.Tag = army;
				army.PointsValueChanged += NodePointsValueChanged;
				nodes[army.ID] = root;
				treeView.Nodes.Add(root);
				root.ExpandAll();
			}
		}
		
		private string CreateNodeName(ICostedWarFoundryObject obj)
		{
            return Translation.GetTranslation("treeNodeText", "{0} ({1} pts)", obj.Name, obj.Points, CurrentGameSystem.GetPointsAbbrev(obj.Points));
		}

		private void NodePointsValueChanged(WarFoundryObject obj, double oldValue, double newValue)
		{
			if (obj is ICostedWarFoundryObject)
			{
				SetNodeName(obj);
			}
		}

		private void SetNodeName(WarFoundryObject obj)
		{
			TreeNode node = nodes[obj.ID];

			if (node != null)
			{
				node.Text = CreateNodeName((ICostedWarFoundryObject)obj);
			}
		}

		private TreeNode CreateTreeNode(Unit unit)
		{
			TreeNode temp = new TreeNode(CreateNodeName(unit));
			temp.Tag = unit;
			unit.NameChanged+= UnitNameChangedMethod;
			unit.PointsValueChanged += NodePointsValueChanged;
			nodes[unit.ID] = temp;
			return temp;
		}

		public void FrmArmyTree_ArmyChanged(Army oldArmy, Army newArmy)
		{
			if (oldArmy != null)
			{
				oldArmy.UnitAdded -= UnitAddedMethod;
				oldArmy.UnitRemoved -= UnitRemovedMethod;
				oldArmy.PointsValueChanged -= NodePointsValueChanged;
			}

			if (newArmy != null)
			{
				newArmy.UnitAdded += UnitAddedMethod;
				newArmy.UnitRemoved += UnitRemovedMethod;
				newArmy.PointsValueChanged += NodePointsValueChanged;
			}

			SetArmy(newArmy);
		}

		private void UnitAdded(WarFoundryObject obj)
		{
			if (obj is Unit)
			{
				Unit unit = (Unit)obj;
				ArmyCategory cat = unit.Category;
				TreeNode parent = nodes[cat.ID];
				TreeNode unitNode = CreateTreeNode(unit);
				parent.Nodes.Add(unitNode);
				parent.Expand(); //make sure it's expanded
			}
		}

		public new FrmMain MdiParent
		{
			get { return (FrmMain) base.MdiParent; }
			set { base.MdiParent = value; }
		}

		private void UnitRemoved(WarFoundryObject obj)
		{
			if (obj is Unit)
			{
				Unit unit = (Unit)obj;
				RemoveUnitFromTree(unit);
			}
		}

		private void RemoveUnitFromTree(Unit unit)
		{
			TreeNode unitNode = nodes[unit.ID];
			unit.NameChanged-= UnitNameChangedMethod;

			if (unitNode!=null)
			{
				unitNode.Remove();
				nodes.Remove(unit.ID);
			}
		}


		private void contextMenu_Popup(object sender, System.EventArgs e)
		{
			TreeNode node = treeView.SelectedNode;

			if (node!=null && node.Tag is Unit)
			{
				foreach(MenuItem item in contextMenu.MenuItems)
				{
					item.Visible = true;
				}
			}
			else
			{
				foreach(MenuItem item in contextMenu.MenuItems)
				{
					item.Visible = false;
				}
			}
		}

		private void treeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
			{
				TreeNode tn = treeView.GetNodeAt(e.X, e.Y);

				if (tn!=null)
				{
					treeView.SelectedNode = tn;
				}
				else
				{
					treeView.SelectedNode = null;
				}
			}
		}

		private void miDelete_Click(object sender, System.EventArgs e)
		{
			DeleteUnit();
		}

		private void DeleteUnit()
		{

			TreeNode selected = treeView.SelectedNode;

			if (selected.Tag != null && selected.Tag is Unit)
			{
				Unit unit = (Unit) selected.Tag;
				commandStack.Execute(new RemoveUnitCommand(unit));
			}
		}

		private void miEdit_Click(object sender, System.EventArgs e)
		{	
			EditUnit();
		}

		private void treeView_DoubleClick(object sender, System.EventArgs e)
		{
			EditUnit();			
		}

		private void EditUnit()
		{
			TreeNode selected = treeView.SelectedNode;
			object tagData = selected.Tag;

			if (tagData is Unit)
			{
				Unit unit = (Unit) tagData;
				MdiParent.OpenUnitDialog(unit);
			}
		}

		private void UpdateUnitName(WarFoundryObject obj, string oldValue, string newValue)
		{
			if (obj is ICostedWarFoundryObject)
			{
				SetNodeName(obj);
			}
		}

		private void UpdateArmyName(WarFoundryObject obj, string oldValue, string newValue)
		{
			if (obj is Army)
			{
				Army army = (Army)obj;
				TreeNode node = treeView.Nodes[0];
				
				if (node!=null)
				{
					node.Text = army.Name;
				}
			}
		}

		private void FrmArmyTree_TreeNameChanged(WarFoundryObject obj, string oldValue, string newValue)
		{
			TreeNode node = nodes[obj.ID];

			if (node!=null)
			{
				node.Text = obj.Name;
			}
		}

		private void toolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
		{
			if (e.Button == bttnDelete)
			{
				DeleteUnit();
			}
			else if (e.Button == bttnEdit)
			{
				EditUnit();
			}
		}

		private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
		{
			TreeNode node = treeView.SelectedNode;

			bttnDelete.Enabled = (node != null && node.Tag is Unit);
			bttnEdit.Enabled = bttnDelete.Enabled;
		}
	}
}