diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 155 |
1 files changed, 113 insertions, 42 deletions
@@ -1,26 +1,33 @@ # Iced - [](https://travis-ci.org/hecrj/iced) -[](https://docs.rs/iced) +[][documentation] [](https://crates.io/crates/iced) [](https://github.com/hecrj/iced/blob/master/LICENSE) -A GUI runtime for Rust, heavily inspired by Elm. +A renderer-agnostic GUI library for Rust focused on simplicity and type-safety. +Inspired by [Elm]. + +__Iced is in a experimental stage.__ [Features are still missing], +[some optimizations are yet to be implemented], and there are probably _many_ +bugs. [Feel free to contribute!] -[![GUI][gui_gif]][gui_gfycat] +[Features are still missing]: https://github.com/hecrj/iced/issues?q=is%3Aissue+is%3Aopen+label%3Afeature +[some optimizations are yet to be implemented]: https://github.com/hecrj/iced/issues?q=is%3Aissue+is%3Aopen+label%3Aoptimization +[Feel free to contribute!]: #contributing--feedback + +[![UI Tour - Coffee][gui_gif]][gui_gfycat] [gui_gif]: https://thumbs.gfycat.com/GloomyWeakHammerheadshark-small.gif [gui_gfycat]: https://gfycat.com/gloomyweakhammerheadshark ## Features - * Simple, easy to use API + * Simple, easy-to-use, renderer-agnostic API * Responsive, flexbox-based layouting - * Type-safe, reactive programming model without weak references + * Type-safe, reactive programming model * Built-in widgets * Custom widget support - * Renderer-agnostic runtime -## Usage +## Installation Add `iced` as a dependency in your `Cargo.toml`: ```toml @@ -33,48 +40,56 @@ you want to learn about a specific release, check out [the release list]. [the release list]: https://github.com/hecrj/iced/releases ## Overview -Here is an example showcasing an interactive counter that can be incremented and -decremented using two different buttons: +Inspired by [The Elm Architecture], Iced expects you to split user interfaces +into four different concepts: + + * __State__ — the state of your application + * __Messages__ — user interactions or meaningful events that you care + about + * __View logic__ — a way to display your __state__ as widgets that + may produce __messages__ on user interaction + * __Update logic__ — a way to react to __messages__ and update your + __state__ + +We can build something to see how this works! Let's say we want a simple counter +that can be incremented and decremented using two buttons. + +We start by modelling the __state__ of our application: ```rust -use iced::{button, Button, Column, Text}; -use crate::MyRenderer; +use iced::button; struct Counter { // The counter value value: i32, - // Local state of the two counter buttons - // This is internal widget state that may change outside our update - // logic + // The local state of the two buttons increment_button: button::State, decrement_button: button::State, } +``` -// The user interactions we are interested on +Next, we need to define the possible user interactions of our counter: +the button presses. These interactions are our __messages__: + +```rust #[derive(Debug, Clone, Copy)] pub enum Message { IncrementPressed, DecrementPressed, } +``` -impl Counter { - // The update logic, called when a message is produced - fn react(&mut self, message: Message) { - // We update the counter value after an interaction here - match message { - Message::IncrementPressed => { - self.value += 1; - } - Message::DecrementPressed => { - self.value -= 1; - } - } - } +Now, let's show the actual counter by putting it all together in our +__view logic__: - // The layout logic, describing the different components of the counter - fn layout(&mut self, window: &Window) -> Element<Message, MyRenderer> { - // We use a column so the elements inside are laid out vertically +```rust +use iced::{Button, Column, Text}; +use iced_wgpu::Renderer; // Iced does not include a renderer! We need to bring our own! + +impl Counter { + pub fn view(&mut self) -> Column<Message, Renderer> { + // We use a column: a simple vertical layout Column::new() .push( // The increment button. We tell it to produce an @@ -92,25 +107,81 @@ impl Counter { Button::new(&mut self.decrement_button, "-") .on_press(Message::DecrementPressed), ) - .into() // We can return a generic `Element` and avoid breaking - // changes if we redesign the counter in the future. } } ``` +Finally, we need to be able to react to any produced __messages__ and change our +__state__ accordingly in our __update logic__: + +```rust +impl Counter { + // ... + + pub fn update(&mut self, message: Message) { + match message { + Message::IncrementPressed => { + self.value += 1; + } + Message::DecrementPressed => { + self.value -= 1; + } + } + } +} +``` + +And that's everything! We just wrote a whole user interface. Iced is now able +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__. + Browse the [documentation] and the [examples] to learn more! -[documentation]: https://docs.rs/iced -[examples]: https://github.com/hecrj/iced/tree/master/examples +## Gallery +[![UI Tour - Coffee][gui_gif]][gui_gfycat] + +[gui_gif]: https://thumbs.gfycat.com/GloomyWeakHammerheadshark-small.gif +[gui_gfycat]: https://gfycat.com/gloomyweakhammerheadshark ## Implementation details -Iced is heavily inspired by [Elm], a delightful language for reliable webapps. -It brings the reactive programming model of [The Elm Architecture] into Rust -without introducing weak references or runtime errors. +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. -Iced also uses [Stretch], an implementation of Flexbox written in Rust, to -perform all the layouting. +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]. +After release, different folks asked if the GUI could be split into a standalone +crate, and well... Iced is here! + +As an interesting note, Iced does not rely on reference counting and interior +mutability at all! There is not a single `Rc`, `RefCell`, or similar used +directly in the library. As a consequence, compiler guarantees stay intact and +many kinds of filthy bugs and runtime errors are banished. No spooky action at +a distance! + +[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 + +## Contributing / Feedback +If you want to contribute, you are more than welcome to be a part of the +project! Check out 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. + +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 `#gui-and-ui` channel in +the [Rust Community Discord]. I go by `@lone_scientist` there. + +[documentation]: http://iced-rs.surge.sh/iced/ +[examples]: https://github.com/hecrj/iced/tree/master/examples +[Coffee]: https://github.com/hecrj/coffee [Elm]: https://elm-lang.org/ [The Elm Architecture]: https://guide.elm-lang.org/architecture/ -[Stretch]: https://github.com/vislyhq/stretch +[issues]: https://github.com/hecrj/iced/issues +[Rust Community Discord]: https://bit.ly/rust-community |