1use glasskit::Ui;
10use glasskit::events::{Event, EventLoop};
11use glasskit::kanban::{Board, BoardEvent, CardData, CardKey};
12use glasskit::widget::{Button, Column, Insets, Row, Spacer, Text, TextStyle};
13use glasskit::window::{Window, WindowEvent};
14
15const CARDS: [(usize, &str, &str); 5] = [
16 (0, "Write the plan", "One page, with the dates."),
17 (0, "Book the room", ""),
18 (1, "Draft the slides", "Ten slides for the first review."),
19 (2, "Pick a date", ""),
20 (2, "Send the invitations", "To all the people of the team."),
21];
22
23fn main() -> glasskit::Result<()> {
24 let ui = Ui::new()?;
25 let mut events: EventLoop<()> = EventLoop::new(&ui)?;
26 let mut window = Window::new(&ui, "Kanban", 820.0, 520.0)?;
27 window.set_min_size(560.0, 360.0);
28
29 let mut board = Board::new(&mut window, &["To do", "Doing", "Done"]);
30 for (lane, title, body) in CARDS {
31 board.add_card(&mut window, lane, CardData::new(title, body));
32 }
33 let pinned = CardData {
34 pinned: true,
35 ..CardData::new("Ask for the budget", "")
36 };
37 board.add_card(&mut window, 1, pinned);
38
39 let title = window.add(Text::new("Board").style(TextStyle::Title));
40 let gap = window.add(Spacer::fill());
41 let archived = window.add(Button::new("Show archived"));
42 let top = window.add(Row::new().child(title).child(gap).child(archived));
43 let root = window.add(
44 Column::new()
45 .padding(Insets::all(16.0))
46 .gap(12.0)
47 .child(top)
48 .child(board.widget()),
49 );
50 window.set_root(root);
51 window.show();
52
53 loop {
54 match events.next(None)? {
55 Event::Window(id) if id == window.id() => {
56 while let Some(event) = window.next_event() {
57 match event {
58 WindowEvent::CloseRequested => return Ok(()),
59 WindowEvent::Clicked(id) if id == archived => {
60 let show = !board.show_archived();
61 board.set_show_archived(&mut window, show);
62 let label = if show {
63 "Hide archived"
64 } else {
65 "Show archived"
66 };
67 window.set_text(archived, label);
68 }
69 event => {
70 if let Some(change) = board.handle(&ui, &mut window, &event)? {
71 println!("{}", describe(&board, &change));
72 }
73 }
74 }
75 }
76 }
77 Event::Quit => return Ok(()),
78 _ => {}
79 }
80 }
81}
82
83fn describe(board: &Board, change: &BoardEvent) -> String {
84 let title = |key: &CardKey| board.card(*key).map_or("", |card| card.title.as_str());
85 let lane = |key: &CardKey| {
86 let lane = board.place(*key).map_or(0, |(lane, _)| lane);
87 board.lane_name(lane).unwrap_or("")
88 };
89 match change {
90 BoardEvent::Added(key) => format!("added {} to {}", title(key), lane(key)),
91 BoardEvent::Edited(key) => format!("edited {}", title(key)),
92 BoardEvent::Moved(key) => {
93 let at = board.place(*key).map_or(0, |(_, at)| at);
94 format!("moved {} to {} at {at}", title(key), lane(key))
95 }
96 BoardEvent::Cloned { from, .. } => format!("cloned {}", title(from)),
97 BoardEvent::Pinned(key) => format!("pinned {}", title(key)),
98 BoardEvent::Archived(key) => format!("archived {}", title(key)),
99 BoardEvent::Deleted { card, .. } => format!("deleted {}", card.title),
100 _ => String::new(),
101 }
102}