diff --git a/README.md b/README.md index 874b839..9ed41c4 100644 --- a/README.md +++ b/README.md @@ -90,11 +90,25 @@ doc.addDrawer(StarXpandDocumentDrawer()); StarXpand.printDocument(printer, doc); ``` +Display: + +```dart +var displayDoc = StarXpandDocumentDisplay() + ..actionClearAll() + ..actionClearLine() + ..actionShowText("StarXpand says:\n") + ..actionClearLine() + ..actionShowText("Hello world!"); + +StarXpand.updateDisplay(printer, displayDoc); +``` + ## Available APIs ```dart +StarXpand.getStatus(printer); StarXpand.findPrinters(interfaces, timeout, callback); - +StarXpand.updateDisplay(printer, stringData); StarXpand.openDrawer(printer); StarXpand.printDocument(printer, document); StarXpand.startInputListener(printer); diff --git a/android/build.gradle b/android/build.gradle index 305f41d..37b528f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -25,7 +25,8 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 31 + namespace 'com.ovatu.starxpand' + compileSdkVersion 34 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -47,5 +48,5 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.starmicronics:stario10:1.3.0' + implementation 'com.starmicronics:stario10:1.5.0' } diff --git a/android/src/main/kotlin/com/ovatu/starxpand/StarxpandPlugin.kt b/android/src/main/kotlin/com/ovatu/starxpand/StarxpandPlugin.kt index 295f28a..d84b6aa 100644 --- a/android/src/main/kotlin/com/ovatu/starxpand/StarxpandPlugin.kt +++ b/android/src/main/kotlin/com/ovatu/starxpand/StarxpandPlugin.kt @@ -11,6 +11,7 @@ import androidx.core.app.ActivityCompat.requestPermissions import androidx.core.content.ContextCompat.checkSelfPermission import com.starmicronics.stario10.* import com.starmicronics.stario10.starxpandcommand.* +import com.starmicronics.stario10.starxpandcommand.display.Contrast import com.starmicronics.stario10.starxpandcommand.drawer.Channel import com.starmicronics.stario10.starxpandcommand.drawer.OpenParameter import com.starmicronics.stario10.starxpandcommand.printer.* @@ -28,610 +29,956 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch /** StarxpandPlugin */ -class StarxpandPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { - private val tag = "StarxpandPlugin" - - /// 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 - private lateinit var activity: Activity - - private var _manager: StarDeviceDiscoveryManager? = null - private var _printers: MutableMap = mutableMapOf() - private var _permissionCallback: ((requestCode: Int, permissions: Array, grantResults: IntArray)->Unit)? = null - - override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - channel = MethodChannel(flutterPluginBinding.binaryMessenger, "starxpand") - channel.setMethodCallHandler(this) - } - - override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { - channel.setMethodCallHandler(null) - } - - override fun onAttachedToActivity(binding: ActivityPluginBinding) { - Log.d(tag, "onAttachedToActivity") - activity = binding.activity - binding.addRequestPermissionsResultListener { requestCode, permissions, grantResults -> callPermissionCallbacks(requestCode, permissions, grantResults) } - } - - private fun callPermissionCallbacks(requestCode: Int, permissions: Array, grantResults: IntArray): Boolean { - Log.d(tag, "callPermissionCallbacks") - _permissionCallback?.invoke(requestCode, permissions, grantResults) - - return true - } - - override fun onDetachedFromActivityForConfigChanges() { - Log.d(tag, "onDetachedFromActivityForConfigChanges") - } - - override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { - Log.d(tag, "onReattachedToActivityForConfigChanges") - } - - override fun onDetachedFromActivity() { - Log.d(tag, "onDetachedFromActivity") - } - - override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { - Log.d(tag, "onMethodCall: ${call.method} - ${call.arguments}") - - when (call.method) { - "findPrinters" -> findPrinters(call.arguments as Map<*, *>, result) - "printDocument" -> printDocument(call.arguments as Map<*, *>, result) - "startInputListener" -> startInputListener(call.arguments as Map<*, *>, result) - "stopInputListener" -> stopInputListener(call.arguments as Map<*, *>, result) - else -> result.notImplemented() +class StarxpandPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { + private val tag = "StarxpandPlugin" + + /// 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 + private lateinit var activity: Activity + + private var _manager: StarDeviceDiscoveryManager? = null + private var _printers: MutableMap = mutableMapOf() + private var _permissionCallback: ((requestCode: Int, permissions: Array, grantResults: IntArray) -> Unit)? = + null + + override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + channel = MethodChannel(flutterPluginBinding.binaryMessenger, "starxpand") + channel.setMethodCallHandler(this) } - } - private fun getPrinter(map: Map<*, *>): StarPrinter { - val connection = StarConnectionSettings(interfaceTypeFromValue(map["interface"] as String)!!, map["identifier"] as String) + override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { + channel.setMethodCallHandler(null) + } - if (!_printers.containsKey(connection.toString())) { - val printer = StarPrinter(connection, activity) - _printers[connection.toString()] = printer + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + Log.d(tag, "onAttachedToActivity") + activity = binding.activity + binding.addRequestPermissionsResultListener { requestCode, permissions, grantResults -> + callPermissionCallbacks( + requestCode, + permissions, + grantResults + ) + } } - return _printers[connection.toString()]!! - } + private fun callPermissionCallbacks( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ): Boolean { + Log.d(tag, "callPermissionCallbacks") + _permissionCallback?.invoke(requestCode, permissions, grantResults) + + return true + } - private fun sendCallback(guid: String, type: String, payload: Map<*, *>) { - Log.d(tag, "sendCallback: $guid - $payload") + override fun onDetachedFromActivityForConfigChanges() { + Log.d(tag, "onDetachedFromActivityForConfigChanges") + } - activity.runOnUiThread { - channel.invokeMethod( - "callback", mutableMapOf( - "guid" to guid, - "type" to type, - "data" to payload - ) - ) + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + Log.d(tag, "onReattachedToActivityForConfigChanges") } - } - private var _findPrintersResult: Result? = null - private var _findPrintersArgs: Map<*, *>? = null + override fun onDetachedFromActivity() { + Log.d(tag, "onDetachedFromActivity") + } - private fun hasBluetoothPermission(): Boolean { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { - return true + override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { + Log.d(tag, "onMethodCall: ${call.method} - ${call.arguments}") + + when (call.method) { + "monitor" -> monitor(call.arguments as Map<*, *>, result) + "openConnection" -> openPrinterConnection(call.arguments as Map<*, *>, result) + "closeConnection" -> closePrinterConnection(call.arguments as Map<*, *>, result) + "getStatus" -> getStatus(call.arguments as Map<*, *>, result) + "findPrinters" -> findPrinters(call.arguments as Map<*, *>, result) + "printRawBytes" -> printRawBytes(call.arguments as Map<*, *>, result) + "printDocument" -> printDocument(call.arguments as Map<*, *>, result, 1) + "updateDisplay" -> printDocument(call.arguments as Map<*, *>, result, 1) + "startInputListener" -> startInputListener(call.arguments as Map<*, *>, result) + "stopInputListener" -> stopInputListener(call.arguments as Map<*, *>, result) + else -> result.notImplemented() + } } - return checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED - } - - private fun findPrinters(@NonNull args: Map<*, *>, result: Result, requestBluetooth: Boolean = true) { - Log.d("Discovery", "findPrinters") - _findPrintersResult = result - _findPrintersArgs = args - - val callbackGuid = args["callback"] as String? - val timeout = args["timeout"] as Int - val interfaces = args["interfaces"] as List<*> - - try { - val foundPrinters: MutableList = mutableListOf() - - // Specify your printer interface types. - val interfaceTypes: List = (interfaces.map { - when (it as String?) { - "lan" -> InterfaceType.Lan - "bluetooth" -> InterfaceType.Bluetooth - "bluetoothLE" -> InterfaceType.Bluetooth - "usb" -> InterfaceType.Usb - else -> InterfaceType.Unknown + private fun monitor(@NonNull args: Map<*, *>, result: Result) { + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + val printer = getPrinter(args["printer"] as Map<*, *>) + val callbackGuid = args["callback"] as String + + if (printer.connectionSettings.interfaceType != InterfaceType.Bluetooth) { + sendCallback( + callbackGuid, "monitor", mutableMapOf( + "updateType" to "connected", + "message" to "Not a bluetooth device, no need to continue." + ) + ) + return result.success(true) } - }).toList() - - if (interfaceTypes.contains(InterfaceType.Bluetooth)) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !hasBluetoothPermission() && requestBluetooth) { - _permissionCallback = { requestCode, _, grantResults -> - if (requestCode == 1000 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - findPrinters(args, result, false) - } else { - result.error("error", "Bluetooth permission denied", null) + + scope.launch { + // Callback for printer state changed. + printer.printerDelegate = object : PrinterDelegate() { + override fun onReady() { + super.onReady() + Log.d("Monitor", "Printer: Ready") + sendCallback( + callbackGuid, "onReady", mutableMapOf( + "updateType" to "connected", + "message" to "Ready for printing" + ) + ) + } + + override fun onError() { + super.onError() + Log.d("Monitor", "Printer: Error") + sendCallback( + callbackGuid, "onError", mutableMapOf( + "updateType" to "error", + "message" to "Printer error, please check the printer." + ) + ) + } + + override fun onCommunicationError(e: StarIO10Exception) { + super.onCommunicationError(e) + e.localizedMessage?.let { Log.d("OnCommunicationError", it) } + + sendCallback( + callbackGuid, "onCommunicationError", mutableMapOf( + "updateType" to "disconnected", + "message" to e.localizedMessage + ) + ) + } } - } - requestPermissions(activity, - arrayOf( - Manifest.permission.BLUETOOTH_CONNECT, - ), 1000 - ) + printer.drawerDelegate = object : DrawerDelegate() { + override fun onOpenCloseSignalSwitched(openCloseSignal: Boolean) { + super.onOpenCloseSignalSwitched(openCloseSignal) + Log.d("Monitor", "Drawer: Open Close Signal Switched: ${openCloseSignal}") + } - Log.d("Discovery", "requesting bluetooth permission") + // ... + // Please refer to document for other callback. + } - return - } - } - - _manager = StarDeviceDiscoveryManagerFactory.create( - interfaceTypes, - activity - ) - - _manager?.discoveryTime = timeout - _manager?.callback = object : StarDeviceDiscoveryManager.Callback { - // Callback for printer found. - override fun onPrinterFound(printer: StarPrinter) { - foundPrinters.add(printer) - if (callbackGuid != null) { - sendCallback(callbackGuid, "printerFound", mutableMapOf( - "model" to printer.information?.model?.value(), - "identifier" to printer.connectionSettings.identifier, - "interface" to printer.connectionSettings.interfaceType.value() - )) - } - } + printer.inputDeviceDelegate = object : InputDeviceDelegate() { + override fun onDataReceived(data: List) { + super.onDataReceived(data) + Log.d("Monitor", "Input Device: DataReceived ${data}") + } - // Callback for discovery finished. (option) - override fun onDiscoveryFinished() { - result.success(mutableMapOf( - "printers" to foundPrinters.map { - mutableMapOf( - "model" to it.information?.model?.value(), - "identifier" to it.connectionSettings.identifier, - "interface" to it.connectionSettings.interfaceType.value() + // ... + // Please refer to document for other callback. + } + + printer.displayDelegate = object : DisplayDelegate() { + override fun onConnected() { + super.onConnected() + Log.d("Monitor", "Display: Connected") + } + + // ... + // Please refer to document for other callback. + } + + try { + Log.d("Monitor", "Printer: $printer") + + // Close if the printer was connected already. + printer.closeAsync().await() + + // Open the printer connection + printer.openAsync().await() + } catch (e: Exception) { + // Exception. + e.localizedMessage?.let { Log.d("Monitor", it) } + sendCallback( + callbackGuid, "monitor", mutableMapOf( + "updateType" to "disconnected", + "message" to "Could not connect" ) - } - )) + ) + } } - } - - _manager?.startDiscovery() - } catch (e: Exception) { - // Exception. - Log.d("Discovery", "${e.message}") - result.error("error", e.localizedMessage, e) } - } - private fun stopInputListener(@NonNull args: Map<*, *>, result: Result) { - Log.d("Discovery", "startInputListener. ${args["printer"]}") - val printer = getPrinter(args["printer"] as Map<*, *>) + private fun openPrinterConnection(@NonNull args: Map<*, *>, result: Result) { + val printer = getPrinter(args["printer"] as Map<*, *>) - val job = SupervisorJob() - val scope = CoroutineScope(Dispatchers.Default + job) - scope.launch { - closePrinter(printer) + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + scope.launch { + val res = openPrinter(printer) - result.success(true) + Log.d( + "OpenPrinterConnection", + "Opening printer connection to ${printer.connectionSettings.identifier}" + ) + result.success(res); + } } - } - private fun startInputListener(@NonNull args: Map<*, *>, result: Result) { - Log.d("Discovery", "startInputListener. ${args["printer"]}") - val callbackGuid = args["callback"] as String + private fun closePrinterConnection(@NonNull args: Map<*, *>, result: Result) { + val printer = getPrinter(args["printer"] as Map<*, *>) + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + scope.launch { + result.success(closePrinter(printer)); + } + } - val printer = getPrinter(args["printer"] as Map<*, *>) + private fun getStatus(@NonNull args: Map<*, *>, result: Result) { + val printer = getPrinter(args["printer"] as Map<*, *>) + Log.d("status", "GetPrinterStatus $printer") + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + scope.launch { + if (openPrinter(printer)) { + try { + + val status = printer.getStatusAsync().await(); + result.success( + mutableMapOf( + "hasError" to status.hasError, + "coverOpen" to status.coverOpen, + "drawerOpenCloseSignal" to status.drawerOpenCloseSignal, + "paperEmpty" to status.paperEmpty, + "paperNearEmpty" to status.paperNearEmpty, + "reserved" to status.reserved, + "detail" to mutableMapOf( + "cleaningNotification" to status.detail.cleaningNotification, + "cutterError" to status.detail.cutterError, + "detectedPaperWidth" to status.detail.detectedPaperWidth, + "drawer1OpenCloseSignal" to status.detail.drawer1OpenCloseSignal, + "drawer1OpenedMethod" to status.detail.drawer1OpenedMethod?.value(), + "drawer2OpenCloseSignal" to status.detail.drawer2OpenCloseSignal, + "drawer2OpenedMethod" to status.detail.drawer2OpenedMethod?.value(), + "drawerOpenError" to status.detail.drawerOpenError, + "externalDevice1Connected" to status.detail.externalDevice1Connected, + "externalDevice2Connected" to status.detail.externalDevice2Connected, + "paperJamError" to status.detail.paperJamError, + "paperPresent" to status.detail.paperPresent, + "paperSeparatorError" to status.detail.paperSeparatorError, + "partsReplacementNotification" to status.detail.partsReplacementNotification, + "printUnitOpen" to status.detail.printUnitOpen, + "rollPositionError" to status.detail.rollPositionError, + ), + ) + ) + } catch (e: java.lang.Exception) { + Log.d("status", "GetStatusError $e") + result.error("error", e.localizedMessage, e) + } finally { + closePrinter(printer) + } + } + } + } - printer.inputDeviceDelegate = object : InputDeviceDelegate() { - override fun onDataReceived(data: List) { - super.onDataReceived(data) + private fun getPrinter(map: Map<*, *>): StarPrinter { + val connection = StarConnectionSettings( + interfaceTypeFromValue(map["interface"] as String)!!, + map["identifier"] as String + ) - val string = String(data.toByteArray()) + if (!_printers.containsKey(connection.toString())) { + val printer = StarPrinter(connection, activity) + _printers[connection.toString()] = printer + } - sendCallback(callbackGuid, "dataReceived", mutableMapOf( - "data" to data.toByteArray(), - "string" to string - )) - } + return _printers[connection.toString()]!! } - val job = SupervisorJob() - val scope = CoroutineScope(Dispatchers.Default + job) - scope.launch { - try { - closePrinter(printer) - openPrinter(printer) - - result.success(true) - } catch (e: Exception) { - result.error("error", e.localizedMessage, e) - } - } - } - - private suspend fun openPrinter(printer: StarPrinter): Boolean { - return try { - printer.openAsync().await() - true - } catch (e: Exception) { - e is StarIO10InvalidOperationException + private fun sendCallback(guid: String, type: String, payload: Map<*, *>) { + Log.d(tag, "sendCallback: $guid - $payload") + + activity.runOnUiThread { + channel.invokeMethod( + "callback", mutableMapOf( + "guid" to guid, + "type" to type, + "data" to payload + ) + ) + } } - } + private var _findPrintersResult: Result? = null + private var _findPrintersArgs: Map<*, *>? = null - private suspend fun closePrinter(printer: StarPrinter): Boolean { - return try { - printer.closeAsync().await() - true - } catch (e: Exception) { - false - } - } + private fun hasBluetoothPermission(): Boolean { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + return true + } - private fun printDocument(@NonNull args: Map<*, *>, result: Result) { - Log.d("print", "print. ${args["printer"]}") + return checkSelfPermission( + activity, + Manifest.permission.BLUETOOTH_CONNECT + ) == PackageManager.PERMISSION_GRANTED + } - val printer = getPrinter(args["printer"] as Map<*, *>) - val document = args["document"] as Map<*, *> - val contents = document["contents"] as Collection<*> + private fun findPrinters( + @NonNull args: Map<*, *>, + result: Result, + requestBluetooth: Boolean = true + ) { + Log.d("Discovery", "findPrinters") + _findPrintersResult = result + _findPrintersArgs = args - Log.d("print", "document: $document") + val callbackGuid = args["callback"] as String? + val timeout = args["timeout"] as Int + val interfaces = args["interfaces"] as List<*> - val job = SupervisorJob() - val scope = CoroutineScope(Dispatchers.Default + job) - scope.launch { - if (openPrinter(printer)) { try { - val builder = StarXpandCommandBuilder() - val docBuilder = DocumentBuilder() - - for (content in contents) { - if (content !is Map<*, *>) continue - - val type = content["type"] as String - val data = content["data"] as Map<*, *> - - when (type) { - "drawer" -> { - docBuilder.addDrawer(getDrawerBuilder(data)) - } - "print" -> { - docBuilder.addPrinter(getPrinterBuilder(data)) - } - } - } + val foundPrinters: MutableList = mutableListOf() + + // Specify your printer interface types. + val interfaceTypes: List = (interfaces.map { + when (it as String?) { + "lan" -> InterfaceType.Lan + "bluetooth" -> InterfaceType.Bluetooth + "bluetoothLE" -> InterfaceType.Bluetooth + "usb" -> InterfaceType.Usb + else -> InterfaceType.Unknown + } + }).toList() + + if (interfaceTypes.contains(InterfaceType.Bluetooth)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !hasBluetoothPermission() && requestBluetooth) { + _permissionCallback = { requestCode, _, grantResults -> + if (requestCode == 1000 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + findPrinters(args, result, false) + } else { + result.error("error", "Bluetooth permission denied", null) + } + } + + requestPermissions( + activity, + arrayOf( + Manifest.permission.BLUETOOTH_CONNECT, + ), 1000 + ) - builder.addDocument(docBuilder) + Log.d("Discovery", "requesting bluetooth permission") - // Get printing data from StarXpandCommandBuilder object. - val commands = builder.getCommands() + return + } + } - Log.d("print", "commands $commands") + _manager = StarDeviceDiscoveryManagerFactory.create( + interfaceTypes, + activity + ) + + _manager?.discoveryTime = timeout + _manager?.callback = object : StarDeviceDiscoveryManager.Callback { + // Callback for printer found. + override fun onPrinterFound(printer: StarPrinter) { + foundPrinters.add(printer) + if (callbackGuid != null) { + sendCallback( + callbackGuid, "printerFound", mutableMapOf( + "model" to printer.information?.model?.value(), + "identifier" to printer.connectionSettings.identifier, + "interface" to printer.connectionSettings.interfaceType.value() + ) + ) + } + } + + // Callback for discovery finished. (option) + override fun onDiscoveryFinished() { + result.success(mutableMapOf( + "printers" to foundPrinters.map { + mutableMapOf( + "model" to it.information?.model?.value(), + "identifier" to it.connectionSettings.identifier, + "interface" to it.connectionSettings.interfaceType.value() + ) + } + )) + } + } - // Print. - printer.printAsync(commands).await() - result.success(true) - } catch (e: java.lang.Exception) { - Log.d("print", "commands $e") - result.error("error", e.localizedMessage, e) - } finally { - closePrinter(printer) + _manager?.startDiscovery() + } catch (e: Exception) { + // Exception. + Log.d("Discovery", "${e.message}") + result.error("error", e.localizedMessage, e) } - } } - } - private fun getDrawerBuilder(data: Map<*, *>): DrawerBuilder { - val channel = when (data["channel"]) { - "no1" -> Channel.No1 - "no2" -> Channel.No2 - else -> Channel.No1 + private fun stopInputListener(@NonNull args: Map<*, *>, result: Result) { + Log.d("Discovery", "startInputListener. ${args["printer"]}") + val printer = getPrinter(args["printer"] as Map<*, *>) + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + scope.launch { + closePrinter(printer) + + result.success(true) + } } - return DrawerBuilder().actionOpen(OpenParameter().setChannel(channel)) - } - private fun getPrinterBuilder(data: Map<*, *>): PrinterBuilder { - val printerBuilder = PrinterBuilder() + private fun startInputListener(@NonNull args: Map<*, *>, result: Result) { + Log.d("Discovery", "startInputListener. ${args["printer"]}") + val callbackGuid = args["callback"] as String - val actions = data["actions"] as Collection<*> + val printer = getPrinter(args["printer"] as Map<*, *>) - Log.d("print", "print actions: $actions") + printer.inputDeviceDelegate = object : InputDeviceDelegate() { + override fun onDataReceived(data: List) { + super.onDataReceived(data) - for (action in actions) { - if (action !is Map<*, *>) continue + val string = String(data.toByteArray()) - when (action["action"] as String) { - "add" -> { - printerBuilder.add(getPrinterBuilder(action["data"] as Map<*, *>)) - } - "style" -> { - if (action["alignment"] != null) { - printerBuilder.styleAlignment(when (action["alignment"]) { - "left" -> Alignment.Left - "center" -> Alignment.Center - "right" -> Alignment.Right - else -> Alignment.Left - }) - } - - if (action["fontType"] != null) { - printerBuilder.styleFont(when (action["fontType"]) { - "a" -> FontType.A - "b" -> FontType.B - else -> FontType.A - }) - } - - if (action["bold"] != null) { - printerBuilder.styleBold(action["bold"] as Boolean) - } - - if (action["invert"] != null) { - printerBuilder.styleInvert(action["invert"] as Boolean) - } - - if (action["underLine"] != null) { - printerBuilder.styleUnderLine(action["underLine"] as Boolean) - } - - if (action["magnification"] != null) { - val magnification = action["magnification"] as Map<*, *> - - printerBuilder.styleMagnification(MagnificationParameter(magnification["width"] as Int, magnification["height"] as Int)) - } - - if (action["characterSpace"] != null) { - printerBuilder.styleCharacterSpace(action["characterSpace"] as Double) - } - - if (action["lineSpace"] != null) { - printerBuilder.styleLineSpace(action["lineSpace"] as Double) - } - - if (action["horizontalPositionTo"] != null) { - printerBuilder.styleHorizontalPositionTo(action["horizontalPositionTo"] as Double) - } - - if (action["horizontalPositionBy"] != null) { - printerBuilder.styleHorizontalPositionBy(action["horizontalPositionBy"] as Double) - } - - if (action["horizontalTabPosition"] != null) { - printerBuilder.styleHorizontalTabPositions((action["horizontalTabPosition"] as List<*>).map { it as Int }) - } - - if (action["internationalCharacter"] != null) { - printerBuilder.styleInternationalCharacter(when (action["internationalCharacter"]) { - "usa" -> InternationalCharacterType.Usa - "france" -> InternationalCharacterType.France - "germany" -> InternationalCharacterType.Germany - "uk" -> InternationalCharacterType.UK - "denmark" -> InternationalCharacterType.Denmark - "sweden" -> InternationalCharacterType.Sweden - "italy" -> InternationalCharacterType.Italy - "spain" -> InternationalCharacterType.Spain - "japan" -> InternationalCharacterType.Japan - "norway" -> InternationalCharacterType.Norway - "denmark2" -> InternationalCharacterType.Denmark2 - "spain2" -> InternationalCharacterType.Spain2 - "latinAmerica" -> InternationalCharacterType.LatinAmerica - "korea" -> InternationalCharacterType.Korea - "ireland" -> InternationalCharacterType.Ireland - "slovenia" -> InternationalCharacterType.Slovenia - "croatia" -> InternationalCharacterType.Croatia - "china" -> InternationalCharacterType.China - "vietnam" -> InternationalCharacterType.Vietnam - "arabic" -> InternationalCharacterType.Arabic - "legal" -> InternationalCharacterType.Legal - else -> InternationalCharacterType.Usa - }) - } - - if (action["secondPriorityCharacterEncoding"] != null) { - printerBuilder.styleSecondPriorityCharacterEncoding(when (data["secondPriorityCharacterEncoding"]) { - "japanese" -> CharacterEncodingType.Japanese - "simplifiedChinese" -> CharacterEncodingType.SimplifiedChinese - "traditionalChinese" -> CharacterEncodingType.TraditionalChinese - "korean" -> CharacterEncodingType.Korean - "codePage" -> CharacterEncodingType.CodePage - else -> CharacterEncodingType.CodePage - }) - } - - if (action["cjkCharacterPriority"] != null) { - printerBuilder.styleCjkCharacterPriority((action["cjkCharacterPriority"] as List<*>).map { - when (it as String?) { - "japanese" -> CjkCharacterType.Japanese - "simplifiedChinese" -> CjkCharacterType.SimplifiedChinese - "traditionalChinese" -> CjkCharacterType.TraditionalChinese - "korean" -> CjkCharacterType.Korean - else -> CjkCharacterType.Japanese - } - }) - } - } - "cut" -> { - val cutType = when (action["type"]) { - "full" -> CutType.Full - "partial" -> CutType.Partial - "fullDirect" -> CutType.FullDirect - "partialDirect" -> CutType.PartialDirect - else -> CutType.Partial - } - printerBuilder.actionCut(cutType) + sendCallback( + callbackGuid, "dataReceived", mutableMapOf( + "data" to data.toByteArray(), + "string" to string + ) + ) + } } - "feed" -> { - val height = (action["height"] as Double?) ?: 10.0 - printerBuilder.actionFeed(height) + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + scope.launch { + try { + closePrinter(printer) + openPrinter(printer) + + result.success(true) + } catch (e: Exception) { + result.error("error", e.localizedMessage, e) + } } - "feedLine" -> { - val lines = (action["lines"] as Int?) ?: 1 - printerBuilder.actionFeedLine(lines) + } + + private suspend fun openPrinter(printer: StarPrinter): Boolean { + return try { + printer.openAsync().await() + true + } catch (e: Exception) { + e is StarIO10InvalidOperationException } - "printText" -> { - val text = action["text"] as String - printerBuilder.actionPrintText(text) + } + + + private suspend fun closePrinter(printer: StarPrinter): Boolean { + return try { + printer.closeAsync().await() + true + } catch (e: Exception) { + false } - "printLogo" -> { - val keyCode = action["keyCode"] as String - printerBuilder.actionPrintLogo(LogoParameter(keyCode)) + } + + private fun printRawBytes(@NonNull args: Map<*, *>, result: Result) { + val printer = getPrinter(args["printer"] as Map<*, *>) + val bytes = args["bytes"] as? ByteArray + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + + scope.launch { + try { + printer.openAsync().await() + if (bytes != null) { + printer.printRawDataAsync(bytes.toList()).await() + } + } catch (e: java.lang.Exception) { + Log.d("print", "commands $e") + result.error("error", e.localizedMessage, e) + } finally { + if (printer.connectionSettings.interfaceType != InterfaceType.Bluetooth) { + printer.closeAsync().await() + } + } } - "printBarcode" -> { - val barcodeContent = action["content"] as String - val symbology = when (action["symbology"] as String) { - "upcE" -> BarcodeSymbology.UpcE - "upcA" -> BarcodeSymbology.UpcA - "jan8" -> BarcodeSymbology.Jan8 - "ean8" -> BarcodeSymbology.Ean8 - "jan13" -> BarcodeSymbology.Jan13 - "ean13" -> BarcodeSymbology.Ean13 - "code39" -> BarcodeSymbology.Code39 - "itf" -> BarcodeSymbology.Itf - "code128" -> BarcodeSymbology.Code128 - "code93" -> BarcodeSymbology.Code93 - "nw7" -> BarcodeSymbology.NW7 - else -> BarcodeSymbology.UpcE - } - - val param = BarcodeParameter(barcodeContent, symbology) - if (action["printHri"] != null) { - param.setPrintHri(action["printHri"] as Boolean) - } - if (action["barDots"] != null) { - param.setBarDots(action["barDots"] as Int) - } - if (action["barRatioLevel"] != null) { - param.setBarRatioLevel(when (action["barRatioLevel"] as String) { - "levelPlus1" -> BarcodeBarRatioLevel.LevelPlus1 - "level0" -> BarcodeBarRatioLevel.Level0 - "levelMinus1" -> BarcodeBarRatioLevel.LevelMinus1 - else -> BarcodeBarRatioLevel.Level0 - }) - } - if (action["height"] != null) { - param.setHeight(action["height"] as Double) - } - - printerBuilder.actionPrintBarcode(param) + } + + private fun printDocument(@NonNull args: Map<*, *>, result: Result, attempt: Int) { + Log.d("print", "${args["printer"]}") + + val printer = getPrinter(args["printer"] as Map<*, *>) + val document = args["document"] as Map<*, *> + val contents = document["contents"] as Collection<*> + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Default + job) + + scope.launch { + try { + val builder = StarXpandCommandBuilder() + val docBuilder = DocumentBuilder() + + for (content in contents) { + if (content !is Map<*, *>) continue + + val type = content["type"] as String + val data = content["data"] as Map<*, *> + + when (type) { + "drawer" -> { + docBuilder.addDrawer(getDrawerBuilder(data)) + } + + "print" -> { + docBuilder.addPrinter(getPrinterBuilder(data)) + } + + "display" -> { + docBuilder.addDisplay(getDisplayBuilder(data)) + } + } + } + + builder.addDocument(docBuilder) + + // Get printing data from StarXpandCommandBuilder object. + val commands = builder.getCommands() + Log.d("print", "commands $commands") + + openPrinter(printer) + printer.printAsync(commands).await() + result.success(true) + } catch (e: java.lang.Exception) { + Log.d("print", "commands $e") + result.error("error", e.localizedMessage, e) + } finally { + closePrinter(printer) + } } - "printPdf417" -> { - val pdf417Content = action["content"] as String - val param = Pdf417Parameter(pdf417Content) - - if (action["column"] != null) { - param.setColumn(action["column"] as Int) - } - if (action["line"] != null) { - param.setLine(action["line"] as Int) - } - if (action["module"] != null) { - param.setModule(action["module"] as Int) - } - if (action["aspect"] != null) { - param.setAspect(action["aspect"] as Int) - } - if (action["level"] != null) { - param.setLevel(when (action["level"] as String) { - "ecc0" -> Pdf417Level.Ecc0 - "ecc1" -> Pdf417Level.Ecc1 - "ecc2" -> Pdf417Level.Ecc2 - "ecc3" -> Pdf417Level.Ecc3 - "ecc4" -> Pdf417Level.Ecc4 - "ecc5" -> Pdf417Level.Ecc5 - "ecc6" -> Pdf417Level.Ecc6 - "ecc7" -> Pdf417Level.Ecc7 - "ecc8" -> Pdf417Level.Ecc8 - else -> Pdf417Level.Ecc0 - }) - } - - printerBuilder.actionPrintPdf417(param) + } + + private fun getDrawerBuilder(data: Map<*, *>): DrawerBuilder { + val channel = when (data["channel"]) { + "no1" -> Channel.No1 + "no2" -> Channel.No2 + else -> Channel.No1 } - "printQRCode" -> { - val qrContent = action["content"] as String - val param = QRCodeParameter(qrContent) - - if (action["model"] != null) { - param.setModel(when (action["model"] as String) { - "model1" -> QRCodeModel.Model1 - "model2" -> QRCodeModel.Model2 - else -> QRCodeModel.Model1 - }) - } - if (action["level"] != null) { - param.setLevel(when (action["level"] as String) { - "l" -> QRCodeLevel.L - "m" -> QRCodeLevel.M - "q" -> QRCodeLevel.Q - "h" -> QRCodeLevel.H - else -> QRCodeLevel.L - }) - } - if (action["cellSize"] != null) { - param.setCellSize(action["cellSize"] as Int) - } - - printerBuilder.actionPrintQRCode(param) + return DrawerBuilder().actionOpen(OpenParameter().setChannel(channel)) + } + + private fun getDisplayBuilder(data: Map<*, *>): DisplayBuilder { + val displayBuilder = DisplayBuilder() + val actions = data["actions"] as Collection<*> + + Log.d("display", "display actions: $actions") + + for (action in actions) { + if (action !is Map<*, *>) continue + + when (action["action"] as String) { + "showText" -> { + displayBuilder.actionShowText(action["data"] as String) + } + + "clearAll" -> { + displayBuilder.actionClearAll() + } + + "clearLine" -> { + displayBuilder.actionClearLine() + } + + "setContrast" -> { + displayBuilder.actionSetContrast( + when (action["data"]) { + "minus3" -> Contrast.Minus3 + "minus2" -> Contrast.Minus2 + "minus1" -> Contrast.Minus1 + "plus1" -> Contrast.Plus1 + "plus2" -> Contrast.Plus2 + "plus3" -> Contrast.Plus3 + else -> Contrast.Default + } + ) + } + + "showImage" -> { + val image = action["image"] as ByteArray + val bmp = BitmapFactory.decodeByteArray(image, 0, image.size) + displayBuilder.actionShowImage( + com.starmicronics.stario10.starxpandcommand.display.ImageParameter( + bmp + ) + ) + } + } } - "printImage" -> { - val image = action["image"] as ByteArray - val width = action["width"] as Int - val bmp = BitmapFactory.decodeByteArray(image, 0, image.size) - printerBuilder.actionPrintImage(ImageParameter(bmp, width)) + + return displayBuilder + } + + private fun getPrinterBuilder(data: Map<*, *>): PrinterBuilder { + val printerBuilder = PrinterBuilder() + + val actions = data["actions"] as Collection<*> + + Log.d("print", "print actions: $actions") + + for (action in actions) { + if (action !is Map<*, *>) continue + + when (action["action"] as String) { + "add" -> { + printerBuilder.add(getPrinterBuilder(action["data"] as Map<*, *>)) + } + + "style" -> { + if (action["alignment"] != null) { + printerBuilder.styleAlignment( + when (action["alignment"]) { + "left" -> Alignment.Left + "center" -> Alignment.Center + "right" -> Alignment.Right + else -> Alignment.Left + } + ) + } + + if (action["fontType"] != null) { + printerBuilder.styleFont( + when (action["fontType"]) { + "a" -> FontType.A + "b" -> FontType.B + else -> FontType.A + } + ) + } + + if (action["bold"] != null) { + printerBuilder.styleBold(action["bold"] as Boolean) + } + + if (action["invert"] != null) { + printerBuilder.styleInvert(action["invert"] as Boolean) + } + + if (action["underLine"] != null) { + printerBuilder.styleUnderLine(action["underLine"] as Boolean) + } + + if (action["magnification"] != null) { + val magnification = action["magnification"] as Map<*, *> + + printerBuilder.styleMagnification( + MagnificationParameter( + magnification["width"] as Int, + magnification["height"] as Int + ) + ) + } + + if (action["characterSpace"] != null) { + printerBuilder.styleCharacterSpace(action["characterSpace"] as Double) + } + + if (action["lineSpace"] != null) { + printerBuilder.styleLineSpace(action["lineSpace"] as Double) + } + + if (action["horizontalPositionTo"] != null) { + printerBuilder.styleHorizontalPositionTo(action["horizontalPositionTo"] as Double) + } + + if (action["horizontalPositionBy"] != null) { + printerBuilder.styleHorizontalPositionBy(action["horizontalPositionBy"] as Double) + } + + if (action["horizontalTabPosition"] != null) { + printerBuilder.styleHorizontalTabPositions((action["horizontalTabPosition"] as List<*>).map { it as Int }) + } + + if (action["internationalCharacter"] != null) { + printerBuilder.styleInternationalCharacter( + when (action["internationalCharacter"]) { + "usa" -> InternationalCharacterType.Usa + "france" -> InternationalCharacterType.France + "germany" -> InternationalCharacterType.Germany + "uk" -> InternationalCharacterType.UK + "denmark" -> InternationalCharacterType.Denmark + "sweden" -> InternationalCharacterType.Sweden + "italy" -> InternationalCharacterType.Italy + "spain" -> InternationalCharacterType.Spain + "japan" -> InternationalCharacterType.Japan + "norway" -> InternationalCharacterType.Norway + "denmark2" -> InternationalCharacterType.Denmark2 + "spain2" -> InternationalCharacterType.Spain2 + "latinAmerica" -> InternationalCharacterType.LatinAmerica + "korea" -> InternationalCharacterType.Korea + "ireland" -> InternationalCharacterType.Ireland + "slovenia" -> InternationalCharacterType.Slovenia + "croatia" -> InternationalCharacterType.Croatia + "china" -> InternationalCharacterType.China + "vietnam" -> InternationalCharacterType.Vietnam + "arabic" -> InternationalCharacterType.Arabic + "legal" -> InternationalCharacterType.Legal + else -> InternationalCharacterType.Usa + } + ) + } + + if (action["secondPriorityCharacterEncoding"] != null) { + printerBuilder.styleSecondPriorityCharacterEncoding( + when (data["secondPriorityCharacterEncoding"]) { + "japanese" -> CharacterEncodingType.Japanese + "simplifiedChinese" -> CharacterEncodingType.SimplifiedChinese + "traditionalChinese" -> CharacterEncodingType.TraditionalChinese + "korean" -> CharacterEncodingType.Korean + "codePage" -> CharacterEncodingType.CodePage + else -> CharacterEncodingType.CodePage + } + ) + } + + if (action["cjkCharacterPriority"] != null) { + printerBuilder.styleCjkCharacterPriority((action["cjkCharacterPriority"] as List<*>).map { + when (it as String?) { + "japanese" -> CjkCharacterType.Japanese + "simplifiedChinese" -> CjkCharacterType.SimplifiedChinese + "traditionalChinese" -> CjkCharacterType.TraditionalChinese + "korean" -> CjkCharacterType.Korean + else -> CjkCharacterType.Japanese + } + }) + } + } + + "cut" -> { + val cutType = when (action["type"]) { + "full" -> CutType.Full + "partial" -> CutType.Partial + "fullDirect" -> CutType.FullDirect + "partialDirect" -> CutType.PartialDirect + else -> CutType.Partial + } + printerBuilder.actionCut(cutType) + } + + "feed" -> { + val height = (action["height"] as Double?) ?: 10.0 + printerBuilder.actionFeed(height) + } + + "feedLine" -> { + val lines = (action["lines"] as Int?) ?: 1 + printerBuilder.actionFeedLine(lines) + } + + "printText" -> { + val text = action["text"] as String + printerBuilder.actionPrintText(text) + } + + "printRuledLine" -> { + val ruleLineWidth = action["width"] as Double + val parameters = RuledLineParameter(ruleLineWidth) + + if (action["thickness"] != null) { + parameters.setThickness(action["thickness"] as Double) + } + + if (action["lineStyle"] != null) { + val lineStyle = when (action["lineStyle"] as String) { + "double" -> LineStyle.Double + else -> LineStyle.Single + } + + parameters.setLineStyle(lineStyle) + } + + printerBuilder.actionPrintRuledLine(parameters) + } + + "printLogo" -> { + val keyCode = action["keyCode"] as String + printerBuilder.actionPrintLogo(LogoParameter(keyCode)) + } + + "printBarcode" -> { + val barcodeContent = action["content"] as String + val symbology = when (action["symbology"] as String) { + "upcE" -> BarcodeSymbology.UpcE + "upcA" -> BarcodeSymbology.UpcA + "jan8" -> BarcodeSymbology.Jan8 + "ean8" -> BarcodeSymbology.Ean8 + "jan13" -> BarcodeSymbology.Jan13 + "ean13" -> BarcodeSymbology.Ean13 + "code39" -> BarcodeSymbology.Code39 + "itf" -> BarcodeSymbology.Itf + "code128" -> BarcodeSymbology.Code128 + "code93" -> BarcodeSymbology.Code93 + "nw7" -> BarcodeSymbology.NW7 + else -> BarcodeSymbology.UpcE + } + + val param = BarcodeParameter(barcodeContent, symbology) + if (action["printHri"] != null) { + param.setPrintHri(action["printHri"] as Boolean) + } + if (action["barDots"] != null) { + param.setBarDots(action["barDots"] as Int) + } + if (action["barRatioLevel"] != null) { + param.setBarRatioLevel( + when (action["barRatioLevel"] as String) { + "levelPlus1" -> BarcodeBarRatioLevel.LevelPlus1 + "level0" -> BarcodeBarRatioLevel.Level0 + "levelMinus1" -> BarcodeBarRatioLevel.LevelMinus1 + else -> BarcodeBarRatioLevel.Level0 + } + ) + } + if (action["height"] != null) { + param.setHeight(action["height"] as Double) + } + + printerBuilder.actionPrintBarcode(param) + } + + "printPdf417" -> { + val pdf417Content = action["content"] as String + val param = Pdf417Parameter(pdf417Content) + + if (action["column"] != null) { + param.setColumn(action["column"] as Int) + } + if (action["line"] != null) { + param.setLine(action["line"] as Int) + } + if (action["module"] != null) { + param.setModule(action["module"] as Int) + } + if (action["aspect"] != null) { + param.setAspect(action["aspect"] as Int) + } + if (action["level"] != null) { + param.setLevel( + when (action["level"] as String) { + "ecc0" -> Pdf417Level.Ecc0 + "ecc1" -> Pdf417Level.Ecc1 + "ecc2" -> Pdf417Level.Ecc2 + "ecc3" -> Pdf417Level.Ecc3 + "ecc4" -> Pdf417Level.Ecc4 + "ecc5" -> Pdf417Level.Ecc5 + "ecc6" -> Pdf417Level.Ecc6 + "ecc7" -> Pdf417Level.Ecc7 + "ecc8" -> Pdf417Level.Ecc8 + else -> Pdf417Level.Ecc0 + } + ) + } + + printerBuilder.actionPrintPdf417(param) + } + + "printQRCode" -> { + val qrContent = action["content"] as String + val param = QRCodeParameter(qrContent) + + if (action["model"] != null) { + param.setModel( + when (action["model"] as String) { + "model1" -> QRCodeModel.Model1 + "model2" -> QRCodeModel.Model2 + else -> QRCodeModel.Model1 + } + ) + } + if (action["level"] != null) { + param.setLevel( + when (action["level"] as String) { + "l" -> QRCodeLevel.L + "m" -> QRCodeLevel.M + "q" -> QRCodeLevel.Q + "h" -> QRCodeLevel.H + else -> QRCodeLevel.L + } + ) + } + if (action["cellSize"] != null) { + param.setCellSize(action["cellSize"] as Int) + } + + printerBuilder.actionPrintQRCode(param) + } + + "printImage" -> { + val image = action["image"] as ByteArray + val width = action["width"] as Int + val bmp = BitmapFactory.decodeByteArray(image, 0, image.size) + printerBuilder.actionPrintImage(ImageParameter(bmp, width)) + } + } } - } + return printerBuilder } - return printerBuilder - } } -fun InterfaceType.value() : String { - return when (this) { - InterfaceType.Lan -> "lan" - InterfaceType.Bluetooth -> "bluetooth" - InterfaceType.Usb -> "usb" - else -> "unknown" - } +fun InterfaceType.value(): String { + return when (this) { + InterfaceType.Lan -> "lan" + InterfaceType.Bluetooth -> "bluetooth" + InterfaceType.Usb -> "usb" + else -> "unknown" + } } -fun interfaceTypeFromValue(value: String) : InterfaceType? { - return when (value) { - "lan" -> InterfaceType.Lan - "bluetooth" -> InterfaceType.Bluetooth - "usb" -> InterfaceType.Usb - else -> null - } +fun DrawerOpenedMethod.value(): String { + return when (this) { + DrawerOpenedMethod.ByHand -> "byHand" + DrawerOpenedMethod.ByCommand -> "byCommand" + } } -fun StarPrinterModel.value() : String { - return when (this) { - StarPrinterModel.TSP650II -> "tsp650II" - StarPrinterModel.TSP700II -> "tsp700II" - StarPrinterModel.TSP800II -> "tsp800II" - StarPrinterModel.TSP100IIU_Plus -> "tsp100IIUPlus" - StarPrinterModel.TSP100IIIW -> "tsp100IIIW" - StarPrinterModel.TSP100IIILAN -> "tsp100IIILAN" - StarPrinterModel.TSP100IIIBI -> "tsp100IIIBI" - StarPrinterModel.TSP100IIIU -> "tsp100IIIU" - StarPrinterModel.TSP100IV -> "tsp100IV" - StarPrinterModel.mPOP -> "mPOP" - StarPrinterModel.mC_Print2 -> "mCPrint2" - StarPrinterModel.mC_Print3 -> "mCPrint3" - StarPrinterModel.SM_S210i -> "smS210i" - StarPrinterModel.SM_S230i -> "smS230i" - StarPrinterModel.SM_T300 -> "smT300" - StarPrinterModel.SM_T300i -> "smT300i" - StarPrinterModel.SM_T400i -> "smT400i" - StarPrinterModel.SM_L200 -> "smL200" - StarPrinterModel.SM_L300 -> "smL300" - StarPrinterModel.SP700 -> "sp700" - else -> "unknown" - } +fun interfaceTypeFromValue(value: String): InterfaceType? { + return when (value) { + "lan" -> InterfaceType.Lan + "bluetooth" -> InterfaceType.Bluetooth + "usb" -> InterfaceType.Usb + else -> null + } +} + +fun StarPrinterModel.value(): String { + return when (this) { + StarPrinterModel.TSP650II -> "tsp650II" + StarPrinterModel.TSP700II -> "tsp700II" + StarPrinterModel.TSP800II -> "tsp800II" + StarPrinterModel.TSP100IIU_Plus -> "tsp100IIUPlus" + StarPrinterModel.TSP100IIIW -> "tsp100IIIW" + StarPrinterModel.TSP100IIILAN -> "tsp100IIILAN" + StarPrinterModel.TSP100IIIBI -> "tsp100IIIBI" + StarPrinterModel.TSP100IIIU -> "tsp100IIIU" + StarPrinterModel.TSP100IV -> "tsp100IV" + StarPrinterModel.mPOP -> "mPOP" + StarPrinterModel.mC_Print2 -> "mCPrint2" + StarPrinterModel.mC_Print3 -> "mCPrint3" + StarPrinterModel.SM_S210i -> "smS210i" + StarPrinterModel.SM_S230i -> "smS230i" + StarPrinterModel.SM_T300 -> "smT300" + StarPrinterModel.SM_T300i -> "smT300i" + StarPrinterModel.SM_T400i -> "smT400i" + StarPrinterModel.SM_L200 -> "smL200" + StarPrinterModel.SM_L300 -> "smL300" + StarPrinterModel.SP700 -> "sp700" + else -> "unknown" + } } \ No newline at end of file diff --git a/example/android/build.gradle b/example/android/build.gradle index 4256f91..63deb8f 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.0.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index bc6a58a..ffed3a2 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/example/lib/main.dart b/example/lib/main.dart index 831de96..3ea1a23 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,9 +1,8 @@ -import 'package:flutter/material.dart'; import 'dart:async'; +import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; - -import 'package:flutter/services.dart'; +import 'package:starxpand/models/starxpand_document_display.dart'; import 'package:starxpand/starxpand.dart'; void main() { @@ -120,27 +119,70 @@ class _MyAppState extends State { printDoc.actionCut(StarXpandCutType.partial); doc.addPrint(printDoc); - doc.addDrawer(StarXpandDocumentDrawer()); - StarXpand.printDocument(printer, doc); } + int displayCounterText = 0; + + /** + * Can also be added to a normal printDocument via + * doc.addDisplay(StarXpandDocumentDisplay display) + */ + void _updateDisplayText(StarXpandPrinter printer) { + var displayDoc = StarXpandDocumentDisplay() + ..actionClearAll() + ..actionClearLine() + ..actionShowText("StarXpand\n") + ..actionClearLine() + ..actionShowText("Updated ${++displayCounterText} times"); + + StarXpand.updateDisplay(printer, displayDoc); + } + + void _getStatus(StarXpandPrinter printer) async { + try { + var status = await StarXpand.getStatus(printer); + print("Got status ${status.toString()}"); + } catch (e) { + print(e.toString()); + } + } + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( - title: const Text('Plugin example app'), + title: const Text('StarXpand SDK - Example app'), ), body: Column(children: [ - TextButton(child: Text('FInd'), onPressed: () => _find()), + TextButton( + child: Text('Search for devices'), onPressed: () => _find()), if (printers != null) for (var p in printers!) ListTile( onTap: () => _print(p), - title: Text(p.model.label), + title: Text(p.model.label + "(${p.interface.name})"), subtitle: Text(p.identifier), - trailing: Text(p.interface.name)) + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + OutlinedButton( + onPressed: () => _print(p), child: Text("Print")), + Container(width: 4), + OutlinedButton( + onPressed: () => _openDrawer(p), + child: Text("Open drawer")), + Container(width: 4), + OutlinedButton( + onPressed: () => _updateDisplayText(p), + child: Text("Update display")), + Container(width: 4), + OutlinedButton( + onPressed: () => _getStatus(p), + child: Text("Get Status")), + ], + )) ]), ), ); diff --git a/example/pubspec.lock b/example/pubspec.lock index 1d74766..8a2ab15 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,63 +5,64 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.2.1" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.3.0" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.1" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.6" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" flutter: @@ -73,7 +74,8 @@ packages: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 + url: "https://pub.dev" source: hosted version: "1.0.4" flutter_test: @@ -85,51 +87,66 @@ packages: dependency: "direct main" description: name: http - url: "https://pub.dartlang.org" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + url: "https://pub.dev" source: hosted - version: "0.13.4" + version: "0.13.6" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.2" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c + url: "https://pub.dev" source: hosted version: "1.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.15" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" sky_engine: dependency: transitive description: flutter @@ -139,72 +156,81 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" starxpand: dependency: "direct main" description: path: ".." relative: true source: path - version: "0.0.2" + version: "0.1.5" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.5.1" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.2" uuid: dependency: transitive description: name: uuid - url: "https://pub.dartlang.org" + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" sdks: - dart: ">=2.17.0 <3.0.0" + dart: ">=3.0.0-0 <4.0.0" flutter: ">=2.5.0" diff --git a/lib/models/starxpand_callbacks.dart b/lib/models/starxpand_callbacks.dart index 01b16e8..caa5e1e 100644 --- a/lib/models/starxpand_callbacks.dart +++ b/lib/models/starxpand_callbacks.dart @@ -52,6 +52,35 @@ class StarXpandPrinterPayload extends StarXpandCallbackPayload { } } +enum StarXpandPrinterStatusUpdateType { + connected, + disconnected, + error; + + static StarXpandPrinterStatusUpdateType fromName(String name) => + StarXpandPrinterStatusUpdateType.values.where((e) => e.name == name).first; +} + +class StarXpandPrinterStatusPayload extends StarXpandCallbackPayload { + late final StarXpandPrinterStatusUpdateType updateType; + late final String message; + + StarXpandPrinterStatusPayload(String type, Map payload) + : super(type, payload); + + @override + fromMap(Map data) { + updateType = StarXpandPrinterStatusUpdateType.fromName(data['updateType']); + message = data['message']; + } + + + @override + String toString() { + return "StarXpandStatusPayload: type($updateType) message($message)"; + } +} + class StarXpandInputPayload extends StarXpandCallbackPayload { late final String inputString; late final Uint8List inputData; diff --git a/lib/models/starxpand_document.dart b/lib/models/starxpand_document.dart index 28fbb7b..26d20db 100644 --- a/lib/models/starxpand_document.dart +++ b/lib/models/starxpand_document.dart @@ -1,3 +1,4 @@ +import 'package:starxpand/models/starxpand_document_display.dart'; import 'package:starxpand/starxpand.dart'; class StarXpandDocument { @@ -5,6 +6,7 @@ class StarXpandDocument { addPrint(StarXpandDocumentPrint print) => _contents.add(print); addDrawer(StarXpandDocumentDrawer drawer) => _contents.add(drawer); + addDisplay(StarXpandDocumentDisplay display) => _contents.add(display); Map toMap() { return {"contents": _contents.map((e) => e.toMap()).toList()}; diff --git a/lib/models/starxpand_document_display.dart b/lib/models/starxpand_document_display.dart new file mode 100644 index 0000000..40bce3f --- /dev/null +++ b/lib/models/starxpand_document_display.dart @@ -0,0 +1,51 @@ +import 'dart:typed_data'; + +import 'package:starxpand/models/starxpand_document.dart'; +import 'package:starxpand/starxpand.dart'; + +enum Contrast { + minus3, + minus2, + minus1, + Default, + plus1, + plus2, + plus3, +} + +class StarXpandDocumentDisplay extends StarXpandDocumentContent { + final List _actions = []; + + StarXpandDocumentDisplay(); + + @override + String get type => 'display'; + + actionShowText(String data) { + _actions.add({'action': 'showText', 'data': data}); + } + + actionClearAll() { + _actions.add({'action': 'clearAll'}); + } + + actionClearLine() { + _actions.add({'action': 'clearLine'}); + } + + actionShowImage(Uint8List image) { + _actions.add({'action': 'showImage', 'image': image }); + } + + actionSetContrast(Contrast contrast) { + _actions.add({ + 'action': 'setContrast', + 'content': contrast.name, + }); + } + + @override + Map getData() { + return {"actions": _actions}; + } +} diff --git a/lib/models/starxpand_document_print.dart b/lib/models/starxpand_document_print.dart index 9515518..08f76e6 100644 --- a/lib/models/starxpand_document_print.dart +++ b/lib/models/starxpand_document_print.dart @@ -33,6 +33,8 @@ enum StarXpandPdf417Level { enum StarXpandQRCodeModel { model1, model2 } enum StarXpandQRCodeLevel { l, m, q, h } +enum StarXpandLineStyle { double, single } + enum StarXpandStyleAlignment { left, center, right } enum StarXpandStyleFontType { a, b } enum StarXpandStyleInternationalCharacter { @@ -192,10 +194,26 @@ class StarXpandDocumentPrint extends StarXpandDocumentContent { }..trim()); } + actionPrintRuledLine(double width, { + required double? thickness, + StarXpandLineStyle lineStyle = StarXpandLineStyle.single, + }) { + _actions.add({ + 'action': 'printRuledLine', + 'width': width, + 'thickness': thickness, + 'lineStyle': lineStyle.name, + }); + } + actionPrintImage(Uint8List image, int width) { _actions.add({'action': 'printImage', 'image': image, 'width': width}); } + List getActions() { + return _actions; + } + @override Map getData() { return {"actions": _actions}; diff --git a/lib/models/starxpand_printer.dart b/lib/models/starxpand_printer.dart index 47c5d98..338ff69 100644 --- a/lib/models/starxpand_printer.dart +++ b/lib/models/starxpand_printer.dart @@ -10,14 +10,15 @@ enum StarXpandInterface { } enum StarXpandPrinterPaper { - mm58('58mm'), // 385 - mm76('76mm'), // 530 - mm80('80mm'), // 567 - mm112('112mm'); + mm58('58mm', 385), // 385 + mm76('76mm', 530), // 530 + mm80('80mm', 567), // 567 + mm112('112mm', 1093); final String label; + final int width; - const StarXpandPrinterPaper(this.label); + const StarXpandPrinterPaper(this.label, this.width); } enum StarXpandPrinterModel { @@ -47,8 +48,16 @@ enum StarXpandPrinterModel { final List paper; const StarXpandPrinterModel(this.label, this.paper); - static StarXpandPrinterModel fromName(String name) => - StarXpandPrinterModel.values.where((e) => e.name == name).first; + + static StarXpandPrinterModel fromName(String name) { + try { + return StarXpandPrinterModel.values + .where((e) => e.name.toLowerCase() == name.toLowerCase()) + .first; + } catch (e) { + return StarXpandPrinterModel.unknown; + } + } } class StarXpandPrinter { @@ -73,7 +82,7 @@ class StarXpandPrinter { return { 'model': model.name, 'identifier': identifier, - 'interface': interface.name + 'interface': interface.name, }; } } diff --git a/lib/models/starxpand_status.dart b/lib/models/starxpand_status.dart new file mode 100644 index 0000000..9e6dac0 --- /dev/null +++ b/lib/models/starxpand_status.dart @@ -0,0 +1,70 @@ +enum DrawerOpenedMethod { + byHand, + byCommand; + + static DrawerOpenedMethod fromName(String name) => + DrawerOpenedMethod.values.where((e) => e.name == name).first; +} + +class StarPrinterStatusDetail { + bool? cleaningNotification; + bool? cutterError; + int? detectedPaperWidth; + bool? drawer1OpenCloseSignal; + DrawerOpenedMethod? drawer1OpenedMethod; + bool? drawer2OpenCloseSignal; + DrawerOpenedMethod? drawer2OpenedMethod; + bool? drawerOpenError; + bool? externalDevice1Connected; + bool? externalDevice2Connected; + bool? paperJamError; + bool? paperPresent; + bool? paperSeparatorError; + bool? partsReplacementNotification; + bool? printUnitOpen; + bool? rollPositionError; + + StarPrinterStatusDetail.fromMap(Map data) + : cleaningNotification = data['cleaningNotification'], + cutterError = data['cutterError'], + detectedPaperWidth = data['detectedPaperWidth'], + drawer1OpenCloseSignal = data['drawer1OpenCloseSignal'], + drawer1OpenedMethod = (data['drawer1OpenedMethod'] as String?) != null + ? DrawerOpenedMethod.fromName(data['drawer1OpenedMethod']) + : null, + drawer2OpenCloseSignal = data['drawer2OpenCloseSignal'], + drawer2OpenedMethod = (data['drawer2OpenedMethod'] as String?) != null + ? DrawerOpenedMethod.fromName(data['drawer2OpenedMethod']) + : null, + drawerOpenError = data['drawerOpenError'], + externalDevice1Connected = data['externalDevice1Connected'], + externalDevice2Connected = data['externalDevice2Connected'], + paperJamError = data['paperJamError'], + paperPresent = data['paperPresent'], + paperSeparatorError = data['paperSeparatorError'], + partsReplacementNotification = data['partsReplacementNotification'], + printUnitOpen = data['printUnitOpen'], + rollPositionError = data['rollPositionError']; +} + +class StarXpandStatus { + bool? hasError = false; + bool? coverOpen = false; + bool? drawerOpenCloseSignal = false; + bool? paperEmpty = false; + bool? paperNearEmpty = false; + Map? reserved = {}; + StarPrinterStatusDetail detail; + + StarXpandStatus.fromMap(Map response) + : hasError = response['hasError'], + coverOpen = response['coverOpen'], + drawerOpenCloseSignal = response['drawerOpenCloseSignal'], + paperEmpty = response['paperEmpty'], + paperNearEmpty = response['paperNearEmpty'], + reserved = (response['reserved'] as Map?) != null + ? (response['reserved'] as Map).cast() + : {}, + detail = StarPrinterStatusDetail.fromMap( + (response['detail'] as Map).cast()); +} diff --git a/lib/starxpand.dart b/lib/starxpand.dart index c8e63fb..b56612d 100644 --- a/lib/starxpand.dart +++ b/lib/starxpand.dart @@ -1,18 +1,19 @@ import 'dart:async'; -import 'package:uuid/uuid.dart'; - import 'package:flutter/services.dart'; import 'package:starxpand/models/starxpand_callbacks.dart'; import 'package:starxpand/models/starxpand_document.dart'; -import 'package:starxpand/models/starxpand_printer.dart'; +import 'package:starxpand/models/starxpand_document_display.dart'; import 'package:starxpand/models/starxpand_document_drawer.dart'; +import 'package:starxpand/models/starxpand_printer.dart'; +import 'package:starxpand/models/starxpand_status.dart'; +import 'package:uuid/uuid.dart'; export 'package:starxpand/models/starxpand_callbacks.dart'; -export 'package:starxpand/models/starxpand_printer.dart'; export 'package:starxpand/models/starxpand_document.dart'; -export 'package:starxpand/models/starxpand_document_print.dart'; export 'package:starxpand/models/starxpand_document_drawer.dart'; +export 'package:starxpand/models/starxpand_document_print.dart'; +export 'package:starxpand/models/starxpand_printer.dart'; class StarXpand { static final MethodChannel _channel = const MethodChannel('starxpand') @@ -56,16 +57,17 @@ class StarXpand { StarXpandInterface.bluetoothLE, StarXpandInterface.lan ], - int timeout = 3000, - StarXpandCallback? callback}) async { + int timeout = 3000, + StarXpandCallback? callback}) async { var guid = _addCallbackHandler( StarXpandCallbackHandler( - (payload) => callback?.call(payload), - (type, data) => StarXpandPrinterPayload( - type, Map.from(data)))); + (payload) => callback?.call(payload), + (type, data) => + StarXpandPrinterPayload( + type, Map.from(data)))); Map result = - Map.from(await _channel.invokeMethod('findPrinters', { + Map.from(await _channel.invokeMethod('findPrinters', { "callback": guid, "timeout": timeout, "interfaces": interfaces.map((e) => e.name).toList() @@ -79,21 +81,67 @@ class StarXpand { .toList(); } - static Future openDrawer(StarXpandPrinter printer) => printDocument( - printer, StarXpandDocument()..addDrawer(StarXpandDocumentDrawer())); + static Future openDrawer(StarXpandPrinter printer) => + printDocument( + printer, StarXpandDocument() + ..addDrawer(StarXpandDocumentDrawer())); + + static Future monitor(StarXpandPrinter printer, + StarXpandCallback callback) async { + var guid = _addCallbackHandler( + StarXpandCallbackHandler( + (payload) => callback.call(payload), + (type, data) => + StarXpandPrinterStatusPayload( + type, Map.from(data)))); + + await _channel.invokeMethod('monitor', { + "printer": printer.toMap(), + "callback": guid + }); - static Future printDocument( - StarXpandPrinter printer, StarXpandDocument document) async { + return guid; + } + + static Future openPrinterConnection(StarXpandPrinter printer) async { + return await _channel + .invokeMethod('openConnection', {"printer": printer.toMap()}); + } + + static Future closePrinterConnection(StarXpandPrinter printer) async { + return await _channel.invokeMethod('closeConnection', {"printer": printer.toMap()}); + } + + static Future printRawBytes(StarXpandPrinter printer, Uint8List bytes) async { + return await _channel.invokeMethod('printRawBytes', { + 'printer': printer.toMap(), + 'bytes': bytes + }); + } + + static Future printDocument(StarXpandPrinter printer, + StarXpandDocument document) async { return await _channel.invokeMethod('printDocument', {"printer": printer.toMap(), "document": document.toMap()}); } + static Future updateDisplay(StarXpandPrinter printer, + StarXpandDocumentDisplay display) => + printDocument(printer, StarXpandDocument() + ..addDisplay(display)); + + static Future getStatus(StarXpandPrinter printer) async { + var result = Map.from( + await _channel.invokeMethod('getStatus', {"printer": printer.toMap()})); + return StarXpandStatus.fromMap(result.cast()); + } + static Future startInputListener(StarXpandPrinter printer, StarXpandCallback callback) async { var guid = _addCallbackHandler( StarXpandCallbackHandler( - (payload) => callback.call(payload), - (type, data) => + (payload) => callback.call(payload), + (type, data) => StarXpandInputPayload(type, Map.from(data)))); await _channel.invokeMethod( diff --git a/pubspec.yaml b/pubspec.yaml index 511f476..15002e8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,17 +1,17 @@ name: starxpand -description: A flutter wrapper around the Star Micronics StarXpand API. -version: 0.0.3 +description: A flutter wrapper around for Star Micronics StarXpand API. +version: 0.3.0 repository: https://github.com/ovatu/starxpand_flutter homepage: https://ovatu.com/us environment: - sdk: ">=2.17.0 <3.0.0" + sdk: '>=3.2.6 <4.0.0' flutter: ">=2.5.0" dependencies: flutter: sdk: flutter - uuid: ^3.0.6 + uuid: ^4.4.2 dev_dependencies: flutter_test: