# Cotis
Cotis is a modular Rust library for building native user interfaces. The core is intentionally split into small, swappable pieces: layout managers, pipes that convert layout output into renderer commands, and render backends that draw those commands. You wire them together through [`CotisApp`](https://docs.rs/cotis/latest/cotis/cotis_app/struct.CotisApp.html), which orchestrates each frame.
> **Status:** Early `0.1.0-alpha` release. APIs are still evolving, especially text, font, and text-measuring integration points in `cotis-utils` and `cotis-defaults`.
This repository contains the **core traits and orchestration** only. It does not open a window or draw pixels by itself. For a runnable desktop app, combine these crates with a layout engine, a pipe, and a renderer backend from the [ecosystem](#ecosystem) below.
## Architecture
Each frame flows through five stages:
```mermaid
flowchart LR
UI[UI_closure] --> LayoutMgr[LayoutManager]
LayoutMgr --> LayoutOut[Layout_output]
LayoutOut --> Pipe[LayoutRenderPipe]
Pipe --> Renderer[CotisRenderer]
```
1. A layout manager prepares for the frame.
2. UI code builds the element tree through the configurator API.
3. The layout manager produces layout output items.
4. A pipe transforms those items into renderer commands.
5. A renderer draws the command stream.
### Workspace crates
| [`cotis`](https://docs.rs/cotis) | Core traits: layout, render, pipes, and `CotisApp` orchestration |
| [`cotis-defaults`](https://docs.rs/cotis-defaults) | Default `ElementConfig` and render command types |
| [`cotis-utils`](https://docs.rs/cotis-utils) | Shared math, input, font, and renderer context traits |
| [`cotis-macros`](https://docs.rs/cotis-macros) | `#[cotis_start]` / `#[cotis_start_async]` entry hooks |
## Installation
Add the core crates to your `Cargo.toml`:
```toml
cotis = "0.1.0-alpha"
cotis-defaults = "0.1.0-alpha"
cotis-utils = "0.1.0-alpha"
cotis-macros = "0.1.0-alpha"
```
A full desktop application also needs a layout engine, a pipe, and a renderer. See [Quick start](#quick-start) and [Ecosystem](#ecosystem).
## Quick start
This workspace has no runnable examples on its own. Clone a renderer backend and run its example:
```bash
git clone https://github.com/igna-778/cotis-wgpu
cd cotis-wgpu
cargo run --example basic_example -p cotis-wgpu
```
That example opens a resizable window, lays out UI with `cotis-layout` and `cotis-pipes`, and renders through wgpu.
### Typical app wiring
```rust
use cotis::cotis_app::CotisApp;
use cotis_layout::preamble::CotisLayoutManager;
use cotis_pipes::cotis_layout_pipes::CotisLayoutToRenderListPipeForGenerics;
use cotis_utils::math::Dimensions;
use cotis_wgpu::prelude::*;
let renderer = CotisWgpuRenderer::auto_start();
let manager = CotisLayoutManager::new(Dimensions::new(1000.0, 800.0));
let mut app = CotisApp::new(renderer, manager, CotisLayoutToRenderListPipeForGenerics);
while !app.render().window_should_close() {
app.compute_frame(|root| {
// Build your UI tree here.
});
}
```
Swap `cotis-wgpu` for [`cotis-raylib`](https://github.com/igna-778/cotis-raylib) or another backend without changing layout or UI code.
## Ecosystem
Cotis is split across several repositories. This repo defines the contracts; sibling repos provide concrete implementations.
| [**cotis**](https://github.com/igna-778/cotis) (this repo) | Core traits and `CotisApp` orchestration |
| [`cotis-layout`](https://github.com/igna-778/cotis-layout) | Flexbox-style layout engine (`CotisLayoutManager`) |
| [`cotis-pipes`](https://github.com/igna-778/cotis-pipes) | Layout output to render commands (`CotisLayoutToRenderListPipeForGenerics`) |
| [`cotis-wgpu`](https://github.com/igna-778/cotis-wgpu) | Desktop renderer (wgpu + winit + glyphon) |
| [`cotis-raylib`](https://github.com/igna-778/cotis-raylib) | Desktop renderer (raylib) |
| [`cotis-renderer-template`](https://github.com/igna-778/cotis-renderer-template) | Scaffold for authoring a custom render backend |
| [`cotis-cli`](https://github.com/igna-778/cotis-cli) | Plugin host for installable build and run routines |
Pick a renderer backend and swap it without changing layout or UI code. Use `cotis-renderer-template` to implement a new backend.
## Features
### `cotis`
- `app_launch` — platform-controlled entry via `cotis-macros` and [`launch`](https://docs.rs/cotis/latest/cotis/launch/index.html) hooks
- `serialization` — serde support for core types
### `cotis-defaults`
- `serialization` — serde support for configs and commands (also enables `cotis/serialization` and `cotis-utils/serialization`)
- `complex_color` — layered and gradient color support
- `complex_colored_text` — extends `complex_color` to text color fields
### `cotis-utils`
- `serialization` — serde derives for math types (`Vector2`, `Dimensions`, `BoundingBox`)
### `cotis-macros`
Proc-macro attributes for environments where the renderer owns program startup:
```rust
use cotis_macros::cotis_start;
#[cotis_start]
fn start() {
// Create CotisApp, then run your frame loop.
}
```
Enable the `app_launch` feature on `cotis` when using this launch path.
## Documentation
- API reference: `cargo doc --open -p cotis`
- Published docs: [cotis](https://docs.rs/cotis), [cotis-defaults](https://docs.rs/cotis-defaults), [cotis-utils](https://docs.rs/cotis-utils), [cotis-macros](https://docs.rs/cotis-macros)