127 lines
4.2 KiB
Dart
127 lines
4.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
import '../controller/home_controller.dart';
|
|
|
|
class FilamentMaterialField extends StatelessWidget {
|
|
const FilamentMaterialField({super.key, required this.controller});
|
|
|
|
final HomeController controller;
|
|
|
|
@override
|
|
Widget build(BuildContext context) => Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
TextFormField(
|
|
controller: controller.materialController,
|
|
onChanged: (value) => controller.material.value = value,
|
|
validator: (value) => value == null || value.trim().isEmpty
|
|
? 'Materialart eingeben oder auswählen'
|
|
: null,
|
|
decoration: InputDecoration(
|
|
labelText: 'Material',
|
|
helperText: 'Auswählen oder eigene Art eingeben',
|
|
prefixIcon: const Icon(Icons.layers_outlined),
|
|
suffixIcon: Obx(
|
|
() => PopupMenuButton<String>(
|
|
tooltip: 'Material auswählen',
|
|
enabled: controller.materialien.isNotEmpty,
|
|
icon: const Icon(Icons.expand_more),
|
|
onSelected: controller.selectMaterial,
|
|
itemBuilder: (context) => controller.materialien
|
|
.map((item) => PopupMenuItem(value: item, child: Text(item)))
|
|
.toList(),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Obx(
|
|
() => Wrap(
|
|
spacing: 8,
|
|
children: [
|
|
TextButton.icon(
|
|
onPressed: controller.isSavingMaterial.value
|
|
? null
|
|
: () async {
|
|
if (await controller.addMaterial() && context.mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content: Text('Art ist in der Liste.'),
|
|
),
|
|
);
|
|
}
|
|
},
|
|
icon: const Icon(Icons.add),
|
|
label: const Text('Art hinzufügen'),
|
|
),
|
|
TextButton.icon(
|
|
onPressed: () => _manage(context),
|
|
icon: const Icon(Icons.tune),
|
|
label: const Text('Arten verwalten'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
_message(),
|
|
],
|
|
);
|
|
|
|
Widget _message() => Obx(() {
|
|
final message = controller.materialMessage.value;
|
|
return message == null
|
|
? const SizedBox.shrink()
|
|
: Text(message, style: const TextStyle(color: Colors.red));
|
|
});
|
|
|
|
Future<void> _manage(BuildContext context) => showDialog<void>(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Materialarten verwalten'),
|
|
content: SizedBox(
|
|
width: 360,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
const Text(
|
|
'Entfernte Arten verschwinden aus der Auswahl. Gespeicherte Filamente bleiben erhalten.',
|
|
),
|
|
const SizedBox(height: 12),
|
|
Flexible(
|
|
child: Obx(() {
|
|
final values = controller.materialien.toList();
|
|
final busy = controller.isSavingMaterial.value;
|
|
if (values.isEmpty) {
|
|
return const Text('Keine Materialarten in der Liste.');
|
|
}
|
|
return ListView.builder(
|
|
shrinkWrap: true,
|
|
itemCount: values.length,
|
|
itemBuilder: (context, index) => ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
title: Text(values[index]),
|
|
trailing: IconButton(
|
|
tooltip: '${values[index]} aus Liste entfernen',
|
|
icon: const Icon(Icons.delete_outline),
|
|
onPressed: busy
|
|
? null
|
|
: () => controller.removeMaterial(values[index]),
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
_message(),
|
|
],
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Schließen'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|