Metadata-Version: 2.4
Name: prosperous
Version: 0.1.0
Summary: A lightweight terminal UI library for high-frequency dynamic refresh scenarios.
Author-email: Mikhail-YellowBegonia <doctorsergei2021@gmail.com>
Project-URL: Homepage, https://github.com/Mikhail-YellowBegonia/prosperous
Project-URL: Bug Tracker, https://github.com/Mikhail-YellowBegonia/prosperous/issues
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Environment :: Console
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Pillow>=9.0.0
Dynamic: license-file

# Prosperous - Terminal UI Library / 终端 UI 库

![coverage](https://img.shields.io/badge/coverage-75%25-yellow?style=flat-square)

[English](#introduction) | [中文](#简介)

---

## Introduction

Prosperous is a lightweight terminal UI library designed for **dynamic high-frequency refresh** scenarios. It serves as a lightweight alternative to Rich.Live, bypassing document-flow or constraint-based layouts in favor of a frame-loop driven canvas. This approach empowers developers to build high-performance, responsive terminal applications with ease.

The only external dependency is **Pillow** (required only for image rendering).

## 简介

Prosperous 是一个轻量的终端 UI 库，专为**动态高频刷新**场景设计，是 Rich.Live 的轻量替代方向。它不引入文档流或约束布局，直接面向帧循环画布，帮助开发者快速搭建高性能、交互灵敏的终端应用。

唯一的外部依赖是 **Pillow**（仅图像渲染需要）。

---

## Core Architecture / 底层架构

### Rendering Engine / 渲染引擎

Prosperous uses **double-buffered differential rendering**, driven by three collaborative threads:
- **Logic Thread**: Runs the user's main loop. It's rate-limited by `live.poll()`. Within the `live.frame()` context, it calls component `draw()` methods, writing to the `screen_prepare` buffer.
- **Render Thread**: Runs at the target FPS. It performs an O(1) pointer swap between `screen_prepare` and `screen_buffer`, compares the new frame with `screen_dump` to calculate the difference, and sends only the changed cells to the terminal.
- **Input Thread**: A byte-stream state machine that parses raw input in real-time. Events are queued and consumed by the Logic thread via `live.poll()`.

ANSI output is handled by an **incremental state machine** (`_RenderContext`), which tracks the terminal's current style state and emits only changed attribute codes, avoiding full resets. This is highly efficient for high-latency environments like SSH.

采用**双缓冲差分渲染**，由三个线程协同驱动：
- **Logic 线程**：用户的主循环，通过 `live.poll()` 限速，在 `live.frame()` 上下文内调用组件 `draw()`，结果写入 `screen_prepare` 缓冲区。
- **Render 线程**：以目标 fps 运行，通过 O(1) 指针交换将 `screen_prepare` 与 `screen_buffer` 互换，然后对比 `screen_dump` 计算差分，只向终端发送变化的格子。
- **Input 线程**：字节流状态机，实时解析原始输入并入队，Logic 线程通过 `live.poll()` 取出。

ANSI 输出采用**增量状态机**（`_RenderContext`）：追踪终端当前样式状态，只发送变化的属性码，不发全量 reset。对 SSH 等高延迟环境友好。

### Coordinate System / 坐标系

Coordinates use the format `pos=(row, col)`, starting from 0. Child component coordinates are relative to the **content origin** of their parent container (`get_child_origin()`), rather than absolute screen coordinates. Top-level components (added directly via `live.add()`) have `pos` equal to screen coordinates.

`VStack` and `HStack` achieve automatic arrangement by overriding `get_child_origin(child)`.

`pos=(row, col)`，从 0 开始。子组件坐标相对于父容器的**内容区原点**（`get_child_origin()`），而非屏幕绝对坐标。顶层组件（直接 `live.add()` 的）`pos` 等于屏幕坐标。

`VStack` / `HStack` 通过覆盖 `get_child_origin(child)` 实现自动排列。

### Focus System / 焦点系统

The `FocusManager` features a built-in **focus stack**. When `live.add()` is called, all `focusable=True` components are automatically registered in declaration order (skipping `visible=False` subtrees). Modals and similar scenarios are handled by `push_group()` / `pop_group()`, which temporarily hijack focus and automatically restore it once popped.

`FocusManager` 内置**焦点栈**。`live.add()` 时自动按声明顺序注册所有 `focusable=True` 的组件（跳过 `visible=False` 子树）。Modal 等场景通过 `push_group()` / `pop_group()` 临时接管焦点，关闭后自动恢复。

---

## Quick Start / 快速上手

```python
from prosperous import Live, Panel, InputBox, Button, Style

def handle_cmd(text):
    # Your logic here
    pass

with Live(fps=30, logic_fps=60) as live:
    cmd = InputBox(id="cmd", width=30, label="INPUT",
                   on_enter=lambda: handle_cmd(cmd.text))

    panel = Panel(pos=(1, 2), width=50, height=5, title="DEMO",
                  children=[cmd, Button(label="OK", on_enter=lambda: handle_cmd(cmd.text))])

    live.add(panel)  # focusable children are automatically registered

    while live.running:
        for key in live.poll():
            if key == "ESC": live.stop()
            live.focus.handle_input(key)
        with live.frame():
            # Add dynamic drawing logic here if needed
            pass
```

---

## Features / 功能一览

- **Components / 组件**: `Panel`, `Box` (custom borders/backgrounds), `VStack`, `HStack`, `Label` (high-performance single-line), `Text` (multi-line/alignment/rich text markup), `Button`, `InputBox`, `ProgressBar`, `LogView`.
- **Layout / 布局**: `padding`, `gap`, `align` (cross-axis alignment), `reverse`, `layer` (rendering order).
- **Rich Text / 富文本**: Supports HTML-like `<tag>content</>` markup (parsed by `markup.py`). Supports themed semantic tags `<#id>`, color names, HEX colors, and nested ANSI attributes.
- **Interaction / 交互**: Declarative callbacks (`on_enter`, `on_key`, `on_focus`, `on_blur`), focus stack (modal isolation), and CJK input support.
- **Styles / 样式**: `Style` objects, TrueColor / 256-color support, style inheritance, and a **Theme** system (default values by component type).
- **Animation / 动画**: `Tween(start, end, duration, easing)` interpolators with built-in `linear`, `ease_in`, `ease_out`, `ease_in_out`, and support for custom easing functions.
- **Query / 查询**: Deep-first search via `component.find(id)` or `live.find(id)`.

---

## Theme System / 主题系统

```python
from prosperous import set_theme, DEFAULT_THEME, Style

set_theme({
    **DEFAULT_THEME,
    "Panel": {"padding": 2, "style": Style(fg=240)},
})
```

Theme defaults are automatically applied when style parameters are omitted. Call `set_theme` once before entering `with Live(...)`.

如果不传样式参数，组件会自动使用 Theme 默认值。在进入 `with Live(...)` 前调用一次 `set_theme` 即可。

---

## Code Style / 代码风格

Prosperous follows the `ruff format --line-length 100` standard.

It is recommended to declare top-level containers as named variables and pass references to `live.add()`, rather than inlining the entire component tree, to avoid excessive nesting depth:

使用 `ruff format --line-length 100`。建议顶层容器用命名变量声明，`live.add()` 只传引用，避免整个组件树内联导致缩进过深。

```python
# Recommended / 推荐
panel = Panel(pos=(1, 2), width=76, height=7, title="METRICS", children=[...])
live.add(panel)

# Not Recommended / 不推荐
live.add(Panel(pos=(1, 2), width=76, height=7, title="METRICS", children=[...]))
```

---

## License / 开源协议

MIT License.

## Acknowledgments / 致谢

Welcome bug reports and contributions! If you're interested in building a terminal application with Prosperous, we'd love to see what you create.

非常欢迎您指正代码中的错误，或者参与到共同开发中。如果您有兴趣尝试用这个小工具开发一个简单的终端应用，那将是对本项目最大的支持。
