The Kas GUI system strives to be both fast and follow Alan Kay's slogan:
Simple things should be simple, complex things should be possible.
An excerpt from examples/hello.rs:
let hello_ui = column![
"Hello, world!",
Button::label("&Close").with(|cx, _| cx.exit())
];
An excerpt from examples/counter.rs:
#[derive(Clone, Debug)]
struct Increment(i32);
fn counter() -> impl Widget<Data = ()> {
let tree = column![
format_value!("{}").align(AlignHints::CENTER),
row![
Button::label_msg("−", Increment(-1)),
Button::label_msg("+", Increment(1)),
]
.map_any(),
];
tree.with_state(0)
.on_message(|_, count, Increment(add)| *count += add)
}
Concerning making complex things possible, the Kas widget library is built using the same custom widget functionality as is available to Kas users with few exceptions. Check the Widget
API docs or browse the widget library and click the "Source" link.
- Docs: Tutorials, Wiki: Getting started
- Prose: Blog, Design
- API docs
- Examples:
examples
dir, kas-gui/7guis.
- Fully keyboard-accessible
- Screen reader support (partial: #509)
- IME support (partial: #508)
- Integrated i18n support (not yet started; #7)
- Complex text support: use system fonts with glyph fallbacks, BiDi, common text effects (#13)
- Automatic margins and layout with pixel-perfect scaling
- Support for custom themes including theme-driven animations and sizing
- Virtual scrolling (list or grid), including support for async data access
- Extremely fast, monolithic Rust binaries
Every approach has its limitations. Ours are:
- Custom widgets are stateful, supporting custom caches and minimal state updates but no protection from bad-state bugs.
- Custom widgets have a lot of flexibility over management of child widgets; this comes with some expectations. Violating these expectations will result in a panic in debug builds.
- Custom widget definitions require the use of macros; the latest versions of these have a low learning curve (except maybe
impl_anon!
) but unfortunatelyimpl_scope!
does not work withrustfmt
and#[impl_self]
causesrust-analyzer
to injectuse
statements in the wrong location (kas-gui/impl-tools#57).
kas is a meta-package serving as the library's public API, but containing no real code. Other crates in this repo:
- kas-core: the core library
- kas-widgets: the main widget library
- kas-view: view widgets supporting virtual scrolling
- kas-resvg: extra widgets over resvg
- kas-dylib: helper crate to support dynamic linking
- kas-macros: proc-macro crate
Significant external dependencies:
- kas-text: complex text support
- impl-tools:
autoimpl
andimpl_scope
(extensible) macros - winit: platform window integration
- wgpu: modern accelerated graphics API
The kas
crate enables most important features by default, excepting those
requiring nightly rustc
. Other crates enable fewer features by default.
See Cargo.toml.
The 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 file or on the following webpage: https://www.apache.org/licenses/LICENSE-2.0