From 0f695010b31a6a4c9c82e1c3918aa0f926109014 Mon Sep 17 00:00:00 2001 From: toly <1981462002@qq.com> Date: Sat, 25 Feb 2023 09:32:02 +0800 Subject: [PATCH] =?UTF-8?q?iconfont=20=E7=B1=BB=E4=BB=A3=E7=A0=81=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/iconfont/icon_builder.dart | 49 --- assets/iconfont/iconfont.ttf | Bin 10588 -> 10852 bytes .../desk_ui/unit_desk_navigation.dart | 2 +- lib/code_gen/code_gen_page.dart | 44 ++- lib/code_gen/desk_widget_top_bar.dart | 9 +- .../icon_font_gen/gen_message_action.dart | 36 ++ .../icon_font_gen/icon_font_class_parser.dart | 148 ++++++++ .../icon_font_gen/icon_font_gen_config.dart | 47 +++ .../icon_font_gen/icon_font_gen_page.dart | 320 ++++++++++++++++++ linux/flutter/generated_plugin_registrant.cc | 4 - linux/flutter/generated_plugins.cmake | 1 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 - packages/app_config/lib/app/cons/sp.dart | 3 + .../app_config/lib/app/res/toly_icon.dart | 9 +- pubspec.lock | 86 ++--- pubspec.yaml | 26 +- test/iconfont_parser_test.dart | 15 + test/yaml_parser_test.dart | 52 +++ test/yaml_parser_test2.dart | 65 ++++ .../flutter/generated_plugin_registrant.cc | 3 - windows/flutter/generated_plugins.cmake | 1 - 21 files changed, 777 insertions(+), 145 deletions(-) delete mode 100644 assets/iconfont/icon_builder.dart create mode 100644 lib/code_gen/icon_font_gen/gen_message_action.dart create mode 100644 lib/code_gen/icon_font_gen/icon_font_class_parser.dart create mode 100644 lib/code_gen/icon_font_gen/icon_font_gen_config.dart create mode 100644 lib/code_gen/icon_font_gen/icon_font_gen_page.dart create mode 100644 test/iconfont_parser_test.dart create mode 100644 test/yaml_parser_test.dart create mode 100644 test/yaml_parser_test2.dart diff --git a/assets/iconfont/icon_builder.dart b/assets/iconfont/icon_builder.dart deleted file mode 100644 index 7876e19f..00000000 --- a/assets/iconfont/icon_builder.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:io'; - -import 'package:path/path.dart' as path; - -main() async{ - String fontName ='TolyIcon'; - String fileName ='toly_icon'; - String resDir="assets/iconfont";//资源文件夹 - String outFile='lib/app/res/$fileName.dart';//输出文件地址 - - String result = """import 'package:flutter/widgets.dart'; -//Power By 张风捷特烈--- Generated file. Do not edit. - -class $fontName { - - $fontName._(); -"""; - File fileCss = File(path.join(Directory.current.path,"$resDir/iconfont.css")); - if (! await fileCss.exists()) return; - - String read = await fileCss.readAsString(); - List split = read.split(".icon-"); - for (String str in split) { - if (str.contains("before")) { - List split = str.split(":"); - result += "static const IconData " + - split[0].replaceAll("-", "_") + - " = IconData(" + - split[2].replaceAll("\"\\", "0x").split("\"")[0] + - ", fontFamily: \"$fontName\");\n"; - } - } - result+="}"; - fileCss.delete();//删除css文件 - - File fileOut = File(path.join(Directory.current.path,outFile)); - if(! await fileOut.exists()){ - await fileOut.create(recursive: true); - } - fileOut.writeAsString(result);//将代码写入dart文件 - - String config=""" - fonts: - - family: $fontName - fonts: - - asset: $resDir/iconfont.ttf"""; - - print("build OK:\n $config"); -} \ No newline at end of file diff --git a/assets/iconfont/iconfont.ttf b/assets/iconfont/iconfont.ttf index 41904bd0335e4d5db090bf76d9cbd331c0c460ce..5860038f01048fb59f48a1b6a7cfbca2c9928ff6 100644 GIT binary patch delta 1174 zcmaKqTWDNW6o&tG&Ya7fxz8k-nOr7wDKn)pBTg_QILuMnO$Gqn{Qv%-utYz{&jvl zb@S2fQo9Psn*h!(x0)M^lh<|tV*@a6Tv&Tm`NUtZw*6WlMfnp+z(g)exX;XZ${**YKJ z8E$+6l<%k03mfZ~Ht#h4=>dn|>Z~^51-L z``|@u(0qw|7lvFKw8pa1j1$-DOlz&DTGgMT==%G?=f8fCY=esZ^sH}#`L6tO26KY!H%c~yJFm9NmvKR3F`+G^_)DeL};EVE+-I?GG#t_D^a2GWFY*jLKR0)W{f1Cd@7KcHlK@ z#kyfXZ2#cwxmVoJgY&^PujoDHeHoe$7sFS>e?`tkZbs*#d$AL-?|lacZS#5lzDIBp zum%T)#$~E5b5g0wgcR>Jsxp&m&rFvm#IYUW`2$i*=VZ_jpj3usl!3+)&gAgnIL-P&7tE zZ%M?A%;fpC^vHb~`6}bZhD*upo#FIsr8gQ+?7nQz7o^bnwsJHgMFgK*Ucb1w(!8{} J>l}Ve{sl0y;C282 delta 910 zcmaKqPe@cz6vn^%-kb4_^SAtyT8%Fzsh|i%3S=m8rP0D9cV&%cPB4>J5*FboNEt*K zuT>BPNr4Ls+_;bg2?f_KT10<9&d4Aw#MaYyy|(RMe(&9LIrp9OefMo#{?(3)z9p4X@nunYlm7nJhP4aY|e-lB3!D z$mqnIGGn#Hcsw`MpBejdzmMnJ7`Nv$qr<8hJg@2)d$%+BfyBFp^e3Px&7y3)zc)6H5??Ew_EUmo0crBj(gRsL5;CpWB*S~jpyF3=Cu_qY2u=Fm6KIi#K zbw@@0Y4zA|ux_2|+TDe^0DE_JlJ82E?t-I|%x{4Q2i2m)k)S_komH;CVO=fgueI#W zRq;rVqkoih$G`C^dimY4fw!3TYPG~l?UD;8&7M_hX iN5&&t(Oh&TmW{2)uVB7V(SAgE{_^oQh57i29`zSeI=f2% diff --git a/lib/app/navigation/desk_ui/unit_desk_navigation.dart b/lib/app/navigation/desk_ui/unit_desk_navigation.dart index af6eaef5..0b9b82c3 100644 --- a/lib/app/navigation/desk_ui/unit_desk_navigation.dart +++ b/lib/app/navigation/desk_ui/unit_desk_navigation.dart @@ -65,7 +65,7 @@ class _UnitDeskNavigationState extends State { onItemClick: _onItemClick, itemData: { //底栏图标 "组件集录": TolyIcon.icon_layout, "收藏集录": TolyIcon.icon_star, - "绘制集录": Icons.palette, "代码生成": Icons.widgets, + "绘制集录": Icons.palette, "代码生成": TolyIcon.icon_fast, "要点集录": TolyIcon.icon_bug, }, ), diff --git a/lib/code_gen/code_gen_page.dart b/lib/code_gen/code_gen_page.dart index da305ab2..5df5945c 100644 --- a/lib/code_gen/code_gen_page.dart +++ b/lib/code_gen/code_gen_page.dart @@ -1,7 +1,6 @@ import 'dart:io'; - -import 'package:file_selector/file_selector.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_unit/code_gen/icon_font_gen/icon_font_gen_page.dart'; import 'class_generator.dart'; import 'desk_widget_top_bar.dart'; @@ -22,6 +21,7 @@ class CodeGenPage extends StatefulWidget { class _CodeGenPageState extends State { TextEditingController _dirPath = TextEditingController(); + final PageController _ctrl = PageController(); int selectIndex = 0; final List selectData = [ @@ -50,12 +50,30 @@ class _CodeGenPageState extends State { children: [ DeskCodeGenTopBar( onTapGen: _doGen, - onTabPressed: (int value) {}, + onTabPressed: (int value) { + _ctrl.jumpToPage(value); + }, ), - Expanded(child: Center( - child: Text( - '敬请期待' - ), + Expanded(child: PageView( + controller:_ctrl, + children: [ + IconFontGenPage(), + Center( + child: Text( + '敬请期待' + ), + ), + Center( + child: Text( + '敬请期待' + ), + ), + Center( + child: Text( + '敬请期待' + ), + ) + ], )), if(false) Padding( @@ -64,11 +82,11 @@ class _CodeGenPageState extends State { children: [ GestureDetector( onTap: () async{ - final String? directoryPath = await getDirectoryPath(); - if (directoryPath != null) { - print("====$directoryPath========="); - _dirPath.text = directoryPath; - } + // final String? directoryPath = await getDirectoryPath(); + // if (directoryPath != null) { + // print("====$directoryPath========="); + // _dirPath.text = directoryPath; + // } }, child: Icon(Icons.file_copy_outlined)), SizedBox(width: 20,), @@ -124,6 +142,8 @@ class _CodeGenPageState extends State { clazz1.write2File(Directory(_dirPath.text)); } } + + } class GenInput extends StatelessWidget { diff --git a/lib/code_gen/desk_widget_top_bar.dart b/lib/code_gen/desk_widget_top_bar.dart index a9232dac..ae4e3de4 100644 --- a/lib/code_gen/desk_widget_top_bar.dart +++ b/lib/code_gen/desk_widget_top_bar.dart @@ -19,7 +19,7 @@ class DeskCodeGenTopBar extends StatefulWidget { class _DeskCodeGenTopBarState extends State with SingleTickerProviderStateMixin { late TabController tabController; - static const List _tabs = ['数据类', 'IconFont', '状态管理', 'Json 解析',]; + static const List _tabs = ['IconFont', '数据类' , '状态管理', 'Json 解析',]; @override void initState() { @@ -62,12 +62,7 @@ class _DeskCodeGenTopBarState extends State with SingleTicke ), ), Spacer(), - ElevatedButton( - style: ElevatedButton.styleFrom( - elevation: 0, - shape: StadiumBorder() - ), - onPressed: widget.onTapGen, child: Text('生成代码')), + const SizedBox(width: 20,), WindowButtons(), ], diff --git a/lib/code_gen/icon_font_gen/gen_message_action.dart b/lib/code_gen/icon_font_gen/gen_message_action.dart new file mode 100644 index 00000000..8059423e --- /dev/null +++ b/lib/code_gen/icon_font_gen/gen_message_action.dart @@ -0,0 +1,36 @@ + +import 'package:app_config/app_config.dart'; +import 'package:flutter/material.dart'; + + + +class GenMessageAction extends StatelessWidget { + final VoidCallback onGen; + const GenMessageAction({Key? key, required this.onGen}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(child: Text( + '使用方式:\n1. 在 iconfont.cn 挑选图标,加入项目,下载压缩包。\n2. 选择 Flutter 项目地址,配置资源、产物文件位置。\n3. 点击生成代码按钮,即可生成相关代码。', + style: TextStyle( + color: Theme.of(context).primaryColor,fontWeight: FontWeight.bold),)), + ElevatedButton( + style: ElevatedButton.styleFrom( + elevation: 0, + shape: const StadiumBorder() + ), + onPressed:onGen, child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + spacing: 4, + children: [ + Icon(TolyIcon.icon_fast,size: 16,), + const Text('生成代码',style: TextStyle(height: 1,fontSize: 12),), + ], + )), + ], + ); + } +} diff --git a/lib/code_gen/icon_font_gen/icon_font_class_parser.dart b/lib/code_gen/icon_font_gen/icon_font_class_parser.dart new file mode 100644 index 00000000..9faa67ae --- /dev/null +++ b/lib/code_gen/icon_font_gen/icon_font_class_parser.dart @@ -0,0 +1,148 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:archive/archive_io.dart'; + +import 'icon_font_gen_config.dart'; +import 'package:path/path.dart' as path; + +class IconFontClassParser{ + + void gen(IconFontGenConfig config){ + final inputStream = InputFileStream(config.srcZip); + // 将压缩包有用资源解压到目标文件 + final archive = ZipDecoder().decodeBuffer(inputStream); + for (var file in archive.files) { + if (file.isFile) { + if (file.name.endsWith('.ttf')) { + final outputStream = OutputFileStream(config.ttfDistPath); + file.writeContent(outputStream); + outputStream.close(); + } + if (file.name.endsWith('.json')) { + dynamic data = file.content; + String jsonContent = utf8.decode(data); + String resultCode = parser(jsonContent,config.fontFamily); + File distFile = File(config.distFilePath); + if(!distFile.existsSync()){ + distFile.createSync(recursive: true); + } + distFile.writeAsStringSync(resultCode); + setYaml(config); + } + } + } + } + + String parser(String input,String fontFamily){ + dynamic map = json.decode(input); + List glyphs = map['glyphs'] as List; + String code = ''; + for(int i=0;i lines = pubspecFile.readAsLinesSync(); + + RegExp fontsRegex = RegExp(r'^ fonts:',multiLine: true); + bool hasFonts = fontsRegex.hasMatch(lines.join('\n')); + + if(!hasFonts){ + // 当前没有 fonts 节点,需要添加到 flutter 节点下 + int index = lines.indexWhere((e) => e.startsWith('flutter:')); + List fonts = [ + ' fonts:', + ' - family: $familyName', + ' fonts:', + ' - asset: $fontAssetsDist', + ]; + + lines.insertAll(index+1, fonts); + pubspecFile.writeAsStringSync(lines.join('\n')); + return; + } + // 存在 fonts 节点,查询 family ,有没有当前字体图标 + bool hasTargetFamily = false; + RegExp regExp = RegExp(r'^ +- family: +(\w+)'); + + for(int i=0;i e.startsWith(fontsRegex)); + List fonts = [ + ' - family: $familyName', + ' fonts:', + ' - asset: $fontAssetsDist', + ]; + lines.insertAll(index+1, fonts); + pubspecFile.writeAsStringSync(lines.join('\n')); + return; + } + } + + // // 修改 pubspec.yaml + // void setYaml(IconFontGenConfig config){ + // String fontFamily = config.fontFamily; + // String assets = config.assetsDist.replaceAll('\\', '/'); + // + // final String filePath = path.join(config.projectPath,'pubspec.yaml'); + // File pubspecFile = File(filePath); + // final String pubspec = pubspecFile.readAsStringSync(); + // final doc = loadYaml(pubspec); + // final modifiableDoc = getModifiableNode(doc); + // + // YamlList? fontsList = doc['flutter']['fonts'] as YamlList?; + // if(fontsList == null){ + // // 新文件,没有配置 fonts 节点 + // modifiableDoc['flutter']['fonts'] = YamlMap.wrap({ + // 'family': fontFamily, + // 'fonts':YamlList.wrap([YamlMap.wrap({'asset':'$assets/iconfont.ttf'})]) + // }); + // }else{ + // final modifiableList = getModifiableNode(fontsList); + // modifiableList.removeWhere((e) => e['family'] == fontFamily); + // modifiableList.add( + // YamlMap.wrap({ + // 'family': fontFamily, + // 'fonts':YamlList.wrap([YamlMap.wrap({'asset':'$assets/iconfont.ttf'})]) + // }) + // ); + // modifiableDoc['flutter']['fonts'] = modifiableList; + // } + // final targetYaml = toYamlString(modifiableDoc); + // pubspecFile.writeAsStringSync(targetYaml); + // } + +} \ No newline at end of file diff --git a/lib/code_gen/icon_font_gen/icon_font_gen_config.dart b/lib/code_gen/icon_font_gen/icon_font_gen_config.dart new file mode 100644 index 00000000..dc058ed4 --- /dev/null +++ b/lib/code_gen/icon_font_gen/icon_font_gen_config.dart @@ -0,0 +1,47 @@ +import 'package:path/path.dart' as path; + +class IconFontGenConfig { + final String srcZip; + final String projectPath; + final String assetsDist; + final String fileDist; + + IconFontGenConfig({ + this.srcZip = '', + this.projectPath = '', + String? assetsDist, + String? fileDist, + }) : fileDist = fileDist ?? 'lib${spa}app${spa}gen${spa}toly_icon.dart', + assetsDist = assetsDist ?? 'assets${spa}iconfont'; + + static String get spa => path.separator; + + String get distFilePath => path.join(projectPath, fileDist); + + String get distAssetsDir => path.join(projectPath, assetsDist); + + String get ttfDistPath => path.join(distAssetsDir, path.basenameWithoutExtension(fileDist)+".ttf"); + + String get yamlAssetDist => assetsDist.replaceAll('\\', '/')+"/"+path.basename(ttfDistPath); + + String get fontFamily => path + .basenameWithoutExtension(fileDist) + .split('_') + .map((e) => e[0].toUpperCase() + e.substring(1,)) + .join(''); + + factory IconFontGenConfig.fromJson(Map map) { + return IconFontGenConfig( + srcZip: map['srcZip'] ?? '', + projectPath: map['projectPath'] ?? '', + assetsDist: map["assetsDist"] ?? '', + fileDist: map["fileDist"] ?? ''); + } + + Map toJson() => { + 'srcZip': srcZip, + 'projectPath': projectPath, + 'assetsDist': assetsDist, + 'fileDist': fileDist, + }; +} diff --git a/lib/code_gen/icon_font_gen/icon_font_gen_page.dart b/lib/code_gen/icon_font_gen/icon_font_gen_page.dart new file mode 100644 index 00000000..e1d7ea2b --- /dev/null +++ b/lib/code_gen/icon_font_gen/icon_font_gen_page.dart @@ -0,0 +1,320 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:app_config/app_config.dart'; +import 'package:archive/archive_io.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:path/path.dart' as path; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:utils/utils.dart'; +import 'package:yaml_modify/yaml_modify.dart'; +import '../code_gen_page.dart'; +import 'gen_message_action.dart'; +import 'icon_font_class_parser.dart'; +import 'icon_font_gen_config.dart'; + +class IconFontGenPage extends StatefulWidget { + const IconFontGenPage({Key? key}) : super(key: key); + + @override + State createState() => _IconFontGenPageState(); +} + +class _IconFontGenPageState extends State + with AutomaticKeepAliveClientMixin { + + final TextEditingController _projectCtrl = TextEditingController(); + final TextEditingController _iconFontCtrl = TextEditingController(); + final TextEditingController _iconFontAssetsCtrl = TextEditingController(); + final TextEditingController _resultFileCtrl = TextEditingController(); + +// + + String get spa => path.separator; + late SharedPreferences _sp; + SharedPreferences get sp => _sp; + @override + void initState() { + super.initState(); + _initData(); + + // _iconFontAssetsCtrl.text = 'assets${spa}iconfont'; + // _resultFileCtrl.text = 'lib${spa}app${spa}gen${spa}toly_icon.dart'; + // _projectCtrl.text = r'E:\Projects\Flutter\FlutterUnit'; + // _iconFontCtrl.text = r'E:\Download\download.zip'; + } + + IconFontGenConfig config = IconFontGenConfig(); + + _initData() async{ + _sp = await SharedPreferences.getInstance(); + String? configStr = sp.getString(SpKey.iconFontGenConfig); + if(configStr!=null){ + config = IconFontGenConfig.fromJson(json.decode(configStr)); + } + _iconFontAssetsCtrl.text = config.assetsDist; + _resultFileCtrl.text = config.fileDist; + _projectCtrl.text = config.projectPath; + _iconFontCtrl.text = config.srcZip; + } + + + @override + Widget build(BuildContext context) { + return Center( + child: SizedBox( + width: 600, + child: Column( + children: [ + const SizedBox( + height: 8, + ), + FileSelectorInput( + controller: _iconFontCtrl, + label: 'Iconfont 压缩包路径', + // controller: clazz.nameCtrl, + hintText: '请选择或输入 iconfont 下载的压缩包路径', + ), + const SizedBox(height: 10), + + FileSelectorInput( + pickerDir: true, + controller: _projectCtrl, + label: '项目路径', + // controller: clazz.nameCtrl, + hintText: '请选择或输入项目地址', + ), + const SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: LabelInputInput( + controller: _iconFontAssetsCtrl, + label: '资源目录', + hintText: 'iconfont 资源存放位置', + ), + ), + const SizedBox(width: 20), + Expanded( + child: LabelInputInput( + controller: _resultFileCtrl, + label: '产物位置', + hintText: '代码类存放位置', + ), + ), + ], + ), + + Expanded( + child: Align( + alignment: Alignment(1, -0.8), + child: GenMessageAction( + onGen: doGen, + ), + )) + ], + ), + ), + ); + } + + final IconFontClassParser parser = IconFontClassParser(); + + void doGen() { + if (_iconFontCtrl.text.isEmpty) return; + if (_projectCtrl.text.isEmpty) return; + + IconFontGenConfig config = IconFontGenConfig( + assetsDist: _iconFontAssetsCtrl.text, + fileDist: _resultFileCtrl.text, + projectPath: _projectCtrl.text, + srcZip: _iconFontCtrl.text, + ); + + parser.gen(config); + // // 将压缩包有用资源解压到目标文件 + // final archive = ZipDecoder().decodeBuffer(inputStream); + // for (var file in archive.files) { + // if (file.isFile) { + // if (file.name.endsWith('.ttf')) { + // String filePath = path.join(assetsDirPath, path.basename(file.name)); + // final outputStream = OutputFileStream(filePath); + // file.writeContent(outputStream); + // outputStream.close(); + // } + // + // if (file.name.endsWith('.json')) { + // dynamic data = file.content; + // String jsonContent = utf8.decode(data); + // + // Toast.success(context, '生成代码成功!'); + // } + // } + // } + Toast.success(context, '生成代码成功!'); + + sp.setString(SpKey.iconFontGenConfig,json.encode(config)); + } + + + + @override + bool get wantKeepAlive => true; +} + +class LabelInputInput extends StatelessWidget { + final String hintText; + final String label; + final TextEditingController? controller; + + const LabelInputInput({ + Key? key, + required this.hintText, + this.controller, + required this.label, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + // direction: Axis.vertical, + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 6), + child: Text( + label, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + ), + ), + Expanded( + child: SizedBox( + height: 35, + child: TextField( + controller: controller, + style: TextStyle(fontSize: 14), + decoration: InputDecoration( + filled: true, + hoverColor: Colors.transparent, + contentPadding: EdgeInsets.only(top: 0, left: 15), + fillColor: Color(0xffF1F2F3), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Theme.of(context).primaryColor), + borderRadius: BorderRadius.all(Radius.circular(6)), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xffE2E7EE)), + borderRadius: BorderRadius.all(Radius.circular(6)), + ), + hintText: hintText, + hintStyle: TextStyle(fontSize: 12, color: Colors.grey)), + ), + ), + ), + ], + ); + } +} + +class FileSelectorInput extends StatelessWidget { + final String hintText; + final String label; + final bool pickerDir; + final TextEditingController? controller; + + const FileSelectorInput( + {Key? key, + required this.hintText, + this.controller, + required this.label, + this.pickerDir = false}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + // direction: Axis.vertical, + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 6), + child: Text( + label, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + ), + ), + SizedBox( + height: 35, + child: TextField( + controller: controller, + style: TextStyle(fontSize: 14), + decoration: InputDecoration( + suffixIconConstraints: BoxConstraints(maxWidth: 80), + suffixIcon: Row( + children: [ + VerticalDivider( + width: 1, + ), + Expanded( + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: _showSelectFile, + child: Center( + child: Text( + "选择", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Theme.of(context).primaryColor), + )), + ), + )), + ], + ), + filled: true, + hoverColor: Colors.transparent, + contentPadding: EdgeInsets.only(top: 0, left: 15), + fillColor: Color(0xffF1F2F3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).primaryColor), + borderRadius: BorderRadius.all(Radius.circular(6)), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xffE2E7EE)), + borderRadius: BorderRadius.all(Radius.circular(6)), + ), + hintText: hintText, + hintStyle: TextStyle(fontSize: 12, color: Colors.grey)), + ), + ), + ], + ); + } + + void _showSelectFile() async { + print("=======_showSelectFile============="); + String? path; + if (pickerDir) { + path = await FilePicker.platform.getDirectoryPath(); + } else { + FilePickerResult? result = await FilePicker.platform.pickFiles(); + if (result != null) { + path = result.files.single.path; + } else { + // User canceled the picker + } + } + if (path != null) { + controller?.text = path; + } else { + // User canceled the picker + } + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index d76db182..0cacc750 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,15 +6,11 @@ #include "generated_plugin_registrant.h" -#include #include #include #include void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); - file_selector_plugin_register_with_registrar(file_selector_linux_registrar); g_autoptr(FlPluginRegistrar) screen_retriever_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 7432170a..62f151fd 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - file_selector_linux screen_retriever url_launcher_linux window_manager diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 6cc33bfe..7426e610 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,7 +5,6 @@ import FlutterMacOS import Foundation -import file_selector_macos import package_info_plus_macos import path_provider_macos import screen_retriever @@ -16,7 +15,6 @@ import url_launcher_macos import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) diff --git a/packages/app_config/lib/app/cons/sp.dart b/packages/app_config/lib/app/cons/sp.dart index 31cb6a22..2dc863d4 100644 --- a/packages/app_config/lib/app/cons/sp.dart +++ b/packages/app_config/lib/app/cons/sp.dart @@ -6,6 +6,9 @@ class SpKey{ SpKey._(); static const themeColorIndex = 'theme_color_index'; + + static const iconFontGenConfig = 'icon_font_gen_config'; + static const showBackground = 'show_background'; static const showTool = 'show_tool'; static const fontFamily = 'font_family'; diff --git a/packages/app_config/lib/app/res/toly_icon.dart b/packages/app_config/lib/app/res/toly_icon.dart index 9227101c..2edca70a 100644 --- a/packages/app_config/lib/app/res/toly_icon.dart +++ b/packages/app_config/lib/app/res/toly_icon.dart @@ -1,9 +1,9 @@ import 'package:flutter/widgets.dart'; -//Power By 张风捷特烈--- Generated file. Do not edit. - +// Power By 张风捷特烈--- Generated file. Do not edit. +// 欢迎支持: https://github.com/toly1994328/FlutterUnit class TolyIcon { - TolyIcon._(); + static const IconData icon_fast = IconData( 0xe607, fontFamily: "TolyIcon"); static const IconData icon_layout = IconData( 0xe85e, fontFamily: "TolyIcon"); static const IconData upload_success = IconData( 0xe60b, fontFamily: "TolyIcon"); static const IconData download = IconData( 0xea51, fontFamily: "TolyIcon"); @@ -35,4 +35,5 @@ static const IconData icon_search = IconData( 0xe604, fontFamily: "TolyIcon"); static const IconData icon_star_ok = IconData( 0xe6ae, fontFamily: "TolyIcon"); static const IconData icon_star = IconData( 0xe609, fontFamily: "TolyIcon"); static const IconData icon_star_add = IconData( 0xe68e, fontFamily: "TolyIcon"); -} \ No newline at end of file + +} diff --git a/pubspec.lock b/pubspec.lock index bc51f65e..fda2f9b7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -16,13 +16,13 @@ packages: source: path version: "0.0.1" archive: - dependency: transitive + dependency: "direct main" description: name: archive - sha256: ed7cc591a948744994714375caf9a2ce89e1d82e8243997c8a2994d57181c212 + sha256: d6347d54a2d8028e0437e3c099f66fdb8ae02c4720c1e7534c9f24c10351f85d url: "https://pub.flutter-io.cn" source: hosted - version: "3.3.5" + version: "3.3.6" args: dependency: transitive description: @@ -180,62 +180,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.1.4" - file_selector: + file_picker: dependency: "direct main" description: - name: file_selector - sha256: b20af14306e7ce567b7c76076b8c010dcce4bc2f3c4b5137dceb9e4db8ece006 - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.9.2+2" - file_selector_ios: - dependency: transitive - description: - name: file_selector_ios - sha256: "904091b110b64565566fbb98b334590670de5d7ddd7541be15db22d4e64203eb" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.5.0+2" - file_selector_linux: - dependency: transitive - description: - name: file_selector_linux - sha256: "30edefcdb76be8f4a2dadf57554b42a2791c06cdbc2db62894a918ea36c37cff" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.9.1" - file_selector_macos: - dependency: transitive - description: - name: file_selector_macos - sha256: "6fd5242e12b6b0b0d2e59e779a7eafaeaa374687c84e8ad1e948e5dad8941109" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.9.0+4" - file_selector_platform_interface: - dependency: transitive - description: - name: file_selector_platform_interface - sha256: "17cdfe3d13a7d3e29e3d3978577ce840fcf94497d7de51bdea378abf9a34fc2c" - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.4.0" - file_selector_web: - dependency: transitive - description: - name: file_selector_web - sha256: "0175186c42ef8d622c7cf214e46294f8dbe81ae32ae4407896c773c8f7dc930b" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.9.0+2" - file_selector_windows: - dependency: transitive - description: - name: file_selector_windows - sha256: "1cfeddc127f78f3f96803ad7c3d3ce500791cbefb15a7b19b9ee71e7b92ff4b4" + name: file_picker + sha256: d090ae03df98b0247b82e5928f44d1b959867049d18d73635e2e0bc3f49542b9 url: "https://pub.flutter-io.cn" source: hosted - version: "0.9.1+4" + version: "5.2.5" flutter: dependency: "direct main" description: flutter @@ -270,6 +222,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.6.13" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "4bef634684b2c7f3468c77c766c831229af829a0cd2d4ee6c1b99558bd14e5d2" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.8" flutter_spinkit: dependency: "direct main" description: @@ -968,6 +928,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.1.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.1" + yaml_modify: + dependency: "direct main" + description: + name: yaml_modify + sha256: "0c67ba263546f44b738c9ae14bd602bb1ef75c74a61a25b9111708a7a7e9af94" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.1" sdks: dart: ">=2.19.0-0 <=3.0.0" flutter: ">=3.7.0-0" diff --git a/pubspec.yaml b/pubspec.yaml index f0194bd4..ddc348d0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: flutter_bloc: ^8.0.1 # 状态管理 stream_transform: ^2.0.0 equatable: ^2.0.3 # 相等辅助 - + archive: ^3.3.6 # 解压 package_info_plus: ^1.3.0 # 应用包信息 r_upgrade: ^0.3.8+2 # 应用升级 @@ -35,7 +35,7 @@ dependencies: flutter_star: ^1.0.2 # 星星组件 dash_painter: ^1.0.2 wrapper: ^1.0.2 - + yaml_modify: ^1.0.1 url_launcher: ^6.1.9 # url share_plus: ^6.3.1 # 文字分享 flutter_svg: ^2.0.1 @@ -44,7 +44,8 @@ dependencies: image: ^3.1.0 flutter_spinkit: ^5.1.0 # loading flutter_markdown: ^0.6.4 # markdown - file_selector: ^0.9.2+2 +# file_selector: ^0.9.2+2 + file_picker: ^5.2.5 window_manager: ^0.2.8 #桌面尺寸 widget_repository: path: packages/widget_repository @@ -83,6 +84,9 @@ flutter: - assets/version.json fonts: # 配置字体,可配置多个,支持ttf和otf,ttc等字体资源 + - family: TolyIcon + fonts: + - asset: assets/iconfont/iconfont.ttf - family: IndieFlower #字体名 fonts: - asset: assets/fonts/IndieFlower-Regular.ttf @@ -101,6 +105,16 @@ flutter: - family: CHOPS fonts: - asset: assets/fonts/CHOPS.TTF - - family: TolyIcon - fonts: - - asset: assets/iconfont/iconfont.ttf \ No newline at end of file + + + + + + + + + + + + + diff --git a/test/iconfont_parser_test.dart b/test/iconfont_parser_test.dart new file mode 100644 index 00000000..37780b40 --- /dev/null +++ b/test/iconfont_parser_test.dart @@ -0,0 +1,15 @@ + +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter_unit/code_gen/icon_font_gen/icon_font_class_parser.dart'; + +void main(){ + final String filePath = r'E:\Download\out\font_1717416_cwm89ioqkfo\iconfont.json'; + File jsonFile = File(filePath); + final String jsonContent = jsonFile.readAsStringSync(); + IconFontClassParser parser = IconFontClassParser(); + String result = parser.parser(jsonContent,'TolyIcon'); + print(result); + +} \ No newline at end of file diff --git a/test/yaml_parser_test.dart b/test/yaml_parser_test.dart new file mode 100644 index 00000000..727198b3 --- /dev/null +++ b/test/yaml_parser_test.dart @@ -0,0 +1,52 @@ + +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter_unit/code_gen/icon_font_gen/icon_font_class_parser.dart'; +// import 'package:yaml/yaml.dart'; +import 'package:yaml_modify/yaml_modify.dart'; + +void main(){ + final String filePath = r'E:\Projects\Flutter\FlutterUnit\pubspec.yaml'; + File pubspecFile = File(filePath); + final String pubspec = pubspecFile.readAsStringSync(); + print(pubspec); + + // YamlEditor doc = YamlEditor(pubspec); + // print(doc); + final doc = loadYaml(pubspec); + print(doc); + + YamlList fontsList = doc['flutter']['fonts'] as YamlList; + + final modifiableDoc = getModifiableNode(doc); + final modifiableList = getModifiableNode(fontsList); + modifiableList.removeWhere((e) => e['family'] == 'TolyIcon'); + modifiableList.add( + YamlMap.wrap({ + 'family': 'TolyIcon3', + 'fonts':YamlList.wrap([YamlMap.wrap({'asset':'assets/iconfont/iconfont.ttf'})]) + }) + ); + modifiableDoc['flutter']['fonts'] = modifiableList; + final strYaml = toYamlString(modifiableDoc); + print(modifiableList); + + // // YamlMap flutterNode = doc[]; + // doc.update('flutter', (value) { + // // YamlList fontsNode = value as YamlList; + // // List filter = fontsNode.where((e) => e['family']!='TolyIcon').toList(); + // + // return YamlMap.wrap({ + // 'family': 'TolyIcon3', + // 'fonts':YamlList.wrap([YamlMap.wrap({'asset':'assets/iconfont/iconfont.ttf'})]) + // }); + // }); + + // YamlList fontsList = doc['flutter']['fonts'] as YamlList; + // + + // // doc. + print(doc); + +} \ No newline at end of file diff --git a/test/yaml_parser_test2.dart b/test/yaml_parser_test2.dart new file mode 100644 index 00000000..da19f887 --- /dev/null +++ b/test/yaml_parser_test2.dart @@ -0,0 +1,65 @@ + +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter_unit/code_gen/icon_font_gen/icon_font_class_parser.dart'; +// import 'package:yaml/yaml.dart'; +import 'package:yaml_modify/yaml_modify.dart'; + +void main(){ + String familyName = 'TolyIcon'; + String fontAssetsDist = 'assets/iconfont/iconfont.ttf'; + + // final String filePath = r'E:\Projects\Flutter\FlutterUnit\pubspec.yaml'; + final String filePath = r'E:\Projects\Flutter\Work\toly_image_edit\pubspec.yaml'; + File pubspecFile = File(filePath); + + List lines = pubspecFile.readAsLinesSync(); + + RegExp fontsRegex = RegExp(r'^ fonts:',multiLine: true); + bool hasFonts = fontsRegex.hasMatch(lines.join('\n')); + + if(!hasFonts){ + // 当前没有 fonts 节点,需要添加到 flutter 节点下 + int index = lines.indexWhere((e) => e.startsWith('flutter:')); + + List fonts = [ + ' fonts:', + ' - family: TolyIcon', + ' fonts:', + ' - asset: assets/iconfont/iconfont.ttf', + ]; + + lines.insertAll(index+1, fonts); + print(lines); + pubspecFile.writeAsStringSync(lines.join('\n')); + return; + } + // 存在 fonts 节点,查询 family ,有没有当前字体图标 + bool hasTargetFamily = false; + RegExp regExp = RegExp(r'^ +- family: +(\w+)'); + + for(int i=0;i e.startsWith(fontsRegex)); + List fonts = [ + ' - family: TolyIcon', + ' fonts:', + ' - asset: $fontAssetsDist', + ]; + lines.insertAll(index+1, fonts); + print(lines); + pubspecFile.writeAsStringSync(lines.join('\n')); + return; + } + +} \ No newline at end of file diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 40213769..02e0e713 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,15 +6,12 @@ #include "generated_plugin_registrant.h" -#include #include #include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { - FileSelectorWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FileSelectorWindows")); ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); SharePlusWindowsPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 83cbfb4e..ce565c40 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - file_selector_windows screen_retriever share_plus url_launcher_windows