Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:39:03.921Z 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

row_identifiers.rs

180 lines · 6.0 KB · rust
1use ui::{
2    ActiveTheme as _, AnyElement, Button, ButtonCommon as _, ButtonSize, ButtonStyle,
3    Clickable as _, Context, ElementId, IntoElement as _, ParentElement as _, SharedString,
4    Styled as _, StyledTypography as _, Tooltip, div,
5};
6
7use crate::{
8    CsvPreviewView,
9    settings::RowIdentifiers,
10    types::{DataRow, DisplayRow, LineNumber},
11};
12
13pub enum RowIdentDisplayMode {
14    /// E.g
15    /// ```text
16    /// 1
17    /// ...
18    /// 5
19    /// ```
20    Vertical,
21    /// E.g.
22    /// ```text
23    /// 1-5
24    /// ```
25    Horizontal,
26}
27
28impl LineNumber {
29    pub fn display_string(&self, mode: RowIdentDisplayMode) -> String {
30        match *self {
31            LineNumber::Line(line) => line.to_string(),
32            LineNumber::LineRange(start, end) => match mode {
33                RowIdentDisplayMode::Vertical => {
34                    if start + 1 == end {
35                        format!("{start}\n{end}")
36                    } else {
37                        format!("{start}\n-\n{end}")
38                    }
39                }
40                RowIdentDisplayMode::Horizontal => {
41                    format!("{start}-{end}")
42                }
43            },
44        }
45    }
46}
47
48impl CsvPreviewView {
49    /// Calculate the optimal width for the row identifier column (line numbers or row numbers).
50    ///
51    /// This ensures the column is wide enough to display the largest identifier comfortably,
52    /// but not wastefully wide for small files.
53    pub(crate) fn calculate_row_identifier_column_width(&self) -> f32 {
54        match self.settings.numbering_type {
55            RowIdentifiers::SrcLines => self.calculate_line_number_width(),
56            RowIdentifiers::RowNum => self.calculate_row_number_width(),
57        }
58    }
59
60    /// Calculate width needed for line numbers (can be multi-line)
61    fn calculate_line_number_width(&self) -> f32 {
62        // Find the maximum line number that could be displayed
63        let max_line_number = self
64            .engine
65            .contents
66            .line_numbers
67            .iter()
68            .map(|ln| match ln {
69                LineNumber::Line(n) => *n,
70                LineNumber::LineRange(_, end) => *end,
71            })
72            .max()
73            .unwrap_or_default();
74
75        let digit_count = if max_line_number == 0 {
76            1
77        } else {
78            (max_line_number as f32).log10().floor() as usize + 1
79        };
80
81        let char_width_px = 9.0; // TODO: get real width of the characters
82        let base_width = (digit_count as f32) * char_width_px;
83        let padding = 20.0;
84        let min_width = 60.0;
85        (base_width + padding).max(min_width)
86    }
87
88    /// Calculate width needed for sequential row numbers
89    fn calculate_row_number_width(&self) -> f32 {
90        let max_row_number = self.engine.contents.rows.len();
91
92        let digit_count = if max_row_number == 0 {
93            1
94        } else {
95            (max_row_number as f32).log10().floor() as usize + 1
96        };
97
98        let char_width_px = 9.0; // TODO: get real width of the characters
99        let base_width = (digit_count as f32) * char_width_px;
100        let padding = 20.0;
101        let min_width = 60.0;
102        (base_width + padding).max(min_width)
103    }
104
105    pub(crate) fn create_row_identifier_header(
106        &self,
107        cx: &mut Context<'_, CsvPreviewView>,
108    ) -> AnyElement {
109        // First column: row identifier (clickable to toggle between Lines and Rows)
110        let row_identifier_text = match self.settings.numbering_type {
111            RowIdentifiers::SrcLines => "Lines",
112            RowIdentifiers::RowNum => "Rows",
113        };
114
115        let view = cx.entity();
116        let value = div()
117            .font_buffer(cx)
118            .child(
119                Button::new(
120                    ElementId::Name("row-identifier-toggle".into()),
121                    row_identifier_text,
122                )
123                .style(ButtonStyle::Subtle)
124                .size(ButtonSize::Compact)
125                .tooltip(Tooltip::text(
126                    "Toggle between: file line numbers or sequential row numbers",
127                ))
128                .on_click(move |_event, _window, cx| {
129                    view.update(cx, |this, cx| {
130                        this.settings.numbering_type = match this.settings.numbering_type {
131                            RowIdentifiers::SrcLines => RowIdentifiers::RowNum,
132                            RowIdentifiers::RowNum => RowIdentifiers::SrcLines,
133                        };
134                        this.sync_column_widths(cx);
135                        cx.notify();
136                    });
137                }),
138            )
139            .into_any_element();
140        value
141    }
142
143    pub(crate) fn create_row_identifier_cell(
144        &self,
145        display_row: DisplayRow,
146        data_row: DataRow,
147        cx: &Context<'_, CsvPreviewView>,
148    ) -> Option<AnyElement> {
149        let row_identifier: SharedString = match self.settings.numbering_type {
150            RowIdentifiers::SrcLines => self
151                .engine
152                .contents
153                .line_numbers
154                .get(*data_row)?
155                .display_string(if self.settings.multiline_cells_effectively_enabled() {
156                    RowIdentDisplayMode::Vertical
157                } else {
158                    RowIdentDisplayMode::Horizontal
159                })
160                .into(),
161            RowIdentifiers::RowNum => (*display_row + 1).to_string().into(),
162        };
163
164        let value = div()
165            .flex()
166            .px_1()
167            .border_color(cx.theme().colors().border_variant)
168            .bg(cx.theme().colors().panel_background)
169            .h_full()
170            .text_color(cx.theme().colors().text_muted)
171            .justify_center()
172            .items_center()
173            .font_buffer(cx)
174            .text_ui(cx)
175            .child(row_identifier)
176            .into_any_element();
177        Some(value)
178    }
179}
180
Served at tenant.openagents/omega Member data and write actions are omitted.