1use fltk::{
4 app, draw, enums, input,
5 prelude::{GroupExt, InputExt, TableExt, WidgetBase, WidgetExt, WidgetProps},
6 table, window,
7};
8use std::cell::RefCell;
9use std::rc::Rc;
10
11pub type MyData = Vec<Vec<String>>;
12
13#[derive(Default)]
15struct CellData {
16 row: i32, col: i32, x: i32,
19 y: i32,
20 w: i32,
21 h: i32,
22}
23
24impl CellData {
25 pub fn select(&mut self, row: i32, col: i32, x: i32, y: i32, w: i32, h: i32) {
26 self.row = row;
27 self.col = col;
28 self.x = x;
29 self.y = y;
30 self.w = w;
31 self.h = h;
32 }
33}
34
35pub struct MyTable {
36 table: table::Table,
37 data: Rc<RefCell<MyData>>,
38 cell: Rc<RefCell<CellData>>,
39}
40
41impl MyTable {
42 pub fn new(mut inp: input::Input) -> Self {
43 let mut table = table::Table::default()
44 .with_size(800 - 10, 600 - 10)
45 .center_of_parent();
46 let data = Rc::from(RefCell::from(vec![vec![String::from(""); 26]; 28]));
47 let cell = Rc::from(RefCell::from(CellData::default()));
48
49 table.set_rows(28);
50 table.set_row_header(true);
51 table.set_row_resize(true);
52 table.set_cols(26);
53 table.set_col_header(true);
54 table.set_col_width_all(80);
55 table.set_col_resize(true);
56 table.end();
57
58 let cell_c = cell.clone();
59 let data_c = data.clone();
60
61 table.draw_cell(move |t, ctx, row, col, x, y, w, h| match ctx {
63 table::TableContext::StartPage => draw::set_font(enums::Font::Helvetica, 14),
64 table::TableContext::ColHeader => {
65 Self::draw_header(&format!("{}", (col + 65) as u8 as char), x, y, w, h)
66 } table::TableContext::RowHeader => {
68 Self::draw_header(&format!("{}", row + 1), x, y, w, h)
69 } table::TableContext::Cell => {
71 if t.is_selected(row, col) {
72 cell_c.borrow_mut().select(row, col, x, y, w, h); }
74 Self::draw_data(
75 &data_c.borrow()[row as usize][col as usize].to_string(),
76 x,
77 y,
78 w,
79 h,
80 t.is_selected(row, col),
81 );
82 }
83 _ => (),
84 });
85
86 let cell_c = cell.clone();
87 let data_c = data.clone();
88
89 table.handle(move |_, ev| match ev {
90 enums::Event::Released => {
94 let c = cell_c.borrow();
95 inp.resize(c.x, c.y, c.w, c.h);
96 inp.set_value(&data_c.borrow_mut()[c.row as usize][c.col as usize]);
97 inp.show();
98 inp.take_focus().ok();
99 inp.redraw();
100 true
101 }
102 _ => false,
103 });
104
105 Self { table, data, cell }
106 }
107
108 pub fn redraw(&mut self) {
109 self.table.redraw()
110 }
111
112 fn draw_header(txt: &str, x: i32, y: i32, w: i32, h: i32) {
113 draw::push_clip(x, y, w, h);
114 draw::draw_box(
115 enums::FrameType::ThinUpBox,
116 x,
117 y,
118 w,
119 h,
120 enums::Color::FrameDefault,
121 );
122 draw::set_draw_color(enums::Color::Black);
123 draw::set_font(enums::Font::Helvetica, 14);
124 draw::draw_text_boxed(txt, x, y, w, h, enums::Align::Center);
125 draw::pop_clip();
126 }
127
128 fn draw_data(txt: &str, x: i32, y: i32, w: i32, h: i32, selected: bool) {
130 draw::push_clip(x, y, w, h);
131 if selected {
132 draw::set_draw_color(enums::Color::from_u32(0x00D3_D3D3));
133 } else {
134 draw::set_draw_color(enums::Color::White);
135 }
136 draw::draw_rectf(x, y, w, h);
137 draw::set_draw_color(enums::Color::Gray0);
138 draw::set_font(enums::Font::Helvetica, 14);
139 draw::draw_text_boxed(txt, x, y, w, h, enums::Align::Center);
140 draw::draw_rect(x, y, w, h);
141 draw::pop_clip();
142 }
143}
144
145fn main() {
146 let app = app::App::default().with_scheme(app::Scheme::Gtk);
147 let mut wind = window::Window::default().with_size(800, 600);
148 let mut inp = input::Input::default();
150 inp.hide();
151
152 let mut table = MyTable::new(inp.clone());
153
154 wind.make_resizable(true);
155 wind.end();
156 wind.show();
157
158 wind.handle(move |_, ev| match ev {
159 enums::Event::KeyDown => {
160 if app::event_key() == enums::Key::Enter {
161 let c = table.cell.borrow();
163 table.data.borrow_mut()[c.row as usize][c.col as usize] = inp.value();
164 inp.set_value("");
165 inp.hide();
166 return true;
167 }
168 table.redraw();
169 false
170 }
171 _ => false,
172 });
173
174 wind.set_callback(|_| {
175 if app::event() == enums::Event::Close {
176 app::quit();
178 }
179 });
180
181 app.run().unwrap();
182}