Skip to content

nannou_ui - A more efficient, nannou-friendly approach to UI compatible with future GUI editor plans. #383

@mitchmindtree

Description

@mitchmindtree

This issue is an actionable follow-up to the conclusions drawn in #2. Here I'll track my progress and plans, updating this top-level comment as I go.

Much of the work will draw from my work on conrod and the lessons learned during that process. That said, nannou_gui will differ in some fundamental ways:

  • nannou_gui will remain tightly associated with nannou, leveraging its existing color, geometry, mesh and windowing abstractions. This will solve some annoying, existing type compatibility issues that currently exist in nannou's Ui, such as the need to use different color types between the UI and Draw APIs.
  • nannou_gui will be based on a "retained-mode" API rather than an "immediate-mode" API. There are a few reasons for this:
    • Performance. The existing immediate mode API is more than efficient enough for projects requiring small, non-complex GUIs, but can become quite taxing on CPU in large, sophisticated applications (see spatial_audio_server). This is due to the requirement for updating all visible widgets once every update, regardless of whether or not they have changed. That said, the ergonomics provided by immediate mode GUIs are highly beneficial. It should be possible to implement an immediate-mode API over the retained-mode API with an approach involving a lot of caching, which is largely how any slightly-efficient immediate mode GUI works internally anyway.
    • GUI Editor. nannou_gui is designed with GUI editor usage in mind - that is, the ability to design and develop efficient GUIs via a GUI. This requires the ability to treat widgets and their events as serializable data, an approach that is not currently possible with the existing immediate mode API in an efficient manner.

Blocking issues

Roadmap

  • Create repository.
  • Settle on design for state synchronisation.
    • Research existing native-target, Rust UI efforts and discuss in comments below:
  • Graph - The data structure describing widget ownership and layout.
  • Events - UI event types and functions for interpreting them from raw windowing events.
  • Widget - a trait implemented for all widget types. Either this trait, or a closely related SerdeWidget trait should require Deserialize and Serialize and allow for trait object serialization via the typetag crate. While designing this interface, it will be important to consider that it should be possible to create widgets and their implementations entirely from scratch at run-time. Edit: alternatively, consider storing dynamically created widgets as code?
  • Theme - a flexible data-structure allowing for the association of unique styling defaults per widget.
  • Primitive Widgets - a small collection of widgets from which all other widgets may be composed:
    • Mesh - indexable triangulation consisting of a collection of vertex attribute channels. E.g. position, texture coordinates, colour, normals.
    • Text - based on the rusttype crate.
    • Crop - crops children to rectangular area, maps directly to wgpu scissor implementation.
    • Path - lyon path that may be stroke/fill tessellated.
    • Blend - all children have the specified blend mode applied.
    • Layout widgets (inspired by druid/flutter):
      • Pad - pads area for specified child.
      • Flex - container automatically distributing children along a range.
      • Flow - container automatically distributing children along multiple ranges (row by row or column by column).
      • Split - container for two children, split in the middle.
      • Either - container conditionally showing child A or child B.
      • Fixed - child has area with fixed size and position (aka not responsive to flex).
  • Render pass for UI.
  • DynWidget (or DataWidget or DynamicWidget) - a highly flexible, serializable Widget implementation allowing for arbitrary configurations of children widgets at runtime. This will serve as the base type for widgets composed within the GUI editor.
  • Proof of concept examples:
    • Demonstration of each primitive widget.
    • Simple graph widget + gantz demonstration.

Upon completing this roadmap, nannou_gui should be ready to serve as the basis of a nannou_gui_editor crate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions