add import export and items
This commit is contained in:
@@ -13,7 +13,7 @@ class AnwendungForm extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final filament = controller.filament.value!;
|
||||
return EntryPanel(
|
||||
title: 'Verarbeitung erfassen',
|
||||
title: 'Verarbeitungsprofil bearbeiten',
|
||||
subtitle:
|
||||
'${filament.marke} · ${filament.material} · ${filament.farbe}\n'
|
||||
'Speichere die Einstellungen für dieses Filament als Profil.',
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:intl/intl.dart';
|
||||
import '../controller/home_controller.dart';
|
||||
import '../theme/app_theme.dart';
|
||||
import '../helper/input_validators.dart';
|
||||
import 'filament_material_field.dart';
|
||||
|
||||
class FilamentForm extends StatelessWidget {
|
||||
const FilamentForm({super.key, required this.controller});
|
||||
@@ -130,29 +131,7 @@ class FilamentForm extends StatelessWidget {
|
||||
: null,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Obx(
|
||||
() => DropdownButtonFormField<String>(
|
||||
key: ValueKey(
|
||||
'${controller.editingId.value ?? "new"}_${controller.material.value}',
|
||||
),
|
||||
initialValue: controller.material.value,
|
||||
isExpanded: true,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Material',
|
||||
prefixIcon: Icon(Icons.layers_outlined),
|
||||
),
|
||||
items: controller.materialien
|
||||
.toSet()
|
||||
.map(
|
||||
(item) =>
|
||||
DropdownMenuItem(value: item, child: Text(item)),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
if (value != null) controller.material.value = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
FilamentMaterialField(controller: controller),
|
||||
const SizedBox(height: 16),
|
||||
TextFormField(
|
||||
controller: controller.farbeController,
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
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'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user