Skip to content

Commit

Permalink
Merge branch 'main' into feat/rethink-parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Aiving authored Oct 16, 2024
2 parents 9836be6 + 672a6b4 commit c32dd2c
Show file tree
Hide file tree
Showing 84 changed files with 2,753 additions and 1,070 deletions.
Binary file added .github/overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ Cargo.lock
.idea
snapshot_before.png
snapshot_after.png
documents_example
documents_example
bacon.toml
8 changes: 5 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ cargo +nightly fmt --all -- --error-on-unformatted --unstable-features
Freya is split in various crates, each with it's own meaning and purpose, here is the list sorted by their importance:

- `freya`: Entrypoint to the library used by end users, mainly reexports the other crates and contains the launch methods.
- `renderer`: GUI Renderer using Winit and a Skia Canvas to render the app.
- `core`: Core logic for events, DOM processing, accessibility integration and text layout measurement is located here.
- `native-core`: DOM tree-like data structure to hold all the nodes with their attribute values and registered event handlers.
- `renderer`: Provides a winit event loop based execution for the app.
- `core`: Core logic for events, DOM processing, accessibility integration, element rendering and text layout measurement is located here.
- `native-core`: DOM data structure to hold all the nodes with their attribute values and registered event handlers.
- `torin`: UI layout library specifically made for Freya, although it's agnostic.
- `hooks`: Various Dioxus hooks to be used in Freya apps (text editing, animation, theming, etc)
- `components`: Collection of built-in Dioxus components to be used out of the box with in Freya apps (Button, Switch, Slider, Table, ScrollView, etc)
Expand All @@ -38,6 +38,8 @@ Freya is split in various crates, each with it's own meaning and purpose, here i
- `native-core-macro`: Just some internal macros to be used in `states` so it can be integrated with `native-core`.
- `common`: Some simple utilities used across the different Freya crates.

![Overview](./.github/overview.png)

## Examples
All important examples are located in the `./examples` folder although you might also find some in the form of docs comments in the code itself.

Expand Down
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ dioxus-signals = { version = "0.5" }
dioxus-core = { version = "0.5" }
dioxus-hot-reload = { version = "0.5", features = ["file_watcher"], default-features = false }
dioxus-router = { version = "0.5", default-features = false }
dioxus-sdk = { version = "0.5", features = ["clipboard"]}
dioxus-clipboard = "0.1"

skia-safe = { version = "0.75.0", features = ["gl", "textlayout", "svg"] }

Expand Down Expand Up @@ -79,6 +79,7 @@ skia-safe = { workspace = true }
tokio = { workspace = true, features = ["fs"]}
dioxus = { workspace = true }
freya = { workspace = true }
freya-hooks = { workspace = true }
freya-core = { workspace = true }
freya-testing = { workspace = true }
reqwest = { version = "0.12.0", features = ["json"] }
Expand All @@ -95,7 +96,8 @@ tree-sitter-highlight = "0.23.0"
tree-sitter-rust = "0.23.0"
rfd = "0.14.1"
bytes = "1.5.0"
dioxus-sdk = { workspace = true }
dioxus-clipboard = { workspace = true }
winit = { workspace = true }

[profile.release]
lto = true
Expand Down
39 changes: 25 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@

[Website](https://freyaui.dev) | [Nightly Docs](https://docs.freyaui.dev/freya) | [Stable Docs](https://docs.rs/freya/latest/freya) | [Book](https://book.freyaui.dev) | [Discord](https://discord.gg/sYejxCdewG)

**Freya** is a cross-paltform GUI library for Rust powered by 🧬 [Dioxus](https://dioxuslabs.com) and 🎨 [Skia](https://skia.org/).
**Freya** is a cross-platform GUI library for Rust powered by 🧬 [Dioxus](https://dioxuslabs.com) and 🎨 [Skia](https://skia.org/).

**It does not use any web tech**, check the [Differences with Dioxus](https://book.freyaui.dev/differences_with_dioxus.html).

⚠️ It's currently work in progress, but you can already play with it! You can join the [Discord](https://discord.gg/sYejxCdewG) server if you have any question or issue.

<br/>
<br/>

<table>
Expand Down Expand Up @@ -66,12 +65,6 @@ fn app() -> Element {
</td>
</table>

### Sponsors 🤗

Thanks to my sponsors for supporting this project! 😄

<!-- sponsors --><a href="https://github.com/piny4man"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;8446285?u&#x3D;fd37db4dd9b4ba94dabe0bccc3a95ef2a35376ab&amp;v&#x3D;4" width="60px" alt="" /></a><!-- sponsors -->

### Want to try it? 🤔

👋 Make sure to check the [Setup guide](https://book.freyaui.dev/setup.html) first.
Expand All @@ -93,19 +86,21 @@ Add Freya and Dioxus as dependencies:
freya = "0.2"
dioxus = { version = "0.5", features = ["macro", "hooks"], default-features = false }
```
### Contributing 🧙‍♂️

If you are interested in contributing please make sure to have read the [Contributing](CONTRIBUTING.md) guide first!

### Features ✨
- ⛏️ Built-in **components** (button, scroll views, switch and more)
- 🚇 Built-in **hooks** library (animations, text editing and more)
- 🔍 Built-in **devtools** panel
- 🚇 Built-in **hooks** (animations, text editing and more)
- 🔍 Built-in **developer tools** (tree inspection, fps overlay)
- 🧰 Built-in **headless runner** to test UI
- 🎨 **Theming** support (not extensible yet ⚠️)
- 🎨 **Theming** support
- 🛩️ **Cross-platform** (Windows, Linux, MacOS)
- 🖼️ SKSL **Shaders** support
- 🔄️ Dioxus **Hot-reload** support
- 📒 Multi-line **text editing**
- 🦾 Basic **Accessibility** Support (experimental ⚠️)
- 🧩Compatible with dioxus-sdk and other Dioxus renderer-agnostic libraries
- 🦾 **Accessibility** support
- 🧩 Compatible with dioxus-sdk and other Dioxus renderer-agnostic libraries

### Goals 😁
- Performant and low memory usage
Expand All @@ -115,6 +110,22 @@ dioxus = { version = "0.5", features = ["macro", "hooks"], default-features = fa
- Useful testing APIs
- Useful and extensible built-in components and hooks

### Support 🤗

If you are interested in supporting the development of this project feel free to donate to my [Github Sponsor](https://github.com/sponsors/marc2332/) page.

Thanks to my sponsors for supporting this project! 😄

<!-- sponsors --><a href="https://github.com/piny4man"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;8446285?u&#x3D;fd37db4dd9b4ba94dabe0bccc3a95ef2a35376ab&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/gqf2008"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;2295878?v&#x3D;4" width="60px" alt="高庆丰" /></a><!-- sponsors -->

### Special thanks 💪

- [Jonathan Kelley](https://github.com/jkelleyrtp) and [Evan Almloff](https://github.com/ealmloff) for making [Dioxus](https://dioxuslabs.com/) and all their help, specially when I was still creating Freya.
- [Armin](https://github.com/pragmatrix) for making [rust-skia](https://github.com/rust-skia/rust-skia/) and all his help and making the favor of hosting prebuilt binaries of skia for the combo of features use by Freya.
- [geom3trik](https://github.com/geom3trik) for helping me figure out how to add incremental rendering.
- [Tropical](https://github.com/Tropix126) for this contributions to improving accessibility and rendering.
- And to the rest of contributors and anybody who gave me any kind of feedback!

### 🤠 Projects

[Valin](https://github.com/marc2332/valin) ⚒️ is a Work-In-Progress cross-platform code editor, made with Freya 🦀 and Rust, by me.
Expand Down
4 changes: 2 additions & 2 deletions crates/common/src/accessibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ impl AccessibilityDirtyNodes {
self.added_or_updated.insert(node_id);
}

pub fn remove(&mut self, node_id: NodeId, ancestor_node_id: NodeId) {
self.removed.insert(node_id, ancestor_node_id);
pub fn remove(&mut self, node_id: NodeId, parent_id: NodeId) {
self.removed.insert(node_id, parent_id);
}

pub fn clear(&mut self) {
Expand Down
24 changes: 23 additions & 1 deletion crates/components/src/activable_route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,29 @@ use dioxus_router::{
};
use freya_hooks::ActivableRouteContext;

/// Provide a context to the inner components so they can know whether the passed route is the current router in the Router or not.
/// Sometimes you might want to know if a route is selected so you can style a specific UI element in a different way,
/// like a button with a different color.
/// To avoid cluttering your components with router-specific code you might instead want to wrap your component in an `ActivableRoute`
/// and inside your component call `use_activable_route`.
///
/// This way, your component and all its desdendants will just know whether a route is activated or not, but not which one.
///
/// ```rs
/// Link {
/// to: Route::Home, // Direction route
/// ActivableRoute {
/// route: Route::Home, // Activation route
/// SidebarItem {
/// // `SidebarItem` will now appear "activated" when the route is `Route::Home`
/// // `ActivableRoute` is letting it know whether `Route::Home` is enabled
/// // or not, without the need to add router-specific logic in `SidebarItem`.
/// label {
/// "Go to Hey ! 👋"
/// }
/// },
/// }
/// }
/// ```
#[allow(non_snake_case)]
#[component]
pub fn ActivableRoute<T: Clone + PartialEq + Routable + 'static>(
Expand Down
143 changes: 115 additions & 28 deletions crates/components/src/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,112 @@ use winit::{
window::CursorIcon,
};

/// Properties for the [`Button`], [`FilledButton`] and [`OutlineButton`] components.
#[derive(Props, Clone, PartialEq)]
pub struct ButtonProps {
/// Theme override.
pub theme: Option<ButtonThemeWith>,
/// Inner children for the button.
pub children: Element,
/// Event handler for when the button is pressed.
pub onpress: Option<EventHandler<PressEvent>>,
/// Event handler for when the button is clicked. Not recommended, use `onpress` instead.
pub onclick: Option<EventHandler<()>>,
}

/// Clickable button.
///
/// # Styling
/// Inherits the [`ButtonTheme`](freya_hooks::ButtonTheme) theme.
///
/// # Example
///
/// ```no_run
/// # use freya::prelude::*;
/// fn app() -> Element {
/// rsx!(
/// Button {
/// onpress: |_| println!("clicked"),
/// label {
/// "Click this"
/// }
/// }
/// )
/// }
/// ```
#[allow(non_snake_case)]
pub fn Button(props: ButtonProps) -> Element {
let theme = use_applied_theme!(&props.theme, button);
ButtonBase(BaseButtonProps {
theme,
children: props.children,
onpress: props.onpress,
onclick: props.onclick,
})
}

/// Clickable button with a solid fill color.
///
/// # Styling
/// Inherits the filled [`ButtonTheme`](freya_hooks::ButtonTheme) theme.
///
/// # Example
///
/// ```no_run
/// # use freya::prelude::*;
/// fn app() -> Element {
/// rsx!(
/// FilledButton {
/// onpress: |_| println!("clicked"),
/// label {
/// "Click this"
/// }
/// }
/// )
/// }
/// ```
#[allow(non_snake_case)]
pub fn FilledButton(props: ButtonProps) -> Element {
let theme = use_applied_theme!(&props.theme, filled_button);
ButtonBase(BaseButtonProps {
theme,
children: props.children,
onpress: props.onpress,
onclick: props.onclick,
})
}

/// Clickable button with an outline style.
///
/// # Styling
/// Inherits the outline [`ButtonTheme`](freya_hooks::ButtonTheme) theme.
///
/// # Example
///
/// ```no_run
/// # use freya::prelude::*;
/// fn app() -> Element {
/// rsx!(
/// OutlineButton {
/// onpress: |_| println!("clicked"),
/// label {
/// "Click this"
/// }
/// }
/// )
/// }
/// ```
#[allow(non_snake_case)]
pub fn OutlineButton(props: ButtonProps) -> Element {
let theme = use_applied_theme!(&props.theme, outline_button);
ButtonBase(BaseButtonProps {
theme,
children: props.children,
onpress: props.onpress,
onclick: props.onclick,
})
}

pub enum PressEvent {
Pointer(PointerEvent),
Key(KeyboardEvent),
Expand All @@ -38,10 +144,10 @@ impl PressEvent {

/// Properties for the [`Button`] component.
#[derive(Props, Clone, PartialEq)]
pub struct ButtonProps {
/// Theme override.
pub theme: Option<ButtonThemeWith>,
/// Inner children for the Button.
pub struct BaseButtonProps {
/// Theme.
pub theme: ButtonTheme,
/// Inner children for the button.
pub children: Element,
/// Event handler for when the button is pressed.
pub onpress: Option<EventHandler<PressEvent>>,
Expand All @@ -59,34 +165,14 @@ pub enum ButtonStatus {
Hovering,
}

/// Clickable button.
///
/// # Styling
/// Inherits the [`ButtonTheme`](freya_hooks::ButtonTheme) theme.
///
/// # Example
///
/// ```no_run
/// # use freya::prelude::*;
/// fn app() -> Element {
/// rsx!(
/// Button {
/// onpress: |_| println!("clicked"),
/// label {
/// "Click this"
/// }
/// }
/// )
/// }
/// ```
#[allow(non_snake_case)]
pub fn Button(
ButtonProps {
pub fn ButtonBase(
BaseButtonProps {
onpress,
children,
theme,
onclick,
}: ButtonProps,
}: BaseButtonProps,
) -> Element {
let mut focus = use_focus();
let mut status = use_signal(ButtonStatus::default);
Expand All @@ -106,7 +192,7 @@ pub fn Button(
height,
font_theme,
shadow,
} = use_applied_theme!(&theme, button);
} = theme;

let onpointerup = {
to_owned![onpress, onclick];
Expand Down Expand Up @@ -188,6 +274,7 @@ pub fn Button(
corner_radius: "{corner_radius}",
background: "{background}",
text_align: "center",
text_height: "disable-least-ascent",
main_align: "center",
cross_align: "center",
{&children}
Expand Down
Loading

0 comments on commit c32dd2c

Please sign in to comment.