Skip to repository content180 lines · 6.0 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:39:03.921Z 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
row_identifiers.rs
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