{"id":49569916,"url":"https://github.com/wan0net/thistle-tk","last_synced_at":"2026-05-03T13:13:27.624Z","repository":{"id":346061325,"uuid":"1188385187","full_name":"wan0net/thistle-tk","owner":"wan0net","description":"Embedded Rust widget toolkit for e-paper and LCD displays, built on embedded-graphics","archived":false,"fork":false,"pushed_at":"2026-03-22T02:07:56.000Z","size":122203,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-22T17:42:47.288Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wan0net.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-22T02:04:28.000Z","updated_at":"2026-03-22T02:08:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wan0net/thistle-tk","commit_stats":null,"previous_names":["wan0net/thistle-tk"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/wan0net/thistle-tk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wan0net%2Fthistle-tk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wan0net%2Fthistle-tk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wan0net%2Fthistle-tk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wan0net%2Fthistle-tk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wan0net","download_url":"https://codeload.github.com/wan0net/thistle-tk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wan0net%2Fthistle-tk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32569996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-03T13:13:23.181Z","updated_at":"2026-05-03T13:13:27.619Z","avatar_url":"https://github.com/wan0net.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# thistle-tk\n\nA `no_std` Rust widget toolkit for embedded displays, built on [embedded-graphics](https://github.com/embedded-graphics/embedded-graphics).\n\nOne widget tree. Any display. E-paper or LCD — same code.\n\n\u003e **Alpha** — under active development as part of [ThistleOS](https://github.com/wan0net/thistle-os).\n\n## What it does\n\nApps build UI using semantic widgets and theme colors. A layout engine positions them. A renderer draws them to any `embedded-graphics` `DrawTarget`. Display-specific backends handle the pixel format.\n\n```text\nApp → Widget Tree → Layout Engine → Renderer → DrawTarget\n                                        │\n                                ┌───────┴───────┐\n                                │               │\n                           MonoMapper       RgbMapper\n                           (BinaryColor)    (Rgb565)\n                           e-paper          LCD/OLED\n```\n\n## Features\n\n- **Semantic colors** — apps use `Color::Primary`, `Color::Text`, etc. The theme resolves them to actual pixel values. On e-paper, everything thresholds to black/white automatically.\n- **Widget types** — Container (flex row/column), Label, Button, TextInput, Image\n- **Flexbox layout** — direction, alignment, gap, padding, flex-grow\n- **Theme system** — built-in monochrome and dark themes, or define your own\n- **Input dispatch** — touch hit-testing and keyboard focus routing\n- **Arena-based widget tree** — stable `WidgetId` handles, subtree removal, dirty tracking\n- **Display-agnostic** — renders to any `DrawTarget` via the `ColorMapper` trait\n\n## Usage\n\n```rust\nuse thistle_tk::*;\nuse thistle_tk::widget::*;\nuse thistle_tk::layout::Direction;\n\n// Create the UI tree\nlet mut tree = UiTree::new();\nlet root = tree.root();\n\n// Add widgets\nlet label = tree.add_child(root, Widget::label(\"Hello, world!\"));\nlet button = tree.add_child(root, Widget::button(\"Press me\", Some(on_click)));\n\n// Set container layout\nif let Some(w) = tree.get_mut(root) {\n    if let Widget::Container(c) = w {\n        c.direction = Direction::Column;\n        c.gap = 8;\n    }\n}\n\n// Layout and render\nlet theme = Theme::monochrome();\nlayout::layout(\u0026mut tree, Rect { x: 0, y: 0, w: 240, h: 320 });\nrender::render(\u0026tree, \u0026theme, \u0026MonoMapper, \u0026mut display);\n```\n\n## Display backends\n\nThe `ColorMapper` trait maps semantic colors to display-specific pixel types:\n\n| Mapper | Target | Use case |\n|--------|--------|----------|\n| `MonoMapper` | `BinaryColor` | E-paper (1-bit, black/white) |\n| `RgbMapper` | `Rgb565` | LCD, OLED (16-bit color) |\n\nWrite your own `ColorMapper` for other pixel formats.\n\n## Modules\n\n| Module | What it does |\n|--------|-------------|\n| `color` | `Color` enum — semantic (Primary, Text, ...) or explicit (Rgb, Black, White) |\n| `theme` | `Theme` struct — color palette + font sizes. Built-in: `monochrome()`, `dark()` |\n| `widget` | Widget types: Container, Label, Button, TextInput, Image |\n| `layout` | Flexbox-like layout engine (row/column, alignment, gap, flex-grow) |\n| `tree` | Arena-based `UiTree` with hit testing, focus management, dirty tracking |\n| `render` | Draws widget tree to any `DrawTarget` via `ColorMapper` |\n| `input` | Routes touch/key events to widgets (hit test, focus, callbacks) |\n\n## Requirements\n\n- Rust (stable)\n- `no_std` + `alloc` (needs a global allocator)\n- `embedded-graphics 0.8`\n\n## License\n\nBSD 3-Clause. See [LICENSE](LICENSE).\n\n---\n\n*Part of the [ThistleOS](https://github.com/wan0net/thistle-os) project — a portable OS for ESP32 devices.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwan0net%2Fthistle-tk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwan0net%2Fthistle-tk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwan0net%2Fthistle-tk/lists"}