Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:33:06.472Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

render_table.rs

178 lines · 7.1 KB · rust
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
Served at tenant.openagents/omega Member data and write actions are omitted.