zsdk 5.0.0 copy "zsdk: ^5.0.0" to clipboard
zsdk: ^5.0.0 copied to clipboard

A Flutter plugin for printers using Zebra Link OS, to allow ZPL and PDF priting over TCP/IP connections.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:zsdk/zsdk.dart' as Printer;
import 'dart:io';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(home: MyApp()));
}

const String btnPrintPdfFileOverTCPIP = 'btnPrintPdfFileOverTCPIP';
const String btnPrintZplFileOverTCPIP = 'btnPrintZplFileOverTCPIP';
const String btnPrintZplDataOverTCPIP = 'btnPrintZplDataOverTCPIP';
const String btnCheckPrinterStatus = 'btnCheckPrinterStatus';
const String btnGetPrinterSettings = 'btnGetPrinterSettings';
const String btnSetPrinterSettings = 'btnSetPrinterSettings';
const String btnResetPrinterSettings = 'btnResetPrinterSettings';
const String btnDoManualCalibration = 'btnDoManualCalibration';
const String btnPrintConfigurationLabel = 'btnPrintConfigurationLabel';
const String btnRebootPrinter = 'btnRebootPrinter';

const String btnGetBondedDevices = 'btnGetBondedDevices';
const String btnDiscoverPrinters = 'btnDiscoverPrinters';
const String btnPrintZplDataOverBluetooth = 'btnPrintZplDataOverBluetooth';

class MyApp extends StatefulWidget {
  final Printer.ZSDK zsdk = Printer.ZSDK();

  MyApp({super.key});

  @override
  State createState() => _MyAppState();
}

enum OperationStatus { SENDING, RECEIVING, SUCCESS, ERROR, NONE }

class _MyAppState extends State<MyApp> {
  final addressIpController = TextEditingController(text: '10.0.0.120');
  final addressPortController = TextEditingController();
  final btMacAddressController = TextEditingController();
  List<Map<String, String>> bondedDevices = [];
  final pathController = TextEditingController();
  final zplDataController = TextEditingController(
    text: '^XA^FO17,16^GB379,371,8^FS^FT65,255^A0N,135,134^FDTEST^FS^XZ',
  );
  final widthController = TextEditingController();
  final heightController = TextEditingController();
  final dpiController = TextEditingController();

  final darknessController = TextEditingController();
  final printSpeedController = TextEditingController();
  final tearOffController = TextEditingController();
  final printWidthController = TextEditingController();
  final labelLengthController = TextEditingController();
  final labelLengthMaxController = TextEditingController();
  final labelTopController = TextEditingController();
  final leftPositionController = TextEditingController();
  Printer.MediaType? selectedMediaType;
  Printer.PrintMethod? selectedPrintMethod;
  Printer.ZPLMode? selectedZPLMode;
  Printer.PowerUpAction? selectedPowerUpAction;
  Printer.HeadCloseAction? selectedHeadCloseAction;
  Printer.PrintMode? selectedPrintMode;
  Printer.ReprintMode? selectedReprintMode;
  Printer.VirtualDevice? selectedVirtualDevice;

  Printer.PrinterSettings? settings;

  Printer.Orientation printerOrientation = Printer.Orientation.LANDSCAPE;
  String? message;
  String? statusMessage;
  String? settingsMessage;
  String? calibrationMessage;
  OperationStatus printStatus = OperationStatus.NONE;
  OperationStatus checkingStatus = OperationStatus.NONE;
  OperationStatus settingsStatus = OperationStatus.NONE;
  OperationStatus calibrationStatus = OperationStatus.NONE;
  OperationStatus rebootingStatus = OperationStatus.NONE;
  OperationStatus btStatus = OperationStatus.NONE;
  String? btMessage;
  String? filePath;
  String? zplData;

  Future<bool> _requestBluetoothPermissions() async {
    // On iOS, Bluetooth access is governed by CoreBluetooth — it is NOT a
    // runtime permission that can be requested via permission_handler.
    // The system dialog is shown automatically by the OS the first time the
    // native SDK opens a CBCentralManager session (i.e. when a Bluetooth
    // operation is actually attempted). Calling Permission.bluetoothConnect
    // / bluetoothScan.request() on iOS always returns permanentlyDenied
    // because those Android-style runtime permissions simply don't exist on
    // iOS. We therefore skip the check on iOS and let the native layer
    // handle the prompt.
    if (Platform.isIOS) {
      return true;
    }

    // Android — request the runtime Bluetooth permissions introduced in API 31.
    var btConnect = await Permission.bluetoothConnect.request();
    var btScan = await Permission.bluetoothScan.request();

    if (btConnect.isGranted && btScan.isGranted) {
      return true;
    }

    if (btConnect.isPermanentlyDenied || btScan.isPermanentlyDenied) {
      if (mounted) {
        showDialog(
          context: context,
          builder: (BuildContext context) => AlertDialog(
            title: const Text('Bluetooth Permissions Required'),
            content: const Text(
              'Bluetooth permissions are required to connect to Zebra printers. '
              'Please enable them in your app settings.',
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('Cancel'),
              ),
              TextButton(
                onPressed: () {
                  openAppSettings();
                  Navigator.of(context).pop();
                },
                child: const Text('Open Settings'),
              ),
            ],
          ),
        );
      }
    }

    return false;
  }

  @override
  void initState() {
    super.initState();
  }

  String getName<T>(T value) {
    String name = 'Unknown';
    if (value is Printer.HeadCloseAction) name = value.name;
    if (value is Printer.MediaType) name = value.name;
    if (value is Printer.PowerUpAction) name = value.name;
    if (value is Printer.PrintMethod) name = value.name;
    if (value is Printer.PrintMode) name = value.name;
    if (value is Printer.ReprintMode) name = value.name;
    if (value is Printer.VirtualDevice) name = value.name;
    if (value is Printer.ZPLMode) name = value.name;
    return name;
  }

  List<DropdownMenuItem<T>> generateDropdownItems<T>(List<T> values) {
    List<DropdownMenuItem<T>> items = [];
    for (var value in values) {
      items.add(DropdownMenuItem<T>(value: value, child: Text(getName(value))));
    }
    return items;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey.shade300,
      appBar: AppBar(title: const Text('Zebra SDK Plugin example app')),
      body: Container(
        padding: const EdgeInsets.all(8),
        child: Scrollbar(
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text(
                  'Print file over TCP/IP',
                  style: TextStyle(fontSize: 18),
                ),
                const Divider(color: Colors.transparent),
                Card(
                  elevation: 4,
                  margin: const EdgeInsets.all(8),
                  child: Container(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      children: <Widget>[
                        const Text(
                          'File to print',
                          style: TextStyle(fontSize: 16),
                        ),
                        TextField(
                          controller: pathController,
                          decoration: const InputDecoration(
                            labelText: 'File path',
                          ),
                        ),
                        const Divider(color: Colors.transparent),
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.green,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed: () async {
                                  try {
                                    FilePickerResult? result = await FilePicker
                                        .platform
                                        .pickFiles(type: FileType.any);
                                    if (result != null) {
                                      filePath = result.files.single.path;
                                      if (filePath != null) {
                                        setState(() {
                                          pathController.text = filePath ?? '';
                                        });
                                      }
                                    }
                                  } catch (e) {
                                    showSnackBar(e.toString());
                                  }
                                },
                                child: Text(
                                  'Pick .zpl file'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                            const VerticalDivider(color: Colors.transparent),
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.lightGreen,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed: () async {
                                  try {
                                    FilePickerResult? result = await FilePicker
                                        .platform
                                        .pickFiles(type: FileType.any);
                                    if (result != null) {
                                      filePath = result.files.single.path;
                                      if (filePath != null) {
                                        setState(() {
                                          pathController.text = filePath ?? '';
                                        });
                                      }
                                    }
                                  } catch (e) {
                                    showSnackBar(e.toString());
                                  }
                                },
                                child: Text(
                                  'Pick .pdf file'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                const SizedBox(height: 16),
                Card(
                  elevation: 4,
                  margin: const EdgeInsets.all(8),
                  child: Container(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      children: <Widget>[
                        const Text(
                          'ZPL data to print',
                          style: TextStyle(fontSize: 16),
                        ),
                        TextField(
                          controller: zplDataController,
                          decoration: const InputDecoration(
                            labelText: 'ZPL data',
                          ),
                          maxLines: 5,
                        ),
                      ],
                    ),
                  ),
                ),
                Card(
                  elevation: 4,
                  margin: const EdgeInsets.all(8),
                  child: Container(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      children: <Widget>[
                        const Text(
                          'Printer address',
                          style: TextStyle(fontSize: 16),
                        ),
                        TextField(
                          controller: addressIpController,
                          decoration: const InputDecoration(
                            labelText: 'Printer IP address',
                          ),
                        ),
                        TextField(
                          controller: addressPortController,
                          decoration: const InputDecoration(
                            labelText: 'Printer port (defaults to 9100)',
                          ),
                        ),
                        const SizedBox(height: 16),
                        Visibility(
                          visible:
                              checkingStatus != OperationStatus.NONE ||
                              rebootingStatus != OperationStatus.NONE,
                          child: Column(
                            children: <Widget>[
                              Text(
                                '$statusMessage',
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontSize: 16,
                                  fontWeight: FontWeight.bold,
                                  color: getOperationStatusColor(
                                    checkingStatus != OperationStatus.NONE
                                        ? checkingStatus
                                        : rebootingStatus,
                                  ),
                                ),
                              ),
                              const SizedBox(height: 16),
                            ],
                          ),
                        ),
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.orange,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed:
                                    checkingStatus == OperationStatus.RECEIVING
                                    ? null
                                    : () => onClick(btnCheckPrinterStatus),
                                child: Text(
                                  'Check printer status'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                            const SizedBox(width: 8),
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.red,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed:
                                    checkingStatus == OperationStatus.SENDING
                                    ? null
                                    : () => onClick(btnRebootPrinter),
                                child: Text(
                                  'Reboot Printer'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                Card(
                  elevation: 4,
                  margin: const EdgeInsets.all(8),
                  child: Container(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        const Center(
                          child: Text(
                            'Printer settings',
                            style: TextStyle(fontSize: 16),
                          ),
                        ),
                        const SizedBox(height: 16),
                        RichText(
                          text: TextSpan(
                            style: TextStyle(
                              color: Theme.of(
                                context,
                              ).textTheme.titleLarge?.color,
                            ),
                            children: [
                              const TextSpan(
                                text: 'Brand and model: ',
                                style: TextStyle(fontWeight: FontWeight.bold),
                              ),
                              TextSpan(
                                text: settings?.printerModelName ?? 'Unknown',
                              ),
                            ],
                          ),
                        ),
                        const Divider(color: Colors.transparent, height: 4),
                        RichText(
                          text: TextSpan(
                            style: TextStyle(
                              color: Theme.of(
                                context,
                              ).textTheme.titleLarge?.color,
                            ),
                            children: [
                              const TextSpan(
                                text: 'Device friendly name: ',
                                style: TextStyle(fontWeight: FontWeight.bold),
                              ),
                              TextSpan(
                                text: settings?.deviceFriendlyName ?? 'Unknown',
                              ),
                            ],
                          ),
                        ),
                        const Divider(color: Colors.transparent, height: 4),
                        RichText(
                          text: TextSpan(
                            style: TextStyle(
                              color: Theme.of(
                                context,
                              ).textTheme.titleLarge?.color,
                            ),
                            children: [
                              const TextSpan(
                                text: 'Firmware: ',
                                style: TextStyle(fontWeight: FontWeight.bold),
                              ),
                              TextSpan(text: settings?.firmware ?? 'Unknown'),
                            ],
                          ),
                        ),
                        const Divider(color: Colors.transparent, height: 4),
                        RichText(
                          text: TextSpan(
                            style: TextStyle(
                              color: Theme.of(
                                context,
                              ).textTheme.titleLarge?.color,
                            ),
                            children: [
                              const TextSpan(
                                text: 'Link-OS Version: ',
                                style: TextStyle(fontWeight: FontWeight.bold),
                              ),
                              TextSpan(
                                text: settings?.linkOSVersion ?? 'Unknown',
                              ),
                            ],
                          ),
                        ),
                        const Divider(color: Colors.transparent, height: 4),
                        RichText(
                          text: TextSpan(
                            style: TextStyle(
                              color: Theme.of(
                                context,
                              ).textTheme.titleLarge?.color,
                            ),
                            children: [
                              const TextSpan(
                                text: 'Printer DPI: ',
                                style: TextStyle(fontWeight: FontWeight.bold),
                              ),
                              TextSpan(text: settings?.printerDpi ?? 'Unknown'),
                            ],
                          ),
                        ),
                        RichText(
                          text: TextSpan(
                            style: TextStyle(
                              color: Theme.of(
                                context,
                              ).textTheme.titleLarge?.color,
                            ),
                            children: [
                              const TextSpan(
                                text:
                                    'Resolution in dots per millimeter (dpmm): ',
                                style: TextStyle(fontWeight: FontWeight.bold),
                              ),
                              TextSpan(
                                text:
                                    settings?.devicePrintHeadResolution != null
                                    ? "${double.tryParse(settings?.devicePrintHeadResolution ?? '')?.truncate()}dpmm"
                                    : 'Unknown',
                              ),
                            ],
                          ),
                        ),
                        TextField(
                          controller: darknessController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: true,
                            decimal: true,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Darkness',
                          ),
                        ),
                        TextField(
                          controller: printSpeedController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: false,
                            decimal: false,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Print speed',
                          ),
                        ),
                        TextField(
                          controller: tearOffController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: true,
                            decimal: false,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Tear off',
                          ),
                        ),
                        DropdownButtonFormField<Printer.MediaType>(
                          items: generateDropdownItems(
                            Printer.MediaType.values,
                          ),
                          initialValue: selectedMediaType,
                          onChanged: (value) =>
                              setState(() => selectedMediaType = value),
                          decoration: const InputDecoration(
                            labelText: 'Media type',
                          ),
                        ),
                        DropdownButtonFormField<Printer.PrintMethod>(
                          items: generateDropdownItems(
                            Printer.PrintMethod.values,
                          ),
                          initialValue: selectedPrintMethod,
                          onChanged: (value) =>
                              setState(() => selectedPrintMethod = value),
                          decoration: const InputDecoration(
                            labelText: 'Print method',
                          ),
                        ),
                        TextField(
                          controller: printWidthController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: false,
                            decimal: false,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Print width',
                          ),
                        ),
                        TextField(
                          controller: labelLengthController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: false,
                            decimal: false,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Label length',
                          ),
                        ),
                        TextField(
                          controller: labelLengthMaxController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: false,
                            decimal: true,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Label length max',
                          ),
                        ),
                        DropdownButtonFormField<Printer.ZPLMode>(
                          items: generateDropdownItems(Printer.ZPLMode.values),
                          initialValue: selectedZPLMode,
                          onChanged: (value) =>
                              setState(() => selectedZPLMode = value),
                          decoration: const InputDecoration(
                            labelText: 'ZPL mode',
                          ),
                        ),
                        DropdownButtonFormField<Printer.PowerUpAction>(
                          items: generateDropdownItems(
                            Printer.PowerUpAction.values,
                          ),
                          initialValue: selectedPowerUpAction,
                          onChanged: (value) =>
                              setState(() => selectedPowerUpAction = value),
                          decoration: const InputDecoration(
                            labelText: 'Power up action',
                          ),
                        ),
                        DropdownButtonFormField<Printer.HeadCloseAction>(
                          items: generateDropdownItems(
                            Printer.HeadCloseAction.values,
                          ),
                          initialValue: selectedHeadCloseAction,
                          onChanged: (value) =>
                              setState(() => selectedHeadCloseAction = value),
                          decoration: const InputDecoration(
                            labelText: 'Head close action',
                          ),
                        ),
                        TextField(
                          controller: labelTopController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: true,
                            decimal: false,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Label top',
                          ),
                        ),
                        TextField(
                          controller: leftPositionController,
                          keyboardType: const TextInputType.numberWithOptions(
                            signed: true,
                            decimal: false,
                          ),
                          textInputAction: TextInputAction.done,
                          decoration: const InputDecoration(
                            labelText: 'Left position',
                          ),
                        ),
                        DropdownButtonFormField<Printer.PrintMode>(
                          items: generateDropdownItems(
                            Printer.PrintMode.values,
                          ),
                          initialValue: selectedPrintMode,
                          onChanged: (value) =>
                              setState(() => selectedPrintMode = value),
                          decoration: const InputDecoration(
                            labelText: 'Print mode',
                          ),
                        ),
                        DropdownButtonFormField<Printer.ReprintMode>(
                          items: generateDropdownItems(
                            Printer.ReprintMode.values,
                          ),
                          initialValue: selectedReprintMode,
                          onChanged: (value) =>
                              setState(() => selectedReprintMode = value),
                          decoration: const InputDecoration(
                            labelText: 'Reprint mode',
                          ),
                        ),
                        DropdownButtonFormField<Printer.VirtualDevice>(
                          items: generateDropdownItems(
                            Printer.VirtualDevice.values,
                          ),
                          initialValue: selectedVirtualDevice,
                          onChanged: (value) =>
                              setState(() => selectedVirtualDevice = value),
                          decoration: const InputDecoration(
                            labelText: 'Virtual device',
                          ),
                        ),
                        const SizedBox(height: 16),
                        Visibility(
                          visible: settingsStatus != OperationStatus.NONE,
                          child: Column(
                            children: <Widget>[
                              Text(
                                '$settingsMessage',
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontSize: 16,
                                  fontWeight: FontWeight.bold,
                                  color: getOperationStatusColor(
                                    settingsStatus,
                                  ),
                                ),
                              ),
                              const SizedBox(height: 16),
                            ],
                          ),
                        ),
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.deepPurple,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed:
                                    settingsStatus == OperationStatus.SENDING ||
                                        settingsStatus ==
                                            OperationStatus.RECEIVING
                                    ? null
                                    : () => onClick(btnSetPrinterSettings),
                                child: Text(
                                  'Set settings'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                            const VerticalDivider(color: Colors.transparent),
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.purple,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed:
                                    settingsStatus == OperationStatus.SENDING ||
                                        settingsStatus ==
                                            OperationStatus.RECEIVING
                                    ? null
                                    : () => onClick(btnGetPrinterSettings),
                                child: Text(
                                  'Get settings'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.pink,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed:
                                    settingsStatus == OperationStatus.SENDING ||
                                        settingsStatus ==
                                            OperationStatus.RECEIVING
                                    ? null
                                    : () => onClick(btnResetPrinterSettings),
                                child: Text(
                                  'Reset settings'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                Card(
                  elevation: 4,
                  margin: const EdgeInsets.all(8),
                  child: Container(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      children: <Widget>[
                        const Text(
                          'Printer calibration',
                          style: TextStyle(fontSize: 16),
                        ),
                        const SizedBox(height: 16),
                        Visibility(
                          visible: calibrationStatus != OperationStatus.NONE,
                          child: Column(
                            children: <Widget>[
                              Text(
                                '$calibrationMessage',
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontSize: 16,
                                  fontWeight: FontWeight.bold,
                                  color: getOperationStatusColor(
                                    calibrationStatus,
                                  ),
                                ),
                              ),
                              const SizedBox(height: 16),
                            ],
                          ),
                        ),
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.blueGrey,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed:
                                    calibrationStatus == OperationStatus.SENDING
                                    ? null
                                    : () => onClick(btnDoManualCalibration),
                                child: Text(
                                  'DO MANUAL CALIBRATION'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                Card(
                  elevation: 4,
                  margin: const EdgeInsets.all(8),
                  child: Container(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      children: <Widget>[
                        const Text(
                          'PDF print configurations',
                          style: TextStyle(fontSize: 16),
                        ),
                        TextField(
                          controller: widthController,
                          keyboardType: const TextInputType.numberWithOptions(
                            decimal: true,
                          ),
                          decoration: const InputDecoration(
                            labelText:
                                'Paper width in cm (defaults to 15.20 cm)',
                          ),
                        ),
                        TextField(
                          controller: heightController,
                          keyboardType: const TextInputType.numberWithOptions(
                            decimal: true,
                          ),
                          decoration: const InputDecoration(
                            labelText:
                                'Paper height in cm (defaults to 7.00 cm)',
                          ),
                        ),
                        TextField(
                          controller: dpiController,
                          keyboardType: const TextInputType.numberWithOptions(
                            decimal: true,
                          ),
                          decoration: const InputDecoration(
                            labelText:
                                'Printer density per inch (defaults to 203 dpi)',
                          ),
                        ),
                        DropdownButtonFormField<Printer.Orientation>(
                          items: const [
                            DropdownMenuItem(
                              value: Printer.Orientation.PORTRAIT,
                              child: Text('Portrait'),
                            ),
                            DropdownMenuItem(
                              value: Printer.Orientation.LANDSCAPE,
                              child: Text('Landscape'),
                            ),
                          ],
                          initialValue: printerOrientation,
                          onChanged: (value) => setState(
                            () => printerOrientation =
                                value ?? Printer.Orientation.LANDSCAPE,
                          ),
                          decoration: const InputDecoration(
                            labelText: 'Print orientation',
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
                const SizedBox(height: 16),
                Visibility(
                  visible: printStatus != OperationStatus.NONE,
                  child: Column(
                    children: <Widget>[
                      Text(
                        '$message',
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontSize: 16,
                          fontWeight: FontWeight.bold,
                          color: getOperationStatusColor(printStatus),
                        ),
                      ),
                      const SizedBox(height: 16),
                    ],
                  ),
                ),
                ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.cyan,
                    foregroundColor: Colors.white,
                  ),
                  onPressed: printStatus == OperationStatus.SENDING
                      ? null
                      : () => onClick(btnPrintConfigurationLabel),
                  child: Text(
                    'Test Print'.toUpperCase(),
                    textAlign: TextAlign.center,
                  ),
                ),
                Row(
                  children: <Widget>[
                    Expanded(
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          backgroundColor: Colors.blueAccent,
                          foregroundColor: Colors.white,
                        ),
                        onPressed: printStatus == OperationStatus.SENDING
                            ? null
                            : () => onClick(btnPrintZplFileOverTCPIP),
                        child: Text(
                          'Print zpl from file'.toUpperCase(),
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),
                    const VerticalDivider(color: Colors.transparent),
                    Expanded(
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          backgroundColor: Colors.lightBlue,
                          foregroundColor: Colors.white,
                        ),
                        onPressed: printStatus == OperationStatus.SENDING
                            ? null
                            : () => onClick(btnPrintPdfFileOverTCPIP),
                        child: Text(
                          'Print pdf from file'.toUpperCase(),
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),
                  ],
                ),
                ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blueAccent,
                    foregroundColor: Colors.white,
                  ),
                  onPressed: printStatus == OperationStatus.SENDING
                      ? null
                      : () => onClick(btnPrintZplDataOverTCPIP),
                  child: Text(
                    'Print zpl data'.toUpperCase(),
                    textAlign: TextAlign.center,
                  ),
                ),
                const SizedBox(height: 32),
                const Text('Bluetooth', style: TextStyle(fontSize: 18)),
                const Divider(color: Colors.transparent),
                Card(
                  elevation: 4,
                  margin: const EdgeInsets.all(8),
                  child: Container(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      children: <Widget>[
                        TextField(
                          controller: btMacAddressController,
                          decoration: const InputDecoration(
                            labelText: 'Printer MAC address',
                          ),
                        ),
                        const SizedBox(height: 8),
                        if (bondedDevices.isNotEmpty)
                          DropdownButtonFormField<String>(
                            decoration: const InputDecoration(
                              labelText: 'Select bonded device',
                            ),
                            items: bondedDevices
                                .map(
                                  (d) => DropdownMenuItem(
                                    value: d['address'],
                                    child: Text(
                                      "${d['name']} (${d['address']})",
                                    ),
                                  ),
                                )
                                .toList(),
                            onChanged: (value) {
                              if (value != null) {
                                setState(() {
                                  btMacAddressController.text = value;
                                });
                              }
                            },
                          ),
                        const SizedBox(height: 16),
                        Visibility(
                          visible: btStatus != OperationStatus.NONE,
                          child: Column(
                            children: <Widget>[
                              Text(
                                '$btMessage',
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontSize: 14,
                                  fontWeight: FontWeight.bold,
                                  color: getOperationStatusColor(btStatus),
                                ),
                              ),
                              const SizedBox(height: 16),
                            ],
                          ),
                        ),
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.indigo,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed: () => onClick(btnGetBondedDevices),
                                child: Text(
                                  'Bonded'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                            const SizedBox(width: 8),
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.deepOrange,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed: btStatus == OperationStatus.RECEIVING
                                    ? null
                                    : () => onClick(btnDiscoverPrinters),
                                child: Text(
                                  "${"Scan".toUpperCase()}\nOnly on Android",
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 8),
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.teal,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed: btStatus == OperationStatus.SENDING
                                    ? null
                                    : () =>
                                          onClick(btnPrintZplDataOverBluetooth),
                                child: Text(
                                  'Print ZPL over Bluetooth'.toUpperCase(),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                const SizedBox(height: 100),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Color getOperationStatusColor(OperationStatus status) {
    switch (status) {
      case OperationStatus.RECEIVING:
      case OperationStatus.SENDING:
        return Colors.blue;
      case OperationStatus.SUCCESS:
        return Colors.green;
      case OperationStatus.ERROR:
        return Colors.red;
      default:
        return Colors.black;
    }
  }

  void updateSettings(Printer.PrinterSettings? newSettings) {
    settings = newSettings;

    darknessController.text = "${settings?.darkness ?? ""}";
    printSpeedController.text = "${settings?.printSpeed ?? ""}";
    tearOffController.text = "${settings?.tearOff ?? ""}";
    printWidthController.text = "${settings?.printWidth ?? ""}";
    labelLengthController.text = "${settings?.labelLength ?? ""}";
    labelLengthMaxController.text = "${settings?.labelLengthMax ?? ""}";
    labelTopController.text = "${settings?.labelTop ?? ""}";
    leftPositionController.text = "${settings?.leftPosition ?? ""}";
    selectedMediaType = settings?.mediaType;
    selectedPrintMethod = settings?.printMethod;
    selectedZPLMode = settings?.zplMode;
    selectedPowerUpAction = settings?.powerUpAction;
    selectedHeadCloseAction = settings?.headCloseAction;
    selectedPrintMode = settings?.printMode;
    selectedReprintMode = settings?.reprintMode;
    selectedVirtualDevice = settings?.virtualDevice;
  }

  void onClick(String id) async {
    try {
      switch (id) {
        case btnDoManualCalibration:
          setState(() {
            calibrationMessage = 'Starting manual callibration...';
            calibrationStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .doManualCalibrationOverTCPIP(
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
              )
              .then(
                (value) {
                  setState(() {
                    calibrationStatus = OperationStatus.SUCCESS;
                    calibrationMessage = '$value';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      calibrationMessage =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause} \n'
                          '${printerResponse.settings?.toString()}';
                    } catch (e) {
                      print(e);
                      calibrationMessage = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    calibrationMessage = '${e.message}';
                  } catch (e) {
                    calibrationMessage = e.toString();
                  }
                  setState(() {
                    calibrationStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnGetPrinterSettings:
          setState(() {
            settingsMessage = 'Getting printer settings...';
            settingsStatus = OperationStatus.RECEIVING;
          });
          widget.zsdk
              .getPrinterSettingsOverTCPIP(
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
              )
              .then(
                (value) {
                  setState(() {
                    settingsStatus = OperationStatus.SUCCESS;
                    settingsMessage = '$value';
                    updateSettings(
                      (Printer.PrinterResponse.fromMap(value)).settings,
                    );
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      settingsMessage =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause} \n'
                          '${printerResponse.settings?.toString()}';
                    } catch (e) {
                      print(e);
                      settingsMessage = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    settingsMessage = '${e.message}';
                  } catch (e) {
                    settingsMessage = e.toString();
                  }
                  setState(() {
                    settingsStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnSetPrinterSettings:
          setState(() {
            settingsMessage = 'Setting printer settings...';
            settingsStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .setPrinterSettingsOverTCPIP(
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
                settings: Printer.PrinterSettings(
                  darkness: double.tryParse(darknessController.text),
                  printSpeed: double.tryParse(printSpeedController.text),
                  tearOff: int.tryParse(tearOffController.text),
                  mediaType: selectedMediaType,
                  printMethod: selectedPrintMethod,
                  printWidth: int.tryParse(printWidthController.text),
                  labelLength: int.tryParse(labelLengthController.text),
                  labelLengthMax: double.tryParse(
                    labelLengthMaxController.text,
                  ),
                  zplMode: selectedZPLMode,
                  powerUpAction: selectedPowerUpAction,
                  headCloseAction: selectedHeadCloseAction,
                  labelTop: int.tryParse(labelTopController.text),
                  leftPosition: int.tryParse(leftPositionController.text),
                  printMode: selectedPrintMode,
                  reprintMode: selectedReprintMode,
                  virtualDevice: selectedVirtualDevice,
                ),
                //            settings: Printer.PrinterSettings(
                //              darkness: 10, //10
                //              printSpeed: 6, //6
                //              tearOff: 0,//0
                //              mediaType: Printer.MediaType.MARK, //MARK
                //              printMethod: Printer.PrintMethod.DIRECT_THERMAL, //DIRECT_THERMAL
                //              printWidth: 568,//600
                //              labelLength: 1202,//1202
                //              labelLengthMax: 39,//39
                //              zplMode: Printer.ZPLMode.ZPL_II,//ZPL II
                //              powerUpAction: Printer.PowerUpAction.NO_MOTION,//NO MOTION
                //              headCloseAction: Printer.HeadCloseAction.FEED,//FEED
                //              labelTop: 0,//0
                //              leftPosition: 0,//0
                //              printMode: Printer.PrintMode.TEAR_OFF,//TEAR_OFF
                //              reprintMode: Printer.ReprintMode.OFF,//OFF
                //              virtualDevice: selectedVirtualDevice,
                //            )
                //            settings: Printer.PrinterSettings(
                //              darkness: 30, //10
                //              printSpeed: 3, //6
                //              tearOff: 100,//0
                //              mediaType: Printer.MediaType.CONTINUOUS, //MARK
                //              printMethod: Printer.PrintMethod.THERMAL_TRANS, //DIRECT_THERMAL
                //              printWidth: 568,//600
                //              labelLength: 1000,//1202
                //              labelLengthMax: 30,//39
                //              zplMode: Printer.ZPLMode.ZPL,//ZPL II
                //              powerUpAction: Printer.PowerUpAction.FEED,//NO MOTION
                //              headCloseAction: Printer.HeadCloseAction.NO_MOTION,//FEED
                //              labelTop: 50,//0
                //              leftPosition: 100,//0
                //              printMode: Printer.PrintMode.CUTTER,//TEAR_OFF
                //              reprintMode: Printer.ReprintMode.ON,//OFF
                //              virtualDevice: selectedVirtualDevice,
                //            )
              )
              .then(
                (value) {
                  setState(() {
                    settingsStatus = OperationStatus.SUCCESS;
                    settingsMessage = '$value';
                    updateSettings(
                      (Printer.PrinterResponse.fromMap(value)).settings,
                    );
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      settingsMessage =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause} \n'
                          '${printerResponse.settings?.toString()}';
                    } catch (e) {
                      print(e);
                      settingsMessage = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    settingsMessage = '${e.message}';
                  } catch (e) {
                    settingsMessage = e.toString();
                  }
                  setState(() {
                    settingsStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnResetPrinterSettings:
          setState(() {
            settingsMessage = 'Setting default settings...';
            settingsStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .setPrinterSettingsOverTCPIP(
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
                settings: Printer.PrinterSettings.defaultSettings(),
              )
              .then(
                (value) {
                  setState(() {
                    settingsStatus = OperationStatus.SUCCESS;
                    settingsMessage = '$value';
                    updateSettings(
                      (Printer.PrinterResponse.fromMap(value)).settings,
                    );
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      settingsMessage =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause} \n'
                          '${printerResponse.settings?.toString()}';
                    } catch (e) {
                      print(e);
                      settingsMessage = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    settingsMessage = '${e.message}';
                  } catch (e) {
                    settingsMessage = e.toString();
                  }
                  setState(() {
                    settingsStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnCheckPrinterStatus:
          setState(() {
            statusMessage = 'Checking printer status...';
            checkingStatus = OperationStatus.RECEIVING;
          });
          widget.zsdk
              .checkPrinterStatusOverTCPIP(
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
              )
              .then(
                (value) {
                  setState(() {
                    checkingStatus = OperationStatus.SUCCESS;
                    Printer.PrinterResponse? printerResponse;
                    if (value != null) {
                      printerResponse = Printer.PrinterResponse.fromMap(value);
                    }
                    statusMessage =
                        '${printerResponse != null ? printerResponse.toMap() : value}';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      statusMessage =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause}';
                    } catch (e) {
                      print(e);
                      statusMessage = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    statusMessage = '${e.message}';
                  } catch (e) {
                    statusMessage = e.toString();
                  }
                  setState(() {
                    checkingStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnRebootPrinter:
          setState(() {
            statusMessage = 'Rebooting printer...';
            rebootingStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .rebootPrinterOverTCPIP(
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
              )
              .then(
                (value) {
                  setState(() {
                    rebootingStatus = OperationStatus.SUCCESS;
                    Printer.PrinterResponse? printerResponse;
                    if (value != null) {
                      printerResponse = Printer.PrinterResponse.fromMap(value);
                    }
                    statusMessage =
                        '${printerResponse != null ? printerResponse.toMap() : value}';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      statusMessage =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause}';
                    } catch (e) {
                      print(e);
                      statusMessage = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    statusMessage = '${e.message}';
                  } catch (e) {
                    statusMessage = e.toString();
                  }
                  setState(() {
                    rebootingStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnPrintConfigurationLabel:
          setState(() {
            message = 'Print job started...';
            printStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .printConfigurationLabelOverTCPIP(
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
              )
              .then(
                (value) {
                  setState(() {
                    printStatus = OperationStatus.SUCCESS;
                    message = '$value';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      message =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause}';
                    } catch (e) {
                      print(e);
                      message = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    message = '${e.message}';
                  } catch (e) {
                    message = e.toString();
                  }
                  setState(() {
                    printStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnPrintPdfFileOverTCPIP:
          if (!pathController.text.endsWith('.pdf')) {
            throw Exception(
              'Make sure you properly write the path or selected a proper pdf file',
            );
          }
          setState(() {
            message = 'Print job started...';
            printStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .printPdfFileOverTCPIP(
                filePath: pathController.text,
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
                printerConf: Printer.PrinterConf(
                  cmWidth: double.tryParse(widthController.text),
                  cmHeight: double.tryParse(heightController.text),
                  dpi: double.tryParse(dpiController.text),
                  orientation: printerOrientation,
                ),
              )
              .then(
                (value) {
                  setState(() {
                    printStatus = OperationStatus.SUCCESS;
                    message = '$value';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      message =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause}';
                    } catch (e) {
                      print(e);
                      message = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    message = '${e.message}';
                  } catch (e) {
                    message = e.toString();
                  }
                  setState(() {
                    printStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnPrintZplFileOverTCPIP:
          if (filePath == null && !pathController.text.endsWith('.zpl')) {
            throw Exception(
              'Make sure you properly write the path or selected a proper zpl file',
            );
          }
          File zplFile = File(filePath!);
          if (await zplFile.exists()) {
            zplData = await zplFile.readAsString();
          }
          if (zplData == null || zplData!.isEmpty) {
            throw Exception(
              'Make sure you properly write the path or selected a proper zpl file',
            );
          }
          setState(() {
            message = 'Print job started...';
            printStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .printZplDataOverTCPIP(
                data: zplData!,
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
                printerConf: Printer.PrinterConf(
                  cmWidth: double.tryParse(widthController.text),
                  cmHeight: double.tryParse(heightController.text),
                  dpi: double.tryParse(dpiController.text),
                  orientation: printerOrientation,
                ),
              )
              .then(
                (value) {
                  setState(() {
                    printStatus = OperationStatus.SUCCESS;
                    message = '$value';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      message =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause}';
                    } catch (e) {
                      print(e);
                      message = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    message = '${e.message}';
                  } catch (e) {
                    message = e.toString();
                  }
                  setState(() {
                    printStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnPrintZplDataOverTCPIP:
          zplData = zplDataController.text;
          if (zplData == null || zplData!.isEmpty) {
            throw Exception("ZPL data can't be empty");
          }
          setState(() {
            message = 'Print job started...';
            printStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .printZplDataOverTCPIP(
                data: zplData!,
                address: addressIpController.text,
                port: int.tryParse(addressPortController.text),
                printerConf: Printer.PrinterConf(
                  cmWidth: double.tryParse(widthController.text),
                  cmHeight: double.tryParse(heightController.text),
                  dpi: double.tryParse(dpiController.text),
                  orientation: printerOrientation,
                ),
              )
              .then(
                (value) {
                  setState(() {
                    printStatus = OperationStatus.SUCCESS;
                    message = '$value';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      message =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause}';
                    } catch (e) {
                      print(e);
                      message = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    message = '${e.message}';
                  } catch (e) {
                    message = e.toString();
                  }
                  setState(() {
                    printStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
        case btnGetBondedDevices:
          setState(() {
            btMessage = 'Requesting permissions...';
            btStatus = OperationStatus.RECEIVING;
          });
          if (!await _requestBluetoothPermissions()) {
            setState(() {
              btStatus = OperationStatus.ERROR;
              btMessage = 'Bluetooth permissions denied';
            });
            break;
          }
          setState(() {
            btMessage = 'Getting bonded devices...';
          });
          widget.zsdk.getBondedDevices().then(
            (devices) {
              setState(() {
                bondedDevices = devices;
                btStatus = OperationStatus.SUCCESS;
                btMessage = 'Found ${devices.length} bonded device(s)';
              });
            },
            onError: (error, stacktrace) {
              setState(() {
                btStatus = OperationStatus.ERROR;
                btMessage = error.toString();
              });
            },
          );
          break;
        case btnDiscoverPrinters:
          setState(() {
            btMessage = 'Requesting permissions...';
            btStatus = OperationStatus.RECEIVING;
          });
          if (!await _requestBluetoothPermissions()) {
            setState(() {
              btStatus = OperationStatus.ERROR;
              btMessage = 'Bluetooth permissions denied';
            });
            break;
          }
          setState(() {
            btMessage = 'Scanning for Zebra printers...';
          });
          widget.zsdk.discoverBluetoothPrinters().then(
            (devices) {
              setState(() {
                bondedDevices = devices;
                btStatus = OperationStatus.SUCCESS;
                btMessage = 'Found ${devices.length} printer(s)';
              });
            },
            onError: (error, stacktrace) {
              setState(() {
                btStatus = OperationStatus.ERROR;
                btMessage = error.toString();
              });
            },
          );
          break;
        case btnPrintZplDataOverBluetooth:
          zplData = zplDataController.text;
          if (zplData == null || zplData!.isEmpty) {
            throw Exception("ZPL data can't be empty");
          }
          if (btMacAddressController.text.isEmpty) {
            throw Exception("MAC address can't be empty");
          }
          setState(() {
            btMessage = 'Print job started...';
            btStatus = OperationStatus.SENDING;
          });
          widget.zsdk
              .printZplDataOverBluetooth(
                data: zplData!,
                macAddress: btMacAddressController.text,
              )
              .then(
                (value) {
                  setState(() {
                    btStatus = OperationStatus.SUCCESS;
                    btMessage = '$value';
                  });
                },
                onError: (error, stacktrace) {
                  try {
                    throw error;
                  } on PlatformException catch (e) {
                    Printer.PrinterResponse printerResponse;
                    try {
                      printerResponse = Printer.PrinterResponse.fromMap(
                        e.details,
                      );
                      btMessage =
                          '${printerResponse.message} ${printerResponse.errorCode} ${printerResponse.statusInfo.status} ${printerResponse.statusInfo.cause}';
                    } catch (e) {
                      print(e);
                      btMessage = e.toString();
                    }
                  } on MissingPluginException catch (e) {
                    btMessage = '${e.message}';
                  } catch (e) {
                    btMessage = e.toString();
                  }
                  setState(() {
                    btStatus = OperationStatus.ERROR;
                  });
                },
              );
          break;
      }
    } catch (e) {
      print(e);
      showSnackBar(e.toString());
    }
  }

  void showSnackBar(String message) {
    ScaffoldMessenger.of(
      context,
    ).showSnackBar(SnackBar(content: Text(message)));
  }
}
43
likes
150
points
943
downloads

Publisher

verified publisherdev.lamt.dev

Weekly Downloads

A Flutter plugin for printers using Zebra Link OS, to allow ZPL and PDF priting over TCP/IP connections.

Repository (GitHub)
View/report issues

Topics

#zebra #thermal #ticket #printer

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on zsdk

Packages that implement zsdk