213 lines
6.8 KiB
Python
Executable File
213 lines
6.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Demo: Accelerometer-based Page Flipping
|
|
|
|
This example demonstrates how to use the accelerometer for hands-free
|
|
page turning by tilting the device forward or backward.
|
|
|
|
Features:
|
|
- Tilt device forward to advance to next page
|
|
- Tilt device backward to go to previous page
|
|
- Touch gestures still work normally
|
|
- Configurable tilt threshold and debounce time
|
|
|
|
Prerequisites:
|
|
1. Run calibration first: python examples/calibrate_accelerometer.py
|
|
2. This creates accelerometer_config.json with calibration data
|
|
|
|
Usage:
|
|
python examples/demo_accelerometer_page_flip.py <epub_file>
|
|
"""
|
|
|
|
import asyncio
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Add parent directory to path for imports
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from dreader.hal_hardware import HardwareDisplayHAL
|
|
from dreader.application import EbookReader
|
|
from dreader.gesture import GestureType
|
|
|
|
|
|
class AccelerometerPageFlipDemo:
|
|
"""Demo application with accelerometer-based page flipping"""
|
|
|
|
def __init__(self, epub_path: str):
|
|
self.epub_path = epub_path
|
|
|
|
# Create HAL with accelerometer enabled
|
|
print("Initializing hardware HAL...")
|
|
self.hal = HardwareDisplayHAL(
|
|
width=1872,
|
|
height=1404,
|
|
enable_orientation=True,
|
|
enable_rtc=False,
|
|
enable_power_monitor=False,
|
|
virtual_display=False # Set to True for testing without hardware
|
|
)
|
|
|
|
# Create reader
|
|
print("Creating ebook reader...")
|
|
self.reader = EbookReader(
|
|
page_size=(self.hal.width, self.hal.height),
|
|
margin=60
|
|
)
|
|
|
|
self.running = False
|
|
|
|
async def run(self):
|
|
"""Run the demo application"""
|
|
print("\n" + "="*60)
|
|
print("Accelerometer Page Flip Demo")
|
|
print("="*60)
|
|
|
|
# Initialize HAL
|
|
await self.hal.initialize()
|
|
|
|
# Load accelerometer calibration
|
|
print("\nLoading accelerometer calibration...")
|
|
calibrated = self.hal.load_accelerometer_calibration("accelerometer_config.json")
|
|
|
|
if not calibrated:
|
|
print("\nWARNING: Accelerometer not calibrated!")
|
|
print("Please run: python examples/calibrate_accelerometer.py")
|
|
print("\nProceeding with touch gestures only...\n")
|
|
else:
|
|
print("Accelerometer calibration loaded successfully!")
|
|
print(f" Up vector: {self.hal.accel_up_vector}")
|
|
print(f" Tilt threshold: {self.hal.accel_tilt_threshold:.2f} rad")
|
|
print(f" Debounce time: {self.hal.accel_debounce_time:.2f}s")
|
|
|
|
# Load EPUB
|
|
print(f"\nLoading EPUB: {self.epub_path}")
|
|
success = self.reader.load_epub(self.epub_path)
|
|
|
|
if not success:
|
|
print(f"ERROR: Failed to load {self.epub_path}")
|
|
await self.hal.cleanup()
|
|
return
|
|
|
|
print(f"Loaded: {self.reader.book_title}")
|
|
print(f"Author: {self.reader.book_author}")
|
|
|
|
# Display first page
|
|
print("\nDisplaying first page...")
|
|
img = self.reader.get_current_page()
|
|
await self.hal.show_image(img)
|
|
|
|
# Instructions
|
|
print("\n" + "="*60)
|
|
print("Controls:")
|
|
print(" - Tilt FORWARD to go to next page")
|
|
print(" - Tilt BACKWARD to go to previous page")
|
|
print(" - Swipe LEFT for next page (touch)")
|
|
print(" - Swipe RIGHT for previous page (touch)")
|
|
print(" - Long press to exit")
|
|
print("="*60 + "\n")
|
|
|
|
# Main event loop
|
|
self.running = True
|
|
try:
|
|
await self.event_loop()
|
|
finally:
|
|
await self.hal.cleanup()
|
|
print("\nDemo finished!")
|
|
|
|
async def event_loop(self):
|
|
"""Main event loop - poll for touch and accelerometer events"""
|
|
accel_poll_interval = 0.05 # Check accelerometer every 50ms
|
|
|
|
while self.running:
|
|
# Check for touch events
|
|
touch_event = await self.hal.get_touch_event()
|
|
if touch_event:
|
|
await self.handle_event(touch_event)
|
|
|
|
# Check for accelerometer tilt events (if calibrated)
|
|
if hasattr(self.hal, 'accel_up_vector'):
|
|
tilt_event = await self.hal.get_tilt_gesture()
|
|
if tilt_event:
|
|
await self.handle_event(tilt_event)
|
|
|
|
# Small delay to avoid busy-waiting
|
|
await asyncio.sleep(accel_poll_interval)
|
|
|
|
async def handle_event(self, event):
|
|
"""Handle a gesture event (touch or accelerometer)"""
|
|
gesture = event.gesture
|
|
print(f"Gesture: {gesture.value}")
|
|
|
|
# Navigation gestures
|
|
if gesture in [GestureType.SWIPE_LEFT, GestureType.TILT_FORWARD]:
|
|
await self.next_page()
|
|
|
|
elif gesture in [GestureType.SWIPE_RIGHT, GestureType.TILT_BACKWARD]:
|
|
await self.previous_page()
|
|
|
|
# Exit on long press
|
|
elif gesture == GestureType.LONG_PRESS:
|
|
print("\nLong press detected - exiting...")
|
|
self.running = False
|
|
|
|
# Word tap
|
|
elif gesture == GestureType.TAP:
|
|
# You could implement word selection here
|
|
print(f" Tap at ({event.x}, {event.y})")
|
|
|
|
async def next_page(self):
|
|
"""Go to next page"""
|
|
img = self.reader.next_page()
|
|
if img:
|
|
progress = self.reader.get_reading_progress()
|
|
chapter = self.reader.get_current_chapter_info()
|
|
print(f" -> Next page ({progress['percent']:.1f}% - {chapter['title']})")
|
|
await self.hal.show_image(img)
|
|
else:
|
|
print(" -> At end of book")
|
|
|
|
async def previous_page(self):
|
|
"""Go to previous page"""
|
|
img = self.reader.previous_page()
|
|
if img:
|
|
progress = self.reader.get_reading_progress()
|
|
chapter = self.reader.get_current_chapter_info()
|
|
print(f" -> Previous page ({progress['percent']:.1f}% - {chapter['title']})")
|
|
await self.hal.show_image(img)
|
|
else:
|
|
print(" -> At start of book")
|
|
|
|
|
|
async def main():
|
|
"""Main entry point"""
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python demo_accelerometer_page_flip.py <epub_file>")
|
|
print("\nExample:")
|
|
print(" python demo_accelerometer_page_flip.py ~/Books/mybook.epub")
|
|
sys.exit(1)
|
|
|
|
epub_path = sys.argv[1]
|
|
|
|
# Check if file exists
|
|
if not Path(epub_path).exists():
|
|
print(f"ERROR: File not found: {epub_path}")
|
|
sys.exit(1)
|
|
|
|
# Run demo
|
|
demo = AccelerometerPageFlipDemo(epub_path)
|
|
await demo.run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
asyncio.run(main())
|
|
except KeyboardInterrupt:
|
|
print("\nDemo interrupted by user")
|
|
sys.exit(0)
|
|
except Exception as e:
|
|
print(f"\nError: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|