use std::sync::Arc;
use druid::lens::{self, LensExt};
use druid::widget::{Button, Flex, Label, List, Scroll, WidgetExt};
use druid::{AppLauncher, Color, Data, Lens, Widget, WindowDesc};
#[derive(Clone, Data, Lens)]
struct AppData {
left: Arc<Vec<u32>>,
right: Arc<Vec<u32>>,
}
fn main() {
let main_window = WindowDesc::new(ui_builder);
let data = AppData {
left: Arc::new(vec![1, 2]),
right: Arc::new(vec![1, 2, 3]),
};
AppLauncher::with_window(main_window)
.use_simple_logger()
.launch(data)
.expect("launch failed");
}
fn ui_builder() -> impl Widget<AppData> {
let mut root = Flex::column();
root.add_child(
Button::new("Add", |_, data: &mut AppData, _| {
let value = data.left.len() + 1;
Arc::make_mut(&mut data.left).push(value as u32);
let value = data.right.len() + 1;
Arc::make_mut(&mut data.right).push(value as u32);
})
.fix_height(30.0),
0.0,
);
let mut lists = Flex::row();
lists.add_child(
Scroll::new(List::new(|| {
Label::new(|item: &u32, _env: &_| format!("List item #{}", item))
.padding(10.0)
.expand()
.height(50.0)
.background(Color::rgb(0.5, 0.5, 0.5))
}))
.vertical()
.lens(AppData::left),
1.0,
);
lists.add_child(
Scroll::new(List::new(|| {
Flex::row()
.with_child(
Label::new(|(_, item): &(Arc<Vec<u32>>, u32), _env: &_| {
format!("List item #{}", item)
}),
1.0,
)
.with_child(
Button::sized(
"Delete",
|_ctx, (shared, item): &mut (Arc<Vec<u32>>, u32), _env| {
Arc::make_mut(shared).retain(|v| v != item);
},
80.0,
20.0,
),
0.0,
)
.padding(10.0)
.background(Color::rgb(0.5, 0.0, 0.5))
.fix_height(50.0)
}))
.vertical()
.lens(lens::Id.map(
|d: &AppData| (d.right.clone(), d.right.clone()),
|d: &mut AppData, x: (Arc<Vec<u32>>, Arc<Vec<u32>>)| {
d.right = x.0
},
)),
1.0,
);
root.add_child(lists, 1.0);
root
}