From 3e261ee077b17c9cb4f8a5dec1383a61d46d9777 Mon Sep 17 00:00:00 2001 From: Jim Westfall Date: Sun, 18 Jan 2015 14:09:11 -0800 Subject: [PATCH] fix sorting on GameGrid When switching to Cell_Formatting to fix rendering in mono and also provide a speed up to displaying the GameGrid, it broken sorting on the CGame and CDescription columns. This is because we are no longer setting the Value field on those cells. On windows, clicking those column headers would do nothing, under mono it would cause a crash. Instead of reverting the Cell_Formatting change, this update make us handle the sorting ourselves. Mono doesnt implement SortCompare, so had to handle column header clicks and make our own IComparer. This also disables sorting on columns that are images, including on RomGrid. --- ROMVault2/FrmMain.Designer.cs | 8 ++- ROMVault2/FrmMain.cs | 93 ++++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/ROMVault2/FrmMain.Designer.cs b/ROMVault2/FrmMain.Designer.cs index 00ba590..e38d02f 100644 --- a/ROMVault2/FrmMain.Designer.cs +++ b/ROMVault2/FrmMain.Designer.cs @@ -656,6 +656,7 @@ this.GameGrid.SelectionChanged += new System.EventHandler(this.GameGridSelectionChanged); this.GameGrid.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.GameGridMouseDoubleClick); this.GameGrid.MouseUp += new System.Windows.Forms.MouseEventHandler(this.GameGrid_MouseUp); + this.GameGrid.ColumnHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.GameGridColumnHeaderMouseClick); // // Type // @@ -664,7 +665,7 @@ this.Type.Name = "Type"; this.Type.ReadOnly = true; this.Type.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.Type.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.Type.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; this.Type.Width = 40; // // CGame @@ -672,6 +673,7 @@ this.CGame.HeaderText = "Game (Directory / Zip)"; this.CGame.Name = "CGame"; this.CGame.ReadOnly = true; + this.CGame.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; this.CGame.Width = 220; // // CDescription @@ -679,6 +681,7 @@ this.CDescription.HeaderText = "Description"; this.CDescription.Name = "CDescription"; this.CDescription.ReadOnly = true; + this.CDescription.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; this.CDescription.Width = 220; // // CCorrect @@ -687,6 +690,7 @@ this.CCorrect.Name = "CCorrect"; this.CCorrect.ReadOnly = true; this.CCorrect.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.CCorrect.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; this.CCorrect.Width = 500; // // RomGrid @@ -756,7 +760,7 @@ this.CGot.Name = "CGot"; this.CGot.ReadOnly = true; this.CGot.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.CGot.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.CGot.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; this.CGot.Width = 65; // // CRom diff --git a/ROMVault2/FrmMain.cs b/ROMVault2/FrmMain.cs index 6f0385d..f5ed8d2 100644 --- a/ROMVault2/FrmMain.cs +++ b/ROMVault2/FrmMain.cs @@ -37,6 +37,9 @@ namespace ROMVault2 private readonly Color[] _displayColor; private bool _updatingGameGrid; + + private int GameGridSortColumnIndex = 0; + private SortOrder GameGridSortOrder = SortOrder.Descending; public static int[] GameGridColumnXPositions; @@ -456,6 +459,11 @@ namespace ROMVault2 GameGrid.Rows.Clear(); RomGrid.Rows.Clear(); + // clear sorting + GameGrid.Columns[GameGridSortColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.None; + GameGridSortColumnIndex = 0; + GameGridSortOrder = SortOrder.Descending; + if (cf == null) return; @@ -600,6 +608,12 @@ namespace ROMVault2 GameGrid.Rows.Clear(); RomGrid.Rows.Clear(); + // clear sorting + GameGrid.Columns[GameGridSortColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.None; + GameGridSortColumnIndex = 0; + GameGridSortOrder = SortOrder.Descending; + + ReportStatus tDirStat; GameGridColumnXPositions = new int[(int)RepStatus.EndValue]; @@ -851,9 +865,86 @@ namespace ROMVault2 e.Value = bmp; } else - Console.WriteLine("WARN: GameGrid_CellFormatting() unknown column: {0}", GameGrid.Columns[e.ColumnIndex].Name); + Console.WriteLine("WARN: GameGrid_CellFormatting() unknown column: {0}", GameGrid.Columns[e.ColumnIndex].Name); } + private void GameGridColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) + { + + // only allow sort on CGame/CDescription + if (e.ColumnIndex != 1 && e.ColumnIndex != 2) + return; + + DataGridViewColumn newColumn = GameGrid.Columns[e.ColumnIndex]; + DataGridViewColumn oldColumn = GameGrid.Columns[GameGridSortColumnIndex]; + + if (newColumn == oldColumn) + { + if (GameGridSortOrder == SortOrder.Ascending) + GameGridSortOrder = SortOrder.Descending; + else + GameGridSortOrder = SortOrder.Ascending; + } + else + { + oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None; + GameGridSortOrder = SortOrder.Ascending; + } + + GameGrid.Sort(new GameGridRowComparer(GameGridSortOrder, e.ColumnIndex)); + newColumn.HeaderCell.SortGlyphDirection = GameGridSortOrder; + GameGridSortColumnIndex = e.ColumnIndex; + } + + private class GameGridRowComparer : System.Collections.IComparer + { + private int sortMod = 1; + private int columnIndex; + + public GameGridRowComparer(SortOrder sortOrder, int index) + { + columnIndex = index; + + if (sortOrder == SortOrder.Descending) + sortMod = -1; + } + + public int Compare(object a, object b) + { + DataGridViewRow aRow = (DataGridViewRow)a; + DataGridViewRow bRow = (DataGridViewRow)b; + + RvDir aRvDir = (ROMVault2.RvDB.RvDir)aRow.Tag; + RvDir bRvDir = (ROMVault2.RvDB.RvDir)bRow.Tag; + + int result = 0; + switch (columnIndex) + { + case 1: // CGame + result = System.String.Compare(aRvDir.Name, bRvDir.Name); + break; + case 2: // CDescription + String aDes = ""; + String bDes = ""; + if (aRvDir.Game != null) + aDes = aRvDir.Game.GetData(RvGame.GameData.Description); + if (bRvDir.Game != null) + bDes = bRvDir.Game.GetData(RvGame.GameData.Description); + + result = System.String.Compare(aDes, bDes); + + // if desciptions match, fall through to sorting by name + if (result == 0) + result = System.String.Compare(aRvDir.Name, bRvDir.Name); + + break; + default: + Console.WriteLine("WARN: GameGridRowComparer::Compare() Invalid columnIndex: {0}", columnIndex); + break; + } + return sortMod * result; + } + } #endregion #region "Rom Grid Code"