MCPcopy Create free account
hub / github.com/GCWing/BitFun / render_question_page

Function render_question_page

src/apps/cli/src/ui/question.rs:448–675  ·  view source on GitHub ↗

Render a single question page with options

(frame: &mut Frame, prompt: &QuestionPrompt, theme: &Theme, area: Rect)

Source from the content-addressed store, hash-verified

446
447/// Render a single question page with options
448fn render_question_page(frame: &mut Frame, prompt: &QuestionPrompt, theme: &Theme, area: Rect) {
449 let q = match prompt.current_question() {
450 Some(q) => q,
451 None => return,
452 };
453
454 // Calculate overlay height: header(1) + question(2) + options + other + hint(2) + padding
455 let options_count = q.options.len() + 1; // +1 for "Other"
456 let description_lines: usize = q
457 .options
458 .iter()
459 .map(|o| if o.description.is_empty() { 0 } else { 1 })
460 .sum();
461 let tab_line = if prompt.tab_count() > 1 { 2 } else { 0 };
462 let editing_line = if prompt.editing_custom { 1 } else { 0 };
463 let content_height = 2 + tab_line + options_count + description_lines + editing_line + 1; // question + options + descriptions + padding
464 let overlay_height = (content_height as u16 + 3).min(area.height.saturating_sub(2)); // +3 for borders/hint
465
466 let overlay_area = Rect {
467 x: area.x,
468 y: area.y + area.height.saturating_sub(overlay_height),
469 width: area.width,
470 height: overlay_height,
471 };
472
473 frame.render_widget(Clear, overlay_area);
474
475 let chunks = Layout::default()
476 .direction(Direction::Vertical)
477 .constraints([
478 Constraint::Min(3), // content
479 Constraint::Length(2), // hint bar
480 ])
481 .split(overlay_area);
482
483 // Content block with accent left border
484 let content_block = Block::default()
485 .borders(Borders::LEFT | Borders::TOP | Borders::RIGHT)
486 .border_style(Style::default().fg(theme.primary))
487 .style(Style::default().bg(theme.background_panel));
488
489 let inner = content_block.inner(chunks[0]);
490 frame.render_widget(content_block, chunks[0]);
491
492 let mut lines: Vec<Line> = Vec::new();
493
494 // Tab bar (multi-question only)
495 if prompt.tab_count() > 1 {
496 let mut tab_spans = Vec::new();
497 for (i, qd) in prompt.questions.iter().enumerate() {
498 if i > 0 {
499 tab_spans.push(Span::raw(" "));
500 }
501 let is_active = i == prompt.current_tab;
502 let is_answered = !prompt.answers[i].is_empty();
503 if is_active {
504 tab_spans.push(Span::styled(
505 format!(" {} ", qd.header),

Callers 1

render_question_overlayFunction · 0.85

Calls 11

render_question_hint_barFunction · 0.85
current_questionMethod · 0.80
iterMethod · 0.80
tab_countMethod · 0.80
styleMethod · 0.80
selection_foregroundMethod · 0.80
on_confirm_pageMethod · 0.80
lenMethod · 0.45
is_emptyMethod · 0.45
pushMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected