gui/README.md
2026-08-24 18:53:59 +00:00

281 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# X11 GUI Library
[![Platform](https://img.shields.io/badge/platform-Linux-blue)]()
[![C++](https://img.shields.io/badge/C++-20-blue)]()
[![License](https://img.shields.io/badge/license-MIT-green)]()
Лёгкая 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](docs/screenshots/theme_win11.png) | ![terminal](docs/screenshots/theme_terminal.png) |
Переключение на лету — клавиша **F6**.
### Виджеты
| Controls (кнопки, ввод, чекбоксы, слайдер, прогресс) | Lists (список, dropdown, дерево, скролл) |
|:---:|:---:|
| ![controls](docs/screenshots/widgets_controls.png) | ![lists](docs/screenshots/widgets_lists.png) |
| Graphics (RawPicture: круги, полигоны, текст) |
|:---:|
| ![graphics](docs/screenshots/widgets_graphics.png) |
### Отладка
| Debug overlay (F1) — FPS, виджеты, partial updates, лог событий |
|:---:|
| ![overlay](docs/screenshots/debug_overlay.png) |
---
## 🚀 Быстрый старт
```cpp
#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;
}
```
Или просто запусти демо со всеми виджетами:
```cpp
#include "gui.h"
int main() { gui::run_demo(); }
```
---
## 🛠 Сборка
### Зависимости
```bash
# 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
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)
```
```bash
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`
```cpp
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()`.
### Программное управление
```cpp
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); // лимит кадров
```
---
3. Что снять (имена файлов = ссылки в 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 |
4. Закоммить папку `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](docs/index.html)** — открой в браузере
---
## 📄 Лицензия
MIT.
## 👤 Автор
**KoDer** — [git.bipfr.ru/KoDer/gui](https://git.bipfr.ru/KoDer)