diff --git a/lib/dialogs/new_ask_for_name.dart b/lib/dialogs/new_ask_for_name.dart new file mode 100644 index 0000000..2ba41f2 --- /dev/null +++ b/lib/dialogs/new_ask_for_name.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; + +class NewAskForNameDialog extends HookWidget { + final String title; + final String? labelText; + + const NewAskForNameDialog({required this.title, this.labelText, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final tec = useTextEditingController(); + final onPressed = useMemoized(() => () { + Navigator.of(context).pop(tec.text); + }, [tec.text]); + + return Dialog( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: IntrinsicWidth( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Align( + alignment: Alignment.centerRight, + child: IconButton( + icon: const Icon(Icons.close), + tooltip: 'Close', + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + Text( + title, + style: Theme.of(context).textTheme.headline6, + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + constraints: const BoxConstraints(minWidth: 300), + child: TextField( + controller: tec, + decoration: InputDecoration( + border: const OutlineInputBorder(), + labelText: labelText, + suffixIcon: IconButton( + icon: const Icon(Icons.done), + onPressed: onPressed, + ), + ), + onSubmitted: (_) => onPressed(), + ), + ), + ), + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/edit_component.dart b/lib/pages/edit_component.dart index 6a9e895..5fa4292 100644 --- a/lib/pages/edit_component.dart +++ b/lib/pages/edit_component.dart @@ -1,6 +1,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:logic_circuits_simulator/dialogs/new_ask_for_name.dart'; import 'package:logic_circuits_simulator/models/project.dart'; import 'package:logic_circuits_simulator/state/project.dart'; import 'package:logic_circuits_simulator/utils/iterable_extension.dart'; @@ -18,11 +19,11 @@ class EditComponentPage extends HookWidget { Widget build(BuildContext context) { final anySave = useState(false); final projectState = useProvider(); - final ce = projectState.index.components.where((c) => c.componentId == component.componentId).first; - final truthTable = useState(ce.truthTable?.toList()); - final inputs = useState(ce.inputs.toList()); - final outputs = useState(ce.outputs.toList()); - final componentNameEditingController = useTextEditingController(text: ce.componentName); + ComponentEntry ce() => projectState.index.components.where((c) => c.componentId == component.componentId).first; + final truthTable = useState(ce().truthTable?.toList()); + final inputs = useState(ce().inputs.toList()); + final outputs = useState(ce().outputs.toList()); + final componentNameEditingController = useTextEditingController(text: ce().componentName); useValueListenable(componentNameEditingController); final dirty = useMemoized( () { @@ -38,29 +39,29 @@ class EditComponentPage extends HookWidget { // Don't allow saving empty outputs return false; } - if (componentNameEditingController.text != ce.componentName) { + if (componentNameEditingController.text != ce().componentName) { return true; } - if (!const ListEquality().equals(inputs.value, ce.inputs)) { + if (!const ListEquality().equals(inputs.value, ce().inputs)) { return true; } - if (!const ListEquality().equals(outputs.value, ce.outputs)) { + if (!const ListEquality().equals(outputs.value, ce().outputs)) { return true; } - if (!const ListEquality().equals(truthTable.value, ce.truthTable)) { + if (!const ListEquality().equals(truthTable.value, ce().truthTable)) { return true; } return false; }, [ componentNameEditingController.text, - ce.componentName, + ce().componentName, inputs.value, - ce.inputs, + ce().inputs, outputs.value, - ce.outputs, + ce().outputs, truthTable.value, - ce.truthTable, + ce().truthTable, ], ); @@ -136,8 +137,20 @@ class EditComponentPage extends HookWidget { IconButton( icon: const Icon(Icons.add), tooltip: 'Add new input', - onPressed: () { - + onPressed: () async { + final inputName = await showDialog( + context: context, + builder: (context) { + return const NewAskForNameDialog( + title: 'New Input', + labelText: 'Input name', + ); + }, + ); + if (inputName != null) { + truthTable.value = truthTable.value?.expand((element) => [element, element]).toList(); + inputs.value = inputs.value.toList()..add(inputName); + } }, ), ], @@ -216,8 +229,20 @@ class EditComponentPage extends HookWidget { IconButton( icon: const Icon(Icons.add), tooltip: 'Add new output', - onPressed: () { - + onPressed: () async { + final outputName = await showDialog( + context: context, + builder: (context) { + return const NewAskForNameDialog( + title: 'New Output', + labelText: 'Output name', + ); + }, + ); + if (outputName != null) { + truthTable.value = truthTable.value?.map((e) => '${e}0').toList(); + outputs.value = outputs.value.toList()..add(outputName); + } }, ), ], @@ -294,15 +319,17 @@ class EditComponentPage extends HookWidget { ), ), ) + ] else ...[ + ], ], ), floatingActionButton: !dirty ? null : FloatingActionButton( onPressed: () async { if (componentNameEditingController.text.isNotEmpty) { - await projectState.editComponent(component.copyWith(componentName: componentNameEditingController.text)); + await projectState.editComponent(ce().copyWith(componentName: componentNameEditingController.text)); } - await projectState.editComponent(ce.copyWith( + await projectState.editComponent(ce().copyWith( inputs: inputs.value, outputs: outputs.value, truthTable: truthTable.value, diff --git a/pubspec.lock b/pubspec.lock index ec8a384..b80131a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -28,7 +28,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" boolean_selector: dependency: transitive description: