algún avance con copilot en apgar
This commit is contained in:
parent
b053fc3900
commit
57becb5577
1 changed files with 120 additions and 67 deletions
|
|
@ -1,3 +1,4 @@
|
|||
// dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import '../formula_models.dart';
|
||||
|
|
@ -15,9 +16,6 @@ class FormulaScreen extends StatefulWidget {
|
|||
State<FormulaScreen> createState() => _FormulaScreenState();
|
||||
}
|
||||
|
||||
// TODO: Create VariableWidget. Depending on VariableSpec.values, it can be a ValueDropdown or a D4rtEditingController
|
||||
// The d4rtValue will be FormulaResult?
|
||||
|
||||
//// Start of D4rtEditingController class ////
|
||||
class D4rtEditingController extends TextEditingController {
|
||||
String? _lastError;
|
||||
|
|
@ -34,8 +32,8 @@ class D4rtEditingController extends TextEditingController {
|
|||
return true;
|
||||
} catch (e, s) {
|
||||
_lastError = e.toString();
|
||||
print( "validate: $text: $e" );
|
||||
print( "stack: $s" );
|
||||
print("validate: $text: $e");
|
||||
print("stack: $s");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -59,19 +57,25 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
final _formKey = GlobalKey<FormState>();
|
||||
final Map<String, D4rtEditingController> _inputControllers = {};
|
||||
final Map<String, String?> _selectedUnits = {};
|
||||
final Map<String, String?> _selectedValues = {}; // for string dropdowns
|
||||
String? _result;
|
||||
String? _selectedOutputUnit;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Initialize controllers and units with listeners
|
||||
for (final input in widget.formula.input) {
|
||||
_inputControllers[input.name] = D4rtEditingController();
|
||||
_selectedUnits[input.name] = input.unit;
|
||||
if (input.values != null && input.values!.isNotEmpty) {
|
||||
// string/categorical variable -> use dropdown
|
||||
_selectedValues[input.name] = input.values!.first;
|
||||
} else {
|
||||
// numeric variable -> use D4rtEditingController
|
||||
_inputControllers[input.name] = D4rtEditingController();
|
||||
_inputControllers[input.name]!.addListener(_evaluateFormula);
|
||||
}
|
||||
}
|
||||
_selectedOutputUnit = widget.formula.output.unit;
|
||||
}
|
||||
|
||||
|
|
@ -91,34 +95,41 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
try {
|
||||
final inputValues = <String, dynamic>{};
|
||||
for (final input in widget.formula.input) {
|
||||
// string/categorical variable
|
||||
if (input.values != null && input.values!.isNotEmpty) {
|
||||
final selected = _selectedValues[input.name];
|
||||
if (selected == null) {
|
||||
_result = "";
|
||||
return;
|
||||
}
|
||||
inputValues[input.name] = selected;
|
||||
continue;
|
||||
}
|
||||
|
||||
// numeric variable - must have controller
|
||||
final controller = _inputControllers[input.name]!;
|
||||
if (controller.d4rtValue == null) {
|
||||
//throw FormulaEvaluationException("Field ${input.name} is invalid");
|
||||
final val = controller.d4rtValue;
|
||||
if (val == null) {
|
||||
_result = "";
|
||||
return;
|
||||
}
|
||||
|
||||
late final dynamic convertedValue;
|
||||
|
||||
switch (controller.d4rtValue) {
|
||||
case NumberResult nr:
|
||||
// Convert input to base unit if needed
|
||||
// Always convert from dropdown unit to variable's base unit
|
||||
dynamic convertedValue;
|
||||
if (val is NumberResult) {
|
||||
if (input.unit != null) {
|
||||
convertedValue = widget.corpus.convert(
|
||||
nr.value,
|
||||
val.value,
|
||||
_selectedUnits[input.name]!,
|
||||
input.unit as String,
|
||||
);
|
||||
} else {
|
||||
convertedValue = nr.value;
|
||||
convertedValue = val.value;
|
||||
}
|
||||
|
||||
case StringResult sr:
|
||||
convertedValue = sr.value;
|
||||
default:
|
||||
} else if (val is StringResult) {
|
||||
convertedValue = val.value;
|
||||
} else {
|
||||
throw FormulaEvaluationException(
|
||||
"Field ${input.name} has unsupported type ${controller.d4rtValue!.runtimeType}",
|
||||
"Field ${input.name} has unsupported type ${val.runtimeType}",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -131,14 +142,15 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
// Convert output to selected unit if needed
|
||||
String? unit = widget.formula.output.unit;
|
||||
if (unit != null) {
|
||||
_result = widget.corpus
|
||||
.convert(result, unit, _selectedOutputUnit!)
|
||||
.toStringAsFixed(2);
|
||||
final converted = widget.corpus.convert(result, unit, _selectedOutputUnit!);
|
||||
if (converted is num) {
|
||||
_result = converted.toStringAsFixed(2);
|
||||
} else {
|
||||
_result = result;
|
||||
_result = converted.toString();
|
||||
}
|
||||
} else {
|
||||
_result = result?.toString();
|
||||
}
|
||||
|
||||
//print( "_evaluateFormula: result:${result} _result:${_result}");
|
||||
|
||||
setState(() {});
|
||||
} catch (e, stack) {
|
||||
|
|
@ -269,12 +281,51 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
}
|
||||
|
||||
Widget _buildVariableRow(VariableSpec variable) {
|
||||
final isCategorical = variable.values != null && variable.values!.isNotEmpty;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(variable.name),
|
||||
const Spacer(),
|
||||
if (isCategorical) ...[
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: _selectedValues[variable.name],
|
||||
items: variable.values!
|
||||
.map((v) => DropdownMenuItem<String>(value: v, child: Text(v)))
|
||||
.toList(),
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_selectedValues[variable.name] = v;
|
||||
});
|
||||
_evaluateFormula();
|
||||
},
|
||||
decoration: const InputDecoration(
|
||||
border: UnderlineInputBorder(),
|
||||
),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) return 'Required';
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (variable.unit != null)
|
||||
UnitDropdown(
|
||||
corpus: widget.corpus,
|
||||
variable: variable,
|
||||
selectedUnit: _selectedUnits[variable.name],
|
||||
onUnitChanged: (unit) {
|
||||
setState(() {
|
||||
_selectedUnits[variable.name] = unit;
|
||||
});
|
||||
_evaluateFormula();
|
||||
},
|
||||
),
|
||||
] else ...[
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: TextFormField(
|
||||
|
|
@ -296,6 +347,7 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (variable.unit != null)
|
||||
UnitDropdown(
|
||||
corpus: widget.corpus,
|
||||
variable: variable,
|
||||
|
|
@ -308,6 +360,7 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue