7.8 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 iced_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)
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.
Layers (#30)
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 kinds 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.
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 (#32)
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 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.