(frame: &mut Frame, app: &mut App, area: Rect)
| 440 | } |
| 441 | |
| 442 | fn draw_cluster(frame: &mut Frame, app: &mut App, area: Rect) { |
| 443 | let topo = match &app.topology { |
| 444 | Some(t) => t.clone(), |
| 445 | None => { |
| 446 | let block = Block::default() |
| 447 | .borders(Borders::ALL) |
| 448 | .border_style(Style::default().fg(Color::DarkGray)) |
| 449 | .title(" cluster "); |
| 450 | let msg = Paragraph::new(" loading topology...") |
| 451 | .style(Style::default().fg(Color::DarkGray)) |
| 452 | .block(block); |
| 453 | frame.render_widget(msg, area); |
| 454 | return; |
| 455 | } |
| 456 | }; |
| 457 | |
| 458 | // Build all node info into a flat list of lines for scrollable rendering |
| 459 | let inner_width = area.width.saturating_sub(2) as usize; |
| 460 | let visible_height = area.height.saturating_sub(2); |
| 461 | |
| 462 | let lines = build_cluster_lines(&topo, inner_width); |
| 463 | app.cluster_total_lines = lines.len() as u16; |
| 464 | |
| 465 | // Clamp scroll |
| 466 | if app.cluster_total_lines > visible_height { |
| 467 | app.cluster_scroll = app |
| 468 | .cluster_scroll |
| 469 | .min(app.cluster_total_lines - visible_height); |
| 470 | } else { |
| 471 | app.cluster_scroll = 0; |
| 472 | } |
| 473 | |
| 474 | let block = Block::default() |
| 475 | .borders(Borders::ALL) |
| 476 | .border_style(Style::default().fg(Color::DarkGray)) |
| 477 | .title(format!( |
| 478 | " {} — {} layers — {} ", |
| 479 | &topo.model, topo.num_layers, &topo.dtype |
| 480 | )); |
| 481 | |
| 482 | let cluster_widget = Paragraph::new(lines) |
| 483 | .block(block) |
| 484 | .scroll((app.cluster_scroll, 0)); |
| 485 | |
| 486 | frame.render_widget(cluster_widget, area); |
| 487 | |
| 488 | if app.cluster_total_lines > visible_height { |
| 489 | let mut scrollbar_state = ScrollbarState::new(app.cluster_total_lines as usize) |
| 490 | .position(app.cluster_scroll as usize) |
| 491 | .viewport_content_length(visible_height as usize); |
| 492 | frame.render_stateful_widget( |
| 493 | Scrollbar::new(ScrollbarOrientation::VerticalRight), |
| 494 | area.inner(Margin::new(0, 1)), |
| 495 | &mut scrollbar_state, |
| 496 | ); |
| 497 | } |
| 498 | } |
| 499 |
no test coverage detected