Complete refactor to clean up project

This commit is contained in:
2026-02-04 11:36:02 +01:00
parent 4f380b5444
commit 704bd0b928
29 changed files with 2057 additions and 1464 deletions

View File

@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import '../../../core/models/config.dart';
import 'pdf_page_display.dart';
/// Callback for page turn events.
typedef PageTurnCallback = void Function(int delta);
/// Gesture layer for touch-based navigation over PDF pages.
///
/// Touch zones:
/// - Top 2cm: Toggle fullscreen (or exit if in fullscreen + top-right corner)
/// - Left side: Turn page backward (-1 or -2 in two-page mode)
/// - Right side: Turn page forward (+1 or +2 in two-page mode)
class TouchNavigationLayer extends StatelessWidget {
final PdfPageDisplay pageDisplay;
final Config config;
final VoidCallback onToggleFullscreen;
final VoidCallback onExit;
final PageTurnCallback onPageTurn;
const TouchNavigationLayer({
super.key,
required this.pageDisplay,
required this.config,
required this.onToggleFullscreen,
required this.onExit,
required this.onPageTurn,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapUp: (details) => _handleTap(context, details),
child: pageDisplay,
);
}
void _handleTap(BuildContext context, TapUpDetails details) {
final mediaQuery = MediaQuery.of(context);
final position = details.localPosition;
// Calculate physical measurements for consistent touch zones
final pixelsPerCm = _calculatePixelsPerCm(mediaQuery.devicePixelRatio);
final touchZoneHeight = 2 * pixelsPerCm;
final touchZoneWidth = 2 * pixelsPerCm;
final screenWidth = mediaQuery.size.width;
final screenCenter = screenWidth / 2;
// Get page sizes for accurate touch zone calculation
final (leftPageSize, rightPageSize) = pageDisplay.calculateScaledPageSizes(
mediaQuery.size,
);
// Check top zone first
if (position.dy < touchZoneHeight) {
_handleTopZoneTap(position, screenWidth, touchZoneWidth);
return;
}
// Handle page turning based on tap position
_handlePageTurnTap(position, screenCenter, leftPageSize, rightPageSize);
}
void _handleTopZoneTap(
Offset position,
double screenWidth,
double touchZoneWidth,
) {
// Top-right corner in fullscreen mode = exit
if (config.fullscreen && position.dx >= screenWidth - touchZoneWidth) {
onExit();
} else {
onToggleFullscreen();
}
}
void _handlePageTurnTap(
Offset position,
double screenCenter,
Size leftPageSize,
Size? rightPageSize,
) {
final isLeftSide = position.dx < screenCenter;
if (config.twoPageMode) {
_handleTwoPageModeTap(
position,
screenCenter,
leftPageSize,
rightPageSize,
);
} else {
// Single page mode: simple left/right
onPageTurn(isLeftSide ? -1 : 1);
}
}
void _handleTwoPageModeTap(
Offset position,
double screenCenter,
Size leftPageSize,
Size? rightPageSize,
) {
final leftEdge = screenCenter - leftPageSize.width / 2;
final rightEdge = screenCenter + (rightPageSize?.width ?? 0) / 2;
if (position.dx < leftEdge) {
onPageTurn(-2);
} else if (position.dx < screenCenter) {
onPageTurn(-1);
} else if (position.dx > rightEdge) {
onPageTurn(2);
} else {
onPageTurn(1);
}
}
double _calculatePixelsPerCm(double devicePixelRatio) {
const baseDpi = 160.0; // Android baseline DPI
const cmPerInch = 2.54;
return (devicePixelRatio * baseDpi) / cmPerInch;
}
}