From 6eb44acd4f17e3e34e1b557682d11f7160ea552f Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Sun, 3 Nov 2019 18:04:31 -0500 Subject: [PATCH] Fix noise from last merge. --- .../PlatformAgnosticVirtualListView.API.cs | 183 ---- ...PlatformAgnosticVirtualListView.Classes.cs | 315 ------- ...PlatformAgnosticVirtualListView.Drawing.cs | 531 ------------ ...rmAgnosticVirtualListView.EventHandlers.cs | 703 ---------------- ...PlatformAgnosticVirtualListView.Helpers.cs | 359 -------- ...tformAgnosticVirtualListView.Properties.cs | 780 ------------------ .../PlatformAgnosticVirtualListView.cs | 356 -------- .../tools/TAStudio/TAStudio.Designer.cs | 2 +- .../tools/TAStudio/TAStudio.MenuItems.cs | 1 - .../tools/TAStudio/TAStudio.resx | 26 +- .../BizHawk.Emulation.Cores.csproj | 39 + 11 files changed, 53 insertions(+), 3242 deletions(-) delete mode 100644 BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.API.cs delete mode 100644 BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Classes.cs delete mode 100644 BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Drawing.cs delete mode 100644 BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.EventHandlers.cs delete mode 100644 BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Helpers.cs delete mode 100644 BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Properties.cs delete mode 100644 BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.cs diff --git a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.API.cs b/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.API.cs deleted file mode 100644 index af741013fc..0000000000 --- a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.API.cs +++ /dev/null @@ -1,183 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// A performant VirtualListView implementation that doesn't rely on native Win32 API calls - /// (and in fact does not inherit the ListView class at all) - /// It is an enhanced version of the work done with GDI+ rendering in InputRoll.cs - /// ------------------- - /// *** API Related *** - /// ------------------- - /// - public partial class PlatformAgnosticVirtualListView - { - private Cell _draggingCell; - - #region Methods - - /// - /// Parent form calls this to add columns - /// - /// - /// - /// - /// - public void AddColumn(string columnName, string columnText, int columnWidth, ListColumn.InputType columnType = ListColumn.InputType.Boolean) - { - if (AllColumns[columnName] == null) - { - var column = new ListColumn - { - Name = columnName, - Text = columnText, - Width = columnWidth, - Type = columnType - }; - - AllColumns.Add(column); - } - } - - /// - /// Sets the state of the passed row index - /// - /// - /// - public void SelectItem(int index, bool val) - { - if (_columns.VisibleColumns.Any()) - { - if (val) - { - SelectCell(new Cell - { - RowIndex = index, - Column = _columns[0] - }); - } - else - { - IEnumerable items = _selectedItems.Where(cell => cell.RowIndex == index); - _selectedItems.RemoveWhere(items.Contains); - } - } - } - - public void SelectAll() - { - var oldFullRowVal = FullRowSelect; - FullRowSelect = true; - for (int i = 0; i < ItemCount; i++) - { - SelectItem(i, true); - } - - FullRowSelect = oldFullRowVal; - } - - public void DeselectAll() - { - _selectedItems.Clear(); - } - - public void TruncateSelection(int index) - { - _selectedItems.RemoveWhere(cell => cell.RowIndex > index); - } - - public bool IsVisible(int index) - { - return (index >= FirstVisibleRow) && (index <= LastFullyVisibleRow); - } - - public bool IsPartiallyVisible(int index) - { - return index >= FirstVisibleRow && index <= LastVisibleRow; - } - - public void DragCurrentCell() - { - _draggingCell = CurrentCell; - } - - public void ReleaseCurrentCell() - { - if (_draggingCell != null) - { - var draggedCell = _draggingCell; - _draggingCell = null; - - if (CurrentCell != draggedCell) - { - CellDropped?.Invoke(this, new CellEventArgs(draggedCell, CurrentCell)); - } - } - } - - /// - /// Scrolls to the given index, according to the scroll settings. - /// - public void ScrollToIndex(int index) - { - if (ScrollMethod == "near") - { - MakeIndexVisible(index); - } - - if (!IsVisible(index) || AlwaysScroll) - { - if (ScrollMethod == "top") - { - FirstVisibleRow = index; - } - else if (ScrollMethod == "bottom") - { - LastVisibleRow = index; - } - else if (ScrollMethod == "center") - { - FirstVisibleRow = Math.Max(index - (VisibleRows / 2), 0); - } - } - } - - /// - /// Scrolls so that the given index is visible, if it isn't already; doesn't use scroll settings. - /// - public void MakeIndexVisible(int index) - { - if (!IsVisible(index)) - { - if (FirstVisibleRow > index) - { - FirstVisibleRow = index; - } - else - { - LastVisibleRow = index; - } - } - } - - /// - /// Compatibility method from VirtualListView - /// - /// - public void ensureVisible() - { - if (_selectedItems.Count != 0) - MakeIndexVisible(_selectedItems.Last().RowIndex.Value); - } - - public void ClearSelectedRows() - { - _selectedItems.Clear(); - } - - #endregion - } -} diff --git a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Classes.cs b/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Classes.cs deleted file mode 100644 index 9e3569e91e..0000000000 --- a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Classes.cs +++ /dev/null @@ -1,315 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Reflection; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// A performant VirtualListView implementation that doesn't rely on native Win32 API calls - /// (and in fact does not inherit the ListView class at all) - /// It is an enhanced version of the work done with GDI+ rendering in InputRoll.cs - /// --------------- - /// *** Classes *** - /// --------------- - /// - public partial class PlatformAgnosticVirtualListView - { - #region Event Args - - public class CellEventArgs - { - public CellEventArgs(Cell oldCell, Cell newCell) - { - OldCell = oldCell; - NewCell = newCell; - } - - public Cell OldCell { get; private set; } - public Cell NewCell { get; private set; } - } - - public class ColumnClickEventArgs - { - public ColumnClickEventArgs(ListColumn column) - { - Column = column; - } - - public ListColumn Column { get; private set; } - } - - public class ColumnReorderedEventArgs - { - public ColumnReorderedEventArgs(int oldDisplayIndex, int newDisplayIndex, ListColumn column) - { - Column = column; - OldDisplayIndex = oldDisplayIndex; - NewDisplayIndex = newDisplayIndex; - } - - public ListColumn Column { get; private set; } - public int OldDisplayIndex { get; private set; } - public int NewDisplayIndex { get; private set; } - } - - #endregion - - #region Columns - - public class ListColumn - { - public enum InputType { Boolean, Float, Text, Image } - - public int Index { get; set; } - public int OriginalIndex { get; set; } // for implementations that dont use ColumnReorderedEventArgs - public string Group { get; set; } - public int? Width { get; set; } - public int? Left { get; set; } - public int? Right { get; set; } - public string Name { get; set; } - public string Text { get; set; } - public InputType Type { get; set; } - public bool Visible { get; set; } - - /// - /// Column will be drawn with an emphasized look, if true - /// - private bool _emphasis; - public bool Emphasis - { - get { return _emphasis; } - set { _emphasis = value; } - } - - public ListColumn() - { - Visible = true; - } - } - - public class ListColumns : List - { - public ListColumn this[string name] - { - get - { - return this.SingleOrDefault(column => column.Name == name); - } - } - - public IEnumerable VisibleColumns - { - get - { - return this.Where(c => c.Visible); - } - } - - public Action ChangedCallback { get; set; } - - private void DoChangeCallback() - { - // no check will make it crash for user too, not sure which way of alarm we prefer. no alarm at all will cause all sorts of subtle bugs - if (ChangedCallback == null) - { - System.Diagnostics.Debug.Fail("ColumnChangedCallback has died!"); - } - else - { - ChangedCallback(); - } - } - - // TODO: this shouldn't be exposed. But in order to not expose it, each RollColumn must have a change callback, and all property changes must call it, it is quicker and easier to just call this when needed - public void ColumnsChanged() - { - int pos = 0; - - var columns = VisibleColumns.ToList(); - - for (int i = 0; i < columns.Count; i++) - { - columns[i].Left = pos; - pos += columns[i].Width.Value; - columns[i].Right = pos; - } - - DoChangeCallback(); - } - - public new void Add(ListColumn column) - { - if (this.Any(c => c.Name == column.Name)) - { - // The designer sucks, doing nothing for now - return; - //throw new InvalidOperationException("A column with this name already exists."); - } - - base.Add(column); - // save the original index for implementations that do not use ColumnReorderedEventArgs - column.OriginalIndex = this.IndexOf(column); - ColumnsChanged(); - } - - public new void AddRange(IEnumerable collection) - { - foreach (var column in collection) - { - if (this.Any(c => c.Name == column.Name)) - { - // The designer sucks, doing nothing for now - return; - - throw new InvalidOperationException("A column with this name already exists."); - } - } - - base.AddRange(collection); - ColumnsChanged(); - } - - public new void Insert(int index, ListColumn column) - { - if (this.Any(c => c.Name == column.Name)) - { - throw new InvalidOperationException("A column with this name already exists."); - } - - base.Insert(index, column); - ColumnsChanged(); - } - - public new void InsertRange(int index, IEnumerable collection) - { - foreach (var column in collection) - { - if (this.Any(c => c.Name == column.Name)) - { - throw new InvalidOperationException("A column with this name already exists."); - } - } - - base.InsertRange(index, collection); - ColumnsChanged(); - } - - public new bool Remove(ListColumn column) - { - var result = base.Remove(column); - ColumnsChanged(); - return result; - } - - public new int RemoveAll(Predicate match) - { - var result = base.RemoveAll(match); - ColumnsChanged(); - return result; - } - - public new void RemoveAt(int index) - { - base.RemoveAt(index); - ColumnsChanged(); - } - - public new void RemoveRange(int index, int count) - { - base.RemoveRange(index, count); - ColumnsChanged(); - } - - public new void Clear() - { - base.Clear(); - ColumnsChanged(); - } - - public IEnumerable Groups - { - get - { - return this - .Select(x => x.Group) - .Distinct(); - } - } - } - - #endregion - - #region Cells - - /// - /// Represents a single cell of the Roll - /// - public class Cell - { - public ListColumn Column { get; internal set; } - public int? RowIndex { get; internal set; } - public string CurrentText { get; internal set; } - - public Cell() { } - - public Cell(Cell cell) - { - Column = cell.Column; - RowIndex = cell.RowIndex; - } - - public bool IsDataCell => Column != null && RowIndex.HasValue; - - public override bool Equals(object obj) - { - if (obj is Cell) - { - var cell = obj as Cell; - return this.Column == cell.Column && this.RowIndex == cell.RowIndex; - } - - return base.Equals(obj); - } - - public override int GetHashCode() - { - return Column.GetHashCode() + RowIndex.GetHashCode(); - } - } - - private class SortCell : IComparer - { - int IComparer.Compare(Cell a, Cell b) - { - Cell c1 = a as Cell; - Cell c2 = b as Cell; - if (c1.RowIndex.HasValue) - { - if (c2.RowIndex.HasValue) - { - int row = c1.RowIndex.Value.CompareTo(c2.RowIndex.Value); - if (row == 0) - { - return c1.Column.Name.CompareTo(c2.Column.Name); - } - - return row; - } - - return 1; - } - - if (c2.RowIndex.HasValue) - { - return -1; - } - - return c1.Column.Name.CompareTo(c2.Column.Name); - } - } - - #endregion - } -} diff --git a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Drawing.cs b/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Drawing.cs deleted file mode 100644 index 96f0b1dd83..0000000000 --- a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Drawing.cs +++ /dev/null @@ -1,531 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// A performant VirtualListView implementation that doesn't rely on native Win32 API calls - /// (and in fact does not inherit the ListView class at all) - /// It is an enhanced version of the work done with GDI+ rendering in InputRoll.cs - /// ------------------------------ - /// *** GDI+ Rendering Methods *** - /// ------------------------------ - /// - public partial class PlatformAgnosticVirtualListView - { - // reusable Pen and Brush objects - private Pen sPen = null; - private Brush sBrush = null; - - /// - /// Called when font sizes are changed - /// Recalculates cell sizes - /// - private void SetCharSize() - { - using (var g = CreateGraphics()) - { - var sizeC = Size.Round(g.MeasureString("A", ColumnHeaderFont)); - var sizeI = Size.Round(g.MeasureString("A", CellFont)); - if (sizeC.Width > sizeI.Width) - _charSize = sizeC; - else - _charSize = sizeI; - } - - UpdateCellSize(); - ColumnWidth = CellWidth; - ColumnHeight = CellHeight + 2; - } - - /// - /// We draw everthing manually and never call base.OnPaint() - /// - /// - protected override void OnPaint(PaintEventArgs e) - { - // white background - sBrush = new SolidBrush(Color.White); - sPen = new Pen(Color.White); - - Rectangle rect = e.ClipRectangle; - - e.Graphics.FillRectangle(sBrush, rect); - e.Graphics.Flush(); - - var visibleColumns = _columns.VisibleColumns.ToList(); - - if (visibleColumns.Any()) - { - DrawColumnBg(e, visibleColumns); - DrawColumnText(e, visibleColumns); - } - - // Background - DrawBg(e, visibleColumns); - - // Foreground - DrawData(e, visibleColumns); - - DrawColumnDrag(e); - DrawCellDrag(e); - - if (BorderSize > 0) - { - // apparently mono can sometimes call OnPaint before attached to the parent?? - if (this.Parent != null) - { - // paint parent border - using (var gParent = this.Parent.CreateGraphics()) - { - Pen borderPen = new Pen(BorderColor); - for (int b = 1, c = 1; b <= BorderSize; b++, c += 2) - { - gParent.DrawRectangle(borderPen, this.Left - b, this.Top - b, this.Width + c, this.Height + c); - } - } - } - } - } - - private void DrawColumnDrag(PaintEventArgs e) - { - if (_draggingCell != null) - { - var text = ""; - int offsetX = 0; - int offsetY = 0; - - QueryItemText?.Invoke(_draggingCell.RowIndex.Value, _columns.IndexOf(_draggingCell.Column), out text); - QueryItemTextAdvanced?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, out text, ref offsetX, ref offsetY); - - Color bgColor = ColumnHeaderBackgroundColor; - QueryItemBkColor?.Invoke(_draggingCell.RowIndex.Value, _columns.IndexOf(_draggingCell.Column), ref bgColor); - QueryItemBkColorAdvanced?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, ref bgColor); - - int x1 = _currentX.Value - (_draggingCell.Column.Width.Value / 2); - int y1 = _currentY.Value - (CellHeight / 2); - int x2 = x1 + _draggingCell.Column.Width.Value; - int y2 = y1 + CellHeight; - - sBrush = new SolidBrush(bgColor); - e.Graphics.FillRectangle(sBrush, x1, y1, x2 - x1, y2 - y1); - sBrush = new SolidBrush(ColumnHeaderFontColor); - e.Graphics.DrawString(text, ColumnHeaderFont, sBrush, (PointF)(new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY))); - } - } - - private void DrawCellDrag(PaintEventArgs e) - { - if (_draggingCell != null) - { - var text = ""; - int offsetX = 0; - int offsetY = 0; - QueryItemText?.Invoke(_draggingCell.RowIndex.Value, _columns.IndexOf(_draggingCell.Column), out text); - QueryItemTextAdvanced?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, out text, ref offsetX, ref offsetY); - - Color bgColor = CellBackgroundColor; - QueryItemBkColor?.Invoke(_draggingCell.RowIndex.Value, _columns.IndexOf(_draggingCell.Column), ref bgColor); - QueryItemBkColorAdvanced?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, ref bgColor); - - int x1 = _currentX.Value - (_draggingCell.Column.Width.Value / 2); - int y1 = _currentY.Value - (CellHeight / 2); - int x2 = x1 + _draggingCell.Column.Width.Value; - int y2 = y1 + CellHeight; - - sBrush = new SolidBrush(bgColor); - e.Graphics.FillRectangle(sBrush, x1, y1, x2 - x1, y2 - y1); - sBrush = new SolidBrush(CellFontColor); - e.Graphics.DrawString(text, CellFont, sBrush, (PointF)(new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY))); - } - } - - private void DrawColumnText(PaintEventArgs e, List visibleColumns) - { - sBrush = new SolidBrush(ColumnHeaderFontColor); - - foreach (var column in visibleColumns) - { - var point = new Point(column.Left.Value + CellWidthPadding - _hBar.Value, CellHeightPadding); - - string t = column.Text; - ResizeTextToFit(ref t, column.Width.Value, ColumnHeaderFont); - - if (IsHoveringOnColumnCell && column == CurrentCell.Column) - { - sBrush = new SolidBrush(InvertColor(ColumnHeaderBackgroundHighlightColor)); - e.Graphics.DrawString(t, ColumnHeaderFont, sBrush, (PointF)(point)); - sBrush = new SolidBrush(ColumnHeaderFontColor); - } - else - { - e.Graphics.DrawString(t, ColumnHeaderFont, sBrush, (PointF)(point)); - } - } - } - - private void DrawData(PaintEventArgs e, List visibleColumns) - { - // Prevent exceptions with small windows - if (visibleColumns.Count == 0) - { - return; - } - - if (QueryItemText != null || QueryItemTextAdvanced != null) - { - int startRow = FirstVisibleRow; - int range = Math.Min(LastVisibleRow, ItemCount - 1) - startRow + 1; - - sBrush = new SolidBrush(CellFontColor); - - int xPadding = CellWidthPadding + 1 - _hBar.Value; - for (int i = 0, f = 0; f < range; i++, f++) // Vertical - { - //f += _lagFrames[i]; - int LastVisible = LastVisibleColumnIndex; - for (int j = FirstVisibleColumn; j <= LastVisible; j++) // Horizontal - { - ListColumn col = visibleColumns[j]; - - string text = ""; - int strOffsetX = 0; - int strOffsetY = 0; - Point point = new Point(col.Left.Value + xPadding, RowsToPixels(i) + CellHeightPadding); - - Bitmap image = null; - int bitmapOffsetX = 0; - int bitmapOffsetY = 0; - - QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY); - - if (image != null) - { - e.Graphics.DrawImage(image, new Point(point.X + bitmapOffsetX, point.Y + bitmapOffsetY + CellHeightPadding)); - } - - QueryItemText?.Invoke(f + startRow, _columns.IndexOf(visibleColumns[j]), out text); - QueryItemTextAdvanced?.Invoke(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY); - - bool rePrep = false; - if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = f + startRow })) - { - sBrush = new SolidBrush(InvertColor(CellBackgroundHighlightColor)); - rePrep = true; - } - - if (!string.IsNullOrWhiteSpace(text)) - { - ResizeTextToFit(ref text, col.Width.Value, CellFont); - e.Graphics.DrawString(text, CellFont, sBrush, (PointF)(new Point(point.X + strOffsetX, point.Y + strOffsetY))); - } - - if (rePrep) - { - sBrush = new SolidBrush(CellFontColor); - } - } - } - } - } - - private void ResizeTextToFit(ref string text, int destinationSize, Font font) - { - Size strLen; - using (var g = CreateGraphics()) - { - strLen = Size.Round(g.MeasureString(text, font)); - } - if (strLen.Width > destinationSize - CellWidthPadding) - { - // text needs trimming - List chars = new List(); - - for (int s = 0; s < text.Length; s++) - { - chars.Add(text[s]); - Size tS; - Size dotS; - using (var g = CreateGraphics()) - { - tS = Size.Round(g.MeasureString(new string(chars.ToArray()), CellFont)); - dotS = Size.Round(g.MeasureString(".", CellFont)); - } - int dotWidth = dotS.Width * 3; - if (tS.Width >= destinationSize - CellWidthPadding - dotWidth) - { - text = new string(chars.ToArray()) + "..."; - break; - } - } - } - } - - // https://stackoverflow.com/a/34107015/6813055 - private Color InvertColor(Color color) - { - var inverted = Color.FromArgb(color.ToArgb() ^ 0xffffff); - - if (inverted.R > 110 && inverted.R < 150 && - inverted.G > 110 && inverted.G < 150 && - inverted.B > 110 && inverted.B < 150) - { - int avg = (inverted.R + inverted.G + inverted.B) / 3; - avg = avg > 128 ? 200 : 60; - inverted = Color.FromArgb(avg, avg, avg); - } - - return inverted; - } - - private void DrawColumnBg(PaintEventArgs e, List visibleColumns) - { - sBrush = new SolidBrush(ColumnHeaderBackgroundColor); - sPen = new Pen(ColumnHeaderOutlineColor); - - int bottomEdge = RowsToPixels(0); - - // Gray column box and black line underneath - e.Graphics.FillRectangle(sBrush, 0, 0, Width + 1, bottomEdge + 1); - e.Graphics.DrawLine(sPen, 0, 0, TotalColWidth.Value + 1, 0); - e.Graphics.DrawLine(sPen, 0, bottomEdge, TotalColWidth.Value + 1, bottomEdge); - - // Vertical black seperators - for (int i = 0; i < visibleColumns.Count; i++) - { - int pos = visibleColumns[i].Left.Value - _hBar.Value; - e.Graphics.DrawLine(sPen, pos, 0, pos, bottomEdge); - } - - // Draw right most line - if (visibleColumns.Any()) - { - int right = TotalColWidth.Value - _hBar.Value; - e.Graphics.DrawLine(sPen, right, 0, right, bottomEdge); - } - - // Emphasis - foreach (var column in visibleColumns.Where(c => c.Emphasis)) - { - sBrush = new SolidBrush(SystemColors.ActiveBorder); - e.Graphics.FillRectangle(sBrush, column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, ColumnHeight - 1); - } - - // If the user is hovering over a column - if (IsHoveringOnColumnCell) - { - // TODO multiple selected columns - for (int i = 0; i < visibleColumns.Count; i++) - { - if (visibleColumns[i] == CurrentCell.Column) - { - // Left of column is to the right of the viewable area or right of column is to the left of the viewable area - if (visibleColumns[i].Left.Value - _hBar.Value > Width || visibleColumns[i].Right.Value - _hBar.Value < 0) - { - continue; - } - - int left = visibleColumns[i].Left.Value - _hBar.Value; - int width = visibleColumns[i].Right.Value - _hBar.Value - left; - - if (CurrentCell.Column.Emphasis) - { - sBrush = new SolidBrush(Color.FromArgb(ColumnHeaderBackgroundHighlightColor.ToArgb() + 0x00550000)); - } - else - { - sBrush = new SolidBrush(ColumnHeaderBackgroundHighlightColor); - } - - e.Graphics.FillRectangle(sBrush, left + 1, 1, width - 1, ColumnHeight - 1); - } - } - } - } - - // TODO refactor this and DoBackGroundCallback functions. - /// - /// Draw Gridlines and background colors using QueryItemBkColor. - /// - private void DrawBg(PaintEventArgs e, List visibleColumns) - { - if (UseCustomBackground && QueryItemBkColor != null) - { - DoBackGroundCallback(e, visibleColumns); - } - - if (GridLines) - { - sPen = new Pen(GridLineColor); - - // Columns - int y = ColumnHeight + 1; - int? totalColWidth = TotalColWidth; - foreach (var column in visibleColumns) - { - int x = column.Left.Value - _hBar.Value; - e.Graphics.DrawLine(sPen, x, y, x, Height - 1); - } - - if (visibleColumns.Any()) - { - e.Graphics.DrawLine(sPen, totalColWidth.Value - _hBar.Value, y, totalColWidth.Value - _hBar.Value, Height - 1); - } - - // Rows - for (int i = 1; i < VisibleRows + 1; i++) - { - e.Graphics.DrawLine(sPen, 0, RowsToPixels(i), Width + 1, RowsToPixels(i)); - } - } - - if (_selectedItems.Any() && !HideSelection) - { - DoSelectionBG(e, visibleColumns); - } - } - - /// - /// Given a cell with rowindex inbetween 0 and VisibleRows, it draws the background color specified. Do not call with absolute rowindices. - /// - private void DrawCellBG(PaintEventArgs e, Color color, Cell cell, List visibleColumns) - { - int x, y, w, h; - - w = cell.Column.Width.Value - 1; - x = cell.Column.Left.Value - _hBar.Value + 1; - y = RowsToPixels(cell.RowIndex.Value) + 1; // We can't draw without row and column, so assume they exist and fail catastrophically if they don't - h = CellHeight - 1; - if (y < ColumnHeight) - { - return; - } - - if (x > DrawWidth || y > DrawHeight) - { - return; - } // Don't draw if off screen. - - var col = cell.Column.Name; - if (color.A == 0) - { - sBrush = new SolidBrush(Color.FromArgb(255, color)); - } - else - { - sBrush = new SolidBrush(color); - } - - e.Graphics.FillRectangle(sBrush, x, y, w, h); - } - - protected override void OnPaintBackground(PaintEventArgs pevent) - { - // Do nothing, and this should never be called - } - - private void DoSelectionBG(PaintEventArgs e, List visibleColumns) - { - // SuuperW: This allows user to see other colors in selected frames. - Color rowColor = CellBackgroundColor; // Color.White; - int _lastVisibleRow = LastVisibleRow; - int lastRow = -1; - foreach (Cell cell in _selectedItems) - { - if (cell.RowIndex > _lastVisibleRow || cell.RowIndex < FirstVisibleRow || !VisibleColumns.Contains(cell.Column)) - { - continue; - } - - Cell relativeCell = new Cell - { - RowIndex = cell.RowIndex - FirstVisibleRow, - Column = cell.Column, - }; - - if (QueryRowBkColor != null && lastRow != cell.RowIndex.Value) - { - QueryRowBkColor(cell.RowIndex.Value, ref rowColor); - lastRow = cell.RowIndex.Value; - } - - Color cellColor = rowColor; - QueryItemBkColor?.Invoke(cell.RowIndex.Value, _columns.IndexOf(cell.Column), ref cellColor); - QueryItemBkColorAdvanced?.Invoke(cell.RowIndex.Value, cell.Column, ref cellColor); - - // Alpha layering for cell before selection - float alpha = (float)cellColor.A / 255; - if (cellColor.A != 255 && cellColor.A != 0) - { - cellColor = Color.FromArgb(rowColor.R - (int)((rowColor.R - cellColor.R) * alpha), - rowColor.G - (int)((rowColor.G - cellColor.G) * alpha), - rowColor.B - (int)((rowColor.B - cellColor.B) * alpha)); - } - - // Alpha layering for selection - alpha = 0.85f; - cellColor = Color.FromArgb(cellColor.R - (int)((cellColor.R - CellBackgroundHighlightColor.R) * alpha), - cellColor.G - (int)((cellColor.G - CellBackgroundHighlightColor.G) * alpha), - cellColor.B - (int)((cellColor.B - CellBackgroundHighlightColor.B) * alpha)); - - DrawCellBG(e, cellColor, relativeCell, visibleColumns); - } - } - - /// - /// Calls QueryItemBkColor callback for all visible cells and fills in the background of those cells. - /// - /// - private void DoBackGroundCallback(PaintEventArgs e, List visibleColumns) - { - int startIndex = FirstVisibleRow; - int range = Math.Min(LastVisibleRow, ItemCount - 1) - startIndex + 1; - int lastVisible = LastVisibleColumnIndex; - int firstVisibleColumn = FirstVisibleColumn; - // Prevent exceptions with small windows - if (firstVisibleColumn < 0) - { - return; - } - for (int i = 0, f = 0; f < range; i++, f++) // Vertical - { - //f += _lagFrames[i]; - - Color rowColor = CellBackgroundColor; - QueryRowBkColor?.Invoke(f + startIndex, ref rowColor); - - for (int j = FirstVisibleColumn; j <= lastVisible; j++) // Horizontal - { - Color itemColor = CellBackgroundColor; - QueryItemBkColor?.Invoke(f + startIndex, _columns.IndexOf(visibleColumns[j]), ref itemColor); - QueryItemBkColorAdvanced?.Invoke(f + startIndex, visibleColumns[j], ref itemColor); - if (itemColor == CellBackgroundColor) - { - itemColor = rowColor; - } - else if (itemColor.A != 255 && itemColor.A != 0) - { - float alpha = (float)itemColor.A / 255; - itemColor = Color.FromArgb(rowColor.R - (int)((rowColor.R - itemColor.R) * alpha), - rowColor.G - (int)((rowColor.G - itemColor.G) * alpha), - rowColor.B - (int)((rowColor.B - itemColor.B) * alpha)); - } - - if (itemColor != Color.White) // An easy optimization, don't draw unless the user specified something other than the default - { - var cell = new Cell - { - Column = visibleColumns[j], - RowIndex = i - }; - DrawCellBG(e, itemColor, cell, visibleColumns); - } - } - } - } - } -} diff --git a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.EventHandlers.cs b/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.EventHandlers.cs deleted file mode 100644 index 6bfa01ccb2..0000000000 --- a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.EventHandlers.cs +++ /dev/null @@ -1,703 +0,0 @@ -using System; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// A performant VirtualListView implementation that doesn't rely on native Win32 API calls - /// (and in fact does not inherit the ListView class at all) - /// It is an enhanced version of the work done with GDI+ rendering in InputRoll.cs - /// ----------------------------------- - /// *** Events *** - /// ----------------------------------- - /// - public partial class PlatformAgnosticVirtualListView - { - #region Event Handlers - - /// - /// Fire the event which requests the text for the passed cell - /// - [Category("Virtual")] - public event QueryItemTextHandler QueryItemText; - - /// - /// Fire the event which requests the text for the passed cell - /// - [Category("Virtual")] - public event QueryItemTextHandlerAdvanced QueryItemTextAdvanced; - - /// - /// Fire the event which requests the background color for the passed cell - /// - [Category("Virtual")] - public event QueryItemBkColorHandler QueryItemBkColor; - - /// - /// Fire the event which requests the background color for the passed cell - /// - [Category("Virtual")] - public event QueryItemBkColorHandlerAdvanced QueryItemBkColorAdvanced; - - [Category("Virtual")] - public event QueryRowBkColorHandler QueryRowBkColor; - - /// - /// Fire the event which requests an icon for a given cell - /// - [Category("Virtual")] - public event QueryItemIconHandler QueryItemIcon; - - /// - /// Fires when the mouse moves from one cell to another (including column header cells) - /// - [Category("Mouse")] - public event CellChangeEventHandler PointedCellChanged; - - /// - /// Fires when a cell is hovered on - /// - [Category("Mouse")] - public event HoverEventHandler CellHovered; - - /// - /// Occurs when a column header is clicked - /// - [Category("Action")] - public event ColumnClickEventHandler ColumnClick; - - /// - /// Occurs when a column header is right-clicked - /// - [Category("Action")] - public event ColumnClickEventHandler ColumnRightClick; - - /// - /// Occurs whenever the 'SelectedItems' property for this control changes - /// - [Category("Behavior")] - public event EventHandler SelectedIndexChanged; - - /// - /// Occurs whenever the mouse wheel is scrolled while the right mouse button is held - /// - [Category("Behavior")] - public event RightMouseScrollEventHandler RightMouseScrolled; - - [Category("Property Changed")] - [Description("Occurs when the column header has been reordered")] - public event ColumnReorderedEventHandler ColumnReordered; - - [Category("Action")] - [Description("Occurs when the scroll value of the visible rows change (in vertical orientation this is the vertical scroll bar change, and in horizontal it is the horizontal scroll bar)")] - public event RowScrollEvent RowScroll; - - [Category("Action")] - [Description("Occurs when the scroll value of the columns (in vertical orientation this is the horizontal scroll bar change, and in horizontal it is the vertical scroll bar)")] - public event ColumnScrollEvent ColumnScroll; - - [Category("Action")] - [Description("Occurs when a cell is dragged and then dropped into a new cell, old cell is the cell that was being dragged, new cell is its new destination")] - public event CellDroppedEvent CellDropped; - - #endregion - - #region Delegates - - /// - /// Retrieve the text for a cell - /// - public delegate void QueryItemTextHandlerAdvanced(int index, ListColumn column, out string text, ref int offsetX, ref int offsetY); - public delegate void QueryItemTextHandler(int index, int column, out string text); - - /// - /// Retrieve the background color for a cell - /// - public delegate void QueryItemBkColorHandlerAdvanced(int index, ListColumn column, ref Color color); - public delegate void QueryItemBkColorHandler(int index, int column, ref Color color); - public delegate void QueryRowBkColorHandler(int index, ref Color color); - - /// - /// Retrieve the image for a given cell - /// - public delegate void QueryItemIconHandler(int index, ListColumn column, ref Bitmap icon, ref int offsetX, ref int offsetY); - - public delegate void CellChangeEventHandler(object sender, CellEventArgs e); - - public delegate void HoverEventHandler(object sender, CellEventArgs e); - - public delegate void RightMouseScrollEventHandler(object sender, MouseEventArgs e); - - public delegate void ColumnClickEventHandler(object sender, ColumnClickEventArgs e); - - public delegate void ColumnReorderedEventHandler(object sender, ColumnReorderedEventArgs e); - - public delegate void RowScrollEvent(object sender, EventArgs e); - - public delegate void ColumnScrollEvent(object sender, EventArgs e); - - public delegate void CellDroppedEvent(object sender, CellEventArgs e); - - #endregion - - #region Mouse and Key Events - - private bool _columnDownMoved; - - protected override void OnMouseMove(MouseEventArgs e) - { - _currentX = e.X; - _currentY = e.Y; - - if (_columnDown != null) - { - _columnDownMoved = true; - } - - Cell newCell = CalculatePointedCell(_currentX.Value, _currentY.Value); - - newCell.RowIndex += FirstVisibleRow; - if (newCell.RowIndex < 0) - { - newCell.RowIndex = 0; - } - - if (!newCell.Equals(CurrentCell)) - { - CellChanged(newCell); - - if (IsHoveringOnColumnCell || - (WasHoveringOnColumnCell && !IsHoveringOnColumnCell)) - { - Refresh(); - } - else if (_columnDown != null) - { - Refresh(); - } - } - else if (_columnDown != null) // Kind of silly feeling to have this check twice, but the only alternative I can think of has it refreshing twice when pointed column changes with column down, and speed matters - { - Refresh(); - } - - if (_columnSeparatorDown != null) - { - // column is being resized - DoColumnResize(); - Refresh(); - } - - // cursor changes - if (IsHoveringOnDraggableColumnDivide && AllowColumnResize) - Cursor.Current = Cursors.VSplit; - else if (IsHoveringOnColumnCell && AllowColumnReorder) - Cursor.Current = Cursors.Hand; - else - Cursor.Current = Cursors.Default; - - base.OnMouseMove(e); - } - - protected override void OnMouseEnter(EventArgs e) - { - CurrentCell = new Cell - { - Column = null, - RowIndex = null - }; - - base.OnMouseEnter(e); - } - - protected override void OnMouseLeave(EventArgs e) - { - _currentX = null; - _currentY = null; - CurrentCell = null; - IsPaintDown = false; - _hoverTimer.Stop(); - Cursor.Current = Cursors.Default; - Refresh(); - base.OnMouseLeave(e); - } - - // TODO add query callback of whether to select the cell or not - protected override void OnMouseDown(MouseEventArgs e) - { - if (!GlobalWin.MainForm.EmulatorPaused && _currentX.HasValue) - { - // copypaste from OnMouseMove() - Cell newCell = CalculatePointedCell(_currentX.Value, _currentY.Value); - - newCell.RowIndex += FirstVisibleRow; - if (newCell.RowIndex < 0) - { - newCell.RowIndex = 0; - } - - if (!newCell.Equals(CurrentCell)) - { - CellChanged(newCell); - - if (IsHoveringOnColumnCell || - (WasHoveringOnColumnCell && !IsHoveringOnColumnCell)) - { - Refresh(); - } - else if (_columnDown != null) - { - Refresh(); - } - } - else if (_columnDown != null) - { - Refresh(); - } - } - - if (e.Button == MouseButtons.Left) - { - if (IsHoveringOnDraggableColumnDivide && AllowColumnResize) - { - _columnSeparatorDown = ColumnAtX(_currentX.Value); - } - else if (IsHoveringOnColumnCell && AllowColumnReorder) - { - _columnDown = CurrentCell.Column; - } - else if (InputPaintingMode) - { - IsPaintDown = true; - } - } - - if (e.Button == MouseButtons.Right) - { - if (!IsHoveringOnColumnCell) - { - RightButtonHeld = true; - } - } - - if (e.Button == MouseButtons.Left) - { - if (IsHoveringOnDataCell) - { - if (ModifierKeys == Keys.Alt) - { - // do marker drag here - } - else if (ModifierKeys == Keys.Shift && (CurrentCell.Column.Type == ListColumn.InputType.Text)) - { - if (_selectedItems.Any()) - { - if (FullRowSelect) - { - var selected = _selectedItems.Any(c => c.RowIndex.HasValue && CurrentCell.RowIndex.HasValue && c.RowIndex == CurrentCell.RowIndex); - - if (!selected) - { - var rowIndices = _selectedItems - .Where(c => c.RowIndex.HasValue) - .Select(c => c.RowIndex ?? -1) - .Where(c => c >= 0) // Hack to avoid possible Nullable exceptions - .Distinct() - .ToList(); - - var firstIndex = rowIndices.Min(); - var lastIndex = rowIndices.Max(); - - if (CurrentCell.RowIndex.Value < firstIndex) - { - for (int i = CurrentCell.RowIndex.Value; i < firstIndex; i++) - { - SelectCell(new Cell - { - RowIndex = i, - Column = CurrentCell.Column - }); - } - } - else if (CurrentCell.RowIndex.Value > lastIndex) - { - for (int i = lastIndex + 1; i <= CurrentCell.RowIndex.Value; i++) - { - SelectCell(new Cell - { - RowIndex = i, - Column = CurrentCell.Column - }); - } - } - else // Somewhere in between, a scenario that can happen with ctrl-clicking, find the previous and highlight from there - { - var nearest = rowIndices - .Where(x => x < CurrentCell.RowIndex.Value) - .Max(); - - for (int i = nearest + 1; i <= CurrentCell.RowIndex.Value; i++) - { - SelectCell(new Cell - { - RowIndex = i, - Column = CurrentCell.Column - }); - } - } - } - } - else - { - MessageBox.Show("Shift click logic for individual cells has not yet implemented"); - } - } - else - { - SelectCell(CurrentCell); - } - } - else if (ModifierKeys == Keys.Control && (CurrentCell.Column.Type == ListColumn.InputType.Text)) - { - SelectCell(CurrentCell, toggle: true); - } - else if (ModifierKeys != Keys.Shift) - { - var hadIndex = _selectedItems.Any(); - _selectedItems.Clear(); - SelectCell(CurrentCell); - } - - Refresh(); - - SelectedIndexChanged?.Invoke(this, new EventArgs()); - } - } - - base.OnMouseDown(e); - - if (AllowRightClickSelecton && e.Button == MouseButtons.Right) - { - if (!IsHoveringOnColumnCell) - { - _currentX = e.X; - _currentY = e.Y; - Cell newCell = CalculatePointedCell(_currentX.Value, _currentY.Value); - newCell.RowIndex += FirstVisibleRow; - CellChanged(newCell); - SelectCell(CurrentCell); - } - } - } - - protected override void OnMouseUp(MouseEventArgs e) - { - if (_columnSeparatorDown != null && AllowColumnResize) - { - DoColumnResize(); - Refresh(); - } - else if (IsHoveringOnColumnCell && AllowColumnReorder) - { - if (_columnDown != null && _columnDownMoved) - { - DoColumnReorder(); - _columnDown = null; - Refresh(); - } - else if (e.Button == MouseButtons.Left) - { - ColumnClickEvent(ColumnAtX(e.X)); - } - else if (e.Button == MouseButtons.Right) - { - ColumnRightClickEvent(ColumnAtX(e.X)); - } - } - - _columnDown = null; - _columnDownMoved = false; - _columnSeparatorDown = null; - RightButtonHeld = false; - IsPaintDown = false; - base.OnMouseUp(e); - } - - private void IncrementScrollBar(ScrollBar bar, bool increment) - { - int newVal; - if (increment) - { - newVal = bar.Value + (bar.SmallChange * ScrollSpeed); - if (newVal > bar.Maximum - bar.LargeChange) - { - newVal = bar.Maximum - bar.LargeChange; - } - } - else - { - newVal = bar.Value - (bar.SmallChange * ScrollSpeed); - if (newVal < 0) - { - newVal = 0; - } - } - - _programmaticallyUpdatingScrollBarValues = true; - bar.Value = newVal; - _programmaticallyUpdatingScrollBarValues = false; - } - - protected override void OnMouseWheel(MouseEventArgs e) - { - IncrementScrollBar(_vBar, e.Delta < 0); - if (_currentX != null) - { - OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, _currentX.Value, _currentY.Value, 0)); - } - - Refresh(); - } - - private void DoRightMouseScroll(object sender, MouseEventArgs e) - { - RightMouseScrolled?.Invoke(sender, e); - } - - private void ColumnClickEvent(ListColumn column) - { - ColumnClick?.Invoke(this, new ColumnClickEventArgs(column)); - } - - private void ColumnRightClickEvent(ListColumn column) - { - ColumnRightClick?.Invoke(this, new ColumnClickEventArgs(column)); - } - - protected override void OnKeyDown(KeyEventArgs e) - { - if (!SuspendHotkeys) - { - if (e.Control && !e.Alt && e.Shift && e.KeyCode == Keys.F) // Ctrl+Shift+F - { - //HorizontalOrientation ^= true; - } - // Scroll - else if (!e.Control && !e.Alt && !e.Shift && e.KeyCode == Keys.PageUp) // Page Up - { - if (FirstVisibleRow > 0) - { - LastVisibleRow = FirstVisibleRow; - Refresh(); - } - } - else if (!e.Control && !e.Alt && !e.Shift && e.KeyCode == Keys.PageDown) // Page Down - { - var totalRows = LastVisibleRow - FirstVisibleRow; - if (totalRows <= ItemCount) - { - var final = LastVisibleRow + totalRows; - if (final > ItemCount) - { - final = ItemCount; - } - - LastVisibleRow = final; - Refresh(); - } - } - else if (!e.Control && !e.Alt && !e.Shift && e.KeyCode == Keys.Home) // Home - { - FirstVisibleRow = 0; - Refresh(); - } - else if (!e.Control && !e.Alt && !e.Shift && e.KeyCode == Keys.End) // End - { - LastVisibleRow = ItemCount; - Refresh(); - } - else if (!e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Up) // Up - { - if (FirstVisibleRow > 0) - { - FirstVisibleRow--; - Refresh(); - } - } - else if (!e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Down) // Down - { - if (FirstVisibleRow < ItemCount - 1) - { - FirstVisibleRow++; - Refresh(); - } - } - // Selection courser - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Up) // Ctrl + Up - { - if (SelectedRows.Any() && LetKeysModifySelection && SelectedRows.First() > 0) - { - foreach (var row in SelectedRows.ToList()) - { - SelectItem(row - 1, true); - SelectItem(row, false); - } - } - } - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Down) // Ctrl + Down - { - if (SelectedRows.Any() && LetKeysModifySelection) - { - foreach (var row in SelectedRows.Reverse().ToList()) - { - SelectItem(row + 1, true); - SelectItem(row, false); - } - } - } - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Left) // Ctrl + Left - { - if (SelectedRows.Any() && LetKeysModifySelection) - { - SelectItem(SelectedRows.Last(), false); - } - } - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Right) // Ctrl + Right - { - if (SelectedRows.Any() && LetKeysModifySelection && SelectedRows.Last() < _itemCount - 1) - { - SelectItem(SelectedRows.Last() + 1, true); - } - } - else if (e.Control && e.Shift && !e.Alt && e.KeyCode == Keys.Left) // Ctrl + Shift + Left - { - if (SelectedRows.Any() && LetKeysModifySelection && SelectedRows.First() > 0) - { - SelectItem(SelectedRows.First() - 1, true); - } - } - else if (e.Control && e.Shift && !e.Alt && e.KeyCode == Keys.Right) // Ctrl + Shift + Right - { - if (SelectedRows.Any() && LetKeysModifySelection) - { - SelectItem(SelectedRows.First(), false); - } - } - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.PageUp) // Ctrl + Page Up - { - //jump to above marker with selection courser - if (LetKeysModifySelection) - { - - } - } - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.PageDown) // Ctrl + Page Down - { - //jump to below marker with selection courser - if (LetKeysModifySelection) - { - - } - - } - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Home) // Ctrl + Home - { - //move selection courser to frame 0 - if (LetKeysModifySelection) - { - DeselectAll(); - SelectItem(0, true); - } - } - else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.End) // Ctrl + End - { - //move selection courser to end of movie - if (LetKeysModifySelection) - { - DeselectAll(); - SelectItem(ItemCount - 1, true); - } - } - } - - base.OnKeyDown(e); - } - - #endregion - - #region Change Events - - protected override void OnResize(EventArgs e) - { - RecalculateScrollBars(); - if (BorderSize > 0 && this.Parent != null) - { - // refresh the parent control to regen the border - this.Parent.Refresh(); - } - base.OnResize(e); - Refresh(); - - - - } - - /// - /// Call this function to change the CurrentCell to newCell - /// - private void CellChanged(Cell newCell) - { - LastCell = CurrentCell; - CurrentCell = newCell; - - if (PointedCellChanged != null && - (LastCell.Column != CurrentCell.Column || LastCell.RowIndex != CurrentCell.RowIndex)) - { - PointedCellChanged(this, new CellEventArgs(LastCell, CurrentCell)); - } - - if (CurrentCell?.Column != null && CurrentCell.RowIndex.HasValue) - { - _hoverTimer.Start(); - } - else - { - _hoverTimer.Stop(); - } - } - - private void VerticalBar_ValueChanged(object sender, EventArgs e) - { - if (!_programmaticallyUpdatingScrollBarValues) - { - Refresh(); - } - - RowScroll?.Invoke(this, e); - } - - private void HorizontalBar_ValueChanged(object sender, EventArgs e) - { - if (!_programmaticallyUpdatingScrollBarValues) - { - Refresh(); - } - - ColumnScroll?.Invoke(this, e); - } - - private void ColumnChangedCallback() - { - RecalculateScrollBars(); - if (_columns.VisibleColumns.Any()) - { - ColumnWidth = _columns.VisibleColumns.Max(c => c.Width.Value) + CellWidthPadding * 4; - } - } - - #endregion - } -} diff --git a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Helpers.cs b/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Helpers.cs deleted file mode 100644 index 555c2bd141..0000000000 --- a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Helpers.cs +++ /dev/null @@ -1,359 +0,0 @@ -using System; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// A performant VirtualListView implementation that doesn't rely on native Win32 API calls - /// (and in fact does not inherit the ListView class at all) - /// It is an enhanced version of the work done with GDI+ rendering in InputRoll.cs - /// ---------------------- - /// *** Helper Methods *** - /// ---------------------- - /// - public partial class PlatformAgnosticVirtualListView - { - // TODO: Make into an extension method - private static Color Add(Color color, int val) - { - var col = color.ToArgb(); - col += val; - return Color.FromArgb(col); - } - - private void DoColumnReorder() - { - if (_columnDown != CurrentCell.Column) - { - var oldIndex = _columns.IndexOf(_columnDown); - var newIndex = _columns.IndexOf(CurrentCell.Column); - - ColumnReordered?.Invoke(this, new ColumnReorderedEventArgs(oldIndex, newIndex, _columnDown)); - - _columns.Remove(_columnDown); - _columns.Insert(newIndex, _columnDown); - } - } - - /// - /// Helper method for implementations that do not make use of ColumnReorderedEventArgs related callbacks - /// Basically, each column stores its initial index when added in .OriginalIndex - /// - /// - /// - public int GetOriginalColumnIndex(int currIndex) - { - return AllColumns[currIndex].OriginalIndex; - } - - // ScrollBar.Maximum = DesiredValue + ScrollBar.LargeChange - 1 - // See MSDN Page for more information on the dumb ScrollBar.Maximum Property - private void RecalculateScrollBars() - { - if (_vBar == null || _hBar == null) - return; - - UpdateDrawSize(); - - var columns = _columns.VisibleColumns.ToList(); - - if (CellHeight == 0) CellHeight++; - NeedsVScrollbar = ItemCount > 1; - NeedsHScrollbar = TotalColWidth.HasValue && TotalColWidth.Value - DrawWidth + 1 > 0; - - UpdateDrawSize(); - if (VisibleRows > 0) - { - _vBar.Maximum = Math.Max((VisibleRows - 1) * CellHeight, _vBar.Maximum); // ScrollBar.Maximum is dumb - _vBar.LargeChange = (VisibleRows - 1) * CellHeight; - // DrawWidth can be negative if the TAStudio window is small enough - // Clamp LargeChange to 0 here to prevent exceptions - _hBar.LargeChange = Math.Max(0, DrawWidth / 2); - } - - // Update VBar - if (NeedsVScrollbar) - { - _vBar.Maximum = RowsToPixels(ItemCount + 1) - (CellHeight * 3) + _vBar.LargeChange - 1; - - _vBar.Location = new Point(Width - _vBar.Width, 0); - _vBar.Height = Height; - _vBar.Visible = true; - } - else - { - _vBar.Visible = false; - _vBar.Value = 0; - } - - // Update HBar - if (NeedsHScrollbar) - { - _hBar.Maximum = TotalColWidth.Value - DrawWidth + _hBar.LargeChange; - - _hBar.Location = new Point(0, Height - _hBar.Height); - _hBar.Width = Width - (NeedsVScrollbar ? (_vBar.Width + 1) : 0); - _hBar.Visible = true; - } - else - { - _hBar.Visible = false; - _hBar.Value = 0; - } - } - - private void UpdateDrawSize() - { - if (NeedsVScrollbar) - { - DrawWidth = Width - _vBar.Width; - } - else - { - DrawWidth = Width; - } - if (NeedsHScrollbar) - { - DrawHeight = Height - _hBar.Height; - } - else - { - DrawHeight = Height; - } - } - - /// - /// If FullRowSelect is enabled, selects all cells in the row that contains the given cell. Otherwise only given cell is added. - /// - /// The cell to select. - private void SelectCell(Cell cell, bool toggle = false) - { - if (cell.RowIndex.HasValue && cell.RowIndex < ItemCount) - { - if (!MultiSelect) - { - _selectedItems.Clear(); - } - - if (FullRowSelect) - { - if (toggle && _selectedItems.Any(x => x.RowIndex.HasValue && x.RowIndex == cell.RowIndex)) - { - var items = _selectedItems - .Where(x => x.RowIndex.HasValue && x.RowIndex == cell.RowIndex) - .ToList(); - - foreach (var item in items) - { - _selectedItems.Remove(item); - } - } - else - { - foreach (var column in _columns) - { - _selectedItems.Add(new Cell - { - RowIndex = cell.RowIndex, - Column = column - }); - } - } - } - else - { - if (toggle && _selectedItems.Any(x => x.RowIndex.HasValue && x.RowIndex == cell.RowIndex)) - { - var item = _selectedItems - .FirstOrDefault(x => x.Equals(cell)); - - if (item != null) - { - _selectedItems.Remove(item); - } - } - else - { - _selectedItems.Add(CurrentCell); - } - } - } - } - - private bool IsHoveringOnDraggableColumnDivide => - IsHoveringOnColumnCell && - ((_currentX <= CurrentCell.Column.Left + 2 && CurrentCell.Column.Index != 0) || - (_currentX >= CurrentCell.Column.Right - 2 && CurrentCell.Column.Index != _columns.Count - 1)); - - private bool IsHoveringOnColumnCell => CurrentCell?.Column != null && !CurrentCell.RowIndex.HasValue; - - private bool IsHoveringOnDataCell => CurrentCell?.Column != null && CurrentCell.RowIndex.HasValue; - - private bool WasHoveringOnColumnCell => LastCell?.Column != null && !LastCell.RowIndex.HasValue; - - private bool WasHoveringOnDataCell => LastCell?.Column != null && LastCell.RowIndex.HasValue; - - /// - /// Finds the specific cell that contains the (x, y) coordinate. - /// - /// The row number that it returns will be between 0 and VisibleRows, NOT the absolute row number. - /// X coordinate point. - /// Y coordinate point. - /// The cell with row number and RollColumn reference, both of which can be null. - private Cell CalculatePointedCell(int x, int y) - { - var newCell = new Cell(); - var columns = _columns.VisibleColumns.ToList(); - - // If pointing to a column header - if (columns.Any()) - { - newCell.RowIndex = PixelsToRows(y); - newCell.Column = ColumnAtX(x); - } - - if (!(IsPaintDown || RightButtonHeld) && newCell.RowIndex <= -1) // -2 if we're entering from the top - { - newCell.RowIndex = null; - } - - return newCell; - } - - - private void CalculateColumnToResize() - { - // if this is reached, we are already over a selectable column divide - _columnSeparatorDown = ColumnAtX(_currentX.Value); - } - - private void DoColumnResize() - { - var widthChange = _currentX - _columnSeparatorDown.Right; - _columnSeparatorDown.Width += widthChange; - if (_columnSeparatorDown.Width < MinimumColumnSize) - _columnSeparatorDown.Width = MinimumColumnSize; - AllColumns.ColumnsChanged(); - } - - // A boolean that indicates if the InputRoll is too large vertically and requires a vertical scrollbar. - private bool NeedsVScrollbar { get; set; } - - // A boolean that indicates if the InputRoll is too large horizontally and requires a horizontal scrollbar. - private bool NeedsHScrollbar { get; set; } - - /// - /// Updates the width of the supplied column. - /// Call when changing the ColumnCell text, CellPadding, or text font. - /// - /// The RollColumn object to update. - /// The new width of the RollColumn object. - private int UpdateWidth(ListColumn col) - { - col.Width = (col.Text.Length * _charSize.Width) + (CellWidthPadding * 4); - return col.Width.Value; - } - - /// - /// Gets the total width of all the columns by using the last column's Right property. - /// - /// A nullable Int representing total width. - private int? TotalColWidth - { - get - { - if (_columns.VisibleColumns.Any()) - { - return _columns.VisibleColumns.Last().Right; - } - - return null; - } - } - - /// - /// Returns the RollColumn object at the specified visible x coordinate. Coordinate should be between 0 and Width of the InputRoll Control. - /// - /// The x coordinate. - /// RollColumn object that contains the x coordinate or null if none exists. - private ListColumn ColumnAtX(int x) - { - foreach (ListColumn column in _columns.VisibleColumns) - { - if (column.Left.Value - _hBar.Value <= x && column.Right.Value - _hBar.Value >= x) - { - return column; - } - } - - return null; - } - - /// - /// Converts a row number to a horizontal or vertical coordinate. - /// - /// A vertical coordinate if Vertical Oriented, otherwise a horizontal coordinate. - private int RowsToPixels(int index) - { - return (index * CellHeight) + ColumnHeight; - } - - /// - /// Converts a horizontal or vertical coordinate to a row number. - /// - /// A vertical coordinate if Vertical Oriented, otherwise a horizontal coordinate. - /// A row number between 0 and VisibleRows if it is a Datarow, otherwise a negative number if above all Datarows. - private int PixelsToRows(int pixels) - { - // Using Math.Floor and float because integer division rounds towards 0 but we want to round down. - if (CellHeight == 0) - CellHeight++; - - return (int)Math.Floor((float)(pixels - ColumnHeight) / CellHeight); - } - - // The width of the largest column cell in Horizontal Orientation - private int ColumnWidth { get; set; } - - // The height of a column cell in Vertical Orientation. - private int ColumnHeight { get; set; } - - // The width of a cell in Horizontal Orientation. Only can be changed by changing the Font or CellPadding. - private int CellWidth { get; set; } - - [Browsable(false)] - public int RowHeight => CellHeight; - - /// - /// Gets or sets a value indicating the height of a cell in Vertical Orientation. Only can be changed by changing the Font or CellPadding. - /// - private int CellHeight { get; set; } - - /// - /// Call when _charSize, MaxCharactersInHorizontal, or CellPadding is changed. - /// - private void UpdateCellSize() - { - CellHeight = _charSize.Height + (CellHeightPadding * 2); - CellWidth = (_charSize.Width/* * MaxCharactersInHorizontal*/) + (CellWidthPadding * 4); // Double the padding for horizontal because it looks better - } - /* - /// - /// Call when _charSize, MaxCharactersInHorizontal, or CellPadding is changed. - /// - private void UpdateColumnSize() - { - - } - */ - - // Number of displayed + hidden frames, if fps is as expected - private int ExpectedDisplayRange() - { - return (VisibleRows + 1); // * LagFramesToHide; - } - } -} diff --git a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Properties.cs b/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Properties.cs deleted file mode 100644 index 971f8c43aa..0000000000 --- a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.Properties.cs +++ /dev/null @@ -1,780 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// A performant VirtualListView implementation that doesn't rely on native Win32 API calls - /// (and in fact does not inherit the ListView class at all) - /// It is an enhanced version of the work done with GDI+ rendering in InputRoll.cs - /// ------------------------- - /// *** Public Properties *** - /// ------------------------- - /// - public partial class PlatformAgnosticVirtualListView - { - #region ListView Compatibility Properties - - /// - /// This VirtualListView implementation doesn't really need this, but it is here for compatibility - /// - [Category("Behavior")] - public int VirtualListSize - { - get - { - return _itemCount; - } - - set - { - _itemCount = value; - RecalculateScrollBars(); - } - } - - /// - /// ListView compatibility property - /// THIS DOES NOT WORK PROPERLY - AVOID! - /// - [System.ComponentModel.Browsable(false)] - public System.Windows.Forms.ListView.SelectedIndexCollection SelectedIndices - { - // !!! does not work properly, avoid using this in the calling implementation !!! - get - { - var tmpListView = new System.Windows.Forms.ListView(); - //tmpListView.VirtualMode = true; - //var selectedIndexCollection = new System.Windows.Forms.ListView.SelectedIndexCollection(tmpListView); - //tmpListView.VirtualListSize = ItemCount; - for (int i = 0; i < ItemCount; i++) - { - tmpListView.Items.Add(i.ToString()); - } - - //tmpListView.Refresh(); - - if (AnyRowsSelected) - { - var indices = SelectedRows.ToList(); - foreach (var i in indices) - { - tmpListView.SelectedIndices.Add(i); - //selectedIndexCollection.Add(i); - } - } - - return tmpListView.SelectedIndices; // selectedIndexCollection; - } - } - - /// - /// Compatibility property - /// With a standard ListView you can add columns in the Designer - /// We will ignore this (but leave it here for compatibility) - /// Columns must be added through the AddColumns() public method - /// - public System.Windows.Forms.ListView.ColumnHeaderCollection Columns = new System.Windows.Forms.ListView.ColumnHeaderCollection(new System.Windows.Forms.ListView()); - - /// - /// Compatibility with ListView class - /// This is not used in this implementation - /// - [Category("Behavior")] - public bool VirtualMode { get; set; } - - /// - /// Gets or sets a value indicating whether the selected item in the control remains highlighted when the control loses focus - /// - [Category("Behavior")] - public bool HideSelection { get; set; } - - /// - /// Gets or sets a value indicating whether the ListView uses state image behavior that is compatible with the .NET Framework 1.1 or the .NET Framework 2.0. - /// Here for ListView api compatibility (we dont care about this) - /// - [System.ComponentModel.Browsable(false)] - public bool UseCompatibleStateImageBehavior { get; set; } - - /// - /// Gets or sets how items are displayed in the control. - /// Here for ListView api compatibility (we dont care about this) - /// - public System.Windows.Forms.View View { get; set; } - - #endregion - - #region VirtualListView Compatibility Properties - - /// - /// Informs user that a select all event is in place, can be used in change events to wait until this is false - /// Not used in this implementation (yet) - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public bool SelectAllInProgress { get; set; } - - /// - /// Gets/Sets the selected item - /// Here for compatibility with VirtualListView.cs - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int selectedItem - { - get - { - if (SelectedRows.Count() == 0) - { - return -1; - } - else - { - return SelectedRows.First(); - } - } - set - { - SelectItem(value, true); - } - } - - [Category("Behavior")] - public bool BlazingFast { get; set; } - - #endregion - - #region Behavior - - /// - /// Gets or sets the amount of left and right padding on the text inside a cell - /// - [DefaultValue(3)] - [Category("Behavior")] - public int CellWidthPadding { get; set; } - - /// - /// Gets or sets the amount of top and bottom padding on the text inside a cell - /// - [DefaultValue(1)] - [Category("Behavior")] - public int CellHeightPadding { get; set; } - - /// - /// Gets or sets the scrolling speed - /// - [Category("Behavior")] - public int ScrollSpeed - { - get - { - if (CellHeight == 0) - CellHeight++; - return _vBar.SmallChange / CellHeight; - } - - set - { - _vBar.SmallChange = value * CellHeight; - } - } - - /// - /// Gets or sets a value indicating whether columns can be resized - /// - [Category("Behavior")] - [DefaultValue(true)] - public bool AllowColumnResize { get; set; } - - /// - /// Gets or sets a value indicating whether columns can be reordered - /// - [Category("Behavior")] - [DefaultValue(true)] - public bool AllowColumnReorder { get; set; } - - /// - /// Gets or sets a value indicating whether multiple items can to be selected - /// - [Category("Behavior")] - [DefaultValue(true)] - public bool MultiSelect { get; set; } - - /// - /// Gets or sets a value indicating whether the control is in input painting mode - /// - [Category("Behavior")] - [DefaultValue(false)] - public bool InputPaintingMode { get; set; } - - /// - /// Gets or sets how the InputRoll scrolls when calling ScrollToIndex. - /// - [DefaultValue("near")] - [Category("Behavior")] - public string ScrollMethod { get; set; } - - /// - /// Gets or sets a value indicating how the Intever for the hover event - /// - [DefaultValue(false)] - [Category("Behavior")] - public bool AlwaysScroll { get; set; } - - /// - /// Gets or sets the lowest seek interval to activate the progress bar - /// - [Category("Behavior")] - public int SeekingCutoffInterval { get; set; } - - [DefaultValue(750)] - [Category("Behavior")] - public int HoverInterval - { - get { return _hoverTimer.Interval; } - set { _hoverTimer.Interval = value; } - } - - /// - /// Gets or sets whether you can use right click to select things - /// - [Category("Behavior")] - public bool AllowRightClickSelecton { get; set; } - - /// - /// Gets or sets whether keys can modify selection - /// - [Category("Behavior")] - public bool LetKeysModifySelection { get; set; } - - /// - /// Gets or sets whether hot keys are suspended - /// - [Category("Behavior")] - public bool SuspendHotkeys { get; set; } - - #endregion - - #region Appearance - - /// - /// Gets or sets a value indicating whether grid lines are displayed around cells - /// - [Category("Appearance")] - [DefaultValue(true)] - public bool GridLines { get; set; } - - /// - /// Gets or sets a value indicating whether the entire row will always be selected - /// - [Category("Appearance")] - [DefaultValue(false)] - public bool FullRowSelect { get; set; } - - /// - /// Gets or sets the font used for the column header text - /// Also forces a cell size re-evaluation - /// - [Category("Appearance")] - public Font ColumnHeaderFont - { - get - { - if (_columnHeaderFont == null) - { - ColumnHeaderFont = new Font("Arial", 8, FontStyle.Bold); - } - - return _columnHeaderFont; - } - set - { - _columnHeaderFont = value; - SetCharSize(); - } - } - private Font _columnHeaderFont; - - /// - /// Gets or sets the color of the column header text - /// - [Category("Appearance")] - public Color ColumnHeaderFontColor - { - get - { - if (_columnHeaderFontColor == null) - _columnHeaderFontColor = Color.Black; - return _columnHeaderFontColor; - } - set { _columnHeaderFontColor = value; } - } - private Color _columnHeaderFontColor; - - /// - /// Gets or sets the background color of the column header cells - /// - [Category("Appearance")] - public Color ColumnHeaderBackgroundColor - { - get - { - if (_columnHeaderBackgroundColor == null) - _columnHeaderBackgroundColor = Color.LightGray; - return _columnHeaderBackgroundColor; - } - set { _columnHeaderBackgroundColor = value; } - } - private Color _columnHeaderBackgroundColor; - - /// - /// Gets or sets the background color of the column header cells when they are highlighted - /// - [Category("Appearance")] - public Color ColumnHeaderBackgroundHighlightColor - { - get - { - if (_columnHeaderBackgroundHighlightColor == null) - _columnHeaderBackgroundHighlightColor = SystemColors.HighlightText; - return _columnHeaderBackgroundHighlightColor; - } - set { _columnHeaderBackgroundHighlightColor = value; } - } - private Color _columnHeaderBackgroundHighlightColor; - - /// - /// Gets or sets the color of the column header outline - /// - [Category("Appearance")] - public Color ColumnHeaderOutlineColor - { - get - { - if (_columnHeaderOutlineColor == null) - _columnHeaderOutlineColor = Color.Black; - return _columnHeaderOutlineColor; - } - set - { - _columnHeaderOutlineColor = value; - } - } - private Color _columnHeaderOutlineColor; - - - /// - /// Gets or sets the font used for every row cell - /// Also forces a cell size re-evaluation - /// - [Category("Appearance")] - public Font CellFont - { - get - { - if (_cellFont == null) - { - CellFont = new Font("Arial", 8, FontStyle.Regular); - } - return _cellFont; - } - set - { - _cellFont = value; - SetCharSize(); - } - } - private Font _cellFont; - - - /// - /// Gets or sets the color of the font used for every row cell - /// - [Category("Appearance")] - public Color CellFontColor - { - get - { - if (_cellFontColor == null) - _cellFontColor = Color.Black; - return _cellFontColor; - } - set { _cellFontColor = value; } - } - private Color _cellFontColor; - - /// - /// Gets or sets the background color for every row cell - /// - [Category("Appearance")] - public Color CellBackgroundColor - { - get - { - if (_cellBackgroundColor == null) - _cellBackgroundColor = Color.White; - return _cellBackgroundColor; - } - set { _cellBackgroundColor = value; } - } - private Color _cellBackgroundColor; - - /// - /// Gets or sets the background color for every row cell that is highlighted - /// - [Category("Appearance")] - public Color CellBackgroundHighlightColor - { - get - { - if (_cellBackgroundHighlightColor == null) - _cellBackgroundHighlightColor = Color.Blue; - return _cellBackgroundHighlightColor; - } - set { _cellBackgroundHighlightColor = value; } - } - private Color _cellBackgroundHighlightColor; - - /// - /// Gets or sets the color used to draw the ListView gridlines - /// - [Category("Appearance")] - public Color GridLineColor - { - get - { - if (_gridLineColor == null) - _gridLineColor = SystemColors.ControlLight; - return _gridLineColor; - } - set { _gridLineColor = value; } - } - private Color _gridLineColor; - - /// - /// Gets or sets the size of control's border - /// Note: this is drawn directly onto the parent control, so large values will probably look terrible - /// - [Category("Appearance")] - public int BorderSize { get; set; } - - /// - /// Defines the absolute minimum column size (used when manually resizing columns) - /// - [DefaultValue(50)] - [Category("Appearance")] - public int MinimumColumnSize { get; set; } - - /// - /// The padding property is disabled for this control (as this is handled internally) - /// - [Category("Appearance")] - public new System.Windows.Forms.Padding Padding - { - get { return new System.Windows.Forms.Padding(0); } - set { } - } - - /// - /// Gets or sets the color of the control's border - /// - [Category("Appearance")] - public Color BorderColor - { - get - { - if (_borderColor == null) - _borderColor = SystemColors.InactiveBorder; - return _borderColor; - } - set { _borderColor = value; } - } - private Color _borderColor; - - - #endregion - - #region API - - /// - /// All visible columns - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public IEnumerable VisibleColumns => _columns.VisibleColumns; - - /// - /// Gets or sets the sets the virtual number of rows to be displayed. Does not include the column header row. - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int ItemCount - { - get { return _itemCount; } - set - { - _itemCount = value; - RecalculateScrollBars(); - } - } - - /// - /// Returns all columns including those that are not visible - /// - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public ListColumns AllColumns => _columns; - - /// - /// Gets whether the mouse is currently over a column cell - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public bool IsPointingAtColumnHeader => IsHoveringOnColumnCell; - - /// - /// Returns the index of the first selected row (null if no selection) - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int? FirstSelectedIndex - { - get - { - if (AnyRowsSelected) - { - return SelectedRows.Min(); - } - - return null; - } - } - - /// - /// Returns the index of the last selected row (null if no selection) - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int? LastSelectedIndex - { - get - { - if (AnyRowsSelected) - { - return SelectedRows.Max(); - } - - return null; - } - } - - /// - /// Gets or sets the first visible row index, if scrolling is needed - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int FirstVisibleRow - { - get // SuuperW: This was checking if the scroll bars were needed, which is useless because their Value is 0 if they aren't needed. - { - if (CellHeight == 0) CellHeight++; - return _vBar.Value / CellHeight; - } - - set - { - if (NeedsVScrollbar) - { - _programmaticallyUpdatingScrollBarValues = true; - if (value * CellHeight <= _vBar.Maximum) - { - _vBar.Value = value * CellHeight; - } - else - { - _vBar.Value = _vBar.Maximum; - } - - _programmaticallyUpdatingScrollBarValues = false; - } - } - } - - /// - /// Gets the last row that is fully visible - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - private int LastFullyVisibleRow - { - get - { - int halfRow = 0; - if ((DrawHeight - ColumnHeight - 3) % CellHeight < CellHeight / 2) - { - halfRow = 1; - } - - return FirstVisibleRow + VisibleRows - halfRow; // + CountLagFramesDisplay(VisibleRows - halfRow); - } - } - - /// - /// Gets or sets the last visible row - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int LastVisibleRow - { - get - { - return FirstVisibleRow + VisibleRows; // + CountLagFramesDisplay(VisibleRows); - } - - set - { - int halfRow = 0; - if ((DrawHeight - ColumnHeight - 3) % CellHeight < CellHeight / 2) - { - halfRow = 1; - } - - FirstVisibleRow = Math.Max(value - (VisibleRows - halfRow), 0); - } - } - - /// - /// Gets the number of rows currently visible including partially visible rows. - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int VisibleRows - { - get - { - if (CellHeight == 0) CellHeight++; - return (DrawHeight - ColumnHeight - 3) / CellHeight; // Minus three makes it work - } - } - - /// - /// Gets the first visible column index, if scrolling is needed - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int FirstVisibleColumn - { - get - { - if (CellHeight == 0) CellHeight++; - var columnList = VisibleColumns.ToList(); - return columnList.FindIndex(c => c.Right > _hBar.Value); - } - } - - /// - /// Gets the last visible column index, if scrolling is needed - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int LastVisibleColumnIndex - { - get - { - if (CellHeight == 0) CellHeight++; - List columnList = VisibleColumns.ToList(); - int ret; - ret = columnList.FindLastIndex(c => c.Left <= DrawWidth + _hBar.Value); - return ret; - } - } - - /// - /// Gets or sets the current Cell that the mouse was in. - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public Cell CurrentCell { get; set; } - - /// - /// Returns whether the current cell is a data cell or not - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public bool CurrentCellIsDataCell => CurrentCell?.RowIndex != null && CurrentCell.Column != null; - - /// - /// Gets a list of selected row indexes - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public IEnumerable SelectedRows - { - get - { - return _selectedItems - .Where(cell => cell.RowIndex.HasValue) - .Select(cell => cell.RowIndex.Value) - .Distinct(); - } - } - - /// - /// Returns whether any rows are selected - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public bool AnyRowsSelected - { - get - { - return _selectedItems.Any(cell => cell.RowIndex.HasValue); - } - } - - /// - /// Gets or sets the previous Cell that the mouse was in. - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public Cell LastCell { get; private set; } - - /// - /// Gets or sets whether paint down is happening - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public bool IsPaintDown { get; private set; } - - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public bool UseCustomBackground { get; set; } - - /// - /// Gets or sets the current draw height - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int DrawHeight { get; private set; } - - /// - /// Gets or sets the current draw width - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public int DrawWidth { get; private set; } - - /// - /// Gets or sets whether the right mouse button is held down - /// - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public bool RightButtonHeld { get; private set; } - - #endregion - } -} diff --git a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.cs b/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.cs deleted file mode 100644 index 0c1d138ef1..0000000000 --- a/BizHawk.Client.EmuHawk/CustomControls/PlatformAgnosticVirtualListView.cs +++ /dev/null @@ -1,356 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Windows.Forms; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// A performant VirtualListView implementation that doesn't rely on native Win32 API calls - /// (and in fact does not inherit the ListView class at all) - /// It is an enhanced version of the work done with GDI+ rendering in InputRoll.cs - /// - public partial class PlatformAgnosticVirtualListView : Control - { - private readonly SortedSet _selectedItems = new SortedSet(new SortCell()); - - private readonly VScrollBar _vBar; - private readonly HScrollBar _hBar; - - private readonly Timer _hoverTimer = new Timer(); - - private ListColumns _columns = new ListColumns(); - - private bool _programmaticallyUpdatingScrollBarValues; - - private int _itemCount; - private Size _charSize; - - private ListColumn _columnDown; - private ListColumn _columnSeparatorDown; - - private int? _currentX; - private int? _currentY; - - public PlatformAgnosticVirtualListView() - { - ColumnHeaderFont = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold, GraphicsUnit.Point); - ColumnHeaderFontColor = Color.Black; - ColumnHeaderBackgroundColor = Color.LightGray; - ColumnHeaderBackgroundHighlightColor = SystemColors.HighlightText; - ColumnHeaderOutlineColor = Color.Black; - - CellFont = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Regular, GraphicsUnit.Point); - CellFontColor = Color.Black; - CellBackgroundColor = Color.White; - CellBackgroundHighlightColor = Color.Blue; - - GridLines = true; - GridLineColor = SystemColors.ControlLight; - - UseCustomBackground = true; - - BorderColor = Color.DarkGray; - BorderSize = 1; - - MinimumColumnSize = 50; - - CellWidthPadding = 3; - CellHeightPadding = 0; - CurrentCell = null; - ScrollMethod = "near"; - - SetStyle(ControlStyles.AllPaintingInWmPaint, true); - SetStyle(ControlStyles.UserPaint, true); - SetStyle(ControlStyles.SupportsTransparentBackColor, true); - SetStyle(ControlStyles.Opaque, true); - SetStyle(ControlStyles.OptimizedDoubleBuffer, true); - - _vBar = new VScrollBar - { - // Location gets calculated later (e.g. on resize) - Visible = false, - SmallChange = CellHeight, - LargeChange = CellHeight * 20 - }; - - _hBar = new HScrollBar - { - // Location gets calculated later (e.g. on resize) - Visible = false, - SmallChange = CellWidth, - LargeChange = 20 - }; - - Controls.Add(_vBar); - Controls.Add(_hBar); - - _vBar.ValueChanged += VerticalBar_ValueChanged; - _hBar.ValueChanged += HorizontalBar_ValueChanged; - - RecalculateScrollBars(); - - _columns.ChangedCallback = ColumnChangedCallback; - - _hoverTimer.Interval = 750; - _hoverTimer.Tick += HoverTimerEventProcessor; - _hoverTimer.Stop(); - } - - private void HoverTimerEventProcessor(object sender, EventArgs e) - { - _hoverTimer.Stop(); - - CellHovered?.Invoke(this, new CellEventArgs(LastCell, CurrentCell)); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - } - - #region Pending Removal - - /* - * - - //private readonly byte[] _lagFrames = new byte[256]; // Large enough value that it shouldn't ever need resizing. // apparently not large enough for 4K - - private int _maxCharactersInHorizontal = 1; - private bool _horizontalOrientation; - - public string UserSettingsSerialized() - { - var settings = ConfigService.SaveWithType(Settings); - return settings; - } - - - - public void LoadSettingsSerialized(string settingsJson) - { - var settings = ConfigService.LoadWithType(settingsJson); - - // TODO: don't silently fail, inform the user somehow - if (settings is InputRollSettings) - { - var rollSettings = settings as InputRollSettings; - _columns = rollSettings.Columns; - _columns.ChangedCallback = ColumnChangedCallback; - HorizontalOrientation = rollSettings.HorizontalOrientation; - //LagFramesToHide = rollSettings.LagFramesToHide; - //HideWasLagFrames = rollSettings.HideWasLagFrames; - } - } - - private InputRollSettings Settings => new InputRollSettings - { - Columns = _columns, - HorizontalOrientation = HorizontalOrientation, - //LagFramesToHide = LagFramesToHide, - //HideWasLagFrames = HideWasLagFrames - }; - - public class InputRollSettings - { - public RollColumns Columns { get; set; } - public bool HorizontalOrientation { get; set; } - public int LagFramesToHide { get; set; } - public bool HideWasLagFrames { get; set; } - } - - - /// - /// Gets or sets the width of data cells when in Horizontal orientation. - /// - public int MaxCharactersInHorizontal - { - get - { - return _maxCharactersInHorizontal; - } - - set - { - _maxCharactersInHorizontal = value; - UpdateCellSize(); - } - } - - /// - /// Gets or sets a value indicating whether the control is horizontal or vertical - /// - [Category("Behavior")] - public bool HorizontalOrientation - { - get - { - return _horizontalOrientation; - } - set - { - if (_horizontalOrientation != value) - { - int temp = ScrollSpeed; - _horizontalOrientation = value; - OrientationChanged(); - _hBar.SmallChange = CellWidth; - _vBar.SmallChange = CellHeight; - ScrollSpeed = temp; - } - } - } - - public IEnumerable GenerateContextMenuItems() - { - yield return new ToolStripSeparator(); - - var rotate = new ToolStripMenuItem - { - Name = "RotateMenuItem", - Text = "Rotate", - ShortcutKeyDisplayString = RotateHotkeyStr, - }; - - rotate.Click += (o, ev) => - { - HorizontalOrientation ^= true; - }; - - yield return rotate; - } - - // SuuperW: Count lag frames between FirstDisplayed and given display position - private int CountLagFramesDisplay(int relativeIndex) - { - if (QueryFrameLag != null && LagFramesToHide != 0) - { - int count = 0; - for (int i = 0; i <= relativeIndex; i++) - { - count += _lagFrames[i]; - } - - return count; - } - - return 0; - } - - // Count lag frames between FirstDisplayed and given relative frame index - private int CountLagFramesAbsolute(int relativeIndex) - { - if (QueryFrameLag != null) // && LagFramesToHide != 0) - { - int count = 0; - for (int i = 0; i + count <= relativeIndex; i++) - { - count += _lagFrames[i]; - } - - return count; - } - - return 0; - } - - private void SetLagFramesArray() - { - if (QueryFrameLag != null) // && LagFramesToHide != 0) - { - bool showNext = false; - - // First one needs to check BACKWARDS for lag frame count. - SetLagFramesFirst(); - int f = _lagFrames[0]; - - if (QueryFrameLag(FirstVisibleRow + f, HideWasLagFrames)) - { - showNext = true; - } - - for (int i = 1; i <= VisibleRows; i++) - { - _lagFrames[i] = 0; - if (!showNext) - { - for (; _lagFrames[i] < LagFramesToHide; _lagFrames[i]++) - { - if (!QueryFrameLag(FirstVisibleRow + i + f, HideWasLagFrames)) - { - break; - } - - f++; - } - } - else - { - if (!QueryFrameLag(FirstVisibleRow + i + f, HideWasLagFrames)) - { - showNext = false; - } - } - - if (_lagFrames[i] == LagFramesToHide && QueryFrameLag(FirstVisibleRow + i + f, HideWasLagFrames)) - { - showNext = true; - } - } - } - else - { - for (int i = 0; i <= VisibleRows; i++) - { - _lagFrames[i] = 0; - } - } - } - - private void SetLagFramesFirst() - { - if (QueryFrameLag != null && LagFramesToHide != 0) - { - // Count how many lag frames are above displayed area. - int count = 0; - do - { - count++; - } - while (QueryFrameLag(FirstVisibleRow - count, HideWasLagFrames) && count <= LagFramesToHide); - count--; - - // Count forward - int fCount = -1; - do - { - fCount++; - } - while (QueryFrameLag(FirstVisibleRow + fCount, HideWasLagFrames) && count + fCount < LagFramesToHide); - _lagFrames[0] = (byte)fCount; - } - else - { - _lagFrames[0] = 0; - } - } - - public string RotateHotkeyStr => "Ctrl+Shift+F"; - - /// - /// Check if a given frame is a lag frame - /// - public delegate bool QueryFrameLagHandler(int index, bool hideWasLag); - - - /// - /// Fire the QueryFrameLag event which checks if a given frame is a lag frame - /// - [Category("Virtual")] - public event QueryFrameLagHandler QueryFrameLag; - - */ - - #endregion - } -} diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs index 9fe6286f25..fc20dcb1fb 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs @@ -1795,4 +1795,4 @@ namespace BizHawk.Client.EmuHawk private System.Windows.Forms.ToolStripMenuItem SingleClickFloatEditMenuItem; private System.Windows.Forms.ToolStripMenuItem LoadBranchOnDoubleclickMenuItem; } -} +} \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs index 09b915a012..178cd9b6de 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs @@ -8,7 +8,6 @@ using BizHawk.Client.Common; using BizHawk.Client.Common.MovieConversionExtensions; using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.WinFormExtensions; -using BizHawk.Common; namespace BizHawk.Client.EmuHawk { diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx index 34d44a8aa8..30922f753b 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx @@ -123,19 +123,19 @@ - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 - JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsBAAALAQE2cE9bAAACTUlE - QVQ4T5WSS29SURSFWx+x0ehERw4cmvgL9E840ehfMHGg6UAnJs6UBm2R1JramJg2yOMWKJfypjwKFgv4 - QIHaUoHyurSTlsSaKJFu1z7pvYHoxMFH9llr73X2Pe0QEf1Fu50cPoTrf/aoDBy2t5PnwFVFWdaXy8Fs - sSDvA0L9A9oyvBvgZP+MVrTbibNAt7npz0bCMzuSVdeVzDqSzI9JsugoHJz+VSr5NtAzCs4MBEAYAXdL - G17FIxt/y84JWn1nIr7965pb1M75J+Sw6WmtKO+i14CNTmsBipK4XK9HU9HwTC8YmKLytwChgVJv53iA - MCA0j/yMZMc4VSuhPfjXRAAe6TgCbhWL8o7PPYkbF8VwsxkjfArlPtmppcSFxhtZTY8okzYftFrxcTXg - BA73V1OmTiT0kur1iBgeCGjFxZk9r9tIIf8LajSis9oGjUZsNB571UnEX7OhgU/C2kZaCk3T+4xFaBzK - IbVaxKQGHEXAbQTsBXzPaWsrLG5i+AGzaQuvjPVdwuPhIDaAP6cGHEHynWzG0pm3jFH+i1MM12pLWhDD - t7PHb8B/FWiTWgCaH5ZK3u/8wosuA62ve0RAP6yx57I/JfR2od1UA4ar1dA9rNf8nLMf2K1j5JD0tJKc - pXx+QcA1a+yhhz8lhpkREcA/OJwHD0ChkF/4GfBNkQ3/gbY3h6BmDV4PPTlwgee0AKZSCZ4C12FGy+XA - frHoOvj4QRKg7kHrwkuj55I6MxDAoOkYuAIm0OgHKyAFfNAM4GJ/PzNw+H9o6A/udhOJUDYlqgAAAABJ - RU5ErkJggg== + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALAQAA + CwEBNnBPWwAAAk1JREFUOE+VkktvUlEUhVsfsdHoREcOHJr4C/RPONHoXzBxoOlAJybOlAZtkdSa2piY + NsjjFiiX8qY8ChYL+ECB2lKB8rq0k5bEmiiRbtc+6b2B6MTBR/ZZa+919j3tEBH9RbudHD6E63/2qAwc + treT58BVRVnWl8vBbLEg7wNC/QPaMrwb4GT/jFa024mzQLe56c9GwjM7klXXlcw6ksyPSbLoKByc/lUq + +TbQMwrODARAGAF3SxtexSMbf8vOCVp9ZyK+/euaW9TO+SfksOlprSjvoteAjU5rAYqSuFyvR1PR8Ewv + GJii8rcAoYFSb+d4gDAgNI/8jGTHOFUroT3410QAHuk4Am4Vi/KOzz2JGxfFcLMZI3wK5T7ZqaXEhcYb + WU2PKJM2H7Ra8XE14AQO91dTpk4k9JLq9YgYHghoxcWZPa/bSCH/C2o0orPaBo1GbDQee9VJxF+zoYFP + wtpGWgpN0/uMRWgcyiG1WsSkBhxFwG0E7AV8z2lrKyxuYvgBs2kLr4z1XcLj4SA2gD+nBhxB8p1sxtKZ + t4xR/otTDNdqS1oQw7ezx2/AfxVok1oAmh+WSt7v/MKLLgOtr3tEQD+sseeyPyX0dqHdVAOGq9XQPazX + /JyzH9itY+SQ9LSSnKV8fkHANWvsoYc/JYaZERHAPzicBw9AoZBf+BnwTZEN/4G2N4egZg1eDz05cIHn + tACmUgmeAtdhRsvlwH6x6Dr4+EESoO5B68JLo+eSOjMQwKDpGLgCJtDoBysgBXzQDOBifz8zcPh/aOgP + 7nYTiVA2JaoAAAAASUVORK5CYII= diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 157b849a24..0e551be12f 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -709,6 +709,38 @@ + + + + + O2Hawk.cs + + + O2Hawk.cs + + + O2Hawk.cs + + + O2Hawk.cs + + + O2Hawk.cs + + + O2Hawk.cs + + + O2Hawk.cs + + + + + + + + + @@ -1607,6 +1639,13 @@ + + + + + + +