Giter Site home page Giter Site logo

iced-rs / iced Goto Github PK

View Code? Open in Web Editor NEW
22.8K 188.0 1.0K 15.97 MB

A cross-platform GUI library for Rust, inspired by Elm

Home Page: https://iced.rs

License: MIT License

Rust 98.74% WGSL 1.26%
gui graphics rust elm interface widget widgets toolkit user-interface renderer-agnostic

iced's Introduction

Iced

Documentation Crates.io License Downloads Test Status Discourse Discord Server

A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm.

Features

Iced is currently experimental software. Take a look at the roadmap, check out the issues, and feel free to contribute!

Installation

Add iced as a dependency in your Cargo.toml:

iced = "0.12"

If your project is using a Rust edition older than 2021, then you will need to set resolver = "2" in the [package] section as well.

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.

Overview

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:

#[derive(Default)]
struct Counter {
    value: i32,
}

Next, we need to define the possible user interactions of our counter: the button presses. These interactions are our messages:

#[derive(Debug, Clone, Copy)]
pub enum Message {
    Increment,
    Decrement,
}

Now, let's show the actual counter by putting it all together in our view logic:

use iced::widget::{button, column, text, Column};

impl Counter {
    pub fn view(&self) -> Column<Message> {
        // We use a column: a simple vertical layout
        column![
            // The increment button. We tell it to produce an
            // `Increment` message when pressed
            button("+").on_press(Message::Increment),

            // We show the value of the counter here
            text(self.value).size(50),

            // The decrement button. We tell it to produce a
            // `Decrement` message when pressed
            button("-").on_press(Message::Decrement),
        ]
    }
}

Finally, we need to be able to react to any produced messages and change our state accordingly in our update logic:

impl Counter {
    // ...

    pub fn update(&mut self, message: Message) {
        match message {
            Message::Increment => {
                self.value += 1;
            }
            Message::Decrement => {
                self.value -= 1;
            }
        }
    }
}

And that's everything! We just wrote a whole user interface. Let's run it:

fn main() -> iced::Result {
    iced::run("A cool counter", Counter::update, Counter::view)
}

Iced will automatically:

  1. Take the result of our view logic and layout its widgets.
  2. Process events from our system and produce messages for our update logic.
  3. Draw the resulting user interface.

Read the book, the documentation, and the examples to learn more!

Implementation details

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 2019 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.

Since then, the focus has shifted towards providing a batteries-included, end-user-oriented GUI library, while keeping the ecosystem modular:

The Iced Ecosystem

Contributing / Feedback

Contributions are greatly appreciated! If you want to contribute, please read our contributing guidelines for more details.

Feedback is also welcome! You can create a new topic in our Discourse forum or come chat to our Discord server.

Sponsors

The development of Iced is sponsored by the Cryptowatch team at Kraken.com

iced's People

Contributors

13r0ck avatar bungoboingo avatar casperstorm avatar clarkmoody avatar cupnfish avatar daxpedda avatar derezzedex avatar dispersia avatar dtzxporter avatar fabianlars avatar friz64 avatar gyulyvgc avatar hatoo avatar hecrj avatar ids1024 avatar imberflur avatar jhff avatar kaiden42 avatar kaimast avatar luni-4 avatar maldela avatar mmstick avatar mtkennerly avatar n1ght-hunter avatar nicksenger avatar nicoburns avatar nisatru avatar polymeilex avatar tarkah avatar wash2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iced's Issues

Fix text caching in `iced_wgpu`

Since we added scrollables (see #35), iced_wgpu supports different layers of primitives.

However, wgpu_glyph does not support drawing text without trimming the cache. In other words, whenever we render multiple layers, we lose text caching.

We will most likely need to contribute to glyph-brush to tackle this.

Radio buttons need to be grouped for proper interaction

Radio buttons should always belong to a group, so that things like the arrow keys work to select a different value, and so that accessibility tools can understand what’s going on with them.

In HTML, this means that grouped radio buttons need to share a name attribute.

Test `Hasher` on Wasm

I have already been able to run Iced on web here: hecrj/coffee#63

However, I had some issues with twox_hash on Wasm and fixed them by migrating to seahash. We should investigate further and use another hasher if necessary.

The Hasher type is opaque, so we should be able to change its underlying implementation without breaking changes.

Text doesn't render until first input event

Hi,
When running the sample counter application, it seems that the text only shows after the first input event:
bug

As you can see, the text only appears after the first time I move the mouse. I can also confirm that pressing a key on the keyboard has the same effect.

As an aside, I've been following Iced for quite some time and am really impressed with how far it has progressed, thanks for such an awesome library 😄

Scrollables / Clippables

Content that can take a (practically) infinite amount of space and can be viewed using a scrollbar. This is a very basic feature.

The end-user API could look like this:

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.

Perform benchmarks

As mentioned in #4, in order to avoid performance regressions, it would be great to run some benchmarks on the different parts of the API.

The most expensive operation is clearly UserInterface::build. This will be the main focus for many of the optimizations we will implement in the future. We should benchmark this first.

UserInterface::update and UserInterface::draw will also get slower the more widgets and events a user interface has to handle. It would be great to have some numbers!

Hot reloading of layout

Like discussed on Discord - perhaps it's nice to provide some sort of "quick iteration" possibility, for example using Lua.

cargo run --example ggez fails

error:

thread 'main' panicked at 'calledResult::unwrap()on anErrvalue: ResourceNotFound("ui.png", [("/Users/marek/projects/iced/target/release/examples/resources", FilesystemError("Path \"ui.png\" is not valid: must be an absolute path with no references to parent directories")), ("/Users/marek/Library/Application Support/ggez.iced", FilesystemError("Path \"ui.png\" is not valid: must be an absolute path with no references to parent directories")), ("/Users/marek/Library/Preferences/ggez.iced", FilesystemError("Path \"ui.png\" is not valid: must be an absolute path with no references to parent directories"))])', src/libcore/result.rs:999:5

Multi-window support

Open and control multiple windows at runtime.

I think this could be achieved by implementing an additional trait in iced_winit similar to Application but with a slightly different view method, allowing users to control what is shown in each window.

This approach should also allow us to perform custom optimizations for this particular use case.

Configurable `futures` executor

I see that you used ThreadPool as the executor. Would you consider making this only the default but allowing to pass a different executor with the help of futures::task::Spawn?

That way a user can implement his own executor or use libraries that support Spawn, hopefully tokio or async-std at some point.

Happy to make a PR for this if you approve.

Originally posted by @daxpedda in #62 (comment)

Panic when running any of the examples under Linux Intel GPU

Environment:

openSUSE Tumbleweed, kernel 5.3.11.
KDE Plasma 5.17.3
System font: Noto Sans
Mesa DRI Intel(R) HD Graphics 620 (Kaby Lake GT2)
Mesa 19.2.4
Vulkan Instance Version: 1.1.127

Running cargo run --example tour causes panic with the following stack trace (snipped):

  15: core::result::Result<T,E>::unwrap
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/result.rs:933
  16: wgpu_glyph::builder::GlyphBrushBuilder<()>::using_fonts_bytes::{{closure}}
             at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu_glyph-0.6.0/src/builder.rs:44
  17: core::iter::adapters::map_fold::{{closure}}
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/iter/adapters/mod.rs:694
  18: core::iter::traits::iterator::Iterator::fold::ok::{{closure}}
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/iter/traits/iterator.rs:1813
  19: core::iter::traits::iterator::Iterator::try_fold
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/iter/traits/iterator.rs:1694
  20: core::iter::traits::iterator::Iterator::fold
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/iter/traits/iterator.rs:1816
  21: <core::iter::adapters::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/iter/adapters/mod.rs:727
  22: core::iter::traits::iterator::Iterator::for_each
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/iter/traits/iterator.rs:616
  23: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::spec_extend
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/liballoc/vec.rs:1966
  24: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/liballoc/vec.rs:1949
  25: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/liballoc/vec.rs:1836
  26: core::iter::traits::iterator::Iterator::collect
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/iter/traits/iterator.rs:1478
  27: wgpu_glyph::builder::GlyphBrushBuilder<()>::using_fonts_bytes
             at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu_glyph-0.6.0/src/builder.rs:41
  28: iced_wgpu::text::Pipeline::new
             at wgpu/src/text.rs:36
  29: iced_wgpu::renderer::Renderer::new
             at wgpu/src/renderer.rs:64
  30: <iced_wgpu::renderer::Renderer as iced_native::renderer::windowed::Windowed>::new
             at wgpu/src/renderer.rs:417
  31: iced_winit::application::Application::run
             at ./winit/src/application.rs:115
  32: iced::application::Application::run
             at ./src/application.rs:140
  33: iced::sandbox::Sandbox::run
             at ./src/sandbox.rs:128
  34: tour::main
             at examples/tour.rs:10

Advanced layout strategies (grid, floating text, etc.)

Currently, iced_native only supports flexbox items. For instance, it is not possible to create a grid of items or make text float around an image.

We will need to enhance the layouting engine to support different strategies and improve the way we measure text to lay it out in a more flexible way.

Height of nested columns is not calculated correctly

Hi,

I'm playing around with iced. I tried GTK rs and OrbTK before. So far I like iced the most. Thanks a lot for all your hard work on that!

I'm building a small test program to search files. The search results are limited to 100 and the user is able to fetch more results with a load more button on the bottom of the results. When clicking on a search result the programm will try to open the file with the associated default program.

Since I need to configure where to search I embedded the search mask into a small tab control. Now It seems that the height of the column inside the tab control does not calculate correctly, because the last five results or so are not visible and the scrollbar is cut off.

See screenshots here:
https://www.notion.so/Search-UI-clipped-scrolbar-1dd435b4ee604e4ab4060971942becc7

For now I set the height of the inner column to fixed to fixed height of 600. If you want to reproduce the issue you can comment out that in line 113 of the /file_search/src/search.rs

The code can be found here
https://github.com/njust/file_search

Thank you again for such a great GUI library!

Hornor

I said help me and i help us and i am here i don't best brain or intelligence but i am a fighter and to the end.

Declarative DSL for creating views

I was checking out vgtk to prototype a quick Gtk UI which follows the same elm architecture story and thought declaring widgets with the gtk! macro is kinda nice, a declarative way for defining pieces of UI is much nicer. Any thoughts? I don't know what the implications of a macro like that would be on iced, if following a similar approach as vgtk's I suspect that a macro that returns a new tree of widgets would require the virtual dom approach for diffing changes and render accordingly?

Error when running examples: "extension NV-GLX missing on display"

I get these errors when I try to run the examples:

todos

    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
     Running `target/debug/examples/todos`
Xlib:  extension "NV-GLX" missing on display ":0.0".
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:378:21
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1028
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1412
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:188
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:205
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:464
  11: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:373
  12: rust_begin_unwind
             at src/libstd/panicking.rs:302
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:139
  14: core::panicking::panic
             at src/libcore/panicking.rs:70
  15: core::option::Option<T>::unwrap
             at /rustc/1423bec54cf2db283b614e527cfd602b481485d1/src/libcore/macros.rs:41
  16: wgpu_request_adapter
             at /home/omer/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-native-0.4.0/src/instance.rs:474
  17: wgpu::Adapter::request
             at /home/omer/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.4.0/src/lib.rs:545
  18: iced_wgpu::renderer::Renderer::new
             at wgpu/src/renderer.rs:51
  19: <iced_wgpu::renderer::Renderer as iced_native::renderer::windowed::Windowed>::new
             at wgpu/src/renderer.rs:417
  20: iced_winit::application::Application::run
             at ./winit/src/application.rs:115
  21: iced::application::Application::run
             at ./src/application.rs:140
  22: todos::main
             at examples/todos.rs:9
  23: std::rt::lang_start::{{closure}}
             at /rustc/1423bec54cf2db283b614e527cfd602b481485d1/src/libstd/rt.rs:61
  24: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:48
  25: std::panicking::try::do_call
             at src/libstd/panicking.rs:287
  26: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
  27: std::panicking::try
             at src/libstd/panicking.rs:265
  28: std::panic::catch_unwind
             at src/libstd/panic.rs:396
  29: std::rt::lang_start_internal
             at src/libstd/rt.rs:47
  30: std::rt::lang_start
             at /rustc/1423bec54cf2db283b614e527cfd602b481485d1/src/libstd/rt.rs:61
  31: main
  32: __libc_start_main
  33: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

tour

    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
     Running `target/debug/examples/tour`
Xlib:  extension "NV-GLX" missing on display ":0.0".
[2019-11-26T06:18:57Z ERROR gfx_backend_vulkan] 
    GENERAL [Loader Message (0)] : setupLoaderTermPhysDevs:  Failed to detect any valid GPUs in the current config
    object info: (type: INSTANCE, hndl: 94410943735344)
    
[2019-11-26T06:18:57Z ERROR gfx_backend_vulkan] 
    GENERAL [Loader Message (0)] : setupLoaderTrampPhysDevs:  Failed during dispatch call of 'vkEnumeratePhysicalDevices' to lower layers or loader to get count.
    object info: (type: INSTANCE, hndl: 94410943735344)
    
[2019-11-26T06:18:57Z ERROR gfx_backend_vulkan] 
    GENERAL [Loader Message (0)] : setupLoaderTermPhysDevs:  Failed to detect any valid GPUs in the current config
    object info: (type: INSTANCE, hndl: 94410943735344)
    
[2019-11-26T06:18:57Z ERROR gfx_backend_vulkan] 
    GENERAL [Loader Message (0)] : setupLoaderTrampPhysDevs:  Failed during dispatch call of 'vkEnumeratePhysicalDevices' to lower layers or loader to get count.
    object info: (type: INSTANCE, hndl: 94410943735344)
    
[2019-11-26T06:18:57Z ERROR gfx_backend_vulkan] Could not enumerate physical devices! Initialization of a object has failed
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:378:21
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1028
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1412
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:188
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:205
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:464
  11: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:373
  12: rust_begin_unwind
             at src/libstd/panicking.rs:302
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:139
  14: core::panicking::panic
             at src/libcore/panicking.rs:70
  15: core::option::Option<T>::unwrap
             at /rustc/1423bec54cf2db283b614e527cfd602b481485d1/src/libcore/macros.rs:41
  16: wgpu_request_adapter
             at /home/omer/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-native-0.4.0/src/instance.rs:474
  17: wgpu::Adapter::request
             at /home/omer/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.4.0/src/lib.rs:545
  18: iced_wgpu::renderer::Renderer::new
             at wgpu/src/renderer.rs:51
  19: <iced_wgpu::renderer::Renderer as iced_native::renderer::windowed::Windowed>::new
             at wgpu/src/renderer.rs:417
  20: iced_winit::application::Application::run
             at ./winit/src/application.rs:115
  21: iced::application::Application::run
             at ./src/application.rs:140
  22: iced::sandbox::Sandbox::run
             at ./src/sandbox.rs:128
  23: tour::main
             at examples/tour.rs:10
  24: std::rt::lang_start::{{closure}}
             at /rustc/1423bec54cf2db283b614e527cfd602b481485d1/src/libstd/rt.rs:61
  25: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:48
  26: std::panicking::try::do_call
             at src/libstd/panicking.rs:287
  27: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
  28: std::panicking::try
             at src/libstd/panicking.rs:265
  29: std::panic::catch_unwind
             at src/libstd/panic.rs:396
  30: std::rt::lang_start_internal
             at src/libstd/rt.rs:47
  31: std::rt::lang_start
             at /rustc/1423bec54cf2db283b614e527cfd602b481485d1/src/libstd/rt.rs:61
  32: main
  33: __libc_start_main
  34: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Can't run example

This error popup on every example project and even on my own iced project.

thread 'main' panicked at 'Unable to enumerate instance extensions: ERROR_INITIALIZATION_FAILED', src\libcore\result.rs:1189:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

Also, when I try to import module in VS code it doesn't seem to provide import suggestion for component (i.e. iced::button, iced::Element) but it does provide import to settings, Sandbox and Settings

System:
OS: Windows 10
GPU: Nvidia GeForce GTX 1080 (Up to date driver)
Version: iced = 0.1.0-beta
Rust: stable-x86_64-pc-windows-msvc

Async actions

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.

Here is an example of how the end-user API could look:

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()
            }
        }
    }
}

Increased CPU usage when interacting with other non-iced windows

When running the examples from the repo (master branch hash 811d8b9) compiled to release, I noticed that the CPU usage for that process increase to 5-10% while interacting with other windows. Examples are moving my mouse along my dock, moving my mouse along files in my file browser, and resizing a different window. All of those actions become choppy and slow as well. When the iced example is closed, those actions return to normal. The idle CPU usage of the iced process is very low otherwise.

I'm not quite sure how the iced process is being affected by doing these unrelated things.

System information:
Manjaro Linux, kernel 5.3.12
KDE Plasma 5.17.3
Rust 1.39

If there's further information I can provide, let me know.

Constants applicable to all renderers

Hi !

As you may have noticed, I'm currently writing a ncurses-based renderer for iced on my spare time, and am using my own fork of iced for that purpose.

The only modification I did was to change some defaults. As it happens, the current constants are assuming pixel unit when pancurses of course works with lines and columns. This makes the current default on some Widgets (e.g. Checkbox, Slider, and Buttons) completely wrong.

Even if not considering my use case, which I agree is fairly uncommon, I am not sure what these constants were there for in the first place, because they assume some sort of mandatory smaller screen resolution.

What do you think would be the correct way of not enforcing those defaults upon every renderer implementor ?

Canvas widget

A widget to draw freely in 2D or 3D. It could be used to draw charts, implement a Paint clone, a CAD application, etc.

As a first approach, we could expose the underlying renderer directly here, and couple this widget with it (wgpu for now). Once wgpu gets WebGL or WebGPU support, this widget will be able to run on web too. The renderer primitive could be a simple texture that the widget draws to.

In the long run, we could expose a renderer-agnostic abstraction to perform the drawing.

Animations

Allow widgets to request a redraw at a specific time.

This is a necessary feature to render loading spinners, a blinking text cursor, GIF images, etc.

winit allows controlling the event loop in a flexible way. We may be able to use ControlFlow::WaitUntil for this purpose.

Set up a chat server

I think a channel for low-effort and low-latency communication may be a good idea to coordinate development between contributors, answer quick questions, and build a community around the library.

While it may be a bit early to do this now, I think we can start discussing our options so we are ready if/when the time comes. Here are the ones I know of:

  • Discord, this is widely used in the Rust ecosystem. The official Rust Programming Language and the Rust Community servers are on Discord.
  • Gitter, a very common alternative. I use it for coffee, wgpu and gfx.
  • Matrix. I know winit uses it, but I am not very familiar with it.
  • Zulip. I haven't used it, not sure how much it favours low-effort messages.
  • Rocket.Chat. I just heard of it recently. It looks very interesting.

I personally think Discord is the option with less friction while still getting a pretty flexible server and functional clients. However, I understand there may be other concerns when choosing a chat server.

Feel free to share your thoughts, experiences, and favorite choices here!

Build script panic when building dependency "x11"

When attempting to build iced the custom build script for x11 panics, however, when cloning x11 from source directly and attempting to build it, it built without issue. I've included the stacktrace below:

error: failed to run custom build command for `x11 v2.18.1`

Caused by:
  process didn't exit successfully: `/home/zack/CLionProjects/Rust/iced_testing/target/debug/build/x11-78cf3bc4c321325c/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Failure { command: "\"pkg-config\" \"--libs\" \"--cflags\" \"x11\" \"x11 >= 1.4.99.1\"", output: Output { status: ExitStatus(ExitStatus(256)), stdout: "", stderr: "Package x11 was not found in the pkg-config search path.\nPerhaps you should add the directory containing `x11.pc\'\nto the PKG_CONFIG_PATH environment variable\nPackage \'x11\', required by \'virtual:world\', not found\nPackage \'x11\', required by \'virtual:world\', not found\n" } }', src/libcore/result.rs:1165:5
stack backtrace:
   0:     0x55ae9bdbe2e4 - backtrace::backtrace::libunwind::trace::hda41dbcdfba36aa0
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/libunwind.rs:88
   1:     0x55ae9bdbe2e4 - backtrace::backtrace::trace_unsynchronized::h1a8d6e1f8cb3f5d4
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/mod.rs:66
   2:     0x55ae9bdbe2e4 - std::sys_common::backtrace::_print_fmt::h610c4127487e10da
                               at src/libstd/sys_common/backtrace.rs:76
   3:     0x55ae9bdbe2e4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h0722dc552e01bd1d
                               at src/libstd/sys_common/backtrace.rs:60
   4:     0x55ae9bddc7dc - core::fmt::write::h01edf6dd68a42c9c
                               at src/libcore/fmt/mod.rs:1030
   5:     0x55ae9bdbb627 - std::io::Write::write_fmt::hf15985f193f03c04
                               at src/libstd/io/mod.rs:1412
   6:     0x55ae9bdc07a5 - std::sys_common::backtrace::_print::hd8d5d08a1795e743
                               at src/libstd/sys_common/backtrace.rs:64
   7:     0x55ae9bdc07a5 - std::sys_common::backtrace::print::hf89a79e3921a2366
                               at src/libstd/sys_common/backtrace.rs:49
   8:     0x55ae9bdc07a5 - std::panicking::default_hook::{{closure}}::h3a8f42beb3bb8ae3
                               at src/libstd/panicking.rs:196
   9:     0x55ae9bdc0496 - std::panicking::default_hook::h8f803b0bc31a5c37
                               at src/libstd/panicking.rs:210
  10:     0x55ae9bdc0df5 - std::panicking::rust_panic_with_hook::h825f041245da8739
                               at src/libstd/panicking.rs:473
  11:     0x55ae9bdc0992 - std::panicking::continue_panic_fmt::hbe0378e33481e81b
                               at src/libstd/panicking.rs:380
  12:     0x55ae9bdc0886 - rust_begin_unwind
                               at src/libstd/panicking.rs:307
  13:     0x55ae9bdd9eea - core::panicking::panic_fmt::h527855ce0bc891f6
                               at src/libcore/panicking.rs:85
  14:     0x55ae9bdd9fe7 - core::result::unwrap_failed::ha8b77e6004f0ba38
                               at src/libcore/result.rs:1165
  15:     0x55ae9bd7a747 - core::result::Result<T,E>::unwrap::h4e34b216e65974e2
                               at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/result.rs:933
  16:     0x55ae9bd79e22 - build_script_build::main::h11f4fc9c02b5d0ff
                               at /home/zack/.cargo/registry/src/github.com-1ecc6299db9ec823/x11-2.18.1/build.rs:36
  17:     0x55ae9bd7c320 - std::rt::lang_start::{{closure}}::h6bfd41807862563b
                               at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libstd/rt.rs:64
  18:     0x55ae9bdc0873 - std::rt::lang_start_internal::{{closure}}::ha04574f12d97cbe2
                               at src/libstd/rt.rs:49
  19:     0x55ae9bdc0873 - std::panicking::try::do_call::h7c2a8488f72db90c
                               at src/libstd/panicking.rs:292
  20:     0x55ae9bdc6dfa - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:80
  21:     0x55ae9bdc12ed - std::panicking::try::hc3a9b5da4250385d
                               at src/libstd/panicking.rs:271
  22:     0x55ae9bdc12ed - std::panic::catch_unwind::hf27600bf8c37809a
                               at src/libstd/panic.rs:394
  23:     0x55ae9bdc12ed - std::rt::lang_start_internal::h409d4f2fe51133b0
                               at src/libstd/rt.rs:48
  24:     0x55ae9bd7c2f9 - std::rt::lang_start::hc65c0d8d6217d1a5
                               at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libstd/rt.rs:64
  25:     0x55ae9bd79f1a - main
  26:     0x7f1376ece1a3 - __libc_start_main
  27:     0x55ae9bd791fe - _start
  28:                0x0 - <unknown>

warning: build failed, waiting for other jobs to finish...

This is occurring on a fully updated installation of Fedora 31 with KDE (so Xorg is installed).

Layers

Currently, Iced assumes widgets cannot be laid out on top of each other. We should implement support for multiple layers of widgets.

This is a necessary feature to implement many kind of interactables, like dropdown menus, select fields, etc.

iced_native will need to group widgets to perform layouting and process some events first for widgets positioned on top.

iced_wgpu will also need to process the scene graph and sort draw calls based on the different layers.

Implement a low-level renderer

Both the renderer in coffee and the ggez one in the examples are using a high-level abstraction. This makes it really easy to build a somewhat simple renderer, but makes interesting features (like scrollables) complicated.

I would like to implement a renderer using a lower-level API. This renderer could accept different kinds of configuration, and also support widgets with many styling options.

I am familiar with wgpu, and supporting all the platforms natively and also the web sounds great! In any case, I think there are many interesting similar efforts that may be worth investigating and contributing to!

TodoMVC example

Once we have scrollables support (#24) and a text widget (#25), 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.

Could not compile on Windows 10

cargo build error:

error: linking with `link.exe` failed: exit code: 1181
  |
  = note: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.0.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.1.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.10.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.11.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.12.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.13.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.14.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.15.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.2.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.3.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.4.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.5.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.6.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.7.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.8.rcgu.o" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.wgpu_native.45c7bj90-cgu.9.rcgu.o" "/OUT:D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.dll" "/DEF:C:\\Users\\win10\\AppData\\Local\\Temp\\rustcE3CSYX\\lib.def" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.8ujg474y49fburg.rcgu.o" "/OPT:REF,NOICF" "/DEBUG" "/NATVIS:C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" "/NATVIS:C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" "/LIBPATH:D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps" "/LIBPATH:D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\build\\spirv_cross-822fdf5d582f829b\\out" "/LIBPATH:C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libvec_map-6b5ed48c56c3ea7e.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\librendy_memory-0c0ceb15de0dd5d1.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libslab-5253dc30818378e7.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libcolorful-1e0115a11262f2fd.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libhibitset-25f9d9d12b665732.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libatom-5e5107ff53c33320.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libcopyless-4c5cdd18f01c8c18.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\librendy_descriptor-41f4fd6eb9214854.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\librelevant-711d85836e875e45.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libgfx_backend_vulkan-b04aee75bf7123ed.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libarrayvec-93444571194bab8e.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libash-a42174fcd071bd32.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libshared_library-1de01e7303241d06.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\liblazy_static-5d95ab3a716e6edf.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libgfx_backend_empty-e982801c1e4b95c0.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libgfx_backend_dx12-7814ae104f2d86cb.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libd3d12-42a2f0339e092af9.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libgfx_backend_dx11-891e8bf47e6dcebb.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libwio-a0de60c49ac1dc96.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libparking_lot-2b2b79b35dee381e.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libparking_lot_core-039a13c8afe2422b.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\liblock_api-275d419f1dc74ff1.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libscopeguard-a2aa3fd973dbd64e.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\liblog-9a9980a9b1c9c283.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libcfg_if-c4543fac99ff34d0.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\liblibloading-be53d77e4a108b64.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libwinapi-5d90a86b74c4e1ef.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\librange_alloc-950acbb746f53dc0.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libgfx_auxil-5c6879679cab3fb0.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libfxhash-8ef6fa334d9de562.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libbyteorder-3cc98079fd79a928.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libspirv_cross-9a7d5d3efcc242bf.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libgfx_hal-f070d8774e1fe4c2.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libraw_window_handle-52e741c03d511b45.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\liblibc-dd19e70b2c3a7d3b.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libsmallvec-6c6d19fc080c63a3.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libmaybe_uninit-9dcc5648539074cb.rlib" "D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\libbitflags-9bd8c071b2f7f67d.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-fd32e3d4d70d74a8.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-557a01ab7680eef9.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-557ff2b95e1a2123.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-6b725878f5860e39.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libbacktrace-eeb49d86966a52f0.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-528449ebe6b7fb1b.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-2b8b04950ded9f63.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-92bce5665c37faaf.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-ccff95d8ef13471a.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-aae606cf8fbaa72b.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-d3be35aad0e0a879.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-ade7404a2a5358d2.rlib" "C:\\Users\\win10\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-6b975b0c697eaeaf.rlib" "advapi32.lib" "cfgmgr32.lib" "comctl32.lib" "credui.lib" "d2d1.lib" "d3d11.lib" "d3d12.lib" "d3dcompiler.lib" "dwmapi.lib" "dwrite.lib" "dxgi.lib" "fwpuclnt.lib" "gdi32.lib" "kernel32.lib" "msimg32.lib" "ntdll.lib" "ole32.lib" "opengl32.lib" "secur32.lib" "shcore.lib" "shell32.lib" "shlwapi.lib" "synchronization.lib" "user32.lib" "uxtheme.lib" "windowscodecs.lib" "winspool.lib" "ws2_32.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "msvcrt.lib" "/DLL" "/IMPLIB:D:\\wkspace\\prsnl\\rusty\\iced\\target\\debug\\deps\\wgpu_native-ab4fe8ae49068d7d.dll.lib"
  = note: LINK : fatal error LNK1181: cannot open input file 'd3d12.lib'


error: aborting due to previous error

error: could not compile `wgpu-native`.

Any ideas? The version is Windows 10 17134

Image::from_bytes factory

Hello!
I think a good idea, to have Image::from_bytes factory. This will allow to include the image bytes in an executable binary or load it manually.

Example:

use iced::{Image, image::ImageFormat};
const MY_IMAGE: &'static [u8] = include_bytes!("resources/img.png");

fn get_img() -> Image {
  Image::from_bytes(MY_IMAGE, ImageFormat::PNG)
}

Use something other than `font-kit` and/or put it behind feature gate

font-kit seems like a nice lib, however it's very much not pure Rust, requiring not only a full c++ build system but also several C libs and their associated header files to be installed on a system (at least on Linux), and as such presents a fairly significant bar to entry. It would be nice not to depend on it. Also, even after getting it to compile on Fedora, I stlil get this output in my terminal when runing the todos example, though it does seem to work at least.

edit

error output was fixed by updating outdated fontconfig-devel.

Just for reference, on Fedora 30, I had to install cmake, g++, freetype, freetype-devel, expat-devel, and fontconfig-devel for it to work.

Upgrade `stretch`

Iced was built during May using the 0.2 version of stretch. It seems that a new minor version was released recently, in July. We should consider upgrading.

At a first glance, the API has changed somewhat considerably. There is a new Stretch type that you have to keep around and mutate accordingly. I am guessing this allows (or will allow) for incremental computation of layouting, which is great!

However, in order to mutate the Stretch type and keep it in sync, we will need to implement a diffing strategy of nodes. This is mostly a solved problem, as React and Elm already do it, but some research will certainly be necessary and we will probably need to change the API a bit.

Also, as a naive first approach, we could simply recreate the Stretch type entirely every time.

In any case, benchmarking before upgrading is a good idea.

Decouple built-in widgets from their style

Some of the built-in widgets have part of their style hard-coded, like height.

We should be able to move this logic into the Renderer trait of each widget. Now, there are different ways of doing this:

  • constants, like Renderer::HEIGHT
  • simple methods, like Renderer::height
  • a single complex method to decorate a provided style, like Renderer::style

We should think about the pros and cons of each before proceeding. Also, feel free to suggest new ideas!

Text input widget

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 (see #24), 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:

pub enum Message {
    TextChanged(String),
}

let text_input = text_input::State::new();
let text = "Hello";

TextInput::new(&mut text_input, &text, Message::TextChanged);

Text shaping and font fallback

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.

The only available library that does a great job at shaping is HarfBuzz, which is implemented in C++. skribo seems to be a nice HarfBuzz wrapper for Rust.

This feature will probably imply rewriting wgpu_glyph entirely, as caching will be more complicated and the API will probably need to ask for more data.

(V)DOM renderer

Iced working on the web would be awesome, the plan of creating a low level renderer with wgpu-rs is great but could take some time on your side and theirs(last time I checked web support was not there?) so DOM rendering in the mean time?(side question, would it be easy to mix renderers? like a map component rendered with a wgpu renderer and the rest of the UI with the DOM one?).

The flexbox model of iced should make it easy to create a DOM renderer. For example with Dodrio, the experimental virtual DOM library showcased by Mozilla, should facilitate things and help with performance at the same time instead of using web-sys APIs directly. Structs implement the render trait of dodrio and build the DOM elements, so would it be just implementing the dodrio trait for each widget and put some DOM there?

Running tour example crashes

$ RUST_BACKTRACE=full cargo run --example tour
   Compiling iced v0.1.0-alpha.1 (/opt/user/projects/rust/iced)
    Finished dev [unoptimized + debuginfo] target(s) in 8.73s
     Running `target/debug/examples/tour`
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:378:21
stack backtrace:
   0:     0x55788f0bf524 - backtrace::backtrace::libunwind::trace::h924a2d8576118736
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/libunwind.rs:88
   1:     0x55788f0bf524 - backtrace::backtrace::trace_unsynchronized::h74a88d3cf8e9a73f
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/mod.rs:66
   2:     0x55788f0bf524 - std::sys_common::backtrace::_print_fmt::hd0a3b38a8cacdd34
                               at src/libstd/sys_common/backtrace.rs:77
   3:     0x55788f0bf524 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h900e23881de8b515
                               at src/libstd/sys_common/backtrace.rs:61
   4:     0x55788f0e18fc - core::fmt::write::hb62ff58e7d34938d
                               at src/libcore/fmt/mod.rs:1028
   5:     0x55788f0bc6c7 - std::io::Write::write_fmt::h1145a99f1b56dffb
                               at src/libstd/io/mod.rs:1412
   6:     0x55788f0c1a5e - std::sys_common::backtrace::_print::h07f05d3309624875
                               at src/libstd/sys_common/backtrace.rs:65
   7:     0x55788f0c1a5e - std::sys_common::backtrace::print::hb74628deb996392c
                               at src/libstd/sys_common/backtrace.rs:50
   8:     0x55788f0c1a5e - std::panicking::default_hook::{{closure}}::h734c09947ffbd003
                               at src/libstd/panicking.rs:188
   9:     0x55788f0c1761 - std::panicking::default_hook::h908a92137d0058d0
                               at src/libstd/panicking.rs:205
  10:     0x55788f0c2155 - std::panicking::rust_panic_with_hook::h650d4fa2f01dd14f
                               at src/libstd/panicking.rs:468
  11:     0x55788f0c1cf2 - std::panicking::continue_panic_fmt::h5a2e12ad03a05116
                               at src/libstd/panicking.rs:375
  12:     0x55788f0c1be6 - rust_begin_unwind
                               at src/libstd/panicking.rs:302
  13:     0x55788f0dd84a - core::panicking::panic_fmt::h2085bf231b704859
                               at src/libcore/panicking.rs:84
  14:     0x55788f0dd789 - core::panicking::panic::h661d298fb9656deb
                               at src/libcore/panicking.rs:49
  15:     0x55788ed50bb8 - core::option::Option<T>::unwrap::h696c273354b9d247
                               at /rustc/d6e4028a0db6b13d9a603baad109d6c902802c03/src/libcore/macros.rs:12
  16:     0x55788ee4fb4a - wgpu_request_adapter
                               at /home/user/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/wgpu-native-0.4.0/src/instance.rs:474
  17:     0x55788ec33a2e - wgpu::Adapter::request::h27ad7906023de13e
                               at /home/user/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/wgpu-0.4.0/src/lib.rs:545
  18:     0x55788e8a7a49 - iced_wgpu::renderer::Renderer::new::hd64e44c0cfaceb9b
                               at wgpu/src/renderer.rs:52
  19:     0x55788e8a95fd - <iced_wgpu::renderer::Renderer as iced_native::renderer::windowed::Windowed>::new::h1187b1c0a75e7ebf
                               at wgpu/src/renderer.rs:408
  20:     0x55788e2b1ad4 - iced_winit::application::Application::run::h9e52d075590b103d
                               at /opt/user/projects/rust/iced/winit/src/application.rs:45
  21:     0x55788e30524f - iced::Application::run::hc8dd05cc18aeb769
                               at /opt/user/projects/rust/iced/src/lib.rs:19
  22:     0x55788e27902e - tour::main::h631a4a9956d12f72
                               at examples/tour.rs:12
  23:     0x55788e29a320 - std::rt::lang_start::{{closure}}::hde72aaacb5a38ea1
                               at /rustc/d6e4028a0db6b13d9a603baad109d6c902802c03/src/libstd/rt.rs:61
  24:     0x55788f0c1b83 - std::rt::lang_start_internal::{{closure}}::hcf6da9c99990640b
                               at src/libstd/rt.rs:48
  25:     0x55788f0c1b83 - std::panicking::try::do_call::h17432816cf89d4ed
                               at src/libstd/panicking.rs:287
  26:     0x55788f0c5f9a - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:80
  27:     0x55788f0c270d - std::panicking::try::h0e688f45fe70b693
                               at src/libstd/panicking.rs:265
  28:     0x55788f0c270d - std::panic::catch_unwind::hbb42d3798dc91a2f
                               at src/libstd/panic.rs:396
  29:     0x55788f0c270d - std::rt::lang_start_internal::h4acffefca599d770
                               at src/libstd/rt.rs:47
  30:     0x55788e29a2f9 - std::rt::lang_start::h14dfe4dc38d8df1b
                               at /rustc/d6e4028a0db6b13d9a603baad109d6c902802c03/src/libstd/rt.rs:61
  31:     0x55788e27f13a - main
  32:     0x7f8b6f1ca153 - __libc_start_main
  33:     0x55788e2691ae - _start
  34:                0x0 - <unknown>

Event subscriptions

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.

The idea here is to also follow Elm's footsteps. We can add a method subscriptions(&self) -> Subscription<Message> to Application and keep the subscriptions alive in the runtime.

The challenge here is designing the public API of subscriptions, so users can build their own, and subscription diffing, or basically detecting when a subscription is added/changed/removed. For this, we can take a look at the source code of Elm for inspiration.

The example still using a custom fork of ggez.

With the ggez 5.1, use your custom fork is still something required?

The example is built on top of ggez, a game library for Rust. Currently, it is using a personal fork to add a FontCache type and fix some issues with HiDPI.

run example error: `cargo run --example tour`

system: archlinux

error backtrace:

$ RUST_BACKTRACE=1 cargo run --example tour
    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
     Running `target/debug/examples/tour`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: IllFormed', src/libcore/result.rs:1165:5
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1028
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1412
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:188
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:205
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:464
  11: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:373
  12: rust_begin_unwind
             at src/libstd/panicking.rs:302
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:139
  14: core::result::unwrap_failed
             at src/libcore/result.rs:1165
  15: core::result::Result<T,E>::unwrap
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/result.rs:933
  16: wgpu_glyph::builder::GlyphBrushBuilder<()>::using_fonts_bytes::{{closure}}
             at /home/fu/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/wgpu_glyph-0.6.0/src/builder.rs:44
  17: core::iter::adapters::map_fold::{{closure}}
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/iter/adapters/mod.rs:694
  18: core::iter::traits::iterator::Iterator::fold::ok::{{closure}}
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/iter/traits/iterator.rs:1828
  19: core::iter::traits::iterator::Iterator::try_fold
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/iter/traits/iterator.rs:1709
  20: core::iter::traits::iterator::Iterator::fold
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/iter/traits/iterator.rs:1831
  21: <core::iter::adapters::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/iter/adapters/mod.rs:727
  22: core::iter::traits::iterator::Iterator::for_each
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/iter/traits/itera
tor.rs:631
  23: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::spec_extend
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/liballoc/vec.rs:2031
  24: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/liballoc/vec.rs:2014
  25: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/liballoc/vec.rs:1901
  26: core::iter::traits::iterator::Iterator::collect
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/iter/traits/iterator.rs:1493
  27: wgpu_glyph::builder::GlyphBrushBuilder<()>::using_fonts_bytes
             at /home/fu/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/wgpu_glyph-0.6.0/src/builder.rs:41
  28: iced_wgpu::text::Pipeline::new
             at wgpu/src/text.rs:36
  29: iced_wgpu::renderer::Renderer::new
             at wgpu/src/renderer.rs:64
  30: <iced_wgpu::renderer::Renderer as iced_native::renderer::windowed::Windowed>::new
             at wgpu/src/renderer.rs:417
  31: iced_winit::application::Application::run
             at ./winit/src/application.rs:115
  32: iced::application::Application::run
             at ./src/application.rs:140
  33: iced::sandbox::Sandbox::run
             at ./src/sandbox.rs:128
  34: tour::main
             at examples/tour.rs:10
  35: std::rt::lang_start::{{closure}}
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libstd/rt.rs:61
  36: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:48
  37: std::panicking::try::do_call
             at src/libstd/panicking.rs:287
  38: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:79
  39: std::panicking::try
             at src/libstd/panicking.rs:265
  40: std::panic::catch_unwind
             at src/libstd/panic.rs:396
  41: std::rt::lang_start_internal
             at src/libstd/rt.rs:47
  42: std::rt::lang_start
             at /rustc/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libstd/rt.rs:61
  43: main
  44: __libc_start_main
  45: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Text Selection

It would be nice to be able to select a range of text with the mouse/+keyboard. I think this would be required for copying sections of text when clipboard support is added.

Is no-std in-scope of this project?

I am looking to implement an embedded UI, so I could port a no-std compatible core to a render backend, if that is in line with the project. Just asking.

Interest in iOS support

Hi friend, I just found this project and think it looks pretty promising.

After looking through a bit of the project and dependencies, it looks like iOS support doesn’t look like it would be hard to add at all. I’d be interested in adding an example Xcode project and some literature on it. What do you think?

Winit Error when running Example on Ubuntu 19.04

Getting the following error when trying to run cargo run --example tour on my Ubuntu 19.04 lappy.

[2019-11-25T23:31:50Z ERROR winit::platform_impl::platform] X11 error: XError {
        description: "BadDrawable (invalid Pixmap or Window parameter)",
        error_code: 9,
        request_code: 149,
        minor_code: 4,
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.