click to focus row

This commit is contained in:
Ben Kunkle
2025-06-13 09:25:51 +02:00
parent 01b2b62d08
commit 1ee034751a
2 changed files with 39 additions and 13 deletions

View File

@@ -319,6 +319,9 @@ impl Render for KeymapEditor {
.column_widths([rems(24.), rems(16.), rems(32.), rems(8.)])
.header(["Command", "Keystrokes", "Context", "Source"])
.selected_item_index(self.selected_index.clone())
.on_click_row(cx.processor(|this, row_index, _window, _cx| {
this.selected_index = Some(row_index);
}))
.uniform_list(
"keymap-editor-table",
row_count,

View File

@@ -1,4 +1,4 @@
use std::{ops::Range, time::Duration};
use std::{ops::Range, rc::Rc, time::Duration};
use editor::{EditorSettings, ShowScrollbar, scroll::ScrollbarAutoHide};
use gpui::{
@@ -355,6 +355,7 @@ pub struct Table<const COLS: usize = 3> {
interaction_state: Option<WeakEntity<TableInteractionState>>,
selected_item_index: Option<usize>,
column_widths: Option<[Length; COLS]>,
on_click_row: Option<Rc<dyn Fn(usize, &mut Window, &mut App)>>,
}
impl<const COLS: usize> Table<COLS> {
@@ -368,6 +369,7 @@ impl<const COLS: usize> Table<COLS> {
interaction_state: None,
selected_item_index: None,
column_widths: None,
on_click_row: None,
}
}
@@ -428,6 +430,14 @@ impl<const COLS: usize> Table<COLS> {
self.column_widths = Some(widths.map(Into::into));
self
}
pub fn on_click_row(
mut self,
callback: impl Fn(usize, &mut Window, &mut App) + 'static,
) -> Self {
self.on_click_row = Some(Rc::new(callback));
self
}
}
fn base_cell_style(width: Option<Length>, cx: &App) -> Div {
@@ -460,7 +470,7 @@ pub fn render_row<const COLS: usize>(
.map_or([None; COLS], |widths| widths.map(|width| Some(width)));
let is_selected = table_context.selected_item_index == Some(row_index);
div()
let row = div()
.w_full()
.border_2()
.border_color(transparent_black())
@@ -489,8 +499,15 @@ pub fn render_row<const COLS: usize>(
.zip(column_widths)
.map(|(cell, width)| base_cell_style(width, cx).child(cell)),
),
)
.into_any_element()
);
if let Some(on_click) = table_context.on_click_row {
row.id(ElementId::named_usize("table-row", row_index))
.on_click(move |_, window, cx| on_click(row_index, window, cx))
.into_any_element()
} else {
row.into_any_element()
}
}
pub fn render_header<const COLS: usize>(
@@ -517,12 +534,13 @@ pub fn render_header<const COLS: usize>(
}))
}
#[derive(Clone, Copy)]
#[derive(Clone)]
pub struct TableRenderContext<const COLS: usize> {
pub striped: bool,
pub total_row_count: usize,
pub selected_item_index: Option<usize>,
pub column_widths: Option<[Length; COLS]>,
pub on_click_row: Option<Rc<dyn Fn(usize, &mut Window, &mut App)>>,
}
impl<const COLS: usize> TableRenderContext<COLS> {
@@ -532,6 +550,7 @@ impl<const COLS: usize> TableRenderContext<COLS> {
total_row_count: table.rows.len(),
column_widths: table.column_widths,
selected_item_index: table.selected_item_index.clone(),
on_click_row: table.on_click_row.clone(),
}
}
}
@@ -581,7 +600,7 @@ impl<const COLS: usize> RenderOnce for Table<COLS> {
})
})
.when_some(self.headers.take(), |this, headers| {
this.child(render_header(headers, table_context, cx))
this.child(render_header(headers, table_context.clone(), cx))
})
.child(
div()
@@ -590,12 +609,11 @@ impl<const COLS: usize> RenderOnce for Table<COLS> {
.relative()
.overflow_hidden()
.map(|parent| match self.rows {
TableContents::Vec(items) => parent.children(
items
.into_iter()
.enumerate()
.map(|(index, row)| render_row(index, row, table_context, cx)),
),
TableContents::Vec(items) => {
parent.children(items.into_iter().enumerate().map(|(index, row)| {
render_row(index, row, table_context.clone(), cx)
}))
}
TableContents::UniformList(uniform_list_data) => parent.child(
uniform_list(
uniform_list_data.element_id,
@@ -608,7 +626,12 @@ impl<const COLS: usize> RenderOnce for Table<COLS> {
.into_iter()
.zip(range)
.map(|(row, row_index)| {
render_row(row_index, row, table_context, cx)
render_row(
row_index,
row,
table_context.clone(),
cx,
)
})
.collect()
}