From a2197a6cb42d511747ccd2159cf1f4d29ef15f07 Mon Sep 17 00:00:00 2001 From: Alexey 'Cluster' Avdyukhin Date: Mon, 6 Feb 2017 16:03:26 +0300 Subject: More folder styles (core only) --- NesMenuCollection.cs | 177 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 147 insertions(+), 30 deletions(-) (limited to 'NesMenuCollection.cs') diff --git a/NesMenuCollection.cs b/NesMenuCollection.cs index cd2480e1..60c087dd 100644 --- a/NesMenuCollection.cs +++ b/NesMenuCollection.cs @@ -3,82 +3,199 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; namespace com.clusterrr.hakchi_gui { public class NesMenuCollection : List { - const int Letters = 25; + const int FoldersEqualLetters = 3; + const int PagesEqualLetters = 3; + public enum SplitStyle + { + NoSplit = 0, + Auto = 1, + PagesEqual = 2, + FoldersEqual = 3, + FoldersAlphabetic_PagesEqual = 4, + FoldersAlphabetic_FoldersEqual = 5, + Custom = 6 + } - public void Split(int maxElements) + public void Split(SplitStyle style, bool originalToRoot, int maxElements) { - if (Count <= maxElements) return; + if (style == SplitStyle.NoSplit) return; + if ((style == SplitStyle.Auto || style == SplitStyle.FoldersEqual || style == SplitStyle.PagesEqual) && + (Count <= maxElements)) return; var total = Count; var partsCount = (int)Math.Ceiling((float)total / (float)maxElements); var perPart = (int)Math.Ceiling((float)total / (float)partsCount); + var alphaNum = new Regex("[^a-zA-Z0-9]"); - var sorted = this.OrderBy(o => o.Name); + NesMenuCollection root; + if (!originalToRoot) + root = this; + else + { + root = new NesMenuCollection(); + root.AddRange(this.Where(o => !(o is NesDefaultGame))); + this.RemoveAll(o => !(o is NesDefaultGame)); + this.Add(new NesMenuFolder() { Name = Resources.FolderNameMoreGames, First = false, Child = root }); + } + var sorted = root.OrderBy(o => o.Name); var collections = new List(); - var collection = new NesMenuCollection(); int i = 0; - foreach (var game in sorted) + if (style == SplitStyle.Auto || style == SplitStyle.FoldersEqual || style == SplitStyle.PagesEqual) { - collection.Add(game); - i++; - if (((i % perPart) == 0) || (i == sorted.Count())) + var collection = new NesMenuCollection(); + foreach (var game in sorted) { - collections.Add(collection); - collection = new NesMenuCollection(); + collection.Add(game); + i++; + if (((i % perPart) == 0) || (i == sorted.Count())) + { + collections.Add(collection); + collection = new NesMenuCollection(); + } } } - // Method A - if (collections.Count >= 12) // minimum amount of games/folders on screen without glitches + if (style == SplitStyle.Auto) + { + if (collections.Count >= 12) + style = SplitStyle.FoldersEqual; + else + style = SplitStyle.PagesEqual; + } + + // Folders, equal + if (style == SplitStyle.FoldersEqual) // minimum amount of games/folders on screen without glitches { - var root = this; root.Clear(); foreach (var coll in collections) { - var fname = coll.Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Name; - var lname = coll.Where(o => (o is NesGame) || (o is NesDefaultGame)).Last().Name; + var fname = alphaNum.Replace(coll.Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Name.ToUpper(), ""); + var lname = alphaNum.Replace(coll.Where(o => (o is NesGame) || (o is NesDefaultGame)).Last().Name.ToUpper(), ""); + var folder = new NesMenuFolder(); folder.Child = coll; - folder.Name = fname.Substring(0, Math.Min(Letters, fname.Length)) + (fname.Length > Letters ? "..." : "") + " - " + lname.Substring(0, Math.Min(Letters, lname.Length)) + (lname.Length > Letters ? "..." : ""); + folder.NameParts = new string[] { fname, lname }; root.Add(folder); - coll.Add(new NesMenuFolder() { Name = "<- Back", Image = Resources.back, Child = root }); + coll.Add(new NesMenuFolder() { Name = Resources.FolderNameBack, Image = Resources.back, Child = root }); } + TrimFolderNames(root); } - else - // Method B + else if (style == SplitStyle.PagesEqual) + // Pages, equal { for (i = 0; i < collections.Count; i++) { for (int j = i - 1; j >= 0; j--) { var folder = new NesMenuFolder(); - var fname = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Name/*.ToUpper().Replace(" ", "")*/; - var lname = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).Last().Name/*.ToUpper().Replace(" ", "")*/; + var fname = alphaNum.Replace(collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Name.ToUpper(), ""); + var lname = alphaNum.Replace(collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).Last().Name.ToUpper(), ""); folder.Child = collections[j]; - folder.Name = fname.Substring(0, Math.Min(Letters, fname.Length)) + (fname.Length > Letters ? "..." : "") + " - " + lname.Substring(0, Math.Min(Letters, lname.Length)) + (lname.Length > Letters ? "..." : ""); - folder.Initial = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Code; + folder.NameParts = new string[] { fname, lname }; + //folder.Initial = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Code; folder.First = true; collections[i].Insert(0, folder); } for (int j = i + 1; j < collections.Count; j++) { var folder = new NesMenuFolder(); - var fname = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Name/*.ToUpper().Replace(" ", "")*/; - var lname = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).Last().Name/*.ToUpper().Replace(" ", "")*/; + var fname = alphaNum.Replace(collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Name.ToUpper(), ""); + var lname = alphaNum.Replace(collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).Last().Name.ToUpper(), ""); folder.Child = collections[j]; - folder.Name = fname.Substring(0, Math.Min(Letters, fname.Length)) + (fname.Length > Letters ? "..." : "") + " - " + lname.Substring(0, Math.Min(Letters, lname.Length)) + (lname.Length > Letters ? "..." : ""); - folder.Initial = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Code; + folder.NameParts = new string[] { fname, lname }; + //folder.Initial = collections[j].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Code; folder.First = false; collections[i].Insert(collections[i].Count, folder); } + TrimFolderNames(collections[i]); + } + root.Clear(); + root.AddRange(collections[0]); + } + else if (style == SplitStyle.FoldersAlphabetic_PagesEqual || style == SplitStyle.FoldersAlphabetic_FoldersEqual) + { + var letters = new Dictionary(); + for (char ch = 'A'; ch <= 'Z'; ch++) + letters[ch] = new NesMenuCollection(); + letters['#'] = new NesMenuCollection(); + foreach (var game in root) + { + if (!(game is NesGame || game is NesDefaultGame)) continue; + var letter = game.Name.Substring(0, 1).ToUpper()[0]; + if (letter < 'A' || letter > 'Z') + letter = '#'; + letters[letter].Add(game); } - Clear(); - AddRange(collections[0]); + + root.Clear(); + foreach (var letter in letters.Keys) + if (letters[letter].Count > 0) + { + var folder = new NesMenuFolder() { Child = letters[letter], Name = letter.ToString() }; + if (style == SplitStyle.FoldersAlphabetic_PagesEqual) + { + folder.Child.Split(SplitStyle.PagesEqual, false, maxElements); + folder.Child.Add(new NesMenuFolder() { Name = Resources.FolderNameBack, Image = Resources.back, Child = root }); + foreach (NesMenuFolder f in folder.Child.Where(o => o is NesMenuFolder)) + if (f.Child != root) + f.Child.Add(new NesMenuFolder() { Name = Resources.FolderNameBack, Image = Resources.back, Child = root }); + } + else if (style == SplitStyle.FoldersAlphabetic_FoldersEqual) + { + folder.Child.Split(SplitStyle.FoldersEqual, false, maxElements); + folder.Child.Add(new NesMenuFolder() { Name = Resources.FolderNameBack, Image = Resources.back, Child = root }); + } + //folder.Initial = letters[letter].Where(o => (o is NesGame) || (o is NesDefaultGame)).First().Code; + root.Add(folder); + } + } + if (originalToRoot) + { + if (style != SplitStyle.FoldersEqual) + root.Add(new NesMenuFolder() { Name = Resources.FolderNameOriginalGames, Image = Resources.back, Child = this }); + else + { + root.Add(new NesMenuFolder() { Name = Resources.FolderNameOriginalGames, Image = Resources.back, Child = this }); + foreach (NesMenuFolder f in root.Where(o => o is NesMenuFolder)) + if (f.Child != root) + f.Child.Add(new NesMenuFolder() { Name = Resources.FolderNameBack, Image = Resources.back, Child = root }); + } + } + } + + void TrimFolderNames(NesMenuCollection nesMenuCollection) + { + const int minChars = 3; + const int maxChars = 8; + var folders = nesMenuCollection.Where(o => o is NesMenuFolder).OrderBy(o => o.Name).ToArray(); + for (int i = 1; i < folders.Length; i++) + { + var prevFolder = i > 0 ? (folders[i - 1] as NesMenuFolder) : null; + var currentFolder = folders[i] as NesMenuFolder; + var nameA = prevFolder.NameParts[1]; + var nameB = currentFolder.NameParts[0]; + int l = Math.Min(maxChars - 1, Math.Max(nameA.Length, nameB.Length)); + while ((nameA.Substring(0, Math.Min(l, nameA.Length)) != + nameB.Substring(0, Math.Min(l, nameB.Length))) && l >= minChars) + l--; + nameA = nameA.Substring(0, Math.Min(l + 1, nameA.Length)); + nameB = nameB.Substring(0, Math.Min(l + 1, nameB.Length)); + prevFolder.NameParts = new string[] { prevFolder.NameParts[0], nameA }; + currentFolder.NameParts = new string[] { nameB, currentFolder.NameParts[1] }; + } + if (folders.Length > 0) + { + var firstFolder = folders[0] as NesMenuFolder; + firstFolder.NameParts = new string[] { firstFolder.NameParts[0].Substring(0, Math.Min(firstFolder.NameParts[0].Length, minChars)), firstFolder.NameParts[1] }; + + var lastFolder = folders[folders.Length - 1] as NesMenuFolder; + lastFolder.NameParts = new string[] { lastFolder.NameParts[0], lastFolder.NameParts[1].Substring(0, Math.Min(lastFolder.NameParts[1].Length, minChars)), }; } } } -- cgit v1.2.3