pub struct Cx<'s, 'u> {
pub store: &'s Store,
/* private fields */
}Expand description
The context passed to components and hooks.
's is the lifetime of the Store and of every hook handle taken from
it; it is independent of the &mut Cx borrow, so a hook can return a guard
that outlives the borrow of the Cx it was taken from.
Fields§
§store: &'s StoreThe hook store. Copy, so it can be re-borrowed into nested closures.
Implementations§
Source§impl<'s, 'u> Cx<'s, 'u>
impl<'s, 'u> Cx<'s, 'u>
Sourcepub fn new(store: &'s Store, ui: &'u mut Ui, scope: Id) -> Self
pub fn new(store: &'s Store, ui: &'u mut Ui, scope: Id) -> Self
Build a Cx for ui under the scope id scope.
This is what an egui container closure (ui.vertical(|ui| ..)) uses to
re-enter the tree with the inner Ui. The layout id starts at scope;
an element that re-enters inside a reused list slot puts the slot’s
layout id back with Cx::with_layout_id.
Sourcepub fn ui(&mut self) -> &mut Ui
pub fn ui(&mut self) -> &mut Ui
The egui Ui currently being drawn into.
In taffy mode this is the tree’s own Ui, so anything drawn through it
is not laid out by taffy. Elements use Cx::leaf and
Cx::container instead; this is the escape hatch for user code that
wants to call egui directly, and it is what a docked <Panel> carves
its space out of.
“The tree’s own Ui” is exact: a container is a rect, not a Ui, so
however many <View>s sit between the tree root and the caller, this
is the Ui the tree was started in. That is what makes four sibling
<Panel>s dock along the window’s four edges instead of each carving
up its own little node.
Sourcepub fn in_taffy(&self) -> bool
pub fn in_taffy(&self) -> bool
Whether this Cx is inside a <View>.
True on both layout paths: what an element reads it for is whether its size is the layout’s decision, and that is the same either way.
Is this Cx inside a display="none" subtree?
True inside a hidden <View> on either layout path, and inside anything
a leaf of one opens (a <ScrollArea>’s children, a tree of their own).
Sourcepub fn layout_id(&self) -> Id
pub fn layout_id(&self) -> Id
The id the next taffy tree or node is keyed by.
The same as Cx::scope_id unless a list element replaced it (see
Cx::with_layout_id). <View> passes this to Cx::container.
Sourcepub fn with_layout_id<R>(
&mut self,
id: Id,
f: impl FnOnce(&mut Cx<'s, '_>) -> R,
) -> R
pub fn with_layout_id<R>( &mut self, id: Id, f: impl FnOnce(&mut Cx<'s, '_>) -> R, ) -> R
Run f with id as the layout id, leaving hooks and the egui id stack
alone.
This is an internal for list elements, not something a component body
needs. <VirtualList> uses it to key each row’s taffy tree by the slot
the row occupies rather than by the row’s index: a slot is drawn on
every frame, so its nodes are reused instead of created, measured in an
invisible pass and thrown away when the row scrolls out.
The ids handed to this must be unique among the nodes drawn in one frame; two of them under one taffy tree would collide.
Sourcepub fn with_root_size<R>(
&mut self,
size: Vec2,
f: impl FnOnce(&mut Cx<'s, '_>) -> R,
) -> R
pub fn with_root_size<R>( &mut self, size: Vec2, f: impl FnOnce(&mut Cx<'s, '_>) -> R, ) -> R
Run f with the size the trees it opens are laid out into.
This is an internal for list elements, like Cx::with_layout_id, not
something a component body needs.
A <View> over a plain Ui normally takes the width that is left,
measures its own height and reserves that much room. Neither is what a
<VirtualList> row wants. Inside egui::ScrollArea::show_rows the
space that is left runs from the row to the bottom of the band of
visible rows, so the root rect moves with the scroll offset; and the
room reserved is whatever the row drew, which is not the row_h the
visible range was worked out from, so the rows drift out of step with
it.
With a size given, the tree’s root rect is that size at the cursor, both axes are definite, and exactly that much room is reserved afterwards. So the rows sit at one pitch, and the root size is the same on every frame: a scrolled frame lays a row out again only when something in the row really changed.
The size wins over what the tree measured. A tree that draws taller than
this overlaps whatever comes after it; <VirtualList> says the same
thing about its rows, and it is the same rule.
The hint is not consumed by the first tree: every tree f opens
over a plain Ui gets it, at any depth of components, until a tree is
entered — inside a tree the hint is dropped, so a tree opened by a leaf
of this one is unaffected. Consuming it would mean shared mutable state,
because a Cx is copied into each child scope rather than borrowed, and
it would buy nothing: the caller’s contract is that everything drawn
here is one row of a fixed height, so a second root tree in the same row
is already a mistake either way.
Sourcepub fn scope<R>(
&mut self,
source: impl Hash + Debug,
f: impl FnOnce(&mut Cx<'s, '_>) -> R,
) -> R
pub fn scope<R>( &mut self, source: impl Hash + Debug, f: impl FnOnce(&mut Cx<'s, '_>) -> R, ) -> R
Enter a component scope: deepen the hook scope, the layout id and the egui id.
source needs Debug as well as Hash because egui 0.36’s
Ui::push_id takes impl AsIdSalt, which is Hash + Debug.
Sourcepub fn hook_scope<R>(
&mut self,
location: &'static Location<'static>,
f: impl FnOnce(&mut Cx<'s, '_>) -> R,
) -> R
pub fn hook_scope<R>( &mut self, location: &'static Location<'static>, f: impl FnOnce(&mut Cx<'s, '_>) -> R, ) -> R
Enter a custom hook scope: deepen the hook scope only.
Unlike Cx::scope this does not touch the egui id stack, because a
custom hook is not a widget boundary.
Sourcepub fn scope_sharing_ui<R>(
&mut self,
source: impl Hash + Debug,
f: impl FnOnce(&mut Cx<'s, '_>) -> R,
) -> R
pub fn scope_sharing_ui<R>( &mut self, source: impl Hash + Debug, f: impl FnOnce(&mut Cx<'s, '_>) -> R, ) -> R
Enter a component scope that draws into this Ui.
Same hook scoping as Cx::scope, but without Ui::push_id, so the
component shares the surface with its parent. #[component(shares_ui)]
elements go through here: a docked panel has to carve space out of the
parent’s Ui, and Ui::end_row only reaches the grid it was called on.
Sourcepub fn leaf<R>(&mut self, style: &ItemStyle, f: impl FnOnce(&mut Ui) -> R) -> R
pub fn leaf<R>(&mut self, style: &ItemStyle, f: impl FnOnce(&mut Ui) -> R) -> R
Draw one egui widget, as a taffy leaf when inside a container.
Outside a container style is ignored: a plain Ui has nothing to
apply flex item properties to, and nothing to paint a background on
either — the engine paints a node’s box from the rect the layout gave
it, and here the rect is only known after the widget has drawn. That is
what <Frame> is for.
Sourcepub fn text(
&mut self,
style: &ItemStyle,
text: WidgetText,
wrap: bool,
selectable: Option<bool>,
) -> Response
pub fn text( &mut self, style: &ItemStyle, text: WidgetText, wrap: bool, selectable: Option<bool>, ) -> Response
Draw static text, as a taffy node when inside a container.
Outside a container this is ui.add(egui::Label::new(text)) and
nothing else. Inside one it skips the Label and the Ui it would need:
the galley is laid out by the layout engine, which is where its size is
wanted anyway, and painted straight onto the tree’s own Ui. What the
engine keeps of Label is the widget rect, the WidgetInfo and the
text selection, so the text is still hoverable, still in the
accessibility tree, still found by egui_kittest’s label queries and
still selectable with the mouse.
wrap picks between TextWrapMode::Wrap and TextWrapMode::Extend,
as <Text>’s own prop does. selectable is Label::selectable:
None follows the style’s interaction.selectable_labels. A <Text>
created this frame is not selectable for that one frame, because its
place on screen is only known once the layout is computed.
Sourcepub fn leaf_fill<R>(
&mut self,
style: &ItemStyle,
f: impl FnOnce(&mut Ui) -> R,
) -> R
pub fn leaf_fill<R>( &mut self, style: &ItemStyle, f: impl FnOnce(&mut Ui) -> R, ) -> R
Like Cx::leaf, but the leaf takes whatever space taffy gives it.
A plain leaf is measured by its content: taffy sizes it to what it drew
and never larger. That is wrong for egui widgets that themselves fill
the space they are given (ScrollArea): the widget fills its node, then
reports that as its content size, and the node is pinned at whatever
size the first frame happened to have. This variant reports no content
size at all, so the node is sized purely by taffy: w / h, grow,
or the remaining space in the container.
Sourcepub fn container<R>(
&mut self,
id: Id,
container: &ContainerStyle,
item: &ItemStyle,
f: impl FnOnce(&mut Cx<'s, '_>) -> R,
) -> R
pub fn container<R>( &mut self, id: Id, container: &ContainerStyle, item: &ItemStyle, f: impl FnOnce(&mut Cx<'s, '_>) -> R, ) -> R
Open a container and draw f inside it.
Outside a container this starts a new layout tree in the current Ui;
inside one it adds a child node. Either way f receives a Cx that is
inside a container, so its direct children become layout nodes.
The two styles are passed as they are rather than merged into a
[taffy::Style], because a <VirtualList> row is laid out by the lite
path (crate::engine::lite), which reads them directly and never builds
a taffy style at all. The taffy path merges them itself.
Sourcepub fn root_container<R>(
&mut self,
id: Id,
style: Style,
f: impl FnOnce(&mut Cx<'s, '_>) -> R,
) -> R
pub fn root_container<R>( &mut self, id: Id, style: Style, f: impl FnOnce(&mut Cx<'s, '_>) -> R, ) -> R
Cx::container for the root of an app: reserve all available space.
The runner uses this so that the outermost <View> fills the window;
nested containers only reserve the available width, so that a column of
them stacks instead of each one claiming the whole height.
Takes a [taffy::Style], unlike Cx::container: an app root is never
a <VirtualList> row, so it never takes the lite path, and the runner’s
root_style() is a taffy style users can reach for. A taffy style says
nothing about paint, so the root node paints nothing; a <View> inside
it does.
Sourcepub fn defer(&self, f: impl FnOnce() + 'static)
pub fn defer(&self, f: impl FnOnce() + 'static)
Queue f to run at the end of the pass, after every guard is gone.
The closure is 'static because it outlives the component body, so
captured values need move. It cannot touch the store, so it does not
request a repaint on its own; use
State::update_later for that.
Auto Trait Implementations§
impl<'s, 'u> Freeze for Cx<'s, 'u>
impl<'s, 'u> !RefUnwindSafe for Cx<'s, 'u>
impl<'s, 'u> !Send for Cx<'s, 'u>
impl<'s, 'u> !Sync for Cx<'s, 'u>
impl<'s, 'u> Unpin for Cx<'s, 'u>
impl<'s, 'u> UnsafeUnpin for Cx<'s, 'u>
impl<'s, 'u> !UnwindSafe for Cx<'s, 'u>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more