boxes now available

This commit is contained in:
2026-04-20 19:50:51 -06:00
parent e8881f3a76
commit fa519d937f
7 changed files with 148 additions and 15 deletions

View File

@@ -1,4 +1,5 @@
#include <desktoplib/terminal/Terminal.hpp> #include <desktoplib/terminal/Terminal.hpp>
#include <desktoplib/terminal/ui/Box.hpp>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <thread> #include <thread>
@@ -12,7 +13,7 @@ int main() {
term.altbuff(true) // Use alternative buffer (clean exit) term.altbuff(true) // Use alternative buffer (clean exit)
.cursor(false) // Hide cursor for cleaner UI .cursor(false) // Hide cursor for cleaner UI
.cls() // Clear screen .cls() // Clear screen
.fill("\033[48;2;20;20;20m"); // Fill background with dark grey (RGB) .fill(color::B_BLACK); // Fill background with dark grey (RGB)
// 2. Draw a Header using subprint and center // 2. Draw a Header using subprint and center
term << pos{ 1, 1 } << backg::BLUE << color::WHITE << style::BOLD; term << pos{ 1, 1 } << backg::BLUE << color::WHITE << style::BOLD;
@@ -49,6 +50,13 @@ int main() {
term << pos{ 2, term.getSize().y - 2 } << style::FAINT term << pos{ 2, term.getSize().y - 2 } << style::FAINT
<< "Press 'q' to quit, or any arrow key to move the cursor..." << style::RESET; << "Press 'q' to quit, or any arrow key to move the cursor..." << style::RESET;
Box myBox({ 5, 5 }, 30, 10, "System Logs");
myBox.charset = BoxSet::THICK; // Switch to rounded corners
myBox.borderFg = color::CYAN;
term << myBox;
term.flush();
pos player = center; pos player = center;
bool running = true; bool running = true;

View File

@@ -5,6 +5,8 @@
#include <desktoplib/os/common.hpp> #include <desktoplib/os/common.hpp>
#include <desktoplib/terminal/UI.hpp>
namespace ckitty { namespace ckitty {
namespace terminal { namespace terminal {
@@ -307,9 +309,7 @@ namespace ckitty {
// Fill padding using a string constructor or a loop // Fill padding using a string constructor or a loop
// Standard strings are easiest for repeated characters // Standard strings are easiest for repeated characters
(*_os) << std::string(left_padding, ' ') (*_os) << std::string(left_padding, ' ') << msg << std::string(right_padding, ' ');
<< msg
<< std::string(right_padding, ' ');
} }
return *this; return *this;
} }

View File

@@ -6,6 +6,8 @@
#include <sstream> #include <sstream>
#include <optional> #include <optional>
#include <desktoplib/terminal/UI.hpp>
namespace ckitty { namespace ckitty {
namespace terminal { namespace terminal {
@@ -229,7 +231,11 @@ namespace ckitty {
template <typename T> template <typename T>
Terminal& operator<<(const T& msg) { Terminal& operator<<(const T& msg) {
if constexpr (std::is_base_of_v<UI, T>) {
msg.render(*this);
} else {
(*_os) << msg; (*_os) << msg;
}
return *this; return *this;
} }

View File

@@ -0,0 +1,16 @@
#pragma once
namespace ckitty {
namespace terminal {
class Terminal;
class UI {
public:
virtual ~UI() = default;
virtual void render(Terminal& t) const = 0;
};
}
}

View File

@@ -0,0 +1,52 @@
#include "Box.hpp"
namespace ckitty::terminal {
// --- Curated Selection of Charsets ---
const BoxSet BoxSet::SINGLE = { "", "", "", "", "", "" };
const BoxSet BoxSet::DOUBLE = { "", "", "", "", "", "" };
const BoxSet BoxSet::ROUNDED = { "", "", "", "", "", "" };
const BoxSet BoxSet::ASCII = { "+", "+", "+", "+", "-", "|" };
const BoxSet BoxSet::THICK = { "", "", "", "", "", "" };
Box::Box(pos p, int w, int h, std::string t)
: position(p), width(w), height(h), title(t) {
}
void Box::render(Terminal& t) const {
// 1. Set Style
t << (selected ? selectedStyle : normalStyle);
t << borderBg << borderFg;
// 2. Top Border
t << position << charset.tl;
for (int i = 0; i < width - 2; ++i) t << charset.h;
t << charset.tr;
// 3. Sides
for (int y = 1; y < height - 1; ++y) {
t << pos{ position.x, position.y + y } << charset.v;
t << pos{ position.x + width - 1, position.y + y } << charset.v;
}
// 4. Bottom Border
t << pos{ position.x, position.y + height - 1 } << charset.bl;
for (int i = 0; i < width - 2; ++i) t << charset.h;
t << charset.br;
// 5. Title Overlay
if (!title.empty()) {
// Ensure title doesn't overflow box width
std::string_view displayTitle = title;
if (title.length() > static_cast<size_t>(width - 4)) {
displayTitle = std::string_view(title).substr(0, size_t(width - 4));
}
t << pos{ position.x + 2, position.y }
<< " " << displayTitle << " ";
}
t << style::RESET;
}
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include <desktoplib/terminal/Terminal.hpp>
#include <desktoplib/terminal/UI.hpp>
#include <string>
namespace ckitty::terminal {
struct BoxSet {
std::string_view tl, tr, bl, br, h, v; // top-left, top-right, etc.
static const BoxSet SINGLE;
static const BoxSet DOUBLE;
static const BoxSet ROUNDED;
static const BoxSet ASCII;
static const BoxSet THICK;
};
class Box : public UI {
public:
pos position;
int width, height;
std::string title;
bool selected = false;
// Visual Configuration
style normalStyle = style::RESET;
style selectedStyle = style::BOLD;
backg borderBg = backg::BLACK;
color borderFg = color::WHITE;
// The line character set
BoxSet charset = BoxSet::SINGLE;
Box(pos p, int w, int h, std::string t = "");
void render(Terminal& t) const override;
};
}

View File

@@ -0,0 +1,9 @@
#pragma once
namespace ckitty {
namespace terminal {
}
}