Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the surface of the Renderer APIs #1110

Merged
merged 94 commits into from
Nov 7, 2021
Merged

Conversation

hecrj
Copy link
Member

@hecrj hecrj commented Nov 5, 2021

This PR reduces the surface of the Renderer APIs in iced to simplify the process of implementing new renderers.

iced_graphics already offers a small set of Backend traits to implement renderers, but it is considerably opinionated as it forces their implementors to deal with a Primitive tree.

The changes here aim to move most of the logic from iced_graphics to iced_native by:

  • unifying the Renderer traits,
  • hiding the Primitive trees,
  • and hardcoding the widget style sheets.

Unified Renderer traits

Instead of defining a Renderer trait for each widget, iced_native now defines only 4 main Renderer traits. Specifically:

  • Renderer exposes methods to draw simple geometric shapes (just rectangles, for now!), as well as methods for layering and applying affine transformations.
  • text::Renderer exposes methods to draw, measure, and hit-test text primitives.
  • image::Renderer exposes methods to measure and draw raster graphics.
  • svg::Renderer exposes methods to measure and draw vector graphics.

As a result, we can implement the drawing logic of the built-in widgets directly in the implementation of Widget::draw in iced_native, instead of depending on iced_graphics.

Hidden Primitive trees

The Primitive tree was initially introduced to allow for easy composition of rendering primitives. However, some renderer implementation may choose to use a different data structure to represent composable drawing operations and, as such, using Primitive should not be enforced.

Therefore, instead of outputting a Primitive as a result, Widget::draw expects you to record the draw commands directly into the renderer argument, using the Painter's algorithm.

Internally, the renderer can choose to represent these drawing operations as it pleases. iced_graphics may even be able to drop the Primitive tree altogether and generate the layers to be uploaded to the GPU directly during the recording of the draw operations!

Decoupled mouse::Interaction

Until now, Widget::draw expected us to produce a mouse::Interaction together with the widget Primitive. This was not only cumbersome but also incorrectly architected, since the mouse interaction has nothing to do with the drawing operations (see #377 (review)).

Therefore, the Widget and Overlay traits now feature a dedicated mouse_interaction method.

Hardcoded StyleSheet

Given that each widget now does not provide its own Renderer trait, the style of a widget is no longer defined through an assocciated type. As a consequence, we can directly depend on iced_style and hardcode the StyleSheet trait for each widget.

Furthermore, we can actually leverage lifetimes! Effectively, this means that now it is possible to borrow any Application state in any StyleSheet implementor!

Together, these changes remove a bunch of unnecessary indirection in iced_native, simplify the overall codebase, and allow for more freedom to implement custom renderers while reducing their API surface at the same time! 🎉

hecrj added 30 commits October 14, 2021 16:07
Rendering the scroller is still WIP
@hecrj hecrj added improvement An internal improvement feature New feature or request labels Nov 5, 2021
@hecrj hecrj added this to the 0.4.0 milestone Nov 5, 2021
@hecrj hecrj merged commit eafad00 into master Nov 7, 2021
@hecrj hecrj deleted the remove-renderer-traits branch November 7, 2021 09:15
@hecrj hecrj self-assigned this Jan 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request improvement An internal improvement
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

1 participant