From 61a49a816128a2d008e4611f485d45e70a91ba31 Mon Sep 17 00:00:00 2001 From: Khoren Markosyan Date: Sat, 14 May 2022 23:13:30 +0400 Subject: [PATCH] added help page --- .vscode/launch.json | 6 +- example/lib/main.dart | 5 +- example/pubspec.lock | 8 +- example/pubspec.yaml | 2 +- lib/image_converter.dart | 2 +- lib/scanner_overlay.dart | 29 +-- lib/writer_widget.dart | 2 +- pubspec.yaml | 8 +- .../android/app/src/main/AndroidManifest.xml | 2 +- .../ios/Runner.xcodeproj/project.pbxproj | 3 +- zxscanner/ios/Runner/Info.plist | 10 +- zxscanner/lib/configs/constants.dart | 2 +- zxscanner/lib/main.dart | 3 +- zxscanner/lib/pages/help_page.dart | 228 +++++++++++++++++- zxscanner/pubspec.lock | 26 +- zxscanner/pubspec.yaml | 4 +- 16 files changed, 295 insertions(+), 45 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e3ada42..74d50f8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,20 +16,20 @@ "type": "dart" }, { - "name": "ZxScanner", + "name": "ZXScanner", "cwd": "zxscanner", "request": "launch", "type": "dart" }, { - "name": "ZxScanner (profile mode)", + "name": "ZXScanner (profile mode)", "cwd": "zxscanner", "request": "launch", "type": "dart", "flutterMode": "profile" }, { - "name": "ZxScanner (release mode)", + "name": "ZXScanner (release mode)", "cwd": "zxscanner", "request": "launch", "type": "dart", diff --git a/example/lib/main.dart b/example/lib/main.dart index 8dafa93..98456b3 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -31,9 +31,12 @@ class _MyAppState extends State { ), ), body: TabBarView( + physics: const NeverScrollableScrollPhysics(), children: [ ReaderWidget( - onScan: (value) {}, + onScan: (value) { + debugPrint(value.textString ?? ''); + }, ), WriterWidget( onSuccess: (result, bytes) {}, diff --git a/example/pubspec.lock b/example/pubspec.lock index fcb1913..19f2603 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -98,7 +98,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.2.1" flutter: dependency: "direct main" description: flutter @@ -176,7 +176,7 @@ packages: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.8.5+2" + version: "0.8.5+3" image_picker_android: dependency: transitive description: @@ -328,7 +328,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" vector_math: dependency: transitive description: @@ -344,5 +344,5 @@ packages: source: hosted version: "5.4.1" sdks: - dart: ">=2.17.0-206.0.dev <3.0.0" + dart: ">=2.17.0 <3.0.0" flutter: ">=2.8.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 3e4ff73..005b100 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -4,7 +4,7 @@ version: 0.0.1 publish_to: "none" # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.16.1 <3.0.0" + sdk: ">=2.17.0 <3.0.0" dependencies: flutter: diff --git a/lib/image_converter.dart b/lib/image_converter.dart index 51e8b88..f1cb8ea 100644 --- a/lib/image_converter.dart +++ b/lib/image_converter.dart @@ -17,7 +17,7 @@ Future convertImage(CameraImage image) async { } return img.getBytes(format: imglib.Format.luminance); } catch (e) { - debugPrint(">>>>>>>>>>>> ERROR:" + e.toString()); + debugPrint(">>>>>>>>>>>> ERROR: $e"); } return Uint8List(0); } diff --git a/lib/scanner_overlay.dart b/lib/scanner_overlay.dart index 4eefc29..7909024 100644 --- a/lib/scanner_overlay.dart +++ b/lib/scanner_overlay.dart @@ -58,10 +58,11 @@ class ScannerOverlay extends ShapeBorder { final borderWidthSize = width / 2; final height = rect.height; final borderOffset = borderWidth / 2; - final _borderLength = borderLength > cutOutSize / 2 + borderWidth * 2 + final newBorderLength = borderLength > cutOutSize / 2 + borderWidth * 2 ? borderWidthSize / 2 : borderLength; - final _cutOutSize = cutOutSize < width ? cutOutSize : width - borderOffset; + final newCutOutSize = + cutOutSize < width ? cutOutSize : width - borderOffset; final backgroundPaint = Paint() ..color = overlayColor @@ -78,10 +79,10 @@ class ScannerOverlay extends ShapeBorder { ..blendMode = BlendMode.dstOut; final cutOutRect = Rect.fromLTWH( - rect.left + width / 2 - _cutOutSize / 2 + borderOffset, - rect.top + height / 2 - _cutOutSize / 2 + borderOffset, - _cutOutSize - borderOffset * 2, - _cutOutSize - borderOffset * 2, + rect.left + width / 2 - newCutOutSize / 2 + borderOffset, + rect.top + height / 2 - newCutOutSize / 2 + borderOffset, + newCutOutSize - borderOffset * 2, + newCutOutSize - borderOffset * 2, ); canvas @@ -96,10 +97,10 @@ class ScannerOverlay extends ShapeBorder { // Draw top right corner ..drawRRect( RRect.fromLTRBAndCorners( - cutOutRect.right - _borderLength, + cutOutRect.right - newBorderLength, cutOutRect.top, cutOutRect.right, - cutOutRect.top + _borderLength, + cutOutRect.top + newBorderLength, topRight: Radius.circular(borderRadius), ), borderPaint, @@ -109,8 +110,8 @@ class ScannerOverlay extends ShapeBorder { RRect.fromLTRBAndCorners( cutOutRect.left, cutOutRect.top, - cutOutRect.left + _borderLength, - cutOutRect.top + _borderLength, + cutOutRect.left + newBorderLength, + cutOutRect.top + newBorderLength, topLeft: Radius.circular(borderRadius), ), borderPaint, @@ -118,8 +119,8 @@ class ScannerOverlay extends ShapeBorder { // Draw bottom right corner ..drawRRect( RRect.fromLTRBAndCorners( - cutOutRect.right - _borderLength, - cutOutRect.bottom - _borderLength, + cutOutRect.right - newBorderLength, + cutOutRect.bottom - newBorderLength, cutOutRect.right, cutOutRect.bottom, bottomRight: Radius.circular(borderRadius), @@ -130,8 +131,8 @@ class ScannerOverlay extends ShapeBorder { ..drawRRect( RRect.fromLTRBAndCorners( cutOutRect.left, - cutOutRect.bottom - _borderLength, - cutOutRect.left + _borderLength, + cutOutRect.bottom - newBorderLength, + cutOutRect.left + newBorderLength, cutOutRect.bottom, bottomLeft: Radius.circular(borderRadius), ), diff --git a/lib/writer_widget.dart b/lib/writer_widget.dart index 45f7309..b2a1494 100644 --- a/lib/writer_widget.dart +++ b/lib/writer_widget.dart @@ -195,7 +195,7 @@ class _WriterWidgetState extends State final img = imglib.Image.fromBytes(width, height, result.bytes); final encodedBytes = Uint8List.fromList(imglib.encodeJpg(img)); widget.onSuccess?.call(result, encodedBytes); - } on Exception catch (e) { + } catch (e) { error = e.toString(); } } else { diff --git a/pubspec.yaml b/pubspec.yaml index a01e7db..077f9e5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,20 +4,20 @@ version: 0.1.2 repository: https://github.com/khoren93/flutter_zxing environment: - sdk: ">=2.16.1 <3.0.0" + sdk: ">=2.17.0 <3.0.0" flutter: ">=2.5.0" dependencies: camera: ^0.9.4 - ffi: ^1.1.2 + ffi: ^1.2.1 flutter: sdk: flutter flutter_beep: ^1.0.0 image: ^3.1.3 dev_dependencies: - ffigen: ^4.1.3 # dart run ffigen - flutter_lints: ^1.0.0 + ffigen: ^5.0.0 # dart run ffigen + flutter_lints: ^2.0.1 flutter_test: sdk: flutter diff --git a/zxscanner/android/app/src/main/AndroidManifest.xml b/zxscanner/android/app/src/main/AndroidManifest.xml index c2a09a2..af2261c 100644 --- a/zxscanner/android/app/src/main/AndroidManifest.xml +++ b/zxscanner/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Zxscanner + ZXScanner CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -43,7 +45,9 @@ UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone - + NSPhotoLibraryUsageDescription + $(APP_DISPLAY_NAME) needs photo library access to scan barcodes + NSCameraUsageDescription + $(APP_DISPLAY_NAME) needs camera access to scan barcodes diff --git a/zxscanner/lib/configs/constants.dart b/zxscanner/lib/configs/constants.dart index 74bf122..3696ffb 100644 --- a/zxscanner/lib/configs/constants.dart +++ b/zxscanner/lib/configs/constants.dart @@ -1,4 +1,4 @@ -const String appName = 'ZxScanner'; +const String appName = 'ZXScanner'; /// space between widgets const spaceSmall = 2.0; diff --git a/zxscanner/lib/main.dart b/zxscanner/lib/main.dart index 3e4bba3..e266f4a 100644 --- a/zxscanner/lib/main.dart +++ b/zxscanner/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:zxscanner/configs/constants.dart'; import 'package:zxscanner/utils/db_service.dart'; import 'package:zxscanner/utils/extensions.dart'; import 'package:nb_utils/nb_utils.dart'; @@ -57,7 +58,7 @@ class _MyAppState extends State { Widget build(BuildContext context) { return Observer( builder: (_) => MaterialApp( - title: 'ZxScanner', + title: appName, theme: AppTheme.flexLightTheme(), darkTheme: AppTheme.flexDarkTheme(), themeMode: appStore.themeMode, diff --git a/zxscanner/lib/pages/help_page.dart b/zxscanner/lib/pages/help_page.dart index f143841..d46bf9c 100644 --- a/zxscanner/lib/pages/help_page.dart +++ b/zxscanner/lib/pages/help_page.dart @@ -1,4 +1,12 @@ +import 'dart:typed_data'; + import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:flutter_zxing/flutter_zxing.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:image/image.dart' as imglib; +import 'package:zxscanner/configs/constants.dart'; +import 'package:zxscanner/widgets/common_widgets.dart'; class HelpPage extends StatelessWidget { const HelpPage({Key? key}) : super(key: key); @@ -9,7 +17,225 @@ class HelpPage extends StatelessWidget { appBar: AppBar( title: const Text('Help'), ), - body: Container(), + body: ContainerX( + child: ListView( + padding: const EdgeInsets.only(bottom: spaceLarge2), + children: createSlides(context), + ), + ), + ); + } + + Widget createSlide( + BuildContext context, { + String? title, + String? body, + int format = Format.QRCode, + String? qrText, + int width = 100, + int height = 100, + }) { + Uint8List? bytes; + if (qrText != null) { + final result = + FlutterZxing.encodeBarcode(qrText, width, height, format, 5, 0); + if (result.isValidBool) { + final img = imglib.Image.fromBytes(width, height, result.bytes); + bytes = Uint8List.fromList(imglib.encodeJpg(img)); + } else { + debugPrint('Error: ${result.errorMessage}'); + } + } + return Card( + margin: const EdgeInsets.all(8.0), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Theme( + data: Theme.of(context).copyWith( + dividerColor: Colors.transparent, + ), + child: ExpansionTile( + leading: bytes != null + ? Image.memory(bytes, width: 100) + : const SizedBox( + width: 100, + child: Icon(FontAwesomeIcons.barcode, size: 50), + ), + title: Text(title ?? ''), + children: [ + Padding( + padding: const EdgeInsets.all(spaceDefault), + child: MarkdownBody(data: body ?? ''), + ), + ], + ), + ), + ), ); } + + createSlides(BuildContext context) { + return [ + createSlide( + context, + title: 'QR Code', + body: """ +QR codes are highly versatile and cover a range of applications because they store a large amount of information in a relatively small area. They are particularly popular in advertising, such as on flyers or shop windows, in public transport and airline ticketing, and in parcel delivery. +* Defined in the ISO/IEC 18004:2006 and JIS X0510 standards. +* 2D barcode that stores a maximum of 7089 digits or 4296 alphanumeric characters. +* Can be used free of charge – specifications are available from the Swiss-based International Organization for Standardization. +* Automatic error correction recovers damage to up to 30%, depending on the correction level chosen. + """, + format: Format.QRCode, + qrText: '123456789012', + ), + createSlide( + context, + title: 'DataMatrix', + body: """ +Due to its small size and large storage capacity, the Data Matrix code is most frequently used in the aerospace, automotive, and electronics sectors. Applied through permanent marking, the code can identify spare parts over their whole lifespan. It also has applications in healthcare and postal services. +* 2D barcode with L-shaped border and pixel matrix. +* Defined in the ISO/IEC 16022 standard. +* Stores up to 3116 numeric or 2335 alphanumeric characters. +* Smallest size: 2.5 mm x 2.5 mm, thus ideal for small units. +* Often engraved on items via Direct Part Marking (DPM). +* Readable even with low contrast. + """, + format: Format.DataMatrix, + qrText: '123456789012', + ), + createSlide( + context, + title: 'Aztec', + body: """ +The transportation sector accounts for most Aztec Code use cases. Lufthansa airline tickets contain this code, as do Deutsche Bahn tickets. The International Union of Railways (UIC) has chosen the Aztec Code as its standard for ticketing. Additionally, Aztec Codes are used in the healthcare sector, notably on patient identification bracelets. +* Two-dimensional barcode, standardized in ISO/IEC 24778. +* Freely available under US patent number 5591956. +* Can store over 3,000 characters in up to 32 layers. +* Less widely used than QR and Data Matrix Codes. +* Enables both high data density and up to 95% error tolerance. +* Pattern resembles a top-down view of an Aztec pyramid + """, + format: Format.Aztec, + qrText: '123456789012', + ), + createSlide( + context, + title: 'PDF417', + body: """ +Ticketing, travel, and logistics are some of the most common areas of application for PDF417 codes. They also find use in healthcare, warehousing, administration, and ID documents, in particular the US driver's license. Due to its high data density and customizable size, the PDF417 is one of the most versatile and widely used barcode types. +* A two-dimensional barcode that stores around 2725 numbers or 1850 alphanumeric characters. +* “PDF” is short for “Portable data file”. +* Defined in the ISO/IEC 15438 standard. +* High data density, yet with adjustable length and width. +* Striking redundancy: Up to 40% damage can be compensated. + """, + format: Format.PDF417, + ), + createSlide( + context, + title: 'UPCA, UPCE', + body: """ +The Universal Product Code (UPC) is perfect for retail, warehousing, and distribution. Stores or warehouses use it in combination with their databases to assign individual prices or quantities to the coded products. Since the price is explicitly not part of the barcode, retail stores can set prices independently using their checkout system. +* Exclusively used within North America. +* One-dimensional barcode that stores exactly 12 numeric characters, which form the Global Trade Item Number (GTIN). +* The low data density makes it inadequate for encoding complex data. + """, + format: Format.UPCA, + qrText: '123456789012', + width: 200, + ), + createSlide( + context, + title: 'EAN8, EAN13', + body: """ +The most important areas of application for EAN codes are retail, distribution, and warehousing. The EAN – short for European Article Number – is used to identify individual products, which can then be linked to quantities or prices in the store’s database. Since they can only store a limited amount of data, EAN codes are not suitable for the kind of complex information seen in ticketing or parcel shipping. +* Used worldwide despite the name, except for North America, which uses the UPC standard. +* Stores either 13 or 8 digits (EAN-13 vs. EAN-8), which encode a GTIN (Global Trade Identification Number). +* The last digit is a mod10 checksum. +* EAN codes are defined as GS1 standards. + """, + format: Format.EAN13, + qrText: '123456789012', + width: 200, + ), + createSlide( + context, + title: 'Code39', + body: """ +Unlike other common barcodes, Code 39 can also encode letters, which makes it indispensable in the industrial sector. A frequent use case is in factory automation in the automotive and electronics industries. In the US, it was standardized and adopted by the AIAG (Automotive Industry Action Group). +* One-dimensional barcode that encodes 43 characters: uppercase letters, numeric digits, and a number of special characters. +* Self-checking. However, a modulo 43 check digit is sometimes included. +* The low data density makes it unsuitable for tiny items. +* Standardized as ANSI MH 10.8 M-1983 and ANSI/AIM BC1/1995. + """, + format: Format.Code39, + qrText: '123456789012', + width: 200, + ), + createSlide( + context, + title: 'Code93', + body: """ +This barcode symbology can store alphanumeric characters. Its main user, Canada Post, encodes supplementary delivery information with it. +* One-dimensional barcode encoding 43 alphanumeric characters and 5 special characters. +* In Code 93 Extended, combinations of those characters can represent all 128 ASCII characters. + """, + format: Format.Code93, + qrText: '123456789012', + width: 200, + ), + createSlide( + context, + title: 'Code128', + body: """ +The Code 128 barcode is most frequently used in transporting goods, especially to mark containers for distribution, and warehousing. With it, various kinds of information about the respective goods can be flexibly encoded and read with a wide range of conventional scanners or smartphones. Its focus is clearly on non-POS areas. Check out our Barcode Scanner for logistics to learn more about possible application among the transportation area. +* A one-dimensional barcode defined in the ISO/IEC 15417 standard. +* Can encode all ASCII characters, including special characters. +* High data density compared to other 1D barcode formats. + """, + format: Format.Code128, + qrText: '123456789012', + width: 200, + ), + createSlide( + context, + title: 'CodaBar', + body: """ +The Codabar barcode is only used in blood banks, libraries, and in laboratories. +* 1D (linear) barcode type. +* Self-checking, with no need for a check digit. +* Encodes alphanumeric characters, as well as six special characters. +* Stores up to 16 characters. +* Newer barcode types can store more data in less space. + """, + format: Format.Codabar, + qrText: '123456789012', + width: 200, + ), + createSlide( + context, + title: 'ITF', + body: """ +ITF barcodes are often described as Standard Distribution Codes. They are frequently found on cardboard boxes and other kinds of outer packaging. +* One-dimensional barcodes that encode two numerical characters for every five bars. +* High data density, as data is stored in both the bars and the gaps.  +* Compared to other linear barcodes, more data can be accommodated using the same label size. + """, + format: Format.ITF, + qrText: '123456789012', + width: 200, + ), + ]; + } } + +/* + +DataBar + +DataBarExpanded + +MaxiCode + +*/ \ No newline at end of file diff --git a/zxscanner/pubspec.lock b/zxscanner/pubspec.lock index 38d4bdb..a201c9c 100644 --- a/zxscanner/pubspec.lock +++ b/zxscanner/pubspec.lock @@ -266,7 +266,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.2.1" file: dependency: transitive description: @@ -312,13 +312,20 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.10" flutter_mobx: dependency: "direct main" description: name: flutter_mobx url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.5+1" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -339,9 +346,9 @@ packages: flutter_zxing: dependency: "direct main" description: - name: flutter_zxing - url: "https://pub.dartlang.org" - source: hosted + path: ".." + relative: true + source: path version: "0.1.2" fluttertoast: dependency: transitive @@ -504,6 +511,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + markdown: + dependency: transitive + description: + name: markdown + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" matcher: dependency: transitive description: @@ -545,7 +559,7 @@ packages: name: mobx_codegen url: "https://pub.dartlang.org" source: hosted - version: "2.0.5+2" + version: "2.0.6+1" nb_utils: dependency: "direct main" description: diff --git a/zxscanner/pubspec.yaml b/zxscanner/pubspec.yaml index 2c8f3e6..d49f793 100644 --- a/zxscanner/pubspec.yaml +++ b/zxscanner/pubspec.yaml @@ -15,8 +15,10 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter + flutter_markdown: ^0.6.10 flutter_mobx: ^2.0.5 - flutter_zxing: ^0.1.2 + flutter_zxing: + path: ../ font_awesome_flutter: ^10.1.0 hive: ^2.1.0 hive_flutter: ^1.1.0