From a51bca38f0ce6e797055299d0f708f7b5d3d5650 Mon Sep 17 00:00:00 2001
From: adelikat <adelikat@tasvideos.org>
Date: Fri, 18 Oct 2019 18:56:21 -0500
Subject: [PATCH] convert RamSearch to use InputRoll

---
 .../Extensions/ControlExtensions.cs           |   1 +
 .../tools/Watch/RamSearch.Designer.cs         |  57 +------
 .../tools/Watch/RamSearch.cs                  | 160 +++++++++++-------
 3 files changed, 101 insertions(+), 117 deletions(-)

diff --git a/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs b/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs
index 6e21c8a88d..9518dde03e 100644
--- a/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs
+++ b/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs
@@ -94,6 +94,7 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
 			{
 				var menuItem = new ToolStripMenuItem
 				{
+					Name = column.Name,
 					Text = $"{column.Text} ({column.Name})",
 					Checked = column.Visible,
 					CheckOnClick = true,
diff --git a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.Designer.cs b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.Designer.cs
index b126c12fe1..ba24ec8b2f 100644
--- a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.Designer.cs
+++ b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.Designer.cs
@@ -32,12 +32,7 @@
 			System.Windows.Forms.ToolStripMenuItem SearchMenuItem;
 			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RamSearch));
 			this.TotalSearchLabel = new System.Windows.Forms.Label();
-			this.WatchListView = new BizHawk.Client.EmuHawk.VirtualListView();
-			this.AddressColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.ValueColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.PreviousColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.ChangesColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.DiffColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.WatchListView = new InputRoll();
 			this.ListViewContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
 			this.DoSearchContextMenuItem = new System.Windows.Forms.ToolStripMenuItem();
 			this.NewSearchContextMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -189,61 +184,24 @@
 			this.WatchListView.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.WatchListView.BlazingFast = false;
-			this.WatchListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
-            this.AddressColumn,
-            this.ValueColumn,
-            this.PreviousColumn,
-            this.ChangesColumn,
-            this.DiffColumn});
 			this.WatchListView.ContextMenuStrip = this.ListViewContextMenu;
 			this.WatchListView.FullRowSelect = true;
 			this.WatchListView.GridLines = true;
-			this.WatchListView.HideSelection = false;
-			this.WatchListView.ItemCount = 0;
+			this.WatchListView.RowCount = 0;
 			this.WatchListView.Location = new System.Drawing.Point(9, 65);
 			this.WatchListView.Name = "WatchListView";
-			this.WatchListView.SelectAllInProgress = false;
-			this.WatchListView.selectedItem = -1;
 			this.WatchListView.Size = new System.Drawing.Size(230, 366);
 			this.WatchListView.TabIndex = 1;
-			this.WatchListView.UseCompatibleStateImageBehavior = false;
 			this.WatchListView.UseCustomBackground = true;
-			this.WatchListView.View = System.Windows.Forms.View.Details;
-			this.WatchListView.VirtualMode = true;
-			this.WatchListView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.WatchListView_ColumnClick);
+
+			this.WatchListView.ColumnClick += new BizHawk.Client.EmuHawk.InputRoll.ColumnClickEventHandler(this.WatchListView_ColumnClick);
 			this.WatchListView.SelectedIndexChanged += new System.EventHandler(this.WatchListView_SelectedIndexChanged);
-			this.WatchListView.VirtualItemsSelectionRangeChanged += new System.Windows.Forms.ListViewVirtualItemsSelectionRangeChangedEventHandler(this.WatchListView_VirtualItemsSelectionRangeChanged);
 			this.WatchListView.DragDrop += new System.Windows.Forms.DragEventHandler(this.NewRamSearch_DragDrop);
 			this.WatchListView.DragEnter += new System.Windows.Forms.DragEventHandler(this.DragEnterWrapper);
 			this.WatchListView.Enter += new System.EventHandler(this.WatchListView_Enter);
 			this.WatchListView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.WatchListView_KeyDown);
 			this.WatchListView.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.WatchListView_MouseDoubleClick);
 			// 
-			// AddressColumn
-			// 
-			this.AddressColumn.Text = "Address";
-			this.AddressColumn.Width = 61;
-			// 
-			// ValueColumn
-			// 
-			this.ValueColumn.Text = "Value";
-			this.ValueColumn.Width = 48;
-			// 
-			// PreviousColumn
-			// 
-			this.PreviousColumn.Text = "Prev";
-			this.PreviousColumn.Width = 48;
-			// 
-			// ChangesColumn
-			// 
-			this.ChangesColumn.Text = "Changes";
-			this.ChangesColumn.Width = 55;
-			// 
-			// DiffColumn
-			// 
-			this.DiffColumn.Text = "Diff";
-			// 
 			// ListViewContextMenu
 			// 
 			this.ListViewContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -1422,11 +1380,7 @@
 		#endregion
 
 		private System.Windows.Forms.Label TotalSearchLabel;
-		VirtualListView WatchListView;
-		private System.Windows.Forms.ColumnHeader AddressColumn;
-		private System.Windows.Forms.ColumnHeader ValueColumn;
-		private System.Windows.Forms.ColumnHeader PreviousColumn;
-		private System.Windows.Forms.ColumnHeader ChangesColumn;
+		InputRoll WatchListView;
 		private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
 		private System.Windows.Forms.ToolStripMenuItem OpenMenuItem;
 		private System.Windows.Forms.ToolStripMenuItem SaveAsMenuItem;
@@ -1530,7 +1484,6 @@
 		private WatchValueBox DifferenceBox;
 		private System.Windows.Forms.ToolStripMenuItem AutoSearchMenuItem;
 		private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
-		private System.Windows.Forms.ColumnHeader DiffColumn;
 		private System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
 		private System.Windows.Forms.ToolStripButton UndoToolBarButton;
 		private System.Windows.Forms.ToolStripButton RedoToolBarItem;
diff --git a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
index 91605466a5..4d82362c12 100644
--- a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
+++ b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
@@ -53,13 +53,13 @@ namespace BizHawk.Client.EmuHawk
 			InitializeComponent();
 			WatchListView.QueryItemText += ListView_QueryItemText;
 			WatchListView.QueryItemBkColor += ListView_QueryItemBkColor;
-			WatchListView.VirtualMode = true;
 			Closing += (o, e) => SaveConfigSettings();
 
 			_sortedColumn = "";
 			_sortReverse = false;
 
 			Settings = new RamSearchSettings();
+			SetColumns();
 		}
 
 		[RequiredService]
@@ -110,15 +110,20 @@ namespace BizHawk.Client.EmuHawk
 
 		private void ColumnToggleCallback()
 		{
-			SaveColumnInfo(WatchListView, Settings.Columns);
-			LoadColumnInfo(WatchListView, Settings.Columns);
+			Settings.Columns = WatchListView.AllColumns;
 		}
 
 		private void RamSearch_Load(object sender, EventArgs e)
 		{
+			// Hack for previous config settings
+			if (Settings.Columns.Any(c => string.IsNullOrWhiteSpace(c.Text)))
+			{
+				Settings = new RamSearchSettings();
+			}
+
 			TopMost = Settings.TopMost;
 
-			RamSearchMenu.Items.Add(Settings.Columns.GenerateColumnsMenu(ColumnToggleCallback));
+			RamSearchMenu.Items.Add(WatchListView.ToColumnsMenu(ColumnToggleCallback));
 
 			_settings = new RamSearchEngine.Settings(MemoryDomains);
 			_searches = new RamSearchEngine(_settings, MemoryDomains);
@@ -161,39 +166,36 @@ namespace BizHawk.Client.EmuHawk
 			ErrorIconButton.Visible = _searches.OutOfRangeAddress.Any();
 		}
 
-		private void ListView_QueryItemBkColor(int index, int column, ref Color color)
+		private void ListView_QueryItemBkColor(int index, InputRoll.RollColumn column, ref Color color)
 		{
-			if (column == 0)
+			if (_searches.Count > 0)
 			{
-				if (_searches.Count > 0 && column == 0)
+				var nextColor = Color.White;
+
+				var isCheat = Global.CheatList.IsActive(_settings.Domain, _searches[index].Address);
+				var isWeeded = Settings.PreviewMode && !_forcePreviewClear && _searches.Preview(_searches[index].Address);
+
+				if (_searches[index].Address >= _searches[index].Domain.Size)
 				{
-					var nextColor = Color.White;
-
-					var isCheat = Global.CheatList.IsActive(_settings.Domain, _searches[index].Address);
-					var isWeeded = Settings.PreviewMode && !_forcePreviewClear && _searches.Preview(_searches[index].Address);
-
-					if (_searches[index].Address >= _searches[index].Domain.Size)
-					{
-						nextColor = Color.PeachPuff;
-					}
-					else if (isCheat)
-					{
-						nextColor = isWeeded ? Color.Lavender : Color.LightCyan;
-					}
-					else
-					{
-						if (isWeeded)
-						{
-							nextColor = Color.Pink;
-						}
-					}
-
-					color = nextColor;
+					nextColor = Color.PeachPuff;
 				}
+				else if (isCheat)
+				{
+					nextColor = isWeeded ? Color.Lavender : Color.LightCyan;
+				}
+				else
+				{
+					if (isWeeded)
+					{
+						nextColor = Color.Pink;
+					}
+				}
+
+				color = nextColor;
 			}
 		}
 
-		private void ListView_QueryItemText(int index, int column, out string text)
+		private void ListView_QueryItemText(int index, InputRoll.RollColumn column, out string text, ref int offsetX, ref int offsetY)
 		{
 			text = "";
 
@@ -202,7 +204,7 @@ namespace BizHawk.Client.EmuHawk
 				return;
 			}
 
-			var columnName = WatchListView.Columns[column].Name;
+			var columnName = column.Name;
 			switch (columnName)
 			{
 				case WatchList.ADDRESS:
@@ -240,7 +242,19 @@ namespace BizHawk.Client.EmuHawk
 
 			TopMost = Settings.TopMost;
 
-			LoadColumnInfo(WatchListView, Settings.Columns);
+			WatchListView.AllColumns.Clear();
+			SetColumns();
+		}
+
+		private void SetColumns()
+		{
+			foreach (var column in Settings.Columns)
+			{
+				if (WatchListView.AllColumns[column.Name] == null)
+				{
+					WatchListView.AllColumns.Add(column);
+				}
+			}
 		}
 
 		#endregion
@@ -252,7 +266,7 @@ namespace BizHawk.Client.EmuHawk
 		/// </summary>
 		private void UpdateList()
 		{
-			WatchListView.ItemCount = _searches.Count;
+			WatchListView.RowCount = _searches.Count;
 			SetTotal();
 		}
 
@@ -282,9 +296,7 @@ namespace BizHawk.Client.EmuHawk
 				}
 
 				_forcePreviewClear = false;
-				WatchListView.BlazingFast = true;
 				WatchListView.Invalidate();
-				WatchListView.BlazingFast = false;
 			}
 		}
 
@@ -314,7 +326,7 @@ namespace BizHawk.Client.EmuHawk
 
 		private void SaveConfigSettings()
 		{
-			SaveColumnInfo(WatchListView, Settings.Columns);
+			Settings.Columns = WatchListView.AllColumns;
 
 			if (WindowState == FormWindowState.Normal)
 			{
@@ -551,7 +563,7 @@ namespace BizHawk.Client.EmuHawk
 			_forcePreviewClear = true;
 		}
 
-		private IEnumerable<int> SelectedIndices => WatchListView.SelectedIndices.Cast<int>();
+		private IEnumerable<int> SelectedIndices => WatchListView.SelectedRows;
 
 		private IEnumerable<Watch> SelectedItems
 		{
@@ -771,10 +783,27 @@ namespace BizHawk.Client.EmuHawk
 			DifferenceRadio.Enabled = true;
 			DifferentByBox.Enabled = true;
 			ClearChangeCountsToolBarItem.Enabled = true;
-			WatchListView.Columns[WatchList.CHANGES].Width = Settings.Columns[WatchList.CHANGES].Width;
+
+			WatchListView.AllColumns[WatchList.CHANGES].Visible = true;
+			ChangesMenuItem.Checked = true;
+
+			ColumnToggleCallback();
 			SetReboot(true);
 		}
 
+		private ToolStripMenuItem ChangesMenuItem
+		{
+			get
+			{
+				var subMenu = (ToolStripMenuItem)RamSearchMenu.Items
+					.Cast<ToolStripItem>()
+					.Single(t => t.Name == "GeneratedColumnsSubMenu"); // InputRoll TODO - make name a constant
+				return subMenu.DropDownItems
+					.Cast<ToolStripMenuItem>()
+					.Single(t => t.Name == WatchList.CHANGES);
+			}
+		}
+
 		private void SetToFastMode()
 		{
 			_settings.Mode = RamSearchEngine.Settings.SearchMode.Fast;
@@ -794,8 +823,10 @@ namespace BizHawk.Client.EmuHawk
 				PreviousValueRadio.Checked = true;
 			}
 
-			Settings.Columns[WatchList.CHANGES].Width = WatchListView.Columns[WatchList.CHANGES].Width;
-			WatchListView.Columns[WatchList.CHANGES].Width = 0;
+			WatchListView.AllColumns[WatchList.CHANGES].Visible = false;
+			ChangesMenuItem.Checked = false;
+
+			ColumnToggleCallback();
 			SetReboot(true);
 		}
 
@@ -808,7 +839,7 @@ namespace BizHawk.Client.EmuHawk
 				_searches.RemoveRange(indices);
 
 				UpdateList();
-				WatchListView.SelectedIndices.Clear();
+				WatchListView.DeselectAll();
 				ToggleSearchDependentToolBarItems();
 			}
 		}
@@ -899,7 +930,7 @@ namespace BizHawk.Client.EmuHawk
 
 		private void GoToSpecifiedAddress()
 		{
-			WatchListView.SelectedIndices.Clear();
+			WatchListView.DeselectAll();
 			var prompt = new InputPrompt
 			{
 				Text = "Go to Address",
@@ -916,8 +947,9 @@ namespace BizHawk.Client.EmuHawk
 					{
 						if (_searches[index].Address == addr)
 						{
-							WatchListView.SelectItem(index, true);
-							WatchListView.ensureVisible();
+							WatchListView.SelectRow(index, true);
+							// InputRoll TODO:
+							//WatchListView.ensureVisible();
 							return; // Don't re-show dialog on success
 						}
 					}
@@ -943,13 +975,13 @@ namespace BizHawk.Client.EmuHawk
 		{
 			public RamSearchSettings()
 			{
-				Columns = new ColumnList
+				Columns = new List<InputRoll.RollColumn>
 				{
-					new Column { Name = WatchList.ADDRESS, Visible = true, Index = 0, Width = 60 },
-					new Column { Name = WatchList.VALUE, Visible = true, Index = 1, Width = 59 },
-					new Column { Name = WatchList.PREV, Visible = true, Index = 2, Width = 59 },
-					new Column { Name = WatchList.CHANGES, Visible = true, Index = 3, Width = 55 },
-					new Column { Name = WatchList.DIFF, Visible = false, Index = 4, Width = 59 },
+					new InputRoll.RollColumn { Text = "Address", Name = WatchList.ADDRESS, Visible = true, Width = 60, Type = InputRoll.RollColumn.InputType.Text },
+					new InputRoll.RollColumn { Text = "Value", Name = WatchList.VALUE, Visible = true, Width = 59, Type = InputRoll.RollColumn.InputType.Text },
+					new InputRoll.RollColumn { Text = "Prev", Name = WatchList.PREV, Visible = false, Width = 59, Type = InputRoll.RollColumn.InputType.Text },
+					new InputRoll.RollColumn { Text = "Changes", Name = WatchList.CHANGES, Visible = true, Width = 60, Type = InputRoll.RollColumn.InputType.Text },
+					new InputRoll.RollColumn { Text = "Diff", Name = WatchList.DIFF, Visible = false, Width = 59, Type = InputRoll.RollColumn.InputType.Text },
 				};
 
 				PreviewMode = true;
@@ -957,7 +989,7 @@ namespace BizHawk.Client.EmuHawk
 				AutoSearchTakeLagFramesIntoAccount = true;
 			}
 
-			public ColumnList Columns { get; }
+			public List<InputRoll.RollColumn> Columns { get; set; }
 			public bool PreviewMode { get; set; }
 			public bool AlwaysExcludeRamWatch { get; set; }
 			public bool AutoSearchTakeLagFramesIntoAccount { get; set; }
@@ -1387,7 +1419,7 @@ namespace BizHawk.Client.EmuHawk
 					.OfType<ToolStripMenuItem>()
 					.First(x => x.Name == "GeneratedColumnsSubMenu"));
 
-			RamSearchMenu.Items.Add(Settings.Columns.GenerateColumnsMenu(ColumnToggleCallback));
+			RamSearchMenu.Items.Add(WatchListView.ToColumnsMenu(ColumnToggleCallback));
 
 			_settings = new RamSearchEngine.Settings(MemoryDomains);
 			if (_settings.Mode == RamSearchEngine.Settings.SearchMode.Fast)
@@ -1396,7 +1428,9 @@ namespace BizHawk.Client.EmuHawk
 			}
 
 			RefreshFloatingWindowControl(Settings.FloatingWindow);
-			LoadColumnInfo(WatchListView, Settings.Columns);
+
+			WatchListView.AllColumns.Clear();
+			SetColumns();
 		}
 
 		#endregion
@@ -1708,16 +1742,17 @@ namespace BizHawk.Client.EmuHawk
 			}
 			else if (e.KeyCode == Keys.Escape && !e.Control && !e.Alt && !e.Shift)
 			{
-				WatchListView.SelectedIndices.Clear();
+				WatchListView.DeselectAll();
 			}
 		}
 
 		private void WatchListView_SelectedIndexChanged(object sender, EventArgs e)
 		{
-			if (WatchListView.SelectAllInProgress)
-			{
-				return;
-			}
+			// InputRoll todo - do we need this?
+			//if (WatchListView.SelectAllInProgress)
+			//{
+			//	return;
+			//}
 
 			RemoveToolBarItem.Enabled =
 				AddToRamWatchToolBarItem.Enabled =
@@ -1729,19 +1764,14 @@ namespace BizHawk.Client.EmuHawk
 				_searches.Domain.CanPoke();
 		}
 
-		private void WatchListView_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e)
-		{
-			WatchListView_SelectedIndexChanged(sender, e);
-		}
-
 		private void WatchListView_Enter(object sender, EventArgs e)
 		{
 			WatchListView.Refresh();
 		}
 
-		private void WatchListView_ColumnClick(object sender, ColumnClickEventArgs e)
+		private void WatchListView_ColumnClick(object sender, InputRoll.ColumnClickEventArgs e)
 		{
-			var column = WatchListView.Columns[e.Column];
+			var column = e.Column;
 			if (column.Name != _sortedColumn)
 			{
 				_sortReverse = false;