pureikyubu/RnD/OldDebugConsole/Cui.cpp
2020-07-26 22:38:14 +03:00

259 lines
4.9 KiB
C++

#include "pch.h"
namespace Debug
{
#pragma region "Cui"
Cui::Cui(std::string title, size_t width, size_t height)
{
conWidth = width;
conHeight = height;
AllocConsole();
StdInput = GetStdHandle(STD_INPUT_HANDLE);
assert(StdInput != INVALID_HANDLE_VALUE);
StdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
assert(StdOutput != INVALID_HANDLE_VALUE);
// Disable mouse input
DWORD flags;
GetConsoleMode(StdInput, &flags);
flags &= ~ENABLE_MOUSE_INPUT;
SetConsoleMode(StdInput, flags);
// Resize console
COORD coord;
SMALL_RECT rect;
rect.Top = rect.Left = 0;
rect.Right = (SHORT)width - 1;
rect.Bottom = (SHORT)height - 1;
coord.X = (SHORT)width;
coord.Y = (SHORT)height;
SetConsoleWindowInfo(StdOutput, TRUE, &rect);
SetConsoleScreenBufferSize(StdOutput, coord);
SetConsoleTitleA(title.c_str());
cuiThread = new Thread(CuiThreadProc, false, this, "CuiThread");
assert(cuiThread);
}
Cui::~Cui()
{
delete cuiThread;
while (!windows.empty())
{
CuiWindow* wnd = windows.back();
windows.pop_back();
delete wnd;
}
FreeConsole();
}
void Cui::CuiThreadProc(void* Parameter)
{
INPUT_RECORD record;
DWORD count;
Cui* cui = (Cui*)Parameter;
while (true)
{
Sleep(10);
// Update
for (auto it = cui->windows.begin(); it != cui->windows.end(); ++it)
{
CuiWindow* wnd = *it;
if (wnd->invalidated)
{
wnd->OnDraw();
cui->BlitWindow(wnd);
wnd->invalidated = false;
}
}
// Pass key event
PeekConsoleInput(cui->StdInput, &record, 1, &count);
if (!count)
continue;
ReadConsoleInput(cui->StdInput, &record, 1, &count);
if (!count)
continue;
if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
{
char ascii = record.Event.KeyEvent.uChar.AsciiChar;
int vcode = record.Event.KeyEvent.wVirtualKeyCode;
int ctrl = record.Event.KeyEvent.dwControlKeyState;
bool shiftPressed = ctrl & SHIFT_PRESSED;
bool ctrlPressed = ctrl & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED);
cui->OnKeyPress(ascii, vcode, shiftPressed, ctrlPressed);
for (auto it = cui->windows.begin(); it != cui->windows.end(); ++it)
{
CuiWindow* wnd = *it;
if (wnd->active)
{
wnd->OnKeyPress(ascii, vcode, shiftPressed, ctrlPressed);
}
}
}
}
}
void Cui::AddWindow(CuiWindow* wnd)
{
windows.push_back(wnd);
}
void Cui::SetWindowFocus(std::string name)
{
for (auto it = windows.begin(); it != windows.end(); ++it)
{
CuiWindow* wnd = *it;
wnd->SetFocus(wnd->wndName == name);
}
}
void Cui::OnKeyPress(char Ascii, int Vkey, bool shift, bool ctrl)
{
}
void Cui::ShowCursor(bool show)
{
CONSOLE_CURSOR_INFO info = { 0 };
info.bVisible = show;
info.dwSize = 1;
SetConsoleCursorInfo(StdOutput, &info);
}
void Cui::SetCursor(COORD& pos)
{
SetConsoleCursorPosition(StdOutput, pos);
}
void Cui::BlitWindow(CuiWindow* wnd)
{
COORD sz;
sz.X = (SHORT)wnd->width;
sz.Y = (SHORT)wnd->height;
COORD pos;
pos.X = 0;
pos.Y = 0;
SMALL_RECT rgn;
rgn.Left = (SHORT)wnd->wndRect.left;
rgn.Top = (SHORT)wnd->wndRect.top;
rgn.Right = (SHORT)wnd->wndRect.right;
rgn.Bottom = (SHORT)wnd->wndRect.bottom;
WriteConsoleOutput(StdOutput, wnd->backBuf, sz, pos, &rgn);
}
void Cui::InvalidateAll()
{
for (auto it = windows.begin(); it != windows.end(); ++it)
{
CuiWindow* wnd = *it;
wnd->Invalidate();
}
}
#pragma endregion "Cui"
#pragma region "CuiWindow"
CuiWindow::CuiWindow(RECT& rect, std::string name)
{
wndRect = rect;
wndName = name;
width = (size_t)rect.right - (size_t)rect.left + 1;
height = (size_t)rect.bottom - (size_t)rect.top + 1;
backBuf = new CHAR_INFO[width * height];
assert(backBuf);
memset(backBuf, 0, width * height * sizeof(CHAR_INFO));
}
CuiWindow::~CuiWindow()
{
delete[] backBuf;
}
void CuiWindow::PutChar(CuiColor back, CuiColor front, int x, int y, char c)
{
if (x < 0 || x >= width)
return;
if (y < 0 || y >= height)
return;
CHAR_INFO* info = &backBuf[y * width + x];
info->Attributes = ((int)back << 4) | (int)front;
info->Char.AsciiChar = c;
}
void CuiWindow::Print(CuiColor back, CuiColor front, int x, int y, std::string text)
{
for (auto it = text.begin(); it != text.end(); ++it)
{
PutChar(back, front, x++, y, *it >= ' ' ? *it : ' ' );
}
}
void CuiWindow::Print(CuiColor back, CuiColor front, int x, int y, const char* fmt, ...)
{
char buf[0x1000];
va_list arg;
va_start(arg, fmt);
vsprintf_s(buf, sizeof(buf) - 1, fmt, arg);
va_end(arg);
std::string text = buf;
Print(back, front, x, y, text);
}
void CuiWindow::Fill(CuiColor back, CuiColor front, char c)
{
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
PutChar(back, front, x, y, c);
}
}
}
void CuiWindow::FillLine(CuiColor back, CuiColor front, int y, char c)
{
for (int x = 0; x < width; x++)
{
PutChar(back, front, x, y, c);
}
}
#pragma endregion "CuiWindow"
}