create ShowFatalError method

This commit is contained in:
Slavasil 2025-03-23 21:21:39 +03:00
parent f2653e66d4
commit b8d73df4b9

View File

@ -12,6 +12,10 @@ namespace Game.UI {
private const string HIDECURSOR_SEQ = "\e[?25l"; private const string HIDECURSOR_SEQ = "\e[?25l";
private const string SHOWCURSOR_SEQ = "\e[?25h"; private const string SHOWCURSOR_SEQ = "\e[?25h";
private readonly char[] SIMPLE_BOX_CHARS = { '─', '│', '┌', '┐', '└', '┘' };
private readonly char[] DOUBLE_BOX_CHARS = { '═', '║', '╔', '╗', '╚', '╝' };
private readonly char[] FALLBACK_BOX_CHARS = { '-', '|', '+', '+', '+', '+' };
private int currentFgColor = 0xffffff, currentBgColor = 0; private int currentFgColor = 0xffffff, currentBgColor = 0;
private int cursorRow = 0, cursorCol = 0; private int cursorRow = 0, cursorCol = 0;
private int windowWidth = 0, windowHeight = 0; private int windowWidth = 0, windowHeight = 0;
@ -72,6 +76,11 @@ namespace Game.UI {
DrawCopyright(0x5e61ed); DrawCopyright(0x5e61ed);
} }
public void ShowFatalError(string text) {
ClearWithColor(0xfc5d2d);
DrawTextBox(HAlignment.Center, VAlignment.Center, BoxType.Double, windowHeight / 2 + 1, windowWidth / 2 + 1, text, 0xffffff, 0xffffff, 0xfc5d2d, windowWidth / 2);
}
void DrawTitle(int y, int bgColor) { void DrawTitle(int y, int bgColor) {
string text1 = "КТО ХОЧЕТ СТАТЬ"; string text1 = "КТО ХОЧЕТ СТАТЬ";
string text2 = "СЕКУНДОМЕРОМ"; string text2 = "СЕКУНДОМЕРОМ";
@ -104,6 +113,75 @@ namespace Game.UI {
WriteColored(bottomText, 0x4d4dc0, bgColor); WriteColored(bottomText, 0x4d4dc0, bgColor);
} }
void DrawTextBox(HAlignment hAlign, VAlignment vAlign, BoxType boxType, int y, int x, string text, int borderColor, int textColor, int bgColor = -1, int preferredWidth = -1) {
int maxWidth = windowWidth;
switch (hAlign) {
case HAlignment.Left:
maxWidth = windowWidth - x + 1;
break;
case HAlignment.Center:
maxWidth = Math.Min(x - 1, windowWidth - x + 1) * 2;
break;
case HAlignment.Right:
maxWidth = x - 1;
break;
}
int maxHeight = windowHeight;
switch (vAlign) {
case VAlignment.Top:
maxHeight = windowHeight - y + 1;
break;
case VAlignment.Center:
maxHeight = Math.Min(y - 1, windowHeight - y + 1) * 2;
break;
case VAlignment.Bottom:
maxHeight = y - 1;
break;
}
string[] lines = WordWrap(text, (preferredWidth == -1 ? maxWidth : preferredWidth) - 4, out bool overflow);
bool reflowed = false;
if (preferredWidth != -1 && lines.Length > maxHeight - 4) {
reflowed = true;
lines = WordWrap(text, maxWidth - 4, out overflow);
}
int actualWidth = Math.Min(preferredWidth == -1 ? maxWidth : (reflowed ? maxWidth : preferredWidth), lines.Max(s => s.Length) + 4);
int actualHeight = Math.Min(maxHeight, lines.Length + 4);
int left = hAlign == HAlignment.Left ? x : (hAlign == HAlignment.Right ? x - actualWidth + 1 : x - (actualWidth - 1) / 2);
int top = vAlign == VAlignment.Top ? y : (vAlign == VAlignment.Bottom ? y - actualHeight + 1 : y - (actualHeight - 1) / 2);
DrawBox(boxType, top, left, actualHeight, actualWidth, borderColor, bgColor);
SetColors(textColor, -1);
for (int i = 0; i < actualHeight - 4; ++i) {
SetCursor(top + 2 + i, left + 2);
WriteColored(lines[i], textColor, bgColor);
}
}
public void DrawBox(BoxType boxType, int y, int x, int h, int w, int borderColor, int bgColor = -1) {
char[] boxChars = boxType == BoxType.Simple ? SIMPLE_BOX_CHARS : (boxType == BoxType.Double ? DOUBLE_BOX_CHARS : FALLBACK_BOX_CHARS);
SetColors(borderColor, bgColor);
SetCursor(y, x);
StringBuilder output = new StringBuilder();
output.Append(boxChars[2]);
output.Append(boxChars[0], w - 2);
output.Append(boxChars[3]);
WriteColored(output.ToString(), borderColor, bgColor);
for (int i = 0; i < h - 2; ++i) {
output.Clear();
SetCursor(y + 1 + i, x);
output.Append(boxChars[1]);
output.Append(' ', w - 2);
output.Append(boxChars[1]);
WriteColored(output.ToString(), borderColor, bgColor);
}
SetCursor(y + h - 1, x);
output.Clear();
output.Append(boxChars[4]);
output.Append(boxChars[0], w - 2);
output.Append(boxChars[5]);
WriteColored(output.ToString(), borderColor, bgColor);
}
public void WriteColored(string s, int color, int bgColor = -1) { public void WriteColored(string s, int color, int bgColor = -1) {
if (color == -1) color = currentFgColor; if (color == -1) color = currentFgColor;
(int r, int g, int b) = ((color >> 16) & 255, (color >> 8) & 255, color & 255); (int r, int g, int b) = ((color >> 16) & 255, (color >> 8) & 255, color & 255);
@ -152,6 +230,51 @@ namespace Game.UI {
//return (int)(fg * alpha + bg * (1f - alpha)); //return (int)(fg * alpha + bg * (1f - alpha));
return ((int)(((fg >> 16) & 255) * alpha + ((bg >> 16) & 255) * (1 - alpha)) << 16) + ((int)(((fg >> 8) & 255) * alpha + ((bg >> 8) & 255) * (1 - alpha)) << 8) + (int)((fg & 255) * alpha + (bg & 255) * (1 - alpha)); return ((int)(((fg >> 16) & 255) * alpha + ((bg >> 16) & 255) * (1 - alpha)) << 16) + ((int)(((fg >> 8) & 255) * alpha + ((bg >> 8) & 255) * (1 - alpha)) << 8) + (int)((fg & 255) * alpha + (bg & 255) * (1 - alpha));
} }
public string[] WordWrap(string text, int width, out bool overflow) {
overflow = false;
List<string> lines = new List<string>();
StringBuilder line = new StringBuilder(text.Length / width * 4 / 3);
int remaining = width;
foreach (string word in text.Split(new char[] {' ', '\n'}, StringSplitOptions.RemoveEmptyEntries)) {
if (word.Length <= remaining) {
if (line.Length == 0 || line[^1] != ' ') {
line.Append(' ');
remaining -= 1;
}
line.Append(word);
remaining -= word.Length;
} else {
lines.Add(line.ToString());
line.Clear();
line.Append(word);
remaining = width - word.Length;
if (remaining < 0) {
overflow = true;
line.Remove(width + 1, line.Length - (width + 1));
lines.Add(line.ToString());
line.Clear();
}
}
}
if (line.Length > 0)
lines.Add(line.ToString());
return lines.ToArray();
}
public enum HAlignment {
Left, Center, Right
}
public enum VAlignment {
Top, Center, Bottom
}
public enum BoxType {
Simple,
Double,
Fallback,
}
} }
static class Win32Imports static class Win32Imports