tabs scroll

This commit is contained in:
2025-12-09 18:28:31 +01:00
parent be60c65ab8
commit 8360d0d9b4
2 changed files with 67 additions and 34 deletions

View File

@@ -13,29 +13,75 @@ pub fn render_tabs_panel(
}
egui::TopBottomPanel::top("tabs_panel").show(ctx, |ui| {
ui.horizontal(|ui| {
for (idx, tab) in tabs.iter().enumerate() {
let is_active = idx == *active_tab_index;
let button_text = if is_active {
egui::RichText::new(format!("📄 {}", tab.filename())).strong()
} else {
egui::RichText::new(format!("📄 {}", tab.filename()))
};
// Get or initialize scroll offset from persistent storage
let scroll_id = egui::Id::new("tabs_scroll_offset");
let mut scroll_offset: f32 = ui.ctx().data_mut(|d| d.get_persisted(scroll_id).unwrap_or(0.0));
if ui.selectable_label(is_active, button_text).clicked() {
*active_tab_index = idx;
// Use horizontal ScrollArea for tabs with hidden scrollbar
let mut scroll_area = egui::ScrollArea::horizontal()
.auto_shrink([false; 2])
.scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysHidden);
// Apply the stored scroll offset
scroll_area = scroll_area.horizontal_scroll_offset(scroll_offset);
let scroll_output = scroll_area.show(ui, |ui| {
ui.horizontal(|ui| {
for (idx, tab) in tabs.iter().enumerate() {
let is_active = idx == *active_tab_index;
let button_text = if is_active {
egui::RichText::new(format!("📄 {}", tab.filename())).strong()
} else {
egui::RichText::new(format!("📄 {}", tab.filename()))
};
if ui.selectable_label(is_active, button_text).clicked() {
*active_tab_index = idx;
}
if ui.small_button("").clicked() {
*on_close_tab = Some(idx);
}
ui.separator();
}
if ui.small_button("").clicked() {
*on_close_tab = Some(idx);
}
ui.separator();
}
if let Some(tab) = tabs.get(*active_tab_index) {
ui.label(format!("({} lines)", tab.line_index.total_lines));
}
})
});
// Check if content overflows (tabs exceed screen width)
let content_width = scroll_output.content_size.x;
let viewport_width = scroll_output.inner_rect.width();
let content_overflows = content_width > viewport_width;
// Handle mouse wheel scrolling when hovering over tabs and content overflows
let mut should_update_offset = false;
if content_overflows && ui.rect_contains_pointer(scroll_output.inner_rect) {
// Get raw scroll delta outside of any closures
let raw_scroll_y = ui.input(|i| i.raw_scroll_delta.y);
// Check for raw mouse wheel events
if raw_scroll_y != 0.0 {
// Use vertical scroll (mouse wheel) for horizontal scrolling
let scroll_amount = -raw_scroll_y * 2.0;
scroll_offset = (scroll_offset + scroll_amount).max(0.0);
// Clamp to valid range
let max_offset = (content_width - viewport_width).max(0.0);
scroll_offset = scroll_offset.min(max_offset);
should_update_offset = true;
}
} else {
// Update offset from ScrollArea state (in case of other interactions)
scroll_offset = scroll_output.state.offset.x;
should_update_offset = true;
}
// Store the offset outside of any input closures
if should_update_offset {
ui.ctx().data_mut(|d| {
d.insert_persisted(scroll_id, scroll_offset);
});
}
});
}