Alright, so, in my C# Cosmos operating system, I'm working on a system that lets me input a string, and a desired width, and wrap the string into lines based on the width.
It works sorta like this: Input string is "Hello beautiful world". Width is 6. The algorithm will iterate through the string, and if the char index is that of the width, and the current char is a Space, it'll take everything from the beginning of the string up until that point, add it to a List, and remove it from the string itself, and reset the char index to 0, and start over. It does this until the string is either empty or smaller than the width. If it's smaller than the width, it's added to the List, and the for loop is terminated. In laymen, our output string should come out like this:
Hello
beautiful
world.
This is my code.
public static List<string> split_string(int width, string text)
{
List<string> text_lines = new List<string>();
//Separate lines of text.
for (int i = 0; i < text.Length; i++)
{
if (text.Length <= width)
{
text_lines.Add(text);
i = text.Length + 5;
}
else
{
if (i >= width)
{
if (text[i] == ' ')
{
text_lines.Add(text.Substring(0, i + 1));
text = text.Remove(0, i + 1);
i = 0;
}
}
}
}
return text_lines;
}
The thing is, sometimes, if I end up having to deal with the string being smaller than the width, we get issues. It seems to skip that part of the string. Yikes!
For example, here's a piece of my OS that uses this. It's supposed to take a title and a message, and display it in a messagebox with an OK button.
public static void ShowMessagebox(string title, string text)
{
int splitWidth = 25;
if(text.Length < splitWidth)
{
splitWidth = text.Length;
}
if(title.Length > splitWidth)
{
splitWidth = title.Length;
}
var lines = new List<string>();
if(splitWidth > text.Length)
{
lines.Add(text);
}
else
{
lines = TUI.Utils.split_string(splitWidth, text);
}
foreach(var line in lines)
{
if(text.Contains(line))
{
text = text.Replace(line, "");
}
}
if(text.Length > 0)
{
lines.Add(text);
}
int h = lines.Count + 4;
int w = 0;
foreach(var line in lines)
{
if(line.Length + 4 > w)
{
w = line.Length + 4;
}
}
int x = (Console.WindowWidth - w) / 2;
int y = (Console.WindowHeight - h) / 2;
TUI.Utils.ClearArea(x, y, w, h, ConsoleColor.Green);
TUI.Utils.ClearArea(x, y, w, 1, ConsoleColor.White);
TUI.Utils.Write(x + 1, y, title, ConsoleColor.White, ConsoleColor.Black);
for(int i = 0; i < lines.Count - 1; i++)
{
TUI.Utils.Write(x + 2, (y + 2) + i, lines[i], ConsoleColor.Green, ConsoleColor.White);
}
int xw = x + w;
int yh = y + h;
TUI.Utils.Write(xw - 6, yh - 2, "<OK>", TUI.Utils.COL_BUTTON_SELECTED, TUI.Utils.COL_BUTTON_TEXT);
bool stuck = true;
while (stuck)
{
var kinf = Console.ReadKey();
if (kinf.Key == ConsoleKey.Enter)
{
stuck = false;
Console.Clear();
}
else
{
}
}
}
Pretty simple. Starts with a default width of 25 chars, and if the title is bigger, it sets it to title length. If text length is smaller than the width it sets the width to compensate. Then it makes the call to the splitter algorithm from above, found in 'TUI.Utils', and then does some stuff to print to the screen.
Here's a piece of my OS's "ConfigurationManager", an application that takes in user input and uses it to generate a config file. Very work-in-progress right now.
Curse.ShowMessagebox("Memphis can't run properly this system.", "Memphis needs at least one FAT partition on a Master Boot Record to be able to store it's configuration and other files on. Please use a partition utility like GParted to partition your hard drive properly.");
But have a look at what comes out onto my screen...
The messagebox coming out of the above method call
As you can see, not really the thing I want. It's missing some of the string!