refactor all navigation to one screen.
This commit is contained in:
@@ -825,6 +825,85 @@ class EbookReader:
|
||||
self.close_overlay()
|
||||
return GestureResponse(ActionType.OVERLAY_CLOSED, {})
|
||||
|
||||
# For navigation overlay, handle tab switching, chapter/bookmark selection, and close
|
||||
elif self.current_overlay_state == OverlayState.NAVIGATION:
|
||||
# Query the overlay to see what was tapped
|
||||
query_result = self.overlay_manager.query_overlay_pixel(x, y)
|
||||
|
||||
# If query failed (tap outside overlay), close it
|
||||
if not query_result:
|
||||
self.close_overlay()
|
||||
return GestureResponse(ActionType.OVERLAY_CLOSED, {})
|
||||
|
||||
# Check if tapped on a link
|
||||
if query_result.get("is_interactive") and query_result.get("link_target"):
|
||||
link_target = query_result["link_target"]
|
||||
|
||||
# Parse "tab:tabname" format for tab switching
|
||||
if link_target.startswith("tab:"):
|
||||
tab_name = link_target.split(":", 1)[1]
|
||||
# Switch to the selected tab
|
||||
self.switch_navigation_tab(tab_name)
|
||||
return GestureResponse(ActionType.TAB_SWITCHED, {
|
||||
"tab": tab_name
|
||||
})
|
||||
|
||||
# Parse "chapter:N" format for chapter navigation
|
||||
elif link_target.startswith("chapter:"):
|
||||
try:
|
||||
chapter_idx = int(link_target.split(":")[1])
|
||||
|
||||
# Get chapter title for response
|
||||
chapters = self.get_chapters()
|
||||
chapter_title = None
|
||||
for title, idx in chapters:
|
||||
if idx == chapter_idx:
|
||||
chapter_title = title
|
||||
break
|
||||
|
||||
# Jump to selected chapter
|
||||
self.jump_to_chapter(chapter_idx)
|
||||
|
||||
# Close overlay
|
||||
self.close_overlay()
|
||||
|
||||
return GestureResponse(ActionType.CHAPTER_SELECTED, {
|
||||
"chapter_index": chapter_idx,
|
||||
"chapter_title": chapter_title or f"Chapter {chapter_idx}"
|
||||
})
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
|
||||
# Parse "bookmark:name" format for bookmark navigation
|
||||
elif link_target.startswith("bookmark:"):
|
||||
bookmark_name = link_target.split(":", 1)[1]
|
||||
|
||||
# Load the bookmark position
|
||||
page = self.load_position(bookmark_name)
|
||||
if page:
|
||||
# Close overlay
|
||||
self.close_overlay()
|
||||
|
||||
return GestureResponse(ActionType.BOOKMARK_SELECTED, {
|
||||
"bookmark_name": bookmark_name
|
||||
})
|
||||
else:
|
||||
# Failed to load bookmark
|
||||
return GestureResponse(ActionType.ERROR, {
|
||||
"message": f"Failed to load bookmark: {bookmark_name}"
|
||||
})
|
||||
|
||||
# Parse "action:close" format for close button
|
||||
elif link_target.startswith("action:"):
|
||||
action = link_target.split(":", 1)[1]
|
||||
if action == "close":
|
||||
self.close_overlay()
|
||||
return GestureResponse(ActionType.OVERLAY_CLOSED, {})
|
||||
|
||||
# Not an interactive element, close overlay
|
||||
self.close_overlay()
|
||||
return GestureResponse(ActionType.OVERLAY_CLOSED, {})
|
||||
|
||||
# For other overlays, just close on any tap for now
|
||||
self.close_overlay()
|
||||
return GestureResponse(ActionType.OVERLAY_CLOSED, {})
|
||||
@@ -1127,6 +1206,64 @@ class EbookReader:
|
||||
|
||||
return result
|
||||
|
||||
def open_navigation_overlay(self, active_tab: str = "contents") -> Optional[Image.Image]:
|
||||
"""
|
||||
Open the unified navigation overlay with Contents and Bookmarks tabs.
|
||||
|
||||
This is the new unified overlay that replaces separate TOC and Bookmarks overlays.
|
||||
It provides a tabbed interface for switching between table of contents and bookmarks.
|
||||
|
||||
Args:
|
||||
active_tab: Which tab to show initially ("contents" or "bookmarks")
|
||||
|
||||
Returns:
|
||||
Composited image with navigation overlay on top of current page, or None if no book loaded
|
||||
"""
|
||||
if not self.is_loaded():
|
||||
return None
|
||||
|
||||
# Get current page as base
|
||||
base_page = self.get_current_page(include_highlights=False)
|
||||
if not base_page:
|
||||
return None
|
||||
|
||||
# Get chapters for Contents tab
|
||||
chapters = self.get_chapters()
|
||||
|
||||
# Get bookmarks for Bookmarks tab
|
||||
bookmark_names = self.list_saved_positions()
|
||||
bookmarks = [
|
||||
{"name": name, "position": f"Saved position"}
|
||||
for name in bookmark_names
|
||||
]
|
||||
|
||||
# Open overlay and get composited image
|
||||
result = self.overlay_manager.open_navigation_overlay(
|
||||
chapters=chapters,
|
||||
bookmarks=bookmarks,
|
||||
base_page=base_page,
|
||||
active_tab=active_tab
|
||||
)
|
||||
self.current_overlay_state = OverlayState.NAVIGATION
|
||||
|
||||
return result
|
||||
|
||||
def switch_navigation_tab(self, new_tab: str) -> Optional[Image.Image]:
|
||||
"""
|
||||
Switch between tabs in the navigation overlay.
|
||||
|
||||
Args:
|
||||
new_tab: Tab to switch to ("contents" or "bookmarks")
|
||||
|
||||
Returns:
|
||||
Updated image with new tab active, or None if navigation overlay is not open
|
||||
"""
|
||||
if self.current_overlay_state != OverlayState.NAVIGATION:
|
||||
return None
|
||||
|
||||
result = self.overlay_manager.switch_navigation_tab(new_tab)
|
||||
return result if result else self.get_current_page()
|
||||
|
||||
def close_overlay(self) -> Optional[Image.Image]:
|
||||
"""
|
||||
Close the current overlay and return to reading view.
|
||||
|
||||
Reference in New Issue
Block a user