commit 5419429426a09120c3a152f264f832265900764b Author: Tothemax Dev Date: Fri Sep 27 13:30:11 2024 +0700 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac5aa98 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..4d26462 --- /dev/null +++ b/.metadata @@ -0,0 +1,33 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819" + channel: "stable" + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: android + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: ios + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..41cc7d8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ba75c69 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7ce89ac --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# max_print_plus + +A new Flutter plugin project. + +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/to/develop-plugins), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..161bdcd --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.cxx diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..24e45de --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,68 @@ +group = "com.example.max_print_plus" +version = "1.0-SNAPSHOT" + +buildscript { + ext.kotlin_version = "1.7.10" + repositories { + google() + mavenCentral() + } + + dependencies { + classpath("com.android.tools.build:gradle:7.3.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: "com.android.library" +apply plugin: "kotlin-android" + +android { + if (project.android.hasProperty("namespace")) { + namespace = "com.example.max_print_plus" + } + + compileSdk = 34 + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8 + } + + sourceSets { + main.java.srcDirs += "src/main/kotlin" + test.java.srcDirs += "src/test/kotlin" + } + + defaultConfig { + minSdk = 21 + } + + dependencies { + testImplementation("org.jetbrains.kotlin:kotlin-test") + testImplementation("org.mockito:mockito-core:5.0.0") + } + + testOptions { + unitTests.all { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + outputs.upToDateWhen {false} + showStandardStreams = true + } + } + } +} diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..24f98f9 --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'max_print_plus' diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4ee2ddf --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/android/src/main/kotlin/com/example/max_print_plus/MaxPrintPlusPlugin.kt b/android/src/main/kotlin/com/example/max_print_plus/MaxPrintPlusPlugin.kt new file mode 100644 index 0000000..7aee2ef --- /dev/null +++ b/android/src/main/kotlin/com/example/max_print_plus/MaxPrintPlusPlugin.kt @@ -0,0 +1,35 @@ +package com.example.max_print_plus + +import androidx.annotation.NonNull + +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result + +/** MaxPrintPlusPlugin */ +class MaxPrintPlusPlugin: FlutterPlugin, MethodCallHandler { + /// The MethodChannel that will the communication between Flutter and native Android + /// + /// This local reference serves to register the plugin with the Flutter Engine and unregister it + /// when the Flutter Engine is detached from the Activity + private lateinit var channel : MethodChannel + + override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + channel = MethodChannel(flutterPluginBinding.binaryMessenger, "max_print_plus") + channel.setMethodCallHandler(this) + } + + override fun onMethodCall(call: MethodCall, result: Result) { + if (call.method == "getPlatformVersion") { + result.success("Android ${android.os.Build.VERSION.RELEASE}") + } else { + result.notImplemented() + } + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + channel.setMethodCallHandler(null) + } +} diff --git a/android/src/test/kotlin/com/example/max_print_plus/MaxPrintPlusPluginTest.kt b/android/src/test/kotlin/com/example/max_print_plus/MaxPrintPlusPluginTest.kt new file mode 100644 index 0000000..548e6a8 --- /dev/null +++ b/android/src/test/kotlin/com/example/max_print_plus/MaxPrintPlusPluginTest.kt @@ -0,0 +1,27 @@ +package com.example.max_print_plus + +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import kotlin.test.Test +import org.mockito.Mockito + +/* + * This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation. + * + * Once you have built the plugin's example app, you can run these tests from the command + * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or + * you can run them directly from IDEs that support JUnit such as Android Studio. + */ + +internal class MaxPrintPlusPluginTest { + @Test + fun onMethodCall_getPlatformVersion_returnsExpectedValue() { + val plugin = MaxPrintPlusPlugin() + + val call = MethodCall("getPlatformVersion", null) + val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java) + plugin.onMethodCall(call, mockResult) + + Mockito.verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE) + } +} diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-Black.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-Black.ttf new file mode 100644 index 0000000..6c6f954 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-Black.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-BlackItalic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-BlackItalic.ttf new file mode 100644 index 0000000..f36983a Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-BlackItalic.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-Bold.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-Bold.ttf new file mode 100644 index 0000000..4d21b3c Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-Bold.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-BoldItalic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-BoldItalic.ttf new file mode 100644 index 0000000..c220475 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-BoldItalic.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraBold.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraBold.ttf new file mode 100644 index 0000000..1b1b5d7 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraBold.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraBoldItalic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraBoldItalic.ttf new file mode 100644 index 0000000..298134f Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraBoldItalic.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraLight.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraLight.ttf new file mode 100644 index 0000000..d05a678 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraLight.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraLightItalic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraLightItalic.ttf new file mode 100644 index 0000000..855a078 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-ExtraLightItalic.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-Italic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-Italic.ttf new file mode 100644 index 0000000..69557d3 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-Italic.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-Light.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-Light.ttf new file mode 100644 index 0000000..1b651fa Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-Light.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-LightItalic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-LightItalic.ttf new file mode 100644 index 0000000..0d3f8c8 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-LightItalic.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-Medium.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-Medium.ttf new file mode 100644 index 0000000..d3634d3 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-Medium.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-MediumItalic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-MediumItalic.ttf new file mode 100644 index 0000000..5af8365 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-MediumItalic.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-Regular.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-Regular.ttf new file mode 100644 index 0000000..1326c3a Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-Regular.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-SemiBold.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-SemiBold.ttf new file mode 100644 index 0000000..e62097e Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-SemiBold.ttf differ diff --git a/assets/fonts/nunito-sans/NunitoSans_7pt-SemiBoldItalic.ttf b/assets/fonts/nunito-sans/NunitoSans_7pt-SemiBoldItalic.ttf new file mode 100644 index 0000000..0b077a6 Binary files /dev/null and b/assets/fonts/nunito-sans/NunitoSans_7pt-SemiBoldItalic.ttf differ diff --git a/assets/fonts/nunito/Nunito-Black.ttf b/assets/fonts/nunito/Nunito-Black.ttf new file mode 100644 index 0000000..81d557c Binary files /dev/null and b/assets/fonts/nunito/Nunito-Black.ttf differ diff --git a/assets/fonts/nunito/Nunito-BlackItalic.ttf b/assets/fonts/nunito/Nunito-BlackItalic.ttf new file mode 100644 index 0000000..b4ba5a1 Binary files /dev/null and b/assets/fonts/nunito/Nunito-BlackItalic.ttf differ diff --git a/assets/fonts/nunito/Nunito-Bold.ttf b/assets/fonts/nunito/Nunito-Bold.ttf new file mode 100644 index 0000000..886134d Binary files /dev/null and b/assets/fonts/nunito/Nunito-Bold.ttf differ diff --git a/assets/fonts/nunito/Nunito-BoldItalic.ttf b/assets/fonts/nunito/Nunito-BoldItalic.ttf new file mode 100644 index 0000000..0cb4efa Binary files /dev/null and b/assets/fonts/nunito/Nunito-BoldItalic.ttf differ diff --git a/assets/fonts/nunito/Nunito-ExtraBold.ttf b/assets/fonts/nunito/Nunito-ExtraBold.ttf new file mode 100644 index 0000000..711765e Binary files /dev/null and b/assets/fonts/nunito/Nunito-ExtraBold.ttf differ diff --git a/assets/fonts/nunito/Nunito-ExtraBoldItalic.ttf b/assets/fonts/nunito/Nunito-ExtraBoldItalic.ttf new file mode 100644 index 0000000..bffce10 Binary files /dev/null and b/assets/fonts/nunito/Nunito-ExtraBoldItalic.ttf differ diff --git a/assets/fonts/nunito/Nunito-ExtraLight.ttf b/assets/fonts/nunito/Nunito-ExtraLight.ttf new file mode 100644 index 0000000..d9eabf9 Binary files /dev/null and b/assets/fonts/nunito/Nunito-ExtraLight.ttf differ diff --git a/assets/fonts/nunito/Nunito-ExtraLightItalic.ttf b/assets/fonts/nunito/Nunito-ExtraLightItalic.ttf new file mode 100644 index 0000000..2037f4a Binary files /dev/null and b/assets/fonts/nunito/Nunito-ExtraLightItalic.ttf differ diff --git a/assets/fonts/nunito/Nunito-Italic.ttf b/assets/fonts/nunito/Nunito-Italic.ttf new file mode 100644 index 0000000..f4ab114 Binary files /dev/null and b/assets/fonts/nunito/Nunito-Italic.ttf differ diff --git a/assets/fonts/nunito/Nunito-Light.ttf b/assets/fonts/nunito/Nunito-Light.ttf new file mode 100644 index 0000000..e64c0fe Binary files /dev/null and b/assets/fonts/nunito/Nunito-Light.ttf differ diff --git a/assets/fonts/nunito/Nunito-LightItalic.ttf b/assets/fonts/nunito/Nunito-LightItalic.ttf new file mode 100644 index 0000000..b465e5a Binary files /dev/null and b/assets/fonts/nunito/Nunito-LightItalic.ttf differ diff --git a/assets/fonts/nunito/Nunito-Medium.ttf b/assets/fonts/nunito/Nunito-Medium.ttf new file mode 100644 index 0000000..e24c1d6 Binary files /dev/null and b/assets/fonts/nunito/Nunito-Medium.ttf differ diff --git a/assets/fonts/nunito/Nunito-MediumItalic.ttf b/assets/fonts/nunito/Nunito-MediumItalic.ttf new file mode 100644 index 0000000..6fec095 Binary files /dev/null and b/assets/fonts/nunito/Nunito-MediumItalic.ttf differ diff --git a/assets/fonts/nunito/Nunito-Regular.ttf b/assets/fonts/nunito/Nunito-Regular.ttf new file mode 100644 index 0000000..9411bfb Binary files /dev/null and b/assets/fonts/nunito/Nunito-Regular.ttf differ diff --git a/assets/fonts/nunito/Nunito-SemiBold.ttf b/assets/fonts/nunito/Nunito-SemiBold.ttf new file mode 100644 index 0000000..1326a7d Binary files /dev/null and b/assets/fonts/nunito/Nunito-SemiBold.ttf differ diff --git a/assets/fonts/nunito/Nunito-SemiBoldItalic.ttf b/assets/fonts/nunito/Nunito-SemiBoldItalic.ttf new file mode 100644 index 0000000..d20e95f Binary files /dev/null and b/assets/fonts/nunito/Nunito-SemiBoldItalic.ttf differ diff --git a/assets/image/ic_connect_off.png b/assets/image/ic_connect_off.png new file mode 100644 index 0000000..43bdffb Binary files /dev/null and b/assets/image/ic_connect_off.png differ diff --git a/assets/image/ic_connect_on.png b/assets/image/ic_connect_on.png new file mode 100644 index 0000000..b53a6d8 Binary files /dev/null and b/assets/image/ic_connect_on.png differ diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..29a3a50 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..42d18dd --- /dev/null +++ b/example/README.md @@ -0,0 +1,16 @@ +# max_print_plus_example + +Demonstrates how to use the max_print_plus plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/example/android/.gitignore b/example/android/.gitignore new file mode 100644 index 0000000..55afd91 --- /dev/null +++ b/example/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle new file mode 100644 index 0000000..acfdfc0 --- /dev/null +++ b/example/android/app/build.gradle @@ -0,0 +1,44 @@ +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +android { + namespace = "com.example.max_print_plus_example" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8 + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.max_print_plus_example" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.debug + } + } +} + +flutter { + source = "../.." +} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..159d9ef --- /dev/null +++ b/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/android/app/src/main/kotlin/com/example/max_print_plus_example/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/max_print_plus_example/MainActivity.kt new file mode 100644 index 0000000..5bb2ae0 --- /dev/null +++ b/example/android/app/src/main/kotlin/com/example/max_print_plus_example/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.max_print_plus_example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() diff --git a/example/android/app/src/main/res/drawable-v21/launch_background.xml b/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/profile/AndroidManifest.xml b/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/build.gradle b/example/android/build.gradle new file mode 100644 index 0000000..d2ffbff --- /dev/null +++ b/example/android/build.gradle @@ -0,0 +1,18 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = "../build" +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/example/android/gradle.properties b/example/android/gradle.properties new file mode 100644 index 0000000..2597170 --- /dev/null +++ b/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e1ca574 --- /dev/null +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle new file mode 100644 index 0000000..536165d --- /dev/null +++ b/example/android/settings.gradle @@ -0,0 +1,25 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.3.0" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" apply false +} + +include ":app" diff --git a/example/integration_test/plugin_integration_test.dart b/example/integration_test/plugin_integration_test.dart new file mode 100644 index 0000000..3aa4568 --- /dev/null +++ b/example/integration_test/plugin_integration_test.dart @@ -0,0 +1,25 @@ +// This is a basic Flutter integration test. +// +// Since integration tests run in a full Flutter application, they can interact +// with the host side of a plugin implementation, unlike Dart unit tests. +// +// For more information about Flutter integration tests, please see +// https://flutter.dev/to/integration-testing + + +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:max_print_plus/max_print_plus.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('getPlatformVersion test', (WidgetTester tester) async { + final MaxPrintPlus plugin = MaxPrintPlus(); + final String? version = await plugin.getPlatformVersion(); + // The version string depends on the host platform running the test, so + // just assert that some non-empty string is returned. + expect(version?.isNotEmpty, true); + }); +} diff --git a/example/ios/.gitignore b/example/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/example/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..7c56964 --- /dev/null +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 12.0 + + diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/example/ios/Podfile b/example/ios/Podfile new file mode 100644 index 0000000..d97f17e --- /dev/null +++ b/example/ios/Podfile @@ -0,0 +1,44 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '12.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7e64ef3 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,619 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = MNQ9T6JSSQ; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.maxPrintPlusExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.maxPrintPlusExample.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.maxPrintPlusExample.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.maxPrintPlusExample.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = MNQ9T6JSSQ; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.maxPrintPlusExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = MNQ9T6JSSQ; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.maxPrintPlusExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..8e3ca5d --- /dev/null +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..6266644 --- /dev/null +++ b/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..7353c41 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6ed2d93 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cd7b00 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..fe73094 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..321773c Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..502f463 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..e9f5fea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..84ac32a Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..8953cba Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0467bf1 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist new file mode 100644 index 0000000..5f9c37c --- /dev/null +++ b/example/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Max Print Plus + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + max_print_plus_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/example/ios/Runner/Runner-Bridging-Header.h b/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/example/ios/RunnerTests/RunnerTests.swift b/example/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..4dc4ba7 --- /dev/null +++ b/example/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,27 @@ +import Flutter +import UIKit +import XCTest + + +@testable import max_print_plus + +// This demonstrates a simple unit test of the Swift portion of this plugin's implementation. +// +// See https://developer.apple.com/documentation/xctest for more information about using XCTest. + +class RunnerTests: XCTestCase { + + func testGetPlatformVersion() { + let plugin = MaxPrintPlusPlugin() + + let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) + + let resultExpectation = expectation(description: "result block must be called.") + plugin.handle(call) { result in + XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion) + resultExpectation.fulfill() + } + waitForExpectations(timeout: 1) + } + +} diff --git a/example/lib/main.dart b/example/lib/main.dart new file mode 100644 index 0000000..7efc7d9 --- /dev/null +++ b/example/lib/main.dart @@ -0,0 +1,294 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:max_print_plus/print/max_print.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: const MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + var countryCode = 'ID'; + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text(widget.title), + ), + body: Center( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + ElevatedButton( + onPressed: () { + // _printReceiveTest(false); + }, + child: Text('Click me')), + ElevatedButton( + onPressed: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => MaxPrint())); + }, + child: Text('Print page mode')), + ], + ), + ), + )); + } + + // Future _printReceiveTest(bool isPage) async { + // List bytes = []; + + // // Xprinter XP-N160I + // final profile = await CapabilityProfile.load(name: 'XP-N160I'); + + // // PaperSize.mm80 or PaperSize.mm58 + // final generator = Generator(PaperSize.mm58, profile); + // bytes += generator.setGlobalCodeTable('CP1252'); + // bytes += generator.text('MM TOYS', + // styles: const PosStyles(align: PosAlign.center, bold: true)); + + // bytes += generator.text('Cikijing, Talaga, Bantarujeg, Rancah', + // styles: const PosStyles(align: PosAlign.center, bold: true)); + + // bytes += generator.row([ + // PosColumn( + // width: 6, + // text: 'PENJUALAN :', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 6, + // text: '2024-03-14', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + + // bytes += generator.row([ + // PosColumn( + // width: 8, + // text: 'PELANGGAN : UMUM-RCH', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 4, + // text: '15:30', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + + // bytes += generator.text('--------------------------------', + // styles: const PosStyles(align: PosAlign.center)); + // bytes += generator.row([ + // PosColumn( + // width: 6, + // text: 'Qty', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 6, + // text: 'Nama Produk', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // ]); + + // bytes += generator.row([ + // PosColumn( + // width: 3, + // text: 'Harga', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // PosColumn( + // width: 3, + // text: 'Dis.', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // PosColumn( + // width: 3, + // text: 'PPn', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // PosColumn( + // width: 3, + // text: 'Netto', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + + // bytes += generator.text('--------------------------------', + // styles: const PosStyles(align: PosAlign.center)); + + // // Dummy transaction data + // List dummyProducts = [ + // 'Product 1', + // 'Product 2', + // 'Product 3', + // ]; + + // for (var productName in dummyProducts) { + // bytes += generator.row([ + // PosColumn( + // width: 12, + // text: '2 ${productName.toUpperCase()}', + // styles: const PosStyles( + // align: PosAlign.left, + // codeTable: 'CP1252', + // )), + // ]); + + // bytes += generator.row([ + // PosColumn( + // width: 3, + // text: '10.0', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 3, + // text: '0.0', + // styles: + // const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // PosColumn( + // width: 3, + // text: '', + // styles: + // const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // PosColumn( + // width: 3, + // text: '20.0', + // styles: + // const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + // } + + // bytes += generator.text('--------------------------------', + // styles: const PosStyles(align: PosAlign.center)); + + // // Dummy total and payment data + // bytes += generator.row([ + // PosColumn( + // width: 4, + // text: 'Jumlah : 3', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 4, + // text: 'Item : 6', + // styles: const PosStyles(align: PosAlign.center, codeTable: 'CP1252')), + // PosColumn( + // width: 4, + // text: '33.0', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + + // // Dummy grand total, payment, change, and cashier data + // bytes += generator.row([ + // PosColumn( + // width: 6, + // text: 'Grand Total', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 1, + // text: ':', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 5, + // text: '33.0', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + // bytes += generator.row([ + // PosColumn( + // width: 6, + // text: 'Pembayaran', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 1, + // text: ':', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 5, + // text: '50.0', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + // bytes += generator.row([ + // PosColumn( + // width: 6, + // text: 'Kembalian', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 1, + // text: ':', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 5, + // text: '17.0', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + // bytes += generator.row([ + // PosColumn( + // width: 6, + // text: 'Kasir', + // styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + // PosColumn( + // width: 6, + // text: 'Anisa', + // styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + // ]); + + // bytes += generator.text('--------------------------------', + // styles: const PosStyles(align: PosAlign.center)); + + // bytes += generator.text( + // 'BARANG YANG SUDAH DI BELI TIDAK DAPAT DITUKAR / DIKEMBALIKAN', + // styles: const PosStyles(align: PosAlign.center)); + // bytes += generator.text('TERIMA KASIH', + // styles: const PosStyles(align: PosAlign.center)); + + // if (isPage == false) { + // _showPrintDialog(bytes, generator); + // } else { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => MaxPrintPage( + // bytes: bytes, + // generator: generator, + // title: 'Test', + // description: 'Test', + // onSuccess: () { + // Navigator.pop(context); + // log('Printed'); + // }, + // appBar: null, + // ))); + // } + // } + + // _showPrintDialog(List bytes, Generator generator) { + // return showDialog( + // context: context, + // builder: (BuildContext context) { + // return MaxPrintDialog( + // bytes: bytes, + // generator: generator, + // title: 'Test', + // description: 'Test', + // ); + // }, + // ); + // } +} diff --git a/example/pubspec.lock b/example/pubspec.lock new file mode 100644 index 0000000..4c40603 --- /dev/null +++ b/example/pubspec.lock @@ -0,0 +1,800 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d + url: "https://pub.dev" + source: hosted + version: "3.6.1" + args: + dependency: transitive + description: + name: args + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + barcode: + dependency: transitive + description: + name: barcode + sha256: ab180ce22c6555d77d45f0178a523669db67f95856e3378259ef2ffeb43e6003 + url: "https://pub.dev" + source: hosted + version: "2.2.8" + bidi: + dependency: transitive + description: + name: bidi + sha256: "9a712c7ddf708f7c41b1923aa83648a3ed44cfd75b04f72d598c45e5be287f9d" + url: "https://pub.dev" + source: hosted + version: "2.0.12" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + url: "https://pub.dev" + source: hosted + version: "3.0.5" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" + dio: + dependency: transitive + description: + name: dio + sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260" + url: "https://pub.dev" + source: hosted + version: "5.7.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + drago_blue_printer: + dependency: transitive + description: + name: drago_blue_printer + sha256: "8758a9d7604c81b6337107b612ea155546d1f6745995d8acc7fa383a64792f3e" + url: "https://pub.dev" + source: hosted + version: "0.0.6" + drago_pos_printer: + dependency: transitive + description: + name: drago_pos_printer + sha256: "5328fa7eb24c3dc97e235ac3a16d1ffda1780185f6ea98f45b514267a773ce59" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + drago_usb_printer: + dependency: transitive + description: + name: drago_usb_printer + sha256: df683917e70ab9369b18f49fbcf95d872346032ee2ba5cae1b752dd6e1aae6a9 + url: "https://pub.dev" + source: hosted + version: "0.1.0" + easy_logger: + dependency: transitive + description: + name: easy_logger + sha256: c764a6e024846f33405a2342caf91c62e357c24b02c04dbc712ef232bf30ffb7 + url: "https://pub.dev" + source: hosted + version: "0.0.2" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_driver: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" + url: "https://pub.dev" + source: hosted + version: "2.0.10+1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + fluttertoast: + dependency: transitive + description: + name: fluttertoast + sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc" + url: "https://pub.dev" + source: hosted + version: "8.2.8" + fuchsia_remote_debug_protocol: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + gbk_codec: + dependency: transitive + description: + name: gbk_codec + sha256: "3af5311fc9393115e3650ae6023862adf998051a804a08fb804f042724999f61" + url: "https://pub.dev" + source: hosted + version: "0.4.0" + hex: + dependency: transitive + description: + name: hex + sha256: "4e7cd54e4b59ba026432a6be2dd9d96e4c5205725194997193bf871703b82c4a" + url: "https://pub.dev" + source: hosted + version: "0.2.0" + html: + dependency: transitive + description: + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" + source: hosted + version: "0.15.4" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + image: + dependency: transitive + description: + name: image + sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8" + url: "https://pub.dev" + source: hosted + version: "4.2.0" + integration_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.dev" + source: hosted + version: "10.0.5" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + lints: + dependency: transitive + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + max_print_plus: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "0.0.1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + network_info_plus: + dependency: transitive + description: + name: network_info_plus + sha256: "6a31fa47c1f6e240f1b60de0a57d65a092ac1af7515247660f03643576984eb8" + url: "https://pub.dev" + source: hosted + version: "6.0.1" + network_info_plus_platform_interface: + dependency: transitive + description: + name: network_info_plus_platform_interface + sha256: b7f35f4a7baef511159e524499f3c15464a49faa5ec10e92ee0bce265e664906 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + open_filex: + dependency: transitive + description: + name: open_filex + sha256: ba425ea49affd0a98a234aa9344b9ea5d4c4f7625a1377961eae9fe194c3d523 + url: "https://pub.dev" + source: hosted + version: "4.5.0" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 + url: "https://pub.dev" + source: hosted + version: "2.1.4" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7" + url: "https://pub.dev" + source: hosted + version: "2.2.10" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 + url: "https://pub.dev" + source: hosted + version: "2.4.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + pdf: + dependency: transitive + description: + name: pdf + sha256: "05df53f8791587402493ac97b9869d3824eccbc77d97855f4545cf72df3cae07" + url: "https://pub.dev" + source: hosted + version: "3.11.1" + pdf_widget_wrapper: + dependency: transitive + description: + name: pdf_widget_wrapper + sha256: c930860d987213a3d58c7ec3b7ecf8085c3897f773e8dc23da9cae60a5d6d0f5 + url: "https://pub.dev" + source: hosted + version: "1.0.4" + permission_handler: + dependency: transitive + description: + name: permission_handler + sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" + url: "https://pub.dev" + source: hosted + version: "11.3.1" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "76e4ab092c1b240d31177bb64d2b0bea43f43d0e23541ec866151b9f7b2490fa" + url: "https://pub.dev" + source: hosted + version: "12.0.12" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0 + url: "https://pub.dev" + source: hosted + version: "9.4.5" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851 + url: "https://pub.dev" + source: hosted + version: "0.1.3+2" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9 + url: "https://pub.dev" + source: hosted + version: "4.2.3" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" + platform: + dependency: transitive + description: + name: platform + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + url: "https://pub.dev" + source: hosted + version: "3.1.5" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + printing: + dependency: transitive + description: + name: printing + sha256: b576764370c920b510cedf3eac7dc199d6d4af34336d608e97546392c0113362 + url: "https://pub.dev" + source: hosted + version: "5.13.3" + process: + dependency: transitive + description: + name: process + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + url: "https://pub.dev" + source: hosted + version: "5.0.2" + puppeteer: + dependency: transitive + description: + name: puppeteer + sha256: fc33b2a12731e0b9e16c40cd91ea2b6886bcc24037a435fceb59b786d4074f2b + url: "https://pub.dev" + source: hosted + version: "3.15.0" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f + url: "https://pub.dev" + source: hosted + version: "2.5.2" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e + url: "https://pub.dev" + source: hosted + version: "2.4.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + sync_http: + dependency: transitive + description: + name: sync_http + sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.dev" + source: hosted + version: "0.7.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc + url: "https://pub.dev" + source: hosted + version: "14.2.4" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + webcontent_converter: + dependency: transitive + description: + name: webcontent_converter + sha256: dab8a6abda92eb83e168d92a66f1b174f7e8c317351e6cc868440a1c1343d5f5 + url: "https://pub.dev" + source: hosted + version: "0.0.9+2" + webdriver: + dependency: transitive + description: + name: webdriver + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + win32: + dependency: transitive + description: + name: win32 + sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" + url: "https://pub.dev" + source: hosted + version: "5.5.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + url: "https://pub.dev" + source: hosted + version: "1.0.4" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" +sdks: + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.22.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml new file mode 100644 index 0000000..9c5f8ce --- /dev/null +++ b/example/pubspec.yaml @@ -0,0 +1,85 @@ +name: max_print_plus_example +description: "Demonstrates how to use the max_print_plus plugin." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +environment: + sdk: ^3.5.0 + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + max_print_plus: + # When depending on this package from a real application you should use: + # max_print_plus: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.8 + +dev_dependencies: + integration_test: + sdk: flutter + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^4.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/to/font-from-package diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart new file mode 100644 index 0000000..0e13811 --- /dev/null +++ b/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:max_print_plus_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data!.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..034771f --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,38 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig +/Flutter/ephemeral/ +/Flutter/flutter_export_environment.sh diff --git a/ios/Assets/.gitkeep b/ios/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/ios/Classes/MaxPrintPlusPlugin.swift b/ios/Classes/MaxPrintPlusPlugin.swift new file mode 100644 index 0000000..9d61501 --- /dev/null +++ b/ios/Classes/MaxPrintPlusPlugin.swift @@ -0,0 +1,19 @@ +import Flutter +import UIKit + +public class MaxPrintPlusPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "max_print_plus", binaryMessenger: registrar.messenger()) + let instance = MaxPrintPlusPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "getPlatformVersion": + result("iOS " + UIDevice.current.systemVersion) + default: + result(FlutterMethodNotImplemented) + } + } +} diff --git a/ios/Resources/PrivacyInfo.xcprivacy b/ios/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..a34b7e2 --- /dev/null +++ b/ios/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTrackingDomains + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/ios/max_print_plus.podspec b/ios/max_print_plus.podspec new file mode 100644 index 0000000..9940495 --- /dev/null +++ b/ios/max_print_plus.podspec @@ -0,0 +1,29 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint max_print_plus.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'max_print_plus' + s.version = '0.0.1' + s.summary = 'A new Flutter plugin project.' + s.description = <<-DESC +A new Flutter plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '12.0' + + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } + s.swift_version = '5.0' + + # If your plugin requires a privacy manifest, for example if it uses any + # required reason APIs, update the PrivacyInfo.xcprivacy file to describe your + # plugin's privacy impact, and then uncomment this line. For more information, + # see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files + # s.resource_bundles = {'max_print_plus_privacy' => ['Resources/PrivacyInfo.xcprivacy']} +end diff --git a/lib/max_print copy.dart b/lib/max_print copy.dart new file mode 100644 index 0000000..54fc7e0 --- /dev/null +++ b/lib/max_print copy.dart @@ -0,0 +1,448 @@ +// library max_print_dialog; + +// import 'dart:async'; +// import 'dart:developer'; +// import 'dart:io'; + +// import 'package:flutter/material.dart'; +// import 'package:thermal_printer/esc_pos_utils_platform/esc_pos_utils_platform.dart'; +// import 'package:thermal_printer/thermal_printer.dart'; +// import 'my_button.dart'; +// import 'printer_devices.dart'; + +// class MaxPrintPage extends StatefulWidget { +// Function()? onSuccess; +// PreferredSizeWidget? appBar; +// String? title, description; +// Color? btnOkTextColor, +// btnOkBorderColor, +// btnOkColor, +// btnCancelTextColor, +// btnCancelBorderColor, +// btnCancelColor; +// double? btnRadius, btnHeight, btnWidth; +// List bytes; +// Generator generator; +// Function()? onCancelTap; + +// MaxPrintPage( +// {Key? key, +// required this.appBar, +// required this.bytes, +// required this.generator, +// this.onSuccess, +// this.description, +// this.title, +// this.btnOkBorderColor, +// this.btnOkColor, +// this.btnRadius, +// this.btnOkTextColor, +// this.btnCancelBorderColor, +// this.btnCancelColor, +// this.btnCancelTextColor, +// this.btnHeight, +// this.btnWidth, +// this.onCancelTap}) +// : super(key: key); + +// @override +// _MaxPrintPageState createState() => _MaxPrintPageState(); +// } + +// class _MaxPrintPageState extends State { +// bool isLoadingButton = false; + +// // Thermal +// var defaultPrinterType = PrinterType.bluetooth; +// var _isBle = false; +// var _reconnect = false; +// var _isConnected = false; +// var printerManager = PrinterManager.instance; +// var devices = []; +// StreamSubscription? _subscription; +// StreamSubscription? _subscriptionBtStatus; +// StreamSubscription? _subscriptionUsbStatus; +// StreamSubscription? _subscriptionTCPStatus; +// BTStatus _currentStatus = BTStatus.none; +// // ignore: unused_field +// TCPStatus _currentTCPStatus = TCPStatus.none; +// // _currentUsbStatus is only supports on Android +// // ignore: unused_field +// USBStatus _currentUsbStatus = USBStatus.none; +// List? pendingTask; +// final String _ipAddress = ''; +// String _port = '9100'; +// final _ipController = TextEditingController(); +// final _portController = TextEditingController(); +// PrinterDevices? selectedPrinter; + +// @override +// void initState() { +// _initialize(); +// super.initState(); +// } + +// @override +// void dispose() { +// _subscription?.cancel(); +// _subscriptionBtStatus?.cancel(); +// _subscriptionUsbStatus?.cancel(); +// _subscriptionTCPStatus?.cancel(); +// _portController.dispose(); +// _ipController.dispose(); +// super.dispose(); +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// backgroundColor: const Color(0xFFFAFAFA), +// bottomNavigationBar: Padding( +// padding: const EdgeInsets.all(16), +// child: Row( +// mainAxisSize: MainAxisSize.min, +// children: [ +// Flexible( +// child: MyButton( +// width: double.infinity, +// text: 'Tutup', +// textColor: widget.btnCancelTextColor ?? Colors.black, +// borderColor: widget.btnCancelBorderColor ?? Colors.amber, +// color: widget.btnCancelColor ?? Colors.white, +// press: widget.onCancelTap ?? +// () { +// Navigator.pop(context); +// })), +// const SizedBox( +// width: 16.0, +// ), +// Flexible( +// child: MyButton( +// width: double.infinity, +// textColor: widget.btnOkTextColor, +// borderColor: widget.btnOkBorderColor, +// color: widget.btnOkColor, +// text: 'Cetak', +// press: () { +// _printReceiveTest(); +// })) +// ], +// ), +// ), +// appBar: widget.appBar, +// body: _buildView(context)); +// } + +// _buildView(BuildContext context) { +// return Padding( +// padding: const EdgeInsets.all(20.0), +// child: ListView( +// shrinkWrap: true, +// children: [ +// const SizedBox( +// height: 16.0, +// ), +// const Text( +// 'Daftar perangkat :', +// style: TextStyle(color: Color(0xFF0E0F0F), fontSize: 16.0), +// ), +// const SizedBox( +// height: 10.0, +// ), +// // Row( +// // children: [ +// // _chipOption(label: 'BT', val: PrinterType.bluetooth), +// // _chipOption(label: 'IP', val: PrinterType.network), +// // ], +// // ), +// Container( +// decoration: BoxDecoration( +// borderRadius: BorderRadius.circular(16.0), color: Colors.white), +// child: Material( +// color: Colors.transparent, +// child: Column( +// children: devices +// .map( +// (device) => ListTile( +// title: Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Text( +// '${device.deviceName}', +// maxLines: 1, +// style: const TextStyle( +// fontWeight: FontWeight.w600, +// fontSize: 16.0), +// ), +// const SizedBox( +// width: 6.0, +// ), +// selectedPrinter != null && +// ((device.typePrinter == +// PrinterType.usb && +// Platform.isWindows +// ? device.deviceName == +// selectedPrinter!.deviceName +// : device.vendorId != null && +// selectedPrinter!.vendorId == +// device.vendorId) || +// (device.address != null && +// selectedPrinter!.address == +// device.address)) +// ? const Icon( +// Icons.check_circle, +// color: Colors.green, +// size: 16.0, +// ) +// : const SizedBox() +// ], +// ), +// subtitle: Platform.isAndroid && +// defaultPrinterType == PrinterType.usb +// ? null +// : Visibility( +// visible: !Platform.isWindows, +// child: Text("${device.address}")), +// onTap: () async { +// // do something +// selectDevice(device); +// _connectDevice(); +// await device.saveToPrefs(); +// }, +// trailing: Material( +// color: Colors.transparent, +// child: IconButton( +// onPressed: selectedPrinter == null || +// device.deviceName != +// selectedPrinter?.deviceName +// ? null +// : () async { +// _connectDevice(); +// await selectedPrinter!.saveToPrefs(); +// }, +// icon: Image.asset( +// device.deviceName == +// selectedPrinter?.deviceName +// ? 'assets/ic_connect_on.png' +// : 'assets/ic_connect_off.png', +// package: 'max_print_dialog', +// )), +// )), +// ) +// .toList()), +// ), +// ), +// const SizedBox( +// height: 16.0, +// ), +// ], +// ), +// ); +// } + +// void _scan() { +// devices.clear(); +// _subscription = printerManager +// .discovery(type: defaultPrinterType, isBle: _isBle) +// .listen((device) { +// devices.add(PrinterDevices( +// deviceName: device.name, +// address: device.address, +// isBle: _isBle, +// vendorId: device.vendorId, +// productId: device.productId, +// typePrinter: defaultPrinterType, +// )); +// setState(() {}); +// }); +// } + +// _connectDevice() async { +// _isConnected = false; +// if (selectedPrinter == null) return; +// switch (selectedPrinter!.typePrinter) { +// case PrinterType.usb: +// await printerManager.connect( +// type: selectedPrinter!.typePrinter, +// model: UsbPrinterInput( +// name: selectedPrinter!.deviceName, +// productId: selectedPrinter!.productId, +// vendorId: selectedPrinter!.vendorId)); +// _isConnected = true; +// break; +// case PrinterType.bluetooth: +// await printerManager.connect( +// type: selectedPrinter!.typePrinter, +// model: BluetoothPrinterInput( +// name: selectedPrinter!.deviceName, +// address: selectedPrinter!.address!, +// isBle: selectedPrinter!.isBle ?? false, +// autoConnect: _reconnect)); +// break; +// case PrinterType.network: +// await printerManager.connect( +// type: selectedPrinter!.typePrinter, +// model: TcpPrinterInput(ipAddress: selectedPrinter!.address!)); +// _isConnected = true; +// break; +// default: +// } + +// setState(() {}); +// } + +// void selectDevice(PrinterDevices device) async { +// if (selectedPrinter != null) { +// if ((device.address != selectedPrinter!.address) || +// (device.typePrinter == PrinterType.usb && +// selectedPrinter!.vendorId != device.vendorId)) { +// await PrinterManager.instance +// .disconnect(type: selectedPrinter!.typePrinter); +// } +// } + +// selectedPrinter = device; +// setState(() {}); +// } + +// _printReceiveTest() { +// _printEscPos(widget.bytes, widget.generator); + +// widget.onSuccess!(); +// } + +// /// print ticket +// void _printEscPos(List bytes, Generator generator) async { +// var connectedTCP = false; +// if (selectedPrinter == null) return; +// var bluetoothPrinter = selectedPrinter!; +// switch (bluetoothPrinter.typePrinter) { +// case PrinterType.usb: +// bytes += generator.feed(2); +// bytes += generator.cut(); +// await printerManager.connect( +// type: bluetoothPrinter.typePrinter, +// model: UsbPrinterInput( +// name: bluetoothPrinter.deviceName, +// productId: bluetoothPrinter.productId, +// vendorId: bluetoothPrinter.vendorId)); +// pendingTask = null; +// break; +// case PrinterType.bluetooth: +// bytes += generator.cut(); +// await printerManager.connect( +// type: bluetoothPrinter.typePrinter, +// model: BluetoothPrinterInput( +// name: bluetoothPrinter.deviceName, +// address: bluetoothPrinter.address!, +// isBle: bluetoothPrinter.isBle ?? false, +// autoConnect: _reconnect)); +// pendingTask = null; +// if (Platform.isAndroid) pendingTask = bytes; +// break; +// case PrinterType.network: +// bytes += generator.feed(2); +// bytes += generator.cut(); +// connectedTCP = await printerManager.connect( +// type: bluetoothPrinter.typePrinter, +// model: TcpPrinterInput(ipAddress: bluetoothPrinter.address!)); +// if (!connectedTCP) print(' --- please review your connection ---'); +// break; +// default: +// } +// if (bluetoothPrinter.typePrinter == PrinterType.bluetooth && +// Platform.isAndroid) { +// if (_currentStatus == BTStatus.connected) { +// printerManager.send(type: bluetoothPrinter.typePrinter, bytes: bytes); +// pendingTask = null; +// } +// } else { +// printerManager.send(type: bluetoothPrinter.typePrinter, bytes: bytes); +// } +// } + +// Future _initialize() async { +// PrinterDevices? printer = await PrinterDevices.getFromPrefs(); + +// _scan(); +// if (printer != null) { +// selectDevice(printer); +// } + +// // subscription to listen change status of bluetooth connection +// _subscriptionBtStatus = +// PrinterManager.instance.stateBluetooth.listen((status) { +// log(' ----------------- status bt $status ------------------ '); +// _currentStatus = status; +// if (status == BTStatus.connected) { +// setState(() { +// _isConnected = true; +// }); +// } +// if (status == BTStatus.none) { +// setState(() { +// _isConnected = false; +// }); +// } +// if (status == BTStatus.connected && pendingTask != null) { +// if (Platform.isAndroid) { +// Future.delayed(const Duration(milliseconds: 1000), () { +// PrinterManager.instance +// .send(type: PrinterType.bluetooth, bytes: pendingTask!); +// pendingTask = null; +// }); +// } else if (Platform.isIOS) { +// PrinterManager.instance +// .send(type: PrinterType.bluetooth, bytes: pendingTask!); +// pendingTask = null; +// } +// } +// }); +// // PrinterManager.instance.stateUSB is only supports on Android +// _subscriptionUsbStatus = PrinterManager.instance.stateUSB.listen((status) { +// log(' ----------------- status usb $status ------------------ '); +// _currentUsbStatus = status; +// if (Platform.isAndroid) { +// if (status == USBStatus.connected && pendingTask != null) { +// Future.delayed(const Duration(milliseconds: 1000), () { +// PrinterManager.instance +// .send(type: PrinterType.usb, bytes: pendingTask!); +// pendingTask = null; +// }); +// } +// } +// }); + +// // PrinterManager.instance.stateUSB is only supports on Android +// _subscriptionTCPStatus = PrinterManager.instance.stateTCP.listen((status) { +// log(' ----------------- status tcp $status ------------------ '); +// _currentTCPStatus = status; +// }); +// } + +// _chipOption({required String label, required PrinterType val}) { +// return Row( +// children: [ +// Radio( +// value: val, +// groupValue: defaultPrinterType, +// onChanged: (v) { +// setState(() { +// defaultPrinterType = v!; +// selectedPrinter = null; +// _isBle = false; +// _isConnected = false; +// _scan(); +// }); +// }), +// const SizedBox( +// width: 10.0, +// ), +// Text( +// label, +// style: const TextStyle(fontSize: 16.0), +// ) +// ], +// ); +// } +// } diff --git a/lib/max_print_plus.dart b/lib/max_print_plus.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/max_print_plus_method_channel.dart b/lib/max_print_plus_method_channel.dart new file mode 100644 index 0000000..f438dc9 --- /dev/null +++ b/lib/max_print_plus_method_channel.dart @@ -0,0 +1,17 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import 'max_print_plus_platform_interface.dart'; + +/// An implementation of [MaxPrintPlusPlatform] that uses method channels. +class MethodChannelMaxPrintPlus extends MaxPrintPlusPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('max_print_plus'); + + @override + Future getPlatformVersion() async { + final version = await methodChannel.invokeMethod('getPlatformVersion'); + return version; + } +} diff --git a/lib/max_print_plus_platform_interface.dart b/lib/max_print_plus_platform_interface.dart new file mode 100644 index 0000000..eba559c --- /dev/null +++ b/lib/max_print_plus_platform_interface.dart @@ -0,0 +1,29 @@ +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'max_print_plus_method_channel.dart'; + +abstract class MaxPrintPlusPlatform extends PlatformInterface { + /// Constructs a MaxPrintPlusPlatform. + MaxPrintPlusPlatform() : super(token: _token); + + static final Object _token = Object(); + + static MaxPrintPlusPlatform _instance = MethodChannelMaxPrintPlus(); + + /// The default instance of [MaxPrintPlusPlatform] to use. + /// + /// Defaults to [MethodChannelMaxPrintPlus]. + static MaxPrintPlusPlatform get instance => _instance; + + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [MaxPrintPlusPlatform] when + /// they register themselves. + static set instance(MaxPrintPlusPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + Future getPlatformVersion() { + throw UnimplementedError('platformVersion() has not been implemented.'); + } +} diff --git a/lib/my_button.dart b/lib/my_button.dart new file mode 100644 index 0000000..c5b7766 --- /dev/null +++ b/lib/my_button.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; + +class MyButton extends StatelessWidget { + final String text; + final Function()? press; + final Color? color; + final Color? textColor; + final Color? borderColor; + final double? width; + final double? heigth; + final double? borderRadius; + final double? textSize; + final EdgeInsetsGeometry? padding; + + const MyButton( + {Key? key, + required this.text, + required this.press, + this.color, + this.padding, + this.textColor, + this.width, + this.heigth, + this.borderRadius, + this.borderColor, + this.textSize}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: heigth, + width: width, + child: ElevatedButton( + onPressed: press, + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + padding: MaterialStateProperty.all( + padding ?? const EdgeInsets.all(16.0)), + backgroundColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.pressed)) { + return Color(0xFFDCDEE0); + } else if (states.contains(MaterialState.disabled)) { + return Color(0xFFF2F2F5); + } else if (states.contains(MaterialState.focused)) { + return Color(0xFFFFC700); + } + return color ?? + Color(0xFFFFC700); // Use the component's default. + }, + ), + textStyle: MaterialStateProperty.all( + TextStyle(color: textColor ?? Color(0xFF242632))), + shape: MaterialStateProperty.resolveWith( + (states) { + return RoundedRectangleBorder( + side: !(states.contains(MaterialState.pressed)) + ? BorderSide(color: borderColor ?? Colors.transparent) + : const BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.circular(borderRadius ?? 1000.0)); + })), + child: Text( + text, + style: TextStyle( + color: textColor ?? Colors.white, + fontSize: textSize, + fontWeight: FontWeight.w600), + )), + ); + } +} diff --git a/lib/print/bluetooth_printer_screen.dart b/lib/print/bluetooth_printer_screen.dart new file mode 100644 index 0000000..6bf497e --- /dev/null +++ b/lib/print/bluetooth_printer_screen.dart @@ -0,0 +1,195 @@ +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:drago_pos_printer/drago_pos_printer.dart'; +import 'package:webcontent_converter/demo.dart'; +import 'package:webcontent_converter/webcontent_converter.dart'; +import '../service/service.dart'; + +class BluetoothPrinterScreen extends StatefulWidget { + @override + _BluetoothPrinterScreenState createState() => _BluetoothPrinterScreenState(); +} + +class _BluetoothPrinterScreenState extends State { + bool _isLoading = false; + List _printers = []; + BluetoothPrinterManager? _manager; + + int paperWidth = 0; + int charPerLine = 0; + + List paperTypes = []; + bool showCustom = false; + @override + void initState() { + _scan(); + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + + paperTypes.add('58mm'); + paperTypes.add('80mmOld'); + paperTypes.add('80mm'); + paperTypes.add('Custom'); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Bluetooth Printer Screen"), + ), + body: ListView( + padding: EdgeInsets.all(20), + children: [ + DropdownButtonHideUnderline( + child: DropdownButtonFormField( + decoration: InputDecoration(labelText: 'Paper Size'), + items: paperTypes.map((item) { + return DropdownMenuItem( + value: item, + child: Text(item), + ); + }).toList(), + onChanged: (String? selected) async { + showCustom = false; + if (selected != null) { + if (selected == "58mm") { + paperWidth = PaperSizeWidth.mm58; + charPerLine = PaperSizeMaxPerLine.mm58; + } else if (selected == "80mmOld") { + paperWidth = PaperSizeWidth.mm80_Old; + charPerLine = PaperSizeMaxPerLine.mm80_Old; + } else if (selected == "80mm") { + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + } else if (selected == "Custom") { + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + showCustom = true; + } + setState(() {}); + } + }, + ), + ), + if (showCustom) + Row( + children: [ + Expanded( + child: TextFormField( + initialValue: paperWidth.toString(), + onChanged: (val) { + if (val.isNotEmpty) { + paperWidth = int.parse(val); + } else + paperWidth = 0; + }, + )), + SizedBox(width: 20), + Expanded( + child: TextFormField( + initialValue: charPerLine.toString(), + onChanged: (val) { + if (val.isNotEmpty) { + charPerLine = int.parse(val); + } else + charPerLine = 0; + }, + )) + ], + ), + SizedBox(height: 10), + ..._printers + .map((printer) => ListTile( + title: Text("${printer.name}"), + subtitle: Text("${printer.address}"), + leading: Icon(Icons.bluetooth), + onTap: () => _connect(printer), + trailing: printer.connected + ? Wrap( + children: [ + IconButton( + tooltip: 'ESC POS Command', + onPressed: () => _startPrinter(1, printer), + icon: Icon(Icons.print)), + IconButton( + tooltip: 'Html Print', + onPressed: () => _startPrinter(3, printer), + icon: Icon(Icons.image)), + ], + ) + : null, + selected: printer.connected, + )) + .toList(), + ], + ), + floatingActionButton: FloatingActionButton( + child: _isLoading ? Icon(Icons.stop) : Icon(Icons.play_arrow), + onPressed: _isLoading ? null : _scan, + ), + ); + } + + _scan() async { + print("scan"); + setState(() { + _isLoading = true; + _printers = []; + }); + var printers = await BluetoothPrinterManager.discover(); + print(printers); + setState(() { + _isLoading = false; + _printers = printers; + }); + } + + Future _connect(BluetoothPrinter printer) async { + var manager = BluetoothPrinterManager(printer); + // await manager.connect(); + print(" -==== connected =====- "); + setState(() { + _manager = manager; + printer.connected = true; + }); + } + + _startPrinter(int byteType, BluetoothPrinter printer) async { + var profile = await CapabilityProfile.load(); + await _connect(printer); + + late List data; + if (byteType == 1) { + data = await ESCPrinterService(null).getSamplePosBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + profile: profile); + } else if (byteType == 2) { + data = await ESCPrinterService(null).getPdfBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + profile: profile); + } else if (byteType == 3) { + final content = Demo.getShortReceiptContent(); + + Uint8List? htmlBytes = await WebcontentConverter.contentToImage( + content: content, + executablePath: WebViewHelper.executablePath(), + ); + + var service = ESCPrinterService(htmlBytes); + data = await service.getBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + profile: profile); + } + + if (_manager != null) { + if (!await _manager!.checkConnected()) await _manager!.connect(); + _manager!.writeBytes(data, isDisconnect: true); + } + } +} diff --git a/lib/print/max_print.dart b/lib/print/max_print.dart new file mode 100644 index 0000000..33004d9 --- /dev/null +++ b/lib/print/max_print.dart @@ -0,0 +1,117 @@ +import 'package:flutter/material.dart'; +import 'package:max_print_plus/print/bluetooth_printer_screen.dart'; +import 'package:max_print_plus/print/network_printer_screen.dart'; +import 'package:max_print_plus/print/usb_printer_screen.dart'; + +import 'tab_bar.dart'; + +enum HistoryTabData { reservation, dinein, waitinglist, pickup, delivery } + +class MaxPrintArgs { + final int _index = 0; + + HistoryTabData initialTab; + + MaxPrintArgs({required this.initialTab}); + + int get initialIndex => mapTabDataToIndex(); + + int mapTabDataToIndex() { + switch (initialTab) { + case HistoryTabData.reservation: + return 0; + case HistoryTabData.dinein: + return 1; + case HistoryTabData.waitinglist: + return 2; + case HistoryTabData.pickup: + return 3; + case HistoryTabData.delivery: + return 4; + default: + return 0; + } + } +} + +class MaxPrint extends StatefulWidget { + MaxPrint({ + Key? key, + }) : super(key: key); + + @override + State createState() => _MaxPrintState(); +} + +class _MaxPrintState extends State with TickerProviderStateMixin { + String? uid; + bool? isLogin; + late final TabController _tabController; + @override + void initState() { + _tabController = TabController(length: 3, vsync: this); + _tabController.addListener(_handleTabSelection); + super.initState(); + } + + int tabIndex = 0; + + void _handleTabSelection() { + setState(() { + tabIndex = _tabController.index; + print('Tab index: $tabIndex'); + }); + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: DefaultTabController( + length: 3, + child: Scaffold( + backgroundColor: Color(0xFFFAFAFA), + appBar: AppBar( + title: Text('Print'), + bottom: CustomTabBar( + tabController: _tabController, + tabs: [ + tabTitle('Bluetooth'), + tabTitle('WiFi'), + tabTitle('USB'), + // tabTitle('Ongoing'), + // tabTitle('Completed'), + ], + ), + ), + body: Column( + children: [ + Expanded( + child: TabBarView( + controller: _tabController, + children: [ + BluetoothPrinterScreen(), + NetWorkPrinterScreen(), + USBPrinterScreen() + ], + ), + ), + ], + )), + )); + } +} + +Tab tabTitle(String title) { + return Tab( + icon: Text( + title, + style: const TextStyle( + // color: Pallete.primary, + fontSize: 12.0, + fontWeight: FontWeight.w600, + overflow: TextOverflow.ellipsis, + letterSpacing: 0.1), + maxLines: 1, + ), + ); +} diff --git a/lib/print/network_printer_screen.dart b/lib/print/network_printer_screen.dart new file mode 100644 index 0000000..ac86b5d --- /dev/null +++ b/lib/print/network_printer_screen.dart @@ -0,0 +1,216 @@ +import 'package:flutter/material.dart'; +import 'package:drago_pos_printer/drago_pos_printer.dart'; +import 'package:webcontent_converter/demo.dart'; +import 'package:webcontent_converter/webcontent_converter.dart'; + +import '../service/service.dart'; + +class NetWorkPrinterScreen extends StatefulWidget { + @override + _NetWorkPrinterScreenState createState() => _NetWorkPrinterScreenState(); +} + +class _NetWorkPrinterScreenState extends State { + bool _isLoading = false; + List _printers = []; + NetworkPrinterManager? _manager; + List _data = []; + String _name = "default"; + + int paperWidth = 0; + int charPerLine = 0; + + List paperTypes = []; + bool showCustom = false; + + @override + void initState() { + _scan(); + + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + + paperTypes.add('58mm'); + paperTypes.add('80mmOld'); + paperTypes.add('80mm'); + paperTypes.add('Custom'); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Network Printer Screen ${printProfiles.length}"), + actions: [ + PopupMenuButton( + itemBuilder: (_) => printProfiles + .map( + (e) => PopupMenuItem( + enabled: e["key"] != _name, + child: Text("${e["key"]}"), + onTap: () { + setState(() { + _name = e["key"]; + }); + }, + ), + ) + .toList(), + ) + ], + ), + body: ListView( + padding: EdgeInsets.all(20), + children: [ + DropdownButtonHideUnderline( + child: DropdownButtonFormField( + decoration: InputDecoration(labelText: 'Paper Size'), + items: paperTypes.map((item) { + return DropdownMenuItem( + value: item, + child: Text(item), + ); + }).toList(), + onChanged: (String? selected) async { + showCustom = false; + if (selected != null) { + if (selected == "58mm") { + paperWidth = PaperSizeWidth.mm58; + charPerLine = PaperSizeMaxPerLine.mm58; + } else if (selected == "80mmOld") { + paperWidth = PaperSizeWidth.mm80_Old; + charPerLine = PaperSizeMaxPerLine.mm80_Old; + } else if (selected == "80mm") { + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + } else if (selected == "Custom") { + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + showCustom = true; + } + setState(() {}); + } + }, + ), + ), + if (showCustom) + Row( + children: [ + Expanded( + child: TextFormField( + initialValue: paperWidth.toString(), + onChanged: (val) { + if (val.isNotEmpty) { + paperWidth = int.parse(val); + } else + paperWidth = 0; + }, + )), + SizedBox(width: 20), + Expanded( + child: TextFormField( + initialValue: charPerLine.toString(), + onChanged: (val) { + if (val.isNotEmpty) { + charPerLine = int.parse(val); + } else + charPerLine = 0; + }, + )) + ], + ), + SizedBox(height: 10), + ..._printers + .map((printer) => ListTile( + title: Text("${printer.name}"), + subtitle: Text("${printer.address}"), + leading: Icon(Icons.cable), + onTap: () => _connect(printer), + trailing: printer.connected + ? Wrap( + children: [ + IconButton( + tooltip: 'ESC POS Command', + onPressed: () => _startPrinter(1, printer), + icon: Icon(Icons.print)), + IconButton( + tooltip: 'Html Print', + onPressed: () => _startPrinter(3, printer), + icon: Icon(Icons.image)), + ], + ) + : null, + selected: printer.connected, + )) + .toList(), + ], + ), + floatingActionButton: FloatingActionButton( + child: _isLoading ? Icon(Icons.stop) : Icon(Icons.play_arrow), + onPressed: _isLoading ? null : _scan, + ), + ); + } + + _scan() async { + setState(() { + _isLoading = true; + _printers = []; + }); + var printers = await NetworkPrinterManager.discover(); + setState(() { + _isLoading = false; + _printers = printers; + }); + } + + Future _connect(NetWorkPrinter printer) async { + var manager = NetworkPrinterManager(printer); + await manager.connect(); + setState(() { + _manager = manager; + printer.connected = true; + }); + } + + _startPrinter(int byteType, NetWorkPrinter printer) async { + await _connect(printer); + // if (_data.isEmpty) { + final content = Demo.getShortReceiptContent(); + + var stopwatch = Stopwatch()..start(); + List data = []; + var profile = await CapabilityProfile.load(); + if (byteType == 1) { + data = await ESCPrinterService(null).getSamplePosBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + profile: profile, + name: _name); + } else if (byteType == 2) { + data = await ESCPrinterService(null).getPdfBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + profile: profile, + name: _name); + } else if (byteType == 3) { + var service = ESCPrinterService(await WebcontentConverter.contentToImage( + content: content, + executablePath: WebViewHelper.executablePath(), + )); + data = await service.getBytes(name: _name); + } + + print("Start print data $_name"); + + if (mounted) setState(() => _data = data); + + if (_manager != null) { + print("isConnected ${_manager!.printer.connected}"); + await _manager!.writeBytes(_data, isDisconnect: true); + WebcontentConverter.logger + .info("completed executed in ${stopwatch.elapsed}"); + } + } +} diff --git a/lib/print/tab_bar.dart b/lib/print/tab_bar.dart new file mode 100644 index 0000000..5de585b --- /dev/null +++ b/lib/print/tab_bar.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; + +import '../theme/theme.config.dart'; + +class CustomTabBar extends StatelessWidget implements PreferredSizeWidget { + const CustomTabBar({ + Key? key, + required TabController tabController, + required List tabs, + }) : _tabController = tabController, + _tabs = tabs, + super(key: key); + + final TabController _tabController; + final List _tabs; + + @override + Size get preferredSize => const Size(double.infinity, 45); + + @override + Widget build(BuildContext context) { + return disableMaterial3( + child: Container( + padding: const EdgeInsets.all(4), + height: 40, + margin: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: Colors.grey[100], + borderRadius: BorderRadius.circular(10), + ), + child: TabBar( + controller: _tabController, + isScrollable: false, + indicator: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.white, + ), + indicatorColor: Colors.white, + labelColor: Colors.black, + unselectedLabelColor: Colors.grey, + tabs: _tabs, + ), + ), + ); + } +} diff --git a/lib/print/usb_printer_screen.dart b/lib/print/usb_printer_screen.dart new file mode 100644 index 0000000..9b7a68f --- /dev/null +++ b/lib/print/usb_printer_screen.dart @@ -0,0 +1,232 @@ +import 'package:image/image.dart' as img; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:max_print_plus/service/service.dart'; +import 'package:open_filex/open_filex.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:drago_pos_printer/drago_pos_printer.dart'; +import 'package:webcontent_converter/demo.dart'; +import 'package:webcontent_converter/webcontent_converter.dart'; + +class USBPrinterScreen extends StatefulWidget { + @override + _USBPrinterScreenState createState() => _USBPrinterScreenState(); +} + +class _USBPrinterScreenState extends State { + bool _isLoading = false; + List _printers = []; + USBPrinterManager? _manager; + List _data = []; + + int paperWidth = 0; + int charPerLine = 0; + + List paperTypes = []; + bool showCustom = false; + + @override + void initState() { + _scan(); + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + + paperTypes.add('58mm'); + paperTypes.add('80mmOld'); + paperTypes.add('80mm'); + paperTypes.add('Custom'); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("USB Printer Screen"), + ), + body: ListView( + padding: EdgeInsets.all(20), + children: [ + DropdownButtonHideUnderline( + child: DropdownButtonFormField( + decoration: InputDecoration(labelText: 'Paper Size'), + items: paperTypes.map((item) { + return DropdownMenuItem( + value: item, + child: Text(item), + ); + }).toList(), + onChanged: (String? selected) async { + showCustom = false; + if (selected != null) { + if (selected == "58mm") { + paperWidth = PaperSizeWidth.mm58; + charPerLine = PaperSizeMaxPerLine.mm58; + } else if (selected == "80mmOld") { + paperWidth = PaperSizeWidth.mm80_Old; + charPerLine = PaperSizeMaxPerLine.mm80_Old; + } else if (selected == "80mm") { + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + } else if (selected == "Custom") { + paperWidth = PaperSizeWidth.mm80; + charPerLine = PaperSizeMaxPerLine.mm80; + showCustom = true; + } + setState(() {}); + } + }, + ), + ), + if (showCustom) + Row( + children: [ + Expanded( + child: TextFormField( + initialValue: paperWidth.toString(), + onChanged: (val) { + if (val.isNotEmpty) { + paperWidth = int.parse(val); + } else + paperWidth = 0; + }, + )), + SizedBox(width: 20), + Expanded( + child: TextFormField( + initialValue: charPerLine.toString(), + onChanged: (val) { + if (val.isNotEmpty) { + charPerLine = int.parse(val); + } else + charPerLine = 0; + }, + )) + ], + ), + SizedBox(height: 10), + ..._printers + .map((printer) => ListTile( + title: Text("${printer.name}"), + subtitle: Text("${printer.address}"), + leading: Icon(Icons.usb), + trailing: Wrap( + children: [ + IconButton( + tooltip: 'Tspl Command', + onPressed: () => _tsplPrint(printer), + icon: Icon(Icons.qr_code)), + IconButton( + tooltip: 'ESC POS Command', + onPressed: () => _startPrinter(1, printer), + icon: Icon(Icons.print)), + IconButton( + tooltip: 'Pdf', + onPressed: () => _startPrinter(2, printer), + icon: Icon(Icons.picture_as_pdf)), + IconButton( + tooltip: 'Html Print', + onPressed: () => _startPrinter(3, printer), + icon: Icon(Icons.image)), + ], + ), + )) + .toList(), + ], + ), + floatingActionButton: FloatingActionButton( + child: _isLoading ? Icon(Icons.stop) : Icon(Icons.play_arrow), + onPressed: _isLoading ? null : _scan, + ), + ); + } + + _scan() async { + setState(() { + _isLoading = true; + _printers = []; + }); + var printers = await USBPrinterManager.discover(); + setState(() { + _isLoading = false; + _printers = printers; + }); + } + + _startPrinter(int byteType, USBPrinter printer) async { + var profile = await CapabilityProfile.load(); + var manager = USBPrinterManager(printer); + _manager = manager; + + final content = Demo.getShortReceiptContent(); + var bytes = byteType == 1 + ? await ESCPrinterService(null).getSamplePosBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + profile: profile) + : byteType == 2 + ? await ESCPrinterService(null).getPdfBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + profile: profile) + : (await WebcontentConverter.contentToImage( + content: content, + executablePath: WebViewHelper.executablePath(), + )) + .toList(); + List data; + if (byteType == 3) { + var service = ESCPrinterService(Uint8List.fromList(bytes)); + data = await service.getBytes( + paperSizeWidthMM: paperWidth, + maxPerLine: charPerLine, + ); + if (bytes.length > 0) { + var dir = await getTemporaryDirectory(); + var path = dir.path + "\\receipt.jpg"; + File file = File(path); + await file.writeAsBytes(bytes); + } + } else + data = bytes; + if (mounted) setState(() => _data = data); + + _manager!.writeBytes(_data); + } + + _tsplPrint(USBPrinter printer) async { + int width = 105; + int height = 22; + int labelWidth = 35; + + var image = await ESCPrinterService(null) + .generateLabel(width, height, labelWidth, 1.5, 3); + + if (image != null) { + var dir = await getTemporaryDirectory(); + var path = dir.path + "\\receipt.png"; + File file = File(path); + await file.writeAsBytes(img.encodePng(image)); + OpenFilex.open(path); + // for (int i = 1; i <= 1; i++) { + // var manager = USBPrinterManager(printer); + // TsplGenerator generator = TsplGenerator(); + // generator.addSize(width: width, height: height); + // generator.addGap(3); + // generator.addSpeed(4); + // generator.addDensity(Density.density15); + // generator.addDirection(Direction.backWord); + // generator.addTear(Tear.on); + // generator.addCodePageUtf8(); + // generator.addCls(); + // generator.addImage(image, needGrayscale: true); + // generator.addPrint(1); + // _data = generator.byte; + // manager.writeBytes(_data); + // } + } + } +} diff --git a/lib/service/service.dart b/lib/service/service.dart new file mode 100644 index 0000000..1e0153e --- /dev/null +++ b/lib/service/service.dart @@ -0,0 +1,561 @@ +import 'dart:io'; +import 'package:flutter/services.dart'; +import 'package:image/image.dart' as img; +import 'package:path_provider/path_provider.dart'; +import 'package:pdf/pdf.dart' as pf; +import 'package:pdf/widgets.dart' as pw; +import 'package:drago_pos_printer/drago_pos_printer.dart'; +import 'package:printing/printing.dart'; +// import 'package:qr_flutter/qr_flutter.dart'; +import 'dart:math' as math; + +class ESCPrinterService { + final Uint8List? receipt; + List? _bytes; + + var dpi; + List? get bytes => _bytes; + int? _paperSizeWidthMM; + int? _maxPerLine; + CapabilityProfile? _profile; + + ESCPrinterService(this.receipt); + + Future> getBytes({ + int paperSizeWidthMM = PaperSizeWidth.mm80, + int maxPerLine = PaperSizeMaxPerLine.mm80, + CapabilityProfile? profile, + String name = "default", + }) async { + List bytes = []; + _profile = profile ?? (await CapabilityProfile.load(name: name)); + print(_profile!.name); + _paperSizeWidthMM = paperSizeWidthMM; + _maxPerLine = maxPerLine; + assert(receipt != null); + assert(_profile != null); + EscGenerator generator = + EscGenerator(_paperSizeWidthMM!, _maxPerLine!, _profile!); + var decodeImage = img.decodeImage(receipt!); + if (decodeImage == null) throw Exception('decoded image is null'); + final img.Image _resize = + img.copyResize(decodeImage, width: _paperSizeWidthMM); + + String dir = (await getTemporaryDirectory()).path; + String fullPath = '$dir/abc.png'; + print("local file full path ${fullPath}"); + File file = File(fullPath); + + await file.writeAsBytes(img.encodePng(decodeImage)); + + // OpenFile.open(fullPath); + + bytes += generator.image(_resize); + bytes += generator.feed(2); + bytes += generator.cut(); + return bytes; + } + + Future generateLabel(int width, int height, int labelWidth, + double horizontalGap, int column) async { + final doc = pw.Document(); + doc.addPage( + pw.Page( + pageFormat: pf.PdfPageFormat( + width * pf.PdfPageFormat.mm, height * pf.PdfPageFormat.mm), + build: (pw.Context context) => pw.Row(children: [ + for (int i = 0; i < column; i++) + pw.Expanded( + child: pw.Center( + child: pw.Column( + crossAxisAlignment: pw.CrossAxisAlignment.start, + mainAxisAlignment: pw.MainAxisAlignment.center, + children: [ + pw.SizedBox(height: 5), + pw.Text('Bodi ananatham department', + style: pw.TextStyle(fontSize: 6), + overflow: pw.TextOverflow.clip), + pw.SizedBox(height: 1), + //barcode + pw.BarcodeWidget( + width: 90, + height: 28, + data: '324324', + barcode: pw.Barcode.code39()), + //qr code + pw.Row(children: [ + pw.Container( + width: 3, + child: pw.Transform.rotateBox( + angle: math.pi / 180, + child: pw.Text( + '13232', + style: pw.TextStyle(fontSize: 5), + ), + ), + ), + pw.SizedBox(width: 2), + pw.BarcodeWidget( + width: 26, + height: 26, + data: '324324', + barcode: pw.Barcode.qrCode()), + pw.SizedBox(width: 5), + pw.Expanded( + child: pw.Column(children: [ + pw.Row(children: [ + pw.Expanded( + child: pw.Text('Rate', + style: pw.TextStyle(fontSize: 6))), + pw.Expanded( + child: pw.Text('0.52', + style: pw.TextStyle(fontSize: 6))), + ]), + pw.Row(children: [ + pw.Expanded( + child: pw.Text('MRP', + style: pw.TextStyle(fontSize: 6))), + pw.Expanded( + child: pw.Text('0.52', + style: pw.TextStyle(fontSize: 6))), + ]), + pw.Row(children: [ + pw.Expanded( + child: pw.Text('Mfd', + style: pw.TextStyle(fontSize: 6))), + pw.Expanded( + child: pw.Text('02/20/23', + style: pw.TextStyle(fontSize: 6))), + ]), + pw.Row(children: [ + pw.Expanded( + child: pw.Text('Expiry', + style: pw.TextStyle(fontSize: 6))), + pw.Expanded( + child: pw.Text('02/20/23', + style: pw.TextStyle(fontSize: 6))), + ]), + ])), + pw.SizedBox(width: 3), + ]), + pw.SizedBox(height: 1.5), + pw.Text('200g Horlicks Choclate flavor [iyj fdgdfgdf dfgdfg]', + style: pw.TextStyle(fontSize: 6)), + ]))) + ]), + ), + ); + + await for (var page in Printing.raster(await doc.save(), dpi: 203)) { + return page.asImage(); + } + return null; + } + + Future _generatePdf() async { + final doc = pw.Document(); + doc.addPage( + pw.Page( + pageFormat: pf.PdfPageFormat.roll57, + build: (pw.Context context) => pw.SizedBox( + height: 10 * pf.PdfPageFormat.mm, + child: pw.Center( + child: pw.Text('Hello World', style: pw.TextStyle(fontSize: 20)), + ), + ), + ), + ); + + return doc.save(); + } + + Future> getPdfBytes({ + int paperSizeWidthMM = PaperSizeMaxPerLine.mm80, + int maxPerLine = PaperSizeMaxPerLine.mm80, + CapabilityProfile? profile, + String name = "default", + }) async { + List bytes = []; + _profile = profile ?? (await CapabilityProfile.load(name: name)); + print(_profile!.name); + _paperSizeWidthMM = paperSizeWidthMM; + _maxPerLine = maxPerLine; + + EscGenerator generator = + EscGenerator(_paperSizeWidthMM!, _maxPerLine!, _profile!); + + await for (var page in Printing.raster(await _generatePdf(), dpi: 96)) { + final image = page.asImage(); + bytes += generator.image(image); + bytes += generator.reset(); + bytes += generator.cut(); + } + return bytes; + } + + Future> getSamplePosBytes({ + int paperSizeWidthMM = PaperSizeMaxPerLine.mm80, + int maxPerLine = PaperSizeMaxPerLine.mm80, + CapabilityProfile? profile, + String name = "default", + }) async { + List bytes = []; + _profile = profile ?? (await CapabilityProfile.load(name: name)); + print(_profile!.name); + _paperSizeWidthMM = paperSizeWidthMM; + _maxPerLine = maxPerLine; + EscGenerator ticket = + EscGenerator(_paperSizeWidthMM!, _maxPerLine!, _profile!); + bytes += ticket.reset(); + //Print image + // final ByteData data = await rootBundle.load('assets/logo.png'); + // final Uint8List imageBytes = data.buffer.asUint8List(); + // final img.Image? image = img.decodeImage(imageBytes); + // if (image != null) { + // img.Image thumbnail = img.copyResize(image, width: 400); + // bytes += ticket.image(thumbnail); + // bytes += ticket.reset(); + // } + + // bytes += ticket.text( + // 'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ'); + // bytes += ticket.text('Special 1: ', styles: PosStyles(codeTable: 'CP1252')); + // bytes += ticket.text('Special 2: blåbærgrød', + // styles: PosStyles(codeTable: 'CP1252')); + + // bytes += ticket.text('Bold text', styles: PosStyles(bold: true)); + // bytes += ticket.text('Reverse text', styles: PosStyles(reverse: true)); + // bytes += ticket.text('Underlined text', + // styles: PosStyles(underline: true), linesAfter: 1); + // bytes += ticket.text('Align left', styles: PosStyles(align: PosAlign.left)); + // bytes += + // ticket.text('Align center', styles: PosStyles(align: PosAlign.center)); + // bytes += ticket.text('Align right', + // styles: PosStyles(align: PosAlign.right), linesAfter: 1); + + // bytes += ticket.text('SKS DEPARTMENT STORE', + // styles: PosStyles( + // align: PosAlign.center, + // height: PosTextSize.size1, + // width: PosTextSize.size1, + // )); + + // bytes += ticket.text('889 Watson Lane', + // styles: PosStyles(align: PosAlign.center)); + // bytes += ticket.text('New Braunfels, TX', + // styles: PosStyles(align: PosAlign.center)); + // bytes += ticket.text('Tel: 830-221-1234', + // styles: PosStyles(align: PosAlign.center)); + // bytes += + // ticket.text('Web: .com', styles: PosStyles(align: PosAlign.center)); + + // bytes += ticket.hr(); + // bytes += ticket.row([ + // PosColumn(text: 'Qty', width: 1), + // PosColumn(text: 'Item', width: 5), + // PosColumn( + // text: 'Price', width: 3, styles: PosStyles(align: PosAlign.right)), + // PosColumn( + // text: 'Total ', width: 3, styles: PosStyles(align: PosAlign.right)), + // ]); + // bytes += ticket.hr(); + + // bytes += ticket.row([ + // PosColumn(text: '2', width: 1), + // PosColumn(text: 'ONION RINGS ONION RINGS ONION', width: 5), + // PosColumn( + // text: '0.99', width: 3, styles: PosStyles(align: PosAlign.right)), + // PosColumn( + // text: '1.98', width: 3, styles: PosStyles(align: PosAlign.right)), + // ]); + // bytes += ticket.row([ + // PosColumn(text: '1', width: 1), + // PosColumn(text: 'PIZZA', width: 7), + // PosColumn( + // text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)), + // PosColumn( + // text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)), + // ]); + // bytes += ticket.row([ + // PosColumn(text: '1', width: 1), + // PosColumn(text: 'SPRING ROLLS', width: 7), + // PosColumn( + // text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)), + // PosColumn( + // text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)), + // ]); + // bytes += ticket.row([ + // PosColumn(text: '3', width: 1), + // PosColumn(text: 'CRUNCHY STICKS', width: 7), + // PosColumn( + // text: '0.85', width: 2, styles: PosStyles(align: PosAlign.right)), + // PosColumn( + // text: '2.55', width: 2, styles: PosStyles(align: PosAlign.right)), + // ]); + // bytes += ticket.hr(); + + // bytes += ticket.row([ + // PosColumn( + // text: 'TOTAL', + // width: 6, + // styles: PosStyles( + // height: PosTextSize.size2, + // width: PosTextSize.size2, + // )), + // PosColumn( + // text: '\$10.97', + // width: 6, + // styles: PosStyles( + // align: PosAlign.right, + // height: PosTextSize.size2, + // width: PosTextSize.size2, + // )), + // ]); + + // bytes += ticket.hr(ch: '=', linesAfter: 1); + + // bytes += ticket.row([ + // PosColumn( + // text: 'CASH', + // width: 7, + // styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), + // PosColumn( + // text: '\$15.00', + // width: 5, + // styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), + // ]); + // bytes += ticket.row([ + // PosColumn( + // text: 'CHANGE', + // width: 7, + // styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), + // PosColumn( + // text: '\$4.03', + // width: 5, + // styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), + // ]); + + // bytes += ticket.feed(1); + bytes += ticket.text('Thank you!', + styles: PosStyles(align: PosAlign.center, bold: true)); + bytes += ticket.text('MM TOYS', + styles: const PosStyles(align: PosAlign.center, bold: true)); + + bytes += ticket.text('Cikijing, Talaga, Bantarujeg, Rancah', + styles: const PosStyles(align: PosAlign.center, bold: true)); + + bytes += ticket.row([ + PosColumn( + width: 6, + text: 'PENJUALAN :', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 6, + text: '2024-03-14', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + + bytes += ticket.row([ + PosColumn( + width: 8, + text: 'PELANGGAN : UMUM-RCH', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 4, + text: '15:30', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + + bytes += ticket.text('--------------------------------', + styles: const PosStyles(align: PosAlign.center)); + bytes += ticket.row([ + PosColumn( + width: 6, + text: 'Qty', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 6, + text: 'Nama Produk', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + ]); + + bytes += ticket.row([ + PosColumn( + width: 3, + text: 'Harga', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + PosColumn( + width: 3, + text: 'Dis.', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + PosColumn( + width: 3, + text: 'PPn', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + PosColumn( + width: 3, + text: 'Netto', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + + bytes += ticket.text('--------------------------------', + styles: const PosStyles(align: PosAlign.center)); + + // Dummy transaction data + List dummyProducts = [ + 'Product 1', + 'Product 2', + 'Product 3', + ]; + + for (var productName in dummyProducts) { + bytes += ticket.row([ + PosColumn( + width: 12, + text: '2 ${productName.toUpperCase()}', + styles: const PosStyles( + align: PosAlign.left, + codeTable: 'CP1252', + )), + ]); + + bytes += ticket.row([ + PosColumn( + width: 3, + text: '10.0', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 3, + text: '0.0', + styles: + const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + PosColumn( + width: 3, + text: '', + styles: + const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + PosColumn( + width: 3, + text: '20.0', + styles: + const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + } + + bytes += ticket.text('--------------------------------', + styles: const PosStyles(align: PosAlign.center)); + + // Dummy total and payment data + bytes += ticket.row([ + PosColumn( + width: 4, + text: 'Jumlah : 3', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 4, + text: 'Item : 6', + styles: const PosStyles(align: PosAlign.center, codeTable: 'CP1252')), + PosColumn( + width: 4, + text: '33.0', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + + // Dummy grand total, payment, change, and cashier data + bytes += ticket.row([ + PosColumn( + width: 6, + text: 'Grand Total', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 1, + text: ':', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 5, + text: '33.0', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + bytes += ticket.row([ + PosColumn( + width: 6, + text: 'Pembayaran', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 1, + text: ':', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 5, + text: '50.0', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + bytes += ticket.row([ + PosColumn( + width: 6, + text: 'Kembalian', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 1, + text: ':', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 5, + text: '17.0', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + bytes += ticket.row([ + PosColumn( + width: 6, + text: 'Kasir', + styles: const PosStyles(align: PosAlign.left, codeTable: 'CP1252')), + PosColumn( + width: 6, + text: 'Anisa', + styles: const PosStyles(align: PosAlign.right, codeTable: 'CP1252')), + ]); + + bytes += ticket.text('--------------------------------', + styles: const PosStyles(align: PosAlign.center)); + + bytes += ticket.text( + 'BARANG YANG SUDAH DI BELI TIDAK DAPAT DITUKAR / DIKEMBALIKAN', + styles: const PosStyles(align: PosAlign.center)); + bytes += ticket.text('TERIMA KASIH', + styles: const PosStyles(align: PosAlign.center)); + + // final now = DateTime.now(); + // final formatter = DateFormat('MM/dd/yyyy H:m'); + // final String timestamp = formatter.format(now); + // bytes += ticket.text(timestamp, + // styles: PosStyles(align: PosAlign.center), linesAfter: 2); + + //Print QR Code from image + // try { + // const String qrData = 'example.com'; + // const double qrSize = 100; + // final uiImg = await QrPainter( + // data: qrData, + // version: QrVersions.auto, + // gapless: false, + // ).toImageData(qrSize); + // final dir = await getTemporaryDirectory(); + // final pathName = '${dir.path}/qr_tmp.png'; + // final qrFile = File(pathName); + // final imgFile = await qrFile.writeAsBytes(uiImg!.buffer.asUint8List()); + // final image = img.decodeImage(imgFile.readAsBytesSync()); + + // bytes += ticket.image(image!); + // } catch (e) { + // print(e); + // } + + // Print QR Code using native function + // bytes += ticket.qrcode('example.com'); + + bytes += ticket.feed(1); + bytes += ticket.cut(); + + return bytes; + } +} diff --git a/lib/theme/theme.config.dart b/lib/theme/theme.config.dart new file mode 100644 index 0000000..297f020 --- /dev/null +++ b/lib/theme/theme.config.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +ThemeData theme({bool? useMaterial3}) { + return ThemeData( + useMaterial3: useMaterial3, + scaffoldBackgroundColor: Colors.white, + appBarTheme: appBarTheme(), + textTheme: textTheme(), + fontFamily: 'Nunito', + inputDecorationTheme: inputDecorationTheme(), + visualDensity: VisualDensity.adaptivePlatformDensity, + textSelectionTheme: const TextSelectionThemeData( + cursorColor: Color(0xFFFFC700), + ), + ); +} + +Theme disableMaterial3({required Widget child}) { + return Theme(data: theme(useMaterial3: false), child: child); +} + +Theme enableMaterial3({required Widget child}) { + return Theme(data: theme(useMaterial3: true), child: child); +} + +AppBarTheme appBarTheme() { + return const AppBarTheme( + color: Colors.white, + // backwardsCompatibility: false, + systemOverlayStyle: SystemUiOverlayStyle( + statusBarColor: Colors.white, + statusBarIconBrightness: Brightness.dark, + ), + + surfaceTintColor: Colors.white, + elevation: 0, + // textTheme: TextTheme( + // headline6: TextStyle(color: Color(0XFF8B8B8B), fontSize: 18), + // ), + ); +} + +TextTheme textTheme() { + return const TextTheme( + bodyLarge: TextStyle( + color: Color(0xFF0E0F0F), + fontSize: 16, + fontWeight: FontWeight.normal, + ), + ); +} + +InputDecorationTheme inputDecorationTheme() { + // OutlineInputBorder outlineInputBorder = OutlineInputBorder( + // borderRadius: BorderRadius.circular(28), + // borderSide: BorderSide(color: Pallete.textPrimary), + // gapPadding: 10, + // ); + + // return const InputDecorationTheme( + // // If you are using latest version of flutter then lable text and hint text shown like this + // // if you r using flutter less then 1.20.* then maybe this is not working properly + // // if we are define our floatingLabelBehavior in our theme then it's not applayed + // // floatingLabelBehavior: FloatingLabelBehavior.always, + // // contentPadding: EdgeInsets.symmetric(horizontal: 42, vertical: 20), + // // enabledBorder: outlineInputBorder, + // // focusedBorder: outlineInputBorder, + // // border: outlineInputBorder, + // ); + + return const InputDecorationTheme( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Color(0xFFFFC700), // Ganti dengan warna yang diinginkan + width: 2, // Atur lebar border sesuai kebutuhan + ), + borderRadius: BorderRadius.all(Radius.circular(8)))); +} diff --git a/lib/utils.dart b/lib/utils.dart new file mode 100644 index 0000000..e69de29 diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..034344d --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,78 @@ +name: max_print_plus +description: "A new Flutter plugin project." +version: 0.0.1 +homepage: + +environment: + sdk: ^3.5.0 + flutter: '>=3.3.0' + +dependencies: + drago_pos_printer: ^1.0.1 + flutter: + sdk: flutter + flutter_svg: ^2.0.10+1 + fluttertoast: ^8.2.8 + open_filex: ^4.5.0 + plugin_platform_interface: ^2.0.2 + shared_preferences: ^2.3.2 + webcontent_converter: ^0.0.9+2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^4.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) + # which should be registered in the plugin registry. This is required for + # using method channels. + # The Android 'package' specifies package in which the registered class is. + # This is required for using method channels on Android. + # The 'ffiPlugin' specifies that native code should be built and bundled. + # This is required for using `dart:ffi`. + # All these are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: com.example.max_print_plus + pluginClass: MaxPrintPlusPlugin + ios: + pluginClass: MaxPrintPlusPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/to/asset-from-package + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/to/font-from-package diff --git a/test/max_print_plus_method_channel_test.dart b/test/max_print_plus_method_channel_test.dart new file mode 100644 index 0000000..32bd57a --- /dev/null +++ b/test/max_print_plus_method_channel_test.dart @@ -0,0 +1,27 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:max_print_plus/max_print_plus_method_channel.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + MethodChannelMaxPrintPlus platform = MethodChannelMaxPrintPlus(); + const MethodChannel channel = MethodChannel('max_print_plus'); + + setUp(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( + channel, + (MethodCall methodCall) async { + return '42'; + }, + ); + }); + + tearDown(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, null); + }); + + test('getPlatformVersion', () async { + expect(await platform.getPlatformVersion(), '42'); + }); +} diff --git a/test/max_print_plus_test.dart b/test/max_print_plus_test.dart new file mode 100644 index 0000000..cf6a603 --- /dev/null +++ b/test/max_print_plus_test.dart @@ -0,0 +1,29 @@ +// import 'package:flutter_test/flutter_test.dart'; +// import 'package:max_print_plus/max_print_plus.dart'; +// import 'package:max_print_plus/max_print_plus_platform_interface.dart'; +// import 'package:max_print_plus/max_print_plus_method_channel.dart'; +// import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +// class MockMaxPrintPlusPlatform +// with MockPlatformInterfaceMixin +// implements MaxPrintPlusPlatform { + +// @override +// Future getPlatformVersion() => Future.value('42'); +// } + +// void main() { +// final MaxPrintPlusPlatform initialPlatform = MaxPrintPlusPlatform.instance; + +// test('$MethodChannelMaxPrintPlus is the default instance', () { +// expect(initialPlatform, isInstanceOf()); +// }); + +// test('getPlatformVersion', () async { +// MaxPrintPlus maxPrintPlusPlugin = MaxPrintPlus(); +// MockMaxPrintPlusPlatform fakePlatform = MockMaxPrintPlusPlatform(); +// MaxPrintPlusPlatform.instance = fakePlatform; + +// expect(await maxPrintPlusPlugin.getPlatformVersion(), '42'); +// }); +// }