-
-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathtimes-tables.rs
More file actions
80 lines (66 loc) · 2.2 KB
/
times-tables.rs
File metadata and controls
80 lines (66 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//! Do you know your times tables?
use kas::prelude::*;
use kas::view::clerk::{Clerk, GeneratorChanges, IndexedGenerator, Len};
use kas::view::{GridIndex, GridView, SelectionMode, SelectionMsg, driver};
use kas::widgets::{EditBox, ScrollRegion, column, row};
/// A cache of the visible part of our table
#[derive(Debug, Default)]
struct TableCache {
dim: u32,
}
fn product(index: GridIndex) -> u64 {
let x = u64::conv(index.col + 1);
let y = u64::conv(index.row + 1);
x * y
}
impl Clerk<GridIndex> for TableCache {
/// Our table is square; it's size is input.
type Data = u32;
/// Data items are `u64` since e.g. 65536² is not representable by `u32`.
type Item = u64;
fn len(&self, _: &Self::Data, _: GridIndex) -> Len<GridIndex> {
Len::Known(GridIndex::splat(self.dim))
}
}
impl IndexedGenerator<GridIndex> for TableCache {
fn update(&mut self, dim: &Self::Data) -> GeneratorChanges<GridIndex> {
if self.dim == *dim {
GeneratorChanges::None
} else {
self.dim = *dim;
GeneratorChanges::LenOnly
}
}
fn generate(&self, _: &Self::Data, index: GridIndex) -> u64 {
product(index)
}
}
fn main() -> kas::runner::Result<()> {
env_logger::init();
let clerk = TableCache::default();
let table = GridView::new(clerk, driver::View)
.with_num_visible(12, 12)
.with_selection_mode(SelectionMode::Single);
let table = ScrollRegion::new_viewport(table);
#[derive(Debug)]
struct SetLen(u32);
let ui = column![
row!["From 1 to", EditBox::parser(|dim: &u32| *dim, SetLen)],
table.align(AlignHints::RIGHT),
];
let ui = ui
.with_state(12)
.on_message(|_, dim, SetLen(len)| *dim = len)
.on_message(|_, _, selection| match selection {
SelectionMsg::<GridIndex>::Select(index) => {
println!("{} × {} = {}", index.col + 1, index.row + 1, product(index));
}
_ => (),
});
let window = Window::new(ui, "Times-Tables").escapable();
let theme = kas::theme::SimpleTheme::new();
kas::runner::Runner::with_theme(theme)
.build(())?
.with(window)
.run()
}