Complete refactor to clean up project
This commit is contained in:
137
lib/features/sheet_viewer/widgets/pdf_page_display.dart
Normal file
137
lib/features/sheet_viewer/widgets/pdf_page_display.dart
Normal file
@@ -0,0 +1,137 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pdfrx/pdfrx.dart';
|
||||
|
||||
import '../../../core/models/config.dart';
|
||||
|
||||
/// Displays PDF pages with optional two-page mode.
|
||||
class PdfPageDisplay extends StatelessWidget {
|
||||
final PdfDocument document;
|
||||
final int numPages;
|
||||
final int currentPageNumber;
|
||||
final Config config;
|
||||
|
||||
const PdfPageDisplay({
|
||||
super.key,
|
||||
required this.document,
|
||||
required this.numPages,
|
||||
required this.currentPageNumber,
|
||||
required this.config,
|
||||
});
|
||||
|
||||
/// Whether two-page mode is active and we have enough pages.
|
||||
bool get _showTwoPages => config.twoPageMode && numPages >= 2;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [_buildLeftPage(), if (_showTwoPages) _buildRightPage()],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLeftPage() {
|
||||
return Expanded(
|
||||
child: Stack(
|
||||
children: [
|
||||
PdfPageView(
|
||||
key: ValueKey(currentPageNumber),
|
||||
document: document,
|
||||
pageNumber: currentPageNumber,
|
||||
maximumDpi: 300,
|
||||
alignment: _showTwoPages ? Alignment.centerRight : Alignment.center,
|
||||
),
|
||||
_buildPageIndicator(currentPageNumber),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildRightPage() {
|
||||
final rightPageNumber = currentPageNumber + 1;
|
||||
|
||||
return Expanded(
|
||||
child: Stack(
|
||||
children: [
|
||||
PdfPageView(
|
||||
key: ValueKey(rightPageNumber),
|
||||
document: document,
|
||||
pageNumber: rightPageNumber,
|
||||
maximumDpi: 300,
|
||||
alignment: Alignment.centerLeft,
|
||||
),
|
||||
_buildPageIndicator(rightPageNumber),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPageIndicator(int pageNumber) {
|
||||
return Positioned.fill(
|
||||
child: Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
padding: const EdgeInsets.only(bottom: 5),
|
||||
child: Text('$pageNumber / $numPages'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Page Size Calculations
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Calculates scaled page sizes for the current view.
|
||||
///
|
||||
/// Returns a tuple of (leftPageSize, rightPageSize).
|
||||
/// rightPageSize is null when not in two-page mode.
|
||||
(Size, Size?) calculateScaledPageSizes(Size parentSize) {
|
||||
if (config.twoPageMode) {
|
||||
return _calculateTwoPageSizes(parentSize);
|
||||
}
|
||||
return (_calculateSinglePageSize(parentSize), null);
|
||||
}
|
||||
|
||||
(Size, Size?) _calculateTwoPageSizes(Size parentSize) {
|
||||
final leftSize = _getUnscaledPageSize(currentPageNumber);
|
||||
final rightSize = numPages > currentPageNumber
|
||||
? _getUnscaledPageSize(currentPageNumber + 1)
|
||||
: leftSize;
|
||||
|
||||
// Combine pages for scaling calculation
|
||||
final combinedSize = Size(
|
||||
leftSize.width + rightSize.width,
|
||||
max(leftSize.height, rightSize.height),
|
||||
);
|
||||
|
||||
final scaledCombined = _scaleToFit(parentSize, combinedSize);
|
||||
final scaleFactor = scaledCombined.width / combinedSize.width;
|
||||
|
||||
return (leftSize * scaleFactor, rightSize * scaleFactor);
|
||||
}
|
||||
|
||||
Size _calculateSinglePageSize(Size parentSize) {
|
||||
return _scaleToFit(parentSize, _getUnscaledPageSize(currentPageNumber));
|
||||
}
|
||||
|
||||
Size _getUnscaledPageSize(int pageNumber) {
|
||||
return document.pages.elementAt(pageNumber - 1).size;
|
||||
}
|
||||
|
||||
/// Scales a page size to fit within parent bounds while maintaining aspect ratio.
|
||||
Size _scaleToFit(Size parentSize, Size pageSize) {
|
||||
// Determine if height or width is the limiting factor
|
||||
if (parentSize.aspectRatio > pageSize.aspectRatio) {
|
||||
// Constrained by height
|
||||
final height = parentSize.height;
|
||||
final width = height * pageSize.aspectRatio;
|
||||
return Size(width, height);
|
||||
} else {
|
||||
// Constrained by width
|
||||
final width = parentSize.width;
|
||||
final height = width / pageSize.aspectRatio;
|
||||
return Size(width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user