/// <summary> /// Draw the background for the box. /// </summary> static void DrawBox() { string topString, bottomString, lineString; // Build the border strings topString = "\x00DA".PadRight(boxW - 1, '\x00C4') + "\x00BF"; // top-left corner, horizontal lines, top-right corner lineString = "\x00B3".PadRight(boxW - 1) + "\x00B3"; // Vertical line, empty spaces, vertical line bottomString = "\x00C0".PadRight(boxW - 1, '\x00C4') + "\x00D9"; // low-left corner, horizontal lines, low-right corner // Write the top SuperConsole.WriteColor(boxX, boxY, ConsoleColor.Black, ConsoleColor.DarkGrey, topString); // Write the necessary middle lines for (int i = 1; i < boxH - 1; i++) { SuperConsole.WriteColor(boxX, boxY + i, ConsoleColor.Black, ConsoleColor.DarkGrey, lineString); } // Finally, the bottom. SuperConsole.WriteColor(boxX, boxY + boxH - 1, ConsoleColor.Black, ConsoleColor.DarkGrey, bottomString); }
/// <summary> /// Redraw the box with the correct scroll position /// </summary> static void DrawElements() { int scrollPos; // We only want to be at scroll position 0 or max scroll when the cursor is on the first or last element respectively. if (cursorPos == 0) { scrollPos = 0; } else if (cursorPos == strings.Length - 1) { scrollPos = strings.Length - (boxH - 2); } else { int minScroll = -1; // Starting at -1 ensures that it does not start scrolling right away. int maxScroll = strings.Length - (boxH - 3); // -3 ensures that it will never scroll all the way down. // Get the scroll percentage ( range [0, 1] ) float fscrollPos = ((float)cursorPos) / ((float)strings.Length - 1); // Calculate the actual scroll position scrollPos = (int)System.Math.Floor(((float)minScroll) + (float)(maxScroll - minScroll) * fscrollPos + 0.3f); // Ensure it doesn't go below 0. if (scrollPos < 0) { scrollPos = 0; } // Also ensure (corner case) that it doesn't scroll farther than possible int trueMax = strings.Length - (boxH - 2); if (scrollPos > trueMax) { scrollPos = trueMax; } } for (int i = 0; i < boxH - 2; i++) { int element = i + scrollPos; // Default colors are Black on DarkGrey ConsoleColor fg = ConsoleColor.Black; ConsoleColor bg = ConsoleColor.DarkGrey; if (element == cursorPos) { // This is the selected element, so draw it as white on dark red bg = ConsoleColor.DarkRed; fg = ConsoleColor.White; } // Build the string string s = strings[i + scrollPos]; // Ensure that the string is no longer than the box width (minus 2 for the border), then pad the rest with spaces if (s.Length > boxW - 2) { s = s.Substring(0, boxW - 2); } s = s.PadRight(boxW - 2); // Draw! SuperConsole.WriteColor(boxX + 1, boxY + i + 1, fg, bg, s); } }
/// <summary> /// Rescan all of the supplied roots. /// </summary> /// <param name="roots"></param> static void Rescan(string[] roots) { scanMutex.WaitOne(); { // Load a list of the paths List <string> pathList = new List <string>(LoadPaths()); // Remove from the path list any paths that belong to any of the given roots. RemoveRootPaths(roots, pathList); // We'll maintain a stack of the paths that need to be searched. Start by pushing all of the roots onto it. Stack <string> pathsToSearch = new Stack <string>(); for (int i = roots.Length - 1; i >= 0; i--) { pathsToSearch.Push(roots[i]); } // Finally, we need the regular expressions corresponding to the ignore rules. Regex[] ignores = LoadIgnoreRegexes(roots); System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); const float timeDiff = 0.5f; float prevTime = ((float)watch.ElapsedMilliseconds) / 1000 - timeDiff - 0.1f; Console.WriteLine(); int writeX = Console.WindowLeft; int writeY = SuperConsole.CursorY - 1; SuperConsole.CacheConsole(writeX, writeY, Console.WindowWidth, 2); SuperConsole.WriteColor(writeX, writeY, ConsoleColor.LightYellow, ConsoleColor.DarkBlue, "Rescanning...".PadRight(Console.WindowWidth)); // For each directory while (pathsToSearch.Count != 0) { // Make sure to add backslashes as necessary. string path = TrailBackslash(pathsToSearch.Pop()); // If this path matches any of the ignore lists, we'll skip it completely. bool ignore = false; for (int i = 0; i < ignores.Length; i++) { if (ignores[i].IsMatch(path)) { ignore = true; break; } } if (ignore) { continue; } // If enough time has elapsed, display a new directory float curTime = ((float)watch.ElapsedMilliseconds) / 1000; if (curTime - prevTime > timeDiff) { prevTime += timeDiff; SuperConsole.WriteColor(writeX, writeY + 1, ConsoleColor.White, ConsoleColor.DarkBlue, path.PadRight(Console.WindowWidth)); System.Threading.Thread.Sleep(1); } // Get the subdirectories (wrapped in a try block mostly to avoid the access denied errors that some folders give) string[] newDirs; try { newDirs = Directory.GetDirectories(path); } catch (Exception) { newDirs = new string[0]; } // Add the lower-cased current path to the list. pathList.Add(path.ToLowerInvariant()); // Add each subdirectory to the scan list. for (int i = newDirs.Length - 1; i >= 0; i--) { pathsToSearch.Push(newDirs[i]); } } SuperConsole.RestoreCache(); SuperConsole.CursorY--; // Sort and write the path list. pathList.Sort(); WritePaths(pathList.ToArray()); } scanMutex.ReleaseMutex(); }