Merge branch 'master' into improvement/docs
20
CONTRIBUTING.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Contributing
|
||||
|
||||
Thank you for considering contributing to Iced! Feel free to read [the ecosystem overview] and [the roadmap] to get an idea of the current state of the library.
|
||||
|
||||
The main advice for new contributors is to share your ideas with the community. Introduce yourself over our [Zulip server] or [start a discussion in an issue](https://github.com/hecrj/iced/issues) explaining what you have in mind (do not be afraid of duplicated issues!). If you want to talk directly to me (@hecrj), you can also find me on Discord (`lone_scientist#9554`).
|
||||
|
||||
This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Please, do not skip it! Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]!
|
||||
|
||||
Iced is in its infancy and, besides directly writing code, there are many other different ways you can contribute. To name a few:
|
||||
|
||||
- Writing tutorials or blog posts
|
||||
- Improving the documentation
|
||||
- Submitting bug reports and use cases
|
||||
- Sharing, discussing, researching and exploring new ideas
|
||||
|
||||
[the ecosystem overview]: ECOSYSTEM.md
|
||||
[the roadmap]: ROADMAP.md
|
||||
[Zulip server]: https://iced.zulipchat.com/
|
||||
[Code is the Easy Part]: https://youtu.be/DSjbTC-hvqQ?t=845
|
||||
[The Hard Parts of Open Source]: https://www.youtube.com/watch?v=o_4EX4dPppA
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "iced"
|
||||
version = "0.1.0-alpha.1"
|
||||
version = "0.1.0-beta"
|
||||
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "A cross-platform GUI library inspired by Elm"
|
||||
@ -29,7 +29,7 @@ members = [
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
iced_winit = { version = "0.1.0-alpha", path = "winit" }
|
||||
iced_wgpu = { version = "0.1.0-alpha", path = "wgpu" }
|
||||
iced_wgpu = { version = "0.1.0", path = "wgpu" }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
iced_web = { version = "0.1.0-alpha", path = "web" }
|
||||
|
88
ECOSYSTEM.md
Normal file
@ -0,0 +1,88 @@
|
||||
# Ecosystem
|
||||
This document describes the Iced ecosystem.
|
||||
|
||||
It quickly lists the different audiences of the library and explains how the different crates relate to each other.
|
||||
|
||||
## Users
|
||||
|
||||
Iced is meant to be used by 2 different types of users:
|
||||
|
||||
- __End-users__. They should be able to:
|
||||
- get started quickly,
|
||||
- have many widgets available,
|
||||
- keep things simple,
|
||||
- and build applications that are __maintainable__ and __performant__.
|
||||
- __GUI toolkit developers / Ecosystem contributors__. They should be able to:
|
||||
- build new kinds of widgets,
|
||||
- implement custom runtimes,
|
||||
- integrate existing runtimes in their own system (like game engines),
|
||||
- and create their own custom renderers.
|
||||
|
||||
## Crates
|
||||
Iced consists of different crates which offer different layers of abstractions for our users. This modular architecture helps us keep implementation details hidden and decoupled, which should allow us to rewrite or change strategies in the future.
|
||||
|
||||
![Ecosystem graph](docs/graphs/ecosystem.png)
|
||||
|
||||
### [`iced_core`]
|
||||
|
||||
[`iced_core`] holds basic reusable types of the public API. For instance, basic data types like `Point`, `Rectangle`, `Length`, etc.
|
||||
|
||||
This crate is meant to be a starting point for an Iced runtime.
|
||||
|
||||
### [`iced_native`]
|
||||
[`iced_native`] takes [`iced_core`] and builds a native runtime on top of it, featuring:
|
||||
- A custom layout engine, greatly inspired by [`druid`]
|
||||
- Event handling for all the built-in widgets
|
||||
- A renderer-agnostic API
|
||||
|
||||
To achieve this, it introduces a bunch of reusable interfaces:
|
||||
- A `Widget` trait, which is used to implement new widgets: from layout requirements to event and drawing logic.
|
||||
- A bunch of `Renderer` traits, meant to keep the crate renderer-agnostic.
|
||||
- A `Windowed` trait, leveraging [`raw-window-handle`], which can be implemented by graphical renderers that target _windows_. Window-based shells (like [`iced_winit`]) can use this trait to stay renderer-agnostic.
|
||||
|
||||
[`druid`]: https://github.com/xi-editor/druid
|
||||
[`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle
|
||||
|
||||
### [`iced_web`]
|
||||
[`iced_web`] takes [`iced_core`] and builds a WebAssembly runtime on top. It achieves this by introducing a `Widget` trait that can be used to produce VDOM nodes.
|
||||
|
||||
The crate is currently a simple abstraction layer over [`dodrio`].
|
||||
|
||||
[`dodrio`]: https://github.com/fitzgen/dodrio
|
||||
|
||||
### [`iced_wgpu`]
|
||||
[`iced_wgpu`] is a [`wgpu`] renderer for [`iced_native`]. For now, it is the default renderer of Iced in native platforms.
|
||||
|
||||
[`wgpu`] supports most modern graphics backends: Vulkan, Metal, DX11, and DX12 (OpenGL and WebGL are still WIP). Additionally, it will support the incoming [WebGPU API].
|
||||
|
||||
Currently, [`iced_wgpu`] supports the following primitives:
|
||||
- Text, which is rendered using [`wgpu_glyph`]. No shaping at all.
|
||||
- Quads or rectangles, with rounded borders and a solid background color.
|
||||
- Images, lazily loaded from the filesystem.
|
||||
- Clip areas, useful to implement scrollables or hide overflowing content.
|
||||
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
||||
[WebGPU API]: https://gpuweb.github.io/gpuweb/
|
||||
[`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
|
||||
|
||||
### [`iced_winit`]
|
||||
[`iced_winit`] offers some convenient abstractions on top of [`iced_native`] to quickstart development when using [`winit`].
|
||||
|
||||
It exposes a renderer-agnostic `Application` trait that can be implemented and then run with a simple call. The use of this trait is optional. A `conversion` module is provided for users that decide to implement a custom event loop.
|
||||
|
||||
[`winit`]: https://github.com/rust-windowing/winit
|
||||
|
||||
### [`iced`]
|
||||
Finally, [`iced`] unifies everything into a simple abstraction to create cross-platform applications:
|
||||
|
||||
- On native, it uses [`iced_winit`] and [`iced_wgpu`].
|
||||
- On the web, it uses [`iced_web`].
|
||||
|
||||
This is the crate meant to be used by __end-users__.
|
||||
|
||||
[`iced_core`]: core
|
||||
[`iced_native`]: native
|
||||
[`iced_web`]: web
|
||||
[`iced_wgpu`]: wgpu
|
||||
[`iced_winit`]: winit
|
||||
[`iced`]: ..
|
122
README.md
@ -3,29 +3,49 @@
|
||||
[![Documentation](https://docs.rs/iced/badge.svg)][documentation]
|
||||
[![Crates.io](https://img.shields.io/crates/v/iced.svg)](https://crates.io/crates/iced)
|
||||
[![License](https://img.shields.io/crates/l/iced.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
|
||||
[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)
|
||||
|
||||
A renderer-agnostic GUI library for Rust focused on simplicity and type-safety.
|
||||
A cross-platform GUI library for Rust focused on simplicity and type-safety.
|
||||
Inspired by [Elm].
|
||||
|
||||
[![Tour - Iced][gui_gif]][gui_gfycat]
|
||||
[![Tour - Coffee][coffee_gui_gif]][coffee_gui_gfycat]
|
||||
|
||||
[gui_gif]: https://thumbs.gfycat.com/VeneratedSourAurochs-small.gif
|
||||
[gui_gfycat]: https://gfycat.com/veneratedsouraurochs
|
||||
|
||||
[coffee_gui_gif]: https://thumbs.gfycat.com/GloomyWeakHammerheadshark-small.gif
|
||||
[coffee_gui_gfycat]: https://gfycat.com/gloomyweakhammerheadshark
|
||||
<div align="center">
|
||||
<a href="https://gfycat.com/littlesanehalicore">
|
||||
<img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" height="350px">
|
||||
</a>
|
||||
<a href="https://gfycat.com/politeadorableiberianmole">
|
||||
<img src="https://thumbs.gfycat.com/PoliteAdorableIberianmole-small.gif">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## Features
|
||||
* Simple, easy-to-use, renderer-agnostic API
|
||||
* Responsive, flexbox-based layouting
|
||||
* Simple, easy-to-use, batteries-included API
|
||||
* Type-safe, reactive programming model
|
||||
* Built-in widgets
|
||||
* Custom widget support
|
||||
* [Cross-platform support] (Windows, macOS, Linux, and the Web)
|
||||
* Responsive layout
|
||||
* Built-in widgets (including [text inputs], [scrollables], and more!)
|
||||
* Custom widget support (create your own!)
|
||||
* [Debug overlay with performance metrics]
|
||||
* First-class support for async actions (use futures!)
|
||||
* [Modular ecosystem] split into reusable parts:
|
||||
* A [renderer-agnostic native runtime] enabling integration with existing systems
|
||||
* A [built-in renderer] supporting Vulkan, Metal, DX11, and DX12
|
||||
* A [windowing shell]
|
||||
* A [web runtime] leveraging the DOM
|
||||
|
||||
__Iced is in a experimental stage.__ [Take a look at the roadmap],
|
||||
[check out the issues], and [feel free to contribute!].
|
||||
__Iced is currently experimental software.__ [Take a look at the roadmap],
|
||||
[check out the issues], and [feel free to contribute!]
|
||||
|
||||
[Cross-platform support]: https://github.com/hecrj/iced/blob/master/docs/images/todos_desktop.jpg?raw=true
|
||||
[text inputs]: https://gfycat.com/alertcalmcrow-rust-gui
|
||||
[scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui
|
||||
[Debug overlay with performance metrics]: https://gfycat.com/artisticdiligenthorseshoebat-rust-gui
|
||||
[Modular ecosystem]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md
|
||||
[renderer-agnostic native runtime]: https://github.com/hecrj/iced/tree/master/native
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
||||
[built-in renderer]: https://github.com/hecrj/iced/tree/master/wgpu
|
||||
[windowing shell]: https://github.com/hecrj/iced/tree/master/winit
|
||||
[`dodrio`]: https://github.com/fitzgen/dodrio
|
||||
[web runtime]: https://github.com/hecrj/iced/tree/master/web
|
||||
[Take a look at the roadmap]: https://github.com/hecrj/iced/blob/master/ROADMAP.md
|
||||
[check out the issues]: https://github.com/hecrj/iced/issues
|
||||
[feel free to contribute!]: #contributing--feedback
|
||||
@ -34,7 +54,7 @@ __Iced is in a experimental stage.__ [Take a look at the roadmap],
|
||||
Add `iced` as a dependency in your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
iced = "0.1"
|
||||
iced = "0.1.0-beta"
|
||||
```
|
||||
|
||||
__Iced moves fast and the `master` branch can contain breaking changes!__ If
|
||||
@ -139,7 +159,7 @@ to:
|
||||
1. Take the result of our __view logic__ and layout its widgets.
|
||||
1. Process events from our system and produce __messages__ for our
|
||||
__update logic__.
|
||||
1. Draw the resulting user interface using our chosen __renderer__.
|
||||
1. Draw the resulting user interface.
|
||||
|
||||
Browse the [documentation] and the [examples] to learn more!
|
||||
|
||||
@ -147,40 +167,54 @@ Browse the [documentation] and the [examples] to learn more!
|
||||
Iced was originally born as an attempt at bringing the simplicity of [Elm] and
|
||||
[The Elm Architecture] into [Coffee], a 2D game engine I am working on.
|
||||
|
||||
The core of the library was implemented during May in [this pull request], using
|
||||
[`stretch`] for flexbox-based layouting. It was later released as the main
|
||||
feature of [Coffee 0.3.0].
|
||||
The core of the library was implemented during May in [this pull request].
|
||||
[The first alpha version] was eventually released as
|
||||
[a renderer-agnostic GUI library]. The library did not provide a renderer and
|
||||
implemented the current [tour example] on top of [`ggez`], a game library.
|
||||
|
||||
After release, different folks suggested me to split the new [`ui` module] into
|
||||
its own standalone crate, as it could potentially benefit other engines and
|
||||
applications. I thought it was a great idea, and after a bit of work... Iced is
|
||||
here!
|
||||
Since then, the focus has shifted towards providing a batteries-included,
|
||||
end-user-oriented GUI library, while keeping [the ecosystem] modular.
|
||||
|
||||
Iced consists of different crates which offer different layers of abstractions
|
||||
for our users. This modular architecture helps us keep implementation details
|
||||
hidden and decoupled, which should allow us to rewrite or change strategies in
|
||||
the future.
|
||||
Currently, Iced is a cross-platform GUI library built on top of smaller crates:
|
||||
|
||||
![Iced ecosystem](https://github.com/hecrj/iced/raw/master/docs/crates_graph.png)
|
||||
- [`iced_core`], a bunch of basic types that can be reused in different runtimes.
|
||||
- [`iced_native`], a renderer-agnostic native runtime implementing widget
|
||||
logic and a layout engine inspired by [`druid`].
|
||||
- [`iced_web`], an experimental web runtime that targets the DOM thanks to
|
||||
[`dodrio`].
|
||||
- [`iced_wgpu`], a renderer leveraging [`wgpu`], [`wgpu_glyph`], and
|
||||
[`font-kit`].
|
||||
- [`iced_winit`], a windowing shell on top of [`winit`].
|
||||
|
||||
Read [the roadmap] if you want to learn more!
|
||||
[![Iced ecosystem](docs/graphs/ecosystem.png)](https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md)
|
||||
|
||||
[this pull request]: https://github.com/hecrj/coffee/pull/35
|
||||
[`stretch`]: https://github.com/vislyhq/stretch
|
||||
[Coffee 0.3.0]: https://github.com/hecrj/coffee/releases/tag/0.3.0
|
||||
[`ui` module]: https://docs.rs/coffee/0.3.2/coffee/ui/index.html
|
||||
[the roadmap]: https://github.com/hecrj/iced/blob/master/ROADMAP.md
|
||||
[The first alpha version]: https://github.com/hecrj/iced/tree/0.1.0-alpha
|
||||
[a renderer-agnostic GUI library]: https://www.reddit.com/r/rust/comments/czzjnv/iced_a_rendereragnostic_gui_library_focused_on/
|
||||
[tour example]: https://github.com/hecrj/iced/blob/master/examples/tour.rs
|
||||
[`ggez`]: https://github.com/ggez/ggez
|
||||
[the ecosystem]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md
|
||||
[`iced_core`]: https://github.com/hecrj/iced/tree/master/core
|
||||
[`iced_native`]: https://github.com/hecrj/iced/tree/master/native
|
||||
[`iced_web`]: https://github.com/hecrj/iced/tree/master/web
|
||||
[`iced_wgpu`]: https://github.com/hecrj/iced/tree/master/wgpu
|
||||
[`iced_winit`]: https://github.com/hecrj/iced/tree/master/winit
|
||||
[`druid`]: https://github.com/xi-editor/druid
|
||||
[`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
|
||||
[`font-kit`]: https://github.com/servo/font-kit
|
||||
[`winit`]: https://github.com/rust-windowing/winit
|
||||
|
||||
## Contributing / Feedback
|
||||
If you want to contribute, you are more than welcome to be a part of the
|
||||
project! Check out [the roadmap] and [the current issues] if you want to find
|
||||
something to work on. Try to share you thoughts first! Feel free to open a new
|
||||
issue if you want to discuss new ideas.
|
||||
Contributions are greatly appreciated! If you want to contribute, please
|
||||
read our [contributing guidelines] for more details.
|
||||
|
||||
Any kind of feedback is welcome! You can open an issue or, if you want to talk,
|
||||
you can find me (and a bunch of awesome folks) over the `#games-and-graphics`
|
||||
and `#gui-and-ui` channels in the [Rust Community Discord]. I go by
|
||||
`@lone_scientist` there.
|
||||
Feedback is also welcome! You can open an issue or, if you want to talk,
|
||||
come chat to our [Zulip server]. Moreover, you can find me (and a bunch of
|
||||
awesome folks) over the `#games-and-graphics` and `#gui-and-ui` channels in
|
||||
the [Rust Community Discord]. I go by `lone_scientist#9554` there.
|
||||
|
||||
## Sponsors
|
||||
The development of Iced is sponsored by the [Cryptowatch] team at [Kraken.com]
|
||||
|
||||
[documentation]: https://docs.rs/iced
|
||||
[examples]: https://github.com/hecrj/iced/tree/master/examples
|
||||
@ -188,4 +222,8 @@ and `#gui-and-ui` channels in the [Rust Community Discord]. I go by
|
||||
[Elm]: https://elm-lang.org/
|
||||
[The Elm Architecture]: https://guide.elm-lang.org/architecture/
|
||||
[the current issues]: https://github.com/hecrj/iced/issues
|
||||
[contributing guidelines]: https://github.com/hecrj/iced/blob/master/CONTRIBUTING.md
|
||||
[Zulip server]: https://iced.zulipchat.com/
|
||||
[Rust Community Discord]: https://bit.ly/rust-community
|
||||
[Cryptowatch]: https://cryptowat.ch/charts
|
||||
[Kraken.com]: https://kraken.com/
|
||||
|
194
ROADMAP.md
@ -1,149 +1,22 @@
|
||||
# Roadmap
|
||||
This document describes the current state of Iced and some of the most important next steps we should take before it can become a production-ready GUI library.
|
||||
|
||||
## Context
|
||||
Before we get into the actual roadmap, let's quickly review what is the current state of the library.
|
||||
|
||||
### Users
|
||||
|
||||
Iced is meant to be used by 2 different types of users:
|
||||
|
||||
- __End-users__. They should be able to:
|
||||
- get started quickly,
|
||||
- have many widgets available,
|
||||
- keep things simple,
|
||||
- and build applications that are __maintainable__ and __performant__.
|
||||
- __GUI toolkit developers / Ecosystem contributors__. They should be able to:
|
||||
- build new kinds of widgets,
|
||||
- implement custom runtimes,
|
||||
- integrate existing runtimes in their own system (like game engines),
|
||||
- and create their own custom renderers.
|
||||
|
||||
### Current state
|
||||
Iced consists of different crates which offer different layers of abstractions for our users. This modular architecture helps us keep implementation details hidden and decoupled, which should allow us to rewrite or change strategies in the future.
|
||||
|
||||
![Crates graph](docs/crates_graph.png)
|
||||
|
||||
#### `iced_core`
|
||||
|
||||
`iced_core` holds most of the reusable types of the public API. For instance, common widgets (like `Column`, `Row`, `Button`...) and basic data types (`Point`, `Rectangle`, `Length`...).
|
||||
|
||||
This crate is meant to be a starting point for an Iced runtime.
|
||||
|
||||
#### `iced_native`
|
||||
`iced_native` takes `iced_core` and builds a native runtime on top of it, featuring:
|
||||
- A flexbox-based layout engine, powered by [`stretch`]
|
||||
- Event handling for all the built-in widgets
|
||||
- A renderer-agnostic API
|
||||
|
||||
To achieve this, it introduces a bunch of reusable interfaces:
|
||||
- A `Widget` trait, which is used to implement new widgets: from layout requirements to event and drawing logic.
|
||||
- A bunch of `Renderer` traits, meant to keep the crate renderer-agnostic.
|
||||
- A `Windowed` trait, which can be implemented by graphical renderers that target _windows_. Window-based runtimes can use this trait to stay renderer-agnostic.
|
||||
|
||||
[`stretch`]: https://github.com/vislyhq/stretch
|
||||
|
||||
#### `iced_web`
|
||||
`iced_web` takes `iced_core` and builds a WebAssembly runtime on top. It achieves this by introducing a `Widget` trait that can be used to produce VDOM nodes.
|
||||
|
||||
The crate is a quite simple abstraction layer over [`dodrio`].
|
||||
|
||||
[`dodrio`]: https://github.com/fitzgen/dodrio
|
||||
|
||||
#### `iced_wgpu`
|
||||
`iced_wgpu` is a [`wgpu`] renderer for `iced_native`. It is meant to become the default renderer of Iced in native platforms.
|
||||
|
||||
[`wgpu`] supports most modern graphics backends: Vulkan, Metal, DX11, and DX12 (OpenGL and WebGL are still WIP). Additionally, it will support the incoming [WebGPU API].
|
||||
|
||||
Currently, `iced_wgpu` only supports a couple of primitives:
|
||||
- Text, which is rendered using [`wgpu_glyph`].
|
||||
- Quads or rectangles, with rounded borders and a solid background color.
|
||||
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
||||
[WebGPU API]: https://gpuweb.github.io/gpuweb/
|
||||
[`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
|
||||
|
||||
#### `iced_winit`
|
||||
`iced_winit` offers some convenient abstractions on top of `iced_native` to quickstart development when using [`winit`].
|
||||
|
||||
It exposes a renderer-agnostic `Application` trait that can be implemented and then run with a simple call. The use of this trait is optional. A `conversion` module is provided for users that decide to implement a custom event loop.
|
||||
|
||||
[`winit`]: https://github.com/rust-windowing/winit
|
||||
|
||||
#### `iced`
|
||||
Finally, `iced` unifies everything into a simple abstraction to create cross-platform applications:
|
||||
|
||||
- On native, it uses `iced_winit` and `iced_wgpu`.
|
||||
- On the web, it uses `iced_web`.
|
||||
|
||||
This is the crate meant to be used by __end-users__.
|
||||
|
||||
This document describes the current state of Iced and some of the most important next steps we should take before it can become a production-ready GUI library. This list keeps the short term new features in sight in order to coordinate work and discussion. Therefore, it is not meant to be exhaustive.
|
||||
|
||||
## Next steps
|
||||
This section describes some important features that should be implemented before Iced can be considered production-ready (before a 1.0 release).
|
||||
|
||||
Most of the work related to these features needs to happen in the `iced_native` path of the ecosystem, as the web already supports many of them.
|
||||
|
||||
### Scrollables / Clippables ([#24])
|
||||
Content that can take a (practically) infinite amount of space and can be viewed using a scrollbar. This is a very basic feature.
|
||||
Once a step is completed, it is collapsed and added to this list:
|
||||
|
||||
The end-user API could look like this:
|
||||
|
||||
```rust
|
||||
Column::new()
|
||||
.push(content)
|
||||
.scroll(&mut self.scroll_state);
|
||||
```
|
||||
|
||||
The challenge here is __composability__. Nested scrollables should work as expected.
|
||||
|
||||
When it comes to `iced_native`, we may need to add the concept of _event propagation_, so mouse wheel events can be captured by the inner-most scrollable and stop propagation.
|
||||
|
||||
When it comes to `iced_wgpu`, we should be able to use scissoring and transformations. [`wgpu`] has a [`RenderPass::set_scissor_rect`] that should work nicely.
|
||||
|
||||
The main issue here will be [`wgpu_glyph`], which is used currently to render text primitives. [`wgpu_glyph`] is powered by [`glyph-brush`], which caches glyphs to render text very fast. However, the current cache model does not seem to be composable (i.e. once you issue a draw call the cache is purged). We will need to change it (and potentially contribute) to accommodate for this use case.
|
||||
* [x] Scrollables / Clippables ([#24])
|
||||
* [x] Text input widget ([#25])
|
||||
* [x] TodoMVC example ([#26])
|
||||
* [x] Async actions ([#27])
|
||||
* [x] Custom layout engine ([#52])
|
||||
|
||||
[#24]: https://github.com/hecrj/iced/issues/24
|
||||
[`RenderPass::set_scissor_rect`]: https://docs.rs/wgpu/0.3.0/src/wgpu/lib.rs.html#1246-1248
|
||||
[`glyph-brush`]: https://github.com/alexheretic/glyph-brush
|
||||
|
||||
### Text input widget ([#25])
|
||||
A widget where the user can type raw text and passwords.
|
||||
|
||||
This widget will have a quite complex event logic, potentially coupled with text rendering. Some examples are:
|
||||
- Text cursor positioning based on a mouse click
|
||||
- Text selection
|
||||
- Clipboard interaction (copy & paste)
|
||||
- Text editing shortcuts (go to start, go to end, etc.)
|
||||
|
||||
It also needs scrollable / clippable text support, as the introduced text may not fit the input and scrolling based on the text cursor will need to be implemented.
|
||||
|
||||
Additionally, the text cursor should blink at a regular interval, which can be considered an _animation_.
|
||||
|
||||
I think we should start simple here, and build a text widget with the most basic functionality: click to focus and type to fill. We can improve the implementation with time as the library matures.
|
||||
|
||||
The end-user API could look like this:
|
||||
|
||||
```rust
|
||||
pub enum Message {
|
||||
TextChanged(String),
|
||||
}
|
||||
|
||||
let text_input = text_input::State::new();
|
||||
let text = "Hello";
|
||||
|
||||
TextInput::new(&mut text_input, &text, Message::TextChanged);
|
||||
```
|
||||
|
||||
[#25]: https://github.com/hecrj/iced/issues/25
|
||||
|
||||
### TodoMVC example ([#26])
|
||||
Once we have scrollables support and a text widget, we could build a [TodoMVC] example. It seems to be a very simple example and could showcase the API quite well.
|
||||
|
||||
We could also consider releasing a `0.1.0` version at this point and share it as a milestone on different social platforms.
|
||||
|
||||
[#26]: https://github.com/hecrj/iced/issues/26
|
||||
[TodoMVC]: http://todomvc.com/
|
||||
[#28]: https://github.com/hecrj/iced/issues/28
|
||||
[#52]: https://github.com/hecrj/iced/pull/52
|
||||
|
||||
### Multi-window support ([#27])
|
||||
Open and control multiple windows at runtime.
|
||||
@ -154,46 +27,6 @@ This approach should also allow us to perform custom optimizations for this part
|
||||
|
||||
[#27]: https://github.com/hecrj/iced/issues/27
|
||||
|
||||
### Async actions ([#28])
|
||||
Most applications need to perform work in the background, without freezing the UI while they work. The current architecture can be easily extended to achieve this.
|
||||
|
||||
We can let users return an asynchronous action (i.e. a future) producing a `Message` in `Application::update`. The runtime will spawn each returned action in a thread pool and, once it finishes, feed the produced message back to `update`. This is also how [Elm] does it.
|
||||
|
||||
When it comes to implementing this, [`winit`] already supports user-specific events that can be sent from another thread. Accommodating `iced_winit` for this functionality should not be too complicated.
|
||||
|
||||
[Elm]: https://elm-lang.org/
|
||||
|
||||
Here is an example of how the end-user API could look:
|
||||
|
||||
```rust
|
||||
impl Application for WeatherReport {
|
||||
fn update(&mut self, message: Message) -> Command<Message> {
|
||||
match message {
|
||||
Message::Refresh => {
|
||||
self.state = State::Loading;
|
||||
|
||||
Command::from_future(
|
||||
Weather::request(self.location),
|
||||
Message::ReportReceived,
|
||||
)
|
||||
}
|
||||
Message::ReportReceived(Ok(report)) => {
|
||||
self.state = State::Show(report);
|
||||
|
||||
Command::none()
|
||||
},
|
||||
Message::ReportReceived(Err(error)) => {
|
||||
self.state = State::Error(error);
|
||||
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[#28]: https://github.com/hecrj/iced/issues/28
|
||||
|
||||
### Event subscriptions ([#29])
|
||||
Besides performing async actions on demand, most applications also need to listen to events passively. An example of this could be a WebSocket connection, where messages can come in at any time.
|
||||
|
||||
@ -233,7 +66,7 @@ In the long run, we could expose a renderer-agnostic abstraction to perform the
|
||||
[#32]: https://github.com/hecrj/iced/issues/32
|
||||
|
||||
### Text shaping and font fallback ([#33])
|
||||
[`wgpu_glyph`] uses [`glyph-brush`], which in turn uses [`rusttype`]. While the current implementation is able to layout text quite nicely, it does not perform any [text shaping].
|
||||
[`wgpu_glyph`] uses [`glyph_brush`], which in turn uses [`rusttype`]. While the current implementation is able to layout text quite nicely, it does not perform any [text shaping].
|
||||
|
||||
[Text shaping] with font fallback is a necessary feature for any serious GUI toolkit. It unlocks support to truly localize your application, supporting many different scripts.
|
||||
|
||||
@ -303,5 +136,8 @@ This could be very useful to build very performant user interfaces with a lot of
|
||||
|
||||
[Elm does it very well!](https://guide.elm-lang.org/optimization/lazy.html)
|
||||
|
||||
### Build a custom layout engine
|
||||
It may be possible to build an optimized layout engine only for `iced_native` if it turns out that there are some flexbox features we end up not using.
|
||||
[Elm]: https://elm-lang.org/
|
||||
[`winit`]: https://github.com/rust-windowing/winit
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
||||
[`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
|
||||
[`glyph_brush`]: https://github.com/alexheretic/glyph-brush
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "iced_core"
|
||||
version = "0.1.0-alpha"
|
||||
version = "0.1.0"
|
||||
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "The essential concepts of Iced"
|
||||
|
25
core/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# `iced_core`
|
||||
[![Documentation](https://docs.rs/iced_core/badge.svg)][documentation]
|
||||
[![Crates.io](https://img.shields.io/crates/v/iced_core.svg)](https://crates.io/crates/iced_core)
|
||||
[![License](https://img.shields.io/crates/l/iced_core.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
|
||||
[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)
|
||||
|
||||
`iced_core` holds basic reusable types of the public API. For instance, basic data types like `Point`, `Rectangle`, `Length`, etc.
|
||||
|
||||
This crate is meant to be a starting point for an Iced runtime.
|
||||
|
||||
![iced_core](../docs/graphs/core.png)
|
||||
|
||||
[documentation]: https://docs.rs/iced_core
|
||||
|
||||
## Installation
|
||||
Add `iced_core` as a dependency in your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
iced_core = "0.1.0"
|
||||
```
|
||||
|
||||
__Iced moves fast and the `master` branch can contain breaking changes!__ If
|
||||
you want to learn about a specific release, check out [the release list].
|
||||
|
||||
[the release list]: https://github.com/hecrj/iced/releases
|
@ -1,12 +0,0 @@
|
||||
digraph G {
|
||||
"iced_core" -> "iced_native"
|
||||
"iced_core" -> "iced_web"
|
||||
"iced_native" -> "iced_wgpu"
|
||||
"iced_native" -> "iced_winit"
|
||||
"iced_web" -> "iced"
|
||||
"iced_wgpu" -> "iced"
|
||||
"iced_winit" -> "iced"
|
||||
|
||||
node[shape=box];
|
||||
"iced" -> "cross-platform application"
|
||||
}
|
Before Width: | Height: | Size: 39 KiB |
13
docs/graphs/core.dot
Normal file
@ -0,0 +1,13 @@
|
||||
digraph G {
|
||||
fontname = "Roboto";
|
||||
newrank=true;
|
||||
node[fontname = "Roboto", style="filled", fontcolor="#333333", fillcolor=white, color="#333333"];
|
||||
edge[color="#333333"];
|
||||
|
||||
{ rank = same; iced_native iced_web }
|
||||
|
||||
iced_core -> iced_native [style=dashed];
|
||||
iced_core -> iced_web [style=dashed];
|
||||
|
||||
iced_core [style=dashed];
|
||||
}
|
BIN
docs/graphs/core.png
Normal file
After Width: | Height: | Size: 13 KiB |
56
docs/graphs/ecosystem.dot
Normal file
@ -0,0 +1,56 @@
|
||||
digraph G {
|
||||
fontname = "Roboto";
|
||||
newrank=true;
|
||||
node[fontname = "Roboto", style="filled", fontcolor="#333333", fillcolor=white, color="#333333"];
|
||||
edge[color="#333333"];
|
||||
|
||||
subgraph cluster_1 {
|
||||
label = "renderers ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_1 [label="...", style=solid, shape=none];
|
||||
iced_wgpu;
|
||||
}
|
||||
|
||||
subgraph cluster_2 {
|
||||
label = "shells ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_2 [label="...", style=solid, shape=none];
|
||||
iced_winit;
|
||||
}
|
||||
|
||||
subgraph cluster_3 {
|
||||
style=invis;
|
||||
margin=20;
|
||||
iced;
|
||||
}
|
||||
|
||||
{ rank = same; iced_native iced_web }
|
||||
{ rank = same; iced_wgpu iced_winit etc_1 etc_2 }
|
||||
|
||||
iced_core -> iced_native [style=dashed];
|
||||
iced_core -> iced_web [style=dashed];
|
||||
iced_native -> iced_wgpu;
|
||||
iced_native -> iced_winit;
|
||||
|
||||
iced_winit -> iced;
|
||||
iced_wgpu -> iced;
|
||||
iced_web -> iced;
|
||||
|
||||
iced -> "cross-platform application";
|
||||
|
||||
iced_core [style=dashed];
|
||||
|
||||
"cross-platform application" [shape=box, width=2.8, height=0.6];
|
||||
}
|
BIN
docs/graphs/ecosystem.png
Normal file
After Width: | Height: | Size: 44 KiB |
6
docs/graphs/generate.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
for file in *.dot
|
||||
do
|
||||
dot -Tpng ${file} -o ${file%.*}.png
|
||||
done
|
46
docs/graphs/iced.dot
Normal file
@ -0,0 +1,46 @@
|
||||
digraph G {
|
||||
fontname = "Roboto";
|
||||
newrank=true;
|
||||
node[fontname = "Roboto", style="filled", fontcolor="#333333", fillcolor=white, color="#333333"];
|
||||
edge[color="#333333"];
|
||||
|
||||
subgraph cluster_1 {
|
||||
label = "renderers ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_1 [label="...", style=solid, shape=none];
|
||||
iced_wgpu;
|
||||
}
|
||||
|
||||
subgraph cluster_2 {
|
||||
label = "shells ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_2 [label="...", style=solid, shape=none];
|
||||
iced_winit;
|
||||
}
|
||||
|
||||
subgraph cluster_3 {
|
||||
style=invis;
|
||||
margin=20;
|
||||
iced;
|
||||
}
|
||||
|
||||
{ rank = same; iced_wgpu iced_winit etc_1 etc_2 }
|
||||
|
||||
iced_winit -> iced;
|
||||
iced_wgpu -> iced;
|
||||
iced_web -> iced;
|
||||
|
||||
iced;
|
||||
}
|
BIN
docs/graphs/iced.png
Normal file
After Width: | Height: | Size: 26 KiB |
41
docs/graphs/native.dot
Normal file
@ -0,0 +1,41 @@
|
||||
digraph G {
|
||||
fontname = "Roboto";
|
||||
newrank=true;
|
||||
node[fontname = "Roboto", style="filled", fontcolor="#333333", fillcolor=white, color="#333333"];
|
||||
edge[color="#333333"];
|
||||
|
||||
subgraph cluster_1 {
|
||||
label = "renderers ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_1 [label="...", style=solid, shape=none];
|
||||
iced_wgpu;
|
||||
}
|
||||
|
||||
subgraph cluster_2 {
|
||||
label = "shells ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_2 [label="...", style=solid, shape=none];
|
||||
iced_winit;
|
||||
}
|
||||
|
||||
|
||||
{ rank = same; iced_wgpu iced_winit etc_1 etc_2 }
|
||||
|
||||
iced_core -> iced_native [style=dashed];
|
||||
iced_native -> iced_wgpu;
|
||||
iced_native -> iced_winit;
|
||||
|
||||
iced_core [style=dashed];
|
||||
}
|
BIN
docs/graphs/native.png
Normal file
After Width: | Height: | Size: 24 KiB |
12
docs/graphs/web.dot
Normal file
@ -0,0 +1,12 @@
|
||||
digraph G {
|
||||
fontname = "Roboto";
|
||||
newrank=true;
|
||||
node[fontname = "Roboto", style="filled", fontcolor="#333333", fillcolor=white, color="#333333"];
|
||||
edge[color="#333333"];
|
||||
|
||||
iced_core -> iced_web [style=dashed];
|
||||
|
||||
iced_web -> iced;
|
||||
|
||||
iced_core [style=dashed];
|
||||
}
|
BIN
docs/graphs/web.png
Normal file
After Width: | Height: | Size: 11 KiB |
31
docs/graphs/wgpu.dot
Normal file
@ -0,0 +1,31 @@
|
||||
digraph G {
|
||||
fontname = "Roboto";
|
||||
newrank=true;
|
||||
node[fontname = "Roboto", style="filled", fontcolor="#333333", fillcolor=white, color="#333333"];
|
||||
edge[color="#333333"];
|
||||
|
||||
subgraph cluster_1 {
|
||||
label = "renderers ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_1 [label="...", style=solid, shape=none];
|
||||
iced_wgpu;
|
||||
}
|
||||
|
||||
subgraph cluster_3 {
|
||||
style=invis;
|
||||
margin=20;
|
||||
iced;
|
||||
}
|
||||
|
||||
{ rank = same; iced_wgpu etc_1 }
|
||||
|
||||
iced_native -> iced_wgpu;
|
||||
|
||||
iced_wgpu -> iced;
|
||||
}
|
BIN
docs/graphs/wgpu.png
Normal file
After Width: | Height: | Size: 16 KiB |
31
docs/graphs/winit.dot
Normal file
@ -0,0 +1,31 @@
|
||||
digraph G {
|
||||
fontname = "Roboto";
|
||||
newrank=true;
|
||||
node[fontname = "Roboto", style="filled", fontcolor="#333333", fillcolor=white, color="#333333"];
|
||||
edge[color="#333333"];
|
||||
|
||||
subgraph cluster_2 {
|
||||
label = "shells ";
|
||||
labelloc = "b";
|
||||
labeljust = "r";
|
||||
fontcolor = "#0366d6";
|
||||
color="#f6f8fa";
|
||||
bgcolor="#f6f8fa";
|
||||
style=rounded;
|
||||
|
||||
etc_2 [label="...", style=solid, shape=none];
|
||||
iced_winit;
|
||||
}
|
||||
|
||||
subgraph cluster_3 {
|
||||
style=invis;
|
||||
margin=20;
|
||||
iced;
|
||||
}
|
||||
|
||||
{ rank = same; iced_winit etc_2 }
|
||||
|
||||
iced_native -> iced_winit;
|
||||
|
||||
iced_winit -> iced;
|
||||
}
|
BIN
docs/graphs/winit.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
docs/images/todos_desktop.jpg
Normal file
After Width: | Height: | Size: 302 KiB |
@ -4,29 +4,17 @@ you want to learn about a specific release, check out [the release list].
|
||||
|
||||
[the release list]: https://github.com/hecrj/iced/releases
|
||||
|
||||
|
||||
## [Tour](tour.rs)
|
||||
A simple UI tour showcasing different widgets that can be built using Iced.
|
||||
|
||||
The example can run both on native and web platforms, using the same GUI code!
|
||||
A simple UI tour that can run both on native platforms and the web! It showcases different widgets that can be built using Iced.
|
||||
|
||||
[![Tour - Iced][gui_gif]][gui_gfycat]
|
||||
The __[`tour`]__ file contains all the code of the example! All the cross-platform GUI is defined in terms of __state__, __messages__, __update logic__ and __view logic__.
|
||||
|
||||
[gui_gif]: https://thumbs.gfycat.com/VeneratedSourAurochs-small.gif
|
||||
[gui_gfycat]: https://gfycat.com/veneratedsouraurochs
|
||||
|
||||
On native, the example uses:
|
||||
- [`iced_winit`], as a bridge between [`iced_native`] and [`winit`].
|
||||
- [`iced_wgpu`], a WIP Iced renderer built on top of [`wgpu`] and supporting
|
||||
Vulkan, Metal, D3D11, and D3D12 (OpenGL and WebGL soon!).
|
||||
|
||||
The web version uses [`iced_web`], which is still a work in progress. In
|
||||
particular, the styling of elements is not finished yet (text color, alignment,
|
||||
sizing, etc).
|
||||
|
||||
The __[`tour`]__ file contains all the code of the example! All the
|
||||
cross-platform GUI is defined in terms of __state__, __messages__,
|
||||
__update logic__ and __view logic__.
|
||||
<div align="center">
|
||||
<a href="https://gfycat.com/politeadorableiberianmole">
|
||||
<img src="https://thumbs.gfycat.com/PoliteAdorableIberianmole-small.gif">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
[`tour`]: tour.rs
|
||||
[`iced_winit`]: ../winit
|
||||
@ -36,42 +24,49 @@ __update logic__ and __view logic__.
|
||||
[`winit`]: https://github.com/rust-windowing/winit
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
||||
|
||||
#### Running the native version
|
||||
Use [Cargo](https://doc.rust-lang.org/cargo/reference/manifest.html#examples)
|
||||
to run the example:
|
||||
|
||||
You can run the native version with `cargo run`:
|
||||
```
|
||||
cargo run --example tour
|
||||
```
|
||||
|
||||
#### Running the web version
|
||||
Build using the `wasm32-unknown-unknown` target and use the [`wasm-bindgen`] CLI
|
||||
to generate appropriate bindings in a `tour` directory.
|
||||
The web version can be run by following [the usage instructions of `iced_web`] or by accessing [iced.rs](https://iced.rs/)!
|
||||
|
||||
[the usage instructions of `iced_web`]: ../web#usage
|
||||
|
||||
|
||||
## [Todos](todos.rs)
|
||||
|
||||
A simple todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input, checkboxes, scrollables, icons, and async actions! It automatically saves your tasks in the background, even if you did not finish typing them.
|
||||
|
||||
All the example code is located in the __[`todos`]__ file.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://gfycat.com/littlesanehalicore">
|
||||
<img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" height="400px">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
You can run the native version with `cargo run`:
|
||||
```
|
||||
cd examples
|
||||
cargo build --example tour --target wasm32-unknown-unknown
|
||||
wasm-bindgen ../target/wasm32-unknown-unknown/debug/examples/tour.wasm --out-dir tour --web
|
||||
cargo run --example todos
|
||||
```
|
||||
We have not yet implemented a `LocalStorage` version of the auto-save feature. Therefore, it does not work on web _yet_!
|
||||
|
||||
Finally, serve the `examples` directory using an HTTP server and access the
|
||||
`tour.html` file.
|
||||
|
||||
[`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen
|
||||
|
||||
[`todos`]: todos.rs
|
||||
[TodoMVC]: http://todomvc.com/
|
||||
|
||||
## [Coffee]
|
||||
|
||||
Since [Iced was born in May], it has been powering the user interfaces in
|
||||
[Coffee], an experimental 2D game engine.
|
||||
|
||||
If you want to give Iced a try without having to write your own renderer,
|
||||
the __[`ui` module]__ in [Coffee] is probably your best choice as of now.
|
||||
|
||||
[![Tour - Coffee][coffee_gui_gif]][coffee_gui_gfycat]
|
||||
<div align="center">
|
||||
<a href="https://gfycat.com/gloomyweakhammerheadshark">
|
||||
<img src="https://thumbs.gfycat.com/GloomyWeakHammerheadshark-small.gif">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
[Iced was born in May]: https://github.com/hecrj/coffee/pull/35
|
||||
[`ui` module]: https://docs.rs/coffee/0.3.2/coffee/ui/index.html
|
||||
[Coffee]: https://github.com/hecrj/coffee
|
||||
[coffee_gui_gif]: https://thumbs.gfycat.com/GloomyWeakHammerheadshark-small.gif
|
||||
[coffee_gui_gfycat]: https://gfycat.com/gloomyweakhammerheadshark
|
||||
|
@ -1,84 +0,0 @@
|
||||
use iced::{
|
||||
button, scrollable, Align, Application, Button, Command, Container,
|
||||
Element, Image, Length, Scrollable, Text,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
Example::run()
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Example {
|
||||
item_count: u16,
|
||||
|
||||
scroll: scrollable::State,
|
||||
add_button: button::State,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Message {
|
||||
AddItem,
|
||||
}
|
||||
|
||||
impl Application for Example {
|
||||
type Message = Message;
|
||||
|
||||
fn new() -> (Example, Command<Message>) {
|
||||
(Example::default(), Command::none())
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
String::from("Scroll - Iced")
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) -> Command<Message> {
|
||||
match message {
|
||||
Message::AddItem => {
|
||||
self.item_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
}
|
||||
|
||||
fn view(&mut self) -> Element<Message> {
|
||||
let content = (0..self.item_count)
|
||||
.fold(
|
||||
Scrollable::new(&mut self.scroll)
|
||||
.spacing(20)
|
||||
.padding(20)
|
||||
.align_items(Align::Center),
|
||||
|scrollable, i| {
|
||||
if i % 2 == 0 {
|
||||
scrollable.push(lorem_ipsum().width(Length::Units(600)))
|
||||
} else {
|
||||
scrollable.push(
|
||||
Image::new(format!(
|
||||
"{}/examples/resources/ferris.png",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
))
|
||||
.width(Length::Units(400)),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
.push(
|
||||
Button::new(&mut self.add_button, Text::new("Add item"))
|
||||
.on_press(Message::AddItem)
|
||||
.padding(20)
|
||||
.border_radius(5),
|
||||
);
|
||||
|
||||
Container::new(content)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.center_y()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn lorem_ipsum() -> Text {
|
||||
Text::new("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi in dui vel massa blandit interdum. Quisque placerat, odio ut vulputate sagittis, augue est facilisis ex, eget euismod felis magna in sapien. Nullam luctus consequat massa, ac interdum mauris blandit pellentesque. Nullam in est urna. Aliquam tristique lectus ac luctus feugiat. Aenean libero diam, euismod facilisis consequat quis, pellentesque luctus erat. Praesent vel tincidunt elit.")
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
||||
<title>Tour - Iced</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
import init from "./tour/tour.js";
|
||||
|
||||
init('./tour/tour_bg.wasm');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -27,7 +27,7 @@ impl Sandbox for Tour {
|
||||
scroll: scrollable::State::new(),
|
||||
back_button: button::State::new(),
|
||||
next_button: button::State::new(),
|
||||
debug: true,
|
||||
debug: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "iced_native"
|
||||
version = "0.1.0-alpha"
|
||||
version = "0.1.0"
|
||||
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "A renderer-agnostic library for native GUIs"
|
||||
@ -8,6 +8,6 @@ license = "MIT"
|
||||
repository = "https://github.com/hecrj/iced"
|
||||
|
||||
[dependencies]
|
||||
iced_core = { version = "0.1.0-alpha", path = "../core", features = ["command"] }
|
||||
iced_core = { version = "0.1.0", path = "../core", features = ["command"] }
|
||||
twox-hash = "1.5"
|
||||
raw-window-handle = "0.3"
|
||||
|
35
native/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# `iced_native`
|
||||
[![Documentation](https://docs.rs/iced_native/badge.svg)][documentation]
|
||||
[![Crates.io](https://img.shields.io/crates/v/iced_native.svg)](https://crates.io/crates/iced_native)
|
||||
[![License](https://img.shields.io/crates/l/iced_native.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
|
||||
[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)
|
||||
|
||||
`iced_native` takes [`iced_core`] and builds a native runtime on top of it, featuring:
|
||||
- A custom layout engine, greatly inspired by [`druid`]
|
||||
- Event handling for all the built-in widgets
|
||||
- A renderer-agnostic API
|
||||
|
||||
To achieve this, it introduces a bunch of reusable interfaces:
|
||||
- A `Widget` trait, which is used to implement new widgets: from layout requirements to event and drawing logic.
|
||||
- A bunch of `Renderer` traits, meant to keep the crate renderer-agnostic.
|
||||
- A `Windowed` trait, leveraging [`raw-window-handle`], which can be implemented by graphical renderers that target _windows_. Window-based shells (like [`iced_winit`]) can use this trait to stay renderer-agnostic.
|
||||
|
||||
![iced_native](../docs/graphs/native.png)
|
||||
|
||||
[documentation]: https://docs.rs/iced_native
|
||||
[`iced_core`]: ../core
|
||||
[`iced_winit`]: ../winit
|
||||
[`druid`]: https://github.com/xi-editor/druid
|
||||
[`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle
|
||||
|
||||
## Installation
|
||||
Add `iced_native` as a dependency in your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
iced_native = "0.1.0"
|
||||
```
|
||||
|
||||
__Iced moves fast and the `master` branch can contain breaking changes!__ If
|
||||
you want to learn about a specific release, check out [the release list].
|
||||
|
||||
[the release list]: https://github.com/hecrj/iced/releases
|
@ -108,11 +108,7 @@ where
|
||||
let layout = if hash == cache.hash {
|
||||
cache.layout
|
||||
} else {
|
||||
let layout_start = std::time::Instant::now();
|
||||
let layout = renderer.layout(&root);
|
||||
dbg!(std::time::Instant::now() - layout_start);
|
||||
|
||||
layout
|
||||
renderer.layout(&root)
|
||||
};
|
||||
|
||||
UserInterface {
|
||||
|
65
web/README.md
Normal file
@ -0,0 +1,65 @@
|
||||
# `iced_web`
|
||||
[![Documentation](https://docs.rs/iced_web/badge.svg)][documentation]
|
||||
[![Crates.io](https://img.shields.io/crates/v/iced_web.svg)](https://crates.io/crates/iced_web)
|
||||
[![License](https://img.shields.io/crates/l/iced_web.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
|
||||
[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)
|
||||
|
||||
`iced_web` takes [`iced_core`] and builds a WebAssembly runtime on top. It achieves this by introducing a `Widget` trait that can be used to produce VDOM nodes.
|
||||
|
||||
The crate is currently a __very experimental__, simple abstraction layer over [`dodrio`].
|
||||
|
||||
![iced_core](../docs/graphs/web.png)
|
||||
|
||||
[documentation]: https://docs.rs/iced_web
|
||||
[`iced_core`]: ../core
|
||||
[`dodrio`]: https://github.com/fitzgen/dodrio
|
||||
|
||||
## Installation
|
||||
Add `iced_web` as a dependency in your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
iced_web = "0.1.0-alpha"
|
||||
```
|
||||
|
||||
__Iced moves fast and the `master` branch can contain breaking changes!__ If
|
||||
you want to learn about a specific release, check out [the release list].
|
||||
|
||||
[the release list]: https://github.com/hecrj/iced/releases
|
||||
|
||||
## Usage
|
||||
The current build process is a bit involved, as [`wasm-pack`] does not currently [support building binary crates](https://github.com/rustwasm/wasm-pack/issues/734).
|
||||
|
||||
Therefore, we instead build using the `wasm32-unknown-unknown` target and use the [`wasm-bindgen`] CLI to generate appropriate bindings.
|
||||
|
||||
For instance, let's say we want to build the [`tour` example]:
|
||||
|
||||
```
|
||||
cd examples
|
||||
cargo build --example tour --target wasm32-unknown-unknown
|
||||
wasm-bindgen ../target/wasm32-unknown-unknown/debug/examples/tour.wasm --out-dir tour --web
|
||||
```
|
||||
|
||||
Then, we need to create an `.html` file to load our application:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
||||
<title>Tour - Iced</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
import init from "./tour/tour.js";
|
||||
|
||||
init('./tour/tour_bg.wasm');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Finally, we serve it using an HTTP server and access it with our browser.
|
||||
|
||||
[`wasm-pack`]: https://github.com/rustwasm/wasm-pack
|
||||
[`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen
|
||||
[`tour` example]: ../examples/README.md#tour
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "iced_wgpu"
|
||||
version = "0.1.0-alpha"
|
||||
version = "0.1.0"
|
||||
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "A wgpu renderer for Iced"
|
||||
@ -8,7 +8,7 @@ license = "MIT"
|
||||
repository = "https://github.com/hecrj/iced"
|
||||
|
||||
[dependencies]
|
||||
iced_native = { version = "0.1.0-alpha", path = "../native" }
|
||||
iced_native = { version = "0.1.0", path = "../native" }
|
||||
wgpu = "0.4"
|
||||
glyph_brush = "0.6"
|
||||
wgpu_glyph = { version = "0.5", git = "https://github.com/hecrj/wgpu_glyph", branch = "feature/scissoring" }
|
||||
|
49
wgpu/README.md
Normal file
@ -0,0 +1,49 @@
|
||||
# `iced_wgpu`
|
||||
[![Documentation](https://docs.rs/iced_wgpu/badge.svg)][documentation]
|
||||
[![Crates.io](https://img.shields.io/crates/v/iced_wgpu.svg)](https://crates.io/crates/iced_wgpu)
|
||||
[![License](https://img.shields.io/crates/l/iced_wgpu.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
|
||||
[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)
|
||||
|
||||
`iced_wgpu` is a [`wgpu`] renderer for [`iced_native`]. For now, it is the default renderer of Iced in native platforms.
|
||||
|
||||
[`wgpu`] supports most modern graphics backends: Vulkan, Metal, DX11, and DX12 (OpenGL and WebGL are still WIP). Additionally, it will support the incoming [WebGPU API].
|
||||
|
||||
Currently, `iced_wgpu` supports the following primitives:
|
||||
- Text, which is rendered using [`wgpu_glyph`]. No shaping at all.
|
||||
- Quads or rectangles, with rounded borders and a solid background color.
|
||||
- Images, lazily loaded from the filesystem.
|
||||
- Clip areas, useful to implement scrollables or hide overflowing content.
|
||||
|
||||
![iced_wgpu](../docs/graphs/wgpu.png)
|
||||
|
||||
[documentation]: https://docs.rs/iced_wgpu
|
||||
[`iced_native`]: ../native
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
||||
[WebGPU API]: https://gpuweb.github.io/gpuweb/
|
||||
[`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
|
||||
|
||||
## Installation
|
||||
Add `iced_wgpu` as a dependency in your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
iced_wgpu = "0.1.0"
|
||||
```
|
||||
|
||||
__Iced moves fast and the `master` branch can contain breaking changes!__ If
|
||||
you want to learn about a specific release, check out [the release list].
|
||||
|
||||
[the release list]: https://github.com/hecrj/iced/releases
|
||||
|
||||
## Current limitations
|
||||
|
||||
The current implementation is quite naive, it uses:
|
||||
|
||||
- A different pipeline/shader for each primitive
|
||||
- A very simplistic layer model: every `Clip` primitive will generate new layers
|
||||
- _Many_ render passes instead of preparing everything upfront
|
||||
- A glyph cache that is trimmed incorrectly when there are multiple layers (a [`glyph_brush`] limitation)
|
||||
|
||||
Some of these issues are already being worked on! If you want to help, [get in touch!]
|
||||
|
||||
[get in touch!]: ../CONTRIBUTING.md
|
||||
[`glyph_brush`]: https://github.com/alexheretic/glyph-brush
|
27
winit/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# `iced_winit`
|
||||
[![Documentation](https://docs.rs/iced_winit/badge.svg)][documentation]
|
||||
[![Crates.io](https://img.shields.io/crates/v/iced_winit.svg)](https://crates.io/crates/iced_winit)
|
||||
[![License](https://img.shields.io/crates/l/iced_winit.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
|
||||
[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)
|
||||
|
||||
`iced_winit` offers some convenient abstractions on top of [`iced_native`] to quickstart development when using [`winit`].
|
||||
|
||||
It exposes a renderer-agnostic `Application` trait that can be implemented and then run with a simple call. The use of this trait is optional. A `conversion` module is provided for users that decide to implement a custom event loop.
|
||||
|
||||
![iced_winit](../docs/graphs/winit.png)
|
||||
|
||||
[documentation]: https://docs.rs/iced_winit
|
||||
[`iced_native`]: ../native
|
||||
[`winit`]: https://github.com/rust-windowing/winit
|
||||
|
||||
## Installation
|
||||
Add `iced_winit` as a dependency in your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
iced_winit = "0.1.0-alpha"
|
||||
```
|
||||
|
||||
__Iced moves fast and the `master` branch can contain breaking changes!__ If
|
||||
you want to learn about a specific release, check out [the release list].
|
||||
|
||||
[the release list]: https://github.com/hecrj/iced/releases
|