✨ Virtual toolbar
This commit is contained in:
		| @@ -5,11 +5,14 @@ PODS: | |||||||
|   - path_provider_foundation (0.0.1): |   - path_provider_foundation (0.0.1): | ||||||
|     - Flutter |     - Flutter | ||||||
|     - FlutterMacOS |     - FlutterMacOS | ||||||
|  |   - url_launcher_ios (0.0.1): | ||||||
|  |     - Flutter | ||||||
|  |  | ||||||
| DEPENDENCIES: | DEPENDENCIES: | ||||||
|   - Flutter (from `Flutter`) |   - Flutter (from `Flutter`) | ||||||
|   - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) |   - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) | ||||||
|   - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) |   - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) | ||||||
|  |   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) | ||||||
|  |  | ||||||
| EXTERNAL SOURCES: | EXTERNAL SOURCES: | ||||||
|   Flutter: |   Flutter: | ||||||
| @@ -18,11 +21,14 @@ EXTERNAL SOURCES: | |||||||
|     :path: ".symlinks/plugins/flutter_native_splash/ios" |     :path: ".symlinks/plugins/flutter_native_splash/ios" | ||||||
|   path_provider_foundation: |   path_provider_foundation: | ||||||
|     :path: ".symlinks/plugins/path_provider_foundation/darwin" |     :path: ".symlinks/plugins/path_provider_foundation/darwin" | ||||||
|  |   url_launcher_ios: | ||||||
|  |     :path: ".symlinks/plugins/url_launcher_ios/ios" | ||||||
|  |  | ||||||
| SPEC CHECKSUMS: | SPEC CHECKSUMS: | ||||||
|   Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 |   Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 | ||||||
|   flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf |   flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf | ||||||
|   path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 |   path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 | ||||||
|  |   url_launcher_ios: 694010445543906933d732453a59da0a173ae33d | ||||||
|  |  | ||||||
| PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e | PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ class AboutPage extends StatelessWidget { | |||||||
|                 Opacity( |                 Opacity( | ||||||
|                   opacity: 0.8, |                   opacity: 0.8, | ||||||
|                   child: Text( |                   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, |                     style: Theme.of(context).textTheme.bodyMedium, | ||||||
|                     textAlign: TextAlign.center, |                     textAlign: TextAlign.center, | ||||||
|                   ), |                   ), | ||||||
| @@ -78,7 +78,7 @@ class AboutPage extends StatelessWidget { | |||||||
|  |  | ||||||
|   Future<void> _launchUrl(String url) async { |   Future<void> _launchUrl(String url) async { | ||||||
|     final Uri uri = Uri.parse(url); |     final Uri uri = Uri.parse(url); | ||||||
|     if (!await launchUrl(uri)) { |     if (!await launchUrl(uri, mode: LaunchMode.externalApplication)) { | ||||||
|       throw Exception('Could not launch $url'); |       throw Exception('Could not launch $url'); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:google_fonts/google_fonts.dart'; | ||||||
| import 'package:latext/latext.dart'; | import 'package:latext/latext.dart'; | ||||||
| import 'package:simple_math_calc/models/calculation_step.dart'; | import 'package:simple_math_calc/models/calculation_step.dart'; | ||||||
| import 'package:simple_math_calc/solver.dart'; | import 'package:simple_math_calc/solver.dart'; | ||||||
| @@ -14,9 +15,28 @@ class CalculatorHomePage extends StatefulWidget { | |||||||
| class _CalculatorHomePageState extends State<CalculatorHomePage> { | class _CalculatorHomePageState extends State<CalculatorHomePage> { | ||||||
|   final TextEditingController _controller = TextEditingController(); |   final TextEditingController _controller = TextEditingController(); | ||||||
|   final SolverService _solverService = SolverService(); |   final SolverService _solverService = SolverService(); | ||||||
|  |   late final FocusNode _focusNode; | ||||||
|  |  | ||||||
|   CalculationResult? _result; |   CalculationResult? _result; | ||||||
|   bool _isLoading = false; |   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() { |   void _solveEquation() { | ||||||
|     if (_controller.text.isEmpty) { |     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 |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return Scaffold( |     return Scaffold( | ||||||
| @@ -66,6 +96,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | |||||||
|                 Expanded( |                 Expanded( | ||||||
|                   child: TextField( |                   child: TextField( | ||||||
|                     controller: _controller, |                     controller: _controller, | ||||||
|  |                     focusNode: _focusNode, | ||||||
|                     textAlign: TextAlign.center, |                     textAlign: TextAlign.center, | ||||||
|                     decoration: InputDecoration( |                     decoration: InputDecoration( | ||||||
|                       border: const OutlineInputBorder(), |                       border: const OutlineInputBorder(), | ||||||
| @@ -74,8 +105,6 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | |||||||
|                       hintText: '例如: 2x^2 - 8x + 6 = 0', |                       hintText: '例如: 2x^2 - 8x + 6 = 0', | ||||||
|                     ), |                     ), | ||||||
|                     onSubmitted: (_) => _solveEquation(), |                     onSubmitted: (_) => _solveEquation(), | ||||||
|                     onTapOutside: (_) => |  | ||||||
|                         FocusManager.instance.primaryFocus?.unfocus(), |  | ||||||
|                   ), |                   ), | ||||||
|                 ), |                 ), | ||||||
|                 IconButton( |                 IconButton( | ||||||
| @@ -92,6 +121,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | |||||||
|                 ? const Center(child: Text('请输入方程开始计算')) |                 ? const Center(child: Text('请输入方程开始计算')) | ||||||
|                 : buildResultView(_result!), |                 : buildResultView(_result!), | ||||||
|           ), |           ), | ||||||
|  |           if (_isInputFocused) _buildToolbar(), | ||||||
|         ], |         ], | ||||||
|       ), |       ), | ||||||
|     ); |     ); | ||||||
| @@ -118,7 +148,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | |||||||
|                     padding: const EdgeInsets.only( |                     padding: const EdgeInsets.only( | ||||||
|                       left: 12, |                       left: 12, | ||||||
|                       right: 12, |                       right: 12, | ||||||
|                       bottom: 4, |                       bottom: 16, | ||||||
|                       top: 16, |                       top: 16, | ||||||
|                     ), |                     ), | ||||||
|                     child: Column( |                     child: Column( | ||||||
| @@ -169,10 +199,9 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | |||||||
|         Card( |         Card( | ||||||
|           color: Theme.of(context).colorScheme.primaryContainer, |           color: Theme.of(context).colorScheme.primaryContainer, | ||||||
|           child: Padding( |           child: Padding( | ||||||
|             padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), |             padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), | ||||||
|             child: Column( |             child: Column( | ||||||
|               children: [ |               children: [ | ||||||
|                 const SizedBox(height: 16), |  | ||||||
|                 Text( |                 Text( | ||||||
|                   "最终答案", |                   "最终答案", | ||||||
|                   style: Theme.of(context).textTheme.titleLarge?.copyWith( |                   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