totem_alecto 0.0.2
totem_alecto: ^0.0.2 copied to clipboard
Package to interface with Totem Alecto printers
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:totem_alecto/totem_alecto.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Totem Alecto Example',
theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
home: const PrinterHomePage(),
);
}
}
class PrinterHomePage extends StatefulWidget {
const PrinterHomePage({super.key});
@override
State<PrinterHomePage> createState() => _PrinterHomePageState();
}
class _PrinterHomePageState extends State<PrinterHomePage> {
final _printer = TotemAlecto();
String _status = 'Desconectado';
bool _isConnected = false;
List<UsbDeviceInfo> _devices = [];
UsbDeviceInfo? _selectedDevice;
StreamSubscription<PrinterEvent>? _eventSubscription;
final _textController = TextEditingController(
text: 'Teste de Impressão\nTotem Alecto Plugin\n\n',
);
@override
void initState() {
super.initState();
_init();
}
@override
void dispose() {
_eventSubscription?.cancel();
_textController.dispose();
super.dispose();
}
Future<void> _init() async {
// Ouvir eventos da impressora
_eventSubscription = _printer.printerEvents.listen((event) {
setState(() {
switch (event.type) {
case PrinterEventType.onOpen:
_status = 'Conectado';
_isConnected = true;
break;
case PrinterEventType.onOpenFailed:
_status = 'Falha na conexão';
_isConnected = false;
break;
case PrinterEventType.onClose:
_status = 'Desconectado';
_isConnected = false;
break;
case PrinterEventType.onPrintComplete:
final success = event.success == true ? 'Sucesso' : 'Falha';
_showSnackBar('Impressão: $success (código: ${event.resultCode})');
break;
default:
break;
}
});
});
// Verificar suporte
final isSupported = await _printer.isSupported();
if (!isSupported) {
setState(() {
_status = 'USB não suportado';
});
return;
}
// Listar dispositivos
await _refreshDevices();
}
Future<void> _refreshDevices() async {
final devices = await _printer.listDevices();
setState(() {
_devices = devices;
if (devices.isNotEmpty && _selectedDevice == null) {
_selectedDevice = devices.first;
}
});
}
Future<void> _connectDevice() async {
if (_selectedDevice == null) {
_showSnackBar('Selecione um dispositivo');
return;
}
setState(() {
_status = 'Conectando...';
});
// Verificar permissão
// var hasPermission = await _printer.hasPermission(_selectedDevice!.deviceName);
// if (!hasPermission) {
// _showSnackBar('Solicitando permissão USB...');
// final granted = await _printer.requestPermission(_selectedDevice!.deviceName);
// if (!granted) {
// _showSnackBar('Permissão USB negada');
// setState(() {
// _status = 'Permissão negada';
// });
// return;
// }
// hasPermission = true;
// }
// Conectar
await _printer.connectByIds(4070, 33054);
}
Future<void> _connect() async {
if (_selectedDevice == null) {
_showSnackBar('Selecione um dispositivo');
return;
}
setState(() {
_status = 'Conectando...';
});
// Verificar permissão
var hasPermission = await _printer.hasPermission(
_selectedDevice!.deviceName,
);
if (!hasPermission) {
_showSnackBar('Solicitando permissão USB...');
final granted = await _printer.requestPermission(
_selectedDevice!.deviceName,
);
if (!granted) {
_showSnackBar('Permissão USB negada');
setState(() {
_status = 'Permissão negada';
});
return;
}
hasPermission = true;
}
// Conectar
if (hasPermission) {
await _printer.connect(_selectedDevice!.deviceName);
}
}
Future<void> _disconnect() async {
await _printer.disconnect();
}
Future<void> _printText() async {
if (!_isConnected) {
_showSnackBar('Impressora não conectada');
return;
}
final text = _textController.text;
if (text.isEmpty) {
_showSnackBar('Digite um texto para imprimir');
return;
}
final result = await _printer.printText(
text,
alignment: TextAlignment.center,
cutPaper: true,
);
_showSnackBar(
result.success ? 'Enviado para impressão' : 'Erro ao imprimir',
);
}
Future<void> _printImage() async {
if (!_isConnected) {
_showSnackBar('Impressora não conectada');
return;
}
// Carregar a imagem do ativo
final byteData = await rootBundle.load('assets/images/epoc_logo.png');
final bytes = byteData.buffer.asUint8List();
final result = await _printer.printPicture(
bytes,
alignment: TextAlignment.center,
cutPaper: false,
);
_showSnackBar(
result.success
? 'Imagem enviada para impressão'
: 'Erro ao imprimir imagem',
);
}
Future<void> _printFormatted() async {
if (!_isConnected) {
_showSnackBar('Impressora não conectada');
return;
}
// Exemplo de texto formatado
await _printer.printTextFormatted(
'=== TOTEM ALECTO ===\n',
alignment: TextAlignment.center,
fontAttributes: const FontAttributes(bold: true, doubleHeight: true),
cutPaper: false,
);
await _printer.printText(
'\nData: ${DateTime.now()}\n',
alignment: TextAlignment.left,
cutPaper: false,
);
await _printer.printTextFormatted(
'\n*** FIM DO TESTE ***\n\n\n',
alignment: TextAlignment.center,
fontAttributes: const FontAttributes(bold: true),
cutPaper: false,
);
await _printer.printTextFormatted(
'\n*** FIM DO TESTE ***\n\n\n',
alignment: TextAlignment.center,
fontAttributes: const FontAttributes(bold: true),
cutPaper: false,
);
await _printer.printTextFormatted(
'\n*** FIM DO TESTE ***\n\n\n',
alignment: TextAlignment.center,
fontAttributes: const FontAttributes(bold: true),
cutPaper: false,
);
await _printer.printTextFormatted(
'\n*** FIM DO TESTE ***\n\n\n',
alignment: TextAlignment.center,
fontAttributes: const FontAttributes(bold: true),
cutPaper: false,
);
await _printer.printTextFormatted(
'\n*** FIM DO TESTE ***\n\n\n',
alignment: TextAlignment.center,
fontAttributes: const FontAttributes(bold: true),
cutPaper: false,
);
await _printer.printTextFormatted(
'\n*** FIM DO TESTE ***\n\n\n',
alignment: TextAlignment.center,
fontAttributes: const FontAttributes(bold: true),
cutPaper: false,
);
_showSnackBar('Impressão formatada enviada');
}
Future<void> _openDrawer() async {
if (!_isConnected) {
_showSnackBar('Impressora não conectada');
return;
}
await _printer.openCashDrawer();
_showSnackBar('Gaveta aberta');
}
Future<void> _beep() async {
if (!_isConnected) {
_showSnackBar('Impressora não conectada');
return;
}
await _printer.beep(times: 3, duration: 100);
}
void _showSnackBar(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message), duration: const Duration(seconds: 2)),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Totem Alecto'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _refreshDevices,
tooltip: 'Atualizar dispositivos',
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Status Card
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Icon(
_isConnected ? Icons.print : Icons.print_disabled,
size: 48,
color: _isConnected ? Colors.green : Colors.grey,
),
const SizedBox(height: 8),
Text(
_status,
style: Theme.of(context).textTheme.titleLarge,
),
],
),
),
),
const SizedBox(height: 16),
// Device Selection
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Dispositivos USB',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
if (_devices.isEmpty)
const Text('Nenhum dispositivo encontrado')
else
DropdownButton<UsbDeviceInfo>(
isExpanded: true,
value: _selectedDevice,
items: _devices.map((device) {
return DropdownMenuItem(
value: device,
child: Text(device.displayName),
);
}).toList(),
onChanged: (device) {
setState(() {
_selectedDevice = device;
});
},
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: _isConnected ? null : _connect,
icon: const Icon(Icons.usb),
label: const Text('Conectar'),
),
),
Expanded(
child: ElevatedButton.icon(
onPressed: _isConnected ? null : _connectDevice,
icon: const Icon(Icons.usb),
label: const Text('Conectar Via Device'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton.icon(
onPressed: _isConnected ? _disconnect : null,
icon: const Icon(Icons.usb_off),
label: const Text('Desconectar'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
),
),
),
],
),
],
),
),
),
const SizedBox(height: 16),
// Print Section
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Impressão',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
TextField(
controller: _textController,
maxLines: 4,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Digite o texto para imprimir...',
),
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: _isConnected ? _printText : null,
icon: const Icon(Icons.print),
label: const Text('Imprimir'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton.icon(
onPressed: _isConnected ? _printFormatted : null,
icon: const Icon(Icons.text_format),
label: const Text('Formatado'),
),
),
],
),
],
),
),
),
const SizedBox(height: 16),
const SizedBox(width: 8),
Image.asset('assets/images/epoc_logo.png', height: 48),
SizedBox(
width: 200,
child: ElevatedButton.icon(
onPressed: _isConnected ? _printImage : null,
icon: const Icon(Icons.text_format),
label: const Text('Imprimir imagem'),
),
),
// Actions Section
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Ações',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton.icon(
onPressed: _isConnected ? _openDrawer : null,
icon: const Icon(Icons.inventory_2),
label: const Text('Gaveta'),
),
ElevatedButton.icon(
onPressed: _isConnected ? _beep : null,
icon: const Icon(Icons.volume_up),
label: const Text('Beep'),
),
ElevatedButton.icon(
onPressed: _isConnected
? () => _printer.feedPaper(lines: 3)
: null,
icon: const Icon(Icons.arrow_downward),
label: const Text('Avançar'),
),
ElevatedButton.icon(
onPressed: _isConnected
? () => _printer.cutPaper()
: null,
icon: const Icon(Icons.content_cut),
label: const Text('Cortar'),
),
],
),
],
),
),
),
],
),
),
);
}
}