use std::cell::RefCell;
use std::rc::Rc;
use saudade::{
App, Button, Checkbox, Column, Container, Dialog, Event, EventCtx, Label, List, ListItem,
Painter, PopupRequest, Rect, TextInput, Theme, Widget, WindowConfig,
};
const WINDOW_W: i32 = 280;
const WINDOW_H: i32 = 296;
fn main() {
let items = vec![
ListItem::new("Anchovy"),
ListItem::new("Basil"),
ListItem::new("Capers"),
ListItem::new("Dill"),
ListItem::new("Endive"),
ListItem::new("Fennel"),
ListItem::new("Garlic"),
];
let mut list = List::new(Rect::new(16, 32, 248, 130)).with_items(items);
list.set_selected(Some(0));
let list = Rc::new(RefCell::new(list));
let name = Rc::new(RefCell::new(
TextInput::new(Rect::new(72, 168, 192, 22)).with_text("Anonymous"),
));
let favorite = Rc::new(RefCell::new(Checkbox::new(
Rect::new(16, 200, 200, 16),
"Add to favorites",
)));
let dialog = Rc::new(RefCell::new(Dialog::new().on_dismiss(|cx| cx.close())));
let ok = Button::new(Rect::new(96, 236, 80, 24), "OK")
.default(true)
.on_click({
let list = list.clone();
let favorite = favorite.clone();
let name = name.clone();
let dialog = dialog.clone();
move |cx| {
let label = {
let l = list.borrow();
l.selected_index()
.and_then(|i| l.items().get(i).map(|x| x.label.clone()))
};
let starred = favorite.borrow().is_checked();
let who = name.borrow().text();
let who = if who.trim().is_empty() {
"Anonymous".to_string()
} else {
who
};
let body = match label {
Some(item) if starred => {
format!("{} picked:\n\n{}\n\nSaved to favorites.", who, item)
}
Some(item) => format!("{} picked:\n\n{}", who, item),
None => format!("{} picked nothing.", who),
};
dialog.borrow_mut().show_info("Confirmed", body);
cx.request_paint();
}
});
let cancel = Button::new(Rect::new(184, 236, 80, 24), "Cancel").on_click({
let dialog = dialog.clone();
move |cx| {
dialog
.borrow_mut()
.show_info("Cancelled", "No selection was saved.");
cx.request_paint();
}
});
let content = Container::new(WINDOW_W, WINDOW_H)
.add(Label::new(
Rect::new(16, 12, WINDOW_W - 32, 16),
"Pick an ingredient (Tab to cycle):",
))
.add(SharedList(list.clone()))
.add(Label::new(Rect::new(16, 172, 60, 16), "Name:"))
.add(SharedTextInput(name.clone()))
.add(SharedCheckbox(favorite.clone()))
.add(ok)
.add(cancel);
let root = Column::new()
.add_fill(content)
.add_overlay(SharedDialog(dialog.clone()));
App::new(WindowConfig::new("Picker", WINDOW_W, WINDOW_H), root)
.with_theme(Theme::windows_31())
.run();
}
struct SharedList(Rc<RefCell<List>>);
impl Widget for SharedList {
fn bounds(&self) -> Rect {
self.0.borrow().bounds()
}
fn paint(&mut self, painter: &mut Painter, theme: &Theme) {
self.0.borrow_mut().paint(painter, theme);
}
fn event(&mut self, event: &Event, ctx: &mut EventCtx) {
self.0.borrow_mut().event(event, ctx);
}
fn captures_pointer(&self) -> bool {
self.0.borrow().captures_pointer()
}
fn focusable(&self) -> bool {
self.0.borrow().focusable()
}
fn set_focused(&mut self, focused: bool) {
self.0.borrow_mut().set_focused(focused);
}
fn layout(&mut self, bounds: Rect) {
self.0.borrow_mut().layout(bounds);
}
}
struct SharedTextInput(Rc<RefCell<TextInput>>);
impl Widget for SharedTextInput {
fn bounds(&self) -> Rect {
self.0.borrow().bounds()
}
fn paint(&mut self, painter: &mut Painter, theme: &Theme) {
self.0.borrow_mut().paint(painter, theme);
}
fn event(&mut self, event: &Event, ctx: &mut EventCtx) {
self.0.borrow_mut().event(event, ctx);
}
fn captures_pointer(&self) -> bool {
self.0.borrow().captures_pointer()
}
fn focusable(&self) -> bool {
self.0.borrow().focusable()
}
fn set_focused(&mut self, focused: bool) {
self.0.borrow_mut().set_focused(focused);
}
fn layout(&mut self, bounds: Rect) {
self.0.borrow_mut().layout(bounds);
}
fn wants_ticks(&self) -> bool {
self.0.borrow().wants_ticks()
}
}
struct SharedCheckbox(Rc<RefCell<Checkbox>>);
impl Widget for SharedCheckbox {
fn bounds(&self) -> Rect {
self.0.borrow().bounds()
}
fn paint(&mut self, painter: &mut Painter, theme: &Theme) {
self.0.borrow_mut().paint(painter, theme);
}
fn event(&mut self, event: &Event, ctx: &mut EventCtx) {
self.0.borrow_mut().event(event, ctx);
}
fn captures_pointer(&self) -> bool {
self.0.borrow().captures_pointer()
}
fn focusable(&self) -> bool {
self.0.borrow().focusable()
}
fn set_focused(&mut self, focused: bool) {
self.0.borrow_mut().set_focused(focused);
}
fn layout(&mut self, bounds: Rect) {
self.0.borrow_mut().layout(bounds);
}
}
struct SharedDialog(Rc<RefCell<Dialog>>);
impl Widget for SharedDialog {
fn bounds(&self) -> Rect {
self.0.borrow().bounds()
}
fn paint(&mut self, painter: &mut Painter, theme: &Theme) {
self.0.borrow_mut().paint(painter, theme);
}
fn paint_overlay(&mut self, painter: &mut Painter, theme: &Theme) {
self.0.borrow_mut().paint_overlay(painter, theme);
}
fn event(&mut self, event: &Event, ctx: &mut EventCtx) {
self.0.borrow_mut().event(event, ctx);
}
fn captures_pointer(&self) -> bool {
self.0.borrow().captures_pointer()
}
fn accepts_accelerators(&self) -> bool {
self.0.borrow().accepts_accelerators()
}
fn layout(&mut self, bounds: Rect) {
self.0.borrow_mut().layout(bounds);
}
fn popup_request(&self) -> Option<PopupRequest> {
self.0.borrow().popup_request()
}
}