94 lines · 3.3 KB · Rust
RawDownload
use gpui::ElementId;use ui::{Tooltip, prelude::*}; use crate::{    CsvPreviewView,    settings::FontType,    table_data_engine::sorting_by_column::{AppliedSorting, SortDirection},    types::AnyColumn,}; impl CsvPreviewView {    /// Create header for data, which is orderable with text on the left and sort button on the right    pub(crate) fn create_header_element_with_sort_button(        &self,        header_text: SharedString,        cx: &mut Context<'_, CsvPreviewView>,        col_idx: AnyColumn,    ) -> AnyElement {        // CSV data columns: text + filter/sort buttons        h_flex()            .justify_between()            .items_center()            .w_full()            .map(|div| match self.settings.font_type {                FontType::Ui => div.font_ui(cx),                FontType::Monospace => div.font_buffer(cx),            })            .child(div().child(header_text))            .child(h_flex().gap_1().child(self.create_sort_button(cx, col_idx)))            .into_any_element()    }     fn create_sort_button(        &self,        cx: &mut Context<'_, CsvPreviewView>,        col_idx: AnyColumn,    ) -> Button {        let sort_btn = Button::new(            ElementId::NamedInteger("sort-button".into(), col_idx.get() as u64),            match self.engine.applied_sorting {                Some(ordering) if ordering.col_idx == col_idx => match ordering.direction {                    SortDirection::Asc => "↓",                    SortDirection::Desc => "↑",                },                _ => "↕", // Unsorted/available for sorting            },        )        .size(ButtonSize::Compact)        .style(            if self                .engine                .applied_sorting                .is_some_and(|o| o.col_idx == col_idx)            {                ButtonStyle::Filled            } else {                ButtonStyle::Subtle            },        )        .tooltip(Tooltip::text(match self.engine.applied_sorting {            Some(ordering) if ordering.col_idx == col_idx => match ordering.direction {                SortDirection::Asc => "Sorted A-Z. Click to sort Z-A",                SortDirection::Desc => "Sorted Z-A. Click to disable sorting",            },            _ => "Not sorted. Click to sort A-Z",        }))        .on_click(cx.listener(move |this, _event, _window, cx| {            let new_sorting = match this.engine.applied_sorting {                Some(ordering) if ordering.col_idx == col_idx => {                    // Same column clicked - cycle through states                    match ordering.direction {                        SortDirection::Asc => Some(AppliedSorting {                            col_idx,                            direction: SortDirection::Desc,                        }),                        SortDirection::Desc => None, // Clear sorting                    }                }                _ => {                    // Different column or no sorting - start with ascending                    Some(AppliedSorting {                        col_idx,                        direction: SortDirection::Asc,                    })                }            };             this.engine.applied_sorting = new_sorting;            this.apply_sort();            cx.notify();        }));        sort_btn    }}