diff --git a/lib/ai/formula_screen.dart b/lib/ai/formula_screen.dart index 823758e..1494e42 100644 --- a/lib/ai/formula_screen.dart +++ b/lib/ai/formula_screen.dart @@ -21,9 +21,42 @@ class FormulaScreen extends StatefulWidget { State createState() => _FormulaScreenState(); } +//// Start of D4rtEditingController class //// +class D4rtEditingController extends TextEditingController { + String? _lastError; + + String? get lastError => _lastError; + + D4rtEditingController({String? text}) : super(text: text); + + bool validate() { + try { + FormulaEvaluator.evaluateExpression(text); + _lastError = null; + return true; + } catch (e) { + _lastError = e.toString(); + return false; + } + } + + @override + set text(String newText) { + super.text = newText; + validate(); + } + + @override + void notifyListeners() { + validate(); + super.notifyListeners(); + } +} +//// End of D4rtEditingController class //// + class _FormulaScreenState extends State { final _formKey = GlobalKey(); - final Map _inputControllers = {}; + final Map _inputControllers = {}; final Map _selectedUnits = {}; String? _result; String? _selectedOutputUnit; @@ -33,7 +66,7 @@ class _FormulaScreenState extends State { super.initState(); // Initialize controllers and units with listeners for (final input in widget.formula.input) { - _inputControllers[input.name] = TextEditingController(); + _inputControllers[input.name] = D4rtEditingController(); _selectedUnits[input.name] = input.unit; _inputControllers[input.name]!.addListener(_evaluateFormula); } @@ -235,7 +268,7 @@ class _FormulaScreenState extends State { if (value == null || value.isEmpty) { return 'Required'; } - return null; + return _inputControllers[variable.name]!.lastError; }, ), ), diff --git a/lib/defaults/formulas.d4rt b/lib/defaults/formulas.d4rt index c173128..09d77a6 100644 --- a/lib/defaults/formulas.d4rt +++ b/lib/defaults/formulas.d4rt @@ -1,4 +1,15 @@ [ + +{ + "name": "Temperature converter", + "description": "Example of simple formula, just unit conversion", + "input": [ + {"name": "Input", "unit": "Celsius" } + ], + "output": {"name": "Output", "unit": "Kelvin" }, + "d4rtCode": "Output = Input;", + "tags": ["converter", "temperature" ] +}, // Free fall distance (vertical) { "name": "Free Fall Distance", diff --git a/lib/formula_evaluator.dart b/lib/formula_evaluator.dart index 686ef2d..caeac55 100644 --- a/lib/formula_evaluator.dart +++ b/lib/formula_evaluator.dart @@ -67,9 +67,11 @@ class FormulaEvaluator { import "package:d4rt_formulas.dart"; main() { - return $code; + late var result; + result = $code; + return result; }"""; - print("evaluateExpression:\n$d4rtCode"); + //print("evaluateExpression:\n$d4rtCode"); final result = interpreter.execute(source: d4rtCode); return result.toDouble(); } diff --git a/pubspec.lock b/pubspec.lock index b1879fe..dcb224b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -33,6 +33,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" + autotrie: + dependency: transitive + description: + name: autotrie + sha256: "55da6faefb53cfcb0abb2f2ca8636123fb40e35286bb57440d2cf467568188f8" + url: "https://pub.dev" + source: hosted + version: "2.0.0" boolean_selector: dependency: transitive description: @@ -49,6 +57,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + charcode: + dependency: transitive + description: + name: charcode + sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a + url: "https://pub.dev" + source: hosted + version: "1.4.0" cli_config: dependency: transitive description: @@ -113,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.4" + equatable: + dependency: transitive + description: + name: equatable + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + url: "https://pub.dev" + source: hosted + version: "2.0.7" fake_async: dependency: transitive description: @@ -134,6 +158,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_code_editor: + dependency: "direct main" + description: + name: flutter_code_editor + sha256: "9af48ba8e3558b6ea4bb98b84c5eb1649702acf53e61a84d88383eeb79b239b0" + url: "https://pub.dev" + source: hosted + version: "0.3.5" flutter_d4rt: dependency: "direct main" description: @@ -142,6 +174,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.3" + flutter_highlight: + dependency: transitive + description: + name: flutter_highlight + sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c" + url: "https://pub.dev" + source: hosted + version: "0.7.0" flutter_lints: dependency: "direct dev" description: @@ -163,6 +203,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" frontend_server_client: dependency: transitive description: @@ -179,6 +224,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + highlight: + dependency: transitive + description: + name: highlight + sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + hive: + dependency: transitive + description: + name: hive + sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" + url: "https://pub.dev" + source: hosted + version: "2.2.3" http: dependency: transitive description: @@ -243,6 +304,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + linked_scroll_controller: + dependency: transitive + description: + name: linked_scroll_controller + sha256: e6020062bcf4ffc907ee7fd090fa971e65d8dfaac3c62baf601a3ced0b37986a + url: "https://pub.dev" + source: hosted + version: "0.2.0" lints: dependency: transitive description: @@ -299,6 +368,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + mocktail: + dependency: transitive + description: + name: mocktail + sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8" + url: "https://pub.dev" + source: hosted + version: "1.0.4" node_preamble: dependency: transitive description: @@ -323,6 +400,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" pool: dependency: transitive description: @@ -347,6 +432,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + scrollable_positioned_list: + dependency: transitive + description: + name: scrollable_positioned_list + sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287" + url: "https://pub.dev" + source: hosted + version: "0.3.8" shelf: dependency: transitive description: @@ -464,6 +557,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.12" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: @@ -472,6 +573,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9" + url: "https://pub.dev" + source: hosted + version: "6.3.24" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 + url: "https://pub.dev" + source: hosted + version: "6.3.4" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f + url: "https://pub.dev" + source: hosted + version: "3.2.3" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + url: "https://pub.dev" + source: hosted + version: "3.1.4" vector_math: dependency: transitive description: @@ -537,5 +702,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.8.1 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.9.0 <4.0.0" + flutter: ">=3.35.0" diff --git a/pubspec.yaml b/pubspec.yaml index 917126f..4c62d14 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: d4rt: flutter_d4rt: flutter_markdown: ^0.6.0 + flutter_code_editor: collection: any dev_dependencies: