Skip to repository content178 lines · 7.1 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T05:35:59.278Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
render_table.rs
1use crate::types::TableCell;
2use gpui::{AnyElement, Entity};
3use std::ops::Range;
4use ui::{ColumnWidthConfig, ResizableColumnsState, Table, UncheckedTableRow, div, prelude::*};
5
6use crate::{
7 CsvPreviewView,
8 settings::RowRenderMechanism,
9 types::{AnyColumn, DisplayCellId, DisplayRow},
10};
11
12impl CsvPreviewView {
13 /// Creates a new table.
14 /// Column number is derived from the `ResizableColumnsState` entity.
15 pub(crate) fn create_table(
16 &self,
17 current_widths: &Entity<ResizableColumnsState>,
18 cx: &mut Context<Self>,
19 ) -> AnyElement {
20 self.create_table_inner(self.engine.contents.rows.len(), current_widths, cx)
21 }
22
23 fn create_table_inner(
24 &self,
25 row_count: usize,
26 current_widths: &Entity<ResizableColumnsState>,
27 cx: &mut Context<Self>,
28 ) -> AnyElement {
29 let cols = current_widths.read(cx).cols();
30 // Create headers array with interactive elements
31 let mut headers = Vec::with_capacity(cols);
32
33 headers.push(self.create_row_identifier_header(cx));
34
35 // Add the actual CSV headers with sort buttons
36 for i in 0..(cols - 1) {
37 let header_text = self
38 .engine
39 .contents
40 .headers
41 .get(AnyColumn(i))
42 .and_then(|h| h.display_value().cloned())
43 .unwrap_or_else(|| format!("Col {}", i + 1).into());
44
45 headers.push(self.create_header_element_with_sort_button(
46 header_text,
47 cx,
48 AnyColumn::from(i),
49 ));
50 }
51
52 Table::new(cols)
53 .interactable(&self.table_interaction_state)
54 .width_config(ColumnWidthConfig::Resizable(current_widths.clone()))
55 .header(headers)
56 .disable_base_style()
57 .pin_cols(1)
58 .map(|table| {
59 let row_identifier_text_color = cx.theme().colors().editor_line_number;
60 match self.settings.rendering_with {
61 RowRenderMechanism::VariableList => {
62 table.variable_row_height_list(row_count, self.list_state.clone(), {
63 cx.processor(move |this, display_row: usize, _window, cx| {
64 this.performance_metrics.rendered_indices.push(display_row);
65
66 let display_row = DisplayRow(display_row);
67 Self::render_single_table_row(
68 this,
69 cols,
70 display_row,
71 row_identifier_text_color,
72 this.row_height,
73 cx,
74 )
75 .unwrap_or_else(|| panic!("Expected to render a table row"))
76 })
77 })
78 }
79 RowRenderMechanism::UniformList => {
80 table.uniform_list("csv-table", row_count, {
81 cx.processor(move |this, range: Range<usize>, _window, cx| {
82 // Record all display indices in the range for performance metrics
83 this.performance_metrics
84 .rendered_indices
85 .extend(range.clone());
86
87 let row_height = this.row_height;
88 range
89 .filter_map(|display_index| {
90 Self::render_single_table_row(
91 this,
92 cols,
93 DisplayRow(display_index),
94 row_identifier_text_color,
95 row_height,
96 cx,
97 )
98 })
99 .collect()
100 })
101 })
102 }
103 }
104 })
105 .into_any_element()
106 }
107
108 /// Render a single table row
109 ///
110 /// Used both by UniformList and VariableRowHeightList
111 fn render_single_table_row(
112 this: &CsvPreviewView,
113 cols: usize,
114 display_row: DisplayRow,
115 row_identifier_text_color: gpui::Hsla,
116 row_height: Pixels,
117 cx: &Context<CsvPreviewView>,
118 ) -> Option<UncheckedTableRow<AnyElement>> {
119 // Get the actual row index from our sorted indices
120 let data_row = this.engine.d2d_mapping().get_data_row(display_row)?;
121 let row = this.engine.contents.get_row(data_row)?;
122
123 let mut elements = Vec::with_capacity(cols);
124 elements.push(this.create_row_identifier_cell(display_row, data_row, cx)?);
125
126 // Remaining columns: actual CSV data
127 for col in (0..this.engine.contents.number_of_cols).map(AnyColumn) {
128 let table_cell = row.expect_get(col);
129
130 // TODO: Introduce `<null>` cell type
131 let cell_content = table_cell.display_value().cloned().unwrap_or_default();
132
133 let display_cell_id = DisplayCellId::new(display_row, col);
134
135 let cell = div()
136 .size_full()
137 .when(
138 !this.settings.multiline_cells_effectively_enabled(),
139 |div| {
140 div.whitespace_nowrap()
141 .text_ellipsis()
142 .h(row_height)
143 .overflow_hidden()
144 },
145 )
146 .child(CsvPreviewView::create_selectable_cell(
147 display_cell_id,
148 cell_content,
149 this.settings.vertical_alignment,
150 cx,
151 ));
152
153 elements.push(
154 div()
155 .size_full()
156 .when(this.settings.show_debug_info, |parent| {
157 parent.child(div().text_color(row_identifier_text_color).child(
158 match table_cell {
159 TableCell::Real { position: pos, .. } => {
160 let slv = pos.start.timestamp().value;
161 let so = pos.start.offset;
162 let elv = pos.end.timestamp().value;
163 let eo = pos.end.offset;
164 format!("Pos {so}(L{slv})-{eo}(L{elv})")
165 }
166 TableCell::Virtual => "Virtual cell".into(),
167 },
168 ))
169 })
170 .child(cell)
171 .into_any_element(),
172 );
173 }
174
175 Some(elements)
176 }
177}
178