Virtual toolbar

This commit is contained in:
2025-09-13 02:36:31 +08:00
parent 3b315d26fa
commit 43f669745e
3 changed files with 75 additions and 7 deletions

View File

@@ -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');
}
}

View File

@@ -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()),
),
),
],
),
),
);
}
}