KAS GUI
=======
[![Test Status](https://github.com/kas-gui/kas/workflows/Tests/badge.svg?event=push)](https://github.com/kas-gui/kas/actions)
[![kas-text](https://img.shields.io/badge/GitHub-kas--text-blueviolet)](https://github.com/kas-gui/kas-text/)
[![Docs](https://docs.rs/kas/badge.svg)](https://docs.rs/kas)
![Minimum rustc version](https://img.shields.io/badge/rustc-1.53+-lightgray.svg)
KAS is a widget-first GUI toolkit:
- widgets retain state
- flexibile drawing, layout, event handling, animation
- clean, type-safe widget interaction
- full keyboard control of UI
- fast, efficient, responsive
### Features
- Good automatic layout (margins, text wrapping width-for-height logic)
- Partially declarative UI descriptions possible through macros
- Stepless DPI scaling
- Advanced text features: shaping, bidirectional support, font fallbacks
- Embedded GPU shaders (see [Mandlebrot example](examples/mandlebrot))
- Supports theming and end-user configuration
- View widgets for seemless scrolling and sharing of large data
### Limitations
- Slow compile times. See [Faster builds](#faster-builds) below.
- Large binaries. Distributing feature-heavy applications without shared
libraries will always have this problem, but if you seek a minimal GUI
toolkit then you should probably look elsewhere.
### Documentation
- API docs: <https://docs.rs/kas>, <https://docs.rs/kas-core>,
<https://docs.rs/kas-widgets>, <https://docs.rs/kas-theme>, <https://docs.rs/kas-wgpu>
- [KAS Tutorials](https://kas-gui.github.io/tutorials/)
- [Changlelog](CHANGELOG.md)
- [Roadmap](ROADMAP.md)
- [Discuss](https://github.com/kas-gui/kas/discussions)
- [KAS Blog](https://kas-gui.github.io/blog/)
### Examples
See the [`examples`](examples) directory and
[kas-gui/7guis](https://github.com/kas-gui/7guis/).
Precompiled example apps can be downloaded as follows:
- go to <https://github.com/kas-gui/kas/actions/workflows/build.yml>
- select the latest (complete) run
- download one of the `examples-*` artifacts
Getting started
---------------
### Dependencies
KAS requires a recent [Rust] compiler. Currently, version 1.53 or greater is
required. Using the **nightly** channel does have a few advantages:
- Proceedural macros emit better diagnostics. In some cases, diagnostics are
missed without nightly rustc, hence **nightly is recommended for development**.
- The `nightly` (`min_spec`) feature allows some visual improvements (see below).
- The `doc_cfg` feature may be used for API docs.
#### Linux libraries
Install dependencies (glslc is optional; see [kas-wgpu's README](crates/kas-wgpu/README.md)):
```sh
# For Ubuntu:
sudo apt-get install build-essential git libxcb-shape0-dev libxcb-xfixes0-dev libharfbuzz-dev
# For Fedora:
sudo dnf install libxcb-devel harfbuzz-devel glslc
```
### Running examples
Clone the repository and run the examples as follows:
```sh
git clone https://github.com/kas-gui/kas.git
cd kas
cargo run --example gallery
cargo run --example layout
cargo run --example filter-list
cd examples/mandlebrot; cargo run
```
#### Buliding documentation locally
```
RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --features=nightly --all --no-deps --open
```
### Faster builds
People variously complain that Rust / KAS is slow to compile, and they have a
point: just recompiling the `gallery` example takes over six seconds on a 5800X!
There are two strategies we can use to speed this up:
1. Dynamic linking. I wouldn't recommend *shipping* code with dynamic linking
due to dependency complications (although it is possible and potentially
useful, especially within Linux distributions), but during development it
can make a lot of sense.
Enabling dynamic linking is very easy: use `--features dynamic`.
2. A faster linker: [LLD](https://lld.llvm.org/) or better yet
[mold](https://github.com/rui314/mold).
Using LLD: (1) install (e.g. via Linux distribution packages), (2) create
`$HOME/.cargo/config`, (3) add this:
```toml
[build]
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
```
Using Mold: (1) install (see project page), (2) prefix build commands with
`mold -run`.
Here are some crude benchmarks. **Method:** build the gallery example, touch
(or re-save) `gallery.rs`, and rebuild. Use the Unix `time` command, run three
times, and report the best `real` time of the three. **Machine:** 5800X, Fedora
34, SSD.
| standard | 0m6.124s | rustc 1.54.0 (a178d0322 2021-07-26) |
| dynamic | 0m2.275s | |
| lld | 0m1.537s | LLD 12.0.1 (lld-12.0.1-1.fc34.src.rpm) |
| lld + dynamic | 0m1.061s | |
| mold | 0m1.147s | mold 0.9.3 (ec3319b37f653dccfa4d1a859a5c687565ab722d) |
| mold + dynamic | 0m0.971s | |
### Run-time configuration
#### Graphics
KAS uses [WebGPU] for rendering, which targets Vulkan and OpenGL on Linux and
Android, Vulkan, DX12 and DX11 on Windows, and finally Metal on MacOS and iOS.
This should satisfy *most* devices, albeit support may be incomplete (refer to
[WebGPU] documentation).
To force use of a specific backend, set `KAS_BACKENDS`, for example:
```
export KAS_BACKENDS=GL
```
To prefer use of a discrete GPU over integrated graphics, set:
```
export KAS_POWER_PREFERENCE=HighPerformance
```
#### Config files
Configuration support is built but not enabled by default, since formats are not
yet stable. It may also be used programmatically.
To use, specify paths (`KAS_CONFIG`, `KAS_THEME_CONFIG`) and mode
(`KAS_CONFIG_MODE`: `Read` (default), `ReadWrite` or `WriteDefault`).
To get started:
```sh
export KAS_CONFIG=kas.yaml
export KAS_THEME_CONFIG=theme.yaml
export KAS_CONFIG_MODE=readwrite
# Optionally, force creation of default files:
KAS_CONFIG_MODE=WriteDefault cargo run --example gallery
# Now, just run:
cargo run --example gallery
```
For further documentation, see [`kas_wgpu::Options`].
Crates and features
-------------------
### Crates
- `kas` is a meta-package; most of the time this is the only one you need to
use directly
- `kas-macros`: a helper crate for proc macros
- `kas-core` provides most interfaces and logic concerning widgets (event
handling, layout, draw API, geometry types)
- [KAS-text]: provides text layout and font management
- `kas-widgets`: the standard widget library
- `kas-theme`: theming support for KAS (API, two themes, config support)
- `kas-wgpu`: provides windowing via [winit] and rendering via [WebGPU]
- `kas-dylib`: support for dynamic linking
- <https://docs.rs/easy-cast>: spin-off crate for checked casts
At this point in time, `kas-wgpu` is the only windowing/rendering implementation
and `kas-theme` the only theme (high-level drawing) implementation, thus `kas`
uses these crates by default, though they are optional.
Futher, capabilities such as text shaping and Markdown processing are enabled by
default. Image-loading support is not currently optional, and includes all
formats supported by the `image` crate. Some improvements to binary size and
compile time should be possible here.
### Feature flags
The `kas` crate enables most important features by default, excepting those
requiring nightly `rustc`. Other crates enable fewer features by defualt.
The following non-default features of `kas` are highlighted:
- `dynamic`: enable dynamic linking for `kas` (see [Faster builds](#faster-builds))
- `internal_doc`: turns on some extra documentation intended for internal
usage but not for end users. (This only affects generated documentation.)
- `nightly`: enables "more stable" unstable features
- `min_spec` (enabled by `nightly`): use `min_specialization` for some visual
improvements: scrolled regions are drawn under scrollbars,
underlines on checkbox accelerator keys show with the <kbd>Alt</kbd> key.
- `spec`: use `specialization` to enable `TryFormat`
For full documentation of feature flags, see the [`Cargo.toml`](Cargo.toml).
[KAS-text]: https://github.com/kas-gui/kas-text/
[winit]: https://github.com/rust-windowing/winit/
[WebGPU]: https://github.com/gfx-rs/wgpu
[`kas_wgpu::Options`]: https://docs.rs/kas-wgpu/latest/kas_wgpu/options/struct.Options.html
Copyright and Licence
---------------------
The [COPYRIGHT](COPYRIGHT) file includes a list of contributors who claim
copyright on this project. This list may be incomplete; new contributors may
optionally add themselves to this list.
The KAS library is published under the terms of the Apache License, Version 2.0.
You may obtain a copy of this licence from the [LICENSE](LICENSE) file or on
the following webpage: <https://www.apache.org/licenses/LICENSE-2.0>