Add painting overlay

This commit is contained in:
2025-07-25 19:37:29 +02:00
parent 0459e19a5f
commit 5d412f54c0

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_drawing_board/flutter_drawing_board.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:pdfrx/pdfrx.dart'; import 'package:pdfrx/pdfrx.dart';
import 'package:sheetless/api.dart'; import 'package:sheetless/api.dart';
@@ -27,6 +28,7 @@ class _SheetViewerPageState extends State<SheetViewerPage> {
late Future<bool> documentLoaded; late Future<bool> documentLoaded;
PdfDocument? document; PdfDocument? document;
bool twoPageMode = true; bool twoPageMode = true;
bool paintMode = false;
@override @override
void initState() { void initState() {
@@ -82,85 +84,149 @@ class _SheetViewerPageState extends State<SheetViewerPage> {
return Stack( return Stack(
children: [ children: [
Container( Stack(
alignment: Alignment.bottomLeft, children: [
margin: EdgeInsets.all(10), Visibility(
child: FloatingActionButton( visible: !paintMode,
onPressed: () { child: GestureDetector(
setState(() { onTapUp: (TapUpDetails details) {
twoPageMode = !twoPageMode; // Get the size of the screen
}); final screenWidth = MediaQuery.of(context).size.width;
},
child: Icon(twoPageMode ? Icons.filter_1 : Icons.filter_2),
),
),
GestureDetector(
onTapUp: (TapUpDetails details) {
// Get the size of the screen
final screenWidth = MediaQuery.of(context).size.width;
// print("Touch at y = ${details.localPosition.dy}"); // print("Touch at y = ${details.localPosition.dy}");
// print("Touch at x = ${details.localPosition.dx}"); // print("Touch at x = ${details.localPosition.dx}");
// print("Screenwidth = ${screenWidth}"); // print("Screenwidth = ${screenWidth}");
// Check where the user tapped // Check where the user tapped
// if (details.localPosition.dy < 100) { // if (details.localPosition.dy < 100) {
// TODO // TODO
// setState(() { // setState(() {
// toggleFullscreen(); // toggleFullscreen();
// }); // });
if (details.localPosition.dx < screenWidth / 2) { if (details.localPosition.dx < screenWidth / 2) {
// Left half of the screen // Left half of the screen
setState(() { setState(() {
page = page > 1 ? page - 1 : 1; page = page > 1 ? page - 1 : 1;
}); });
} else { } else {
// Right half of the screen // Right half of the screen
setState(() { setState(() {
page = page < numPages ? page + 1 : numPages; page = page < numPages ? page + 1 : numPages;
}); });
} }
}, },
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
children: [
PdfPageView(
key: ValueKey(page),
document: document,
pageNumber: page,
alignment: Alignment.center,
),
Positioned.fill(
child: Container(
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 5),
child: Text('$page / $numPages'),
),
),
],
),
Visibility(
visible: twoPageMode == true,
child: Stack(
children: [ children: [
PdfPageView( Stack(
key: ValueKey(page), children: [
document: document, PdfPageView(
pageNumber: page + 1, key: ValueKey(page),
// alignment: Alignment.center, document: document,
pageNumber: page,
maximumDpi: 300,
),
Positioned.fill(
child: Container(
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 5),
child: Text('$page / $numPages'),
),
),
],
), ),
Positioned.fill( Visibility(
child: Container( visible: twoPageMode == true,
alignment: Alignment.bottomCenter, child: Stack(
padding: EdgeInsets.only(bottom: 5), children: [
child: Text('${page + 1} / $numPages'), PdfPageView(
key: ValueKey(page),
document: document,
pageNumber: page + 1,
maximumDpi: 300,
// alignment: Alignment.center,
),
Positioned.fill(
child: Container(
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 5),
child: Text('${page + 1} / $numPages'),
),
),
],
), ),
), ),
], ],
), ),
), ),
),
// Positioned.fill(
Visibility(
visible: paintMode,
child: SizedBox.expand(
child: LayoutBuilder(
builder: (context, constraints) {
return DrawingBoard(
background: SizedBox(
width: calcScaledPageWidth(
constraints.maxHeight,
document!.pages.elementAt(page).size,
),
height: constraints.maxHeight,
child: PdfPageView(
document: document,
pageNumber: page,
alignment: Alignment.center,
),
),
// showDefaultTools: true,
// showDefaultActions: true,
boardConstrained: true,
minScale: 1,
maxScale: 3,
alignment: Alignment.topRight,
boardBoundaryMargin: EdgeInsets.all(0),
);
},
),
),
),
],
),
Container(
alignment: Alignment.bottomLeft,
margin: EdgeInsets.all(10),
child: Column(
spacing: 10,
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () {
setState(() {
if (twoPageMode) {
// TODO: notification that paint mode only in single page mode
} else {
paintMode = !paintMode;
}
});
},
child: Icon(Icons.brush),
),
FloatingActionButton(
onPressed: () {
setState(() {
twoPageMode = !twoPageMode;
if (twoPageMode) {
paintMode = false;
// TODO: notification that paint mode was deactivated since only possible in single page mode
}
});
},
child: Icon(
twoPageMode ? Icons.filter_1 : Icons.filter_2,
),
),
], ],
), ),
), ),
@@ -183,4 +249,8 @@ class _SheetViewerPageState extends State<SheetViewerPage> {
), ),
); );
} }
double calcScaledPageWidth(double parentHeight, Size pageSize) {
return parentHeight * pageSize.width / pageSize.height;
}
} }