diff --git a/app/lib/cubits/current_index.dart b/app/lib/cubits/current_index.dart index fc221f5b07ec..8bfb42cea868 100644 --- a/app/lib/cubits/current_index.dart +++ b/app/lib/cubits/current_index.dart @@ -625,6 +625,7 @@ class CurrentIndexCubit extends Cubit { Future renderPDF( NoteData document, DocumentInfo info, { + DocumentState? state, required List areas, bool renderBackground = true, }) async { @@ -632,7 +633,9 @@ class CurrentIndexCubit extends Cubit { for (final preset in areas) { final areaName = preset.name; final quality = preset.quality; - final page = document.getPage(preset.page); + final page = state?.pageName == preset.page + ? state?.page + : document.getPage(preset.page); final area = preset.area ?? page?.getAreaByName(areaName); if (area == null || page == null) { continue; diff --git a/app/lib/dialogs/export/pdf.dart b/app/lib/dialogs/export/pdf.dart index 6e1790c54a0f..c6c2436fb63c 100644 --- a/app/lib/dialogs/export/pdf.dart +++ b/app/lib/dialogs/export/pdf.dart @@ -75,15 +75,17 @@ class _PdfExportDialogState extends State { ), IconButton( onPressed: () async { - final result = await showDialog<(String, String)>( + final result = await showDialog<(String, Area)>( context: context, - builder: (context) => - _AreaSelectionDialog(document: state.data), + builder: (_) => BlocProvider.value( + value: context.read(), + child: _AreaSelectionDialog(document: state.data), + ), ); if (result != null) { final (page, area) = result; setState(() { - areas.add(AreaPreset(name: area, page: page)); + areas.add(AreaPreset(name: area.name, page: page)); }); } }, @@ -96,77 +98,83 @@ class _PdfExportDialogState extends State { child: Padding( padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 15), - child: Column(mainAxisSize: MainAxisSize.min, children: [ - Flexible( - child: SingleChildScrollView( - child: Wrap( - alignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - children: areas.mapIndexed((i, e) { - final area = - e.area ?? state.page.getAreaByName(e.name); - if (area == null) { - return Container(); - } - return FutureBuilder( - future: currentIndex.render( - state.data, state.page, state.info, - width: area.width, - height: area.height, - quality: e.quality, - x: area.position.x, - y: area.position.y), - builder: (context, snapshot) => _AreaPreview( - area: area, - quality: e.quality, - onRemove: () { - setState(() { - areas.removeAt(i); - }); - }, - onQualityChanged: (value) { - setState(() { - areas[i] = e.copyWith(quality: value); - }); - }, - image: snapshot.data?.buffer.asUint8List(), - ), - ); - }).toList(), - ), - ), - ), - const Divider(), - Row( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Expanded(child: Container()), - TextButton( - child: Text(AppLocalizations.of(context).cancel), - onPressed: () => Navigator.of(context).pop(), + Flexible( + child: SingleChildScrollView( + child: Wrap( + alignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + children: areas.mapIndexed((i, e) { + final area = e.area ?? + state.page.getAreaByName(e.name); + if (area == null) { + return Container(); + } + return FutureBuilder( + future: currentIndex.render( + state.data, state.page, state.info, + width: area.width, + height: area.height, + quality: e.quality, + x: area.position.x, + y: area.position.y), + builder: (context, snapshot) => + _AreaPreview( + area: area, + quality: e.quality, + onRemove: () { + setState(() { + areas.removeAt(i); + }); + }, + onQualityChanged: (value) { + setState(() { + areas[i] = e.copyWith(quality: value); + }); + }, + image: + snapshot.data?.buffer.asUint8List(), + ), + ); + }).toList(), + ), + ), ), - ElevatedButton( - child: Text(widget.print - ? AppLocalizations.of(context).print - : AppLocalizations.of(context).export), - onPressed: () async { - Future getBytes() async => - (await currentIndex.renderPDF( - state.data, state.info, - areas: areas)) - .save(); - Navigator.of(context).pop(); - if (widget.print) { - Printing.layoutPdf( - onLayout: (_) => getBytes(), - ); - return; - } - exportPdf(context, await getBytes()); - }, - ), - ], - ) - ]), + const Divider(), + Row( + children: [ + Expanded(child: Container()), + TextButton( + child: + Text(AppLocalizations.of(context).cancel), + onPressed: () => Navigator.of(context).pop(), + ), + ElevatedButton( + child: Text(widget.print + ? AppLocalizations.of(context).print + : AppLocalizations.of(context).export), + onPressed: () async { + Future getBytes() async => + (await currentIndex.renderPDF( + state.data, state.info, + areas: areas, state: state)) + .save(); + Navigator.of(context).pop(); + if (widget.print) { + Printing.layoutPdf( + onLayout: (_) => getBytes(), + ); + return; + } + exportPdf(context, await getBytes()); + }, + ), + ], + ) + ]), ), ), ]); @@ -255,28 +263,34 @@ class _AreaSelectionDialogState extends State<_AreaSelectionDialog> { ), ), Flexible( - child: Column( - mainAxisSize: MainAxisSize.min, - children: widget.document - .getPages() - .expand( - (page) => - widget.document - .getPage(page) - ?.areas - .where((element) => - element.name.contains(_searchQuery)) - .map((e) { - return ListTile( - title: Text(e.name), - subtitle: Text(page), - onTap: () => Navigator.of(context).pop((page, e)), - ); - }).toList() ?? - [], - ) - .toList(), - ), + child: BlocBuilder( + buildWhen: (previous, current) => + previous.page != current.page || + previous.pageName != current.pageName, + builder: (context, state) => Column( + mainAxisSize: MainAxisSize.min, + children: widget.document + .getPages() + .expand( + (page) => + (page == state.pageName + ? state.page + : widget.document.getPage(page)) + ?.areas + .where((element) => + element.name.contains(_searchQuery)) + .map((e) { + return ListTile( + title: Text(e.name), + subtitle: Text(page), + onTap: () => + Navigator.of(context).pop((page, e)), + ); + }).toList() ?? + [], + ) + .toList(), + )), ), Padding( padding: const EdgeInsets.all(8.0), diff --git a/app/lib/handlers/area.dart b/app/lib/handlers/area.dart index 5491294f404e..068446e48458 100644 --- a/app/lib/handlers/area.dart +++ b/app/lib/handlers/area.dart @@ -62,15 +62,32 @@ class AreaHandler extends Handler { void onScaleUpdate(ScaleUpdateDetails details, EventContext context) { final currentIndex = context.getCurrentIndex(); if (details.pointerCount > 1 || - currentIndex.buttons == kSecondaryMouseButton) { + currentIndex.buttons == kSecondaryMouseButton || + start == null) { currentRect = null; context.refresh(); return; } - final globalPosition = + var end = context.getCameraTransform().localToGlobal(details.localFocalPoint); - - end = globalPosition; + if (data.constrainedWidth != 0) { + end = Offset(data.constrainedWidth + start!.dx, end.dy); + } + if (data.constrainedHeight != 0) { + end = Offset(end.dx, data.constrainedHeight + start!.dy); + } + if (data.constrainedAspectRatio != 0) { + final aspectRatio = data.constrainedAspectRatio; + final width = end.dx - start!.dx; + final height = end.dy - start!.dy; + final currentAspectRatio = width / height; + if (currentAspectRatio < aspectRatio) { + end = Offset(start!.dx + height * aspectRatio, end.dy); + } else { + end = Offset(end.dx, start!.dy + width / aspectRatio); + } + } + currentRect = Rect.fromPoints(start!, end); context.refresh(); }