148 lines
4.4 KiB
Dart
148 lines
4.4 KiB
Dart
import 'dart:typed_data';
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
/// Represents a single signature placement on a page combining both the
|
|
/// geometric rectangle (UI coordinate space) and the identifier of the
|
|
/// image/signature asset assigned to that placement.
|
|
class SignaturePlacement {
|
|
final Rect rect;
|
|
|
|
/// Rotation in degrees to apply when rendering/exporting this placement.
|
|
final double rotationDeg;
|
|
|
|
/// Identifier of the image (e.g., filename / asset id) assigned to this placement.
|
|
/// Nullable to allow a placement reserved before an image is chosen.
|
|
final String? imageId;
|
|
const SignaturePlacement({
|
|
required this.rect,
|
|
this.imageId,
|
|
this.rotationDeg = 0.0,
|
|
});
|
|
|
|
SignaturePlacement copyWith({
|
|
Rect? rect,
|
|
String? imageId,
|
|
double? rotationDeg,
|
|
}) => SignaturePlacement(
|
|
rect: rect ?? this.rect,
|
|
imageId: imageId ?? this.imageId,
|
|
rotationDeg: rotationDeg ?? this.rotationDeg,
|
|
);
|
|
}
|
|
|
|
class PdfState {
|
|
final bool loaded;
|
|
final int pageCount;
|
|
final int currentPage;
|
|
final String? pickedPdfPath;
|
|
final Uint8List? pickedPdfBytes;
|
|
final int? signedPage;
|
|
// Multiple signature placements per page, each combines geometry and optional image id.
|
|
final Map<int, List<SignaturePlacement>> placementsByPage;
|
|
// UI state: selected placement index on the current page (if any)
|
|
final int? selectedPlacementIndex;
|
|
const PdfState({
|
|
required this.loaded,
|
|
required this.pageCount,
|
|
required this.currentPage,
|
|
this.pickedPdfPath,
|
|
this.pickedPdfBytes,
|
|
this.signedPage,
|
|
this.placementsByPage = const {},
|
|
this.selectedPlacementIndex,
|
|
});
|
|
factory PdfState.initial() => const PdfState(
|
|
loaded: false,
|
|
pageCount: 0,
|
|
currentPage: 1,
|
|
pickedPdfBytes: null,
|
|
signedPage: null,
|
|
placementsByPage: {},
|
|
selectedPlacementIndex: null,
|
|
);
|
|
PdfState copyWith({
|
|
bool? loaded,
|
|
int? pageCount,
|
|
int? currentPage,
|
|
String? pickedPdfPath,
|
|
Uint8List? pickedPdfBytes,
|
|
int? signedPage,
|
|
Map<int, List<SignaturePlacement>>? placementsByPage,
|
|
int? selectedPlacementIndex,
|
|
}) => PdfState(
|
|
loaded: loaded ?? this.loaded,
|
|
pageCount: pageCount ?? this.pageCount,
|
|
currentPage: currentPage ?? this.currentPage,
|
|
pickedPdfPath: pickedPdfPath ?? this.pickedPdfPath,
|
|
pickedPdfBytes: pickedPdfBytes ?? this.pickedPdfBytes,
|
|
signedPage: signedPage ?? this.signedPage,
|
|
placementsByPage: placementsByPage ?? this.placementsByPage,
|
|
selectedPlacementIndex:
|
|
selectedPlacementIndex ?? this.selectedPlacementIndex,
|
|
);
|
|
}
|
|
|
|
class SignatureState {
|
|
final Rect? rect;
|
|
final bool aspectLocked;
|
|
final bool bgRemoval;
|
|
final double contrast;
|
|
final double brightness;
|
|
// Rotation in degrees applied to the signature image when rendering/exporting
|
|
final double rotation;
|
|
final List<List<Offset>> strokes;
|
|
final Uint8List? imageBytes;
|
|
// The ID of the signature asset the current overlay is based on (from library)
|
|
final String? assetId;
|
|
// When true, the active signature overlay is movable/resizable and should not be exported.
|
|
// When false, the overlay is confirmed (unmovable) and eligible for export.
|
|
final bool editingEnabled;
|
|
const SignatureState({
|
|
required this.rect,
|
|
required this.aspectLocked,
|
|
required this.bgRemoval,
|
|
required this.contrast,
|
|
required this.brightness,
|
|
this.rotation = 0.0,
|
|
required this.strokes,
|
|
this.imageBytes,
|
|
this.assetId,
|
|
this.editingEnabled = false,
|
|
});
|
|
factory SignatureState.initial() => const SignatureState(
|
|
rect: null,
|
|
aspectLocked: false,
|
|
bgRemoval: false,
|
|
contrast: 1.0,
|
|
brightness: 0.0,
|
|
rotation: 0.0,
|
|
strokes: [],
|
|
imageBytes: null,
|
|
assetId: null,
|
|
editingEnabled: false,
|
|
);
|
|
SignatureState copyWith({
|
|
Rect? rect,
|
|
bool? aspectLocked,
|
|
bool? bgRemoval,
|
|
double? contrast,
|
|
double? brightness,
|
|
double? rotation,
|
|
List<List<Offset>>? strokes,
|
|
Uint8List? imageBytes,
|
|
String? assetId,
|
|
bool? editingEnabled,
|
|
}) => SignatureState(
|
|
rect: rect ?? this.rect,
|
|
aspectLocked: aspectLocked ?? this.aspectLocked,
|
|
bgRemoval: bgRemoval ?? this.bgRemoval,
|
|
contrast: contrast ?? this.contrast,
|
|
brightness: brightness ?? this.brightness,
|
|
rotation: rotation ?? this.rotation,
|
|
strokes: strokes ?? this.strokes,
|
|
imageBytes: imageBytes ?? this.imageBytes,
|
|
assetId: assetId ?? this.assetId,
|
|
editingEnabled: editingEnabled ?? this.editingEnabled,
|
|
);
|
|
}
|