pub trait View {
// Required method
fn id(&self) -> ViewId;
// Provided methods
fn view_style(&self) -> Option<Style> { ... }
fn view_class(&self) -> Option<StyleClassRef> { ... }
fn debug_name(&self) -> Cow<'static, str> { ... }
fn update(&mut self, cx: &mut UpdateCx<'_>, state: Box<dyn Any>) { ... }
fn style_pass(&mut self, cx: &mut StyleCx<'_>) { ... }
fn layout(&mut self, cx: &mut LayoutCx<'_>) -> NodeId { ... }
fn compute_layout(&mut self, cx: &mut ComputeLayoutCx<'_>) -> Option<Rect> { ... }
fn event_before_children(
&mut self,
cx: &mut EventCx<'_>,
event: &Event,
) -> EventPropagation { ... }
fn event_after_children(
&mut self,
cx: &mut EventCx<'_>,
event: &Event,
) -> EventPropagation { ... }
fn paint(&mut self, cx: &mut PaintCx<'_>) { ... }
fn scroll_to(
&mut self,
cx: &mut AppState,
target: ViewId,
rect: Option<Rect>,
) -> bool { ... }
}
Expand description
The View trait contains the methods for implementing updates, styling, layout, events, and painting.
The id method must be implemented. The other methods may be implemented as necessary to implement the functionality of the View.
§State Management in a Custom View
For all reactive state that your type contains, either in the form of signals or derived signals, you need to process the changes within an effect.
The most common pattern is to get the data in an effect and pass it in to id.update_state()
and then handle that data in the update
method of the View trait.
For example a minimal slider might look like the following. First, we define the struct that contains the ViewId.
Then, we use a function to construct the slider. As part of this function we create an effect that will be re-run every time the signals in the percent
closure change.
In the effect we send the change to the associated ViewId. This change can then be handled in the View::update method.
struct Slider {
id: ViewId,
percent: f32,
}
pub fn slider(percent: impl Fn() -> f32 + 'static) -> Slider {
let id = ViewId::new();
// If the following effect is not created, and `percent` is accessed directly,
// `percent` will only be accessed a single time and will not be reactive.
// Therefore the following `create_effect` is necessary for reactivity.
create_effect(move |_| {
let percent = percent();
id.update_state(percent);
});
Slider { id, percent: 0.0 }
}
impl View for Slider {
fn id(&self) -> ViewId {
self.id
}
fn update(&mut self, cx: &mut floem::context::UpdateCx, state: Box<dyn std::any::Any>) {
if let Ok(percent) = state.downcast::<f32>() {
self.percent = *percent;
self.id.request_layout();
}
}
}
Required Methods§
Provided Methods§
fn view_style(&self) -> Option<Style>
fn view_class(&self) -> Option<StyleClassRef>
fn debug_name(&self) -> Cow<'static, str>
Sourcefn update(&mut self, cx: &mut UpdateCx<'_>, state: Box<dyn Any>)
fn update(&mut self, cx: &mut UpdateCx<'_>, state: Box<dyn Any>)
Use this method to react to changes in view-related state.
You will usually send state to this hook manually using the View
’s Id
handle
self.id.update_state(SomeState)
You are in charge of downcasting the state to the expected type.
If the update needs other passes to run you’re expected to call
_cx.app_state_mut().request_changes
.
Sourcefn style_pass(&mut self, cx: &mut StyleCx<'_>)
fn style_pass(&mut self, cx: &mut StyleCx<'_>)
Use this method to style the view’s children.
If the style changes needs other passes to run you’re expected to call
cx.app_state_mut().request_changes
.
Sourcefn layout(&mut self, cx: &mut LayoutCx<'_>) -> NodeId
fn layout(&mut self, cx: &mut LayoutCx<'_>) -> NodeId
Use this method to layout the view’s children.
Usually you’ll do this by calling LayoutCx::layout_node
.
If the layout changes needs other passes to run you’re expected to call
cx.app_state_mut().request_changes
.
Sourcefn compute_layout(&mut self, cx: &mut ComputeLayoutCx<'_>) -> Option<Rect>
fn compute_layout(&mut self, cx: &mut ComputeLayoutCx<'_>) -> Option<Rect>
Responsible for computing the layout of the view’s children.
If the layout changes needs other passes to run you’re expected to call
cx.app_state_mut().request_changes
.
fn event_before_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation
fn event_after_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation
Sourcefn paint(&mut self, cx: &mut PaintCx<'_>)
fn paint(&mut self, cx: &mut PaintCx<'_>)
View
-specific implementation. Will be called in PaintCx::paint_view
.
Usually you’ll call paint_view
for every child view. But you might also draw text, adjust the offset, clip
or draw text.
Trait Implementations§
Source§impl View for Box<dyn View>
impl View for Box<dyn View>
fn id(&self) -> ViewId
fn view_style(&self) -> Option<Style>
fn view_class(&self) -> Option<StyleClassRef>
fn debug_name(&self) -> Cow<'static, str>
Source§fn update(&mut self, cx: &mut UpdateCx<'_>, state: Box<dyn Any>)
fn update(&mut self, cx: &mut UpdateCx<'_>, state: Box<dyn Any>)
View
’s Id
handle Read moreSource§fn style_pass(&mut self, cx: &mut StyleCx<'_>)
fn style_pass(&mut self, cx: &mut StyleCx<'_>)
Source§fn layout(&mut self, cx: &mut LayoutCx<'_>) -> NodeId
fn layout(&mut self, cx: &mut LayoutCx<'_>) -> NodeId
LayoutCx::layout_node
. Read morefn event_before_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation
fn event_after_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation
Source§fn compute_layout(&mut self, cx: &mut ComputeLayoutCx<'_>) -> Option<Rect>
fn compute_layout(&mut self, cx: &mut ComputeLayoutCx<'_>) -> Option<Rect>
Source§fn paint(&mut self, cx: &mut PaintCx<'_>)
fn paint(&mut self, cx: &mut PaintCx<'_>)
View
-specific implementation. Will be called in PaintCx::paint_view
.
Usually you’ll call paint_view
for every child view. But you might also draw text, adjust the offset, clip
or draw text.