131 lines
4.2 KiB
Dart
131 lines
4.2 KiB
Dart
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
|
|
import 'package:math_expressions/math_expressions.dart';
|
|||
|
|
import '../../core/utils/shared_provider.dart';
|
|||
|
|
|
|||
|
|
// 1. DEFINIZIONE DELL'OGGETTO CRONOLOGIA CON NOTE
|
|||
|
|
class HistoryItem {
|
|||
|
|
final String equation;
|
|||
|
|
final String result;
|
|||
|
|
String note; // Campo editabile per il PDF
|
|||
|
|
|
|||
|
|
HistoryItem({
|
|||
|
|
required this.equation,
|
|||
|
|
required this.result,
|
|||
|
|
this.note = "",
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. PROVIDER PER LA CRONOLOGIA (Gestisce la lista degli HistoryItem)
|
|||
|
|
class HistoryNotifier extends StateNotifier<List<HistoryItem>> {
|
|||
|
|
HistoryNotifier() : super([]);
|
|||
|
|
|
|||
|
|
void addItem(HistoryItem item) {
|
|||
|
|
state = [...state, item];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void updateNote(int index, String newNote) {
|
|||
|
|
state[index].note = newNote;
|
|||
|
|
state = [...state]; // Forza l'aggiornamento della UI
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void clear() {
|
|||
|
|
state = [];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
final historyProvider = StateNotifierProvider<HistoryNotifier, List<HistoryItem>>((ref) {
|
|||
|
|
return HistoryNotifier();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 3. STATO DELLA CALCOLATRICE
|
|||
|
|
class CalculatorState {
|
|||
|
|
final String equation;
|
|||
|
|
final String result;
|
|||
|
|
CalculatorState({this.equation = "0", this.result = "0"});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 4. LOGICA DELLA CALCOLATRICE
|
|||
|
|
class CalculatorNotifier extends StateNotifier<CalculatorState> {
|
|||
|
|
final Ref ref;
|
|||
|
|
CalculatorNotifier(this.ref) : super(CalculatorState());
|
|||
|
|
|
|||
|
|
void onBtnPressed(String label) {
|
|||
|
|
if (label == "C") {
|
|||
|
|
state = CalculatorState();
|
|||
|
|
ref.read(sharedValueProvider.notifier).state = 0.0;
|
|||
|
|
}
|
|||
|
|
// NUOVO: Logica per cancellare l'ultima cifra inserita
|
|||
|
|
else if (label == "⌫") {
|
|||
|
|
if (state.equation != "0" && state.equation.isNotEmpty) {
|
|||
|
|
String newEq = state.equation.substring(0, state.equation.length - 1);
|
|||
|
|
if (newEq.isEmpty) newEq = "0";
|
|||
|
|
state = CalculatorState(equation: newEq, result: state.result);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (label == "=") {
|
|||
|
|
_calculate();
|
|||
|
|
} else if (label == "±") {
|
|||
|
|
_toggleSign();
|
|||
|
|
} else {
|
|||
|
|
String newEq = (state.equation == "0") ? label : state.equation + label;
|
|||
|
|
state = CalculatorState(equation: newEq, result: state.result);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void _toggleSign() {
|
|||
|
|
if (state.equation != "0") {
|
|||
|
|
if (state.equation.startsWith("-")) {
|
|||
|
|
state = CalculatorState(equation: state.equation.substring(1), result: state.result);
|
|||
|
|
} else {
|
|||
|
|
state = CalculatorState(equation: "-${state.equation}", result: state.result);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void _calculate() {
|
|||
|
|
try {
|
|||
|
|
// Pulizia stringa per il motore di calcolo
|
|||
|
|
String finalEq = state.equation.replaceAll('×', '*').replaceAll('÷', '/').replaceAll(',', '.');
|
|||
|
|
|
|||
|
|
// 1. Calcolo del totale reale
|
|||
|
|
Parser p = Parser();
|
|||
|
|
double eval = p.parse(finalEq).evaluate(EvaluationType.REAL, ContextModel());
|
|||
|
|
|
|||
|
|
String res = eval.toString();
|
|||
|
|
if (res.endsWith(".0")) res = res.substring(0, res.length - 2);
|
|||
|
|
|
|||
|
|
// 2. LOGICA DI SCOMPOSIZIONE (Splitting degli addendi)
|
|||
|
|
// Dividiamo l'equazione originale usando il simbolo '+'
|
|||
|
|
List<String> components = state.equation.split('+');
|
|||
|
|
|
|||
|
|
if (components.length > 1) {
|
|||
|
|
// Se ci sono più addendi (es: 12+25+36), li aggiungiamo uno per uno
|
|||
|
|
for (var comp in components) {
|
|||
|
|
String trimmedComp = comp.trim();
|
|||
|
|
if (trimmedComp.isNotEmpty) {
|
|||
|
|
// Puliamo il singolo addendo per salvarlo come risultato individuale
|
|||
|
|
String cleanComp = trimmedComp.replaceAll(',', '.');
|
|||
|
|
ref.read(historyProvider.notifier).addItem(
|
|||
|
|
HistoryItem(equation: trimmedComp, result: cleanComp)
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// Se non è una somma (es: operazione singola, sottrazione o moltiplicazione)
|
|||
|
|
// salviamo il risultato finale come voce unica
|
|||
|
|
ref.read(historyProvider.notifier).addItem(
|
|||
|
|
HistoryItem(equation: state.equation, result: res)
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. Aggiornamento degli stati globali
|
|||
|
|
ref.read(sharedValueProvider.notifier).state = eval;
|
|||
|
|
state = CalculatorState(equation: res, result: res);
|
|||
|
|
|
|||
|
|
} catch (e) {
|
|||
|
|
state = CalculatorState(equation: state.equation, result: "Errore");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
final calculatorProvider = StateNotifierProvider<CalculatorNotifier, CalculatorState>((ref) => CalculatorNotifier(ref));
|