feat: add zoom level listener and scroll thumbs to PDF viewer

This commit is contained in:
insleker 2025-09-17 17:03:07 +08:00
parent 994c1b2569
commit 6652de28bf
3 changed files with 95 additions and 7 deletions

View File

@ -237,4 +237,6 @@ void main() {
await tester.pumpAndSettle();
expect(container.read(pdfViewModelProvider), 2);
});
//TODO: Scroll Thumbs
}

View File

@ -1,4 +1,3 @@
import 'dart:typed_data';
import 'package:file_selector/file_selector.dart' as fs;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -197,11 +196,37 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
return name;
}
void _onControllerChanged() {
if (mounted) {
if (_viewModel.controller.isReady) {
final newZoomLevel = (_viewModel.controller.currentZoom * 100)
.round()
.clamp(10, 800);
if (newZoomLevel != _zoomLevel) {
setState(() {
_zoomLevel = newZoomLevel;
});
}
} else {
// Reset to default zoom level when controller is not ready
if (_zoomLevel != 100) {
setState(() {
_zoomLevel = 100;
});
}
}
}
}
@override
void initState() {
super.initState();
// Build areas once with builders; keep these instances stable.
_viewModel = ref.read(pdfViewModelProvider.notifier);
// Add listener to update zoom level when controller zoom changes
_viewModel.controller.addListener(_onControllerChanged);
_areas = [
Area(
size: _lastPagesWidth,
@ -270,6 +295,7 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
@override
void dispose() {
_viewModel.controller.removeListener(_onControllerChanged);
_splitController.dispose();
super.dispose();
}
@ -323,14 +349,36 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
onClosePdf: _closePdf,
onJumpToPage: _jumpToPage,
onZoomOut: () {
if (_viewModel.controller.isReady) {
_viewModel.controller.zoomDown();
// Update display zoom level after controller zoom
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
setState(() {
_zoomLevel = (_zoomLevel - 10).clamp(10, 800);
_zoomLevel = (_viewModel.controller.currentZoom *
100)
.round()
.clamp(10, 800);
});
}
});
}
},
onZoomIn: () {
if (_viewModel.controller.isReady) {
_viewModel.controller.zoomUp();
// Update display zoom level after controller zoom
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
setState(() {
_zoomLevel = (_zoomLevel + 10).clamp(10, 800);
_zoomLevel = (_viewModel.controller.currentZoom *
100)
.round()
.clamp(10, 800);
});
}
});
}
},
zoomLevel: _zoomLevel,
filePath: widget.currentFile.path,

View File

@ -126,6 +126,44 @@ class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> {
onClearActiveOverlay: widget.onClearActiveOverlay,
onSelectPlaced: widget.onSelectPlaced,
),
// Vertical scroll thumb on the right
PdfViewerScrollThumb(
controller: widget.controller,
orientation: ScrollbarOrientation.right,
thumbSize: const Size(40, 25),
thumbBuilder:
(context, thumbSize, pageNumber, controller) => Container(
color: Colors.black.withValues(alpha: 0.7),
child: Center(
child: Text(
pageNumber.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
),
),
),
),
// Horizontal scroll thumb on the bottom
PdfViewerScrollThumb(
controller: widget.controller,
orientation: ScrollbarOrientation.bottom,
thumbSize: const Size(40, 25),
thumbBuilder:
(context, thumbSize, pageNumber, controller) => Container(
color: Colors.black.withValues(alpha: 0.7),
child: Center(
child: Text(
pageNumber.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
),
),
),
),
];
},
),