细化书签功能:正文指示器、侧边栏书签列表、跳转功能

This commit is contained in:
2026-05-15 11:27:22 +08:00
parent 88f15d307a
commit 2df605c864
2 changed files with 108 additions and 8 deletions

View File

@@ -42,7 +42,8 @@ pub fn reading_view(
bg_type: BgType,
_file_path: &str,
profile_names: &[String],
) -> ReaderAction {
bookmarks: &[crate::theme::Bookmark],
) -> (ReaderAction, Option<usize>) {
let mut action = ReaderAction {
go_back: false,
toggle_theme: false,
@@ -52,21 +53,35 @@ pub fn reading_view(
page_next: false,
page_prev: false,
};
let mut jump_to_bookmark: Option<usize> = None;
let panel_size = ui.available_size();
recalculate_pages(book, style.font_size, style.line_height(), panel_size.x, panel_size.y);
let colors = theme::reader_colors(theme);
let has_bookmark = bookmarks.iter().any(|b| b.section == *current_section && b.page == *current_page);
// --- Sidebar (TOC) ---
// --- Sidebar (TOC + Bookmarks) ---
let mut sidebar_tab: usize = 0;
if *sidebar_open {
egui::SidePanel::left("toc_sidebar")
.resizable(true)
.default_width(200.0)
.default_width(240.0)
.show_inside(ui, |ui| {
ui.heading("目录");
ui.horizontal(|ui| {
let toc_response = ui.selectable_label(sidebar_tab == 0, "📋 目录");
let bm_response = ui.selectable_label(sidebar_tab == 1,
format!("🔖 书签 ({})", bookmarks.len())
);
if toc_response.clicked() { sidebar_tab = 0; }
if bm_response.clicked() { sidebar_tab = 1; }
});
ui.separator();
render_toc(ui, &book.toc, current_section, current_page);
if sidebar_tab == 0 {
render_toc(ui, &book.toc, current_section, current_page);
} else {
render_bookmarks(ui, bookmarks, &mut jump_to_bookmark);
}
});
}
@@ -88,7 +103,9 @@ pub fn reading_view(
if ui.button(theme_icon).on_hover_text(theme_hint).clicked() {
action.toggle_theme = true;
}
if ui.button("🔖").on_hover_text("添加/移除书签").clicked() {
let bookmark_icon = if has_bookmark { "🔴" } else { "🔖" };
let bookmark_hint = if has_bookmark { "移除书签" } else { "添加书签" };
if ui.button(bookmark_icon).on_hover_text(bookmark_hint).clicked() {
action.toggle_bookmark = true;
}
if ui.button("A⁻").on_hover_text("缩小字体").clicked() {
@@ -224,6 +241,18 @@ egui::ComboBox::from_id_salt("bg_type_selector")
},
);
});
if has_bookmark {
let painter = ui.painter();
let bookmark_pos = egui::pos2(rect.max.x - 30.0, rect.min.y + 10.0);
painter.text(
bookmark_pos,
egui::Align2::RIGHT_TOP,
"🔴",
egui::FontId::proportional(18.0),
egui::Color32::RED,
);
}
}
}
@@ -248,7 +277,7 @@ egui::ComboBox::from_id_salt("bg_type_selector")
}
});
action
(action, jump_to_bookmark)
}
fn render_toc(
@@ -282,6 +311,31 @@ fn render_toc(
}
}
fn render_bookmarks(
ui: &mut egui::Ui,
bookmarks: &[crate::theme::Bookmark],
jump_to_bookmark: &mut Option<usize>,
) {
if bookmarks.is_empty() {
ui.horizontal(|ui| {
ui.label("暂无书签");
});
ui.label("点击工具栏 🔖 按钮添加书签");
return;
}
for (idx, bm) in bookmarks.iter().enumerate() {
let label_text = egui::RichText::new(&bm.label).size(13.0);
if ui.add(
egui::Button::new(label_text)
.frame(false)
.wrap()
).on_hover_text("点击跳转到该书签").clicked() {
*jump_to_bookmark = Some(idx);
}
}
}
pub fn calculate_pages(text: &str, chars_per_page: usize) -> Vec<usize> {
let mut pages = Vec::new();
pages.push(0);