dreader-application/examples/navigation_overlay_example.py

197 lines
6.9 KiB
Python

"""
Example demonstrating the unified navigation overlay feature.
This example shows how to:
1. Open the navigation overlay with Contents and Bookmarks tabs
2. Switch between tabs
3. Navigate to chapters and bookmarks
4. Handle user interactions with the overlay
The navigation overlay replaces the separate TOC and Bookmarks overlays
with a single, unified interface that provides both features in a tabbed view.
"""
from pathlib import Path
from dreader.application import EbookReader
from dreader.state import OverlayState
def main():
# Create reader instance
reader = EbookReader(page_size=(800, 1200), margin=20)
# Load a sample book (adjust path as needed)
book_path = Path(__file__).parent / "books" / "hamlet.epub"
if not book_path.exists():
print(f"Book not found at {book_path}")
print("Creating a simple HTML book for demo...")
# Create a simple multi-chapter book
html = """
<html>
<head><title>Demo Book</title></head>
<body>
<h1>Chapter 1: Introduction</h1>
<p>This is the first chapter with some introductory content.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<h1>Chapter 2: Main Content</h1>
<p>This is the second chapter with main content.</p>
<p>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<h1>Chapter 3: Conclusion</h1>
<p>This is the final chapter with concluding remarks.</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
</body>
</html>
"""
reader.load_html(
html_string=html,
title="Demo Book",
author="Example Author",
document_id="demo_navigation"
)
else:
print(f"Loading book: {book_path}")
reader.load_epub(str(book_path))
print("\n=== Navigation Overlay Demo ===\n")
# Display current page
position_info = reader.get_position_info()
print(f"Current position: {position_info}")
print(f"Reading progress: {reader.get_reading_progress():.1%}")
# Get chapters
chapters = reader.get_chapters()
print(f"\nAvailable chapters: {len(chapters)}")
for i, (title, idx) in enumerate(chapters[:5]): # Show first 5
print(f" {i+1}. {title}")
# Save some bookmarks for demonstration
print("\n--- Saving bookmarks ---")
reader.save_position("Start of Book")
print("Saved bookmark: 'Start of Book'")
reader.next_page()
reader.next_page()
reader.save_position("Chapter 1 Progress")
print("Saved bookmark: 'Chapter 1 Progress'")
# List saved bookmarks
bookmarks = reader.list_saved_positions()
print(f"\nTotal bookmarks: {len(bookmarks)}")
for name in bookmarks:
print(f" - {name}")
# === Demo 1: Open navigation overlay with Contents tab ===
print("\n\n--- Demo 1: Opening Navigation Overlay (Contents Tab) ---")
image = reader.open_navigation_overlay(active_tab="contents")
if image:
print(f"✓ Navigation overlay opened successfully")
print(f" Overlay state: {reader.get_overlay_state()}")
print(f" Is overlay open: {reader.is_overlay_open()}")
print(f" Image size: {image.size}")
# Save the rendered overlay for inspection
output_path = Path("/tmp/navigation_overlay_contents.png")
image.save(output_path)
print(f" Saved to: {output_path}")
# === Demo 2: Switch to Bookmarks tab ===
print("\n\n--- Demo 2: Switching to Bookmarks Tab ---")
image = reader.switch_navigation_tab("bookmarks")
if image:
print(f"✓ Switched to Bookmarks tab")
print(f" Overlay state: {reader.get_overlay_state()}")
# Save the rendered overlay for inspection
output_path = Path("/tmp/navigation_overlay_bookmarks.png")
image.save(output_path)
print(f" Saved to: {output_path}")
# === Demo 3: Switch back to Contents tab ===
print("\n\n--- Demo 3: Switching back to Contents Tab ---")
image = reader.switch_navigation_tab("contents")
if image:
print(f"✓ Switched back to Contents tab")
# Save the rendered overlay for inspection
output_path = Path("/tmp/navigation_overlay_contents_2.png")
image.save(output_path)
print(f" Saved to: {output_path}")
# === Demo 4: Close overlay ===
print("\n\n--- Demo 4: Closing Navigation Overlay ---")
image = reader.close_overlay()
if image:
print(f"✓ Overlay closed successfully")
print(f" Overlay state: {reader.get_overlay_state()}")
print(f" Is overlay open: {reader.is_overlay_open()}")
# === Demo 5: Open with Bookmarks tab directly ===
print("\n\n--- Demo 5: Opening directly to Bookmarks Tab ---")
image = reader.open_navigation_overlay(active_tab="bookmarks")
if image:
print(f"✓ Navigation overlay opened with Bookmarks tab")
# Save the rendered overlay for inspection
output_path = Path("/tmp/navigation_overlay_bookmarks_direct.png")
image.save(output_path)
print(f" Saved to: {output_path}")
# Close overlay
reader.close_overlay()
# === Demo 6: Simulate user interaction flow ===
print("\n\n--- Demo 6: Simulated User Interaction Flow ---")
print("Simulating: User opens overlay, switches tabs, selects bookmark")
# 1. User opens navigation overlay
print("\n 1. User taps navigation button -> Opens overlay with Contents tab")
reader.open_navigation_overlay(active_tab="contents")
print(f" State: {reader.get_overlay_state()}")
# 2. User switches to Bookmarks tab
print("\n 2. User taps 'Bookmarks' tab")
reader.switch_navigation_tab("bookmarks")
print(f" State: {reader.get_overlay_state()}")
# 3. User selects a bookmark
print("\n 3. User taps on bookmark 'Start of Book'")
page = reader.load_position("Start of Book")
if page:
print(f" ✓ Loaded bookmark successfully")
print(f" Position: {reader.get_position_info()}")
# 4. Close overlay
print("\n 4. System closes overlay after selection")
reader.close_overlay()
print(f" State: {reader.get_overlay_state()}")
# === Summary ===
print("\n\n=== Demo Complete ===")
print(f"\nGenerated overlay images in /tmp:")
print(f" - navigation_overlay_contents.png")
print(f" - navigation_overlay_bookmarks.png")
print(f" - navigation_overlay_contents_2.png")
print(f" - navigation_overlay_bookmarks_direct.png")
print("\n✓ Navigation overlay provides unified interface for:")
print(" • Table of Contents (chapter navigation)")
print(" • Bookmarks (saved positions)")
print(" • Tab switching between Contents and Bookmarks")
print(" • Consistent interaction patterns")
# Cleanup
reader.close()
print("\nReader closed.")
if __name__ == "__main__":
main()