From cbb9ca724bd36de9c3186ff69f9fceae512b0a39 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Wed, 14 Apr 2021 15:45:40 -0400 Subject: [PATCH 01/15] Initial UI Building Blocks RFC Moved from https://github.com/alice-i-cecile/bevy-temp-rfc/pull/4 --- rfcs/ui-building-blocks.md | 413 +++++++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 rfcs/ui-building-blocks.md diff --git a/rfcs/ui-building-blocks.md b/rfcs/ui-building-blocks.md new file mode 100644 index 00000000..0bf88224 --- /dev/null +++ b/rfcs/ui-building-blocks.md @@ -0,0 +1,413 @@ +# Feature Name: `ui_building_blocks` + +## Summary + +This RFC establishes a common vocabulary, and basic data structures for UI. +It is combined with a design pattern to manipulate UI styles ergonomically using Bevy's ECS, to tangibly demonstrate the feasibility of the approach. + +## Motivation + +UI is the next big challenge for Bevy, with a complex set of data structures that need to be stored and manipulated. +In particular, the ability to style elements (by setting) in a reusable fashion is central to a polished, easy-to UI, but there's no immediately obvious approach to handling them. +What makes a "style" in Bevy? How do we represent the individual style parameters? How are widgets represented? How are styles composed? How are they applied? + +None of these questions are terribly challenging to implement on their own, but taking the first-seen path is particularly dangerous here, due to the risk of proliferation of non-local configuration and similar-but-not-identical style parameters, as seen in CSS. + +We need to settle on a common standard, in order to enable interop between and establish basic building blocks that more complex UI decisions can build off of. + +## Guide-level explanation + +User interfaces in Bevy are made out of **widgets**, which are modified by the **styles** that are applied to them, and the aesthetic and functional behavior of is ultimately implemented through **UI systems**. + +A **widget** is a distinct part of the UI that needs its own data: be that its position, local state or any style parameters. +Widgets in Bevy are represented by entities with a `Widget` marker component. + +Each widget has an associated `Styles` component, which contains a `Vec` which points to some (possibly 0) number of **styles**, represented as entities with a `Style` marker component. + +Each style in that vector is applied, in order, to the widget, overriding the **style parameters** that already exist. +Style parameters are stored as components, and serve to control some element of its presentation, such as the font, background color or text alignment. +Style parameters can be reused across disparate widget types, with functionality achieved through systems that query for the relevant components. +The type of the style parameter components determines which behavior it controls, +while the value returned by `.get()` controls the final behavior of the widget. + +Every style parameter has both a `MyStyle` and a `MyStyle` variant, stored together on each entity. +When creating a new style parameter, you must ensure that it implements `StyleParam`, typically achieved with `#[derive(StyleParam)]`. + +When working on complex games or applications, you're likely to want to group your styles into **themes**, +automatically applying them to large groups of widgets at once. +In Bevy, themes are applied by adding a generic system that corresponds to that theme to your app's schedule. +Select a marker component type `W`, then add a theme system to your app with `W` as a type parameter: +`app.add_startup_system(solarized_theme::