scrolling window centered
This commit is contained in:
41
src/main.rs
41
src/main.rs
@@ -217,7 +217,7 @@ fn handle_key(app: &mut App, code: KeyCode) {
|
|||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match code {
|
match code {
|
||||||
KeyCode::Char('q') => app.should_exit = true,
|
KeyCode::Char('q') => app.should_exit = true,
|
||||||
|
|
||||||
@@ -298,9 +298,34 @@ fn ui(frame: &mut Frame, app: &App) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_window(len: usize, selected: usize, viewport: usize) -> (usize, usize) {
|
||||||
|
if len == 0 || viewport == 0 {
|
||||||
|
return (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let viewport = viewport.min(len);
|
||||||
|
let half = viewport / 2;
|
||||||
|
|
||||||
|
let mut start = selected.saturating_sub(half);
|
||||||
|
if start + viewport > len {
|
||||||
|
start = len - viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
let end = start + viewport;
|
||||||
|
(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn render_categories(frame: &mut Frame, app: &App, left: Rect, right: Rect) {
|
fn render_categories(frame: &mut Frame, app: &App, left: Rect, right: Rect) {
|
||||||
let items: Vec<ListItem> = app
|
// how many rows can we show inside the bordered block?
|
||||||
.items
|
let viewport = left.height.saturating_sub(2) as usize;
|
||||||
|
|
||||||
|
let len = app.items.len();
|
||||||
|
let selected = app.selected.min(len.saturating_sub(1));
|
||||||
|
|
||||||
|
let (start, end) = compute_window(len, selected, viewport);
|
||||||
|
|
||||||
|
let items: Vec<ListItem> = app.items[start..end]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| ListItem::new(s.as_str()))
|
.map(|s| ListItem::new(s.as_str()))
|
||||||
.collect();
|
.collect();
|
||||||
@@ -311,11 +336,17 @@ fn render_categories(frame: &mut Frame, app: &App, left: Rect, right: Rect) {
|
|||||||
.highlight_style(Style::default().add_modifier(Modifier::REVERSED));
|
.highlight_style(Style::default().add_modifier(Modifier::REVERSED));
|
||||||
|
|
||||||
let mut state = ListState::default();
|
let mut state = ListState::default();
|
||||||
state.select(Some(app.selected));
|
state.select(Some(selected - start)); // selection relative to slice
|
||||||
|
|
||||||
frame.render_stateful_widget(list, left, &mut state);
|
frame.render_stateful_widget(list, left, &mut state);
|
||||||
|
|
||||||
let detail = format!("Details for:\n\n{}", app.items[app.selected]);
|
// Right pane details (use the real selected item)
|
||||||
|
let detail = if len > 0 {
|
||||||
|
format!("Details for:\n\n{}", app.items[selected])
|
||||||
|
} else {
|
||||||
|
"No items".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
frame.render_widget(
|
frame.render_widget(
|
||||||
Paragraph::new(detail)
|
Paragraph::new(detail)
|
||||||
.block(Block::bordered().title("Details").merge_borders(MergeStrategy::Exact)),
|
.block(Block::bordered().title("Details").merge_borders(MergeStrategy::Exact)),
|
||||||
|
|||||||
Reference in New Issue
Block a user