import 'package:flutter/material.dart'; import 'plugins.dart'; /// 工具网格:可搜索的插件入口。 /// /// 工具页面的实现全部在 lib/tools/ 下,是从 mathtool2 直接搬过来的 /// (依赖 rational / math_expressions / fl_chart,全是纯 Dart)。 class ToolsPage extends StatefulWidget { const ToolsPage({super.key}); @override State createState() => _ToolsPageState(); } class _ToolsPageState extends State { final _search = TextEditingController(); String _q = ''; static const _palette = [ Color(0xFF5C6BC0), Color(0xFF26A69A), Color(0xFFEF5350), Color(0xFFAB47BC), Color(0xFF42A5F5), Color(0xFFFFA726), Color(0xFF66BB6A), Color(0xFF8D6E63), ]; @override void dispose() { _search.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final items = kTools.where((t) => t.matches(_q)).toList(); return Column( children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 12, 16, 8), child: TextField( controller: _search, decoration: InputDecoration( isDense: true, hintText: '搜索工具(支持拼音首字母)', prefixIcon: const Icon(Icons.search), suffixIcon: _q.isEmpty ? null : IconButton( icon: const Icon(Icons.clear), onPressed: () { _search.clear(); setState(() => _q = ''); }, ), border: const OutlineInputBorder(), ), onChanged: (v) => setState(() => _q = v), ), ), Expanded( child: items.isEmpty ? const Center(child: Text('没有匹配的工具')) : GridView.builder( padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 12, crossAxisSpacing: 12, childAspectRatio: 1.5, ), itemCount: items.length, itemBuilder: (_, i) { final t = items[i]; final color = _palette[kTools.indexOf(t) % _palette.length]; return _ToolCard( plugin: t, color: color, onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (_) => t.build(), settings: RouteSettings(name: t.name), ), ), ); }, ), ), ], ); } } class _ToolCard extends StatelessWidget { const _ToolCard({ required this.plugin, required this.color, required this.onTap, }); final ToolPlugin plugin; final Color color; final VoidCallback onTap; @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(16), child: Ink( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [color, Color.lerp(color, Colors.black, 0.22)!], ), ), padding: const EdgeInsets.all(14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Icon(plugin.icon, color: Colors.white, size: 26), Text( plugin.name, style: const TextStyle( color: Colors.white, fontSize: 15, fontWeight: FontWeight.w600, ), ), ], ), ), ), ); } }