| examples | add make fmt for astyle format and standar 2 indent | |
| include/catui | add make fmt for astyle format and standar 2 indent | |
| src | add make fmt for astyle format and standar 2 indent | |
| tests | add make fmt for astyle format and standar 2 indent | |
| .gitignore | fix: prevent double-draw and edge cases in draw_rect | |
| Makefile | add make fmt for astyle format and standar 2 indent | |
| README.md | add tests suite and API Examples | |
CatUI
Text User Interface (TUI) library for building text editors in the terminal.
Version 0.1 - Helix-style editor with gap buffer text storage.
Overview
CatUI provides a set of components for creating terminal-based text editors, including:
- Terminal management and raw mode handling (via termbox2)
- Double-buffered screen rendering
- Gap buffer data structure for efficient text editing
- Canvas drawing primitives (rectangles, lines, text)
- Styled output with colors and attributes
- Event handling for keyboard and mouse input
- Selection-first editing (Helix-style)
Building
Prerequisites
- GNU Make
- C++17 compatible compiler (GCC or Clang)
- termbox2 library
Install termbox2
make install-termbox
Build the library and demo
make
Run the demo
make run
Development build with sanitizers
make dev
Project Structure
catui/
├── bin/ # Compiled binaries
├── build/ # Object files
├── examples/ # Example programs
│ ├── 01_hello_world.cpp
│ ├── 02_shapes.cpp
│ ├── 03_colors.cpp
│ ├── 04_input.cpp
│ ├── 05_animation.cpp
│ ├── 06_mouse.cpp
│ ├── 07_notepad.cpp
│ ├── 08_menu.cpp
│ ├── 09_gap_buffer.cpp
│ └── 10_calculator.cpp
├── include/catui/ # Public headers
│ ├── core/ # Terminal, buffer, events, point
│ ├── editor/ # Editor, gap buffer, mode, selection
│ └── render/ # Canvas and style
├── src/ # Implementation files
│ ├── core/
│ └── editor/
├── Makefile
└── README.md
Examples
Basic Examples
01_hello_world.cpp
Simple "Hello World" demonstration showing basic terminal initialization and text rendering.
02_shapes.cpp
Demonstrates drawing shapes including rectangles, horizontal/vertical lines, and nested shapes with different colors.
03_colors.cpp
Shows the complete color palette with various text styles (bold, italic, underline) and color combinations.
Intermediate Examples
04_input.cpp
Keyboard input handling example showing how to capture and display keystrokes in real-time.
05_animation.cpp
Simple bouncing ball animation demonstrating frame-by-frame rendering and animation loops.
06_mouse.cpp
Mouse input handling with interactive buttons that respond to hover and click events.
Advanced Examples
07_notepad.cpp
Full-featured notepad application using the Editor component with Helix-style keybindings.
08_menu.cpp
Interactive menu system with keyboard navigation, selection highlighting, and separators.
09_gap_buffer.cpp
Demonstrates the gap buffer data structure API for efficient text manipulation.
10_calculator.cpp
Simple calculator application with expression evaluation and a visual keypad.
Running Examples
To compile and run individual examples:
# Compile an example
g++ -std=c++17 -Iinclude examples/01_hello_world.cpp src/core/*.cpp src/editor/*.cpp -o hello_demo -ltermbox2
# Run it
./hello_demo
API Usage
Basic Terminal Setup
#include "catui/catui.hpp"
int main() {
using namespace catui;
// Initialize terminal
term::Terminal term;
if (!term.init()) {
std::cerr << "Failed to initialize terminal\n";
return 1;
}
// Create screen buffer
ScreenBuffer buffer(term.width(), term.height());
// Draw styled text
Style title_style = Style()
.with_fg(Color::Cyan())
.with_bold(true);
buffer.draw_text(10, 5, "Hello, CatUI!", title_style);
// Render to terminal
buffer.present(term);
// Wait for input
term.poll_event();
// Cleanup
term.shutdown();
return 0;
}
Using the Editor Component
#include "catui/catui.hpp"
using namespace catui;
using namespace catui::editor;
int main() {
term::Terminal term;
term.init();
Editor editor;
editor.set_content("Hello, World!");
editor.set_mode(Mode::Normal);
ScreenBuffer screen(term.width(), term.height());
// Main loop
bool running = true;
while (running) {
auto event = term.poll_event();
if (event) {
if (auto* key_ev = std::get_if<KeyEvent>(&*event)) {
if (key_ev->ch == 'q') {
running = false;
} else if (key_ev->ch == 'i') {
editor.set_mode(Mode::Insert);
}
// Handle other keys...
}
}
screen.clear();
Rect viewport = {0, 0, term.width(), term.height() - 1};
editor.render(screen, viewport);
screen.present(term);
}
term.shutdown();
return 0;
}
Drawing Shapes
// Draw a rectangle
buffer.draw_rect(5, 5, 20, 10, Style().with_fg(Color::Blue()));
// Draw horizontal line
buffer.draw_hline(5, 10, 30, Style().with_fg(Color::Green()));
// Draw vertical line
buffer.draw_vline(10, 5, 15, Style().with_fg(Color::Red()));
Color and Style System
// Create custom style
Style my_style = Style()
.with_fg(Color::Cyan())
.with_bg(Color::DarkGray())
.with_bold(true)
.with_underline(true);
// Available colors
Color::White(), Color::Black(), Color::Red(), Color::Green(),
Color::Blue(), Color::Yellow(), Color::Magenta(), Color::Cyan(),
Color::Gray(), Color::DarkGray()
Event Handling
auto event = term.poll_event();
if (event) {
if (auto* key_ev = std::get_if<KeyEvent>(&*event)) {
if (key_ev->key == Key::Escape) {
// Handle escape key
} else if (key_ev->ch == 'a') {
// Handle character 'a'
}
} else if (auto* mouse_ev = std::get_if<MouseEvent>(&*event)) {
int x = mouse_ev->x;
int y = mouse_ev->y;
// Handle mouse at position (x, y)
} else if (auto* resize_ev = std::get_if<ResizeEvent>(&*event)) {
int new_width = resize_ev->width;
int new_height = resize_ev->height;
// Handle resize
}
}
Key Bindings (Editor)
The editor uses Helix-style selection-first editing:
Normal Mode
h/j/k/l- Move cursor left/down/up/righti- Enter Insert moded- Delete selectiony- Yank (copy) selectionp- PasteEsc- Clear selectionq- Quit
Insert Mode
Esc- Return to Normal modeEnter- Insert newlineBackspace- Delete character before cursor- Any printable character - Insert character
Known Issues
- API is still evolving and may change
- Limited Unicode support
- No undo/redo functionality yet
- Basic clipboard (internal only)
- No syntax highlighting
Contributing
Bug reports and patches are welcome. Please include:
- Steps to reproduce
- Expected behavior
- Actual behavior
- Terminal emulator and version
License
This project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Copyright
Copyright (C) 2024-2026 R3noDev