calcolatrice/lib/features/calculator/calculator_provider.dart

131 lines
4.2 KiB
Dart
Raw Permalink Normal View History

2026-03-04 14:33:15 +01:00
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));