feat: found root cause of slow image process is store them in bytes rather than image object
This commit is contained in:
parent
8daf5ea3ca
commit
81a352a513
|
|
@ -18,7 +18,7 @@ class SignatureCard {
|
||||||
});
|
});
|
||||||
|
|
||||||
SignatureCard copyWith({
|
SignatureCard copyWith({
|
||||||
double? rotationDeg,
|
double? rotationDeg, //z axis is out of the screen, positive is CCW
|
||||||
SignatureAsset? asset,
|
SignatureAsset? asset,
|
||||||
GraphicAdjust? graphicAdjust,
|
GraphicAdjust? graphicAdjust,
|
||||||
}) => SignatureCard(
|
}) => SignatureCard(
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@ class _DrawCanvasState extends State<DrawCanvas> {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
// Export signature to PNG bytes first
|
// Export signature to PNG bytes first
|
||||||
final byteData = await _control.toImage(
|
final byteData = await _control.toImage(
|
||||||
width: 1024,
|
width: 512,
|
||||||
height: 512,
|
height: 256,
|
||||||
fit: true,
|
fit: true,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
background: Colors.transparent,
|
background: Colors.transparent,
|
||||||
|
|
|
||||||
|
|
@ -11,21 +11,10 @@ class PdfPageArea extends ConsumerStatefulWidget {
|
||||||
const PdfPageArea({
|
const PdfPageArea({
|
||||||
super.key,
|
super.key,
|
||||||
required this.pageSize,
|
required this.pageSize,
|
||||||
required this.onDragSignature,
|
|
||||||
required this.onResizeSignature,
|
|
||||||
required this.onConfirmSignature,
|
|
||||||
required this.onClearActiveOverlay,
|
|
||||||
required this.onSelectPlaced,
|
|
||||||
required this.controller,
|
required this.controller,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Size pageSize;
|
final Size pageSize;
|
||||||
// viewerController removed in migration
|
|
||||||
final ValueChanged<Offset> onDragSignature;
|
|
||||||
final ValueChanged<Offset> onResizeSignature;
|
|
||||||
final VoidCallback onConfirmSignature;
|
|
||||||
final VoidCallback onClearActiveOverlay;
|
|
||||||
final ValueChanged<int?> onSelectPlaced;
|
|
||||||
final PdfViewerController controller;
|
final PdfViewerController controller;
|
||||||
@override
|
@override
|
||||||
ConsumerState<PdfPageArea> createState() => _PdfPageAreaState();
|
ConsumerState<PdfPageArea> createState() => _PdfPageAreaState();
|
||||||
|
|
@ -156,11 +145,6 @@ class _PdfPageAreaState extends ConsumerState<PdfPageArea> {
|
||||||
if (isContinuous) {
|
if (isContinuous) {
|
||||||
return PdfViewerWidget(
|
return PdfViewerWidget(
|
||||||
pageSize: widget.pageSize,
|
pageSize: widget.pageSize,
|
||||||
onDragSignature: widget.onDragSignature,
|
|
||||||
onResizeSignature: widget.onResizeSignature,
|
|
||||||
onConfirmSignature: widget.onConfirmSignature,
|
|
||||||
onClearActiveOverlay: widget.onClearActiveOverlay,
|
|
||||||
onSelectPlaced: widget.onSelectPlaced,
|
|
||||||
pageKeyBuilder: _pageKey,
|
pageKeyBuilder: _pageKey,
|
||||||
scrollToPage: _scrollToPage,
|
scrollToPage: _scrollToPage,
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
|
|
|
||||||
|
|
@ -109,22 +109,6 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _confirmSignature() {
|
|
||||||
// In simplified UI, confirmation is a no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onDragSignature(Offset delta) {
|
|
||||||
// In simplified UI, interactive overlay disabled
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onResizeSignature(Offset delta) {
|
|
||||||
// In simplified UI, interactive overlay disabled
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onSelectPlaced(int? index) {
|
|
||||||
// In simplified UI, selection is a no-op for tests
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List?> _openDrawCanvas() async {
|
Future<Uint8List?> _openDrawCanvas() async {
|
||||||
final result = await showModalBottomSheet<Uint8List>(
|
final result = await showModalBottomSheet<Uint8List>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -323,11 +307,6 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
|
||||||
controller: _viewModel.controller,
|
controller: _viewModel.controller,
|
||||||
key: const ValueKey('pdf_page_area'),
|
key: const ValueKey('pdf_page_area'),
|
||||||
pageSize: _pageSize,
|
pageSize: _pageSize,
|
||||||
onDragSignature: _onDragSignature,
|
|
||||||
onResizeSignature: _onResizeSignature,
|
|
||||||
onConfirmSignature: _confirmSignature,
|
|
||||||
onClearActiveOverlay: () {},
|
|
||||||
onSelectPlaced: _onSelectPlaced,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,12 @@ class PdfViewerWidget extends ConsumerStatefulWidget {
|
||||||
const PdfViewerWidget({
|
const PdfViewerWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.pageSize,
|
required this.pageSize,
|
||||||
required this.onDragSignature,
|
|
||||||
required this.onResizeSignature,
|
|
||||||
required this.onConfirmSignature,
|
|
||||||
required this.onClearActiveOverlay,
|
|
||||||
required this.onSelectPlaced,
|
|
||||||
this.pageKeyBuilder,
|
this.pageKeyBuilder,
|
||||||
this.scrollToPage,
|
this.scrollToPage,
|
||||||
required this.controller,
|
required this.controller,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Size pageSize;
|
final Size pageSize;
|
||||||
final ValueChanged<Offset> onDragSignature;
|
|
||||||
final ValueChanged<Offset> onResizeSignature;
|
|
||||||
final VoidCallback onConfirmSignature;
|
|
||||||
final VoidCallback onClearActiveOverlay;
|
|
||||||
final ValueChanged<int?> onSelectPlaced;
|
|
||||||
final GlobalKey Function(int page)? pageKeyBuilder;
|
final GlobalKey Function(int page)? pageKeyBuilder;
|
||||||
final void Function(int page)? scrollToPage;
|
final void Function(int page)? scrollToPage;
|
||||||
final PdfViewerController controller;
|
final PdfViewerController controller;
|
||||||
|
|
@ -88,11 +78,6 @@ class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> {
|
||||||
widget.pageKeyBuilder ??
|
widget.pageKeyBuilder ??
|
||||||
(page) => GlobalKey(debugLabel: 'page_$page'),
|
(page) => GlobalKey(debugLabel: 'page_$page'),
|
||||||
scrollToPage: widget.scrollToPage ?? (page) {},
|
scrollToPage: widget.scrollToPage ?? (page) {},
|
||||||
onDragSignature: widget.onDragSignature,
|
|
||||||
onResizeSignature: widget.onResizeSignature,
|
|
||||||
onConfirmSignature: widget.onConfirmSignature,
|
|
||||||
onClearActiveOverlay: widget.onClearActiveOverlay,
|
|
||||||
onSelectPlaced: widget.onSelectPlaced,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,11 +148,6 @@ class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> {
|
||||||
PdfPageOverlays(
|
PdfPageOverlays(
|
||||||
pageSize: Size(pageRect.width, pageRect.height),
|
pageSize: Size(pageRect.width, pageRect.height),
|
||||||
pageNumber: page.pageNumber,
|
pageNumber: page.pageNumber,
|
||||||
onDragSignature: widget.onDragSignature,
|
|
||||||
onResizeSignature: widget.onResizeSignature,
|
|
||||||
onConfirmSignature: widget.onConfirmSignature,
|
|
||||||
onClearActiveOverlay: widget.onClearActiveOverlay,
|
|
||||||
onSelectPlaced: widget.onSelectPlaced,
|
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image/image.dart' as img;
|
|
||||||
import '../../../../utils/rotation_utils.dart' as rot;
|
import '../../../../utils/rotation_utils.dart' as rot;
|
||||||
|
|
||||||
/// A lightweight widget to render signature bytes with rotation and an
|
/// A lightweight widget to render signature bytes with rotation and an
|
||||||
/// angle-aware scale-to-fit so the rotated image stays within its bounds.
|
/// angle-aware scale-to-fit so the rotated image stays within its bounds.
|
||||||
|
/// Aware that `decodeImage` large images can be crazily slow, especially on web.
|
||||||
class RotatedSignatureImage extends StatefulWidget {
|
class RotatedSignatureImage extends StatefulWidget {
|
||||||
const RotatedSignatureImage({
|
const RotatedSignatureImage({
|
||||||
super.key,
|
super.key,
|
||||||
|
|
@ -12,6 +12,8 @@ class RotatedSignatureImage extends StatefulWidget {
|
||||||
this.rotationDeg = 0.0, // counterclockwise as positive
|
this.rotationDeg = 0.0, // counterclockwise as positive
|
||||||
this.filterQuality = FilterQuality.low,
|
this.filterQuality = FilterQuality.low,
|
||||||
this.semanticLabel,
|
this.semanticLabel,
|
||||||
|
this.cacheWidth,
|
||||||
|
this.cacheHeight,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Uint8List bytes;
|
final Uint8List bytes;
|
||||||
|
|
@ -22,6 +24,10 @@ class RotatedSignatureImage extends StatefulWidget {
|
||||||
final Alignment alignment = Alignment.center;
|
final Alignment alignment = Alignment.center;
|
||||||
final bool wrapInRepaintBoundary = true;
|
final bool wrapInRepaintBoundary = true;
|
||||||
final String? semanticLabel;
|
final String? semanticLabel;
|
||||||
|
// Hint the decoder to decode at a smaller size to reduce memory/latency.
|
||||||
|
// On some platforms these may be ignored, but they are safe no-ops.
|
||||||
|
final int? cacheWidth;
|
||||||
|
final int? cacheHeight;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<RotatedSignatureImage> createState() => _RotatedSignatureImageState();
|
State<RotatedSignatureImage> createState() => _RotatedSignatureImageState();
|
||||||
|
|
@ -67,16 +73,6 @@ class _RotatedSignatureImageState extends State<RotatedSignatureImage> {
|
||||||
_setAspectRatio(1.0); // safe fallback
|
_setAspectRatio(1.0); // safe fallback
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// One-time synchronous header decode to establish aspect ratio quickly.
|
|
||||||
// This only runs when bytes change (not on rotation), so it's acceptable.
|
|
||||||
try {
|
|
||||||
final decoded = img.decodeImage(widget.bytes);
|
|
||||||
if (decoded != null && decoded.width > 0 && decoded.height > 0) {
|
|
||||||
_setAspectRatio(decoded.width / decoded.height);
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
// ignore decode errors and rely on image stream listener
|
|
||||||
}
|
|
||||||
final stream = _provider.resolve(createLocalImageConfiguration(context));
|
final stream = _provider.resolve(createLocalImageConfiguration(context));
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
_listener = ImageStreamListener((ImageInfo info, bool sync) {
|
_listener = ImageStreamListener((ImageInfo info, bool sync) {
|
||||||
|
|
@ -113,6 +109,9 @@ class _RotatedSignatureImageState extends State<RotatedSignatureImage> {
|
||||||
filterQuality: widget.filterQuality,
|
filterQuality: widget.filterQuality,
|
||||||
alignment: widget.alignment,
|
alignment: widget.alignment,
|
||||||
semanticLabel: widget.semanticLabel,
|
semanticLabel: widget.semanticLabel,
|
||||||
|
// Provide at most one dimension to preserve aspect ratio if only one is set
|
||||||
|
cacheWidth: widget.cacheWidth,
|
||||||
|
cacheHeight: widget.cacheHeight,
|
||||||
isAntiAlias: false,
|
isAntiAlias: false,
|
||||||
errorBuilder: (context, error, stackTrace) {
|
errorBuilder: (context, error, stackTrace) {
|
||||||
// Return a placeholder for invalid images
|
// Return a placeholder for invalid images
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:pdf_signature/domain/models/model.dart' as domain;
|
import 'package:pdf_signature/domain/models/model.dart' as domain;
|
||||||
|
|
@ -7,15 +8,14 @@ import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||||
import '../view_model/signature_view_model.dart';
|
import '../view_model/signature_view_model.dart';
|
||||||
import '../view_model/dragging_signature_view_model.dart';
|
import '../view_model/dragging_signature_view_model.dart';
|
||||||
|
|
||||||
class SignatureCard extends ConsumerWidget {
|
class SignatureCardView extends ConsumerStatefulWidget {
|
||||||
const SignatureCard({
|
const SignatureCardView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.asset,
|
required this.asset,
|
||||||
required this.disabled,
|
required this.disabled,
|
||||||
required this.onDelete,
|
required this.onDelete,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.onAdjust,
|
this.onAdjust,
|
||||||
this.useCurrentBytesForDrag = false,
|
|
||||||
this.rotationDeg = 0.0,
|
this.rotationDeg = 0.0,
|
||||||
this.graphicAdjust = const domain.GraphicAdjust(),
|
this.graphicAdjust = const domain.GraphicAdjust(),
|
||||||
});
|
});
|
||||||
|
|
@ -24,9 +24,14 @@ class SignatureCard extends ConsumerWidget {
|
||||||
final VoidCallback onDelete;
|
final VoidCallback onDelete;
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
final VoidCallback? onAdjust;
|
final VoidCallback? onAdjust;
|
||||||
final bool useCurrentBytesForDrag;
|
|
||||||
final double rotationDeg;
|
final double rotationDeg;
|
||||||
final domain.GraphicAdjust graphicAdjust;
|
final domain.GraphicAdjust graphicAdjust;
|
||||||
|
@override
|
||||||
|
ConsumerState<SignatureCardView> createState() => _SignatureCardViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SignatureCardViewState extends ConsumerState<SignatureCardView> {
|
||||||
|
Uint8List? _lastBytesRef;
|
||||||
Future<void> _showContextMenu(BuildContext context, Offset position) async {
|
Future<void> _showContextMenu(BuildContext context, Offset position) async {
|
||||||
final selected = await showMenu<String>(
|
final selected = await showMenu<String>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -50,22 +55,40 @@ class SignatureCard extends ConsumerWidget {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
if (selected == 'adjust') {
|
if (selected == 'adjust') {
|
||||||
onAdjust?.call();
|
widget.onAdjust?.call();
|
||||||
} else if (selected == 'delete') {
|
} else if (selected == 'delete') {
|
||||||
onDelete();
|
widget.onDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _maybePrecache(Uint8List bytes) {
|
||||||
|
if (identical(_lastBytesRef, bytes)) return;
|
||||||
|
_lastBytesRef = bytes;
|
||||||
|
// Schedule after frame to avoid doing work during build.
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
// Use single-dimension hints to preserve aspect ratio.
|
||||||
|
final img128 = ResizeImage(MemoryImage(bytes), height: 128);
|
||||||
|
final img256 = ResizeImage(MemoryImage(bytes), height: 256);
|
||||||
|
precacheImage(img128, context);
|
||||||
|
precacheImage(img256, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final displayData = ref
|
final displayData = ref
|
||||||
.watch(signatureViewModelProvider)
|
.watch(signatureViewModelProvider)
|
||||||
.getDisplaySignatureData(asset, graphicAdjust);
|
.getDisplaySignatureData(widget.asset, widget.graphicAdjust);
|
||||||
|
_maybePrecache(displayData.bytes);
|
||||||
// Fit inside 96x64 with 6px padding using the shared rotated image widget
|
// Fit inside 96x64 with 6px padding using the shared rotated image widget
|
||||||
const boxW = 96.0, boxH = 64.0, pad = 6.0;
|
const boxW = 96.0, boxH = 64.0, pad = 6.0;
|
||||||
|
// Hint decoder with small target size to reduce decode cost.
|
||||||
|
// The card shows inside 96x64 with 6px padding; request ~128px max.
|
||||||
Widget coreImage = RotatedSignatureImage(
|
Widget coreImage = RotatedSignatureImage(
|
||||||
bytes: displayData.bytes,
|
bytes: displayData.bytes,
|
||||||
rotationDeg: rotationDeg,
|
rotationDeg: widget.rotationDeg,
|
||||||
|
// Only set one dimension to keep aspect ratio
|
||||||
|
cacheHeight: 128,
|
||||||
);
|
);
|
||||||
Widget img =
|
Widget img =
|
||||||
(displayData.colorMatrix != null)
|
(displayData.colorMatrix != null)
|
||||||
|
|
@ -102,7 +125,7 @@ class SignatureCard extends ConsumerWidget {
|
||||||
top: 0,
|
top: 0,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: const Icon(Icons.close, size: 16),
|
icon: const Icon(Icons.close, size: 16),
|
||||||
onPressed: disabled ? null : onDelete,
|
onPressed: widget.disabled ? null : widget.onDelete,
|
||||||
tooltip: 'Remove',
|
tooltip: 'Remove',
|
||||||
padding: const EdgeInsets.all(2),
|
padding: const EdgeInsets.all(2),
|
||||||
),
|
),
|
||||||
|
|
@ -111,31 +134,29 @@ class SignatureCard extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Widget child = onTap != null ? InkWell(onTap: onTap, child: base) : base;
|
Widget child =
|
||||||
|
widget.onTap != null ? InkWell(onTap: widget.onTap, child: base) : base;
|
||||||
// Add context menu for adjust/delete on right-click or long-press
|
// Add context menu for adjust/delete on right-click or long-press
|
||||||
child = GestureDetector(
|
child = GestureDetector(
|
||||||
key: const Key('gd_signature_card_area'),
|
key: const Key('gd_signature_card_area'),
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onSecondaryTapDown:
|
onSecondaryTapDown:
|
||||||
disabled
|
widget.disabled
|
||||||
? null
|
? null
|
||||||
: (details) => _showContextMenu(context, details.globalPosition),
|
: (details) => _showContextMenu(context, details.globalPosition),
|
||||||
onLongPressStart:
|
onLongPressStart:
|
||||||
disabled
|
widget.disabled
|
||||||
? null
|
? null
|
||||||
: (details) => _showContextMenu(context, details.globalPosition),
|
: (details) => _showContextMenu(context, details.globalPosition),
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
if (disabled) return child;
|
if (widget.disabled) return child;
|
||||||
return Draggable<SignatureDragData>(
|
return Draggable<SignatureDragData>(
|
||||||
data:
|
data: SignatureDragData(
|
||||||
useCurrentBytesForDrag
|
|
||||||
? const SignatureDragData()
|
|
||||||
: SignatureDragData(
|
|
||||||
card: domain.SignatureCard(
|
card: domain.SignatureCard(
|
||||||
asset: asset,
|
asset: widget.asset,
|
||||||
rotationDeg: rotationDeg,
|
rotationDeg: widget.rotationDeg,
|
||||||
graphicAdjust: graphicAdjust,
|
graphicAdjust: widget.graphicAdjust,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onDragStarted: () {
|
onDragStarted: () {
|
||||||
|
|
@ -166,12 +187,14 @@ class SignatureCard extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
child: RotatedSignatureImage(
|
child: RotatedSignatureImage(
|
||||||
bytes: displayData.bytes,
|
bytes: displayData.bytes,
|
||||||
rotationDeg: rotationDeg,
|
rotationDeg: widget.rotationDeg,
|
||||||
|
cacheHeight: 256,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: RotatedSignatureImage(
|
: RotatedSignatureImage(
|
||||||
bytes: displayData.bytes,
|
bytes: displayData.bytes,
|
||||||
rotationDeg: rotationDeg,
|
rotationDeg: widget.rotationDeg,
|
||||||
|
cacheHeight: 256,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:pdf_signature/domain/models/model.dart';
|
import 'package:pdf_signature/domain/models/model.dart';
|
||||||
|
|
||||||
class SignatureDragData {
|
class SignatureDragData {
|
||||||
final SignatureCard? card; // null means use current processed signature
|
final SignatureCard card; // null means use current processed signature
|
||||||
const SignatureDragData({this.card});
|
const SignatureDragData({required this.card});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:pdf_signature/data/repositories/signature_asset_repository.dart';
|
import 'package:pdf_signature/data/repositories/signature_asset_repository.dart';
|
||||||
import 'package:pdf_signature/data/repositories/signature_card_repository.dart';
|
import 'package:pdf_signature/data/repositories/signature_card_repository.dart';
|
||||||
import 'package:pdf_signature/domain/models/model.dart' hide SignatureCard;
|
import 'package:pdf_signature/domain/models/signature_asset.dart';
|
||||||
import 'image_editor_dialog.dart';
|
import 'image_editor_dialog.dart';
|
||||||
import 'signature_card.dart';
|
import 'signature_card_view.dart';
|
||||||
import '../../pdf/view_model/pdf_view_model.dart';
|
import '../../pdf/view_model/pdf_view_model.dart';
|
||||||
|
|
||||||
/// Data for drag-and-drop is in signature_drag_data.dart
|
/// Data for drag-and-drop is in signature_drag_data.dart
|
||||||
|
|
@ -49,7 +49,7 @@ class _SignatureDrawerState extends ConsumerState<SignatureDrawer> {
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
child: SignatureCard(
|
child: SignatureCardView(
|
||||||
key: ValueKey('sig_card_${library.indexOf(card)}'),
|
key: ValueKey('sig_card_${library.indexOf(card)}'),
|
||||||
asset: card.asset,
|
asset: card.asset,
|
||||||
rotationDeg: card.rotationDeg,
|
rotationDeg: card.rotationDeg,
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,6 @@ void main() {
|
||||||
height: 520,
|
height: 520,
|
||||||
child: PdfPageArea(
|
child: PdfPageArea(
|
||||||
pageSize: Size(676, 400),
|
pageSize: Size(676, 400),
|
||||||
onDragSignature: _noopOffset,
|
|
||||||
onResizeSignature: _noopOffset,
|
|
||||||
onConfirmSignature: _noop,
|
|
||||||
onClearActiveOverlay: _noop,
|
|
||||||
onSelectPlaced: _noopInt,
|
|
||||||
controller: PdfViewerController(),
|
controller: PdfViewerController(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -75,6 +70,4 @@ void main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _noop() {}
|
// No extra callbacks required in the new API
|
||||||
void _noopInt(int? _) {}
|
|
||||||
void _noopOffset(Offset _) {}
|
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,6 @@ void main() {
|
||||||
height: 520,
|
height: 520,
|
||||||
child: PdfPageArea(
|
child: PdfPageArea(
|
||||||
pageSize: Size(676, 400),
|
pageSize: Size(676, 400),
|
||||||
onDragSignature: _noopOffset,
|
|
||||||
onResizeSignature: _noopOffset,
|
|
||||||
onConfirmSignature: _noop,
|
|
||||||
onClearActiveOverlay: _noop,
|
|
||||||
onSelectPlaced: _noopInt,
|
|
||||||
controller: PdfViewerController(),
|
controller: PdfViewerController(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -106,6 +101,4 @@ void main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _noop() {}
|
// No extra callbacks required in the new API
|
||||||
void _noopInt(int? _) {}
|
|
||||||
void _noopOffset(Offset _) {}
|
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,6 @@ void main() {
|
||||||
height: 520,
|
height: 520,
|
||||||
child: PdfPageArea(
|
child: PdfPageArea(
|
||||||
pageSize: const Size(676, 400),
|
pageSize: const Size(676, 400),
|
||||||
onDragSignature: _noopOffset,
|
|
||||||
onResizeSignature: _noopOffset,
|
|
||||||
onConfirmSignature: _noop,
|
|
||||||
onClearActiveOverlay: _noop,
|
|
||||||
onSelectPlaced: _noopInt,
|
|
||||||
controller: PdfViewerController(),
|
controller: PdfViewerController(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -91,11 +86,6 @@ void main() {
|
||||||
// Keep aspect ratio consistent with uiPageSize
|
// Keep aspect ratio consistent with uiPageSize
|
||||||
child: PdfPageArea(
|
child: PdfPageArea(
|
||||||
pageSize: uiPageSize,
|
pageSize: uiPageSize,
|
||||||
onDragSignature: _noopOffset,
|
|
||||||
onResizeSignature: _noopOffset,
|
|
||||||
onConfirmSignature: _noop,
|
|
||||||
onClearActiveOverlay: _noop,
|
|
||||||
onSelectPlaced: _noopInt,
|
|
||||||
controller: PdfViewerController(),
|
controller: PdfViewerController(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -170,6 +160,4 @@ void main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _noop() {}
|
// No extra callbacks required in the new API
|
||||||
void _noopInt(int? _) {}
|
|
||||||
void _noopOffset(Offset _) {}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue