to do

to do

--- Source/ComponentInspector/PropertiesInspector.cs
+++ Source/ComponentInspector/PropertiesInspector.cs
@@ -10,764 +10,790 @@
 namespace Inspector
 {

-	public partial class PropertiesInspector : UserControl
-	{
-
-		#region Private internal var./properties
-
-		// Properties
-		private int mFirstColumnWidth = 100;
-		private int mItemHeight = 24;
-		private BaseItem mItemSelected = null;
-		private BaseItem PreviousItemSelected = null;
-		private Color mTextForeColor = Color.White;
-		private CategoryCollection m_CategoryList = null;
-		private ItemCollection m_ItemList = null;
-		private bool resizeCursorOnScreen = false;
-		private bool controlChangeEventLocked = true;
-
-		#endregion
-
-		#region Control constructor/destructor
-
-		public PropertiesInspector()
-		{
-			m_CategoryList = new CategoryCollection();
-			m_ItemList = new ItemCollection();
-
-			InitializeComponent();
-		}
-
-		~PropertiesInspector()
-		{
-			ItemsClear();
-			m_CategoryList = null;
-			m_ItemList = null;
-		}
-
-		#endregion
-
-		#region Public properties
-
-		public BaseItem this[string itemKey]
-		{
-			get
-			{
-				if (m_ItemList.Contains(itemKey))
-					return m_ItemList[itemKey];
-				else
-					return null;
-			}
-		}
-
-		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
-		Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
-		Bindable(false)]
-		public override string Text
-		{
-			get
-			{
-				return base.Text;
-			}
-			set
-			{
-				base.Text = value;
-			}
-		}
-
-		public int ColumnWidth
-		{
-			get
-			{
-				return mFirstColumnWidth;
-			}
-			set
-			{
-				mFirstColumnWidth = value;
-				if (mFirstColumnWidth < 40) mFirstColumnWidth = 40;
-				if (mFirstColumnWidth > this.Width) mFirstColumnWidth = this.Width;
-			}
-		}
-
-		public int RowsHeight
-		{
-			get
-			{
-				return mItemHeight;
-			}
-			set
-			{
-				if (value < 19)
-					mItemHeight = 19;
-				else
-					mItemHeight = (value < 64) ? mItemHeight = value :
-												 mItemHeight = 64;
-			}
-		}
-
-		public BaseItem SelectedItem
-		{
-			get
-			{
-				return mItemSelected;
-			}
-			set
-			{
-				mItemSelected = value;
-			}
-		}
-
-
-		public int ItemsCount
-		{
-			get
-			{
-				return m_ItemList.Count;
-			}
-		}
-
-		public bool ItemExist(string itemKey)
-		{
-			// Add BaseItem to category list and BaseItem list
-			return m_ItemList.Contains(itemKey);
-		}
-
-
-		public int CategoryCount
-		{
-			get
-			{
-				return m_CategoryList.Count;
-			}
-		}
-
-		#endregion
-
-		#region Private internal functions
-
-		private string NowTimeString()
-		{
-			return System.DateTime.Now.ToLongTimeString() + ":" + DateTime.Now.Millisecond.ToString("000") + ") ";
-		}
-
-		private void PaintItem(BaseItem item, int x1, int x2, ref int y1, ref int y2)
-		{
-			System.Drawing.Font propFont = null;
-			if (!item.Visible) return;
-
-			item.Rect = new Rectangle(mFirstColumnWidth, y1, this.Width - mFirstColumnWidth, y2 - y1);
-			//             if (item == mItemSelected)
-			//                 g.FillRectangle(brush, x1 + 14, y1, mFirstColumnWidth - 14, mItemHeight);
-			//             g.DrawLine(pen, x1, y2, x2, y2);
-			// Property title (text)
-
-			propFont = item.Changed ? new Font(this.Font, FontStyle.Bold) :
-									  new Font(this.Font, FontStyle.Regular);
-			//             {
-			//                 if (item.Enabled)
-			//                     g.DrawString(item.ValueString, propFont, txtBrush, (float)mFirstColumnWidth, (float)y1 + 2);
-			//                 else
-			//                     g.DrawString(item.ValueString, propFont, txtDisabledBrush, (float)mFirstColumnWidth, (float)y1 + 2);
-			//             }
-			Panel panelItem = new Panel();
-			panelItem.BackColor = Color.White;
-			panelItem.Dock = DockStyle.None;
-			panelItem.Location = new Point(0, y1);
-			panelItem.Name = "panel" + item.Name;
-			panelItem.Size = new Size(this.Width, mItemHeight);
-			this.panelProperties.Controls.Add(panelItem);
-
-			if (item is StringItem)
-			{
-				Label labelItem = new Label();
-				labelItem.AutoSize = true;
-				labelItem.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
-				labelItem.ForeColor = Color.Black;
-				labelItem.Location = new Point(24, 3);
-				labelItem.Name = "label" + item.Name;
-				labelItem.Text = item.Name;
-
-				TextBox textItem = new TextBox();
-				textItem.Location = new Point(100, 1);
-				textItem.Size = new Size(this.Width - 100, mItemHeight - 2);
-				textItem.Name = "text" + item.Name;
-				textItem.Text = item.ValueString;
-				textItem.ReadOnly = item.Enabled;
-
-				panelItem.Controls.Add(labelItem);
-				panelItem.Controls.Add(textItem);
-			}
-
-			y1 = y2;
-			y2 += mItemHeight;
-		}
-
-		private void PaintAsCategory(int x1, int x2, int y1, ref int y2)
-		{
-			CategoryItem category = null;
-			BaseItem item = null;
-			int k, j;
-
-			for (k = 0; k < m_CategoryList.Count; k++)
-			{
-				category = m_CategoryList[k];
-
-				Button btnExpand = new Button();
-				btnExpand.Image = this.imageListExpand.Images[0];
-				btnExpand.ImageAlign = ContentAlignment.MiddleCenter;
-				btnExpand.Name = "button" + category.Name + "Expand";
-				btnExpand.Text = "";
-				btnExpand.Location = new Point(2, 2);
-				btnExpand.Size = new Size(20, 20);
-				if (category.Expanded)
-					btnExpand.Image = this.imageListExpand.Images[1];
-				else
-					btnExpand.Image = this.imageListExpand.Images[0];
-
-				Label labelCategory = new Label();
-				labelCategory.AutoSize = true;
-				labelCategory.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
-				labelCategory.ForeColor = Color.Black;
-				labelCategory.Location = new Point(24, 3);
-				labelCategory.Name = "label" + category.Name;
-				labelCategory.AutoSize = true;
-				labelCategory.Text = category.Name;
-
-				Panel panelCategory = new Panel();
-				panelCategory.BackColor = Color.FromArgb(240, 240, 240);
-				panelCategory.Dock = DockStyle.None;
-				panelCategory.Location = new Point(0, y1);
-				panelCategory.Name = "panel" + category.Name;
-				panelCategory.Size = new Size(this.Width, mItemHeight);
-				panelCategory.Controls.Add(btnExpand);
-				panelCategory.Controls.Add(labelCategory);
-
-				this.panelProperties.Controls.Add(panelCategory);
-
-				category.Rect = new Rectangle(2, y1 + 2, 20, 20);
-
-				y1 = y2;
-				y2 += mItemHeight;
-
-				if (category.Expanded)
-				{
-					for (j = 0; j < category.ItemList.Count; j++)
-					{
-						item = category.ItemList[j];
-						PaintItem(item, x1, x2, ref y1, ref y2);
-					}
-				}
-			}
-		}
-
-		private void RefreshCursor(int xMouse)
-		{
-			int x1;
-			int x2;
-
-			x1 = xMouse - 3;
-			x2 = xMouse + 3;
-			resizeCursorOnScreen = (mFirstColumnWidth >= x1 && mFirstColumnWidth <= x2);
-			if (resizeCursorOnScreen)
-			{
-				if (this.Cursor != Cursors.VSplit)
-				{
-					UpdateControl();
-					this.Cursor = Cursors.VSplit;
-				}
-			}
-			else
-				this.Cursor = Cursors.Default;
-		}
-
-		private void VerifyMouseUpOnCategory(MouseEventArgs e)
-		{
-			//             Rectangle rect;
-			//             CategoryItem category;
-			//             BaseItem item;
-			//             int k, j;
-			//             int itemWidth;
-			//
-			//             for (k = 0; k < m_CategoryList.Count; k++)
-			//             {
-			//                 category = m_CategoryList[k];
-			//                 rect = category.Rect;
-			//                 // - Category
-			//                 if (e.X >= rect.X && e.X <= (rect.X + rect.Width) && e.Y >= rect.Y && e.Y <= (rect.Y + rect.Height))
-			//                 {
-			//                     // Expand/Collapse category
-			//                     category.Expanded = !category.Expanded;
-			//                     PaintControl();
-			//                     return;     // Exit
-			//                 }
-			//                 // - Property BaseItem (search for active selected item)
-			//                 if (category.Expanded)
-			//                     for (j = 0; j < category.ItemList.Count; j++)
-			//                     {
-			//                         item = category.ItemList[j];
-			//                         rect = item.Rect;
-			//                         if (e.Y >= rect.Y && e.Y <= (rect.Y + rect.Height))
-			//                         {
-			//                             PreviousItemSelected = mItemSelected;
-			//                             mItemSelected = item;
-			//                             RefreshHelp(item);
-			//                             PaintControl();
-			//                             // Show input box (if BaseItem is enabled)
-			//                             if (pnlProp.VerticalScroll.Visible)
-			//                                 itemWidth = rect.Width - 20;
-			//                             else
-			//                                 itemWidth = rect.Width;
-			//                             if (itemWidth < 8) itemWidth = 8;
-			//                             if (item.Enabled)
-			//                                 ShowInputControl(rect.X, rect.Y, itemWidth, mItemHeight, item);
-			//                             return;     // Exit
-			//                         }
-			//                     }
-			//             }
-		}
-
-		private void VerifyMouseUpOnItemList(MouseEventArgs e)
-		{
-			//             Rectangle rect;
-			//             int j;
-			//
-			//             for (j = 0; j < m_ItemList.Count; j++)
-			//             {
-			//                 rect = m_ItemList[j].Rect;
-			//                 if (e.Y >= rect.Y && e.Y <= (rect.Y + rect.Height))
-			//                 {
-			//                     PreviousItemSelected = mItemSelected;
-			//                     mItemSelected = m_ItemList[j];
-			//                     RefreshHelp(m_ItemList[j]);
-			//                     PaintControl();
-			//                     // Show input box (if BaseItem is enabled)
-			//                     if (m_ItemList[j].Enabled)
-			//                         ShowInputControl(rect.X, rect.Y, rect.Width, mItemHeight, m_ItemList[j]);
-			//                     return;     // Exit
-			//                 }
-			//             }
-		}
-
-		private void MoreButtonIsPressed()
-		{
-			//             DialogResult diagRet;
-			//             ColorItem colItem = null;
-			//             ImageItem imgItem = null;
-			//             FileItem fileItem = null;
-			//             StringItem StringItem = null;
-			//             string oldValue = "";
-			//
-			//             if (!btnMore.Visible) return;
-			//             btnMore.Enabled = false;
-			//             if (mItemSelected is ColorItem)
-			//             {
-			//                 colItem = (ColorItem)mItemSelected;
-			//                 colDiag.Color = colItem.Value;
-			//                 diagRet = colDiag.ShowDialog();
-			//                 if (diagRet == DialogResult.OK)
-			//                 {
-			//                     colItem.Value = colDiag.Color;
-			//                     PaintControl();
-			//                 }
-			//                 btnMore.Enabled = true;
-			//                 return;
-			//             }
-			//             if (mItemSelected is ImageItem)
-			//             {
-			//                 imgItem = (ImageItem)mItemSelected;
-			//                 fileDiag.FileName = imgItem.FileName;
-			//                 fileDiag.Filter = "All pictures (*.bmp;*.png;*.jpg;*.tiff;*.gif)|*.bmp;*.png;*.jpg;*.tiff;*.gif|All files (*.*)|*.*";
-			//                 fileDiag.FilterIndex = 1;
-			//                 diagRet = fileDiag.ShowDialog();
-			//                 if (diagRet == DialogResult.OK)
-			//                 {
-			//                     imgItem.FileName = fileDiag.FileName;
-			//                     PaintControl();
-			//                 }
-			//                 btnMore.Enabled = true;
-			//                 return;
-			//             }
-			//             if (mItemSelected is FileItem)
-			//             {
-			//                 fileItem = (FileItem)mItemSelected;
-			//                 fileDiag.FileName = fileItem.Value;
-			//                 fileDiag.Filter = fileItem.Filter;
-			//                 fileDiag.FilterIndex = fileItem.FilterIndex;
-			//                 diagRet = fileDiag.ShowDialog();
-			//                 if (diagRet == DialogResult.OK)
-			//                 {
-			//                     fileItem.Value = fileDiag.FileName;
-			//                     PaintControl();
-			//                 }
-			//                 btnMore.Enabled = true;
-			//                 return;
-			//             }
-			//             if (mItemSelected is StringItem)
-			//             {
-			//                 // The more button is visible when the property
-			//                 // .ShowExpandButton is true. Use this button to run
-			//                 // a user defined action like to open a dialog box.
-			//                 // (The event ExpandButtonPressed will be raised;
-			//                 //  add your action into this event)
-			//                 StringItem = (StringItem)mItemSelected;
-			//                 oldValue = StringItem.Value;
-			//                 RaiseExpandButtonPressed(StringItem);
-			//                 btnMore.Enabled = true;
-			//                 if (oldValue != StringItem.Value)
-			//                     // Execute control refresh if the user chage a property value
-			//                     RefreshControl(true);
-			//                 return;
-			//             }
-			//             // Exit
-			//             btnMore.Enabled = true;
-		}
-
-		/// <summary>
-		/// Validate text
-		/// </summary>
-		private void txtBox_ValidateText(BaseItem item)
-		{
-			// Validate data!
-			//             Int32Item int32Item = null;
-			//             FloatItem dblItem = null;
-			//
-			//             if (item == null) return;
-			//             if (item is Int32Item)
-			//             {
-			//                 int32Item = (Int32Item)item;
-			//                 int32Item.ValueString = txtBox.Text;
-			//                 return;
-			//             }
-			//             if (item is FloatItem)
-			//             {
-			//                 dblItem = (FloatItem)item;
-			//                 dblItem.ValueString = txtBox.Text;
-			//                 if (dblItem.ValidationRangeCheck == ValidationRangeCheckType.Manual)
-			//                 {
-			//                     if (dblItem.Value < dblItem.Minimum || dblItem.Value > dblItem.Maximum)
-			//                         System.Media.SystemSounds.Hand.Play();
-			//                 }
-			//                 return;
-			//             }
-		}
-
-		#endregion
-
-		#region Public methods
-
-		public void UpdateControl()
-		{
-			panelProperties.Controls.Clear();
-
-			int x1 = 0;
-			int x2 = this.Width;
-			if (x2 < 32) x2 = 32;
-			int y1 = 0;
-			int y2 = y1 + mItemHeight;
-
-			foreach (var category in m_CategoryList)
-			{
-				Button btnExpand = new Button();
-				btnExpand.Image = this.imageListExpand.Images[0];
-				btnExpand.ImageAlign = ContentAlignment.MiddleCenter;
-				btnExpand.Name = "button" + category.Name + "Expand";
-				btnExpand.Text = "";
-				btnExpand.Location = new Point(2, 2);
-				btnExpand.Size = new Size(20, 20);
-				if (category.Expanded)
-					btnExpand.Image = this.imageListExpand.Images[1];
-				else
-					btnExpand.Image = this.imageListExpand.Images[0];
-
-				Label labelCategory = new Label();
-				labelCategory.AutoSize = true;
-				labelCategory.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
-				labelCategory.ForeColor = Color.Black;
-				labelCategory.Location = new Point(24, 3);
-				labelCategory.Name = "label" + category.Name;
-				labelCategory.AutoSize = true;
-				labelCategory.Text = category.Name;
-
-				Panel panelCategory = new Panel();
-				panelCategory.BackColor = Color.FromArgb(240, 240, 240);
-				panelCategory.Dock = DockStyle.None;
-				panelCategory.Location = new Point(0, y1);
-				panelCategory.Name = "panel" + category.Name;
-				panelCategory.Size = new Size(this.Width, mItemHeight);
-				panelCategory.Controls.Add(btnExpand);
-				panelCategory.Controls.Add(labelCategory);
-
-				this.panelProperties.Controls.Add(panelCategory);
-
-				category.Rect = new Rectangle(2, y1 + 2, 20, 20);
-
-				y1 = y2;
-				y2 += mItemHeight;
-
-				if (category.Expanded)
-				{
-					foreach (var item in category.ItemList)
-					{
-						PaintItem(item, x1, x2, ref y1, ref y2);
-					}
-				}
-			}
-		}
-
-		public void ResetChanges()
-		{
-			int t;
-
-			if (m_ItemList == null) return;
-			for (t = 0; t < m_ItemList.Count; t++)
-				m_ItemList[t].Changed = false;
-			UpdateControl();
-		}
-
-		public void ItemsClear()
-		{
-			if (m_CategoryList != null)
-			{
-				for (int i = 0; i < m_CategoryList.Count; i++)
-				{
-					if (m_CategoryList[i].ItemList != null)
-					{
-						m_CategoryList[i].ItemList.Clear();
-						m_CategoryList[i].ItemList = null;
-					}
-				}
-				m_CategoryList.Clear();
-			}
-
-			if (m_ItemList != null)
-				m_ItemList.Clear();
-			UpdateControl();
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, StringItem strItem)
-		{
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, strItem);
-				m_ItemList.Add(itemKey, strItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = strItem;
-			}
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, Int32Item intItem)
-		{
-			// Add BaseItem to category list and BaseItem list
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, intItem);
-				m_ItemList.Add(itemKey, intItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = intItem;
-			}
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, DropDownItem cmbItem)
-		{
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, cmbItem);
-				m_ItemList.Add(itemKey, cmbItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = cmbItem;
-			}
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, BooleanItem boolItem)
-		{
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, boolItem);
-				m_ItemList.Add(itemKey, boolItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = boolItem;
-			}
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, FloatItem dblItem)
-		{
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, dblItem);
-				m_ItemList.Add(itemKey, dblItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = dblItem;
-			}
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, ColorItem colItem)
-		{
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, colItem);
-				m_ItemList.Add(itemKey, colItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = colItem;
-			}
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, ImageItem imgItem)
-		{
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, imgItem);
-				m_ItemList.Add(itemKey, imgItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = imgItem;
-			}
-		}
-
-		public void ItemAdd(string categoryKey, string itemKey, FileItem fileItem)
-		{
-			if (m_CategoryList.Contains(categoryKey))
-			{
-				m_CategoryList[categoryKey].ItemList.Add(itemKey, fileItem);
-				m_ItemList.Add(itemKey, fileItem);
-				if (this.SelectedItem == null)
-					this.SelectedItem = fileItem;
-			}
-		}
-
-
-		//TODO:Add any new BaseItem management here... (ItemAdd() function)
-
-
-		public void CategoryAdd(string categoryKey, CategoryItem catItem)
-		{
-			m_CategoryList.Add(categoryKey, catItem);
-		}
-
-		public string GetItemValue(string itemKey)
-		{
-			if (m_ItemList.Contains(itemKey))
-				return m_ItemList[itemKey].ValueString;
-			else
-				return null;
-		}
-
-		public double GetPropertyItemDoubleValue(string itemKey)
-		{
-			FloatItem dblItem = null;
-
-			if (m_ItemList.Contains(itemKey) && m_ItemList[itemKey] is FloatItem)
-			{
-				dblItem = (FloatItem)m_ItemList[itemKey];
-				return dblItem.Value;
-			}
-			else
-				return 0.0;
-		}
-
-		public void SetItemValue(string itemKey, string value)
-		{
-
-			if (m_ItemList.Contains(itemKey) && (m_ItemList[itemKey] is StringItem ||
-				m_ItemList[itemKey] is DropDownItem))
-				m_ItemList[itemKey].ValueString = value;
-		}
-
-		public void SetItemValue(string itemKey, double value)
-		{
-			string format;
-
-			if (m_ItemList.Contains(itemKey) && m_ItemList[itemKey] is FloatItem)
-			{
-				format = m_ItemList[itemKey].Format;
-				m_ItemList[itemKey].ValueString = value.ToString(format);
-			}
-		}
-
-		public void SetItemValue(string itemKey, int value)
-		{
-			if (m_ItemList.Contains(itemKey) && m_ItemList[itemKey] is Int32Item)
-				m_ItemList[itemKey].ValueString = value.ToString();
-		}
-
-		public string GetItemText(string itemKey)
-		{
-			if (m_ItemList.Contains(itemKey))
-				return m_ItemList[itemKey].Name;
-			else
-				return null;
-		}
-
-		public BaseItem GetItem(string itemKey)
-		{
-			if (m_ItemList.Contains(itemKey))
-				return m_ItemList[itemKey];
-			else
-				return null;
-		}
-
-		public CategoryItem GetCategory(string key)
-		{
-			if (m_CategoryList.Contains(key))
-				return m_CategoryList[key];
-			else
-				return null;
-		}
-
-		public void SetCategoryText(string key, string text)
-		{
-			if (m_CategoryList.Contains(key))
-				m_CategoryList[key].Name = text;
-		}
-
-		#endregion
-
-		#region Public events
-
-		public delegate void ExpandButtonPressedHandle(object sender, StringItem item);
-
-		public event ExpandButtonPressedHandle ExpandButtonPressed;
-
-		private void RaiseExpandButtonPressed(StringItem item)
-		{
-			if (ExpandButtonPressed != null)
-				ExpandButtonPressed(this, item);
-		}
-
-		public delegate void ApplyButtonPressedHandle(object sender, ref bool cancel);
-
-		public event ApplyButtonPressedHandle ApplyButtonPressed;
-
-		private void RaiseApplyButtonPressed()
-		{
-			bool cancel = false;
-
-			if (ApplyButtonPressed != null)
-			{
-				// Raise event
-				ApplyButtonPressed(this, ref cancel);
-				if (!cancel)
-					ResetChanges();
-			}
-		}
-
-		#endregion
-
-		#region Private internal events generated by user interface
-
-		private void txtBox_TextChanged(object sender, EventArgs e)
-		{
-			StringItem strItem = null;
-			//Int32Item int32Item = null;
-			//FloatItem dblItem = null;
-
-			if (controlChangeEventLocked) return;
-			if (mItemSelected == null) return;
-			if (mItemSelected is StringItem)
-			{
-				strItem = (StringItem)mItemSelected;
-				//                 strItem.Value = txtBox.Text;
-				return;
-			}
-			/*
+    public partial class PropertiesInspector : UserControl
+    {
+
+        #region Private internal var./properties
+
+        // Properties
+        private int mFirstColumnWidth = 100;
+        private int mItemHeight = 24;
+        private BaseItem mItemSelected = null;
+        private BaseItem PreviousItemSelected = null;
+        private Color mTextForeColor = Color.White;
+        private CategoryCollection m_CategoryList = null;
+        private ItemCollection m_ItemList = null;
+        private bool resizeCursorOnScreen = false;
+        private bool controlChangeEventLocked = true;
+
+        #endregion
+
+        #region Control constructor/destructor
+
+        public PropertiesInspector()
+        {
+            m_CategoryList = new CategoryCollection();
+            m_ItemList = new ItemCollection();
+
+            InitializeComponent();
+        }
+
+        ~PropertiesInspector()
+        {
+            ItemsClear();
+            m_CategoryList = null;
+            m_ItemList = null;
+        }
+
+        #endregion
+
+        #region Public properties
+
+        public BaseItem this[string itemKey]
+        {
+            get
+            {
+                if (m_ItemList.Contains(itemKey))
+                    return m_ItemList[itemKey];
+                else
+                    return null;
+            }
+        }
+
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
+        Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
+        Bindable(false)]
+        public override string Text
+        {
+            get
+            {
+                return base.Text;
+            }
+            set
+            {
+                base.Text = value;
+            }
+        }
+
+        public int ColumnWidth
+        {
+            get
+            {
+                return mFirstColumnWidth;
+            }
+            set
+            {
+                mFirstColumnWidth = value;
+                if (mFirstColumnWidth < 40) mFirstColumnWidth = 40;
+                if (mFirstColumnWidth > this.Width) mFirstColumnWidth = this.Width;
+            }
+        }
+
+        public int RowsHeight
+        {
+            get
+            {
+                return mItemHeight;
+            }
+            set
+            {
+                if (value < 19)
+                    mItemHeight = 19;
+                else
+                    mItemHeight = (value < 64) ? mItemHeight = value :
+                                                 mItemHeight = 64;
+            }
+        }
+
+        public BaseItem SelectedItem
+        {
+            get
+            {
+                return mItemSelected;
+            }
+            set
+            {
+                mItemSelected = value;
+            }
+        }
+
+
+        public int ItemsCount
+        {
+            get
+            {
+                return m_ItemList.Count;
+            }
+        }
+
+        public bool ItemExist(string itemKey)
+        {
+            // Add BaseItem to category list and BaseItem list
+            return m_ItemList.Contains(itemKey);
+        }
+
+
+        public int CategoryCount
+        {
+            get
+            {
+                return m_CategoryList.Count;
+            }
+        }
+
+        #endregion
+
+        #region Private internal functions
+
+        private string NowTimeString()
+        {
+            return System.DateTime.Now.ToLongTimeString() + ":" + DateTime.Now.Millisecond.ToString("000") + ") ";
+        }
+
+        private void AddStringItemControl(BaseItem item, Panel panelItem)
+        {
+            Label labelItem = new Label();
+            labelItem.AutoSize = true;
+            labelItem.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
+            labelItem.ForeColor = Color.Black;
+            labelItem.Location = new Point(24, 3);
+            labelItem.Name = "label" + item.Name;
+            labelItem.Text = item.Name;
+
+            TextBox textItem = new TextBox();
+            textItem.Location = new Point(100, 1);
+            textItem.Size = new Size(this.Width - 100, mItemHeight - 2);
+            textItem.Name = "text" + item.Name;
+            textItem.Text = item.ValueString;
+            textItem.ReadOnly = item.Enabled;
+
+            panelItem.Controls.Add(labelItem);
+            panelItem.Controls.Add(textItem);
+        }
+
+        private void AddVector3ItemControl(BaseItem item, Panel panelItem)
+        {
+            Label labelItem = new Label();
+            labelItem.AutoSize = true;
+            labelItem.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
+            labelItem.ForeColor = Color.Black;
+            labelItem.Location = new Point(24, 3);
+            labelItem.Name = "label" + item.Name;
+            labelItem.Text = item.Name;
+
+            string[] elements = item.ValueString.Split(',');
+            if (elements.Length != 3)
+                return;
+
+            const int labelWidth = 16;
+            int textWidth = (this.Width - 100 - labelWidth * 3 - 2) / 3;
+            int x1 = 100;
+
+            Label labelX = new Label();
+            labelX.AutoSize = true;
+            labelX.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
+            labelX.ForeColor = Color.Black;
+            labelX.Location = new Point(x1, 3);
+            labelX.Name = "label" + item.Name + "X";
+            labelX.Text = "X";
+
+            x1 += labelWidth;
+            TextBox textX = new TextBox();
+            textX.Location = new Point(x1, 1);
+            textX.Size = new Size(textWidth, mItemHeight - 2);
+            textX.Name = "text" + item.Name + "X";
+            textX.Text = elements[0];
+            textX.ReadOnly = item.Enabled;
+
+            x1 += textWidth;
+            Label labelY = new Label();
+            labelY.AutoSize = true;
+            labelY.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
+            labelY.ForeColor = Color.Black;
+            labelY.Location = new Point(x1 + 1, 3);
+            labelY.Name = "label" + item.Name + "Y";
+            labelY.Text = "Y";
+
+            x1 += labelWidth;
+            TextBox textY = new TextBox();
+            textY.Location = new Point(x1, 1);
+            textY.Size = new Size(textWidth, mItemHeight - 2);
+            textY.Name = "text" + item.Name + "Y";
+            textY.Text = elements[1];
+            textY.ReadOnly = item.Enabled;
+
+            x1 += textWidth;
+            Label labelZ = new Label();
+            labelZ.AutoSize = true;
+            labelZ.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
+            labelZ.ForeColor = Color.Black;
+            labelZ.Location = new Point(x1 + 1, 3);
+            labelZ.Name = "label" + item.Name + "Z";
+            labelZ.Text = "Z";
+
+            x1 += labelWidth;
+            TextBox textZ = new TextBox();
+            textZ.Location = new Point(x1, 1);
+            textZ.Size = new Size(textWidth, mItemHeight - 2);
+            textZ.Name = "text" + item.Name + "Z";
+            textZ.Text = elements[2];
+            textZ.ReadOnly = item.Enabled;
+
+            panelItem.Controls.Add(labelItem);
+            panelItem.Controls.Add(labelX);
+            panelItem.Controls.Add(textX);
+            panelItem.Controls.Add(labelY);
+            panelItem.Controls.Add(textY);
+            panelItem.Controls.Add(labelZ);
+            panelItem.Controls.Add(textZ);
+        }
+
+        private void PaintItem(BaseItem item, int x1, int x2, ref int y1, ref int y2)
+        {
+            System.Drawing.Font propFont = null;
+            if (!item.Visible) return;
+
+            item.Rect = new Rectangle(mFirstColumnWidth, y1, this.Width - mFirstColumnWidth, y2 - y1);
+
+            propFont = item.Changed ? new Font(this.Font, FontStyle.Bold) :
+                                      new Font(this.Font, FontStyle.Regular);
+            Panel panelItem = new Panel();
+            panelItem.BackColor = Color.White;
+            panelItem.Dock = DockStyle.None;
+            panelItem.Location = new Point(0, y1);
+            panelItem.Name = "panel" + item.Name;
+            panelItem.Size = new Size(this.Width, mItemHeight);
+            this.panelProperties.Controls.Add(panelItem);
+
+            if (item is StringItem)
+            {
+                AddStringItemControl(item, panelItem);
+            }
+            else if (item is Vector3Item)
+            {
+                AddVector3ItemControl(item, panelItem);
+            }
+
+            y1 = y2;
+            y2 += mItemHeight;
+        }
+
+        private void RefreshCursor(int xMouse)
+        {
+            int x1;
+            int x2;
+
+            x1 = xMouse - 3;
+            x2 = xMouse + 3;
+            resizeCursorOnScreen = (mFirstColumnWidth >= x1 && mFirstColumnWidth <= x2);
+            if (resizeCursorOnScreen)
+            {
+                if (this.Cursor != Cursors.VSplit)
+                {
+                    UpdateControl();
+                    this.Cursor = Cursors.VSplit;
+                }
+            }
+            else
+                this.Cursor = Cursors.Default;
+        }
+
+        private void VerifyMouseUpOnCategory(MouseEventArgs e)
+        {
+            //             Rectangle rect;
+            //             CategoryItem category;
+            //             BaseItem item;
+            //             int k, j;
+            //             int itemWidth;
+            //
+            //             for (k = 0; k < m_CategoryList.Count; k++)
+            //             {
+            //                 category = m_CategoryList[k];
+            //                 rect = category.Rect;
+            //                 // - Category
+            //                 if (e.X >= rect.X && e.X <= (rect.X + rect.Width) && e.Y >= rect.Y && e.Y <= (rect.Y + rect.Height))
+            //                 {
+            //                     // Expand/Collapse category
+            //                     category.Expanded = !category.Expanded;
+            //                     PaintControl();
+            //                     return;     // Exit
+            //                 }
+            //                 // - Property BaseItem (search for active selected item)
+            //                 if (category.Expanded)
+            //                     for (j = 0; j < category.ItemList.Count; j++)
+            //                     {
+            //                         item = category.ItemList[j];
+            //                         rect = item.Rect;
+            //                         if (e.Y >= rect.Y && e.Y <= (rect.Y + rect.Height))
+            //                         {
+            //                             PreviousItemSelected = mItemSelected;
+            //                             mItemSelected = item;
+            //                             RefreshHelp(item);
+            //                             PaintControl();
+            //                             // Show input box (if BaseItem is enabled)
+            //                             if (pnlProp.VerticalScroll.Visible)
+            //                                 itemWidth = rect.Width - 20;
+            //                             else
+            //                                 itemWidth = rect.Width;
+            //                             if (itemWidth < 8) itemWidth = 8;
+            //                             if (item.Enabled)
+            //                                 ShowInputControl(rect.X, rect.Y, itemWidth, mItemHeight, item);
+            //                             return;     // Exit
+            //                         }
+            //                     }
+            //             }
+        }
+
+        private void VerifyMouseUpOnItemList(MouseEventArgs e)
+        {
+            //             Rectangle rect;
+            //             int j;
+            //
+            //             for (j = 0; j < m_ItemList.Count; j++)
+            //             {
+            //                 rect = m_ItemList[j].Rect;
+            //                 if (e.Y >= rect.Y && e.Y <= (rect.Y + rect.Height))
+            //                 {
+            //                     PreviousItemSelected = mItemSelected;
+            //                     mItemSelected = m_ItemList[j];
+            //                     RefreshHelp(m_ItemList[j]);
+            //                     PaintControl();
+            //                     // Show input box (if BaseItem is enabled)
+            //                     if (m_ItemList[j].Enabled)
+            //                         ShowInputControl(rect.X, rect.Y, rect.Width, mItemHeight, m_ItemList[j]);
+            //                     return;     // Exit
+            //                 }
+            //             }
+        }
+
+        private void MoreButtonIsPressed()
+        {
+            //             DialogResult diagRet;
+            //             ColorItem colItem = null;
+            //             ImageItem imgItem = null;
+            //             FileItem fileItem = null;
+            //             StringItem StringItem = null;
+            //             string oldValue = "";
+            //
+            //             if (!btnMore.Visible) return;
+            //             btnMore.Enabled = false;
+            //             if (mItemSelected is ColorItem)
+            //             {
+            //                 colItem = (ColorItem)mItemSelected;
+            //                 colDiag.Color = colItem.Value;
+            //                 diagRet = colDiag.ShowDialog();
+            //                 if (diagRet == DialogResult.OK)
+            //                 {
+            //                     colItem.Value = colDiag.Color;
+            //                     PaintControl();
+            //                 }
+            //                 btnMore.Enabled = true;
+            //                 return;
+            //             }
+            //             if (mItemSelected is ImageItem)
+            //             {
+            //                 imgItem = (ImageItem)mItemSelected;
+            //                 fileDiag.FileName = imgItem.FileName;
+            //                 fileDiag.Filter = "All pictures (*.bmp;*.png;*.jpg;*.tiff;*.gif)|*.bmp;*.png;*.jpg;*.tiff;*.gif|All files (*.*)|*.*";
+            //                 fileDiag.FilterIndex = 1;
+            //                 diagRet = fileDiag.ShowDialog();
+            //                 if (diagRet == DialogResult.OK)
+            //                 {
+            //                     imgItem.FileName = fileDiag.FileName;
+            //                     PaintControl();
+            //                 }
+            //                 btnMore.Enabled = true;
+            //                 return;
+            //             }
+            //             if (mItemSelected is FileItem)
+            //             {
+            //                 fileItem = (FileItem)mItemSelected;
+            //                 fileDiag.FileName = fileItem.Value;
+            //                 fileDiag.Filter = fileItem.Filter;
+            //                 fileDiag.FilterIndex = fileItem.FilterIndex;
+            //                 diagRet = fileDiag.ShowDialog();
+            //                 if (diagRet == DialogResult.OK)
+            //                 {
+            //                     fileItem.Value = fileDiag.FileName;
+            //                     PaintControl();
+            //                 }
+            //                 btnMore.Enabled = true;
+            //                 return;
+            //             }
+            //             if (mItemSelected is StringItem)
+            //             {
+            //                 // The more button is visible when the property
+            //                 // .ShowExpandButton is true. Use this button to run
+            //                 // a user defined action like to open a dialog box.
+            //                 // (The event ExpandButtonPressed will be raised;
+            //                 //  add your action into this event)
+            //                 StringItem = (StringItem)mItemSelected;
+            //                 oldValue = StringItem.Value;
+            //                 RaiseExpandButtonPressed(StringItem);
+            //                 btnMore.Enabled = true;
+            //                 if (oldValue != StringItem.Value)
+            //                     // Execute control refresh if the user chage a property value
+            //                     RefreshControl(true);
+            //                 return;
+            //             }
+            //             // Exit
+            //             btnMore.Enabled = true;
+        }
+
+        /// <summary>
+        /// Validate text
+        /// </summary>
+        private void txtBox_ValidateText(BaseItem item)
+        {
+            // Validate data!
+            //             Int32Item int32Item = null;
+            //             FloatItem dblItem = null;
+            //
+            //             if (item == null) return;
+            //             if (item is Int32Item)
+            //             {
+            //                 int32Item = (Int32Item)item;
+            //                 int32Item.ValueString = txtBox.Text;
+            //                 return;
+            //             }
+            //             if (item is FloatItem)
+            //             {
+            //                 dblItem = (FloatItem)item;
+            //                 dblItem.ValueString = txtBox.Text;
+            //                 if (dblItem.ValidationRangeCheck == ValidationRangeCheckType.Manual)
+            //                 {
+            //                     if (dblItem.Value < dblItem.Minimum || dblItem.Value > dblItem.Maximum)
+            //                         System.Media.SystemSounds.Hand.Play();
+            //                 }
+            //                 return;
+            //             }
+        }
+
+        #endregion
+
+        #region Public methods
+
+        public void UpdateControl()
+        {
+            panelProperties.Controls.Clear();
+
+            int x1 = 0;
+            int x2 = this.Width;
+            if (x2 < 32) x2 = 32;
+            int y1 = 0;
+            int y2 = y1 + mItemHeight;
+
+            foreach (var category in m_CategoryList)
+            {
+                Button btnExpand = new Button();
+                btnExpand.Image = this.imageListExpand.Images[0];
+                btnExpand.ImageAlign = ContentAlignment.MiddleCenter;
+                btnExpand.Name = "button" + category.Name + "Expand";
+                btnExpand.Text = "";
+                btnExpand.Location = new Point(2, 2);
+                btnExpand.Size = new Size(20, 20);
+                if (category.Expanded)
+                    btnExpand.Image = this.imageListExpand.Images[1];
+                else
+                    btnExpand.Image = this.imageListExpand.Images[0];
+
+                Label labelCategory = new Label();
+                labelCategory.AutoSize = true;
+                labelCategory.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
+                labelCategory.ForeColor = Color.Black;
+                labelCategory.Location = new Point(24, 3);
+                labelCategory.Name = "label" + category.Name;
+                labelCategory.AutoSize = true;
+                labelCategory.Text = category.Name;
+
+                Panel panelCategory = new Panel();
+                panelCategory.BackColor = Color.FromArgb(240, 240, 240);
+                panelCategory.Dock = DockStyle.None;
+                panelCategory.Location = new Point(0, y1);
+                panelCategory.Name = "panel" + category.Name;
+                panelCategory.Size = new Size(this.Width, mItemHeight);
+                panelCategory.Controls.Add(btnExpand);
+                panelCategory.Controls.Add(labelCategory);
+
+                this.panelProperties.Controls.Add(panelCategory);
+
+                category.Rect = new Rectangle(2, y1 + 2, 20, 20);
+
+                y1 = y2;
+                y2 += mItemHeight;
+
+                if (category.Expanded)
+                {
+                    foreach (var item in category.ItemList)
+                    {
+                        PaintItem(item, x1, x2, ref y1, ref y2);
+                    }
+                }
+            }
+        }
+
+        public void ResetChanges()
+        {
+            int t;
+
+            if (m_ItemList == null) return;
+            for (t = 0; t < m_ItemList.Count; t++)
+                m_ItemList[t].Changed = false;
+            UpdateControl();
+        }
+
+        public void ItemsClear()
+        {
+            if (m_CategoryList != null)
+            {
+                for (int i = 0; i < m_CategoryList.Count; i++)
+                {
+                    if (m_CategoryList[i].ItemList != null)
+                    {
+                        m_CategoryList[i].ItemList.Clear();
+                        m_CategoryList[i].ItemList = null;
+                    }
+                }
+                m_CategoryList.Clear();
+            }
+
+            if (m_ItemList != null)
+                m_ItemList.Clear();
+            UpdateControl();
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, StringItem strItem)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, strItem);
+                m_ItemList.Add(itemKey, strItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = strItem;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, Int32Item intItem)
+        {
+            // Add BaseItem to category list and BaseItem list
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, intItem);
+                m_ItemList.Add(itemKey, intItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = intItem;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, DropDownItem cmbItem)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, cmbItem);
+                m_ItemList.Add(itemKey, cmbItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = cmbItem;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, BooleanItem boolItem)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, boolItem);
+                m_ItemList.Add(itemKey, boolItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = boolItem;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, FloatItem dblItem)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, dblItem);
+                m_ItemList.Add(itemKey, dblItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = dblItem;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, Vector3Item vector3Item)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, vector3Item);
+                m_ItemList.Add(itemKey, vector3Item);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = vector3Item;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, ColorItem colItem)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, colItem);
+                m_ItemList.Add(itemKey, colItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = colItem;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, ImageItem imgItem)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, imgItem);
+                m_ItemList.Add(itemKey, imgItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = imgItem;
+            }
+        }
+
+        public void ItemAdd(string categoryKey, string itemKey, FileItem fileItem)
+        {
+            if (m_CategoryList.Contains(categoryKey))
+            {
+                m_CategoryList[categoryKey].ItemList.Add(itemKey, fileItem);
+                m_ItemList.Add(itemKey, fileItem);
+                if (this.SelectedItem == null)
+                    this.SelectedItem = fileItem;
+            }
+        }
+
+
+        //TODO:Add any new BaseItem management here... (ItemAdd() function)
+
+
+        public void CategoryAdd(string categoryKey, CategoryItem catItem)
+        {
+            m_CategoryList.Add(categoryKey, catItem);
+        }
+
+        public string GetItemValue(string itemKey)
+        {
+            if (m_ItemList.Contains(itemKey))
+                return m_ItemList[itemKey].ValueString;
+            else
+                return null;
+        }
+
+        public double GetPropertyItemDoubleValue(string itemKey)
+        {
+            FloatItem dblItem = null;
+
+            if (m_ItemList.Contains(itemKey) && m_ItemList[itemKey] is FloatItem)
+            {
+                dblItem = (FloatItem)m_ItemList[itemKey];
+                return dblItem.Value;
+            }
+            else
+                return 0.0;
+        }
+
+        public void SetItemValue(string itemKey, string value)
+        {
+
+            if (m_ItemList.Contains(itemKey) && (m_ItemList[itemKey] is StringItem ||
+                m_ItemList[itemKey] is DropDownItem))
+                m_ItemList[itemKey].ValueString = value;
+        }
+
+        public void SetItemValue(string itemKey, double value)
+        {
+            if (m_ItemList.Contains(itemKey) && m_ItemList[itemKey] is FloatItem)
+            {
+                m_ItemList[itemKey].ValueString = value.ToString();
+            }
+        }
+
+        public void SetItemValue(string itemKey, int value)
+        {
+            if (m_ItemList.Contains(itemKey) && m_ItemList[itemKey] is Int32Item)
+                m_ItemList[itemKey].ValueString = value.ToString();
+        }
+
+        public string GetItemText(string itemKey)
+        {
+            if (m_ItemList.Contains(itemKey))
+                return m_ItemList[itemKey].Name;
+            else
+                return null;
+        }
+
+        public BaseItem GetItem(string itemKey)
+        {
+            if (m_ItemList.Contains(itemKey))
+                return m_ItemList[itemKey];
+            else
+                return null;
+        }
+
+        public CategoryItem GetCategory(string key)
+        {
+            if (m_CategoryList.Contains(key))
+                return m_CategoryList[key];
+            else
+                return null;
+        }
+
+        public void SetCategoryText(string key, string text)
+        {
+            if (m_CategoryList.Contains(key))
+                m_CategoryList[key].Name = text;
+        }
+
+        #endregion
+
+        #region Public events
+
+        public delegate void ExpandButtonPressedHandle(object sender, StringItem item);
+
+        public event ExpandButtonPressedHandle ExpandButtonPressed;
+
+        private void RaiseExpandButtonPressed(StringItem item)
+        {
+            if (ExpandButtonPressed != null)
+                ExpandButtonPressed(this, item);
+        }
+
+        public delegate void ApplyButtonPressedHandle(object sender, ref bool cancel);
+
+        public event ApplyButtonPressedHandle ApplyButtonPressed;
+
+        private void RaiseApplyButtonPressed()
+        {
+            bool cancel = false;
+
+            if (ApplyButtonPressed != null)
+            {
+                // Raise event
+                ApplyButtonPressed(this, ref cancel);
+                if (!cancel)
+                    ResetChanges();
+            }
+        }
+
+        #endregion
+
+        #region Private internal events generated by user interface
+
+        private void txtBox_TextChanged(object sender, EventArgs e)
+        {
+            StringItem strItem = null;
+            //Int32Item int32Item = null;
+            //FloatItem dblItem = null;
+
+            if (controlChangeEventLocked) return;
+            if (mItemSelected == null) return;
+            if (mItemSelected is StringItem)
+            {
+                strItem = (StringItem)mItemSelected;
+                //                 strItem.Value = txtBox.Text;
+                return;
+            }
+            /*
 			if (mItemSelected is Int32Item)
 			{
 				int32Item = (Int32Item)mItemSelected;
@@ -781,105 +807,105 @@
 				return;
 			}
 			*/
-		}
-
-		private void cmbBox_TextChanged(object sender, EventArgs e)
-		{
-			DropDownItem listItem = null;
-
-			if (controlChangeEventLocked) return;
-			if (mItemSelected == null) return;
-			if (mItemSelected is DropDownItem)
-			{
-				listItem = (DropDownItem)mItemSelected;
-				//                 listItem.Value = cmbBox.Text;
-			}
-		}
-
-		private void cmbBox_SelectedIndexChanged(object sender, EventArgs e)
-		{
-			DropDownItem listItem = null;
-
-			if (controlChangeEventLocked) return;
-			if (mItemSelected == null) return;
-			if (mItemSelected is DropDownItem)
-			{
-				listItem = (DropDownItem)mItemSelected;
-				//                 listItem.Value = cmbBox.Text;
-			}
-		}
-
-		private void btnMore_Click(object sender, EventArgs e)
-		{
-			MoreButtonIsPressed();
-		}
-
-		private void txtBox_KeyPress(object sender, KeyPressEventArgs e)
-		{
-			//             if (e.KeyChar == (Char)13)
-			//             {
-			//                 txtBox_ValidateText(mItemSelected);
-			//                 HideInputControls(true);
-			//             }
-		}
-
-		private void cmbBox_KeyPress(object sender, KeyPressEventArgs e)
-		{
-			//             if (e.KeyChar == (Char)13)
-			//                 HideInputControls();
-		}
-
-		private void picProp_MouseUp(object sender, MouseEventArgs e)
-		{
-			if (e.Button == MouseButtons.Left && !resizeCursorOnScreen)
-			{
-				VerifyMouseUpOnCategory(e);
-			}
-			else
-			{
-				controlChangeEventLocked = true;
-			}
-		}
-
-		private void picProp_MouseMove(object sender, MouseEventArgs e)
-		{
-			if (e.Button == MouseButtons.Left && resizeCursorOnScreen)
-			{
-				if (mFirstColumnWidth != e.X)
-				{
-					mFirstColumnWidth = e.X;
-					UpdateControl();
-				}
-			}
-			else
-				RefreshCursor(e.X);
-		}
-
-		private void txtBox_DoubleClick(object sender, EventArgs e)
-		{
-			MoreButtonIsPressed();
-		}
-
-		private void picProp_DoubleClick(object sender, EventArgs e)
-		{
-			MoreButtonIsPressed();
-		}
-
-		private void txtBox_Leave(object sender, EventArgs e)
-		{
-			txtBox_ValidateText(PreviousItemSelected);
-		}
-
-		private void btnApply_Click(object sender, EventArgs e)
-		{
-			RaiseApplyButtonPressed();
-		}
-
-		#endregion
-
-		private void PropertiesInspector_SizeChanged(object sender, EventArgs e)
-		{
-			UpdateControl();
-		}
-	}
+        }
+
+        private void cmbBox_TextChanged(object sender, EventArgs e)
+        {
+            DropDownItem listItem = null;
+
+            if (controlChangeEventLocked) return;
+            if (mItemSelected == null) return;
+            if (mItemSelected is DropDownItem)
+            {
+                listItem = (DropDownItem)mItemSelected;
+                //                 listItem.Value = cmbBox.Text;
+            }
+        }
+
+        private void cmbBox_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            DropDownItem listItem = null;
+
+            if (controlChangeEventLocked) return;
+            if (mItemSelected == null) return;
+            if (mItemSelected is DropDownItem)
+            {
+                listItem = (DropDownItem)mItemSelected;
+                //                 listItem.Value = cmbBox.Text;
+            }
+        }
+
+        private void btnMore_Click(object sender, EventArgs e)
+        {
+            MoreButtonIsPressed();
+        }
+
+        private void txtBox_KeyPress(object sender, KeyPressEventArgs e)
+        {
+            //             if (e.KeyChar == (Char)13)
+            //             {
+            //                 txtBox_ValidateText(mItemSelected);
+            //                 HideInputControls(true);
+            //             }
+        }
+
+        private void cmbBox_KeyPress(object sender, KeyPressEventArgs e)
+        {
+            //             if (e.KeyChar == (Char)13)
+            //                 HideInputControls();
+        }
+
+        private void picProp_MouseUp(object sender, MouseEventArgs e)
+        {
+            if (e.Button == MouseButtons.Left && !resizeCursorOnScreen)
+            {
+                VerifyMouseUpOnCategory(e);
+            }
+            else
+            {
+                controlChangeEventLocked = true;
+            }
+        }
+
+        private void picProp_MouseMove(object sender, MouseEventArgs e)
+        {
+            if (e.Button == MouseButtons.Left && resizeCursorOnScreen)
+            {
+                if (mFirstColumnWidth != e.X)
+                {
+                    mFirstColumnWidth = e.X;
+                    UpdateControl();
+                }
+            }
+            else
+                RefreshCursor(e.X);
+        }
+
+        private void txtBox_DoubleClick(object sender, EventArgs e)
+        {
+            MoreButtonIsPressed();
+        }
+
+        private void picProp_DoubleClick(object sender, EventArgs e)
+        {
+            MoreButtonIsPressed();
+        }
+
+        private void txtBox_Leave(object sender, EventArgs e)
+        {
+            txtBox_ValidateText(PreviousItemSelected);
+        }
+
+        private void btnApply_Click(object sender, EventArgs e)
+        {
+            RaiseApplyButtonPressed();
+        }
+
+        #endregion
+
+        private void PropertiesInspector_SizeChanged(object sender, EventArgs e)
+        {
+            UpdateControl();
+        }
+    }
 }


Spacing.

Spacing.

--- src/SparkPost/DataMapper.cs
+++ src/SparkPost/DataMapper.cs
@@ -93,7 +93,6 @@

         private object BuildTheRecipientRequestFrom(Transmission transmission)
         {
-
             return transmission.ListId != null
                 ? (object)new Dictionary<string, object> { ["list_id"] = transmission.ListId }
                 : transmission.Recipients.Select(ToDictionary);


Android: Use dynamic layout for simple app

--- Source/Eto.Test/Eto.Test.Android/MainActivity.cs
+++ Source/Eto.Test/Eto.Test.Android/MainActivity.cs
@@ -12,17 +12,21 @@
 	[Activity(Label = "Eto.Test.Android", MainLauncher = true)]
 	public class MainActivity : Activity
 	{
-
 		public class SimpleApplication : Forms.Application
 		{
 			public SimpleApplication(Generator generator = null)
 				: base(generator)
 			{
 			}
+
 			public override void OnInitialized(EventArgs e)
 			{
 				base.OnInitialized(e);
-				MainForm = new Form { Content = new Label { Text = "Hello world", VerticalAlign = VerticalAlign.Middle, HorizontalAlign = HorizontalAlign.Center } };
+				var layout = new DynamicLayout();
+				layout.Add(new Label { Text = "Hello world", VerticalAlign = VerticalAlign.Middle, HorizontalAlign = HorizontalAlign.Center });
+				layout.Add(new Label { Text = "Hello world2", VerticalAlign = VerticalAlign.Middle, HorizontalAlign = HorizontalAlign.Center });
+
+				MainForm = new Form { Content = layout };
 				MainForm.Show();
 			}
 		}
@@ -34,18 +38,6 @@
 			var generator = new Eto.Platform.Android.Generator();
 			//new TestApplication(generator).Attach(this);
 			new SimpleApplication(generator).Attach(this).Run();
-
-			// Set our view from the "main" layout resource
-			//SetContentView(Resource.Layout.Main);
-
-			// Get our button from the layout resource,
-			// and attach an event to it
-			/*Button button = FindViewById<Button>(Resource.Id.myButton);
-
-			button.Click += delegate
-			{
-				button.Text = string.Format("{0} clicks!", count++);
-			};*/
 		}
 	}
 }


Refactor.

Refactor.

--- src/SparkPost/DataMapper.cs
+++ src/SparkPost/DataMapper.cs
@@ -47,11 +47,16 @@

         public virtual IDictionary<string, object> ToDictionary(Options options)
         {
-            if (typeof(Options)
+            return AtLeastOneOptionWasSet(options)
+                ? WithCommonConventions(options, new Dictionary<string, object>())
+                : null;
+        }
+
+        private static bool AtLeastOneOptionWasSet(Options options)
+        {
+            return typeof(Options)
                 .GetProperties()
-                .Any(x => x.GetValue(options) != null))
-                return WithCommonConventions(options, new Dictionary<string, object>());
-            return null;
+                .Any(x => x.GetValue(options) != null);
         }

         public virtual IDictionary<string, object> ToDictionary(Content content)


(#61) Add max width item to instructional buttons menu

--- Source/Examples/Showcase/InstructionalButtons.cs
+++ Source/Examples/Showcase/InstructionalButtons.cs
@@ -33,11 +33,31 @@
                 }
             };

+            var maxWidth = new UIMenuNumericScrollerItem<float>("Max Width", $"Modifies the ~b~{nameof(RAGENativeUI.Elements.InstructionalButtons)}.{nameof(RAGENativeUI.Elements.InstructionalButtons.MaxWidth)}~s~ property.",
+                                0.0f, 1.0f, 0.01f)
+            {
+                Formatter = v => v.ToString("0.00"),
+            };
+            maxWidth.Value = InstructionalButtons.MaxWidth;
+            maxWidth.IndexChanged += (s, o, n) =>
+            {
+                float v = maxWidth.Value;
+                InstructionalButtons.MaxWidth = v;
+                InstructionalButtons.Update();
+                foreach (UIMenu child in Children.Values)
+                {
+                    child.InstructionalButtons.MaxWidth = v;
+                    child.InstructionalButtons.Update();
+                }
+            };
+
             var addButton = new UIMenuItem("Add Button");
             addButton.Activated += (m, s) =>
             {
                 var button = new InstructionalButton("A", "Slot #" + slotId++);
                 var buttonMenu = new ButtonMenu(button);
+                buttonMenu.InstructionalButtons.BackgroundColor = bg.SelectedItem.GetColor();
+                buttonMenu.InstructionalButtons.MaxWidth = maxWidth.Value;
                 buttonMenu.InstructionalButtons.Buttons.Clear();
                 foreach (IInstructionalButtonSlot slot in InstructionalButtons.Buttons)
                 {
@@ -56,6 +76,7 @@
             };

             AddItem(bg);
+            AddItem(maxWidth);
             AddItem(addButton);
         }


More file.Length protection fixes.

More file.Length protection fixes.

--- src/TagLib/IFD/IFDReader.cs
+++ src/TagLib/IFD/IFDReader.cs
@@ -797,10 +797,18 @@
 			// to identify the makernote types
 			int header_size = 18;

-			if (file.Length < makernote_offset)
+			long length = 0;
+			try {
+				length = file.Length;
+			} catch (Exception) {
+				// Use a safety-value of 4 gigabyte.
+				length = 1073741824L * 4;
+			}
+
+			if (makernote_offset > length)
 			    throw new Exception ("offset to makernote is beyond file size");

-			if (file.Length < makernote_offset + header_size)
+			if (makernote_offset + header_size > length)
 				throw new Exception ("data is to short to contain a maker note ifd");

 			// read header


Add ru-RU and pl-PL to language service

Add ru-RU and pl-PL to language service

--- Source/Monitorian.Core/Models/LanguageService.cs
+++ Source/Monitorian.Core/Models/LanguageService.cs
@@ -13,7 +13,9 @@
 		private static IReadOnlyDictionary<string, string> PreparedCulturePairs => new Dictionary<string, string>
 		{
 			{ "/en", "en-US" },
-			{ "/ja", "ja-JP" }
+			{ "/ja", "ja-JP" },
+			{ "/pl", "pl-PL" },
+			{ "/ru", "ru-RU" },
 		};

 		public static IReadOnlyCollection<string> Options => PreparedCulturePairs.Keys.ToArray();


No need for a byte array or pinning

No need for a byte array or pinning

--- src/UnixNativeTransport.cs
+++ src/UnixNativeTransport.cs
@@ -142,14 +142,13 @@
 		//different platforms do this in different ways
 		unsafe public override void WriteCred ()
 		{
+			//null credentials byte
+			byte buf = 0;
+
 #if HAVE_CMSGCRED
-			//null credentials byte
-			byte[] buf = new byte[] { 0 };
-
 			IOVector iov = new IOVector ();
-			fixed (byte *bufPtr = buf)
-				iov.Base = (IntPtr)bufPtr;
-			iov.Length = buf.Length;
+			iov.Base = (IntPtr)(&buf);
+			iov.Length = 1;

 			msghdr msg = new msghdr ();
 			msg.msg_iov = &iov;
@@ -164,10 +163,10 @@

 			int written = UnixSocket.sendmsg (socket.Handle, (IntPtr)(&msg), 0);
 			UnixMarshal.ThrowExceptionForLastErrorIf (written);
-			if (written != buf.Length)
+			if (written != 1)
 				throw new Exception ("Failed to write credentials");
 #else
-			Stream.WriteByte (0);
+			Stream.WriteByte (buf);
 #endif
 		}


Refine footnote

Refine footnote

--- src/Views/Home/Index.cshtml
+++ src/Views/Home/Index.cshtml
@@ -104,7 +104,7 @@

-                * Vooruitgang wordt gemeten in een getal. Hoe hoger het getal hoe meer vooruitgang. 0 is neutraal. Negatief betekent achteruitgang

+                * Vooruitgang wordt gemeten in een getal. Hoe hoger het getal hoe meer vooruitgang (op de opgaven waarbij deze waarde kon worden berekent). 0 is neutraal. Negatief betekent achteruitgang.


Update Demo

Update Demo

--- Src/Asp.Net/SugarCodeGeneration/Codes/Methods.cs
+++ Src/Asp.Net/SugarCodeGeneration/Codes/Methods.cs
@@ -14,6 +14,7 @@
     /// </summary>
     public class Methods
     {
+        public static Dictionary<string, string> ProjectIds = new Dictionary<string, string>();
         public static string GetCurrentProjectPath
         {

@@ -47,6 +48,7 @@

             XElement itemGroup = new XElement("ItemGroup");
             itemGroup.Add(new XElement("Name", refProjectName));
+            itemGroup.Add(new XElement("Project", "{" + ProjectIds[refProjectName] + "}"));
             itemGroup.Add(new XElement("ProjectReference", new XAttribute("Include", string.Format(@"..\{0}\{0}.csproj", refProjectName))));
             root.Add(itemGroup);

@@ -136,6 +138,7 @@
                 FileHelper.CreateFile(projectPath, project, System.Text.Encoding.UTF8);
                 FileHelper.CreateFile(projectDic + "\\class1.cs", "", System.Text.Encoding.UTF8);
                 //没成功File.Copy(GetCurrentProjectPath + "/Template/nuget.txt", projectDic + "packages.config");
+                ProjectIds.Add(name, projectId);
                 AppendProjectToSln(projectId, name);
             }
         }


Improve parser test

Improve parser test

--- Src/RSharp.Core.Tests/Interpreter/ParserTests.cs
+++ Src/RSharp.Core.Tests/Interpreter/ParserTests.cs
@@ -212,6 +212,14 @@
             Assert.IsNotNull(expr);
             Assert.IsInstanceOfType(expr, typeof(ArrayAccessExpression));

+            var aexpr = (ArrayAccessExpression)expr;
+
+            Assert.IsNotNull(aexpr.ArrayExpression);
+            Assert.IsInstanceOfType(aexpr.ArrayExpression, typeof(CallExpression));
+            Assert.IsNotNull(aexpr.ArgumentExpressions);
+            Assert.AreEqual(1, aexpr.ArgumentExpressions.Count);
+            Assert.IsInstanceOfType(aexpr.ArgumentExpressions[0], typeof(ConstantExpression));
+
             Context context = new Context();
             context.SetValue("c", new MakeVector());


Updated platform test suite with resolveall and IEnumerable dependency tests

--- TinyIoC.Tests/PlatformTestSuite/PlatformTests.cs
+++ TinyIoC.Tests/PlatformTestSuite/PlatformTests.cs
@@ -142,6 +142,18 @@
             {
                 _Factory = factory;
                 Prop1 = _Factory.Invoke("Testing", new Dictionary<String, object> { { "stringProperty", "Testing" }, { "intProperty", 22 } });
+            }
+        }
+
+        internal class TestClassEnumerableDependency
+        {
+            IEnumerable<ITestInterface> _Enumerable;
+
+            public int EnumerableCount { get { return _Enumerable == null ? 0 : _Enumerable.Count(); } }
+
+            public TestClassEnumerableDependency(IEnumerable<ITestInterface> enumerable)
+            {
+                _Enumerable = enumerable;
             }
         }
         #endregion
@@ -180,8 +192,10 @@
 #if EXPRESSIONS
                 ResolveLazyFactory,
                 ResolveNamedLazyFactory,
-                ResolveNamedAndParamsLazyFactory
+                ResolveNamedAndParamsLazyFactory,
 #endif
+                ResolveAll,
+                IEnumerableDependency,
             };
         }

@@ -380,6 +394,32 @@
             var output = container.Resolve<TestclassWithNameAndParamsLazyFactory>();
             return (output.Prop1 != null);
         }
+
 #endif
+
+        private bool ResolveAll(TinyIoCContainer container, ILogger logger)
+        {
+            logger.WriteLine("ResolveAll");
+            container.Register<ITestInterface, TestClassWithInterface>();
+            container.Register<ITestInterface, TestClassWithInterface>("Named1");
+            container.Register<ITestInterface, TestClassWithInterface>("Named2");
+
+            IEnumerable<ITestInterface> result = container.ResolveAll<ITestInterface>();
+
+            return (result.Count() == 3);
+        }
+
+        private bool IEnumerableDependency(TinyIoCContainer container, ILogger logger)
+        {
+            logger.WriteLine("IEnumerableDependency");
+            container.Register<ITestInterface, TestClassWithInterface>();
+            container.Register<ITestInterface, TestClassWithInterface>("Named1");
+            container.Register<ITestInterface, TestClassWithInterface>("Named2");
+            container.Register<TestClassEnumerableDependency>();
+
+            var result = container.Resolve<TestClassEnumerableDependency>();
+
+            return (result.EnumerableCount == 3);
+        }
     }
 }


CHanged portfolio scheduling bounds

CHanged portfolio scheduling bounds

--- Tools/Testing/Tester/Testing/TestingPortfolio.cs
+++ Tools/Testing/Tester/Testing/TestingPortfolio.cs
@@ -30,7 +30,7 @@
         /// <param name="configuration">Configuration</param>
         internal static void ConfigureStrategyForCurrentProcess(Configuration configuration)
         {
-            // Random, PCT[1], ProbabilisticRandom[5], PCT[5], ProbabilisticRandom[10], PCT[10], etc.
+            // Random, PCT[1], ProbabilisticRandom[1], PCT[5], ProbabilisticRandom[2], PCT[10], etc.
             if (configuration.TestingProcessId == 0)
             {
                 configuration.SchedulingStrategy = SchedulingStrategy.Random;
@@ -38,7 +38,7 @@
             else if (configuration.TestingProcessId % 2 == 0)
             {
                 configuration.SchedulingStrategy = SchedulingStrategy.ProbabilisticRandom;
-                configuration.CoinFlipBound = 5 * (int)(configuration.TestingProcessId / 2);
+                configuration.CoinFlipBound = (int)(configuration.TestingProcessId / 2);
             }
             else if (configuration.TestingProcessId == 1)
             {


- Bug fix for getting avatar URL from Trovo chat message

--- Trovo/Trovo.Base/Models/Chat/ChatMessageModel.cs
+++ Trovo/Trovo.Base/Models/Chat/ChatMessageModel.cs
@@ -287,6 +287,16 @@
         /// Returns the full avatar URL for the user.
         /// </summary>
         [JsonIgnore]
-        public string FullAvatarURL { get { return (this.avatar.StartsWith(FullAvatarURLFormat)) ? this.avatar : FullAvatarURLFormat + this.avatar; } }
+        public string FullAvatarURL
+        {
+            get
+            {
+                if (!string.IsNullOrEmpty(this.avatar))
+                {
+                    return (this.avatar.StartsWith(FullAvatarURLFormat)) ? this.avatar : FullAvatarURLFormat + this.avatar;
+                }
+                return null;
+            }
+        }
     }
 }


Fixed detection of Msiexec quiet uninstall deadlocks and fixed timeout timer not resetting. Fixes #10

--- UninstallTools/Uninstaller/BulkUninstallEntry.cs
+++ UninstallTools/Uninstaller/BulkUninstallEntry.cs
@@ -98,7 +98,7 @@
             worker.Start(options);
         }

-        public sealed class RunUninstallerOptions
+        internal sealed class RunUninstallerOptions
         {
             public RunUninstallerOptions(bool autoKillStuckQuiet, bool retryFailedQuiet, bool preferQuiet, bool simulate)
             {
@@ -134,7 +134,6 @@
                             uninstaller.PriorityClass = ProcessPriorityClass.BelowNormal;

                         var checkCounters = options.PreferQuiet && options.AutoKillStuckQuiet && UninstallerEntry.QuietUninstallPossible;
-
                         var watchedProcesses = new List<Process> { uninstaller };
                         var idleCounter = 0;

@@ -143,9 +142,15 @@
                             if (_skipLevel == SkipCurrentLevel.Skip)
                                 break;

-                            foreach (var watchedProcess in watchedProcesses.ToList())
+                            var processesToScanForChildren = watchedProcesses.ToList();
+                            // Msiexec service can start processes, but we don't want to watch the service
+                            if(UninstallerEntry.UninstallerKind == UninstallerType.Msiexec)
+                                processesToScanForChildren.AddRange(Process.GetProcessesByName("msiexec"));
+
+                            foreach (var watchedProcess in processesToScanForChildren.Distinct((p1, p2) => p1.Id.Equals(p2.Id)))
                                 watchedProcesses.AddRange(watchedProcess.GetChildProcesses());

+                            // Remove dead and blaclisted processes
                             watchedProcesses.RemoveAll(p =>
                             {
                                 if (p.HasExited)
@@ -166,7 +171,8 @@

                                 return processSnapshot.Contains(p.Id);
                             });
-
+
+                            // Check if we are done, or if there are some proceses left that we missed
                             if (watchedProcesses.Count == 0)
                             {
                                 if(string.IsNullOrEmpty(UninstallerEntry.InstallLocation))
@@ -191,6 +197,7 @@
                                     break;
                             }

+                            // Check for deadlocks during silent uninstall
                             if (checkCounters)
                             {
                                 var processNames = watchedProcesses.Select(x =>
@@ -208,11 +215,13 @@

                                 if (TestUninstallerForStalls(processNames))
                                     idleCounter++;
+                                else
+                                    idleCounter = 0;

                                 // Kill the uninstaller (and children) if they were idle/stalled for too long
-                                if (idleCounter > 40)
-                                {
-                                    uninstaller.Kill(true);
+                                if (idleCounter > 30)
+                                {
+                                    KillProcesses(watchedProcesses);
                                     throw new IOException(Localisation.UninstallError_UninstallerTimedOut);
                                 }
                             }
@@ -224,19 +233,7 @@
                                 if (UninstallerEntry.UninstallerKind == UninstallerType.Msiexec)
                                     watchedProcesses.AddRange(Process.GetProcessesByName("Msiexec"));

-                                foreach (var process in watchedProcesses)
-                                {
-                                    try
-                                    {
-                                        process.Kill();
-                                    }
-                                    catch (InvalidOperationException)
-                                    {
-                                    }
-                                    catch (Win32Exception)
-                                    {
-                                    }
-                                }
+                                KillProcesses(watchedProcesses);
                                 break;
                             }
                         }
@@ -327,6 +324,23 @@
             IsRunning = false;
         }

+        private static void KillProcesses(IEnumerable<Process> processes)
+        {
+            foreach (var process in processes)
+            {
+                try
+                {
+                    process.Kill();
+                }
+                catch (InvalidOperationException)
+                {
+                }
+                catch (Win32Exception)
+                {
+                }
+            }
+        }
+
         /// <summary>
         /// Returns true if uninstaller appears to be stalled. Blocks for 1000ms to gather data.
         /// </summary>
@@ -353,9 +367,8 @@
             }

             Thread.Sleep(1000);
-
-            //Has problems with Msiexec
-            if (counters != null && UninstallerEntry.UninstallerKind != UninstallerType.Msiexec)
+
+            if (counters != null)
             {
                 try
                 {


dfhgfh

dfhgfh

--- WebApplication1/Controllers/AccountController.cs
+++ WebApplication1/Controllers/AccountController.cs
@@ -20,6 +20,7 @@

         private string _msg;
         private string _msg1;
+        private dfhbjkd;

         public AccountController()
         {


Generated files as a result of building

Generated files as a result of building

--- WebRtc.Mono.Droid/Resources/Resource.Designer.cs
+++ WebRtc.Mono.Droid/Resources/Resource.Designer.cs
@@ -1,73 +1,112 @@
+#pragma warning disable 1591
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:2.0.50727.4952
+//     Runtime Version:4.0.30319.18408
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
 // </auto-generated>
 //------------------------------------------------------------------------------

+[assembly: global::Android.Runtime.ResourceDesignerAttribute("WebRtc.Mono.Droid.Resource", IsApplication=true)]
+
 namespace WebRtc.Mono.Droid
 {
-
-
+
+
+	[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
 	public partial class Resource
 	{
-
+
+		static Resource()
+		{
+			global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+		}
+
+		public static void UpdateIdValues()
+		{
+		}
+
 		public partial class Attribute
 		{
-
+
+			static Attribute()
+			{
+				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+			}
+
 			private Attribute()
 			{
 			}
 		}
-
+
 		public partial class Drawable
 		{
-
+
 			// aapt resource value: 0x7f020000
 			public const int Icon = 2130837504;
-
+
+			static Drawable()
+			{
+				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+			}
+
 			private Drawable()
 			{
 			}
 		}
-
+
 		public partial class Id
 		{
-
+
 			// aapt resource value: 0x7f050000
 			public const int MyButton = 2131034112;
-
+
+			static Id()
+			{
+				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+			}
+
 			private Id()
 			{
 			}
 		}
-
+
 		public partial class Layout
 		{
-
+
 			// aapt resource value: 0x7f030000
 			public const int Main = 2130903040;
-
+
+			static Layout()
+			{
+				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+			}
+
 			private Layout()
 			{
 			}
 		}
-
+
 		public partial class String
 		{
-
+
 			// aapt resource value: 0x7f040001
 			public const int ApplicationName = 2130968577;
-
+
 			// aapt resource value: 0x7f040000
 			public const int Hello = 2130968576;
-
+
+			static String()
+			{
+				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+			}
+
 			private String()
 			{
 			}
 		}
 	}
 }
+#pragma warning restore 1591


CharaSim: Update to CMST.141

CharaSim: Update to CMST.141

--- WzComparerR2.Common/CharaSim/ItemStringHelper.cs
+++ WzComparerR2.Common/CharaSim/ItemStringHelper.cs
@@ -97,7 +97,7 @@
                 case GearPropType.incPQEXPr: return "组队任务经验值增加" + value + "%";
                 case GearPropType.incEXPr: return "经验值增加" + value + "%";
                 case GearPropType.incBDR:
-                case GearPropType.bdR: return "攻击BOSS怪物时，伤害+" + value + "%";
+                case GearPropType.bdR: return "攻击首领怪时，伤害+" + value + "%";
                 case GearPropType.incIMDR:
                 case GearPropType.imdR: return "无视怪物防御率：+" + value + "%";
                 case GearPropType.limitBreak: return "伤害上限突破至" + value + "。";


Add cache on SpriterFile for optimization.

--- Xmas-Hell/Xmas-Hell-Core/Spriter/SpriterUtils.cs
+++ Xmas-Hell/Xmas-Hell-Core/Spriter/SpriterUtils.cs
@@ -5,11 +5,16 @@
 using System.Linq;
 using System.IO;
 using XmasHell.Extensions;
+using System.Collections.Generic;

 namespace XmasHell.Spriter
 {
     static class SpriterUtils
     {
+        // Key = Tuple(SpritePartFilename, AnimatorEntityName)
+        // Value = Tuple(SpriterFile, FolderId)
+        private static Dictionary<Tuple<string, string>, Tuple<SpriterFile, int>> _spriterFilesCache = new Dictionary<Tuple<string, string>, Tuple<SpriterFile, int>>();
+
         public static SpriterObject GetSpriterFileData(string spritePartFileName, MonoGameAnimator animator, string timelineName = null)
         {
             if (animator.FrameData == null)
@@ -18,7 +23,7 @@
             int folderId;
             var spriterFile = GetSpriterFile(spritePartFileName, animator, out folderId);
             var spriteData = animator.FrameData.SpriteData;
-            var fileSpriteDataFound = spriteData.FindAll((so) =>
+            var fileSpriteDataFound = spriteData.Find((so) =>
             {
                 if (timelineName != null)
                     return so.FolderId == folderId && so.FileId == spriterFile.Id && so.Name == timelineName;
@@ -26,10 +31,7 @@
                     return so.FolderId == folderId && so.FileId == spriterFile.Id;
             });

-            if (fileSpriteDataFound.Count == 0)
-                return null;
-
-            return fileSpriteDataFound.First();
+            return fileSpriteDataFound;
         }

         public static Vector2 GetSpriterFilePosition(string spritePartFileName, MonoGameAnimator animator, string timelineName = null)
@@ -99,14 +101,23 @@
             if (animator == null)
                 throw new ArgumentException("Please make sure that a Spriter animator is linked to the given entity.");

+            var cacheKey = new Tuple<string, string>(spritePartFileName, animator.Entity.Name);
+            if (_spriterFilesCache.ContainsKey(cacheKey))
+            {
+                folderId = _spriterFilesCache[cacheKey].Item2;
+                return _spriterFilesCache[cacheKey].Item1;
+            }
+
             foreach (var folder in animator.Entity.Spriter.Folders)
             {
                 var spriterFileId = Array.FindIndex(folder.Files, (file) => Path.GetFileName(file.Name) == spritePartFileName);

-                folderId = folder.Id;
-
-                if (spriterFileId != -1)
+                if (spriterFileId != -1)
+                {
+                    folderId = folder.Id;
+                    _spriterFilesCache.Add(new Tuple<string, string>(spritePartFileName, animator.Entity.Name), new Tuple<SpriterFile, int>(folder.Files[spriterFileId], folderId));
                     return folder.Files[spriterFileId];
+                }
             }

             throw new ArgumentException("Please make sure that the given Spriter entity has a sprite part named: " + spritePartFileName);


Add Larry to contact page.

Add Larry to contact page.

--- ZirMed.TrainingSandbox/Views/Home/Contact.cshtml
+++ ZirMed.TrainingSandbox/Views/Home/Contact.cshtml
@@ -22,4 +22,5 @@
     Travis2: travis.elkins@zirmed.com
     Stephanie: stephanie.craig@zirmed.com
     Bruce Wayne:
+    Larry Briggs:
 </address>