✨ Virtual toolbar
This commit is contained in:
		| @@ -5,11 +5,14 @@ PODS: | ||||
|   - path_provider_foundation (0.0.1): | ||||
|     - Flutter | ||||
|     - FlutterMacOS | ||||
|   - url_launcher_ios (0.0.1): | ||||
|     - Flutter | ||||
|  | ||||
| DEPENDENCIES: | ||||
|   - Flutter (from `Flutter`) | ||||
|   - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) | ||||
|   - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) | ||||
|   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) | ||||
|  | ||||
| EXTERNAL SOURCES: | ||||
|   Flutter: | ||||
| @@ -18,11 +21,14 @@ EXTERNAL SOURCES: | ||||
|     :path: ".symlinks/plugins/flutter_native_splash/ios" | ||||
|   path_provider_foundation: | ||||
|     :path: ".symlinks/plugins/path_provider_foundation/darwin" | ||||
|   url_launcher_ios: | ||||
|     :path: ".symlinks/plugins/url_launcher_ios/ios" | ||||
|  | ||||
| SPEC CHECKSUMS: | ||||
|   Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 | ||||
|   flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf | ||||
|   path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 | ||||
|   url_launcher_ios: 694010445543906933d732453a59da0a173ae33d | ||||
|  | ||||
| PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e | ||||
|  | ||||
|   | ||||
| @@ -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