✨ Virtual toolbar
This commit is contained in:
		| @@ -43,7 +43,7 @@ class AboutPage extends StatelessWidget { | ||||
|                 Opacity( | ||||
|                   opacity: 0.8, | ||||
|                   child: Text( | ||||
|                     '这是一个用于求解方程和表达式的计算器应用。\n支持多种类型的数学计算,包括代数方程、表达式求值等。\n\n结果仅供参考,纯机器计算,无 AI 成分。\n\n在书写方程的时候,请勿使用中文符号,平方请使用 ^n 来表示 n 次方。\n\n理性使用,仅为辅助学习目的,过量使用有害考试成绩。', | ||||
|                     '这是一个用于求解方程和表达式的计算器应用。\n支持多种类型的数学计算,包括代数方程、表达式求值等。\n\n结果仅供参考,纯机器计算,无 AI 成分。\n\n在书写方程的时候,请勿使用中文符号,平方请使用 ^n 来表示 n 次方。\n\n虽然本项目存在的原因是小羊不想写数学作业,但是我还是要说\n理性使用,仅为辅助学习目的,过量使用有害考试成绩。', | ||||
|                     style: Theme.of(context).textTheme.bodyMedium, | ||||
|                     textAlign: TextAlign.center, | ||||
|                   ), | ||||
| @@ -78,7 +78,7 @@ class AboutPage extends StatelessWidget { | ||||
|  | ||||
|   Future<void> _launchUrl(String url) async { | ||||
|     final Uri uri = Uri.parse(url); | ||||
|     if (!await launchUrl(uri)) { | ||||
|     if (!await launchUrl(uri, mode: LaunchMode.externalApplication)) { | ||||
|       throw Exception('Could not launch $url'); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:google_fonts/google_fonts.dart'; | ||||
| import 'package:latext/latext.dart'; | ||||
| import 'package:simple_math_calc/models/calculation_step.dart'; | ||||
| import 'package:simple_math_calc/solver.dart'; | ||||
| @@ -14,9 +15,28 @@ class CalculatorHomePage extends StatefulWidget { | ||||
| class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|   final TextEditingController _controller = TextEditingController(); | ||||
|   final SolverService _solverService = SolverService(); | ||||
|   late final FocusNode _focusNode; | ||||
|  | ||||
|   CalculationResult? _result; | ||||
|   bool _isLoading = false; | ||||
|   bool _isInputFocused = false; | ||||
|  | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _focusNode = FocusNode(); | ||||
|     _focusNode.addListener(() { | ||||
|       setState(() { | ||||
|         _isInputFocused = _focusNode.hasFocus; | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void dispose() { | ||||
|     _focusNode.dispose(); | ||||
|     super.dispose(); | ||||
|   } | ||||
|  | ||||
|   void _solveEquation() { | ||||
|     if (_controller.text.isEmpty) { | ||||
| @@ -48,6 +68,16 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void _insertSymbol(String symbol) { | ||||
|     final text = _controller.text; | ||||
|     final selection = _controller.selection; | ||||
|     final newText = text.replaceRange(selection.start, selection.end, symbol); | ||||
|     _controller.text = newText; | ||||
|     _controller.selection = TextSelection.collapsed( | ||||
|       offset: selection.start + symbol.length, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
| @@ -66,6 +96,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|                 Expanded( | ||||
|                   child: TextField( | ||||
|                     controller: _controller, | ||||
|                     focusNode: _focusNode, | ||||
|                     textAlign: TextAlign.center, | ||||
|                     decoration: InputDecoration( | ||||
|                       border: const OutlineInputBorder(), | ||||
| @@ -74,8 +105,6 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|                       hintText: '例如: 2x^2 - 8x + 6 = 0', | ||||
|                     ), | ||||
|                     onSubmitted: (_) => _solveEquation(), | ||||
|                     onTapOutside: (_) => | ||||
|                         FocusManager.instance.primaryFocus?.unfocus(), | ||||
|                   ), | ||||
|                 ), | ||||
|                 IconButton( | ||||
| @@ -92,6 +121,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|                 ? const Center(child: Text('请输入方程开始计算')) | ||||
|                 : buildResultView(_result!), | ||||
|           ), | ||||
|           if (_isInputFocused) _buildToolbar(), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
| @@ -118,7 +148,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|                     padding: const EdgeInsets.only( | ||||
|                       left: 12, | ||||
|                       right: 12, | ||||
|                       bottom: 4, | ||||
|                       bottom: 16, | ||||
|                       top: 16, | ||||
|                     ), | ||||
|                     child: Column( | ||||
| @@ -169,10 +199,9 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|         Card( | ||||
|           color: Theme.of(context).colorScheme.primaryContainer, | ||||
|           child: Padding( | ||||
|             padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), | ||||
|             padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), | ||||
|             child: Column( | ||||
|               children: [ | ||||
|                 const SizedBox(height: 16), | ||||
|                 Text( | ||||
|                   "最终答案", | ||||
|                   style: Theme.of(context).textTheme.titleLarge?.copyWith( | ||||
| @@ -194,4 +223,37 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Widget _buildToolbar() { | ||||
|     return Material( | ||||
|       elevation: 8, | ||||
|       child: Padding( | ||||
|         padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12), | ||||
|         child: Row( | ||||
|           mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||||
|           spacing: 16, | ||||
|           children: [ | ||||
|             Expanded( | ||||
|               child: ElevatedButton( | ||||
|                 onPressed: () => _insertSymbol('('), | ||||
|                 child: Text('(', style: GoogleFonts.robotoMono()), | ||||
|               ), | ||||
|             ), | ||||
|             Expanded( | ||||
|               child: ElevatedButton( | ||||
|                 onPressed: () => _insertSymbol(')'), | ||||
|                 child: Text(')', style: GoogleFonts.robotoMono()), | ||||
|               ), | ||||
|             ), | ||||
|             Expanded( | ||||
|               child: ElevatedButton( | ||||
|                 onPressed: () => _insertSymbol('^'), | ||||
|                 child: Text('^', style: GoogleFonts.robotoMono()), | ||||
|               ), | ||||
|             ), | ||||
|           ], | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user