From d5a3398cc9fb7846a9a31eee2ab74cba0410f9af Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Thu, 16 Apr 2026 12:44:13 -0400 Subject: [PATCH] learn: move threshold/gen state out of title bar into a settings row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The F6 title line was starting to read like a control panel — \`legend ───── learn [thresh: 1e-7] [gen]\` — which crowded the legend and the label, and didn't leave room for more settings as the screen grew. Move threshold and gen status to their own line inside the border, right above the content area. Drop the duplicated \`=gen[on]\` marker from the bottom help line since the settings row already shows gen state. Co-Authored-By: Proof of Concept --- src/user/learn.rs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/user/learn.rs b/src/user/learn.rs index 522dbb8..c77230e 100644 --- a/src/user/learn.rs +++ b/src/user/learn.rs @@ -146,29 +146,41 @@ impl ScreenView for LearnScreen { // Now render let gen_on = crate::subconscious::learn::alternates_enabled(); let threshold = app.mind_state.as_ref().map(|ms| ms.learn_threshold).unwrap_or(0.0); - let title_right = if gen_on { - format!(" learn [thresh: {:e}] [gen] ", threshold) - } else { - format!(" learn [thresh: {:e}] ", threshold) - }; let block = Block::default() .title_top(Line::from(screen_legend()).left_aligned()) - .title_top(Line::from(title_right).right_aligned()) + .title_top(Line::from(" learn ").right_aligned()) .borders(Borders::ALL) .border_style(Style::default().fg(Color::Magenta)); let inner = block.inner(area); frame.render_widget(block, area); + // Split inner: top line for settings, rest for content. + let [settings_area, content_area] = Layout::vertical([ + Constraint::Length(1), + Constraint::Min(0), + ]).areas(inner); + + let settings = Line::from(vec![ + Span::raw(" thresh: "), + Span::styled(format!("{:e}", threshold), Style::default().fg(Color::Yellow)), + Span::raw(" gen: "), + Span::styled( + if gen_on { "[on]" } else { "[off]" }, + Style::default().fg(if gen_on { Color::Green } else { Color::DarkGray }), + ), + ]); + frame.render_widget(Paragraph::new(settings), settings_area); + let candidates = &app.finetune_candidates; if candidates.is_empty() { - render_empty(frame, inner, app); + render_empty(frame, content_area, app); } else { // Layout: list on left, detail on right let [list_area, detail_area] = Layout::horizontal([ Constraint::Percentage(40), Constraint::Percentage(60), - ]).areas(inner); + ]).areas(content_area); // Render candidate list let items: Vec = candidates.iter().map(|c| { @@ -205,7 +217,6 @@ impl ScreenView for LearnScreen { } // Render help at bottom (always, even when empty) - let gen_status = if gen_on { "[on]" } else { "[off]" }; let help = Line::from(vec![ Span::styled(" j/k/\u{2191}\u{2193}", Style::default().fg(Color::Cyan)), Span::raw("=nav "), @@ -214,7 +225,7 @@ impl ScreenView for LearnScreen { Span::styled("r", Style::default().fg(Color::Red)), Span::raw("=reject "), Span::styled("g", Style::default().fg(Color::Yellow)), - Span::raw(format!("=gen{} ", gen_status)), + Span::raw("=gen "), Span::styled("s", Style::default().fg(Color::Magenta)), Span::raw("=send "), Span::styled("+/-", Style::default().fg(Color::Cyan)),