CCCPaste

Assignment Code

import 'package:flutter/material.dart';
import 'package:math_expressions/math_expressions.dart';
import 'package:shared_preferences/shared_preferences.dart';

class CalculatorScreen2 extends StatefulWidget {
  const CalculatorScreen2({super.key});

  @override
  _CalculatorScreen2State createState() => _CalculatorScreen2State();
}

class _CalculatorScreen2State extends State {
  String _expression = '';
  String _result = '';
  String themeMode = 'dark';

  final List _buttons = [
    'C', '⌫', '%', '÷',
    '7', '8', '9', '×',
    '4', '5', '6', '-',
    '1', '2', '3', '+',
    '0', '.', '=',
  ];

  bool _isOperator(String s) {
    return ['+', '-', '×', '÷', '%', '*', '/'].contains(s);
  }

  void _buttonPressed(String text) {
    setState(() {
      if (text == 'C') {
        _expression = '';
        _result = '';
      } else if (text == '⌫') {
        if (_expression.isNotEmpty) {
          _expression = _expression.substring(0, _expression.length - 1);
        }
      } else if (text == '=') {
        _calculateResult();
      } else if (text == '.') {
        
        int lastOp = _expression.lastIndexOf(RegExp(r'[\+\-\×\÷\*\/%]'));
        String lastNumber = lastOp == -1 ? _expression : _expression.substring(lastOp + 1);
        if (!lastNumber.contains('.')) {
          _expression += text;
        }
      } else {
        
        if (_expression.isNotEmpty &&
            _isOperator(text) &&
            _isOperator(_expression[_expression.length - 1])) {
          _expression = _expression.substring(0, _expression.length - 1) + text;
        } else {
          _expression += text;
        }
      }
    });
  }

  void _calculateResult() {
    try {
      if (_expression.isEmpty) return;

      // Remove trailing operator if any
      while (_expression.isNotEmpty && _isOperator(_expression[_expression.length - 1])) {
        _expression = _expression.substring(0, _expression.length - 1);
      }
      if (_expression.isEmpty) return;

      String finalExpression = _expression
          .replaceAll('×', '*')
          .replaceAll('÷', '/')
          .replaceAll('%', '/100');

      Parser p = Parser();
      Expression exp = p.parse(finalExpression);
      ContextModel cm = ContextModel();
      double eval = exp.evaluate(EvaluationType.REAL, cm);

      String res = eval.toString();
      if (res.endsWith('.0')) res = res.substring(0, res.length - 2);
      _result = res;
    } catch (e) {
      _result = 'Error';
    }
  }

  
  Future loadTheme() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      themeMode = prefs.getString('theme') ?? 'dark';
    });
  }

  
  Future saveTheme(String mode) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('theme', mode);
  }

  @override
  void initState() {
    super.initState();
    loadTheme(); 
  }

  Color _getButtonColor(String text) {
    if (text == 'C') return Colors.redAccent;
    if (text == '=' || text == '+' || text == '-' || text == '×' || text == '÷') {
      return Colors.blueAccent;
    }
    return themeMode == 'dark' ? Colors.grey[850]! : Colors.grey[300]!;
  }

  Color _getTextColor(String text) {
    if (text == 'C' || text == '=' || text == '+' || text == '-' || text == '×' || text == '÷') {
      return Colors.white;
    }
    return themeMode == 'dark' ? Colors.white70 : Colors.black87;
  }

  @override
  Widget build(BuildContext context) {
    final bool isDark = themeMode == 'dark';

    return Scaffold(
      appBar: AppBar(
        title: const Text('Calculator App'),
        centerTitle: true,
        actions: [
          IconButton(
            onPressed: () {
              setState(() {
                themeMode = isDark ? 'light' : 'dark';
              });
              saveTheme(themeMode);
            },
            icon: Icon(isDark ? Icons.sunny : Icons.dark_mode),
          ),
        ],
      ),
      backgroundColor: isDark ? Colors.black : Colors.white,
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Container(
              padding: const EdgeInsets.all(20),
              alignment: Alignment.centerRight,
              child: Text(
                _expression,
                style: TextStyle(
                  fontSize: 30,
                  color: isDark ? Colors.white : Colors.black,
                ),
              ),
            ),
            Container(
              padding: const EdgeInsets.all(20),
              alignment: Alignment.centerRight,
              child: Text(
                _result,
                style: TextStyle(
                  fontSize: 40,
                  color: isDark ? Colors.white : Colors.black,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            Divider(color: isDark ? Colors.white24 : Colors.black12),
            Expanded(
              flex: 2,
              child: Container(
                padding: const EdgeInsets.all(10),
                child: GridView.builder(
                  itemCount: _buttons.length,
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4,
                    mainAxisSpacing: 10,
                    crossAxisSpacing: 10,
                  ),
                  itemBuilder: (context, index) {
                    final buttonText = _buttons[index];
                    return ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        shape: const CircleBorder(),
                        padding: const EdgeInsets.all(20),
                        backgroundColor: _getButtonColor(buttonText),
                      ),
                      onPressed: () => _buttonPressed(buttonText),
                      child: Text(
                        buttonText,
                        style: TextStyle(
                          fontSize: 24,
                          color: _getTextColor(buttonText),
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}