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 }}
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
}
}