refactor: mystery model #2

This commit is contained in:
Edward Langley
2026-04-01 00:40:22 -07:00
parent a57d3ed294
commit 87fd6a1620

View File

@ -346,18 +346,13 @@ fn draw_title(f: &mut Frame, area: Rect, app: &App) {
fn draw_content(f: &mut Frame, area: Rect, app: &App) { fn draw_content(f: &mut Frame, area: Rect, app: &App) {
let side_open = app.formula_panel_open || app.category_panel_open || app.view_panel_open; let side_open = app.formula_panel_open || app.category_panel_open || app.view_panel_open;
if side_open { let grid_area = if side_open {
let side_w = 32u16; let side_w = 32u16;
let chunks = Layout::default() let chunks = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.constraints([Constraint::Min(40), Constraint::Length(side_w)]) .constraints([Constraint::Min(40), Constraint::Length(side_w)])
.split(area); .split(area);
f.render_widget(
GridWidget::new(&app.model, &app.mode, &app.search_query),
chunks[0],
);
let side = chunks[1]; let side = chunks[1];
let panel_count = [ let panel_count = [
app.formula_panel_open, app.formula_panel_open,
@ -366,40 +361,37 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) {
] ]
.iter() .iter()
.filter(|&&b| b) .filter(|&&b| b)
.count() as u16; .count();
let ph = side.height / panel_count.max(1);
let mut y = side.y; let constraints: Vec<Constraint> = std::iter::repeat(Constraint::Fill(1))
.take(panel_count)
.collect();
let panel_areas = Layout::default()
.direction(Direction::Vertical)
.constraints(constraints)
.split(side);
let mut slots = panel_areas.iter().copied();
if app.formula_panel_open { if app.formula_panel_open {
let a = Rect::new(side.x, y, side.width, ph); f.render_widget(FormulaPanel::new(&app.model, &app.mode, app.formula_cursor), slots.next().unwrap());
f.render_widget(
FormulaPanel::new(&app.model, &app.mode, app.formula_cursor),
a,
);
y += ph;
} }
if app.category_panel_open { if app.category_panel_open {
let a = Rect::new(side.x, y, side.width, ph); f.render_widget(CategoryPanel::new(&app.model, &app.mode, app.cat_panel_cursor), slots.next().unwrap());
f.render_widget(
CategoryPanel::new(&app.model, &app.mode, app.cat_panel_cursor),
a,
);
y += ph;
} }
if app.view_panel_open { if app.view_panel_open {
let a = Rect::new(side.x, y, side.width, ph); f.render_widget(ViewPanel::new(&app.model, &app.mode, app.view_panel_cursor), slots.next().unwrap());
f.render_widget(
ViewPanel::new(&app.model, &app.mode, app.view_panel_cursor),
a,
);
} }
chunks[0]
} else { } else {
area
};
f.render_widget( f.render_widget(
GridWidget::new(&app.model, &app.mode, &app.search_query), GridWidget::new(&app.model, &app.mode, &app.search_query),
area, grid_area,
); );
} }
}
fn draw_tile_bar(f: &mut Frame, area: Rect, app: &App) { fn draw_tile_bar(f: &mut Frame, area: Rect, app: &App) {
f.render_widget(TileBar::new(&app.model, &app.mode), area); f.render_widget(TileBar::new(&app.model, &app.mode), area);
@ -490,6 +482,37 @@ fn draw_export_prompt(f: &mut Frame, area: Rect, app: &App) {
); );
} }
#[derive(Copy, Clone)]
enum LineKind {
Intro,
Header,
Command,
Example,
Plain,
}
const WELCOME_LINES: &[(&str, LineKind)] = &[
("Multi-dimensional data modeling — in your terminal.", LineKind::Intro),
("", LineKind::Plain),
("Getting started", LineKind::Header),
("", LineKind::Plain),
(":import <file.json> Import a JSON file", LineKind::Command),
(":add-cat <name> Add a category (dimension)", LineKind::Command),
(":add-item <cat> <name> Add an item to a category", LineKind::Command),
(":formula <cat> <expr> Add a formula, e.g.:", LineKind::Command),
(" Profit = Revenue - Cost", LineKind::Example),
(":w <file.improv> Save your model", LineKind::Command),
("", LineKind::Plain),
("Navigation", LineKind::Header),
("", LineKind::Plain),
("F C V Open panels (Formulas/Categories/Views)", LineKind::Plain),
("T Tile-select: pivot rows ↔ cols ↔ page", LineKind::Plain),
("i Enter Edit a cell", LineKind::Plain),
("[ ] Cycle the page-axis filter", LineKind::Plain),
("? or :help Full key reference", LineKind::Plain),
(":q Quit", LineKind::Plain),
];
fn draw_welcome(f: &mut Frame, area: Rect, _app: &App) { fn draw_welcome(f: &mut Frame, area: Rect, _app: &App) {
let w = 58u16.min(area.width.saturating_sub(4)); let w = 58u16.min(area.width.saturating_sub(4));
let h = 20u16.min(area.height.saturating_sub(2)); let h = 20u16.min(area.height.saturating_sub(2));
@ -506,83 +529,20 @@ fn draw_welcome(f: &mut Frame, area: Rect, _app: &App) {
let inner = block.inner(popup); let inner = block.inner(popup);
f.render_widget(block, popup); f.render_widget(block, popup);
let lines: &[(&str, Style)] = &[ for (i, (text, kind)) in WELCOME_LINES.iter().enumerate() {
(
"Multi-dimensional data modeling — in your terminal.",
Style::default().fg(Color::White),
),
("", Style::default()),
(
"Getting started",
Style::default()
.fg(Color::Blue)
.add_modifier(Modifier::BOLD),
),
("", Style::default()),
(
":import <file.json> Import a JSON file",
Style::default().fg(Color::Cyan),
),
(
":add-cat <name> Add a category (dimension)",
Style::default().fg(Color::Cyan),
),
(
":add-item <cat> <name> Add an item to a category",
Style::default().fg(Color::Cyan),
),
(
":formula <cat> <expr> Add a formula, e.g.:",
Style::default().fg(Color::Cyan),
),
(
" Profit = Revenue - Cost",
Style::default().fg(Color::Green),
),
(
":w <file.improv> Save your model",
Style::default().fg(Color::Cyan),
),
("", Style::default()),
(
"Navigation",
Style::default()
.fg(Color::Blue)
.add_modifier(Modifier::BOLD),
),
("", Style::default()),
(
"F C V Open panels (Formulas/Categories/Views)",
Style::default(),
),
(
"T Tile-select: pivot rows ↔ cols ↔ page",
Style::default(),
),
("i Enter Edit a cell", Style::default()),
(
"[ ] Cycle the page-axis filter",
Style::default(),
),
(
"? or :help Full key reference",
Style::default(),
),
(":q Quit", Style::default()),
];
for (i, (text, style)) in lines.iter().enumerate() {
if i >= inner.height as usize { if i >= inner.height as usize {
break; break;
} }
let style = match kind {
LineKind::Intro => Style::default().fg(Color::White),
LineKind::Header => Style::default().fg(Color::Blue).add_modifier(Modifier::BOLD),
LineKind::Command => Style::default().fg(Color::Cyan),
LineKind::Example => Style::default().fg(Color::Green),
LineKind::Plain => Style::default(),
};
f.render_widget( f.render_widget(
Paragraph::new(*text).style(*style), Paragraph::new(*text).style(style),
Rect::new( Rect::new(inner.x + 1, inner.y + i as u16, inner.width.saturating_sub(2), 1),
inner.x + 1,
inner.y + i as u16,
inner.width.saturating_sub(2),
1,
),
); );
} }
} }