1
1
Fork
You've already forked catui
0
CatUI is a TUI library that provides components for creating text editors
  • C++ 92.4%
  • Makefile 7.6%
Find a file
2026年06月13日 04:17:05 +00:00
examples add make fmt for astyle format and standar 2 indent 2026年06月13日 04:17:05 +00:00
include/catui add make fmt for astyle format and standar 2 indent 2026年06月13日 04:17:05 +00:00
src add make fmt for astyle format and standar 2 indent 2026年06月13日 04:17:05 +00:00
tests add make fmt for astyle format and standar 2 indent 2026年06月13日 04:17:05 +00:00
.gitignore fix: prevent double-draw and edge cases in draw_rect 2026年06月13日 02:49:35 +00:00
Makefile add make fmt for astyle format and standar 2 indent 2026年06月13日 04:17:05 +00:00
README.md add tests suite and API Examples 2026年06月13日 03:44:57 +00:00

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/right
  • i - Enter Insert mode
  • d - Delete selection
  • y - Yank (copy) selection
  • p - Paste
  • Esc - Clear selection
  • q - Quit

Insert Mode

  • Esc - Return to Normal mode
  • Enter - Insert newline
  • Backspace - 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:

  1. Steps to reproduce
  2. Expected behavior
  3. Actual behavior
  4. 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 (C) 2024-2026 R3noDev