pub trait UiNode: Any + Send {
Show 22 methods
// Required methods
fn init(&mut self);
fn deinit(&mut self);
fn info(&mut self, info: &mut WidgetInfoBuilder);
fn event(&mut self, update: &EventUpdate);
fn update(&mut self, updates: &WidgetUpdates);
fn measure(&mut self, wm: &mut WidgetMeasure) -> Size2D<Px, Px>;
fn layout(&mut self, wl: &mut WidgetLayout) -> Size2D<Px, Px>;
fn render(&mut self, frame: &mut FrameBuilder);
fn render_update(&mut self, update: &mut FrameUpdate);
// Provided methods
fn boxed(self) -> Box<dyn UiNodeBoxed>
where Self: Sized { ... }
fn cfg_boxed(self) -> Box<dyn UiNodeBoxed>
where Self: Sized { ... }
fn is_widget(&self) -> bool { ... }
fn is_nil(&self) -> bool { ... }
fn with_context<R, F>(
&mut self,
update_mode: WidgetUpdateMode,
f: F,
) -> Option<R>
where F: FnOnce() -> R { ... }
fn into_widget(self) -> Box<dyn UiNodeBoxed>
where Self: Sized { ... }
fn init_widget(
self,
) -> (Box<dyn UiNodeBoxed>, ReadOnlyVar<Response<WidgetId>, ArcVar<Response<WidgetId>>>)
where Self: Sized { ... }
fn downcast_unbox<T>(self) -> Result<T, Box<dyn UiNodeBoxed>>
where T: UiNode,
Self: Sized { ... }
fn actual_type_id(&self) -> TypeId { ... }
fn as_any(&self) -> &(dyn Any + 'static)
where Self: Sized { ... }
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
where Self: Sized { ... }
fn trace<E, S>(self, enter_mtd: E) -> Box<dyn UiNodeBoxed>
where Self: Sized,
E: FnMut(UiNodeOpMethod) -> S + Send + 'static { ... }
fn op(&mut self, op: UiNodeOp<'_>) { ... }
}
Expand description
Represents an UI tree node.
You can use the match_node
helper to quickly declare a new node from a closure, most property nodes are implemented
using the match helpers. For more advanced nodes you can use the ui_node
proc-macro attribute.
Required Methods§
sourcefn init(&mut self)
fn init(&mut self)
Initializes the node in a new UI context.
Common init operations are subscribing to variables and events and initializing data.
You can use WIDGET
to subscribe events and vars, the subscriptions live until the widget is deinited.
If the node is a custom widget (is_widget
) it must request an info, layout and render updates, other nodes
do not need to request any sort of update on init.
Note that this method can be called again, after a deinit
.
sourcefn deinit(&mut self)
fn deinit(&mut self)
Deinitializes the node in the current UI context.
Common deinit operations include dropping allocations and handlers.
If the node is a custom widget (is_widget
) it must request an info, layout and render updates, other nodes
do not need to request any sort of update on deinit.
Note that init
can be called again after this.
sourcefn info(&mut self, info: &mut WidgetInfoBuilder)
fn info(&mut self, info: &mut WidgetInfoBuilder)
Builds widget info.
This method is called every time there are structural changes in the UI tree such as a node added or removed, you
can also request an info rebuild using WIDGET.update_info
.
Only nodes in widgets that requested info rebuild and nodes in their ancestors receive this call. Other
widgets reuse their info in the new info tree. The widget’s latest built info is available in WIDGET.info
.
Note that info rebuild has higher priority over event, update, layout and render, this means that if you set a variable and request info update the next info rebuild will still observe the old variable value, you can work around this issue by only requesting info rebuild after the variable updates.
sourcefn event(&mut self, update: &EventUpdate)
fn event(&mut self, update: &EventUpdate)
Receives an event.
Every call to this method is for a single update of a single event type, you can listen to events
by subscribing to then on init and using the Event::on
method in this method to detect the event.
Note that events sent to descendant nodes also flow through this method and must be delegated. If you observe an event for a descendant before delegating to the descendant this is a preview handling, in the normal handling you delegate first, then check the event propagation.
sourcefn update(&mut self, updates: &WidgetUpdates)
fn update(&mut self, updates: &WidgetUpdates)
Receives variable and other non-event updates.
Calls to this method aggregate all updates that happen in the last pass, multiple variables can be new at the same time.
You can listen to variable updates by subscribing to then on init and using the Var::get_new
method in this method to
receive the new values.
A custom update can be requested using the context WIDGET.update
. Common update operations include reacting to variable
changes that generate an intermediary value for layout or render, the update implementation uses WIDGET
to request layout
and render after updating the data. Note that for simple variables that are used directly on layout or render you can subscribe
to that operation directly, skipping update.
sourcefn measure(&mut self, wm: &mut WidgetMeasure) -> Size2D<Px, Px>
fn measure(&mut self, wm: &mut WidgetMeasure) -> Size2D<Px, Px>
Computes the widget size given the contextual layout metrics without actually updating the widget layout.
Implementers must return the same size layout
returns for the given LayoutMetrics
, without
affecting the actual widget render. Panel widgets that implement some complex layouts need to get an
what the widget would be given some constraints, this value is used to inform the actual layout
call.
Nodes that implement layout
must also implement this method, the LAYOUT
context can be used to retrieve the metrics,
the WidgetMeasure
parameter can be used to communicate with the parent layout, such as disabling inline layout, the
returned PxSize
is the desired size given the parent constraints.
sourcefn layout(&mut self, wl: &mut WidgetLayout) -> Size2D<Px, Px>
fn layout(&mut self, wl: &mut WidgetLayout) -> Size2D<Px, Px>
Computes the widget layout given the contextual layout metrics.
Implementers must also implement measure
. This method is called by the parent layout once the final constraints
for the frame are defined, the LAYOUT
context can be used to retrieve the constraints, the WidgetLayout
parameter
can be used to communicate layout metadata such as inline segments to the parent layout, the returned PxSize
is the
final size given the constraints.
Only widgets and ancestors that requested layout or use metrics that changed since last layout receive this call. Other widgets reuse the last layout result.
Nodes that render can also implement this operation just to observe the latest widget size, if changes are detected
the WIDGET.render
method can be used to request render.
sourcefn render(&mut self, frame: &mut FrameBuilder)
fn render(&mut self, frame: &mut FrameBuilder)
Generates render instructions and updates transforms and hit-test areas.
This method does not generate pixels immediately, it generates display items that are visual building block instructions for the renderer that will run after the window display list is built.
Only widgets and ancestors that requested render receive this call, other widgets reuse the display items and transforms from the last frame.
sourcefn render_update(&mut self, update: &mut FrameUpdate)
fn render_update(&mut self, update: &mut FrameUpdate)
Updates values in the last generated frame.
Some display item values and transforms can be updated directly, without needing to rebuild the display list. All FrameBuilder
methods that accept a FrameValue<T>
input can be bound to an ID that can be used to update that value.
Only widgets and ancestors that requested render update receive this call. Note that if any other widget in the same window requests render all pending render update requests are upgraded to render requests.
Provided Methods§
sourcefn boxed(self) -> Box<dyn UiNodeBoxed>where
Self: Sized,
fn boxed(self) -> Box<dyn UiNodeBoxed>where
Self: Sized,
Box this node or just returns self
if it is already a BoxedUiNode
.
sourcefn cfg_boxed(self) -> Box<dyn UiNodeBoxed>where
Self: Sized,
fn cfg_boxed(self) -> Box<dyn UiNodeBoxed>where
Self: Sized,
Helper for complying with the "dyn_node"
feature, boxes the node or just returns it depending of the
compile time feature.
sourcefn is_widget(&self) -> bool
fn is_widget(&self) -> bool
Gets if this node represents a full widget, that is, it is the outer-most widget node and defines a widget context.
If this is true
the with_context
method can be used to get the widget context.
sourcefn is_nil(&self) -> bool
fn is_nil(&self) -> bool
Gets if this node does nothing and is layout collapsed.
Implementers must return true
only if the node will always do nothing, nodes that may change
and stop being collapsed are not nil.
sourcefn with_context<R, F>(
&mut self,
update_mode: WidgetUpdateMode,
f: F,
) -> Option<R>where
F: FnOnce() -> R,
fn with_context<R, F>(
&mut self,
update_mode: WidgetUpdateMode,
f: F,
) -> Option<R>where
F: FnOnce() -> R,
Calls f
with the WIDGET
context of the node if it is_widget
.
Returns None
if the node does not represent a widget.
If update_mode
is WidgetUpdateMode::Bubble
the update flags requested for the widget in f
will be copied to the
caller widget context, otherwise they are ignored.
sourcefn into_widget(self) -> Box<dyn UiNodeBoxed>where
Self: Sized,
fn into_widget(self) -> Box<dyn UiNodeBoxed>where
Self: Sized,
Gets a BoxedUiNode
that is a full widget.
If this node is_widget
returns self
boxed. Otherwise returns a new minimal widget
that has self
as a child node.
Use this if you know that the widget is not a full widget or you don’t mind that some
nodes become full widgets only after init, otherwise use init_widget
.
sourcefn init_widget(
self,
) -> (Box<dyn UiNodeBoxed>, ReadOnlyVar<Response<WidgetId>, ArcVar<Response<WidgetId>>>)where
Self: Sized,
fn init_widget(
self,
) -> (Box<dyn UiNodeBoxed>, ReadOnlyVar<Response<WidgetId>, ArcVar<Response<WidgetId>>>)where
Self: Sized,
Gets a BoxedUiNode
that already is a full widget or will be after init and a response var that
already is the widget ID or will update once after init with the ID.
If this node is_widget
returns self
boxed and an already responded var. Otherwise returns
a node that will ensure self
is a full widget after init and update the response var with the
widget ID.
Some nodes become full widgets only after init, the ArcNode::take_on_init
for example, this node
supports these cases at the expense of having to reinit inside the generated widget when self
is
not a full widget even after init.
sourcefn downcast_unbox<T>(self) -> Result<T, Box<dyn UiNodeBoxed>>
fn downcast_unbox<T>(self) -> Result<T, Box<dyn UiNodeBoxed>>
Downcast to T
, if self
is T
or self
is a BoxedUiNode
that is T
.
sourcefn actual_type_id(&self) -> TypeId
fn actual_type_id(&self) -> TypeId
Returns the type_id
of the unboxed node.
sourcefn as_any_mut(&mut self) -> &mut (dyn Any + 'static)where
Self: Sized,
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)where
Self: Sized,
Access to mut dyn Any
methods.
sourcefn trace<E, S>(self, enter_mtd: E) -> Box<dyn UiNodeBoxed>
fn trace<E, S>(self, enter_mtd: E) -> Box<dyn UiNodeBoxed>
Wraps the node in a node that, before delegating each method, calls a closure with
the UiNodeOpMethod
, the closure can return a span that is dropped after the method delegation.
You can use the tracing
crate to create the span.