ViewSwitcher

Struct ViewSwitcher 

Source
pub struct ViewSwitcher<T, U> { /* private fields */ }
Expand description

A widget that switches dynamically between multiple children.

Implementations§

Source§

impl<T: Data, U: Data> ViewSwitcher<T, U>

Source

pub fn new( child_picker: impl Fn(&T, &Env) -> U + 'static, child_builder: impl Fn(&U, &T, &Env) -> Box<dyn Widget<T>> + 'static, ) -> Self

Create a new view switcher.

The child_picker closure is called every time the application data changes. If the value it returns is the same as the one it returned during the previous data change, nothing happens. If it returns a different value, then the child_builder closure is called with the new value.

The child_builder closure creates a new child widget based on the value passed to it.

§Examples
use druid::{
    widget::{Label, ViewSwitcher},
    Data, Widget,
};

#[derive(Clone, PartialEq, Data)]
enum Foo {
    A,
    B,
    C,
}

fn ui() -> impl Widget<Foo> {
    ViewSwitcher::new(
        |data: &Foo, _env| data.clone(),
        |selector, _data, _env| match selector {
            Foo::A => Box::new(Label::new("A")),
            _ => Box::new(Label::new("Not A")),
        },
    )
}
Examples found in repository?
examples/slider.rs (lines 75-89)
55fn build_root_widget() -> impl Widget<AppState> {
56    let range = Flex::row()
57        .with_child(Label::dynamic(|value: &(f64, f64), _| {
58            format!("Value Range: {value:?}")
59        }))
60        .with_default_spacer()
61        .with_child(
62            RangeSlider::new()
63                .with_range(0.0, 20.0)
64                .with_step(1.0)
65                .track_color(KeyOrValue::Concrete(Color::RED))
66                .fix_width(250.0),
67        )
68        .lens(AppState::range);
69
70    let value = Flex::row()
71        .with_child(Label::dynamic(|value: &AppState, _| {
72            format!("Value: {:?}", value.value)
73        }))
74        .with_default_spacer()
75        .with_child(ViewSwitcher::new(
76            |data: &AppState, _| data.range,
77            |range, _, _| {
78                Slider::new()
79                    .with_range(range.0, range.1)
80                    .track_color(KeyOrValue::Concrete(Color::RED))
81                    .knob_style(KnobStyle::Wedge)
82                    .axis(Axis::Vertical)
83                    .with_step(0.25)
84                    .annotated(1.0, 0.25)
85                    .fix_height(250.0)
86                    .lens(AppState::value)
87                    .boxed()
88            },
89        ));
90
91    // arrange the two widgets vertically, with some padding
92    Flex::column()
93        .with_child(range)
94        .with_spacer(VERTICAL_WIDGET_SPACING)
95        .with_child(value)
96        .cross_axis_alignment(CrossAxisAlignment::End)
97        .align_vertical(UnitPoint::RIGHT)
98        .padding(20.0)
99}
More examples
Hide additional examples
examples/tabs.rs (lines 159-162)
102fn build_root_widget() -> impl Widget<AppState> {
103    fn group<T: Data, W: Widget<T> + 'static>(text: &str, w: W) -> impl Widget<T> {
104        Flex::column()
105            .cross_axis_alignment(CrossAxisAlignment::Start)
106            .with_child(
107                Label::new(text)
108                    .background(theme::PLACEHOLDER_COLOR)
109                    .expand_width(),
110            )
111            .with_default_spacer()
112            .with_child(w)
113            .with_default_spacer()
114            .border(Color::WHITE, 0.5)
115    }
116
117    let axis_picker = group(
118        "Tab bar axis",
119        RadioGroup::column(vec![
120            ("Horizontal", Axis::Horizontal),
121            ("Vertical", Axis::Vertical),
122        ])
123        .lens(TabConfig::axis),
124    );
125
126    let cross_picker = group(
127        "Tab bar edge",
128        RadioGroup::column(vec![
129            ("Leading", TabsEdge::Leading),
130            ("Trailing", TabsEdge::Trailing),
131        ])
132        .lens(TabConfig::edge),
133    );
134
135    let transit_picker = group(
136        "Transition",
137        RadioGroup::column(vec![
138            ("Instant", TabsTransition::Instant),
139            (
140                "Slide",
141                TabsTransition::Slide(Duration::from_millis(250).as_nanos() as u64),
142            ),
143        ])
144        .lens(TabConfig::transition),
145    );
146
147    let sidebar = Flex::column()
148        .main_axis_alignment(MainAxisAlignment::Start)
149        .cross_axis_alignment(CrossAxisAlignment::Start)
150        .with_child(axis_picker)
151        .with_default_spacer()
152        .with_child(cross_picker)
153        .with_default_spacer()
154        .with_child(transit_picker)
155        .with_flex_spacer(1.)
156        .fix_width(200.0)
157        .lens(AppState::tab_config);
158
159    let vs = ViewSwitcher::new(
160        |app_s: &AppState, _| app_s.tab_config.clone(),
161        |tc: &TabConfig, _, _| Box::new(build_tab_widget(tc)),
162    );
163    Flex::row().with_child(sidebar).with_flex_child(vs, 1.0)
164}
examples/view_switcher.rs (lines 58-97)
41fn make_ui() -> impl Widget<AppState> {
42    let mut switcher_column = Flex::column();
43    switcher_column.add_child(
44        Label::new(|data: &u32, _env: &Env| format!("Current view: {data}"))
45            .lens(AppState::current_view),
46    );
47    for i in 0..6 {
48        switcher_column.add_spacer(80.);
49        switcher_column.add_child(
50            Button::new(format!("View {i}"))
51                .on_click(move |_event, data: &mut u32, _env| {
52                    *data = i;
53                })
54                .lens(AppState::current_view),
55        );
56    }
57
58    let view_switcher = ViewSwitcher::new(
59        |data: &AppState, _env| data.current_view,
60        |selector, _data, _env| match selector {
61            0 => Box::new(Label::new("Simple Label").center()),
62            1 => Box::new(
63                Button::new("Simple Button").on_click(|_event, _data, _env| {
64                    println!("Simple button clicked!");
65                }),
66            ),
67            2 => Box::new(
68                Button::new("Another Simple Button").on_click(|_event, _data, _env| {
69                    println!("Another simple button clicked!");
70                }),
71            ),
72            3 => Box::new(
73                Flex::column()
74                    .with_flex_child(Label::new("Here is a label").center(), 1.0)
75                    .with_flex_child(
76                        Button::new("Button").on_click(|_event, _data, _env| {
77                            println!("Complex button clicked!");
78                        }),
79                        1.0,
80                    )
81                    .with_flex_child(TextBox::new().lens(AppState::current_text), 1.0)
82                    .with_flex_child(
83                        Label::new(|data: &String, _env: &Env| format!("Value entered: {data}"))
84                            .lens(AppState::current_text),
85                        1.0,
86                    ),
87            ),
88            4 => Box::new(
89                Split::columns(
90                    Label::new("Left split").center(),
91                    Label::new("Right split").center(),
92                )
93                .draggable(true),
94            ),
95            _ => Box::new(Label::new("Unknown").center()),
96        },
97    );
98
99    Flex::row()
100        .with_child(switcher_column)
101        .with_flex_child(view_switcher, 1.0)
102}

Trait Implementations§

Source§

impl<T: Data, U: Data> Widget<T> for ViewSwitcher<T, U>

Source§

fn event( &mut self, ctx: &mut EventCtx<'_, '_>, event: &Event, data: &mut T, env: &Env, )

Handle an event. Read more
Source§

fn lifecycle( &mut self, ctx: &mut LifeCycleCtx<'_, '_>, event: &LifeCycle, data: &T, env: &Env, )

Handle a life cycle notification. Read more
Source§

fn update( &mut self, ctx: &mut UpdateCtx<'_, '_>, _old_data: &T, data: &T, env: &Env, )

Update the widget’s appearance in response to a change in the app’s Data or Env. Read more
Source§

fn layout( &mut self, ctx: &mut LayoutCtx<'_, '_>, bc: &BoxConstraints, data: &T, env: &Env, ) -> Size

Compute layout. Read more
Source§

fn paint(&mut self, ctx: &mut PaintCtx<'_, '_, '_>, data: &T, env: &Env)

Paint the widget appearance. Read more
Source§

fn compute_max_intrinsic( &mut self, axis: Axis, ctx: &mut LayoutCtx<'_, '_>, bc: &BoxConstraints, data: &T, env: &Env, ) -> f64

Computes max intrinsic/preferred dimension of a widget on the provided axis. Read more

Auto Trait Implementations§

§

impl<T, U> !Freeze for ViewSwitcher<T, U>

§

impl<T, U> !RefUnwindSafe for ViewSwitcher<T, U>

§

impl<T, U> !Send for ViewSwitcher<T, U>

§

impl<T, U> !Sync for ViewSwitcher<T, U>

§

impl<T, U> Unpin for ViewSwitcher<T, U>
where U: Unpin, T: Unpin,

§

impl<T, U> !UnwindSafe for ViewSwitcher<T, U>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> RoundFrom<T> for T

Source§

fn round_from(x: T) -> T

Performs the conversion.
Source§

impl<T, U> RoundInto<U> for T
where U: RoundFrom<T>,

Source§

fn round_into(self) -> U

Performs the conversion.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, W> TestWidgetExt<T> for W
where T: Data, W: Widget<T> + 'static,

Source§

fn record(self, recording: &Recording) -> Recorder<Self>

Available on non-WebAssembly only.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T, W> WidgetExt<T> for W
where T: Data, W: Widget<T> + 'static,

Source§

fn padding(self, insets: impl Into<KeyOrValue<Insets>>) -> Padding<T, Self>

Wrap this widget in a Padding widget with the given Insets. Read more
Source§

fn center(self) -> Align<T>

Wrap this widget in an Align widget, configured to center it.
Source§

fn align_left(self) -> Align<T>

Wrap this widget in an Align widget, configured to align left.
Source§

fn align_right(self) -> Align<T>

Wrap this widget in an Align widget, configured to align right.
Source§

fn align_vertical(self, align: UnitPoint) -> Align<T>

Wrap this widget in an Align widget, configured to align vertically.
Source§

fn align_horizontal(self, align: UnitPoint) -> Align<T>

Wrap this widget in an Align widget, configured to align horizontally.
Source§

fn fix_width(self, width: impl Into<KeyOrValue<f64>>) -> SizedBox<T>

Wrap this widget in a SizedBox with an explicit width.
Source§

fn fix_height(self, height: impl Into<KeyOrValue<f64>>) -> SizedBox<T>

Wrap this widget in a SizedBox with an explicit height.
Source§

fn fix_size( self, width: impl Into<KeyOrValue<f64>>, height: impl Into<KeyOrValue<f64>>, ) -> SizedBox<T>

Wrap this widget in an SizedBox with an explicit width and height
Source§

fn expand(self) -> SizedBox<T>

Wrap this widget in a SizedBox with an infinite width and height. Read more
Source§

fn expand_width(self) -> SizedBox<T>

Wrap this widget in a SizedBox with an infinite width. Read more
Source§

fn expand_height(self) -> SizedBox<T>

Wrap this widget in a SizedBox with an infinite width. Read more
Source§

fn background(self, brush: impl Into<BackgroundBrush<T>>) -> Container<T>

Wrap this widget in a Container with the provided background brush. Read more
Source§

fn foreground(self, brush: impl Into<BackgroundBrush<T>>) -> Container<T>

Wrap this widget in a Container with the provided foreground brush. Read more
Source§

fn border( self, color: impl Into<KeyOrValue<Color>>, width: impl Into<KeyOrValue<f64>>, ) -> Container<T>

Wrap this widget in a Container with the given border. Read more
Source§

fn env_scope(self, f: impl Fn(&mut Env, &T) + 'static) -> EnvScope<T, Self>

Wrap this widget in a EnvScope widget, modifying the parent Env with the provided closure.
Source§

fn controller<C: Controller<T, Self>>( self, controller: C, ) -> ControllerHost<Self, C>

Wrap this widget with the provided Controller.
Source§

fn on_added( self, f: impl Fn(&mut Self, &mut LifeCycleCtx<'_, '_>, &T, &Env) + 'static, ) -> ControllerHost<Self, Added<T, Self>>

Provide a closure that will be called when this widget is added to the widget tree. Read more
Source§

fn on_click( self, f: impl Fn(&mut EventCtx<'_, '_>, &mut T, &Env) + 'static, ) -> ControllerHost<Self, Click<T>>

Control the events of this widget with a Click widget. The closure provided will be called when the widget is clicked with the left mouse button. Read more
Source§

fn debug_paint_layout(self) -> EnvScope<T, Self>

Draw the layout Rects of this widget and its children.
Source§

fn debug_widget_id(self) -> EnvScope<T, Self>

Display the WidgetIds for this widget and its children, when hot. Read more
Source§

fn debug_invalidation(self) -> DebugInvalidation<T, Self>

Draw a color-changing rectangle over this widget, allowing you to see the invalidation regions.
Source§

fn debug_widget(self) -> EnvScope<T, Self>

Set the DEBUG_WIDGET env variable for this widget (and its descendants). Read more
Source§

fn lens<S: Data, L: Lens<S, T>>(self, lens: L) -> LensWrap<S, T, L, Self>

Wrap this widget in a LensWrap widget for the provided Lens.
Source§

fn with_id(self, id: WidgetId) -> IdentityWrapper<Self>

Assign the widget a specific WidgetId. Read more
Source§

fn boxed(self) -> Box<dyn Widget<T>>

Wrap this widget in a Box.
Source§

fn scroll(self) -> Scroll<T, Self>

Wrap this widget in a Scroll widget.
Source§

fn disabled_if( self, disabled_if: impl Fn(&T, &Env) -> bool + 'static, ) -> DisabledIf<T, Self>

Wrap this widget in a DisabledIf widget. Read more
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more