iced-mobile/ROADMAP.md

7.4 KiB

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

Before diving into the roadmap, check out the ecosystem overview to get an idea of the current state of the library.

Next steps

Most of the work related to these features needs to happen in the native path of the ecosystem, as the web already supports many of them.

Once a step is completed, it is collapsed and added to this list:

  • Scrollables / Clippables (#24)
  • Text input widget (#25)
  • TodoMVC example (#26)
  • Async actions (#28)
  • Custom layout engine (#52)
  • Event subscriptions (#122)
  • Custom styling (#146)
  • Canvas for 2D graphics (#193)
  • Basic overlay support (#444)

Multi-window support (#27)

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.

Animations (#31)

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 flexible control of its event loop. We may be able to use ControlFlow::WaitUntil for this purpose.

Canvas widget for 3D graphics (#32)

A widget to draw freely in 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 the 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.

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.

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.

Grid layout and text layout (#34)

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.

Ideas that may be worth exploring

Reuse existing 2D renderers

While I believe wgpu has a great future ahead of it, implementing iced_wgpu and making it performant will definitely be a challenge.

We should keep an eye on existing 2D graphic libraries, like piet or pathfinder, and give them a try once/if they mature a bit more.

The good news here is that most of Iced is renderer-agnostic, so changing the rendering strategy, if we deem it worth it, should be really easy. Also, a 2D graphics library will expose a higher-level API than wgpu, so implementing a new renderer on top of it should be fairly straightforward.

Remove explicit state handling and lifetimes

Currently, iced_native forces users to provide the local state of each widget. While this could be considered a really pure form of describing a GUI, it makes some optimizations harder because of the borrow checker.

The current borrow checker is not able to detect a drop was performed before reassigning a value to a mutable variable. Thus, keeping the generated widgets in Application::view alive between iterations of the event loop is not possible, which forces us to call this method quite often. unsafe could be used to workaround this, but it would feel fishy.

We could take a different approach, and keep some kind of state tree decoupled from the actual widget definitions. This would force us to perform diffing of nodes, as the widgets will represent the desired state and not the whole state.

Once the state lifetime of widgets is removed, we could keep them alive between iterations and even make Application::view take a non-mutable reference. This would also improve the end-user API, as it will not be necessary to constantly provide mutable state to widgets.

This is a big undertaking and introduces a new set of problems. We should research and consider the implications of this approach in detail before going for it.

Try a different font rasterizer

wgpu_glyph depends indirectly on rusttype. We may be able to gain performance by using a different font rasterizer. fontdue, for instance, has reported noticeable speedups.

Connect iced_web with web-view

It may be interesting to try to connect iced_web with web-view. It would give users a feature-complete renderer for free, and applications would still be leaner than with Electron.

Implement a lazy widget

Once we remove state lifetimes from widgets, we should be able to implement a widget storing a function that generates additional widgets. The runtime would then be able to control when to call this function and cache the generated widgets while some given value does not change.

This could be very useful to build very performant user interfaces with a lot of different items.

Elm does it very well!