From 8a42d53c77489dccd31fe2696ec08c7b2fff5db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Fri, 17 Apr 2026 12:37:12 +0200 Subject: [PATCH] Added share menu to FormulaScreen --- lib/ai/formula_list.dart | 96 ++++++++++++++++++++------------------ lib/ai/formula_screen.dart | 37 +++++++++++++++ lib/formula_evaluator.dart | 4 +- 3 files changed, 90 insertions(+), 47 deletions(-) diff --git a/lib/ai/formula_list.dart b/lib/ai/formula_list.dart index 198477d..3c1f48f 100644 --- a/lib/ai/formula_list.dart +++ b/lib/ai/formula_list.dart @@ -1,6 +1,8 @@ +import 'package:d4rt_formulas/error_handler.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; // For Clipboard import 'package:d4rt_formulas/formula_models.dart'; +import 'package:get_it/get_it.dart'; import '../corpus.dart'; import '../set_utils.dart'; import 'formula_screen.dart'; @@ -22,6 +24,53 @@ class FormulaList extends StatefulWidget { @override State createState() => _FormulaListState(); + + static String _formulaAndDependenciesToExportStringLiteral(Formula formula) { + final corpus = GetIt.instance.get(); + final dependencies = corpus.withDependencies(formula); + final dependenciesAsMap = dependencies.map((f) => f.toMap()).toList(); + for( final f in dependenciesAsMap ){ + f.remove("uuid"); + } + return SetUtils.prettyPrint(dependenciesAsMap); + } + + + static void shareFormula(Formula formula) async { + try { + final exportString = _formulaAndDependenciesToExportStringLiteral(formula); + + // Share the string + await share_plus.SharePlus.instance.share( + share_plus.ShareParams( + text: exportString, + subject: 'Sharing formula: ${formula.name}', + ), + ); + } catch (e, st) { + errorHandler.notify(e, st); + } + } + + static void copyFormula(BuildContext context, Formula formula) async { + try { + final exportString = _formulaAndDependenciesToExportStringLiteral(formula); + + // Copy to clipboard + await Clipboard.setData(ClipboardData(text: exportString)); + + // Show a snackbar to confirm + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Formula and dependencies copied to clipboard!'), + duration: Duration(seconds: 2), + ), + ); + } catch (e, st) { + errorHandler.notify(e, st); + } + } + } class _FormulaListState extends State { @@ -56,49 +105,6 @@ class _FormulaListState extends State { }).toList(); } - String _formulaAndDependenciesToExportStringLiteral(Formula formula) { - final dependencies = widget.corpus.withDependencies(formula); - final dependenciesAsMap = dependencies.map((f) => f.toMap()).toList(); - for( final f in dependenciesAsMap ){ - f.remove("uuid"); - } - return SetUtils.prettyPrint(dependenciesAsMap); - } - - void _shareFormula(Formula formula) async { - try { - final exportString = _formulaAndDependenciesToExportStringLiteral(formula); - - // Share the string - await share_plus.SharePlus.instance.share( - share_plus.ShareParams( - text: exportString, - subject: 'Sharing formula: ${formula.name}', - ), - ); - } catch (e) { - _showErrorDialog('Error sharing formula: $e'); - } - } - - void _copyFormula(Formula formula) async { - try { - final exportString = _formulaAndDependenciesToExportStringLiteral(formula); - - // Copy to clipboard - await Clipboard.setData(ClipboardData(text: exportString)); - - // Show a snackbar to confirm - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Formula and dependencies copied to clipboard!'), - duration: Duration(seconds: 2), - ), - ); - } catch (e) { - _showErrorDialog('Error copying formula: $e'); - } - } void _showErrorDialog(String message) { showDialog( @@ -155,9 +161,9 @@ class _FormulaListState extends State { tooltip: 'Share or copy to clipboard', onSelected: (value) { if (value == 'share') { - _shareFormula(formula); + FormulaList.shareFormula(formula); } else if (value == 'copy') { - _copyFormula(formula); + FormulaList.copyFormula(context, formula); } }, itemBuilder: (context) => [ diff --git a/lib/ai/formula_screen.dart b/lib/ai/formula_screen.dart index 973b0a9..442a163 100644 --- a/lib/ai/formula_screen.dart +++ b/lib/ai/formula_screen.dart @@ -9,6 +9,7 @@ import '../corpus.dart'; import '../error_handler.dart'; import '../value_formatter.dart'; import 'd4rt_editing_controller.dart'; +import 'formula_list.dart'; import 'unit_dropdown.dart'; import 'formula_editor.dart'; @@ -157,6 +158,42 @@ class _FormulaScreenState extends State { appBar: AppBar( title: Text(formula.name), actions: [ + PopupMenuButton( + icon: const Icon(Icons.share), + tooltip: 'Share or copy to clipboard', + onSelected: (value) { + if (value == 'share') { + FormulaList.shareFormula(formula.originalFormula); + } else if (value == 'copy') { + FormulaList.copyFormula(context, formula.originalFormula); + } + }, + itemBuilder: (context) => [ + PopupMenuItem( + value: 'share', + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.share, size: 20), + const SizedBox(width: 8), + Flexible(child: Text('Share', softWrap: false)), + ], + ), + ), + PopupMenuItem( + value: 'copy', + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.copy, size: 20), + const SizedBox(width: 8), + Flexible(child: Text('Copy to clipboard', softWrap: false)), + ], + ), + ), + ], + ), + IconButton( icon: const Icon(Icons.edit), onPressed: formula is DerivedFormula diff --git a/lib/formula_evaluator.dart b/lib/formula_evaluator.dart index 047c01d..09385c1 100644 --- a/lib/formula_evaluator.dart +++ b/lib/formula_evaluator.dart @@ -423,7 +423,7 @@ Number functionSolver( final Number dy = numericalDerivative(x); if (dy == 0 || dy.abs() < 1e-12) { - throw NoSolutionException("Derivative is zero or too small, cannot continue Newton-Raphson."); + throw NoSolutionException("Derivative is zero or too small, cannot continue Newton-Raphson: $dy"); } final Number delta = y / dy; @@ -436,7 +436,7 @@ Number functionSolver( // If step exploded, cap the step to a reasonable multiple of `step` final Number maxStepAllowed = step * 1e6; if ((xNew - x).abs() > maxStepAllowed) { - xNew = x + (delta.isNegative ? -maxStepAllowed : maxStepAllowed); + xNew = x - (delta.isNegative ? -maxStepAllowed : maxStepAllowed); } x = xNew;