Browse Source

created EccLevel enum

pull/76/head
Khoren Markosyan 2 years ago
parent
commit
fae705a1de
  1. 2
      README.md
  2. 20
      lib/src/logic/barcode_encoder.dart
  3. 8
      lib/src/models/format.dart
  4. 13
      lib/src/models/messages.dart
  5. 25
      lib/src/models/params.dart
  6. 102
      lib/src/ui/writer_widget.dart
  7. 58
      lib/zxing_mobile.dart

2
README.md

@ -122,7 +122,7 @@ final Encode result = zx.encodeBarcode(
width: 120, width: 120,
height: 120, height: 120,
margin: 10, margin: 10,
eccLevel: 0, eccLevel: EccLevel.low,
), ),
); );
if (result.isValid) { if (result.isValid) {

20
lib/src/logic/barcode_encoder.dart

@ -1,22 +1,18 @@
part of 'zxing.dart'; part of 'zxing.dart';
// Encode a string into a barcode // Encode a string into a barcode
Encode zxingEncodeBarcode( Encode zxingEncodeBarcode({
String contents, { required String contents,
int format = Format.qrCode, required EncodeParams params,
int width = 300,
int height = 300,
int margin = 0,
int eccLevel = 0,
}) { }) {
return bindings return bindings
.encodeBarcode( .encodeBarcode(
contents.toNativeUtf8().cast<Char>(), contents.toNativeUtf8().cast<Char>(),
width, params.width,
height, params.height,
format, params.format,
margin, params.margin,
eccLevel, params.eccLevel.value,
) )
.toEncode(); .toEncode();
} }

8
lib/src/models/format.dart

@ -35,6 +35,14 @@ abstract class Format {
static const int any = oneDCodes | twoDCodes; static const int any = oneDCodes | twoDCodes;
} }
extension EccSupportedExtension on int {
bool get isSupportedEccLevel => eccSupported.contains(this);
static final List<int> eccSupported = <int>[
Format.qrCode,
];
}
extension CodeFormat on Format { extension CodeFormat on Format {
String get name => formatNames[this] ?? 'Unknown'; String get name => formatNames[this] ?? 'Unknown';

13
lib/src/models/messages.dart

@ -3,28 +3,37 @@ class Messages {
const Messages({ const Messages({
this.createButton = 'Create', this.createButton = 'Create',
this.textLabel = 'Enter barcode text here', this.textLabel = 'Enter barcode text here',
this.formatLabel = 'Format',
this.marginLabel = 'Margin', this.marginLabel = 'Margin',
this.eccLevelLabel = 'ECC Level', this.eccLevelLabel = 'ECC Level',
this.widthLabel = 'Width', this.widthLabel = 'Width',
this.heightLabel = 'Height', this.heightLabel = 'Height',
this.lowEccLevel = 'Low (7%)',
this.mediumEccLevel = 'Medium (15%)',
this.quartileEccLevel = 'Quartile (25%)',
this.highEccLevel = 'High (30%)',
this.invalidText = 'Please enter some text', this.invalidText = 'Please enter some text',
this.invalidWidth = 'Invalid width', this.invalidWidth = 'Invalid width',
this.invalidHeight = 'Invalid height', this.invalidHeight = 'Invalid height',
this.invalidMargin = 'Invalid margin', this.invalidMargin = 'Invalid margin',
this.invalidEccLevel = 'Invalid ECC level',
}); });
final String createButton; final String createButton;
final String textLabel; final String textLabel;
final String formatLabel;
final String marginLabel; final String marginLabel;
final String eccLevelLabel; final String eccLevelLabel;
final String widthLabel; final String widthLabel;
final String heightLabel; final String heightLabel;
final String lowEccLevel;
final String mediumEccLevel;
final String quartileEccLevel;
final String highEccLevel;
final String invalidText; final String invalidText;
final String invalidWidth; final String invalidWidth;
final String invalidHeight; final String invalidHeight;
final String invalidMargin; final String invalidMargin;
final String invalidEccLevel;
} }

25
lib/src/models/params.dart

@ -39,7 +39,7 @@ class EncodeParams {
this.width = 120, this.width = 120,
this.height = 120, this.height = 120,
this.margin = 0, this.margin = 0,
this.eccLevel = 0, this.eccLevel = EccLevel.low,
}); });
// The barcode format to be generated. The default is QRCode. // The barcode format to be generated. The default is QRCode.
@ -54,6 +54,25 @@ class EncodeParams {
// Used for all formats, sets the minimum number of quiet zone pixels // Used for all formats, sets the minimum number of quiet zone pixels
int margin; int margin;
// Used for Aztec, PDF417, and QRCode only, [0-8] // The error correction level determines how much damage the QR code can withstand while still being readable.
int eccLevel; // Used for Aztec, PDF417, and QRCode only
EccLevel eccLevel;
}
enum EccLevel {
low, // Low error correction level. Can withstand up to 7% damage.
medium, // Medium error correction level. Can withstand up to 15% damage.
quartile, // Quartile error correction level. Can withstand up to 25% damage.
high, // High error correction level. Can withstand up to 30% damage.
}
extension EccLevelExtension on EccLevel {
static const Map<EccLevel, int> _valuesMap = <EccLevel, int>{
EccLevel.low: 2,
EccLevel.medium: 4,
EccLevel.quartile: 6,
EccLevel.high: 8,
};
int get value => _valuesMap[this] ?? 0;
} }

102
lib/src/ui/writer_widget.dart

@ -14,7 +14,7 @@ class WriterWidget extends StatefulWidget {
this.width = 120, this.width = 120,
this.height = 120, this.height = 120,
this.margin = 0, this.margin = 0,
this.eccLevel = 0, this.eccLevel = EccLevel.low,
this.messages = const Messages(), this.messages = const Messages(),
this.onSuccess, this.onSuccess,
this.onError, this.onError,
@ -25,7 +25,7 @@ class WriterWidget extends StatefulWidget {
final int width; final int width;
final int height; final int height;
final int margin; final int margin;
final int eccLevel; final EccLevel eccLevel;
final Messages messages; final Messages messages;
final Function(Encode result, Uint8List? bytes)? onSuccess; final Function(Encode result, Uint8List? bytes)? onSuccess;
final Function(String error)? onError; final Function(String error)? onError;
@ -41,13 +41,22 @@ class _WriterWidgetState extends State<WriterWidget>
final TextEditingController _widthController = TextEditingController(); final TextEditingController _widthController = TextEditingController();
final TextEditingController _heightController = TextEditingController(); final TextEditingController _heightController = TextEditingController();
final TextEditingController _marginController = TextEditingController(); final TextEditingController _marginController = TextEditingController();
final TextEditingController _eccController = TextEditingController();
bool isAndroid() => Theme.of(context).platform == TargetPlatform.android; bool isAndroid() => Theme.of(context).platform == TargetPlatform.android;
final int _maxTextLength = 2000; final int _maxTextLength = 2000;
final List<int> _supportedFormats = CodeFormat.writerFormats; final List<int> _supportedFormats = CodeFormat.writerFormats;
int _codeFormat = Format.qrCode; int _codeFormat = Format.qrCode;
EccLevel _eccLevel = EccLevel.low;
Messages get messages => widget.messages;
Map<EccLevel, String> get _eccTitlesMap => <EccLevel, String>{
EccLevel.low: messages.lowEccLevel,
EccLevel.medium: messages.mediumEccLevel,
EccLevel.quartile: messages.quartileEccLevel,
EccLevel.high: messages.highEccLevel,
};
@override @override
void initState() { void initState() {
@ -55,7 +64,7 @@ class _WriterWidgetState extends State<WriterWidget>
_widthController.text = widget.width.toString(); _widthController.text = widget.width.toString();
_heightController.text = widget.height.toString(); _heightController.text = widget.height.toString();
_marginController.text = widget.margin.toString(); _marginController.text = widget.margin.toString();
_eccController.text = widget.eccLevel.toString(); _eccLevel = widget.eccLevel;
_codeFormat = widget.format; _codeFormat = widget.format;
super.initState(); super.initState();
} }
@ -66,13 +75,11 @@ class _WriterWidgetState extends State<WriterWidget>
_widthController.dispose(); _widthController.dispose();
_heightController.dispose(); _heightController.dispose();
_marginController.dispose(); _marginController.dispose();
_eccController.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Messages m = widget.messages;
return SingleChildScrollView( return SingleChildScrollView(
child: Form( child: Form(
key: _formKey, key: _formKey,
@ -95,21 +102,29 @@ class _WriterWidgetState extends State<WriterWidget>
decoration: InputDecoration( decoration: InputDecoration(
border: const OutlineInputBorder(), border: const OutlineInputBorder(),
filled: true, filled: true,
labelText: m.textLabel, labelText: messages.textLabel,
counterText: counterText:
'${_textController.value.text.length} / $_maxTextLength', '${_textController.value.text.length} / $_maxTextLength',
), ),
validator: (String? value) { validator: (String? value) {
if (value?.isEmpty ?? false) { if (value?.isEmpty ?? false) {
return m.invalidText; return messages.invalidText;
} }
return null; return null;
}, },
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
// Format DropDown button // Format DropDown button
DropdownButtonFormField<int>( Row(
children: <Widget>[
Flexible(
child: DropdownButtonFormField<int>(
value: _codeFormat, value: _codeFormat,
decoration: InputDecoration(
border: const OutlineInputBorder(),
filled: true,
labelText: messages.formatLabel,
),
items: _supportedFormats items: _supportedFormats
.map((int format) => DropdownMenuItem<int>( .map((int format) => DropdownMenuItem<int>(
value: format, value: format,
@ -122,75 +137,81 @@ class _WriterWidgetState extends State<WriterWidget>
}); });
}, },
), ),
const SizedBox(height: 20), ),
Row( if (_codeFormat.isSupportedEccLevel) ...<Widget>[
children: <Widget>[ const SizedBox(width: 10),
Flexible( Flexible(
child: TextFormField( child: DropdownButtonFormField<EccLevel>(
controller: _widthController, value: _eccLevel,
keyboardType: TextInputType.number,
decoration: InputDecoration( decoration: InputDecoration(
labelText: m.widthLabel, border: const OutlineInputBorder(),
filled: true,
labelText: messages.eccLevelLabel,
), ),
validator: (String? value) { items: _eccTitlesMap.entries
final int? width = int.tryParse(value ?? ''); .map((MapEntry<EccLevel, String> entry) =>
if (width == null) { DropdownMenuItem<EccLevel>(
return m.invalidWidth; value: entry.key,
} child: Text(entry.value),
return null; ))
.toList(),
onChanged: (EccLevel? ecc) {
setState(() {
_eccLevel = ecc ?? EccLevel.low;
});
}, },
), ),
), ),
const SizedBox(width: 8), ]
],
),
const SizedBox(height: 20),
Row(
children: <Widget>[
Flexible( Flexible(
child: TextFormField( child: TextFormField(
controller: _heightController, controller: _widthController,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
decoration: InputDecoration( decoration: InputDecoration(
labelText: m.heightLabel, labelText: messages.widthLabel,
), ),
validator: (String? value) { validator: (String? value) {
final int? width = int.tryParse(value ?? ''); final int? width = int.tryParse(value ?? '');
if (width == null) { if (width == null) {
return m.invalidHeight; return messages.invalidWidth;
} }
return null; return null;
}, },
), ),
), ),
], // const SizedBox(width: 8),
),
const SizedBox(height: 20),
Row(
children: <Widget>[
Flexible( Flexible(
child: TextFormField( child: TextFormField(
controller: _marginController, controller: _heightController,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
decoration: InputDecoration( decoration: InputDecoration(
labelText: m.marginLabel, labelText: messages.heightLabel,
), ),
validator: (String? value) { validator: (String? value) {
final int? width = int.tryParse(value ?? ''); final int? width = int.tryParse(value ?? '');
if (width == null) { if (width == null) {
return m.invalidMargin; return messages.invalidHeight;
} }
return null; return null;
}, },
), ),
), ),
const SizedBox(width: 8),
Flexible( Flexible(
child: TextFormField( child: TextFormField(
controller: _eccController, controller: _marginController,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
decoration: InputDecoration( decoration: InputDecoration(
labelText: m.eccLevelLabel, labelText: messages.marginLabel,
), ),
validator: (String? value) { validator: (String? value) {
final int? width = int.tryParse(value ?? ''); final int? width = int.tryParse(value ?? '');
if (width == null) { if (width == null) {
return m.invalidEccLevel; return messages.invalidMargin;
} }
return null; return null;
}, },
@ -198,11 +219,12 @@ class _WriterWidgetState extends State<WriterWidget>
), ),
], ],
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
// Write button // Write button
ElevatedButton( ElevatedButton(
onPressed: createBarcode, onPressed: createBarcode,
child: Text(m.createButton), child: Text(messages.createButton),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
@ -220,7 +242,7 @@ class _WriterWidgetState extends State<WriterWidget>
final int width = int.parse(_widthController.value.text); final int width = int.parse(_widthController.value.text);
final int height = int.parse(_heightController.value.text); final int height = int.parse(_heightController.value.text);
final int margin = int.parse(_marginController.value.text); final int margin = int.parse(_marginController.value.text);
final int ecc = int.parse(_eccController.value.text); final EccLevel ecc = _eccLevel;
final Encode result = zx.encodeBarcode( final Encode result = zx.encodeBarcode(
contents: text, contents: text,
params: EncodeParams( params: EncodeParams(

58
lib/zxing_mobile.dart

@ -30,14 +30,7 @@ class ZxingMobile implements Zxing {
required String contents, required String contents,
required EncodeParams params, required EncodeParams params,
}) => }) =>
zxingEncodeBarcode( zxingEncodeBarcode(contents: contents, params: params);
contents,
format: params.format,
width: params.width,
height: params.height,
margin: params.margin,
eccLevel: params.eccLevel,
);
@override @override
Future<void> startCameraProcessing() => zxingStartCameraProcessing(); Future<void> startCameraProcessing() => zxingStartCameraProcessing();
@ -50,40 +43,28 @@ class ZxingMobile implements Zxing {
CameraImage image, { CameraImage image, {
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingProcessCameraImage( zxingProcessCameraImage(image, params: params);
image,
params: params,
);
@override @override
Future<Code?> readBarcodeImagePathString( Future<Code?> readBarcodeImagePathString(
String path, { String path, {
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcodeImagePathString( zxingReadBarcodeImagePathString(path, params: params);
path,
params: params,
);
@override @override
Future<Code?> readBarcodeImagePath( Future<Code?> readBarcodeImagePath(
XFile path, { XFile path, {
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcodeImagePath( zxingReadBarcodeImagePath(path, params: params);
path,
params: params,
);
@override @override
Future<Code?> readBarcodeImageUrl( Future<Code?> readBarcodeImageUrl(
String url, { String url, {
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcodeImageUrl( zxingReadBarcodeImageUrl(url, params: params);
url,
params: params,
);
@override @override
Code readBarcode( Code readBarcode(
@ -92,42 +73,28 @@ class ZxingMobile implements Zxing {
required int height, required int height,
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcode( zxingReadBarcode(bytes, width: width, height: height, params: params);
bytes,
width: width,
height: height,
params: params,
);
@override @override
Future<List<Code>> readBarcodesImagePathString( Future<List<Code>> readBarcodesImagePathString(
String path, { String path, {
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcodesImagePathString( zxingReadBarcodesImagePathString(path, params: params);
path,
params: params,
);
@override @override
Future<List<Code>> readBarcodesImagePath( Future<List<Code>> readBarcodesImagePath(
XFile path, { XFile path, {
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcodesImagePath( zxingReadBarcodesImagePath(path, params: params);
path,
params: params,
);
@override @override
Future<List<Code>> readBarcodesImageUrl( Future<List<Code>> readBarcodesImageUrl(
String url, { String url, {
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcodesImageUrl( zxingReadBarcodesImageUrl(url, params: params);
url,
params: params,
);
@override @override
List<Code> readBarcodes( List<Code> readBarcodes(
@ -136,10 +103,5 @@ class ZxingMobile implements Zxing {
required int height, required int height,
DecodeParams? params, DecodeParams? params,
}) => }) =>
zxingReadBarcodes( zxingReadBarcodes(bytes, width: width, height: height, params: params);
bytes,
width: width,
height: height,
params: params,
);
} }

Loading…
Cancel
Save