diff --git a/lib/ai/d4rt_editing_controller.dart b/lib/ai/d4rt_editing_controller.dart new file mode 100644 index 0000000..a8bc3b7 --- /dev/null +++ b/lib/ai/d4rt_editing_controller.dart @@ -0,0 +1,73 @@ + +import 'package:flutter/cupertino.dart'; + +import '../formula_evaluator.dart'; + +//// Start of D4rtEditingController class //// +class D4rtEditingController extends TextEditingController { + String? _lastError; + String? get lastError => _lastError; + FormulaResult? _lastValue; + final bool isString; + + D4rtEditingController({super.text, this.isString = false}); + + bool validate() { + if( _validateAsNumberExpression(text) ){ + return true; + } + if( isString && _validateAsStringExpression(text) ){ + return true; + } + return false; + } + + bool _validateAsNumberExpression(String text){ + return _validateAsD4rtExpression(text) && _lastValue is NumberResult; + } + + bool _validateAsD4rtExpression(String text){ + try { + _lastValue = null; + if( text.trim().isEmpty ){ + return true; + } + _lastValue = FormulaEvaluator.evaluateExpression(text); + _lastError = null; + return true; + } catch (e, s) { + //errorHandler.notify(e, s); + _lastError = e.toString(); + return false; + } + } + + bool _validateAsStringExpression(String text){ + if( _validateAsD4rtExpression(text) && _lastValue is StringResult ){ + return true; + } + if( _validateAsD4rtExpression('"$text"') && _lastValue is StringResult ){ + return true; + } + if( _validateAsD4rtExpression("'$text'") && _lastValue is StringResult ){ + return true; + } + return false; + } + + + FormulaResult? get d4rtValue => _lastValue; + + @override + set text(String newText) { + super.text = newText; + validate(); + } + + @override + void notifyListeners() { + validate(); + super.notifyListeners(); + } +} +//// End of D4rtEditingController class //// diff --git a/lib/ai/formula_screen.dart b/lib/ai/formula_screen.dart index f8828c7..8bca858 100644 --- a/lib/ai/formula_screen.dart +++ b/lib/ai/formula_screen.dart @@ -7,6 +7,7 @@ import '../formula_models.dart'; import '../formula_evaluator.dart'; import '../corpus.dart'; import '../error_handler.dart'; +import 'd4rt_editing_controller.dart'; import 'unit_dropdown.dart'; import 'formula_editor.dart'; @@ -20,74 +21,6 @@ class FormulaScreen extends StatefulWidget { State createState() => _FormulaScreenState(); } -//// Start of D4rtEditingController class //// -class D4rtEditingController extends TextEditingController { - String? _lastError; - String? get lastError => _lastError; - FormulaResult? _lastValue; - final bool isString; - - D4rtEditingController({super.text, this.isString = false}); - - bool validate() { - if( _validateAsNumberExpression(text) ){ - return true; - } - if( isString && _validateAsStringExpression(text) ){ - return true; - } - return false; - } - - bool _validateAsNumberExpression(String text){ - return _validateAsD4rtExpression(text) && _lastValue is NumberResult; - } - - bool _validateAsD4rtExpression(String text){ - try { - _lastValue = null; - if( text.trim().isEmpty ){ - return true; - } - _lastValue = FormulaEvaluator.evaluateExpression(text); - _lastError = null; - return true; - } catch (e, s) { - //errorHandler.notify(e, s); - _lastError = e.toString(); - return false; - } - } - - bool _validateAsStringExpression(String text){ - if( _validateAsD4rtExpression(text) && _lastValue is StringResult ){ - return true; - } - if( _validateAsD4rtExpression('"$text"') && _lastValue is StringResult ){ - return true; - } - if( _validateAsD4rtExpression("'$text'") && _lastValue is StringResult ){ - return true; - } - return false; - } - - - FormulaResult? get d4rtValue => _lastValue; - - @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(); diff --git a/lib/ai/unit_list.dart b/lib/ai/unit_list.dart deleted file mode 100644 index 8ca03ed..0000000 --- a/lib/ai/unit_list.dart +++ /dev/null @@ -1,159 +0,0 @@ -import 'package:flutter/material.dart'; -import '../corpus.dart'; -import '../formula_models.dart'; -import 'formula_screen.dart'; - -class UnitList extends StatefulWidget { - final Corpus corpus; - - const UnitList({super.key, required this.corpus}); - - @override - State createState() => _UnitListState(); -} - -class _UnitListState extends State { - final TextEditingController _searchController = TextEditingController(); - String _searchQuery = ''; - - @override - void initState() { - super.initState(); - _searchController.addListener(_onSearchChanged); - } - - void _onSearchChanged() { - setState(() { - _searchQuery = _searchController.text.toLowerCase(); - }); - } - - @override - void dispose() { - _searchController.dispose(); - super.dispose(); - } - - List get _filteredUnits { - bool filter(UnitSpec unit) => unit.name.toLowerCase().contains(_searchQuery); - return widget.corpus.allUnits().where(filter).toList(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Units List'), - actions: [ - IconButton( - icon: const Icon(Icons.functions), - onPressed: () { - final sampleFormula = Formula( - name: "Kinetic Energy", - input: [ - VariableSpec(name: 'mass', unit: 'kilogram'), - VariableSpec(name: 'velocity', unit: 'meters_per_second'), - ], - description : """ - # titulo - hola - ## otro titulo - """, - output: VariableSpec(name: 'energy', unit: 'joule'), - d4rtCode: "energy = 0.5 * mass * velocity * velocity;", - ); - - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FormulaScreen( - formula: sampleFormula, - corpus: widget.corpus, - ), - ), - ); - }, - ), - ], - ), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: TextField( - controller: _searchController, - decoration: const InputDecoration( - labelText: 'Search units', - hintText: 'Start typing unit name...', - prefixIcon: Icon(Icons.search), - border: OutlineInputBorder(), - ), - ), - ), - Expanded( - child: _filteredUnits.isEmpty - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.search_off, size: 40, color: Theme.of(context).colorScheme.outline), - const SizedBox(height: 16), - Text('No matching units found', - style: Theme.of(context).textTheme.titleSmall?.copyWith( - color: Theme.of(context).colorScheme.outline - ), - ), - ], - ), - ) - : ListView.builder( - itemCount: _filteredUnits.length, - itemBuilder: (context, index) { - final unit = _filteredUnits[index]; - return ListTile( - title: Text(unit.name), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Symbol: ${unit.symbol}'), - Text('Base: ${unit.baseUnit}', - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant - ), - ), - if (unit.factorFromUnitToBase != null) - Padding( - padding: const EdgeInsets.only(top: 4), - child: Text('1 ${unit.name} = ${unit.factorFromUnitToBase} ${unit.baseUnit}', - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontFeatures: [const FontFeature.tabularFigures()], - color: Theme.of(context).colorScheme.primary, - ), - ), - ), - ], - ), - contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - tileColor: index.isEven - ? Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.2) - : null, - visualDensity: VisualDensity.compact, - ); - }, - ), - ), - Padding( - padding: const EdgeInsets.all(16.0), - child: Text('hello Informáticos', - style: TextStyle( - fontSize: 18, - color: Theme.of(context).colorScheme.primary, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - ); - } -}