movecall/moui

0.1.5

Latest
uploaded 4 hours ago
Moui — lightweight mono-display UI framework for OLED, RLCD and E-Paper

Readme

<p align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="assets/moui-lockup-dark.svg">
    <source media="(prefers-color-scheme: light)" srcset="assets/moui-lockup-light.svg">
    <img alt="Moui UI Framework Logo" src="assets/moui-lockup-dark.svg" width="600">
  </picture>
</p>

<p align="center">
  <b>A lightweight mono-display UI framework for OLED, RLCD, and E-Paper screens</b>
</p>

<p align="center">
  <a href="README_CN.md"><b>简体中文</b></a> | <b>English</b>
</p>

<p align="center">
  <img src="https://img.shields.io/badge/C-C11-blue.svg" alt="Language">
  <img src="https://img.shields.io/badge/ESP--IDF-%3E%3Dv5.0-red.svg" alt="ESP-IDF">
  <img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License">
  <img src="https://img.shields.io/badge/Tests-71%2F71%20PASS-brightgreen.svg" alt="Tests">
  <img src="https://img.shields.io/badge/RAM-%3C18KB-orange.svg" alt="RAM">
</p>

---

ESP Component Registry: `movecall/moui`

> 📢 **Project Status & Community Invitation**
> 
> Moui is currently in active development (**Beta / Developer Preview**). While core architecture and base widgets are backed by automated tests, real-world deployment across diverse hardware setups and edge cases benefits immensely from community exploration.
> 
> We warmly welcome your feedback and contributions! Whether you discover bugs on actual hardware, have performance suggestions, or request new features, feel free to open [Issues](../../issues) or submit [Pull Requests](../../pulls). Your testing and feedback are the driving forces shaping Moui's stability and growth! 🚀

## Documentation

- 📘 [**API Reference**](docs/api_reference.md) — Comprehensive guide for all 30 widgets, layout engines & animations
- 🛠️ [**Porting Guide**](docs/porting_guide.md) — Step-by-step MCU & display driver integration guide
- ⚡ [**Optimization Log**](docs/optimization_log.md) — Benchmark numbers, memory profiling & performance logs

## Installation

```yaml
# idf_component.yml
dependencies:
  movecall/moui: "^0.1.5"
```

## Minimal Example ("Hello Moui")

```c
#include "moui.h"

void app_init(moui_screen_mgr_t *mgr) {
    static moui_screen_t main_scr;
    moui_screen_init(&main_scr);

    // Create a label
    static moui_widget_label_t title;
    moui_label_init(&title, "Hello Moui!", &moui_font_inter_16);
    title.base.bounds = (moui_rect_t){20, 20, 160, 30};
    moui_screen_add_widget(&main_scr, &title.base);

    // Push screen to manager
    moui_screen_push(mgr, &main_scr);
}
```

## Features

- **Tiny footprint**: ~45 KB Flash, ~18 KB RAM
- **4-level grayscale**: `moui_color_t` supports WHITE/LGRAY/DGRAY/BLACK; 1bpp and 2bpp backends
- **30 widgets**: Full suite of controls including `VirtualList` (<1KB RAM for 100k+ items), `TimePicker`, `BarChart`, `Roller`, `IconBar`, `TreeView`, `LogView`, etc.
- **128 Material Mono Icons**: Built-in 16x16 vector mono icons with 1x/2x/3x integer scaling (`moui_draw_icon_scaled`) and alignment
- **4 Modern Architecture Subsystems**: Flexbox layout (`moui_layout_flex`), Anchor constraints (`moui_anchor`), Reactive data binding (`moui_property`), Timeline animations (`moui_timeline`)
- **Smooth 50 fps animation**: 10 easing functions + sequence/parallel groups + keyframe timelines
- **Cross-platform**: same UI code runs on any MCU and SDL2 desktop simulator
- **10 built-in display drivers**: SSD1306/SSD1309/SH1106/ST7565/ST7567/ST7920/UC1701/UC8151/SSD1677/ST7305
- **Kconfig trimming**: `idf.py menuconfig` to pick only the widgets/drivers/fonts you need
- **Font fallback chain**: auto CJK/Latin mixed rendering with `moui_font_set_fallback()`
- **Backend abstraction**: `moui_backend_t` interface + Full-FB / Page-Buffer modes
- **Encoder-native input**: ISR-safe ring buffer + focus chain + long-press/capture
- **Mono-specific**: 7 dither patterns + 8 texture fills + QR code + RLE / Floyd-Steinberg dithered bitmaps
- **Display rotation**: 0/90/180/270 degrees, two modes (zero-RAM pixel mapping or flush-time buffer transpose)
- **Theme / dark mode**: global color inversion, one-line toggle

## Project Structure

```
moui/
├── src/                Core framework (all platforms)
│   ├── hal/            HAL interface + display descriptor
│   ├── core/           Drawing, dither, patterns, QR, 128 icons, theme, style, events
│   ├── backend/        Backend abstraction: moui_backend_t + FB/Page
│   ├── drivers/        10 display driver templates (inc. ST7305)
│   ├── font/           Font engine
│   ├── input/          Input queue, focus manager, input device
│   ├── anim/           10 easing functions + timeline animation engine
│   ├── widget/         30 widgets (inc. VirtualList, TimePicker, BarChart, Roller, etc.)
│   ├── layout/         Stack container, Grid, Flexbox, Anchor
│   └── screen/         Screen stack + 7 transitions + popup
├── fonts/              Font data + generator tool
├── examples/           ESP-IDF examples + HAL reference
├── host/               Desktop simulator + demos (WeChat Chat Demo, App Framework Demo)
├── tools/              img_to_c.py / gen_font.py
├── idf_component.yml   Component metadata
└── CMakeLists.txt      Dual-mode build (ESP + desktop)
```

## Quick Start

### Simulator

```bash
cmake -B build && cmake --build build
./build/host/apps/st7305_4p2/st7305_4p2
```

Simulators included:
- `st7305_4p2` — 4.2" 300x400 RLCD (Reflective LCD) simulator (includes 17 demo screens: VirtualList 100k, WeChat Chat Demo, App Framework Demo, 128 Icons Gallery, Photorealistic Image test)
- `moui_sim` — Standard 128x64 OLED simulator
- `watch_sim` — Smartwatch UI simulator

Controls: `Up/Down` navigate / `Enter` confirm / `ESC` back / `R` rotate

### ESP-IDF

1. Add the component dependency (see Installation above)
2. `idf.py menuconfig` > Moui Configuration > select drivers and widgets
3. Refer to `examples/esp32s3_port/` for HAL implementation

### Adding a New Display (3 steps)

```c
// 1. Implement two transport functions
void my_write_cmd(uint8_t cmd, void *user) { /* SPI/I2C command */ }
void my_write_data(const uint8_t *d, uint32_t len, void *user) { /* data */ }

// 2. Initialize the driver
moui_drv_ssd1306_t display;
moui_drv_ssd1306_init(&display, &cfg);

// 3. Create draw context
moui_draw_ctx_t ctx;
moui_draw_ctx_init_be(&ctx, moui_drv_ssd1306_backend(&display));
```

## Backend Architecture

```c
struct moui_backend {
    void (*set_pixel)(moui_backend_t *be, int x, int y, moui_color_t c);
    moui_color_t (*get_pixel)(moui_backend_t *be, int x, int y);
    void (*clear)(moui_backend_t *be, moui_color_t c);
    void (*flush)(moui_backend_t *be);
    int width, height;
    int phys_w, phys_h;
    moui_rotation_t rotation;
    bool sw_rotate;
};
```

- **`moui_backend_fb_t`** — Full framebuffer (1 KB+ for 128x64)
- **`moui_backend_page_t`** — Page-buffer rendering (128 bytes for 128x64)

## Widget List (30 types)

| Widget | Description |
|--------|-------------|
| Label | Text (inverse, word-wrap, proportional font) |
| List | Scrollable list with animated indicator |
| VirtualList | High-performance recycled cell list (100k+ items <1KB RAM) |
| Button | Push / Toggle / Checkbox |
| Slider | Slider with value display |
| Chart | Waveform chart, ring buffer |
| ScrollView | Scroll container with scrollbar |
| StatusBar | Title + time + battery |
| Progress | Read-only progress bar |
| Radio | Radio button group |
| Spinner | Numeric stepper |
| Tab | Tabbed pages |
| Dropdown | Drop-down selector |
| TextInput | Character input field |
| TimePicker | HH:MM:SS wheel selection widget |
| BarChart | Dynamic histogram with gridlines & dither fill |
| Roller | 3D perspective wheel selector |
| IconBar | RSSI WiFi signal strength + battery status bar |
| TreeView | Expandable/collapsible hierarchy tree |
| LogView | Console ring-buffer log viewer with auto-scroll |
| Gauge | Semicircle gauge meter |
| Table | Data table |
| BtnMatrix | Button matrix |
| Switch | Slide toggle |
| Calendar | Month calendar |
| Image | Bitmap display (RLE & Floyd-Steinberg dither supported) |
| Ring | Arc progress indicator |
| Keyboard | On-screen keyboard |
| Extra | Dots / Number / Stepper / Sparkline / Checklist |
| Misc | Marquee / Badge / Divider / Loading |

## Performance & Optimization

| Metric | Value |
|--------|-------|
| Frame rate | 50 fps |
| hline optimization | Byte-level memset, 3-5x speedup |
| 180° rotation transpose | < 12 μs / frame (20x speedup) |
| Full-screen DMA | 1.6 ms (8064 B @ 40 MHz) |
| Smart refresh | Skip unchanged frames, zero CPU |
| Memory safety | 70/70 unit tests 100% PASS |
| Code size | ~45 KB |
| RAM usage | ~18 KB (VirtualList < 1 KB) |

## License

MIT

Links

To add this component to your project, run:

idf.py add-dependency "movecall/moui^0.1.5"

download archive

Stats

  • Archive size
    Archive size ~ 2.63 MB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

movecall/moui version: 0.1.5
|