Fix TOC issues: add ScrollArea, fix section jump mechanism

This commit is contained in:
2026-05-22 17:28:44 +08:00
parent f12297d580
commit 21e9aba274
2 changed files with 42 additions and 23 deletions

View File

@@ -375,6 +375,15 @@ BgType::Custom(ref path) if !path.is_empty() => {
ctx.set_style(theme::create_style(&self.settings.theme)); ctx.set_style(theme::create_style(&self.settings.theme));
} }
if action.toggle_sidebar {
self.state.sidebar_open = !self.state.sidebar_open;
}
if let Some(section) = action.jump_to_section {
self.state.current_section = section;
self.state.current_page = 0;
}
if action.page_prev { if action.page_prev {
self.state.prev_page(); self.state.prev_page();
} }

View File

@@ -210,6 +210,8 @@ pub struct ReaderAction {
pub switch_font: Option<String>, pub switch_font: Option<String>,
pub page_next: bool, pub page_next: bool,
pub page_prev: bool, pub page_prev: bool,
pub toggle_sidebar: bool,
pub jump_to_section: Option<usize>,
} }
pub fn reading_view( pub fn reading_view(
@@ -235,6 +237,8 @@ pub fn reading_view(
switch_font: None, switch_font: None,
page_next: false, page_next: false,
page_prev: false, page_prev: false,
toggle_sidebar: false,
jump_to_section: None,
}; };
let mut jump_to_bookmark: Option<usize> = None; let mut jump_to_bookmark: Option<usize> = None;
@@ -266,9 +270,15 @@ pub fn reading_view(
}); });
ui.separator(); ui.separator();
if sidebar_tab == 0 { if sidebar_tab == 0 {
render_toc(ui, &book.toc, current_section, current_page); egui::ScrollArea::vertical().show(ui, |ui| {
if let Some(section) = render_toc(ui, &book.toc, *current_section) {
action.jump_to_section = Some(section);
}
});
} else { } else {
egui::ScrollArea::vertical().show(ui, |ui| {
render_bookmarks(ui, bookmarks, &mut jump_to_bookmark); render_bookmarks(ui, bookmarks, &mut jump_to_bookmark);
});
} }
}); });
} }
@@ -527,6 +537,9 @@ egui::ComboBox::from_id_salt("bg_type_selector")
if ui.input(|i| i.key_pressed(egui::Key::ArrowLeft)) { if ui.input(|i| i.key_pressed(egui::Key::ArrowLeft)) {
action.page_prev = true; action.page_prev = true;
} }
if ui.input(|i| i.key_pressed(egui::Key::B)) {
action.toggle_sidebar = true;
}
}); });
(action, jump_to_bookmark) (action, jump_to_bookmark)
@@ -535,32 +548,29 @@ egui::ComboBox::from_id_salt("bg_type_selector")
fn render_toc( fn render_toc(
ui: &mut egui::Ui, ui: &mut egui::Ui,
entries: &[crate::book::TocEntry], entries: &[crate::book::TocEntry],
current_section: &mut usize, current_section: usize,
current_page: &mut usize, ) -> Option<usize> {
) { let mut jump = None;
for entry in entries { for entry in entries {
let is_current = entry.section == *current_section; let label_text = egui::RichText::new(&entry.label);
let label_text = if is_current {
egui::RichText::new(&entry.label).color(egui::Color32::YELLOW).strong()
} else {
egui::RichText::new(&entry.label)
};
let response = ui.add( let response = ui.add(
egui::Button::new(label_text) egui::Button::new(label_text)
.frame(false) .frame(false)
.wrap() .wrap()
); );
if response.clicked() { if response.clicked() {
*current_section = entry.section; jump = Some(entry.section);
*current_page = 0;
} }
response.on_hover_text(format!("跳转到: {}", entry.label)); response.on_hover_text(format!("跳转到: {} (章节 {})", entry.label, entry.section));
if !entry.children.is_empty() { if !entry.children.is_empty() {
ui.indent(&entry.label, |ui| { ui.indent(&entry.label, |ui| {
render_toc(ui, &entry.children, current_section, current_page); if let Some(s) = render_toc(ui, &entry.children, current_section) {
jump = Some(s);
}
}); });
} }
} }
jump
} }
fn render_bookmarks( fn render_bookmarks(