Expand description
§Reactive Data-Driven UI
Feather is a reactive data-driven UI framework that only mutates application state in response to user inputs or events, using event streams and reactive properties, and represents application state using persistent data structures, which then efficiently render only the parts of the UI that changed using either a standard GPU compositor or custom shaders.
Examples can be found in feather-ui/examples, and can be run
via cargo run --example <example_name>
.
Re-exports§
pub use guillotiere::euclid;
pub use cosmic_text;
pub use eyre;
pub use im;
pub use notify;
pub use wgpu;
pub use wide;
pub use winit;
pub use mlua;
Modules§
Macros§
- children
- This macro automates away some boilerplate necessary to make a vector of children that can be passed into a component. The first argument is the required layout of the parent, followed by a list of children to include (by value).
- gen_
from_ to_ dyn - gen_id
- While the ID scope provides a .next() method to generate a new, unique ID, this macro allows you to generate a unique ID with the file name and line embedded in it. This helps when debugging, because it’ll tell you exactly what line of code generated the element causing the problem.
- handlers
Structs§
- Access
Cell AccessCell
allows feather to track when a value passed into a function has actually been changed, by tracking if a mutable borrow has been requested. Likestd::cell::RefCell
, it implementsstd::borrow::Borrow
andstd::borrow::BorrowMut
, but also implements thestd::ops::Deref
andstd::ops::DerefMut
operators so it can be used more like a smart pointer.- App
- Represents a feather application with a given
AppData
and persistent outline functionO
. The outline function must always be a persistent function that takes two parameters, a copy of the AppData, and a ScopeID. It must always return [OutlineReturn
]. - AppData
Machine - Cross
Reference Domain - DAbs
Point - A point with both pixel and display independent units, but no relative component. Must be
constructed manually or from a
PxPoint
orAbsPoint
. This is commonly used in DPI sensitive values that could theoretically have pixels, or logical units, or both, but where a relative value doesn’t make any sense (such as the intrinsic size of a shape). - DAbs
Rect - A rectangle with both pixel and display independent units, but no relative component.
- DLimits
- DPoint
- Unified Display Point with both per-pixel and display-independent pixels. Unlike a Rect, must
be constructed manually or from a
PxPoint
,AbsPoint
orRelPoint
. - DRect
- Unified Display Rectangle with both per-pixel and display-independent pixels. Can be
constructed by adding together any combination of
PxRect
,AbsRect
orRelRect
. - DValue
- Limits
- The Limits type represents both a minimum size and a maximum size for a given unit. Adding limits together actually merges them, by taking the largest minimum size and the smallest maximum size of either. You aren’t expected to construct this type manually, however - the Limits constructor takes a range parameter to make it easier to represent the minimum and maximum range of sizes you want.
- Logical
- Represents display-independent pixels, or logical units
- Perimeter
- A perimeter has the same top/left/right/bottom elements as a rectangle, but when used in calculations, the bottom and right elements are subtracted, not added.
- Pixel
- Represents an actual pixel
- Rect
- Represents a 2D Rectangle, similar to the Euclid rectangle, but SSE optimized and uses a LTRB absolute representation, instead of a position and a size.
- Relative
- Represents relative values
- Resolved
- Represents a combination of DIP and Pixels that have been resolved for the current DPI
- ScopeID
- Represents a scope with a particular ID assigned to it. Used to generate new IDs for anything created
inside this scope, with this scope’s ID as parents, or to generate a new
ScopeID
with this scope as its parent. IncludesScopeID::iter
andScopeID::cond
to make it easier to generate stable IDs across control flow boundaries. It can be used in conjunction withgen_id
to generate child IDs with source and line numbers. - Scope
IterID - Slot
- SourceID
- Represents a unique ID out of a linked list of
DataID
. Taken together, all the IDs in a program form a tree that doesn’t just ensure uniqueness, but also allows tracking the structure of the data being used and how each piece of data depends on another piece of data. As a result, the tree structure of IDs generally diverges from the component tree of the actual UI, and may or may not actually resemble the storage structure of the data. - State
Manager StateManager
is used to manage the mutable state associated with a particular component’s ID. Because components technically only exist while a layout tree is being calculated, this is where a component is expected to store all it’s durable state that must survive through the next layout pass. The StateManager also requires that all components implementStateMachineChild
, even if they are stateless. A derive macro is provided for this case. Likewise, the internal state object must implementevent::EventRouter
, even if it doesn’t process any events, in which case it can simply set Input and Output tostd::convert::Infallible
- UPoint
- Partially resolved unified coordinate
- URect
- Partially resolved unified coordinate rectangle
- UValue
Enums§
- DataID
- Represents different kinds of IDs that can be used to populate a
SourceID
. Provides both static strings and owned strings, plus a way to create your own ID using a dynamic hash object. - Error
- Input
Result - This replaces
Result
and allows event handlers to consume an event withInputResult::Consume
(preventing any further processing), forward an event withInputResult::Forward
(allow other components to process the event), or return an error. - RowDirection
- Represents a particular layout direction, which is used in several layout operations. Note
that this is also used for a Grid’s layout directions, but
RowDirection::TopToBottom
doesn’t make sense for a grid and instead means a combination ofRowDirection::RightToLeft
andRowDirection::BottomToTop
. While this is confusing, Rust does not allow us to create two variants with the same discriminator, so we can’t make aRowDirection::RightToLeftAndBottomToTop
option without duplicating the entire enum for Grid. Tracking issue.
Constants§
- APP_
SOURCE_ ID - This is the root ID for the application itself, representing the user’s AppState. All IDs are derived
from this root ID, and this is the only ID that is allowed to have a parent of
None
- AUTO_
DRECT - AUTO_
URECT - BASE_
DPI - The standard base DPI, by convention, is 96, which corresponds to a scale factor of 1.0 - all other DPI values are divided by this to get the appropriate scale factor.
- DEFAULT_
ABSLIMITS - Represents the default absolute value limit with a minimum size of
f32::NEG_INFINITY
and a maximum size off32::INFINITY
- DEFAULT_
DLIMITS - DEFAULT_
LIMITS - Represents the default limit values for any limit type. This simply represents a minimum size
of
f32::NEG_INFINITY
and a maximum size off32::INFINITY
- DEFAULT_
RLIMITS - Represents the default relative value limit with a minimum size of
f32::NEG_INFINITY
and a maximum size off32::INFINITY
- FILL_
DRECT - FILL_
URECT - UNSIZED_
AXIS - Represents an axis that is “unsized”, which is roughly equivelent to CSS
auto
. It will set the size of the axis either to the size of the children, if the layout has any, or to the intrinsic size of the element, if one exists. Otherwise it will evaluate to 0. - ZERO_
DABSRECT - ZERO_
DPOINT - ZERO_
DRECT - ZERO_
RECT - ZERO_
UPOINT - ZERO_
URECT
Traits§
- Dispatchable
- DynHash
Eq - Object-safe version of Hash + PartialEq
- State
Machine Child - Represents any potentially stateful component. All components must implement this trait
because all components are tracked by the state manager even if they are stateless. A
derive macro
feather_macro::StateMachineChild
is provided to make it easier for stateless components to correctly implement StateMachineChild and correctly propagate events to their children. It is important that this is done correctly, as a component can be stateless itself, but have stateful children. - Wrap
Event Ex - This trait is used to wrap rust lambdas into
AppEvent<AppData>
objects that can be boxed for use inApp::new
. These lambdas must always take the form of|evt: AnEventEnum, state: AccessCell<AppData>| -> InputResult<()> {}
After implorting this extension trait, you will be able to callWrapEventEx::wrap
on a qualifying lambda.
Functions§
Type Aliases§
- AbsDim
- A 2D dimension (or size) in logical units (display-independent pixels)
- AbsLimits
- AbsPoint
- A 2D point in logical units (display-independent pixels)
- AbsRect
- A 2D rectangle in logical units (display-independent pixels)
- AbsVector
- A 2D vector in logical units (display-independent pixels)
- AppEvent
- Represents a wrapped lambda that can act as an top-level event handler using the AppState.
- Dispatch
Pair - Used internally for event routing.
- Event
Pair - PxDim
- A 2D dimension (or size) in physical device pixels
- PxLimits
- PxPerimeter
- PxPoint
- A 2D point in physical device pixels
- PxRect
- A 2D rectangle in physical pixels
- PxVector
- A 2D vector in physical device pixels
- RelDim
- A 2D dimension (or size) in relative coordinates
- RelLimits
- RelPoint
- A 2D point in relative coordinates
- RelRect
- A 2D rectangle in relative values
- RelVector
- A 2D vector in relative coordinates
- ResDim
- A 2D dimension (or size) in resolved physical pixels that hasn’t yet been combined with it’s paired relative coordinates.
- ResLimits
- ResPoint
- A 2D point in resolved physical pixels that hasn’t yet been combined with it’s paired relative coordinates.
- ResRect
- A 2D rectangle in resolved pixels that haven’t been merged with their paired relative component
- ResVector
- A 2D vector in resolved physical pixels that hasn’t yet been combined with it’s paired relative coordinates.