diff --git a/src/main.rs b/src/main.rs index 8e2f0cc..58526be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -346,13 +346,18 @@ fn draw_title(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 grid_area = if side_open { + if side_open { let side_w = 32u16; let chunks = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Min(40), Constraint::Length(side_w)]) .split(area); + f.render_widget( + GridWidget::new(&app.model, &app.mode, &app.search_query), + chunks[0], + ); + let side = chunks[1]; let panel_count = [ app.formula_panel_open, @@ -361,36 +366,39 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) { ] .iter() .filter(|&&b| b) - .count(); - - let constraints: Vec = 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(); + .count() as u16; + let ph = side.height / panel_count.max(1); + let mut y = side.y; if app.formula_panel_open { - f.render_widget(FormulaPanel::new(&app.model, &app.mode, app.formula_cursor), slots.next().unwrap()); + let a = Rect::new(side.x, y, side.width, ph); + f.render_widget( + FormulaPanel::new(&app.model, &app.mode, app.formula_cursor), + a, + ); + y += ph; } if app.category_panel_open { - f.render_widget(CategoryPanel::new(&app.model, &app.mode, app.cat_panel_cursor), slots.next().unwrap()); + let a = Rect::new(side.x, y, side.width, ph); + f.render_widget( + CategoryPanel::new(&app.model, &app.mode, app.cat_panel_cursor), + a, + ); + y += ph; } if app.view_panel_open { - f.render_widget(ViewPanel::new(&app.model, &app.mode, app.view_panel_cursor), slots.next().unwrap()); + let a = Rect::new(side.x, y, side.width, ph); + f.render_widget( + ViewPanel::new(&app.model, &app.mode, app.view_panel_cursor), + a, + ); } - - chunks[0] } else { - area - }; - - f.render_widget( - GridWidget::new(&app.model, &app.mode, &app.search_query), - grid_area, - ); + f.render_widget( + GridWidget::new(&app.model, &app.mode, &app.search_query), + area, + ); + } } fn draw_tile_bar(f: &mut Frame, area: Rect, app: &App) { @@ -482,37 +490,6 @@ 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 Import a JSON file", LineKind::Command), - (":add-cat Add a category (dimension)", LineKind::Command), - (":add-item Add an item to a category", LineKind::Command), - (":formula Add a formula, e.g.:", LineKind::Command), - (" Profit = Revenue - Cost", LineKind::Example), - (":w 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) { let w = 58u16.min(area.width.saturating_sub(4)); let h = 20u16.min(area.height.saturating_sub(2)); @@ -529,20 +506,83 @@ fn draw_welcome(f: &mut Frame, area: Rect, _app: &App) { let inner = block.inner(popup); f.render_widget(block, popup); - for (i, (text, kind)) in WELCOME_LINES.iter().enumerate() { + let lines: &[(&str, Style)] = &[ + ( + "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 Import a JSON file", + Style::default().fg(Color::Cyan), + ), + ( + ":add-cat Add a category (dimension)", + Style::default().fg(Color::Cyan), + ), + ( + ":add-item Add an item to a category", + Style::default().fg(Color::Cyan), + ), + ( + ":formula Add a formula, e.g.:", + Style::default().fg(Color::Cyan), + ), + ( + " Profit = Revenue - Cost", + Style::default().fg(Color::Green), + ), + ( + ":w 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 { 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( - Paragraph::new(*text).style(style), - Rect::new(inner.x + 1, inner.y + i as u16, inner.width.saturating_sub(2), 1), + Paragraph::new(*text).style(*style), + Rect::new( + inner.x + 1, + inner.y + i as u16, + inner.width.saturating_sub(2), + 1, + ), ); } }