calcolatrice/lib/features/calculator/calculator_provider.dart

131 lines
No EOL
4.2 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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));