From fa519d937f05a4ccafccc3d62f37e3454fdf6a68 Mon Sep 17 00:00:00 2001 From: Kittycannon Date: Mon, 20 Apr 2026 19:50:51 -0600 Subject: [PATCH] boxes now available --- src/desktoplib/main.cpp | 30 ++++++++++------ src/desktoplib/terminal/Terminal.cpp | 6 ++-- src/desktoplib/terminal/Terminal.hpp | 8 ++++- src/desktoplib/terminal/UI.hpp | 16 +++++++++ src/desktoplib/terminal/ui/Box.cpp | 52 ++++++++++++++++++++++++++++ src/desktoplib/terminal/ui/Box.hpp | 42 ++++++++++++++++++++++ src/desktoplib/terminal/ui/Theme.hpp | 9 +++++ 7 files changed, 148 insertions(+), 15 deletions(-) create mode 100644 src/desktoplib/terminal/UI.hpp create mode 100644 src/desktoplib/terminal/ui/Box.cpp create mode 100644 src/desktoplib/terminal/ui/Theme.hpp diff --git a/src/desktoplib/main.cpp b/src/desktoplib/main.cpp index c1cafd0..dc5a375 100644 --- a/src/desktoplib/main.cpp +++ b/src/desktoplib/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -12,27 +13,27 @@ int main() { term.altbuff(true) // Use alternative buffer (clean exit) .cursor(false) // Hide cursor for cleaner UI .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 - term << pos{1, 1} << backg::BLUE << color::WHITE << style::BOLD; + term << pos{ 1, 1 } << backg::BLUE << color::WHITE << style::BOLD; term.center(term.getSize().x, " TERMINAL LIBRARY TEST SUITE "); term << style::RESET; // 3. Demonstrate Cartesian Positioning and Colors pos center = { term.getSize().x / 2, term.getSize().y / 2 }; - term << pos{center.x - 10, 5} << color::GREEN << "Green Text at (x-10, 5)" - << pos{center.x - 10, 6} << color::B_RED << style::ITALIC << "Bright Red Italic" - << style::RESET; + term << pos{ center.x - 10, 5 } << color::GREEN << "Green Text at (x-10, 5)" + << pos{ center.x - 10, 6 } << color::B_RED << style::ITALIC << "Bright Red Italic" + << style::RESET; // 4. Test RGB and HSL colors - term << pos{2, 10} << "RGB Test: "; + term << pos{ 2, 10 } << "RGB Test: "; for (int i = 0; i < 5; ++i) { term << color::rgb(50 * i, 255 - (50 * i), 150) << "■ "; } - term << pos{2, 11} << "HSL Test: "; + term << pos{ 2, 11 } << "HSL Test: "; for (float h = 0.0f; h < 1.0f; h += 0.2f) { term << color::hsl(h, 0.8f, 0.5f) << "■ "; } @@ -40,14 +41,21 @@ int main() { // 5. Test subprint_center std::string long_msg = "This is a very long string that we will slice and center."; - term << pos{1, 15} << color::YELLOW; + term << pos{ 1, 15 } << color::YELLOW; // Centers only the word "long string" in a width of 40 - term.subprint_center(10, 21, long_msg); + term.subprint_center(10, 21, long_msg); term << style::RESET; // 6. Interaction Loop - term << pos{2, term.getSize().y - 2} << style::FAINT - << "Press 'q' to quit, or any arrow key to move the cursor..." << style::RESET; + term << pos{ 2, term.getSize().y - 2 } << style::FAINT + << "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; bool running = true; diff --git a/src/desktoplib/terminal/Terminal.cpp b/src/desktoplib/terminal/Terminal.cpp index 7cf12bc..01618e9 100644 --- a/src/desktoplib/terminal/Terminal.cpp +++ b/src/desktoplib/terminal/Terminal.cpp @@ -5,6 +5,8 @@ #include +#include + namespace ckitty { namespace terminal { @@ -307,9 +309,7 @@ namespace ckitty { // Fill padding using a string constructor or a loop // Standard strings are easiest for repeated characters - (*_os) << std::string(left_padding, ' ') - << msg - << std::string(right_padding, ' '); + (*_os) << std::string(left_padding, ' ') << msg << std::string(right_padding, ' '); } return *this; } diff --git a/src/desktoplib/terminal/Terminal.hpp b/src/desktoplib/terminal/Terminal.hpp index b6fe742..157819e 100644 --- a/src/desktoplib/terminal/Terminal.hpp +++ b/src/desktoplib/terminal/Terminal.hpp @@ -6,6 +6,8 @@ #include #include +#include + namespace ckitty { namespace terminal { @@ -229,7 +231,11 @@ namespace ckitty { template Terminal& operator<<(const T& msg) { - (*_os) << msg; + if constexpr (std::is_base_of_v) { + msg.render(*this); + } else { + (*_os) << msg; + } return *this; } diff --git a/src/desktoplib/terminal/UI.hpp b/src/desktoplib/terminal/UI.hpp new file mode 100644 index 0000000..981c70e --- /dev/null +++ b/src/desktoplib/terminal/UI.hpp @@ -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; + }; + + } +} \ No newline at end of file diff --git a/src/desktoplib/terminal/ui/Box.cpp b/src/desktoplib/terminal/ui/Box.cpp new file mode 100644 index 0000000..48ffaf1 --- /dev/null +++ b/src/desktoplib/terminal/ui/Box.cpp @@ -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(width - 4)) { + displayTitle = std::string_view(title).substr(0, size_t(width - 4)); + } + + t << pos{ position.x + 2, position.y } + << " " << displayTitle << " "; + } + + t << style::RESET; + } + +} diff --git a/src/desktoplib/terminal/ui/Box.hpp b/src/desktoplib/terminal/ui/Box.hpp index e69de29..03e727e 100644 --- a/src/desktoplib/terminal/ui/Box.hpp +++ b/src/desktoplib/terminal/ui/Box.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +#include + +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; + }; + +} \ No newline at end of file diff --git a/src/desktoplib/terminal/ui/Theme.hpp b/src/desktoplib/terminal/ui/Theme.hpp new file mode 100644 index 0000000..5918b97 --- /dev/null +++ b/src/desktoplib/terminal/ui/Theme.hpp @@ -0,0 +1,9 @@ +#pragma once + + +namespace ckitty { + namespace terminal { + + + } +} \ No newline at end of file