floem

Trait View

Source
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§

Source

fn id(&self) -> ViewId

Provided Methods§

Source

fn view_style(&self) -> Option<Style>

Source

fn view_class(&self) -> Option<StyleClassRef>

Source

fn debug_name(&self) -> Cow<'static, str>

Source

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.

Source

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.

Source

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.

Source

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.

Source

fn event_before_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation

Source

fn event_after_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation

Source

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.

Source

fn scroll_to( &mut self, cx: &mut AppState, target: ViewId, rect: Option<Rect>, ) -> bool

Scrolls the view and all direct and indirect children to bring the target view to be visible. Returns true if this view contains or is the target.

Trait Implementations§

Source§

impl View for Box<dyn View>

Source§

fn id(&self) -> ViewId

Source§

fn view_style(&self) -> Option<Style>

Source§

fn view_class(&self) -> Option<StyleClassRef>

Source§

fn debug_name(&self) -> Cow<'static, str>

Source§

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 Read more
Source§

fn style_pass(&mut self, cx: &mut StyleCx<'_>)

Use this method to style the view’s children. Read more
Source§

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. Read more
Source§

fn event_before_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation

Source§

fn event_after_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation

Source§

fn compute_layout(&mut self, cx: &mut ComputeLayoutCx<'_>) -> Option<Rect>

Responsible for computing the layout of the view’s children. Read more
Source§

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.
Source§

fn scroll_to( &mut self, cx: &mut AppState, target: ViewId, rect: Option<Rect>, ) -> bool

Scrolls the view and all direct and indirect children to bring the target view to be visible. Returns true if this view contains or is the target.

Implementations on Foreign Types§

Source§

impl View for Box<dyn View>

Source§

fn id(&self) -> ViewId

Source§

fn view_style(&self) -> Option<Style>

Source§

fn view_class(&self) -> Option<StyleClassRef>

Source§

fn debug_name(&self) -> Cow<'static, str>

Source§

fn update(&mut self, cx: &mut UpdateCx<'_>, state: Box<dyn Any>)

Source§

fn style_pass(&mut self, cx: &mut StyleCx<'_>)

Source§

fn layout(&mut self, cx: &mut LayoutCx<'_>) -> NodeId

Source§

fn event_before_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation

Source§

fn event_after_children( &mut self, cx: &mut EventCx<'_>, event: &Event, ) -> EventPropagation

Source§

fn compute_layout(&mut self, cx: &mut ComputeLayoutCx<'_>) -> Option<Rect>

Source§

fn paint(&mut self, cx: &mut PaintCx<'_>)

Source§

fn scroll_to( &mut self, cx: &mut AppState, target: ViewId, rect: Option<Rect>, ) -> bool

Implementors§