Introduction
Freya is native GUI library built on top of 🧬 Dioxus and powered by 🎨 Skia, for 🦀 Rust.
⚠️ It's currently work in progress and not usable for production, but you can already play with it!
You can join the Discord server if you have any question or issue.
You can also see the API Reference.
#![allow(unused)] fn main() { fn app(cx: Scope) -> Element { let mut count = use_state(cx, || 0); render!( container { height: "100%", width: "100%", background: "rgb(35, 35, 35)", color: "white", padding: "12.5", onclick: move |_| count += 1, label { "Click to increase -> {count}" } } ) } }
Check out the examples in the Freya repository to learn more.
About
Freya is built on top of Dioxus, it provides a renderer powered by Skia, alongside a set of elements, components, hooks and testing utilities.
Why 🧬 Dioxus?
Dioxus is heavily influenced by React, resulting in a streamlined process for creating complex components without the need for excessive code.
This sets it apart from other Rust libraries, where equivalent components often require a significant amount of additional code.
Why 🎨 Skia?
Skia is a battle-tested and well maintained graphics library, and there are even some rusty bindings.
Environment Setup
Make sure you have Rust and your OS dependencies installed.
Windows
You will need C++ build tools which you can get through Visual Studio 2022, learn more here.
Linux
Debian-based (Ubuntu, PopOS, etc)
Install these packages:
sudo apt install build-essential libssl-dev pkg-config cmake libgtk-3-dev libclang-dev
Don't hesitate to contribute so other distros can be added here.
MacOS
No setup required. But feel free to add more if we miss something.
Hello, World!
Let's start by creating a hello world project.
Creating the project
mkdir freya-app
cd freya-app
cargo init
Cargo.toml
Make sure to add Freya and Dioxus as dependencies:
[package]
name = "freya-app"
version = "0.1.0"
edition = "2021"
[dependencies]
freya = { git="https://github.com/marc2332/freya" }
dioxus = { git="https://github.com/DioxusLabs/dioxus", rev="49c5a5043a16fc82210af146c345793dd448e519"}
src/main.rs
And paste this code in your main.rs
file.
#![cfg_attr( all(not(debug_assertions), target_os = "windows"), windows_subsystem = "windows" )] use freya::prelude::*; fn main() { launch(app); } fn app(cx: Scope) -> Element { let mut count = use_state(cx, || 0); render!( container { height: "100%", width: "100%", background: "rgb(35, 35, 35)", color: "white", padding: "12", onclick: move |_| count += 1, label { "Click to increase -> {count}" } } ) }
Running
Simply run with cargo
:
cargo run
Hot reload
Freya supports Dioxus hot reload, this means you can update the layout
and styling
of your app on the fly, without having to compile any rust code.
Setup
Just before launching your app, you need to initialize the hot-reload context:
fn main() { dioxus_hot_reload::hot_reload_init!(Config::<FreyaCtx>::default()); launch(app); }
That's it!
Virtualizing
Virtualizing helps you render a lot of data efficiently. It will only mount the elements you see in the screen, no matter how big the data is.
Target usages
- Text editor
- Tables
- Etc
Usage
Freya comes with a VirtualScrollView
component which can help you archive the virtualization of some data.
The virtualization logic of
VirtualScrollView
is implemented at component-level, so, you could implement your own version if you wanted.
Here is an example:
fn main() { launch(app); } fn app(cx: Scope) -> Element { let values = use_state(cx, || vec!["Hello World"].repeat(400)); render!( VirtualScrollView { width: "100%", height: "100%", show_scrollbar: true, direction: "vertical", length: values.get().len(), item_size: 25.0, builder_values: values.get(), builder: Box::new(move |(key, index, values)| { let values = values.unwrap(); let value = values[index]; rsx! { label { key: "{key}", height: "25", "{index} {value}" } } }) } ) }
Parameters
show_scrollbar
By default, it does not display a scrollbar. However, you can enable it by setting the show_scrollbar
parameter to true.
direction
It supports both vertical
and horizontal
directions. If direction is set to vertical
, the items will be displayed in a single column, with the scrollbar appearing on the right-hand side. If direction is set to horizontal
, the items will be displayed in a single row, with the scrollbar appearing at the bottom.
length
How many elements can be rendered. Usually the lenth of your data.
item_size
Used to calculate how many elements can be fit in the viewport.
builder_values
Any data that you might need in the builder
function
builder
This is a function that dinamically creates an element for the given index in the list. It receives 3 arguments, a key
for the element, the index
of the element and the builder_values
.