mirror of
https://github.com/danbulant/cushy
synced 2026-05-19 12:19:02 +00:00
The overlay example now supports right-clicking to open overlays at the clicked location, showing how a context menu widget can begin being built.
102 lines
3.2 KiB
Rust
102 lines
3.2 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use cushy::value::{Dynamic, MapEach, Source};
|
|
use cushy::widget::{MakeWidget, WidgetList};
|
|
use cushy::widgets::input::InputValue;
|
|
use cushy::Run;
|
|
|
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
pub struct Contact {
|
|
pub id: u64,
|
|
pub first_name: String,
|
|
pub last_name: String,
|
|
pub title: String,
|
|
}
|
|
|
|
fn main() -> cushy::Result {
|
|
let initial_contacts = vec![
|
|
Contact {
|
|
id: 0,
|
|
first_name: String::from("John"),
|
|
last_name: String::from("Doe"),
|
|
title: String::from("Chef"),
|
|
},
|
|
Contact {
|
|
id: 1,
|
|
first_name: String::from("Jane"),
|
|
last_name: String::from("Smith"),
|
|
title: String::from("Doctor"),
|
|
},
|
|
];
|
|
let db = Dynamic::new(
|
|
initial_contacts
|
|
.into_iter()
|
|
.map(|contact| (contact.id, contact))
|
|
.collect::<HashMap<_, _>>(),
|
|
);
|
|
let selected_contact = Dynamic::new(None::<u64>);
|
|
let contact_list = db.map_each({
|
|
let selected_contact = selected_contact.clone();
|
|
move |contacts| {
|
|
let mut entries = contacts
|
|
.iter()
|
|
.map(|(id, contact)| (contact.last_name.clone(), contact.first_name.clone(), *id))
|
|
.collect::<Vec<_>>();
|
|
entries.sort();
|
|
entries
|
|
.into_iter()
|
|
.map(|(last, first, id)| {
|
|
selected_contact
|
|
.new_select(Some(id), format!("{first} {last}").align_left())
|
|
.make_widget()
|
|
})
|
|
.collect::<WidgetList>()
|
|
}
|
|
});
|
|
|
|
let editing_contact = (&selected_contact, &db).map_each({
|
|
let db = db.clone();
|
|
move |(selected, contacts)| {
|
|
selected
|
|
.map(|id| edit_contact_form(&contacts[&id], &db).make_widget())
|
|
.unwrap_or_else(|| "Select a contact".centered().make_widget())
|
|
}
|
|
});
|
|
contact_list
|
|
.into_rows()
|
|
.vertical_scroll()
|
|
.and(editing_contact.expand())
|
|
.into_columns()
|
|
.run()
|
|
}
|
|
|
|
fn edit_contact_form(contact: &Contact, db: &Dynamic<HashMap<u64, Contact>>) -> impl MakeWidget {
|
|
let first = Dynamic::new(contact.first_name.clone());
|
|
let last = Dynamic::new(contact.last_name.clone());
|
|
let title = Dynamic::new(contact.title.clone());
|
|
|
|
"First Name"
|
|
.and(first.to_input())
|
|
.and("Last Name")
|
|
.and(last.to_input())
|
|
.and("Title")
|
|
.and(title.to_input())
|
|
.and(
|
|
"Save"
|
|
.into_button()
|
|
.on_click({
|
|
let contact_id = contact.id;
|
|
let db = db.clone();
|
|
move |_| {
|
|
let mut db = db.lock();
|
|
let contact = db.get_mut(&contact_id).expect("missing contact");
|
|
contact.first_name = first.get();
|
|
contact.last_name = last.get();
|
|
contact.title = title.get();
|
|
}
|
|
})
|
|
.into_default()
|
|
.align_right(),
|
|
)
|
|
.into_rows()
|
|
}
|