Fix TOC issues: add ScrollArea, fix section jump mechanism
This commit is contained in:
@@ -375,6 +375,15 @@ BgType::Custom(ref path) if !path.is_empty() => {
|
||||
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 {
|
||||
self.state.prev_page();
|
||||
}
|
||||
|
||||
@@ -210,6 +210,8 @@ pub struct ReaderAction {
|
||||
pub switch_font: Option<String>,
|
||||
pub page_next: bool,
|
||||
pub page_prev: bool,
|
||||
pub toggle_sidebar: bool,
|
||||
pub jump_to_section: Option<usize>,
|
||||
}
|
||||
|
||||
pub fn reading_view(
|
||||
@@ -235,6 +237,8 @@ pub fn reading_view(
|
||||
switch_font: None,
|
||||
page_next: false,
|
||||
page_prev: false,
|
||||
toggle_sidebar: false,
|
||||
jump_to_section: None,
|
||||
};
|
||||
let mut jump_to_bookmark: Option<usize> = None;
|
||||
|
||||
@@ -266,9 +270,15 @@ pub fn reading_view(
|
||||
});
|
||||
ui.separator();
|
||||
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 {
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
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)) {
|
||||
action.page_prev = true;
|
||||
}
|
||||
if ui.input(|i| i.key_pressed(egui::Key::B)) {
|
||||
action.toggle_sidebar = true;
|
||||
}
|
||||
});
|
||||
|
||||
(action, jump_to_bookmark)
|
||||
@@ -535,32 +548,29 @@ egui::ComboBox::from_id_salt("bg_type_selector")
|
||||
fn render_toc(
|
||||
ui: &mut egui::Ui,
|
||||
entries: &[crate::book::TocEntry],
|
||||
current_section: &mut usize,
|
||||
current_page: &mut usize,
|
||||
) {
|
||||
current_section: usize,
|
||||
) -> Option<usize> {
|
||||
let mut jump = None;
|
||||
for entry in entries {
|
||||
let is_current = entry.section == *current_section;
|
||||
let label_text = if is_current {
|
||||
egui::RichText::new(&entry.label).color(egui::Color32::YELLOW).strong()
|
||||
} else {
|
||||
egui::RichText::new(&entry.label)
|
||||
};
|
||||
let label_text = egui::RichText::new(&entry.label);
|
||||
let response = ui.add(
|
||||
egui::Button::new(label_text)
|
||||
.frame(false)
|
||||
.wrap()
|
||||
);
|
||||
if response.clicked() {
|
||||
*current_section = entry.section;
|
||||
*current_page = 0;
|
||||
jump = Some(entry.section);
|
||||
}
|
||||
response.on_hover_text(format!("跳转到: {}", entry.label));
|
||||
response.on_hover_text(format!("跳转到: {} (章节 {})", entry.label, entry.section));
|
||||
if !entry.children.is_empty() {
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user