diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index c43a970..c8aa51f 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -73,6 +73,7 @@ namespace AssetStudioGUI //asset list sorting private int sortColumn = -1; private bool reverseSort; + private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast(); //asset list filter private System.Timers.Timer delayTimer; @@ -621,6 +622,15 @@ namespace AssetStudioGUI return reverseSort ? pathID_Y.CompareTo(pathID_X) : pathID_X.CompareTo(pathID_Y); }); } + else if (sortColumn == 0) // Name + { + visibleAssets.Sort((a, b) => + { + var at = a.SubItems[sortColumn].Text; + var bt = b.SubItems[sortColumn].Text; + return reverseSort ? alphanumComparator.Compare(bt, at) : alphanumComparator.Compare(at, bt); + }); + } else { visibleAssets.Sort((a, b) => diff --git a/AssetStudioGUI/Components/AlphanumComparatorFast.cs b/AssetStudioGUI/Components/AlphanumComparatorFast.cs new file mode 100644 index 0000000..7998344 --- /dev/null +++ b/AssetStudioGUI/Components/AlphanumComparatorFast.cs @@ -0,0 +1,96 @@ +// This code developed by Dot Net Perls +using System.Collections; + + +namespace AssetStudioGUI +{ + internal class AlphanumComparatorFast : IComparer + { + public int Compare(object x, object y) + { + if (!(x is string s1)) + { + return 0; + } + if (!(y is string s2)) + { + return 0; + } + + int len1 = s1.Length; + int len2 = s2.Length; + int marker1 = 0; + int marker2 = 0; + + // Walk through two the strings with two markers. + while (marker1 < len1 && marker2 < len2) + { + char ch1 = s1[marker1]; + char ch2 = s2[marker2]; + + // Some buffers we can build up characters in for each chunk. + char[] space1 = new char[len1]; + int loc1 = 0; + char[] space2 = new char[len2]; + int loc2 = 0; + + // Walk through all following characters that are digits or + // characters in BOTH strings starting at the appropriate marker. + // Collect char arrays. + do + { + space1[loc1++] = ch1; + marker1++; + + if (marker1 < len1) + { + ch1 = s1[marker1]; + } + else + { + break; + } + } while (char.IsDigit(ch1) == char.IsDigit(space1[0])); + + do + { + space2[loc2++] = ch2; + marker2++; + + if (marker2 < len2) + { + ch2 = s2[marker2]; + } + else + { + break; + } + } while (char.IsDigit(ch2) == char.IsDigit(space2[0])); + + // If we have collected numbers, compare them numerically. + // Otherwise, if we have strings, compare them alphabetically. + string str1 = new string(space1); + string str2 = new string(space2); + + int result; + + if (char.IsDigit(space1[0]) && char.IsDigit(space2[0])) + { + int thisNumericChunk = int.Parse(str1); + int thatNumericChunk = int.Parse(str2); + result = thisNumericChunk.CompareTo(thatNumericChunk); + } + else + { + result = str1.CompareTo(str2); + } + + if (result != 0) + { + return result; + } + } + return len1 - len2; + } + } +}