102 lines
3.7 KiB
Markdown
102 lines
3.7 KiB
Markdown
# iris
|
|
|
|
My experimental attempt at a rust ui library (also my first ui library).
|
|
|
|
It's currently designed around using retained data structures (widgets), rather than diffing generated trees from data like xilem or iced. This is an experiment and I'm not sure if it's a good idea or not.
|
|
|
|
Examples are in `examples`, eg. `cargo run --example tabs`.
|
|
|
|
## Android applications
|
|
|
|
An Android application is a library because Android loads its Rust code as a
|
|
native shared library:
|
|
|
|
```toml
|
|
[lib]
|
|
crate-type = ["cdylib", "rlib"]
|
|
|
|
[dependencies]
|
|
iris = { path = "../iris" }
|
|
|
|
[package.metadata.iris.android]
|
|
application-id = "com.example.myapp"
|
|
label = "My app"
|
|
```
|
|
|
|
`#[iris::app_init]` marks the factory called when Android creates the Iris
|
|
view. The attribute supplies its own Android target gate and generates the JNI
|
|
loader glue. The returned state chooses its resources through
|
|
`AndroidAppState::Resources`; `StdRsc` is the standard bundle, not a
|
|
requirement.
|
|
|
|
```rust
|
|
use iris::prelude::*;
|
|
|
|
#[derive(AndroidUiState)]
|
|
struct State {
|
|
ui_state: AndroidUiState,
|
|
}
|
|
|
|
impl AndroidAppState for State {
|
|
type Resources = StdRsc<Self>;
|
|
}
|
|
|
|
#[iris::app_init]
|
|
fn create(mut ui_state: AndroidUiState, rsc: &mut StdRsc<State>) -> State {
|
|
rect(PaintId::RED).set_root(rsc, &mut ui_state);
|
|
State { ui_state }
|
|
}
|
|
```
|
|
|
|
Install the Cargo subcommand from a checkout, then invoke it from the
|
|
application's directory:
|
|
|
|
```sh
|
|
cargo install --path /path/to/iris/cargo-iris
|
|
cargo iris apk --abi arm64-v8a
|
|
cargo iris run --abi x86_64 --device emulator-5554
|
|
```
|
|
|
|
`cargo iris` packages directly with `cargo-ndk`, `javac`, `d8`, `aapt2`,
|
|
`jar`, `zipalign`, and `apksigner`; it does not require Gradle. The caller
|
|
provides a JDK, Android SDK and NDK, and any emulator or physical device. Set
|
|
`ANDROID_HOME` to the SDK. `run` always requires an explicit device and never
|
|
creates or starts one.
|
|
|
|
Debug APKs use the standard key at `~/.android/debug.keystore`, creating it
|
|
with `keytool` when absent. A release build requires the long-lived signing
|
|
identity explicitly:
|
|
|
|
```sh
|
|
IRIS_KEYSTORE_PASSWORD=... IRIS_KEY_PASSWORD=... \
|
|
cargo iris apk --release --keystore /secure/upload.jks --key-alias upload
|
|
```
|
|
|
|
APK staging and output live under
|
|
`target/iris-android/<package>/<debug|release>/<abi>/`; the command's final
|
|
line is the verified APK's absolute path.
|
|
|
|
Goals, in general order:
|
|
1. does what I want it to (text, images, video, animations)
|
|
2. very easy to use ignoring ergonomic ref counting
|
|
3. reasonably fast / efficient (a lot faster than electron, save battery life, try to beat iced and xilem)
|
|
|
|
## dev details
|
|
|
|
not targeting web rn cause wanna use actual nice gpu features & entire point of this is to make desktop apps / not need a web browser
|
|
|
|
general ideas trynna use rn / experiment with:
|
|
- retained mode
|
|
- specifically designed around wgpu so there's no translation
|
|
- postfix functions for most things to prevent unreadable indentation (going very well)
|
|
- events can be done directly where you draw the widgets
|
|
- almost no macros in user code & actual LSP typechecking (variadic generics if you can hear me please save us)
|
|
- relative anchor + absolute offset coord system (+ "rest" / leftover during widget layout)
|
|
- single threaded ui & pass context around to make non async usage straightforward (pretty unsure about this)
|
|
- widgets store outside of the actual rendering so they can be moved around and swapped easily (unsure about this but seems to work good for now)
|
|
|
|
under heavy initial development so not gonna try to explain status, maybe check TODO for that;
|
|
sizable chance it gets a rewrite once I know everything I need and what seems to work best
|
|
|
|
it's called iris because it's the structure around what you actually want to display and colorful
|