mirror of https://github.com/linebender/xilem
add checkbox to widget example (#568)
This PR adds another widget to the widgets example, and also draws boxes around each widget to separate them visually. I wanted to use flex wrap to display them, but I don't think that's implemented yet in Xilem, and the layout I did use isn't bad. It also provides a simple example of the use of `Adapt` --------- Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This commit is contained in:
parent
c563029372
commit
c1da921af5
|
@ -7,50 +7,95 @@ use masonry::dpi::LogicalSize;
|
|||
use masonry::event_loop_runner::{EventLoop, EventLoopBuilder};
|
||||
use winit::error::EventLoopError;
|
||||
use winit::window::Window;
|
||||
use xilem::view::{button, checkbox, flex, label, progress_bar, FlexSpacer};
|
||||
use xilem::{WidgetView, Xilem};
|
||||
use xilem::core::adapt;
|
||||
use xilem::view::{button, checkbox, flex, flex_item, progress_bar, sized_box, Axis, FlexSpacer};
|
||||
use xilem::{Color, WidgetView, Xilem};
|
||||
|
||||
const SPACER_WIDTH: f64 = 10.;
|
||||
|
||||
/// The state of the entire application.
|
||||
///
|
||||
/// This is owned by Xilem, used to construct the view tree, and updated by event handlers.
|
||||
struct WidgetGallery {
|
||||
progress: Option<f64>,
|
||||
checked: bool,
|
||||
}
|
||||
|
||||
fn app_logic(data: &mut WidgetGallery) -> impl WidgetView<WidgetGallery> {
|
||||
fn progress_bar_view(data: Option<f64>) -> impl WidgetView<Option<f64>> {
|
||||
flex((
|
||||
label("this 'widgets' example currently only has 1 widget"),
|
||||
FlexSpacer::Flex(1.),
|
||||
progress_bar(data.progress),
|
||||
progress_bar(data),
|
||||
checkbox(
|
||||
"set indeterminate progress",
|
||||
data.progress.is_none(),
|
||||
|state: &mut WidgetGallery, checked| {
|
||||
data.is_none(),
|
||||
|state: &mut Option<f64>, checked| {
|
||||
if checked {
|
||||
state.progress = None;
|
||||
*state = None;
|
||||
} else {
|
||||
state.progress = Some(0.5);
|
||||
*state = Some(0.5);
|
||||
}
|
||||
},
|
||||
),
|
||||
button("change progress", |state: &mut WidgetGallery| {
|
||||
match state.progress {
|
||||
Some(ref mut v) => *v = (*v + 0.1).rem_euclid(1.),
|
||||
None => state.progress = Some(0.5),
|
||||
}
|
||||
button("change progress", |state: &mut Option<f64>| match state {
|
||||
Some(ref mut v) => *v = (*v + 0.1).rem_euclid(1.),
|
||||
None => *state = Some(0.5),
|
||||
}),
|
||||
FlexSpacer::Flex(1.),
|
||||
))
|
||||
}
|
||||
|
||||
fn checkbox_view(data: bool) -> impl WidgetView<bool> {
|
||||
checkbox("a simple checkbox", data, |data, new_state| {
|
||||
*data = new_state;
|
||||
})
|
||||
}
|
||||
|
||||
/// Wrap `inner` in a box with a border
|
||||
fn border_box<State: 'static, Action: 'static>(
|
||||
inner: impl WidgetView<State, Action>,
|
||||
) -> impl WidgetView<State, Action> {
|
||||
sized_box(
|
||||
flex((
|
||||
FlexSpacer::Flex(1.),
|
||||
flex((FlexSpacer::Flex(1.), inner, FlexSpacer::Flex(1.))),
|
||||
FlexSpacer::Flex(1.),
|
||||
))
|
||||
.direction(Axis::Horizontal),
|
||||
)
|
||||
.border(Color::WHITE, 2.)
|
||||
.width(450.)
|
||||
.height(200.)
|
||||
}
|
||||
|
||||
/// Top-level view
|
||||
fn app_logic(data: &mut WidgetGallery) -> impl WidgetView<WidgetGallery> {
|
||||
// Use a `sized_box` to pad the window contents
|
||||
sized_box(
|
||||
flex((
|
||||
adapt(
|
||||
flex_item(border_box(progress_bar_view(data.progress)), 1.),
|
||||
|data: &mut WidgetGallery, thunk| thunk.call(&mut data.progress),
|
||||
),
|
||||
adapt(
|
||||
flex_item(border_box(checkbox_view(data.checked)), 1.),
|
||||
|data: &mut WidgetGallery, thunk| thunk.call(&mut data.checked),
|
||||
),
|
||||
))
|
||||
.gap(SPACER_WIDTH)
|
||||
.direction(Axis::Horizontal),
|
||||
)
|
||||
.border(Color::TRANSPARENT, SPACER_WIDTH)
|
||||
}
|
||||
|
||||
fn run(event_loop: EventLoopBuilder) -> Result<(), EventLoopError> {
|
||||
// Set up the initial state of the app
|
||||
let data = WidgetGallery {
|
||||
progress: Some(0.5),
|
||||
checked: false,
|
||||
};
|
||||
|
||||
// Instantiate and run the UI using the passed event loop.
|
||||
let app = Xilem::new(data, app_logic);
|
||||
let min_window_size = LogicalSize::new(300., 200.);
|
||||
let window_size = LogicalSize::new(450., 300.);
|
||||
let window_size = LogicalSize::new(650., 500.);
|
||||
let window_attributes = Window::default_attributes()
|
||||
.with_title("Xilem Widgets")
|
||||
.with_resizable(true)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//! Views for the widgets which are built-in to Masonry. These are the primitives your Xilem app's view tree will generally be constructed from.
|
||||
|
||||
mod task;
|
||||
pub use task::*;
|
||||
|
||||
|
|
Loading…
Reference in New Issue