mirror of
https://gitlab.com/niansa/llama_nds.git
synced 2025-03-06 20:53:28 +01:00
114 lines
3 KiB
C++
114 lines
3 KiB
C++
#ifndef NDSUI_HPP
|
|
#define NDSUI_HPP
|
|
#include "basic-coro/AwaitableTask.hpp"
|
|
#include "basic-coro/SingleEvent.hpp"
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <array>
|
|
#include <vector>
|
|
|
|
|
|
class LineWrappedString {
|
|
unsigned maxCharsPerLine;
|
|
std::vector<std::string> lines;
|
|
|
|
void split(std::string_view, unsigned maxCharsPerLine);
|
|
|
|
public:
|
|
LineWrappedString(std::string_view str, unsigned maxCharsPerLine) : maxCharsPerLine(maxCharsPerLine) {
|
|
split(str, maxCharsPerLine);
|
|
}
|
|
LineWrappedString(const LineWrappedString& o) : maxCharsPerLine(o.maxCharsPerLine), lines(o.lines) {}
|
|
LineWrappedString(LineWrappedString&& o) : maxCharsPerLine(o.maxCharsPerLine), lines(std::move(o.lines)) {}
|
|
|
|
auto& operator=(LineWrappedString&& o) {
|
|
maxCharsPerLine = o.maxCharsPerLine;
|
|
lines = std::move(o.lines);
|
|
return *this;
|
|
}
|
|
auto& operator=(const LineWrappedString& o) {
|
|
maxCharsPerLine = o.maxCharsPerLine;
|
|
lines = o.lines;
|
|
return *this;
|
|
}
|
|
|
|
const std::vector<std::string>& getLines() const {
|
|
return lines;
|
|
}
|
|
};
|
|
|
|
struct Position2D {
|
|
unsigned x, y;
|
|
};
|
|
struct Box2D {
|
|
Position2D topLeft, bottomRight;
|
|
|
|
constexpr
|
|
unsigned height() const {
|
|
return bottomRight.y - topLeft.y;
|
|
}
|
|
constexpr
|
|
unsigned width() const {
|
|
return bottomRight.x - topLeft.x;
|
|
}
|
|
};
|
|
|
|
class NDSUI {
|
|
static NDSUI *currentInstance; // Currently updating instance
|
|
std::array<char, 512> inputLineBuf;
|
|
unsigned inputLineBufHead = 0;
|
|
std::vector<LineWrappedString> messages;
|
|
std::unique_ptr<basiccoro::SingleEvent<std::string>> userInputHandler = nullptr;
|
|
unsigned boxesRendered;
|
|
unsigned scrollOff = 0;
|
|
|
|
static void kbCallback(int key);
|
|
|
|
static consteval
|
|
Box2D calcInputLineDimensions();
|
|
static consteval
|
|
Box2D calcMessageLogDimensions();
|
|
|
|
void renderMessageLog();
|
|
void renderInputLine();
|
|
|
|
static consteval
|
|
unsigned calcMaxCharsInLine(unsigned width);
|
|
static consteval
|
|
unsigned calcMaxLinesInRow(unsigned height);
|
|
|
|
bool printChar(const char character, Position2D *topleftpos, const int color, bool bold = false);
|
|
void print(std::string_view str, Position2D topleftpos, const int color, bool bold = false);
|
|
|
|
void handleInput(char);
|
|
|
|
void scanButtons();
|
|
|
|
void resetInputLine() {
|
|
inputLineBufHead = 0;
|
|
inputLineBuf[0] = '\0';
|
|
}
|
|
|
|
public:
|
|
NDSUI();
|
|
|
|
bool shouldRun() const {
|
|
return userInputHandler != nullptr;
|
|
}
|
|
void run();
|
|
|
|
auto& addLogMessage(LineWrappedString &&msg) {
|
|
return messages.emplace_back(std::move(msg));
|
|
}
|
|
|
|
basiccoro::AwaitableTask<std::string> readLine() {
|
|
userInputHandler = std::make_unique<std::remove_reference<decltype(*userInputHandler)>::type>();
|
|
co_return co_await *userInputHandler;
|
|
}
|
|
|
|
static
|
|
LineWrappedString createLogMessage(const char *username, std::string_view message);
|
|
};
|
|
#endif // NDSUI_HPP
|