tabs scroll
This commit is contained in:
@@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user