2026-08-25 01:52:39 +07:00
2026-08-25 01:52:39 +07:00
2026-08-25 01:40:01 +07:00
2026-08-25 01:40:01 +07:00
2026-08-25 01:40:01 +07:00
2026-08-25 01:52:39 +07:00

X11 GUI Library

Platform C++ License

Лёгкая GUI-библиотека для C++20 на X11: программный рендеринг, частичная перерисовка (dirty rectangles), TTF-шрифты (FreeType), две темы (WIN11 / TERMINAL), плавные анимации и встроенная отладка как в Android Studio.


✨ Возможности

  • Частичная перерисовка — обновляются только изменённые области, а не весь экран
  • Двойная буферизация — без мерцания
  • TTF/TTC шрифты через FreeType с кешированием (быстрый текст)
  • Две темы: WIN11 (скругления, синий акцент) и TERMINAL (квадратная, зелёная) + полная кастомизация
  • Анимации: hover, нажатие (push-down), галочки, dropdown, мигающий курсор
  • EventBus + колбэки на виджетах
  • Отладка: оверлей FPS, визуализация dirty-областей, маркеры кликов, границы виджетов (F1–F6)
  • Только активная страница рендерится — остальные не жгут CPU

🖼 Скриншоты

Темы

WIN11 TERMINAL
win11 terminal

Переключение на лету — клавиша F6.

Виджеты

Controls (кнопки, ввод, чекбоксы, слайдер, прогресс) Lists (список, dropdown, дерево, скролл)
controls lists
Graphics (RawPicture: круги, полигоны, текст)
graphics

Отладка

| Debug overlay (F1) — FPS, виджеты, partial updates, лог событий | Dirty rectangles (F2) — подсветка перерисованных областей | |:---:| | overlay |


🚀 Быстрый старт

#include "gui.h"

int main() {
    gui::set_theme(gui::ThemeStyle::WIN11);
    gui::window win("My App");
    win.set_font("SGr-Iosevka-Regular.ttc");   // любой TTF/TTC рядом с бинарником
    win.set_default_icon();

    win.configur_page("main", [](gui::page& p) {
        gui::WidgetData b;
        b.id = "btn"; b.text = "Hello";
        b.x = 100; b.y = 100; b.width = 300; b.height = 70;
        b.primary = true;                       // акцентная кнопка
        p.Button(b);
    }, true);

    gui::EventBus::get().on("button.click", [](const gui::EventData& e) {
        std::cout << "clicked: " << e.source_id << "\n";
    });

    while (win.running()) win.update();
    return 0;
}

Или просто запусти демо со всеми виджетами:

#include "gui.h"
int main() { gui::run_demo(); }

🛠 Сборка

Зависимости

# Ubuntu/Debian
sudo apt install libx11-dev libfreetype-dev cmake g++

# Fedora
sudo dnf install libX11-devel freetype-devel cmake gcc-c++

# Arch
sudo pacman -S libx11 freetype2 cmake

CMake

cmake_minimum_required(VERSION 3.10)
project(host)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(X11 REQUIRED)
find_package(Freetype REQUIRED)

add_executable(host
    main.cpp
    libs/gui/core/event_bus.cpp
    libs/gui/core/raw_picture.cpp
    libs/gui/core/font_manager.cpp
    libs/gui/core/theme.cpp
    libs/gui/widgets/widget.cpp
    libs/gui/widgets/draw_basic.cpp
    libs/gui/widgets/draw_toggles.cpp
    libs/gui/widgets/draw_lists.cpp
    libs/gui/window.cpp
    libs/gui/demo.cpp
)
target_include_directories(host PRIVATE libs/gui ${X11_INCLUDE_DIR})
target_link_libraries(host PRIVATE ${X11_LIBRARIES} Freetype::Freetype)
mkdir build && cd build
cmake ..
make -j$(nproc)
./host

Положи SGr-Iosevka-Regular.ttc (или любой TTF) рядом с бинарником. Если шрифт не найден — используется фолбэк на X11 core font.


🧩 Виджеты

Метод Тип Описание
Button(d) BUTTON Кнопка (primary = true — акцентная)
Label(d) LABEL Текстовая метка
Input(d) INPUT Поле ввода: клик — фокус, нижняя линия, мигающий курсор, Enter — input.submit
Checkbox(d) CHECKBOX Флажок с анимированной галочкой
Radiobutton(d) RADIO Радио-кнопка (группа по id)
Slider(d) SLIDER Ползунок 0..1, перетаскивание
Progressbar(d) PROGRESS Прогресс (+ indeterminate — бегущий)
Listbox(d) LISTBOX Список с прокруткой и выделением
Dropdown(d) DROPDOWN Выпадающий список с анимацией
TreeView(d) + TreeNode(d) TREE_VIEW / TREE Дерево с раскрытием [+]/[-]
ScrollView(d) SCROLL Контейнер с прокруткой
RawPictureWidget(d) RAW_PIC Картинка из RawPicture
SpriteButton(d) SPRITE_BTN Кликабельный спрайт

Основные поля WidgetData

std::string id, text;          // идентификатор и подпись
int x, y, width, height;       // геометрия (масштаб x2)
unsigned long bg_color, fg_color, frame_color; // 0 = из темы, иначе override
int font_size;                 // 0 = системный, иначе свой
bool primary;                  // акцентная кнопка
bool checked;                  // checkbox / radio
float value, target_value;     // slider / progress (0..1)
std::vector<std::string> items;// listbox / dropdown
std::shared_ptr<RawPicture> picture;
// колбэки:
on_change / on_page_click / on_window_click

🐞 Отладка

Горячие клавиши

Клавиша Действие
F1 Debug overlay: FPS, кол-во виджетов, счётчик partial updates, координаты мыши, лог последних событий
F2 Визуализация dirty rectangles — мигание перерисованных областей (как «Show screen updates» в Android)
F3 Маркеры кликов — красный крестик в точке нажатия
F4 Границы всех виджетов (magenta)
F5 Логирование событий в консоль
F6 Переключение темы WIN11 ↔ TERMINAL

Как читать оверлей (F1)

  • FPS — реальная частота перерисовок (в простое ~0, при анимациях до max_fps)
  • Widgets — виджетов на активной странице
  • Partial updates — сколько dirty-областей перерисовано всего. Растёт медленно = оптимизация работает
  • Mouse — координаты курсора
  • EVENT LOG — последние 5 событий шины

Что показывает F2

Каждая перерисованная область на 0.2 сек подсвечивается XOR-цветом. Наведи на кнопку — мигнёт только она. Двинь слайдер — мигнёт только слайдер. Если мигает весь экран — значит ты сам позвал mark_all_dirty().

Программное управление

win.debug().show_debug_overlay = true;   // F1
win.debug().show_dirty_rects   = true;   // F2
win.debug().show_click_markers = true;   // F3
win.debug().show_widget_bounds = true;   // F4
win.debug().log_to_console     = true;   // F5
win.debug().max_log_size       = 30;

win.mark_dirty(x, y, w, h);  // пометить область как грязную
win.mark_all_dirty();        // перерисовать всё
win.set_max_fps(144);        // лимит кадров

  1. Что снять (имена файлов = ссылки в README):
Файл Что показать
theme_win11.png демо в теме WIN11
theme_terminal.png нажми F6 → тема TERMINAL
widgets_controls.png страница controls
widgets_lists.png страница lists
widgets_graphics.png страница graphics
debug_overlay.png нажми F1
debug_dirty.png F2 + покликай кнопки
debug_clicks.png F3 + покликай
debug_bounds.png F4
  1. Закоммить папку docs/screenshots/ — и картинки появятся на Gitea.

📁 Структура проекта

/
├── README.md
├── docs/
│   ├── index.html                 ← интерактивная документация
│   └── screenshots/               ← скриншоты для README
└── gui/
    ├── gui.h                      ← umbrella-заголовок
    ├── demo.h / demo.cpp          ← run_demo()
    ├── window.h / window.cpp      ← окно, dirty-рендер, оверлей, иконка
    ├── core/
    │   ├── common.h               ← EventData, DebugInfo, DirtyRegion, easing
    │   ├── event_bus.h/.cpp
    │   ├── raw_picture.h/.cpp     ← пиксельный буфер + примитивы + BMP/PPM
    │   ├── font_manager.h/.cpp    ← TTF + кеш текста
    │   └── theme.h/.cpp           ← WIN11 / TERMINAL
    └── widgets/
        ├── widget.h / widget.cpp  ← WidgetData, Widget, combat, page
        ├── draw_basic.cpp         ← Button, Label, Input, Sprite
        ├── draw_toggles.cpp       ← Checkbox, Radio, Slider, Progress
        └── draw_lists.cpp         ← Listbox, Dropdown, Tree, Scroll

📚 Документация

Полная интерактивная документация (9 страниц: старт, окно, виджеты, темы, свои виджеты, события, анимации, отладка, API):

👉 docs/index.html — открой в браузере


📄 Лицензия

MIT.

👤 Автор

KoDer — git.bipfr.ru/KoDer/gui

Description
Lightweight X11 GUI library for C++ with widget system and event handling
Readme MIT 31 MiB