From 96b3a7384d01bec558d366ecd8c5f994a6d58c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=82=E6=B2=AB?= <1992724048@qq.com> Date: Thu, 17 Sep 2026 19:08:33 +0800 Subject: [PATCH 1/8] =?UTF-8?q?refactor(ui):=20=E4=BC=98=E5=8C=96=E4=BA=86?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E9=A1=B5=E9=9D=A2=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/app_info.dart | 6 +- lib/controls/build_options.dart | 393 +++++++------------ lib/controls/pack_manage.dart | 5 +- lib/main.dart | 272 +++---------- lib/models/pack_model.dart | 99 ++--- lib/pages/about.dart | 91 +++-- lib/pages/pack_compile_settings.dart | 205 +++------- lib/pages/pack_dependencies.dart | 239 +++++------ lib/pages/pack_files.dart | 278 ++++--------- lib/pages/pack_packaging.dart | 61 +-- lib/pages/setting.dart | 213 +++------- lib/widgets/floating_toast.dart | 2 +- lib/widgets/library_card.dart | 59 +-- lib/widgets/settings/settings_card.dart | 89 +---- lib/widgets/settings/settings_group.dart | 2 +- lib/widgets/settings/settings_page.dart | 17 +- test/build/library_recipes/openvino/build.py | 2 +- 17 files changed, 651 insertions(+), 1382 deletions(-) diff --git a/lib/app_info.dart b/lib/app_info.dart index 51f94b3..3900d7b 100644 --- a/lib/app_info.dart +++ b/lib/app_info.dart @@ -1,8 +1,8 @@ -const String appName = 'C++ NuGet 打包工具'; +const String appName = 'CPPP'; /// 与 pubspec.yaml 的 version 同步(去掉 +build 与末尾 .0,如 26.1.0+1 → 26.1);不一致时 test/app_info_test.dart 会失败。 -const String appVersion = '26.2'; +const String appVersion = '26.3 WIP'; -const String appDescription = '将 C++ 头文件、源码与库可视化为原生 NuGet 包的 Windows 桌面工具。'; +const String appDescription = '啊这个这个,0百万元以内最好用的包管理,遥遥领先'; const String appRepositoryUrl = 'https://github.com/1992724048/cpp-pack-tool'; diff --git a/lib/controls/build_options.dart b/lib/controls/build_options.dart index f3a7f40..5eefb24 100644 --- a/lib/controls/build_options.dart +++ b/lib/controls/build_options.dart @@ -7,15 +7,8 @@ import 'package:fluent_ui/fluent_ui.dart'; /// 选项按 `build.py` 声明顺序渲染;值变更经 [onChange] 上报(`null` 表示移除保存键); /// [saving] 为保存挂起标志,为 true 时全部控件禁用(fluent 禁用态)。 class BuildOptionsPanel extends StatefulWidget { - const BuildOptionsPanel({ - super.key, - required this.options, - required this.values, - required this.expanded, - required this.onToggleExpanded, - required this.saving, - required this.onChange, - }); + const BuildOptionsPanel( + {super.key, required this.options, required this.values, required this.expanded, required this.onToggleExpanded, required this.saving, required this.onChange}); final List options; @@ -49,33 +42,31 @@ class _BuildOptionsPanelState extends State { final FluentThemeData theme = FluentTheme.of(context); return Padding( key: const Key('buildOptionsSection'), - padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), + padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SizedBox( - height: 28, + Card( + margin: EdgeInsetsGeometry.fromLTRB(0, 3, 0, 0), + padding: EdgeInsetsGeometry.fromLTRB(5, 2, 5, 2), child: Row( children: [ Text( '构建选项', style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.w600, - color: theme.resources.textFillColorPrimary, - ), + fontSize: 13, fontWeight: FontWeight.w600, color: theme.resources.textFillColorPrimary), ), + SizedBox(width: 5), + Text(('(${widget.options.length} 项)'), style: TextStyle(color: FluentTheme + .of(context) + .resources + .textFillColorSecondary)), const Spacer(), _buildToggle(), ], ), ), if (widget.expanded) ...[ - Container( - height: 1, - color: theme.resources.dividerStrokeColorDefault, - ), - const SizedBox(height: 8), ConstrainedBox( constraints: const BoxConstraints(maxHeight: _maxListHeight), child: Scrollbar( @@ -86,15 +77,10 @@ class _BuildOptionsPanelState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - for ( - int index = 0; - index < widget.options.length; - index++ - ) ...[ - if (index > 0) const SizedBox(height: 4), - _buildOptionRow(theme, widget.options[index]), + for (int index = 0; index < widget.options.length; index++) ...[ + Card(margin: EdgeInsetsGeometry.fromLTRB(0, 3, 0, 0), padding: EdgeInsetsGeometry.fromLTRB( + 0, 0, 0, 0), child: _buildOptionRow(theme, widget.options[index])), ], - const SizedBox(height: 8), ], ), ), @@ -108,18 +94,13 @@ class _BuildOptionsPanelState extends State { Widget _buildToggle() { return SizedBox( - width: 24, - height: 24, + width: 26, + height: 26, child: Tooltip( message: widget.expanded ? '收起构建选项' : '展开构建选项', - child: IconButton( - key: const Key('buildOptionsToggle'), - icon: Icon( - widget.expanded ? FluentIcons.chevron_down : FluentIcons.chevron_up, - size: 14, - ), - onPressed: widget.onToggleExpanded, - ), + child: IconButton(key: const Key('buildOptionsToggle'), + icon: Icon(widget.expanded ? FluentIcons.chevron_down : FluentIcons.chevron_up, size: 15), + onPressed: widget.onToggleExpanded), ), ); } @@ -129,12 +110,10 @@ class _BuildOptionsPanelState extends State { case BuildOptionControl.dropdown: return _buildDropdownRow(theme, option); case BuildOptionControl.checkbox: - return _CheckboxOptionRow( - option: option, - value: effectiveBuildOptionValue(option, widget.values), - enabled: !widget.saving, - onChanged: widget.onChange, - ); + return _CheckboxOptionRow(option: option, + value: effectiveBuildOptionValue(option, widget.values), + enabled: !widget.saving, + onChanged: widget.onChange); case BuildOptionControl.multiselect: return _buildMultiSelectRow(theme, option); } @@ -145,82 +124,75 @@ class _BuildOptionsPanelState extends State { return SizedBox( key: Key('buildOptionRow_${option.name}'), height: 40, - child: Row( - children: [ - Expanded(child: _buildOptionTitle(theme, option.name)), - SizedBox( - width: _optionFieldWidth, - child: FluentTheme( - data: FluentTheme.of(context).copyWith( - visualDensity: comboBoxDensity, - ), - child: ComboBox( - key: Key('buildOption_${option.name}'), - value: value, - isExpanded: true, - onChanged: widget.saving - ? null - : (String? selected) { - if (selected != null && selected != value) { - widget.onChange(option.name, selected); - } - }, - items: >[ - for (final String item in option.values) - ComboBoxItem( - value: item, - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Text( - item, - maxLines: 1, - overflow: TextOverflow.ellipsis, + child: Padding( + padding: EdgeInsetsGeometry.fromLTRB(5, 0, 5, 0), + child: Row( + children: [ + Expanded(child: _buildOptionTitle(theme, option.name)), + SizedBox( + width: _optionFieldWidth, + child: FluentTheme( + data: FluentTheme.of(context).copyWith(visualDensity: comboBoxDensity), + child: ComboBox( + key: Key('buildOption_${option.name}'), + value: value, + isExpanded: true, + onChanged: widget.saving + ? null + : (String? selected) { + if (selected != null && selected != value) { + widget.onChange(option.name, selected); + } + }, + items: >[ + for (final String item in option.values) + ComboBoxItem( + value: item, + child: Align( + alignment: AlignmentDirectional.centerStart, + child: Text(item, maxLines: 1, overflow: TextOverflow.ellipsis), ), ), - ), - ], + ], + ), ), ), - ), - ], + ], + ), ), ); } Widget _buildMultiSelectRow(FluentThemeData theme, BuildScriptOption option) { - final Set selected = multiSelectSelection( - option.values, - widget.values[option.name], - ); - return ConstrainedBox( - key: Key('buildOptionRow_${option.name}'), - constraints: const BoxConstraints(minHeight: 40), - child: Row( - children: [ - Expanded(child: _buildOptionTitle(theme, option.name)), - ConstrainedBox( - constraints: const BoxConstraints(maxWidth: _multiSelectMaxWidth), - child: Wrap( - key: Key('buildOption_${option.name}'), - alignment: WrapAlignment.end, - spacing: 16, - runSpacing: 6, - children: [ - for (final String value in option.values) - _buildMultiSelectItem(option, value, selected.contains(value)), - ], + final Set selected = multiSelectSelection(option.values, widget.values[option.name]); + return Padding( + padding: EdgeInsetsGeometry.fromLTRB(5, 0, 5, 0), + child: ConstrainedBox( + key: Key('buildOptionRow_${option.name}'), + constraints: const BoxConstraints(minHeight: 40), + child: Row( + children: [ + Expanded(child: _buildOptionTitle(theme, option.name)), + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: _multiSelectMaxWidth), + child: Wrap( + key: Key('buildOption_${option.name}'), + alignment: WrapAlignment.end, + spacing: 16, + runSpacing: 6, + children: [ + for (final String value in option.values) _buildMultiSelectItem( + option, value, selected.contains(value)) + ], + ), ), - ), - ], + ], + ), ), ); } - Widget _buildMultiSelectItem( - BuildScriptOption option, - String value, - bool checked, - ) { + Widget _buildMultiSelectItem(BuildScriptOption option, String value, bool checked) { return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -228,10 +200,7 @@ class _BuildOptionsPanelState extends State { key: Key('buildOptionValue_${option.name}_$value'), checked: checked, semanticLabel: value, - onChanged: widget.saving - ? null - : (bool? next) => - _toggleMultiSelectValue(option, value, next ?? !checked), + onChanged: widget.saving ? null : (bool? next) => _toggleMultiSelectValue(option, value, next ?? !checked), ), const SizedBox(width: 8), Text(value, style: _optionTextStyle(FluentTheme.of(context))), @@ -239,19 +208,11 @@ class _BuildOptionsPanelState extends State { ); } - void _toggleMultiSelectValue( - BuildScriptOption option, - String value, - bool checked, - ) { - final Set current = multiSelectSelection( - option.values, - widget.values[option.name], - ); + void _toggleMultiSelectValue(BuildScriptOption option, String value, bool checked) { + final Set current = multiSelectSelection(option.values, widget.values[option.name]); final List selected = [ for (final String candidate in option.values) - if (candidate == value ? checked : current.contains(candidate)) - candidate, + if (candidate == value ? checked : current.contains(candidate)) candidate, ]; widget.onChange(option.name, selected.join(';')); } @@ -261,21 +222,13 @@ class _BuildOptionsPanelState extends State { TextStyle _optionTextStyle(FluentThemeData theme) => TextStyle(fontSize: 13, color: theme.resources.textFillColorPrimary); -Widget _buildOptionTitle(FluentThemeData theme, String name) => Text( - name, - overflow: TextOverflow.ellipsis, - style: _optionTextStyle(theme), -); +Widget _buildOptionTitle(FluentThemeData theme, String name) => + Text(name, overflow: TextOverflow.ellipsis, style: _optionTextStyle(theme)); /// 布尔选项行:整行可点(悬停背景 + click 光标),Checkbox 自身保留键盘切换; /// 行外层与 Checkbox 手势竞技场由内层胜出,单击只切换一次。 class _CheckboxOptionRow extends StatefulWidget { - const _CheckboxOptionRow({ - required this.option, - required this.value, - required this.enabled, - required this.onChanged, - }); + const _CheckboxOptionRow({required this.option, required this.value, required this.enabled, required this.onChanged}); final BuildScriptOption option; final String value; @@ -310,23 +263,19 @@ class _CheckboxOptionRowState extends State<_CheckboxOptionRow> { behavior: HitTestBehavior.opaque, onTap: _toggle, child: Container( + margin: EdgeInsetsGeometry.all(0), + padding: EdgeInsetsGeometry.fromLTRB(5, 0, 5, 0), key: Key('buildOptionRow_${widget.option.name}'), constraints: const BoxConstraints(minHeight: 40), - decoration: BoxDecoration( - color: _hovered - ? theme.resources.controlFillColorSecondary - : Colors.transparent, - borderRadius: BorderRadius.circular(4), - ), + decoration: BoxDecoration(color: _hovered ? theme.resources.controlFillColorSecondary : Colors.transparent, + borderRadius: BorderRadius.circular(4)), child: Row( children: [ Expanded(child: _buildOptionTitle(theme, widget.option.name)), - Checkbox( - key: Key('buildOption_${widget.option.name}'), - checked: _checked, - semanticLabel: widget.option.name, - onChanged: widget.enabled ? (bool? _) => _toggle() : null, - ), + Checkbox(key: Key('buildOption_${widget.option.name}'), + checked: _checked, + semanticLabel: widget.option.name, + onChanged: widget.enabled ? (bool? _) => _toggle() : null), ], ), ), @@ -339,12 +288,7 @@ class _CheckboxOptionRowState extends State<_CheckboxOptionRow> { /// /// 保存口径:默认 = 键不存在([onChanged] 收到 null);MD / MT = 显式写入。 class RuntimeLibrarySelector extends StatelessWidget { - const RuntimeLibrarySelector({ - super.key, - required this.value, - required this.enabled, - required this.onChanged, - }); + const RuntimeLibrarySelector({super.key, required this.value, required this.enabled, required this.onChanged}); /// 当前保存值:`MD` / `MT`;null 显示「默认(跟随配方)」。 final String? value; @@ -353,111 +297,74 @@ class RuntimeLibrarySelector extends StatelessWidget { final ValueChanged onChanged; static const String _defaultItemValue = 'default'; - static const double _width = 168; + static const double _width = 75; @override Widget build(BuildContext context) { - return SizedBox( - width: _width, - child: ComboBox( - key: const Key('buildRuntimeSelector'), - value: value ?? _defaultItemValue, - isExpanded: true, - onChanged: enabled - ? (String? selected) => onChanged( - selected == null || selected == _defaultItemValue ? null : selected, - ) - : null, - items: const >[ - ComboBoxItem( - value: _defaultItemValue, - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Text( - '默认(跟随配方)', - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), + final TextStyle boldPhrase = const TextStyle(fontWeight: FontWeight.w600); + return Tooltip( + richMessage: TextSpan( + children: [ + TextSpan(text: '运行库(MSVC CRT)', style: boldPhrase), + const TextSpan(text: '\n· '), + TextSpan(text: '默认', style: boldPhrase), + const TextSpan( + text: + ':由 build.py 配方的编译参数决定;' + '需要覆盖时再显式选择 MD / MT。', ), - ComboBoxItem( - value: 'MD', - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Text( - 'MD(动态运行库)', - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), + const TextSpan(text: '\n· '), + TextSpan(text: 'MD(动态运行库)', style: boldPhrase), + const TextSpan( + text: + ':CRT 以共享 dll 提供,多个模块共用同一份,产物体积更小;' + '运行需目标机器安装匹配的 VC++ Redistributable。', ), - ComboBoxItem( - value: 'MT', - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Text( - 'MT(静态运行库)', - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), + const TextSpan(text: '\n· '), + TextSpan(text: 'MT(静态运行库)', style: boldPhrase), + const TextSpan( + text: + ':CRT 静态链入每个模块,无运行时依赖、部署最简单;' + '各模块各自持有一份,总体积更大。', ), + const TextSpan(text: '\n· Debug 构建自动使用 d 变体(MDd / MTd),无需手动切换。'), + const TextSpan(text: '\n· 推荐:优先 MD 并随包分发共享 dll + lib,可显著减小体积;需要免依赖分发时选 MT。'), ], ), - ); - } -} - -/// 运行库帮助入口:「?」按钮悬停显示反色富文本 Tooltip(只读说明)。 -class RuntimeLibraryHelpButton extends StatelessWidget { - const RuntimeLibraryHelpButton({super.key}); - - @override - Widget build(BuildContext context) { - final TextStyle boldPhrase = const TextStyle(fontWeight: FontWeight.w600); - return SizedBox( - width: 28, - height: 28, - child: Tooltip( - richMessage: TextSpan( - children: [ - TextSpan(text: '运行库(MSVC CRT)', style: boldPhrase), - const TextSpan(text: '\n· '), - TextSpan(text: '默认(跟随配方)', style: boldPhrase), - const TextSpan( - text: - ':由 build.py 配方的编译参数决定;' - '需要覆盖时再显式选择 MD / MT。', - ), - const TextSpan(text: '\n· '), - TextSpan(text: 'MD(动态运行库)', style: boldPhrase), - const TextSpan( - text: - ':CRT 以共享 dll 提供,多个模块共用同一份,产物体积更小;' - '运行需目标机器安装匹配的 VC++ Redistributable。', + style: const TooltipThemeData(maxWidth: 360, showDuration: Duration(seconds: 30)), + child: SizedBox( + width: _width, + height: 29, + child: ComboBox( + key: const Key('buildRuntimeSelector'), + value: value ?? _defaultItemValue, + isExpanded: true, + onChanged: enabled ? (String? selected) => + onChanged(selected == null || selected == _defaultItemValue ? null : selected) : null, + items: const >[ + ComboBoxItem( + value: _defaultItemValue, + child: Align( + alignment: AlignmentDirectional.centerStart, + child: Text('默认', maxLines: 1, overflow: TextOverflow.ellipsis), + ), ), - const TextSpan(text: '\n· '), - TextSpan(text: 'MT(静态运行库)', style: boldPhrase), - const TextSpan( - text: - ':CRT 静态链入每个模块,无运行时依赖、部署最简单;' - '各模块各自持有一份,总体积更大。', + ComboBoxItem( + value: 'MD', + child: Align( + alignment: AlignmentDirectional.centerStart, + child: Text('MD', maxLines: 1, overflow: TextOverflow.ellipsis), + ), ), - const TextSpan(text: '\n· Debug 构建自动使用 d 变体(MDd / MTd),无需手动切换。'), - const TextSpan( - text: '\n· 推荐:优先 MD 并随包分发共享 dll + lib,可显著减小体积;需要免依赖分发时选 MT。', + ComboBoxItem( + value: 'MT', + child: Align( + alignment: AlignmentDirectional.centerStart, + child: Text('MT', maxLines: 1, overflow: TextOverflow.ellipsis), + ), ), ], ), - style: const TooltipThemeData( - maxWidth: 360, - showDuration: Duration(seconds: 30), - ), - child: IconButton( - key: const Key('buildRuntimeHelp'), - icon: const Icon(FluentIcons.help, size: 16), - onPressed: () {}, - ), ), ); } diff --git a/lib/controls/pack_manage.dart b/lib/controls/pack_manage.dart index 07bdd39..084da2a 100644 --- a/lib/controls/pack_manage.dart +++ b/lib/controls/pack_manage.dart @@ -171,10 +171,7 @@ class _PackManageState extends State { return Builder( builder: (BuildContext context) { final theme = FluentTheme.of(context); - return Container( - decoration: BoxDecoration(color: theme.cardColor), - child: child, - ); + return child; }, ); } diff --git a/lib/main.dart b/lib/main.dart index 8282e97..694c65a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -31,8 +31,8 @@ import 'package:cpp_nuget_pack/util/system_entries.dart'; import 'package:cpp_nuget_pack/widgets/floating_toast.dart'; import 'package:cpp_nuget_pack/widgets/library_card.dart'; import 'package:file_selector/file_selector.dart'; -import 'package:flutter/services.dart'; import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter/services.dart'; import 'app_info.dart'; import 'controls/add_directory_dialog.dart'; @@ -92,7 +92,7 @@ class _PackToolState extends State { @override Widget build(BuildContext context) { return FluentApp( - title: 'C++ Pack Tool', + title: 'C++ Pack', themeMode: switch (_settings.themeMode) { ThemeModeSetting.system => ThemeMode.system, ThemeModeSetting.dark => ThemeMode.dark, @@ -100,11 +100,7 @@ class _PackToolState extends State { }, theme: buildTheme(Brightness.light), darkTheme: buildTheme(Brightness.dark), - home: MainLayout( - store: widget.store, - settings: _settings, - onSaveSettings: _saveSettings, - ), + home: MainLayout(store: widget.store, settings: _settings, onSaveSettings: _saveSettings), ); } } @@ -140,8 +136,7 @@ Future _preparePackBuildEnvironment( onCompilersDetected: onCompilersDetected, onDownloadProgress: onDownloadProgress, proxy: proxy, - loadSupportModule: () => - rootBundle.loadString('assets/build/cnp_build_support.py'), + loadSupportModule: () => rootBundle.loadString('assets/build/cnp_build_support.py'), ); } @@ -179,16 +174,8 @@ class MainLayout extends StatefulWidget { final PackStore store; final SettingsModel settings; final Future Function(SettingsModel settings) onSaveSettings; - final Future Function( - PackModel pack, - String outputDirectory, - ) - exportPackage; - final Future Function( - PackModel pack, - String outputDirectory, - ) - exportCmakePackage; + final Future Function(PackModel pack, String outputDirectory) exportPackage; + final Future Function(PackModel pack, String outputDirectory) exportCmakePackage; final PackBuildRunner buildPack; final PackBuildEnvironmentPreparer? prepareBuildEnv; @@ -248,8 +235,7 @@ class _MainLayoutState extends State { final Map> _repoIconQueries = >{}; /// 仓库地址 → 远端最新 tag 查询 Future(去重同一仓库的并发查询)。 - final Map> _latestTagQueries = - >{}; + final Map> _latestTagQueries = >{}; /// 仓库地址 → 已完成的远端最新 tag;查询失败/无可用 tag 时为 null。 final Map _latestTags = {}; @@ -286,12 +272,7 @@ class _MainLayoutState extends State { packs = result.packs; errors.addAll(result.errors); } catch (error) { - errors.add( - PackLoadError( - fileName: widget.store.rootPath, - message: error.toString(), - ), - ); + errors.add(PackLoadError(fileName: widget.store.rootPath, message: error.toString())); } if (!mounted) { return; @@ -303,13 +284,9 @@ class _MainLayoutState extends State { }); _resolveRepos(); if (errors.isNotEmpty) { - WidgetsBinding.instance.addPostFrameCallback( - (_) => _showLoadErrorsToast(errors), - ); + WidgetsBinding.instance.addPostFrameCallback((_) => _showLoadErrorsToast(errors)); } - WidgetsBinding.instance.addPostFrameCallback( - (_) => unawaited(_fixPlaceholderAuthors()), - ); + WidgetsBinding.instance.addPostFrameCallback((_) => unawaited(_fixPlaceholderAuthors())); } /// 占位作者批量修正:默认作者非空且自身不是占位值时逐个替换并写盘; @@ -319,9 +296,7 @@ class _MainLayoutState extends State { return; } final String defaultAuthor = widget.settings.defaultAuthor.trim(); - if (defaultAuthor.isEmpty || - isPlaceholderAuthor(defaultAuthor) || - _packs.isEmpty) { + if (defaultAuthor.isEmpty || isPlaceholderAuthor(defaultAuthor) || _packs.isEmpty) { return; } _fixingAuthors = true; @@ -346,12 +321,10 @@ class _MainLayoutState extends State { if (updatedPacks.isNotEmpty && mounted) { setState(() { final Map replacements = { - for (final PackModel pack in updatedPacks) - pack.name.toLowerCase(): pack, + for (final PackModel pack in updatedPacks) pack.name.toLowerCase(): pack, }; for (int index = 0; index < _packs.length; index++) { - final PackModel? replacement = - replacements[_packs[index].name.toLowerCase()]; + final PackModel? replacement = replacements[_packs[index].name.toLowerCase()]; if (replacement != null) { _packs[index] = replacement; } @@ -383,11 +356,7 @@ class _MainLayoutState extends State { ); return; } - showFloatingToast( - context, - '已按默认作者修正 $fixed 个包的作者', - type: FloatingToastType.info, - ); + showFloatingToast(context, '已按默认作者修正 $fixed 个包的作者', type: FloatingToastType.info); } /// 全字段拷贝并替换作者(`PackModel.author` 为 final,只能重建)。 @@ -416,10 +385,7 @@ class _MainLayoutState extends State { /// 写盘前的作者兜底:占位作者替换为默认作者(静默)。 PackModel _withResolvedAuthor(PackModel pack) { - final String resolved = resolveDefaultAuthor( - pack.author, - widget.settings.defaultAuthor, - ); + final String resolved = resolveDefaultAuthor(pack.author, widget.settings.defaultAuthor); return resolved == pack.author ? pack : _withAuthor(pack, resolved); } @@ -427,9 +393,7 @@ class _MainLayoutState extends State { if (!mounted) { return; } - final String details = errors - .map((PackLoadError error) => error.toString()) - .join('\n'); + final String details = errors.map((PackLoadError error) => error.toString()).join('\n'); showFloatingToast( context, '${errors.length} 个配置加载失败\n$details', @@ -449,19 +413,13 @@ class _MainLayoutState extends State { final Future> scanFuture = widget.scanFiles(path); final PackModel? pack = await showDialog( context: context, - builder: (_) => AddDirectoryDialog( - directoryPath: path, - scanFuture: scanFuture, - initialAuthor: widget.settings.defaultAuthor, - ), + builder: (_) => + AddDirectoryDialog(directoryPath: path, scanFuture: scanFuture, initialAuthor: widget.settings.defaultAuthor), ); if (pack == null || !mounted) { return; } - final int totalSize = pack.files.fold( - 0, - (int sum, FileModel file) => sum + file.size, - ); + final int totalSize = pack.files.fold(0, (int sum, FileModel file) => sum + file.size); pack.history = appendHistoryEntry( pack.history, HistoryModel( @@ -497,12 +455,7 @@ class _MainLayoutState extends State { builder: (BuildContext dialogContext) => ContentDialog( title: const Text('保存失败'), content: Text('包「${pack.name}」保存失败:$error'), - actions: [ - Button( - onPressed: () => Navigator.pop(dialogContext), - child: const Text('确定'), - ), - ], + actions: [Button(onPressed: () => Navigator.pop(dialogContext), child: const Text('确定'))], ), ); return false; @@ -516,9 +469,7 @@ class _MainLayoutState extends State { void _upsertPack(PackModel pack) { setState(() { - final int existing = _packs.indexWhere( - (PackModel item) => item.name.toLowerCase() == pack.name.toLowerCase(), - ); + final int existing = _packs.indexWhere((PackModel item) => item.name.toLowerCase() == pack.name.toLowerCase()); if (existing >= 0) { _packs[existing] = pack; } else { @@ -578,9 +529,7 @@ class _MainLayoutState extends State { return; } final String? resolvedRepo = repo; - final RepoLocation? location = resolvedRepo == null - ? null - : parseRepoLocation(resolvedRepo); + final RepoLocation? location = resolvedRepo == null ? null : parseRepoLocation(resolvedRepo); final String? previousRepo = _packRepos[name]; setState(() { _packRepos[name] = resolvedRepo; @@ -601,10 +550,7 @@ class _MainLayoutState extends State { /// 解析并缓存侧栏头像:同一仓库 URL 复用进行中的查询,成功后写入 [_repoIcons]。 Future _resolveRepoAvatar(String packName, String repoUrl) async { - final Future query = _repoIconQueries.putIfAbsent( - repoUrl, - () => _queryRepoIcon(repoUrl), - ); + final Future query = _repoIconQueries.putIfAbsent(repoUrl, () => _queryRepoIcon(repoUrl)); String? path; try { path = await query; @@ -619,8 +565,7 @@ class _MainLayoutState extends State { Future _queryRepoIcon(String repoUrl) async { try { - final Future Function(String repoUrl)? loader = - widget.loadRepoIcon; + final Future Function(String repoUrl)? loader = widget.loadRepoIcon; if (loader != null) { return await loader(repoUrl); } @@ -657,16 +602,12 @@ class _MainLayoutState extends State { Future _queryLatestTag(String repoUrl) async { List? tags; try { - final Future?> Function(String repoUrl)? loader = - widget.loadRemoteTags; + final Future?> Function(String repoUrl)? loader = widget.loadRemoteTags; if (loader != null) { tags = await loader(repoUrl); } else { final ProxyResolution proxy = await _proxyResolution(); - tags = await listRemoteTags( - repoUrl, - environment: proxyEnvironmentOverrides(proxy), - ); + tags = await listRemoteTags(repoUrl, environment: proxyEnvironmentOverrides(proxy)); } } catch (_) { tags = null; @@ -685,9 +626,7 @@ class _MainLayoutState extends State { } final String? current = pack.sourceVersion; final String? latest = _latestTags[repo]; - if (current != null && - latest != null && - compareTagVersions(latest, current) > 0) { + if (current != null && latest != null && compareTagVersions(latest, current) > 0) { return RepoBadge.update; } return RepoBadge.git; @@ -725,12 +664,7 @@ class _MainLayoutState extends State { if (!mounted) { return; } - showFloatingToast( - context, - '删除失败:$error', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + showFloatingToast(context, '删除失败:$error', type: FloatingToastType.error, duration: const Duration(seconds: 5)); return; } if (!mounted) { @@ -805,11 +739,7 @@ class _MainLayoutState extends State { final Future> scanFuture = widget.scanFiles(sourcePath); await showDialog( context: context, - builder: (_) => RemapPackDialog( - pack: pack, - scanFuture: scanFuture, - onApply: _applyRemap, - ), + builder: (_) => RemapPackDialog(pack: pack, scanFuture: scanFuture, onApply: _applyRemap), ); } @@ -817,22 +747,12 @@ class _MainLayoutState extends State { pack = _withResolvedAuthor(pack); final PackModel? previous = _findPack(pack.name); if (previous != null) { - final Set oldPaths = { - for (final FileModel file in previous.files) file.path.toLowerCase(), - }; - final Set newPaths = { - for (final FileModel file in pack.files) file.path.toLowerCase(), - }; + final Set oldPaths = {for (final FileModel file in previous.files) file.path.toLowerCase()}; + final Set newPaths = {for (final FileModel file in pack.files) file.path.toLowerCase()}; final int added = newPaths.difference(oldPaths).length; final int removed = oldPaths.difference(newPaths).length; - final int oldSize = previous.files.fold( - 0, - (int sum, FileModel file) => sum + file.size, - ); - final int newSize = pack.files.fold( - 0, - (int sum, FileModel file) => sum + file.size, - ); + final int oldSize = previous.files.fold(0, (int sum, FileModel file) => sum + file.size); + final int newSize = pack.files.fold(0, (int sum, FileModel file) => sum + file.size); if (added != 0 || removed != 0 || oldSize != newSize) { pack.history = appendHistoryEntry( pack.history, @@ -866,11 +786,7 @@ class _MainLayoutState extends State { } catch (_) { header = null; } - return applySystemEntries( - pack, - header: header, - resolvePackVersion: (String name) => _findPack(name)?.version, - ).pack; + return applySystemEntries(pack, header: header, resolvePackVersion: (String name) => _findPack(name)?.version).pack; } void _selectPackagingBuilder(PackageBuilder builder) { @@ -926,17 +842,13 @@ class _MainLayoutState extends State { onSourceVersion: onSourceVersion, gitGlobalArguments: gitGlobalArguments, ), - prepare: - ( - PackModel pack, { - ToolDownloadProgressCallback? onDownloadProgress, - }) => prepare( - pack, - compilerPriority: widget.settings.compilerPriority, - cachedCompilers: widget.settings.detectedCompilers, - onCompilersDetected: _persistDetectedCompilers, - onDownloadProgress: onDownloadProgress, - ), + prepare: (PackModel pack, {ToolDownloadProgressCallback? onDownloadProgress}) => prepare( + pack, + compilerPriority: widget.settings.compilerPriority, + cachedCompilers: widget.settings.detectedCompilers, + onCompilersDetected: _persistDetectedCompilers, + onDownloadProgress: onDownloadProgress, + ), scanFiles: widget.scanFiles, onApply: _applyRemap, fixIncludes: widget.fixIncludes, @@ -967,10 +879,7 @@ class _MainLayoutState extends State { } /// 记录构建失败条目(失败会话关闭时落盘一次);保存失败仅提示、不阻断。 - Future _recordBuildFailure( - PackModel pack, - HistoryModel entry, - ) async { + Future _recordBuildFailure(PackModel pack, HistoryModel entry) async { final PackModel? current = _findPack(pack.name); if (current == null) { return; @@ -1042,14 +951,9 @@ class _MainLayoutState extends State { return; } final PackModel pack = _packs[selected]; - final PackageBuilder builder = effectivePackagingBuilder( - pack, - _packagingBuilder, - ); + final PackageBuilder builder = effectivePackagingBuilder(pack, _packagingBuilder); final bool isCmake = builder.id == _cmakeBuilderId; - final String? outputDirectory = isCmake - ? widget.settings.cmakeOutputDirectory - : widget.settings.outputDirectory; + final String? outputDirectory = isCmake ? widget.settings.cmakeOutputDirectory : widget.settings.outputDirectory; if (outputDirectory == null || outputDirectory.isEmpty) { showFloatingToast( context, @@ -1060,20 +964,12 @@ class _MainLayoutState extends State { return; } if (pack.sourcePath == null) { - showFloatingToast( - context, - '该包缺少源目录信息,无法打包', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + showFloatingToast(context, '该包缺少源目录信息,无法打包', type: FloatingToastType.error, duration: const Duration(seconds: 5)); return; } final List missing = _missingDependencies(pack); if (missing.isNotEmpty) { - final bool proceed = await showMissingDependenciesDialog( - context, - missing: missing, - ); + final bool proceed = await showMissingDependenciesDialog(context, missing: missing); if (!proceed || !mounted) { return; } @@ -1086,8 +982,7 @@ class _MainLayoutState extends State { ? const [] : collectExecutableWarnings(plan); final List issues = [ - if (plan != null && builder.id == _nugetBuilderId) - ...collectPackagingIssues(pack, plan), + if (plan != null && builder.id == _nugetBuilderId) ...collectPackagingIssues(pack, plan), ...executableWarnings, ]; if (issues.isNotEmpty) { @@ -1100,13 +995,8 @@ class _MainLayoutState extends State { return; } } - final Future Function( - PackModel pack, - String outputDirectory, - ) - exportPackage = builder.id == _cmakeBuilderId - ? widget.exportCmakePackage - : widget.exportPackage; + final Future Function(PackModel pack, String outputDirectory) exportPackage = + builder.id == _cmakeBuilderId ? widget.exportCmakePackage : widget.exportPackage; await showDialog( context: context, builder: (_) => PackExportDialog( @@ -1118,10 +1008,7 @@ class _MainLayoutState extends State { ); } - Future _buildPackagingPlan( - PackageBuilder builder, - PackModel pack, - ) async { + Future _buildPackagingPlan(PackageBuilder builder, PackModel pack) async { try { return await builder.buildPlan(pack); } catch (_) { @@ -1147,11 +1034,7 @@ class _MainLayoutState extends State { Future _recordExport(PackModel pack, PackageExportResult result) async { pack.history = appendHistoryEntry( pack.history, - HistoryModel( - time: widget.now(), - type: HistoryType.exported, - message: '打包导出:${result.outputPath}', - ), + HistoryModel(time: widget.now(), type: HistoryType.exported, message: '打包导出:${result.outputPath}'), ); try { await widget.store.savePack(pack); @@ -1178,11 +1061,7 @@ class _MainLayoutState extends State { if (selected == null || selected < 0 || selected >= _packs.length) { return; } - await showPackHistoryDialog( - context, - pack: _packs[selected], - onSave: _savePack, - ); + await showPackHistoryDialog(context, pack: _packs[selected], onSave: _savePack); } Future _openDependencyGraph() async { @@ -1195,9 +1074,7 @@ class _MainLayoutState extends State { void _sortPacks() { _packs.sort((PackModel first, PackModel second) { - final int insensitive = first.name.toLowerCase().compareTo( - second.name.toLowerCase(), - ); + final int insensitive = first.name.toLowerCase().compareTo(second.name.toLowerCase()); if (insensitive != 0) { return insensitive; } @@ -1227,11 +1104,8 @@ class _MainLayoutState extends State { @override Widget build(BuildContext context) { return NavigationView( - titleBar: TitleBar( - isBackButtonVisible: false, - title: const Center(widthFactor: 1.0, child: Text('C++ NuGet 打包工具')), - ), paneBodyBuilder: _buildPaneBody, + titleBar: SizedBox.shrink(), pane: NavigationPane( selected: _selected, onChanged: (int newIndex) => setState(() => _selected = newIndex), @@ -1244,31 +1118,19 @@ class _MainLayoutState extends State { ), Tooltip( message: '删除文件夹', - child: IconButton( - icon: Svgs.deleteFolder, - onPressed: _hasSelectedPack ? _deleteSelectedPack : null, - ), + child: IconButton(icon: Svgs.deleteFolder, onPressed: _hasSelectedPack ? _deleteSelectedPack : null), ), Tooltip( message: '重新映射', - child: IconButton( - icon: Svgs.mapAsDrive, - onPressed: _hasSelectedPack ? _remapSelectedPack : null, - ), + child: IconButton(icon: Svgs.mapAsDrive, onPressed: _hasSelectedPack ? _remapSelectedPack : null), ), Tooltip( message: '打包文件夹', - child: IconButton( - icon: Svgs.moveToFolder, - onPressed: _hasSelectedPack ? _packSelectedPack : null, - ), + child: IconButton(icon: Svgs.moveToFolder, onPressed: _hasSelectedPack ? _packSelectedPack : null), ), Tooltip( message: '历史记录', - child: IconButton( - icon: Svgs.historyFolder, - onPressed: _hasSelectedPack ? _historySelectedPack : null, - ), + child: IconButton(icon: Svgs.historyFolder, onPressed: _hasSelectedPack ? _historySelectedPack : null), ), Tooltip( message: '依赖关系图', @@ -1280,11 +1142,7 @@ class _MainLayoutState extends State { ], ), displayMode: PaneDisplayMode.expanded, - size: NavigationPaneSize( - openMaxWidth: 260, - openMinWidth: 260, - compactWidth: 50, - ), + size: NavigationPaneSize(openMaxWidth: 260, openMinWidth: 260, compactWidth: 50), items: PackList.buildCards( _packs, onSave: _savePack, @@ -1296,10 +1154,7 @@ class _MainLayoutState extends State { repoBadgeFor: _repoBadgeFor, repoIconFor: (PackModel pack) { final String name = pack.name.toLowerCase(); - return ( - platform: _repoPlatforms[name], - avatarPath: _repoIcons[name], - ); + return (platform: _repoPlatforms[name], avatarPath: _repoIcons[name]); }, loadHeader: widget.loadBuildHeader, ), @@ -1315,12 +1170,7 @@ class _MainLayoutState extends State { detectCompilers: widget.detectCompilers, ), ), - LibraryItem( - icon: Svgs.info, - title: '关于', - version: appVersion, - body: const About(), - ), + LibraryItem(icon: Svgs.info, title: '关于', version: appVersion, body: const About()), ], ), ); diff --git a/lib/models/pack_model.dart b/lib/models/pack_model.dart index 8b1707d..e7df2d4 100644 --- a/lib/models/pack_model.dart +++ b/lib/models/pack_model.dart @@ -37,16 +37,8 @@ class PackModel { static List packs = []; - PackModel({ - required this.name, - required this.version, - required this.author, - this.description, - this.license, - this.iconPath, - this.sourcePath, - this.sourceVersion, - }); + PackModel( + {required this.name, required this.version, required this.author, this.description, this.license, this.iconPath, this.sourcePath, this.sourceVersion}); Map toMap() { return { @@ -58,43 +50,22 @@ class PackModel { if (iconPath != null) 'iconPath': iconPath, if (sourcePath != null) 'sourcePath': sourcePath, if (sourceVersion != null) 'sourceVersion': sourceVersion, - 'files': >[ - for (final FileModel file in files) file.toMap(), - ], - 'dependencies': >[ - for (final DependencyModel dependency in dependencies) - dependency.toMap(), - ], - 'commands': >[ - for (final CmdModel command in commands) command.toMap(), - ], - 'macros': >[ - for (final MacroModel macro in macros) macro.toMap(), - ], + 'files': >[for (final FileModel file in files) file.toMap()], + 'dependencies': >[for (final DependencyModel dependency in dependencies) dependency.toMap()], + 'commands': >[for (final CmdModel command in commands) command.toMap()], + 'macros': >[for (final MacroModel macro in macros) macro.toMap()], 'libDirectories': >[ - for (final LibDirModel libDirectory in libDirectories) - libDirectory.toMap(), - ], - 'libraries': >[ - for (final LibraryModel library in libraries) library.toMap(), - ], - 'history': >[ - for (final HistoryModel entry in history) entry.toMap(), + for (final LibDirModel libDirectory in libDirectories) libDirectory.toMap() ], - 'scripts': >[ - for (final ScriptProjectModel script in scripts) script.toMap(), - ], - if (buildOptions.isNotEmpty) - 'buildOptions': {...buildOptions}, - if (enabledFormats.isNotEmpty) - 'enabledFormats': [...enabledFormats], + 'libraries': >[for (final LibraryModel library in libraries) library.toMap()], + 'history': >[for (final HistoryModel entry in history) entry.toMap()], + 'scripts': >[for (final ScriptProjectModel script in scripts) script.toMap()], + if (buildOptions.isNotEmpty) 'buildOptions': {...buildOptions}, + if (enabledFormats.isNotEmpty) 'enabledFormats': [...enabledFormats], }; } - factory PackModel.fromMap( - Map map, { - List? warnings, - }) { + factory PackModel.fromMap(Map map, {List? warnings}) { final PackModel pack = PackModel( name: _requiredString(map, 'name'), version: _requiredString(map, 'version'), @@ -106,42 +77,27 @@ class PackModel { sourceVersion: _optionalSourceVersion(map), ); - pack.files.addAll([ - for (final Map item in _mapList(map, 'files')) - FileModel.fromMap(item), - ]); + pack.files.addAll( + [for (final Map item in _mapList(map, 'files')) FileModel.fromMap(item)]); pack.dependencies.addAll([ - for (final Map item in _mapList(map, 'dependencies')) - DependencyModel.fromMap(item), - ]); - pack.commands.addAll([ - for (final Map item in _mapList(map, 'commands')) - CmdModel.fromMap(item), - ]); - pack.macros.addAll([ - for (final Map item in _mapList(map, 'macros')) - MacroModel.fromMap(item), + for (final Map item in _mapList(map, 'dependencies')) DependencyModel.fromMap(item) ]); + pack.commands.addAll( + [for (final Map item in _mapList(map, 'commands')) CmdModel.fromMap(item)]); + pack.macros.addAll( + [for (final Map item in _mapList(map, 'macros')) MacroModel.fromMap(item)]); pack.libDirectories.addAll([ - for (final Map item in _mapList(map, 'libDirectories')) - LibDirModel.fromMap(item), - ]); - pack.libraries.addAll([ - for (final Map item in _mapList(map, 'libraries')) - LibraryModel.fromMap(item), - ]); - pack.history.addAll([ - for (final Map item in _mapList(map, 'history')) - HistoryModel.fromMap(item), + for (final Map item in _mapList(map, 'libDirectories')) LibDirModel.fromMap(item) ]); + pack.libraries.addAll( + [for (final Map item in _mapList(map, 'libraries')) LibraryModel.fromMap(item)]); + pack.history.addAll( + [for (final Map item in _mapList(map, 'history')) HistoryModel.fromMap(item)]); final Set scriptIds = {}; for (final Map item in _mapList(map, 'scripts')) { try { - final ScriptProjectModel script = ScriptProjectModel.fromMap( - item, - warnings: warnings, - ); + final ScriptProjectModel script = ScriptProjectModel.fromMap(item, warnings: warnings); if (!scriptIds.add(script.id)) { warnings?.add('脚本 id 重复,已丢弃:${script.id}'); continue; @@ -189,8 +145,7 @@ Map _stringStringMap(Map map, String key) { } return { for (final MapEntry entry in value.entries) - if (entry.key is String && entry.value is String) - entry.key as String: entry.value as String, + if (entry.key is String && entry.value is String) entry.key as String: entry.value as String, }; } diff --git a/lib/pages/about.dart b/lib/pages/about.dart index 066a962..eca12b2 100644 --- a/lib/pages/about.dart +++ b/lib/pages/about.dart @@ -34,56 +34,53 @@ class _AboutState extends State { final Color secondaryColor = theme.resources.textFillColorSecondary; return SizedBox.expand( key: const Key('aboutPage'), - child: Container( - decoration: BoxDecoration(color: theme.cardColor), - child: Center( - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SvgPicture.asset( - 'assets/icons/cardboard_box.svg', - width: 64, - height: 64, + child: Center( + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset( + 'assets/icons/cardboard_box.svg', + width: 64, + height: 64, + ), + const SizedBox(height: 16), + Text( + appName, + style: theme.typography.titleLarge?.copyWith( + fontWeight: FontWeight.w600, ), - const SizedBox(height: 16), - Text( - appName, - style: theme.typography.titleLarge?.copyWith( - fontWeight: FontWeight.w600, - ), + ), + const SizedBox(height: 8), + Tag(text: 'v$appVersion', fontSize: 11), + const SizedBox(height: 16), + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 420), + child: Text( + appDescription, + textAlign: TextAlign.center, + style: TextStyle(color: secondaryColor), ), - const SizedBox(height: 8), - Tag(text: 'v$appVersion', fontSize: 11), - const SizedBox(height: 16), - ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 420), - child: Text( - appDescription, - textAlign: TextAlign.center, - style: TextStyle(color: secondaryColor), - ), + ), + const SizedBox(height: 24), + FilledButton( + key: const Key('aboutRepoButton'), + onPressed: _openRepository, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Svgs.openBox, + const SizedBox(width: 8), + const Text('项目主页'), + ], ), - const SizedBox(height: 24), - FilledButton( - key: const Key('aboutRepoButton'), - onPressed: _openRepository, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Svgs.openBox, - const SizedBox(width: 8), - const Text('项目主页'), - ], - ), - ), - const SizedBox(height: 24), - Text( - '第三方组件许可见仓库 THIRD_PARTY_NOTICES.md', - style: TextStyle(color: secondaryColor, fontSize: 12), - ), - ], - ), + ), + const SizedBox(height: 24), + Text( + '第三方组件许可见仓库 THIRD_PARTY_NOTICES.md', + style: TextStyle(color: secondaryColor, fontSize: 12), + ), + ], ), ), ), diff --git a/lib/pages/pack_compile_settings.dart b/lib/pages/pack_compile_settings.dart index 46ac64d..0423121 100644 --- a/lib/pages/pack_compile_settings.dart +++ b/lib/pages/pack_compile_settings.dart @@ -45,11 +45,7 @@ class _PackCompileSettingsState extends State { bool _saving = false; Future _addMacro() async { - final CompileEntryResult? result = await _openEntryDialog( - title: '添加宏定义', - label: '宏定义', - hintText: 'MY_MACRO=1', - ); + final CompileEntryResult? result = await _openEntryDialog(title: '添加宏定义', label: '宏定义', hintText: 'MY_MACRO=1'); if (result == null || !mounted) { return; } @@ -82,10 +78,7 @@ class _PackCompileSettingsState extends State { pack, macros: [ for (int i = 0; i < pack.macros.length; i++) - if (i == index) - MacroModel(value: result.text, buildModel: result.buildModel) - else - pack.macros[i], + if (i == index) MacroModel(value: result.text, buildModel: result.buildModel) else pack.macros[i], ], ), '已保存', @@ -121,11 +114,7 @@ class _PackCompileSettingsState extends State { pack, commands: [ ...pack.commands, - CmdModel( - command: result.text, - type: type, - buildModel: result.buildModel, - ), + CmdModel(command: result.text, type: type, buildModel: result.buildModel), ], ), '已添加', @@ -152,11 +141,7 @@ class _PackCompileSettingsState extends State { commands: [ for (int i = 0; i < pack.commands.length; i++) if (i == index) - CmdModel( - command: result.text, - type: command.type, - buildModel: result.buildModel, - ) + CmdModel(command: result.text, type: command.type, buildModel: result.buildModel) else pack.commands[i], ], @@ -218,10 +203,7 @@ class _PackCompileSettingsState extends State { pack, libDirectories: [ for (int i = 0; i < pack.libDirectories.length; i++) - if (i == index) - LibDirModel(path: result.text, buildModel: result.buildModel) - else - pack.libDirectories[i], + if (i == index) LibDirModel(path: result.text, buildModel: result.buildModel) else pack.libDirectories[i], ], ), '已保存', @@ -242,11 +224,7 @@ class _PackCompileSettingsState extends State { } Future _addLibrary() async { - final CompileEntryResult? result = await _openEntryDialog( - title: '添加附加库', - label: '库名称', - hintText: 'mylib.lib', - ); + final CompileEntryResult? result = await _openEntryDialog(title: '添加附加库', label: '库名称', hintText: 'mylib.lib'); if (result == null || !mounted) { return; } @@ -279,10 +257,7 @@ class _PackCompileSettingsState extends State { pack, libraries: [ for (int i = 0; i < pack.libraries.length; i++) - if (i == index) - LibraryModel(name: result.text, buildModel: result.buildModel) - else - pack.libraries[i], + if (i == index) LibraryModel(name: result.text, buildModel: result.buildModel) else pack.libraries[i], ], ), '已保存', @@ -335,10 +310,7 @@ class _PackCompileSettingsState extends State { ]; } - Future _persist( - PackModel Function(PackModel pack) update, - String message, - ) async { + Future _persist(PackModel Function(PackModel pack) update, String message) async { if (_saving) { return; } @@ -450,11 +422,13 @@ class _PackCompileSettingsState extends State { Widget build(BuildContext context) { return SizedBox.expand( child: Padding( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + Divider(), + SizedBox(height: 5), _buildSection( title: '宏定义', columnLabel: '宏定义', @@ -518,14 +492,8 @@ class _PackCompileSettingsState extends State { }) { return _buildSectionFrame( title: title, - action: FilledButton( - key: addKey, - onPressed: _saving ? null : onAdd, - child: const Text('添加'), - ), - body: entries.isEmpty - ? _buildEmptyText(emptyText) - : _buildEntryList(entries, columnLabel), + action: Button(key: addKey, onPressed: _saving ? null : onAdd, child: const Text('添加')), + body: _buildEntryList(entries, columnLabel), ); } @@ -534,62 +502,52 @@ class _PackCompileSettingsState extends State { return _buildSectionFrame( sectionKey: const Key('nodeScriptsSection'), title: '节点脚本', - action: FilledButton( + action: Button( key: const Key('openScriptEditorButton'), onPressed: _saving ? null : _openScriptEditor, child: const Text('打开节点编辑器'), ), - body: scripts.isEmpty - ? _buildEmptyText('暂无节点脚本') - : _buildScriptList(scripts), + body: _buildScriptList(scripts), ); } - Widget _buildSectionFrame({ - required String title, - required Widget action, - required Widget body, - Key? sectionKey, - }) { + Widget _buildSectionFrame({required String title, required Widget action, required Widget body, Key? sectionKey}) { return Column( - key: sectionKey, - crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Expanded( - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: FluentTheme.of(context).typography.body?.color, - ), + Padding( + padding: .fromLTRB(0, 8, 0, 0), + child: Column( + key: sectionKey, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Text( + title, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: FluentTheme.of(context).typography.body?.color, + ), + ), + ), + action, + ], ), - ), - action, - ], + ], + ), ), - const SizedBox(height: 4), + SizedBox(height: 5), body, ], ); } - Widget _buildEmptyText(String text) { - return Text( - text, - style: TextStyle( - color: FluentTheme.of(context).resources.textFillColorSecondary, - ), - ); - } - void _openScriptEditor() { Navigator.of(context).push( FluentPageRoute( - builder: (_) => - ScriptEditorPage(pack: widget.pack, onSave: widget.onSave), + builder: (_) => ScriptEditorPage(pack: widget.pack, onSave: widget.onSave), ), ); } @@ -597,17 +555,16 @@ class _PackCompileSettingsState extends State { Widget _buildScriptList(List scripts) { return _buildTable( header: _buildScriptHeaderRow(), - rows: [ - for (final ScriptProjectModel script in scripts) - _buildScriptRow(script), - ], + rows: scripts.isEmpty + ? [SizedBox.shrink()] + : [for (final ScriptProjectModel script in scripts) _buildScriptRow(script)], ); } Widget _buildScriptHeaderRow() { final TextStyle style = _headerTextStyle(); - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), + return Card( + margin: const .fromLTRB(0, 0, 0, 2), child: Row( children: [ Expanded(child: Text('名称', style: style)), @@ -630,8 +587,9 @@ class _PackCompileSettingsState extends State { Widget _buildScriptRow(ScriptProjectModel script) { final (String statusText, Color statusColor) = _scriptStatus(script); - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), + return Card( + margin: const .fromLTRB(0, 0, 0, 2), + padding: const .fromLTRB(8, 8, 8, 8), child: Row( children: [ Expanded(child: Text(script.name, overflow: TextOverflow.ellipsis)), @@ -658,10 +616,7 @@ class _PackCompileSettingsState extends State { SizedBox( width: _statusColumnWidth, child: Center( - child: Text( - statusText, - style: TextStyle(fontSize: 12, color: statusColor), - ), + child: Text(statusText, style: TextStyle(fontSize: 12, color: statusColor)), ), ), ], @@ -672,9 +627,7 @@ class _PackCompileSettingsState extends State { (String, Color) _scriptStatus(ScriptProjectModel script) { final Brightness brightness = FluentTheme.of(context).brightness; final List diagnostics = GraphValidator.validate(script); - final int errors = diagnostics - .where((ScriptDiagnostic diagnostic) => diagnostic.isError) - .length; + final int errors = diagnostics.where((ScriptDiagnostic diagnostic) => diagnostic.isError).length; final int warnings = diagnostics.length - errors; if (errors > 0) { return ('$errors 个错误', AppColors.critical(brightness)); @@ -688,42 +641,21 @@ class _PackCompileSettingsState extends State { Widget _buildEntryList(List<_CompileEntry> entries, String columnLabel) { return _buildTable( header: _buildHeaderRow(columnLabel), - rows: [ - for (final _CompileEntry entry in entries) _buildEntryRow(entry), - ], + rows: entries.isEmpty + ? [SizedBox.shrink()] + : [for (final _CompileEntry entry in entries) _buildEntryRow(entry)], ); } Widget _buildTable({required Widget header, required List rows}) { - final FluentThemeData theme = FluentTheme.of(context); - final DividerThemeData dividerTheme = theme.dividerTheme; - return FluentTheme( - data: theme.copyWith( - // 全局分割线自带 8px 水平边距,覆盖为 0 使线与列表内容同宽 - dividerTheme: DividerThemeData( - decoration: dividerTheme.decoration, - verticalMargin: dividerTheme.verticalMargin, - horizontalMargin: EdgeInsets.zero, - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - header, - const Divider(), - for (int index = 0; index < rows.length; index++) ...[ - if (index > 0) const Divider(), - rows[index], - ], - ], - ), - ); + return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [header, ...rows]); } Widget _buildHeaderRow(String columnLabel) { final TextStyle style = _headerTextStyle(); - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), + return Card( + margin: const .fromLTRB(0, 0, 0, 2), + padding: const .fromLTRB(8, 8, 8, 8), child: Row( children: [ Expanded(child: Text(columnLabel, style: style)), @@ -741,30 +673,24 @@ class _PackCompileSettingsState extends State { } TextStyle _headerTextStyle() { - return TextStyle( - fontSize: 12, - color: FluentTheme.of(context).resources.textFillColorSecondary, - ); + return TextStyle(fontSize: 12, color: FluentTheme.of(context).resources.textFillColorSecondary); } Widget _buildEntryRow(_CompileEntry entry) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), + return Card( + margin: const .fromLTRB(0, 0, 0, 2), + padding: const .fromLTRB(8, 2, 8, 2), child: Row( children: [ Expanded( child: Row( children: [ - Flexible( - child: Text(entry.text, overflow: TextOverflow.ellipsis), - ), + Flexible(child: Text(entry.text, overflow: TextOverflow.ellipsis)), if (entry.isSystem) ...[ const SizedBox(width: 5), Tag( text: '系统', - color: FluentTheme.of( - context, - ).resources.solidBackgroundFillColorQuarternary, + color: FluentTheme.of(context).resources.solidBackgroundFillColorQuarternary, fontSize: 10, ), ], @@ -794,14 +720,13 @@ class _PackCompileSettingsState extends State { onPressed: _saving || entry.isSystem ? null : entry.onEdit, ), ), + SizedBox(width: 2), Tooltip( message: entry.isSystem ? _systemLockTooltip : '删除', child: IconButton( key: entry.deleteKey, icon: const Icon(FluentIcons.delete, size: 16), - onPressed: _saving || entry.isSystem - ? null - : entry.onDelete, + onPressed: _saving || entry.isSystem ? null : entry.onDelete, ), ), ], diff --git a/lib/pages/pack_dependencies.dart b/lib/pages/pack_dependencies.dart index 4df3655..9c346c1 100644 --- a/lib/pages/pack_dependencies.dart +++ b/lib/pages/pack_dependencies.dart @@ -12,12 +12,7 @@ const double _actionColumnWidth = 80; const String _systemLockTooltip = '由构建管线注册,禁止修改/删除'; class PackDependencies extends StatefulWidget { - const PackDependencies({ - super.key, - required this.pack, - required this.allPacks, - required this.onSave, - }); + const PackDependencies({super.key, required this.pack, required this.allPacks, required this.onSave}); final PackModel pack; final List allPacks; @@ -33,14 +28,11 @@ class _PackDependenciesState extends State { List get _candidates { final String self = widget.pack.name.toLowerCase(); final Set added = { - for (final DependencyModel dependency in widget.pack.dependencies) - dependency.name.toLowerCase(), + for (final DependencyModel dependency in widget.pack.dependencies) dependency.name.toLowerCase(), }; return [ for (final PackModel pack in widget.allPacks) - if (pack.name.toLowerCase() != self && - !added.contains(pack.name.toLowerCase())) - pack, + if (pack.name.toLowerCase() != self && !added.contains(pack.name.toLowerCase())) pack, ]; } @@ -52,10 +44,7 @@ class _PackDependenciesState extends State { if (result == null || !mounted) { return; } - await _persist([ - ...widget.pack.dependencies, - result, - ], '已添加'); + await _persist([...widget.pack.dependencies, result], '已添加'); } Future _edit(DependencyModel dependency) async { @@ -68,9 +57,7 @@ class _PackDependenciesState extends State { } final List updated = [ for (final DependencyModel item in widget.pack.dependencies) - item.name.toLowerCase() == dependency.name.toLowerCase() - ? result - : item, + item.name.toLowerCase() == dependency.name.toLowerCase() ? result : item, ]; await _persist(updated, '已保存'); } @@ -83,10 +70,7 @@ class _PackDependenciesState extends State { await _persist(updated, '已删除'); } - Future _persist( - List dependencies, - String message, - ) async { + Future _persist(List dependencies, String message) async { if (_saving) { return; } @@ -106,21 +90,29 @@ class _PackDependenciesState extends State { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - FilledButton( - key: const Key('addDependencyButton'), - onPressed: _saving ? null : _add, - child: const Text('添加依赖'), - ), - const SizedBox(height: 12), - Expanded( - child: widget.pack.dependencies.isEmpty - ? _buildEmptyGuide() - : _buildDependencyList(), + Divider(), + Padding( + padding: const EdgeInsets.fromLTRB(8, 5, 8, 0), + child: Row( + children: [ + Button( + key: const Key('addDependencyButton'), + onPressed: _saving ? null : _add, + child: const Row( + mainAxisSize: .min, + children: [Icon(FluentIcons.add), SizedBox(width: 5), Text('添加依赖')], + ), + ), + Spacer(), + ], + ), ), + const SizedBox(height: 5), + Expanded(child: widget.pack.dependencies.isEmpty ? _buildEmptyGuide() : _buildDependencyList()), ], ), ); @@ -129,143 +121,112 @@ class _PackDependenciesState extends State { Widget _buildDependencyList() { final FluentThemeData theme = FluentTheme.of(context); final DividerThemeData dividerTheme = theme.dividerTheme; - return FluentTheme( - data: theme.copyWith( - // 全局分割线自带 8px 水平边距,覆盖为 0 使线与列表内容同宽 - dividerTheme: DividerThemeData( - decoration: dividerTheme.decoration, - verticalMargin: dividerTheme.verticalMargin, - horizontalMargin: EdgeInsets.zero, - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildHeaderRow(), - const Divider(), - Expanded( - child: ListView.separated( - itemCount: widget.pack.dependencies.length, - separatorBuilder: (BuildContext context, int index) => - const Divider(), - itemBuilder: (BuildContext context, int index) => - _buildRow(context, widget.pack.dependencies[index]), - ), + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildHeaderRow(), + Expanded( + child: ListView.builder( + itemCount: widget.pack.dependencies.length, + itemBuilder: (BuildContext context, int index) => _buildRow(context, widget.pack.dependencies[index]), ), - ], - ), + ), + ], ); } Widget _buildHeaderRow() { - final TextStyle style = TextStyle( - fontSize: 12, - color: FluentTheme.of(context).resources.textFillColorSecondary, - ); + final TextStyle style = TextStyle(fontSize: 12, color: FluentTheme.of(context).resources.textFillColorSecondary); return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: Row( - children: [ - Expanded(child: Text('包名', style: style)), - SizedBox( - width: _versionColumnWidth, - child: Text('版本范围', style: style), - ), - SizedBox( - width: _actionColumnWidth, - child: Text('操作', style: style, textAlign: TextAlign.center), - ), - ], + padding: const EdgeInsets.fromLTRB(8, 0, 8, 2), + child: Card( + child: Row( + children: [ + Expanded(child: Text('包名', style: style)), + SizedBox( + width: _versionColumnWidth, + child: Text('版本范围', style: style), + ), + SizedBox( + width: _actionColumnWidth, + child: Text('操作', style: style, textAlign: TextAlign.center), + ), + ], + ), ), ); } Widget _buildEmptyGuide() { return const Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [Text('暂无依赖'), SizedBox(height: 6), Text('点击「添加依赖」开始')], - ), + child: Column(mainAxisSize: MainAxisSize.min, children: [Text('暂无依赖'), SizedBox(height: 6), Text('点击「添加依赖」开始')]), ); } Widget _buildRow(BuildContext context, DependencyModel dependency) { final FluentThemeData theme = FluentTheme.of(context); final bool missing = !widget.allPacks.any( - (PackModel pack) => - pack.name.toLowerCase() == dependency.name.toLowerCase(), + (PackModel pack) => pack.name.toLowerCase() == dependency.name.toLowerCase(), ); return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: Row( - children: [ - Expanded( - child: Row( - children: [ - Flexible( - child: Text(dependency.name, overflow: TextOverflow.ellipsis), - ), - if (dependency.system) ...[ - const SizedBox(width: 5), - Tag( - text: '系统', - color: theme.resources.solidBackgroundFillColorQuarternary, - fontSize: 10, - ), + padding: const EdgeInsets.fromLTRB(8, 2, 8, 2), + child: Card( + padding: EdgeInsetsGeometry.fromLTRB(8, 2, 8, 2), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + Flexible(child: Text(dependency.name, overflow: TextOverflow.ellipsis)), + if (dependency.system) ...[ + const SizedBox(width: 5), + Tag(text: '系统', color: theme.resources.solidBackgroundFillColorQuarternary, fontSize: 10), + ], + if (missing) ...[const SizedBox(width: 5), Tag(text: '缺失', color: MarkerColors.red, fontSize: 10)], ], - if (missing) ...[ - const SizedBox(width: 5), - Tag(text: '缺失', color: MarkerColors.red, fontSize: 10), - ], - ], + ), ), - ), - SizedBox( - width: _versionColumnWidth, - child: Text( - dependency.version, - overflow: TextOverflow.ellipsis, - style: TextStyle(color: theme.resources.textFillColorSecondary), + SizedBox( + width: _versionColumnWidth, + child: Text( + dependency.version, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: theme.resources.textFillColorSecondary), + ), ), - ), - SizedBox( - width: _actionColumnWidth, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Tooltip( - message: dependency.system ? _systemLockTooltip : '编辑', - child: IconButton( - key: Key('dependencyEditButton_${dependency.name}'), - icon: const Icon(FluentIcons.edit, size: 16), - onPressed: _saving || dependency.system - ? null - : () => _edit(dependency), + SizedBox( + width: _actionColumnWidth, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Tooltip( + message: dependency.system ? _systemLockTooltip : '编辑', + child: IconButton( + key: Key('dependencyEditButton_${dependency.name}'), + icon: const Icon(FluentIcons.edit, size: 16), + onPressed: _saving || dependency.system ? null : () => _edit(dependency), + ), ), - ), - Tooltip( - message: dependency.system ? _systemLockTooltip : '删除', - child: IconButton( - key: Key('dependencyDeleteButton_${dependency.name}'), - icon: const Icon(FluentIcons.delete, size: 16), - onPressed: _saving || dependency.system - ? null - : () => _remove(dependency), + SizedBox(width: 3), + Tooltip( + message: dependency.system ? _systemLockTooltip : '删除', + child: IconButton( + key: Key('dependencyDeleteButton_${dependency.name}'), + icon: const Icon(FluentIcons.delete, size: 16), + onPressed: _saving || dependency.system ? null : () => _remove(dependency), + ), ), - ), - ], + ], + ), ), - ), - ], + ], + ), ), ); } } -PackModel _withDependencies( - PackModel pack, - List dependencies, -) { +PackModel _withDependencies(PackModel pack, List dependencies) { return PackModel( name: pack.name, version: pack.version, diff --git a/lib/pages/pack_files.dart b/lib/pages/pack_files.dart index 6a0838b..ec52c3e 100644 --- a/lib/pages/pack_files.dart +++ b/lib/pages/pack_files.dart @@ -49,6 +49,7 @@ class PackFiles extends StatefulWidget { class _PackFilesState extends State { static const double _treeIconSize = 18; + // TreeView 行内容原有效高度 18,按用户确认加高 8 后为 26(行容器另加 4)。 static const double _treeRowContentMinHeight = 26; static const Set _buildLabelTypes = { @@ -56,6 +57,7 @@ class _PackFilesState extends State { FileType.dll, FileType.pdb, FileType.executable, + FileType.source }; static final RegExp _pathSeparator = RegExp(r'[/\\]'); @@ -90,8 +92,7 @@ class _PackFilesState extends State { if (before.name != after.name || before.sourcePath != after.sourcePath) { return true; } - return findBuildScript(before.files)?.path != - findBuildScript(after.files)?.path; + return findBuildScript(before.files)?.path != findBuildScript(after.files)?.path; } Future _refreshHeader() async { @@ -112,8 +113,7 @@ class _PackFilesState extends State { Future _refreshLatestVersion() async { final String? repo = _header?.repo; - final Future Function(String repoUrl)? loader = - widget.loadLatestVersion; + final Future Function(String repoUrl)? loader = widget.loadLatestVersion; final int loadId = ++_latestLoadId; if (repo == null) { setState(() { @@ -148,10 +148,8 @@ class _PackFilesState extends State { }); } - static List _pathSegments(String path) => path - .split(_pathSeparator) - .where((String segment) => segment.isNotEmpty) - .toList(); + static List _pathSegments(String path) => + path.split(_pathSeparator).where((String segment) => segment.isNotEmpty).toList(); static int _compareNames(String first, String second) { final int insensitive = first.toLowerCase().compareTo(second.toLowerCase()); @@ -171,13 +169,8 @@ class _PackFilesState extends State { } _DirNode parent = root; for (final String segment in segments.take(segments.length - 1)) { - final String childPath = parent.path.isEmpty - ? segment - : '${parent.path}/$segment'; - parent = parent.children.putIfAbsent( - segment, - () => _DirNode(name: segment, path: childPath), - ); + final String childPath = parent.path.isEmpty ? segment : '${parent.path}/$segment'; + parent = parent.children.putIfAbsent(segment, () => _DirNode(name: segment, path: childPath)); parent.size += file.size; parent.fileCount += 1; } @@ -189,51 +182,33 @@ class _PackFilesState extends State { List _buildTreeItems(_DirNode node, Color sizeColor) { final List items = []; final List<_DirNode> dirs = node.children.values.toList() - ..sort( - (_DirNode first, _DirNode second) => - _compareNames(first.name, second.name), - ); + ..sort((_DirNode first, _DirNode second) => _compareNames(first.name, second.name)); for (final _DirNode dir in dirs) { final bool expanded = _expandedDirs.contains(dir.path); items.add( TreeViewItem( value: dir.path, - leading: _buildIcon( - dir.name, - isDirectory: true, - isExpanded: expanded, - ), + leading: _buildIcon(dir.name, isDirectory: true, isExpanded: expanded), expanded: expanded, content: _buildRow( dir.name, formatBytes(dir.size), sizeColor, - label: Text( - '(${dir.fileCount} 个文件)', - style: TextStyle(color: sizeColor), - ), + label: Text('(${dir.fileCount} 个文件)', style: TextStyle(color: sizeColor)), ), children: _buildTreeItems(dir, sizeColor), ), ); } final List files = node.files.toList() - ..sort( - (FileModel first, FileModel second) => - _compareNames(first.name, second.name), - ); + ..sort((FileModel first, FileModel second) => _compareNames(first.name, second.name)); for (final FileModel file in files) { items.add( TreeViewItem( leading: _buildIcon(file.name), content: GestureDetector( onDoubleTap: () => _openFile(file), - child: _buildRow( - file.name, - formatBytes(file.size), - sizeColor, - label: _buildBuildLabel(file), - ), + child: _buildRow(file.name, formatBytes(file.size), sizeColor, label: _buildBuildLabel(file)), ), ), ); @@ -241,29 +216,17 @@ class _PackFilesState extends State { return items; } - Widget _buildIcon( - String name, { - bool isDirectory = false, - bool isExpanded = false, - }) { + Widget _buildIcon(String name, {bool isDirectory = false, bool isExpanded = false}) { return SvgPicture.asset( - iconAssetFor( - brightness: FluentTheme.of(context).brightness, - name: name, - isDirectory: isDirectory, - isExpanded: isExpanded, - ), + iconAssetFor(brightness: FluentTheme + .of(context) + .brightness, name: name, isDirectory: isDirectory, isExpanded: isExpanded), width: _treeIconSize, height: _treeIconSize, ); } - static Widget _buildRow( - String name, - String size, - Color sizeColor, { - Widget? label, - }) { + static Widget _buildRow(String name, String size, Color sizeColor, {Widget? label}) { final Widget nameText = Text(name, overflow: TextOverflow.ellipsis); return ConstrainedBox( constraints: const BoxConstraints(minHeight: _treeRowContentMinHeight), @@ -283,6 +246,7 @@ class _PackFilesState extends State { ), const SizedBox(width: 8), Text(size, style: TextStyle(color: sizeColor)), + const SizedBox(width: 16), ], ), ); @@ -296,24 +260,14 @@ class _PackFilesState extends State { if (label == null) { return null; } - return Tag( - text: label, - color: label == releaseBuildLabel - ? MarkerColors.green - : MarkerColors.orange, - fontSize: 10, - ); + return Tag(text: label, color: label == releaseBuildLabel ? MarkerColors.green : MarkerColors.orange, fontSize: 10); } Future _openFile(FileModel file) async { final String? sourcePath = widget.pack.sourcePath; if (sourcePath == null) { - showFloatingToast( - context, - '该包缺少源目录信息,无法打开文件', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + showFloatingToast(context, '该包缺少源目录信息,无法打开文件', type: FloatingToastType.error, + duration: const Duration(seconds: 5)); return; } final bool opened = await widget.openFile(joinPath(sourcePath, file.path)); @@ -322,18 +276,11 @@ class _PackFilesState extends State { } if (!opened) { showFloatingToast( - context, - '无法打开文件:${file.name}', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + context, '无法打开文件:${file.name}', type: FloatingToastType.error, duration: const Duration(seconds: 5)); } } - Future _onItemInvoked( - TreeViewItem item, - TreeViewItemInvokeReason reason, - ) async { + Future _onItemInvoked(TreeViewItem item, TreeViewItemInvokeReason reason) async { if (reason != TreeViewItemInvokeReason.pressed) { return; } @@ -360,28 +307,29 @@ class _PackFilesState extends State { } } - Widget _buildToolbar({ - required String? openRepoUrl, - required bool canBuild, - required bool showVersionChip, - }) { + Widget _buildToolbar({required String? openRepoUrl, required bool canBuild, required bool showVersionChip}) { return Padding( - padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), - child: Wrap( - spacing: 16, - runSpacing: 8, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - if (openRepoUrl != null) _buildOpenRepoButton(openRepoUrl), - if (canBuild) - FilledButton( - key: const Key('buildPackButton'), - onPressed: () => widget.onBuildPack!(widget.pack), - child: const Text('构建'), + padding: const EdgeInsets.fromLTRB(8, 3, 8, 0), + child: Card( + padding: EdgeInsetsGeometry.all(5), + child: Row( + children: [ + Wrap( + spacing: 5, + runSpacing: 0, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + if (canBuild) FilledButton(key: const Key('buildPackButton'), + onPressed: () => widget.onBuildPack!(widget.pack), + child: const Text('构建')), + if (openRepoUrl != null) _buildOpenRepoButton(openRepoUrl), + if (canBuild) _buildRuntimeGroup(), + ], ), - if (canBuild) _buildRuntimeGroup(), - if (showVersionChip) _buildVersionChip(), - ], + Spacer(), + if (showVersionChip) ...[_buildVersionChip()], + ], + ), ), ); } @@ -389,18 +337,7 @@ class _PackFilesState extends State { Widget _buildOpenRepoButton(String url) { return Tooltip( message: url, - child: Button( - key: const Key('openRepoButton'), - onPressed: () => _openRepo(url), - child: const Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(FluentIcons.open_in_new_window, size: 14), - SizedBox(width: 6), - Text('打开远程仓库'), - ], - ), - ), + child: Button(key: const Key('openRepoButton'), onPressed: () => _openRepo(url), child: Text('远程仓库')), ); } @@ -410,12 +347,7 @@ class _PackFilesState extends State { return; } if (!opened) { - showFloatingToast( - context, - '无法打开链接', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + showFloatingToast(context, '无法打开链接', type: FloatingToastType.error, duration: const Duration(seconds: 5)); } } @@ -424,14 +356,6 @@ class _PackFilesState extends State { return Row( mainAxisSize: MainAxisSize.min, children: [ - Text( - '运行库', - style: TextStyle( - fontSize: 12, - color: FluentTheme.of(context).resources.textFillColorSecondary, - ), - ), - const SizedBox(width: 8), RuntimeLibrarySelector( value: runtimeValue, enabled: widget.onSave != null && !_savingOption, @@ -441,30 +365,23 @@ class _PackFilesState extends State { } }, ), - const SizedBox(width: 6), - const RuntimeLibraryHelpButton(), ], ); } /// 运行库保存值(`MD` / `MT` 大写归一);缺失或非法显示「默认(跟随配方)」。 String? _savedRuntimeLibrary() { - final String? normalized = normalizeRuntimeLibrary( - widget.pack.buildOptions[runtimeOptionName], - ); + final String? normalized = normalizeRuntimeLibrary(widget.pack.buildOptions[runtimeOptionName]); return normalized?.toUpperCase(); } /// 版本胶囊:纯展示(不可点击、不参与 Tab 序),四态见设计规格 §5.3。 Widget _buildVersionChip() { - final String current = widget.pack.sourceVersion ?? '—'; + final String current = widget.pack.sourceVersion ?? '不可用'; final bool querying = !_latestLoaded; final String? latestVersion = _latestVersion; - final String latestText = querying ? '查询中…' : (latestVersion ?? '—'); - final bool hasUpdate = - !querying && - latestVersion != null && - compareTagVersions(latestVersion, current) > 0; + final String latestText = querying ? '查询中…' : (latestVersion ?? '不可用'); + final bool hasUpdate = !querying && latestVersion != null && compareTagVersions(latestVersion, current) > 0; final String latestTooltip; if (querying) { latestTooltip = '最新版本:查询中…'; @@ -473,65 +390,38 @@ class _PackFilesState extends State { } else if (latestVersion != null) { latestTooltip = '最新版本:$latestText(已是最新)'; } else { - latestTooltip = '最新版本:—'; + latestTooltip = '最新版本:不可用'; } final FluentThemeData theme = FluentTheme.of(context); final Color valueColor = theme.resources.textFillColorPrimary; final Color placeholderColor = theme.resources.textFillColorTertiary; - final TextStyle labelStyle = TextStyle( - fontSize: 12, - color: theme.resources.textFillColorSecondary, - ); + final TextStyle labelStyle = TextStyle(fontSize: 12, color: theme.resources.textFillColorSecondary); return Container( key: const Key('packRepoVersionLabel'), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), decoration: BoxDecoration( - color: theme.resources.solidBackgroundFillColorQuarternary, - borderRadius: BorderRadius.circular(999), - ), + color: theme.resources.solidBackgroundFillColorSecondary, borderRadius: BorderRadius.circular(999)), child: Tooltip( message: '当前版本:$current\n$latestTooltip', child: Row( mainAxisSize: MainAxisSize.min, children: [ if (hasUpdate) ...[ - const Icon( - FluentIcons.update_restore, - size: 12, - color: MarkerColors.green, - ), - const SizedBox(width: 6), + const Icon(FluentIcons.update_restore, size: 12, color: MarkerColors.green), + const SizedBox(width: 6) ], Text('当前', style: labelStyle), const SizedBox(width: 4), - Text( - current, - style: TextStyle( - fontSize: 12, - color: widget.pack.sourceVersion == null - ? placeholderColor - : valueColor, - ), - ), + Text(current, style: TextStyle( + fontSize: 12, color: widget.pack.sourceVersion == null ? placeholderColor : valueColor)), Padding( padding: const EdgeInsets.symmetric(horizontal: 8), - child: Icon( - FluentIcons.chevron_right, - size: 12, - color: placeholderColor, - ), + child: Icon(FluentIcons.chevron_right, size: 12, color: placeholderColor), ), Text('最新', style: labelStyle), const SizedBox(width: 4), - Text( - latestText, - style: TextStyle( - fontSize: 12, - color: querying || latestVersion == null - ? placeholderColor - : valueColor, - ), - ), + Text(latestText, style: TextStyle( + fontSize: 12, color: querying || latestVersion == null ? placeholderColor : valueColor)), ], ), ), @@ -560,60 +450,44 @@ class _PackFilesState extends State { if (saved) { showFloatingToast(context, '已保存'); } else { - showFloatingToast( - context, - '保存失败', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + showFloatingToast(context, '保存失败', type: FloatingToastType.error, duration: const Duration(seconds: 5)); } } @override Widget build(BuildContext context) { - final bool canBuild = - widget.onBuildPack != null && - findBuildScript(widget.pack.files) != null; + final bool canBuild = widget.onBuildPack != null && findBuildScript(widget.pack.files) != null; final String? openRepoUrl = openableRepoWebUrl(_header?.repo ?? ''); final bool showVersionChip = _header?.repo != null; - final List options = canBuild && widget.onSave != null - ? (_header?.options ?? const []) - : const []; - final Color sizeColor = FluentTheme.of(context) + final List options = canBuild && widget.onSave != null ? (_header?.options ?? + const []) : const []; + final Color sizeColor = FluentTheme + .of(context) .resources .textFillColorSecondary; return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - if (openRepoUrl != null || canBuild || showVersionChip) - _buildToolbar( - openRepoUrl: openRepoUrl, - canBuild: canBuild, - showVersionChip: showVersionChip, - ), + Divider(), + if (openRepoUrl != null || canBuild || showVersionChip) _buildToolbar( + openRepoUrl: openRepoUrl, canBuild: canBuild, showVersionChip: showVersionChip), if (options.isNotEmpty) BuildOptionsPanel( options: options, values: widget.pack.buildOptions, expanded: _optionsExpanded, - onToggleExpanded: () => - setState(() => _optionsExpanded = !_optionsExpanded), + onToggleExpanded: () => setState(() => _optionsExpanded = !_optionsExpanded), saving: _savingOption, onChange: _changeBuildOption, ), Expanded( child: widget.pack.files.isEmpty ? const Center(child: Text('该包暂无文件')) - : TreeView( - items: _buildTreeItems( - _buildTree(widget.pack.files), - sizeColor, - ), - onItemInvoked: _onItemInvoked, - onItemExpandToggle: _onExpandToggle, - shrinkWrap: false, - scrollPrimary: false, - ), + : TreeView(items: _buildTreeItems(_buildTree(widget.pack.files), sizeColor), + onItemInvoked: _onItemInvoked, + onItemExpandToggle: _onExpandToggle, + shrinkWrap: false, + scrollPrimary: false), ), ], ); diff --git a/lib/pages/pack_packaging.dart b/lib/pages/pack_packaging.dart index adb50f2..1672c99 100644 --- a/lib/pages/pack_packaging.dart +++ b/lib/pages/pack_packaging.dart @@ -43,11 +43,7 @@ class _PackPackagingState extends State { if (widget.builders.isEmpty) { return null; } - return effectivePackagingBuilder( - widget.pack, - widget.selectedBuilder ?? _localBuilder, - all: widget.builders, - ); + return effectivePackagingBuilder(widget.pack, widget.selectedBuilder ?? _localBuilder, all: widget.builders); } PackageBuilder? _findBuilder(String id) { @@ -70,11 +66,7 @@ class _PackPackagingState extends State { /// 该包当前启用的格式 id(规范序);未记录时回退全部。 List _enabledFormatIds() => [ - for (final PackageBuilder builder in enabledBuildersFor( - widget.pack, - all: widget.builders, - )) - builder.id, + for (final PackageBuilder builder in enabledBuildersFor(widget.pack, all: widget.builders)) builder.id, ]; Future _modifyFormats() async { @@ -115,12 +107,7 @@ class _PackPackagingState extends State { showFloatingToast(context, '已保存'); return; } - showFloatingToast( - context, - '保存失败', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + showFloatingToast(context, '保存失败', type: FloatingToastType.error, duration: const Duration(seconds: 5)); } /// 全字段拷贝并仅替换启用格式集合。 @@ -212,11 +199,7 @@ class _PackPackagingState extends State { children: [ Text( '打包格式', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: theme.typography.body?.color, - ), + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: theme.typography.body?.color), ), const SizedBox(height: 8), Row( @@ -233,34 +216,23 @@ class _PackPackagingState extends State { isExpanded: true, onChanged: _selectBuilder, items: >[ - for (final PackageBuilder builder - in enabledBuildersFor( - widget.pack, - all: widget.builders, - )) - ComboBoxItem( - value: builder.id, - child: Text(builder.displayName), - ), + for (final PackageBuilder builder in enabledBuildersFor(widget.pack, all: widget.builders)) + ComboBoxItem(value: builder.id, child: Text(builder.displayName)), ], ), ), ), - const SizedBox(width: 12), + const SizedBox(width: 8), Button( key: const Key('modifyEnabledFormatsButton'), - onPressed: widget.onSave == null || _savingFormats - ? null - : _modifyFormats, - child: const Text('修改启用格式…'), + onPressed: widget.onSave == null || _savingFormats ? null : _modifyFormats, + child: SizedBox(height: 22, child: const Text('修改启用格式…'),), ), ], ), const SizedBox(height: 8), - Text( - '仅列出该包已启用的格式;可点击「修改启用格式…」调整。', - style: TextStyle(color: theme.resources.textFillColorSecondary), - ), + Text('仅列出该包已启用的格式;可点击「修改启用格式…」调整。', + style: TextStyle(color: theme.resources.textFillColorSecondary)), const SizedBox(height: 16), FilledButton( key: const Key('packPreviewButton'), @@ -268,15 +240,10 @@ class _PackPackagingState extends State { child: const Text('预览打包内容'), ), const SizedBox(height: 16), - Text( - _descriptionFor(_builder), - style: TextStyle(color: theme.resources.textFillColorSecondary), - ), + Text(_descriptionFor(_builder), style: TextStyle(color: theme.resources.textFillColorSecondary)), const SizedBox(height: 8), - Text( - '点击「预览打包内容」可查看包内完整文件列表与文件内容。', - style: TextStyle(color: theme.resources.textFillColorSecondary), - ), + Text('点击「预览打包内容」可查看包内完整文件列表与文件内容。', + style: TextStyle(color: theme.resources.textFillColorSecondary)), ], ), ), diff --git a/lib/pages/setting.dart b/lib/pages/setting.dart index b8f2e52..aadc4c4 100644 --- a/lib/pages/setting.dart +++ b/lib/pages/setting.dart @@ -37,22 +37,19 @@ class Setting extends StatefulWidget { } class _SettingState extends State { - static const Map _themeModeLabels = - { - ThemeModeSetting.system: '系统', - ThemeModeSetting.dark: '深色', - ThemeModeSetting.light: '浅色', - }; - - static const Map _proxyModeLabels = - { - ProxyModeSetting.off: '关闭(直连)', - ProxyModeSetting.auto: '自动检测', - ProxyModeSetting.manual: '手动设置', - }; - - List _detected = - const []; + static const Map _themeModeLabels = { + ThemeModeSetting.system: '系统', + ThemeModeSetting.dark: '深色', + ThemeModeSetting.light: '浅色', + }; + + static const Map _proxyModeLabels = { + ProxyModeSetting.off: '关闭', + ProxyModeSetting.auto: '自动检测', + ProxyModeSetting.manual: '手动设置', + }; + + List _detected = const []; bool _detecting = true; late final TextEditingController _defaultAuthorController; late final FocusNode _defaultAuthorFocusNode; @@ -65,20 +62,13 @@ class _SettingState extends State { @override void initState() { super.initState(); - _defaultAuthorController = TextEditingController( - text: widget.settings.defaultAuthor, - ); + _defaultAuthorController = TextEditingController(text: widget.settings.defaultAuthor); _defaultAuthorFocusNode = FocusNode()..addListener(_onAuthorFocusChanged); - _proxyHostController = TextEditingController( - text: widget.settings.proxyHost, - ); + _proxyHostController = TextEditingController(text: widget.settings.proxyHost); _proxyHostFocusNode = FocusNode()..addListener(_onProxyHostFocusChanged); - _proxyPortController = TextEditingController( - text: widget.settings.proxyPort?.toString() ?? '', - ); + _proxyPortController = TextEditingController(text: widget.settings.proxyPort?.toString() ?? ''); _proxyPortFocusNode = FocusNode()..addListener(_onProxyPortFocusChanged); - final List cached = - widget.settings.detectedCompilers; + final List cached = widget.settings.detectedCompilers; if (cached.isEmpty) { _detectCompilers(showLoading: false); } else { @@ -90,16 +80,13 @@ class _SettingState extends State { @override void didUpdateWidget(covariant Setting oldWidget) { super.didUpdateWidget(oldWidget); - if (oldWidget.settings.defaultAuthor != widget.settings.defaultAuthor && - !_defaultAuthorFocusNode.hasFocus) { + if (oldWidget.settings.defaultAuthor != widget.settings.defaultAuthor && !_defaultAuthorFocusNode.hasFocus) { _defaultAuthorController.text = widget.settings.defaultAuthor; } - if (oldWidget.settings.proxyHost != widget.settings.proxyHost && - !_proxyHostFocusNode.hasFocus) { + if (oldWidget.settings.proxyHost != widget.settings.proxyHost && !_proxyHostFocusNode.hasFocus) { _proxyHostController.text = widget.settings.proxyHost; } - if (oldWidget.settings.proxyPort != widget.settings.proxyPort && - !_proxyPortFocusNode.hasFocus) { + if (oldWidget.settings.proxyPort != widget.settings.proxyPort && !_proxyPortFocusNode.hasFocus) { _proxyPortController.text = widget.settings.proxyPort?.toString() ?? ''; } } @@ -245,21 +232,13 @@ class _SettingState extends State { showFloatingToast(context, '已保存'); } - SettingsModel _directorySettings({ - required String? outputDirectory, - required String? cmakeOutputDirectory, - }) { - return widget.settings.copyWith( - outputDirectory: outputDirectory, - cmakeOutputDirectory: cmakeOutputDirectory, - ); + SettingsModel _directorySettings({required String? outputDirectory, required String? cmakeOutputDirectory}) { + return widget.settings.copyWith(outputDirectory: outputDirectory, cmakeOutputDirectory: cmakeOutputDirectory); } - SettingsModel _defaultAuthorSettings(String defaultAuthor) => - widget.settings.copyWith(defaultAuthor: defaultAuthor); + SettingsModel _defaultAuthorSettings(String defaultAuthor) => widget.settings.copyWith(defaultAuthor: defaultAuthor); - SettingsModel _themeSettings({ThemeModeSetting? themeMode}) => - widget.settings.copyWith(themeMode: themeMode); + SettingsModel _themeSettings({ThemeModeSetting? themeMode}) => widget.settings.copyWith(themeMode: themeMode); SettingsModel _compilerSettings(List compilerPriority) => widget.settings.copyWith(compilerPriority: compilerPriority); @@ -268,9 +247,7 @@ class _SettingState extends State { widget.settings.copyWith(detectedCompilers: detected); void _moveCompiler(int index, int offset) { - final List priority = List.of( - widget.settings.compilerPriority, - ); + final List priority = List.of(widget.settings.compilerPriority); final int target = index + offset; if (target < 0 || target >= priority.length) { return; @@ -285,40 +262,22 @@ class _SettingState extends State { if (path == null || !mounted) { return; } - await _apply( - _directorySettings( - outputDirectory: path, - cmakeOutputDirectory: widget.settings.cmakeOutputDirectory, - ), - ); + await _apply(_directorySettings(outputDirectory: path, cmakeOutputDirectory: widget.settings.cmakeOutputDirectory)); } - Future _clearDirectory() => _apply( - _directorySettings( - outputDirectory: null, - cmakeOutputDirectory: widget.settings.cmakeOutputDirectory, - ), - ); + Future _clearDirectory() => + _apply(_directorySettings(outputDirectory: null, cmakeOutputDirectory: widget.settings.cmakeOutputDirectory)); Future _pickCmakeDirectory() async { final String? path = await widget.pickDirectory(); if (path == null || !mounted) { return; } - await _apply( - _directorySettings( - outputDirectory: widget.settings.outputDirectory, - cmakeOutputDirectory: path, - ), - ); + await _apply(_directorySettings(outputDirectory: widget.settings.outputDirectory, cmakeOutputDirectory: path)); } - Future _clearCmakeDirectory() => _apply( - _directorySettings( - outputDirectory: widget.settings.outputDirectory, - cmakeOutputDirectory: null, - ), - ); + Future _clearCmakeDirectory() => + _apply(_directorySettings(outputDirectory: widget.settings.outputDirectory, cmakeOutputDirectory: null)); Future _generateSkill() async { final String? path = await widget.pickSaveFile(_skillFileName); @@ -348,13 +307,10 @@ class _SettingState extends State { @override Widget build(BuildContext context) { - final bool manualProxy = - widget.settings.proxyMode == ProxyModeSetting.manual; + final bool manualProxy = widget.settings.proxyMode == ProxyModeSetting.manual; return SettingsPage( title: '设置', - description: const Text( - '配置打包输出目录、默认作者、外观、编译器优先级、网络代理与 AI 技能输出。', - ), + description: const Text('配置打包输出目录、默认作者、外观、编译器优先级、网络代理与 AI 技能输出。'), children: [ SettingsGroup( header: '打包', @@ -378,29 +334,14 @@ class _SettingState extends State { ), ], ), - SettingsGroup( - header: '新包默认值', - children: [_buildDefaultAuthorCard()], - ), - SettingsGroup( - header: '外观', - children: [_buildThemeModeCard()], - ), - SettingsGroup( - header: '编译器', - children: [_buildCompilerCard()], - ), + SettingsGroup(header: '新包默认值', children: [_buildDefaultAuthorCard()]), + SettingsGroup(header: '外观', children: [_buildThemeModeCard()]), + SettingsGroup(header: '编译器', children: [_buildCompilerCard()]), SettingsGroup( header: '网络', - children: [ - _buildProxyModeCard(), - if (manualProxy) _buildProxyManualCard(), - ], - ), - SettingsGroup( - header: 'AI 技能', - children: [_buildSkillCard()], + children: [_buildProxyModeCard(), if (manualProxy) _buildProxyManualCard()], ), + SettingsGroup(header: 'AI 技能', children: [_buildSkillCard()]), ], ); } @@ -414,14 +355,9 @@ class _SettingState extends State { required VoidCallback onClear, }) { return SettingsCard( + padding: const .fromLTRB(8, 8, 8, 8), header: Text(header), - content: _buildPathControls( - path: path, - pickKey: pickKey, - clearKey: clearKey, - onPick: onPick, - onClear: onClear, - ), + content: _buildPathControls(path: path, pickKey: pickKey, clearKey: clearKey, onPick: onPick, onClear: onClear), ); } @@ -451,21 +387,16 @@ class _SettingState extends State { ), ), Button(key: pickKey, onPressed: onPick, child: const Text('选择目录…')), - Button( - key: clearKey, - onPressed: path == null ? null : onClear, - child: const Text('清除'), - ), + Button(key: clearKey, onPressed: path == null ? null : onClear, child: const Text('清除')), ], ); } Widget _buildDefaultAuthorCard() { return SettingsCard( + padding: const .fromLTRB(8, 8, 8, 8), header: const Text('默认作者'), - description: const Text( - '新包将预填此值;作者为空或占位(「无」「未知」等)的包将自动替换为默认作者。', - ), + description: const Text('新包将预填此值;作者为空或占位(「无」「未知」等)的包将自动替换为默认作者。'), content: SizedBox( width: 320, child: TextBox( @@ -481,6 +412,7 @@ class _SettingState extends State { Widget _buildThemeModeCard() { return SettingsCard( header: const Text('主题模式'), + padding: const .fromLTRB(8, 8, 8, 8), content: _comboBoxField( width: 160, child: ComboBox( @@ -494,10 +426,7 @@ class _SettingState extends State { }, items: >[ for (final ThemeModeSetting mode in ThemeModeSetting.values) - ComboBoxItem( - value: mode, - child: Text(_themeModeLabels[mode]!), - ), + ComboBoxItem(value: mode, child: Text(_themeModeLabels[mode]!)), ], ), ), @@ -506,6 +435,7 @@ class _SettingState extends State { Widget _buildProxyModeCard() { return SettingsCard( + padding: const .fromLTRB(8, 8, 8, 8), header: const Text('代理模式'), description: const Text( '自动检测:使用 Windows 系统代理设置,不可用时自动直连。' @@ -524,10 +454,7 @@ class _SettingState extends State { }, items: >[ for (final ProxyModeSetting mode in ProxyModeSetting.values) - ComboBoxItem( - value: mode, - child: Text(_proxyModeLabels[mode]!), - ), + ComboBoxItem(value: mode, child: Text(_proxyModeLabels[mode]!)), ], ), ), @@ -537,6 +464,7 @@ class _SettingState extends State { Widget _buildProxyManualCard() { final FluentThemeData theme = FluentTheme.of(context); return SettingsCard( + padding: const .fromLTRB(8, 8, 8, 8), header: const Text('手动设置'), description: const Text( '服务器地址支持 host:port 或 http://host:port,端口留空时使用地址中声明的端口' @@ -578,10 +506,7 @@ class _SettingState extends State { padding: const EdgeInsets.only(top: 4), child: Text( _proxyPortError!, - style: TextStyle( - fontSize: 12, - color: AppColors.critical(theme.brightness), - ), + style: TextStyle(fontSize: 12, color: AppColors.critical(theme.brightness)), ), ), ], @@ -594,6 +519,7 @@ class _SettingState extends State { final List priority = widget.settings.compilerPriority; final bool hideRows = _detecting && _detected.isEmpty; return SettingsCard( + padding: const .fromLTRB(8, 8, 8, 8), header: const Text('编译器优先级'), description: const Text('优先使用的编译器(自上而下)'), content: SizedBox( @@ -605,27 +531,20 @@ class _SettingState extends State { Row( children: [ if (_detecting) ...[ - const SizedBox( - width: 16, - height: 16, - child: ProgressRing(strokeWidth: 2), - ), + const SizedBox(width: 16, height: 16, child: ProgressRing(strokeWidth: 2)), const SizedBox(width: 12), const Text('正在检测编译器…'), ], const Spacer(), Button( key: const Key('settingCompilerRefreshButton'), - onPressed: _detecting - ? null - : () => _detectCompilers(showLoading: true), + onPressed: _detecting ? null : () => _detectCompilers(showLoading: true), child: const Text('重新检测'), ), ], ), if (!hideRows) - for (var index = 0; index < priority.length; index++) - _buildCompilerRow(priority[index], index), + for (var index = 0; index < priority.length; index++) _buildCompilerRow(priority[index], index), ], ), ), @@ -646,9 +565,7 @@ class _SettingState extends State { child: Text( compiler?.version ?? '未检测到', overflow: TextOverflow.ellipsis, - style: compiler == null - ? TextStyle(color: theme.resources.textFillColorSecondary) - : null, + style: compiler == null ? TextStyle(color: theme.resources.textFillColorSecondary) : null, ), ), _buildMoveButton( @@ -661,9 +578,7 @@ class _SettingState extends State { key: Key('settingCompilerMoveDown_$id'), icon: FluentIcons.chevron_down, tooltip: '下移', - onPressed: index < widget.settings.compilerPriority.length - 1 - ? () => _moveCompiler(index, 1) - : null, + onPressed: index < widget.settings.compilerPriority.length - 1 ? () => _moveCompiler(index, 1) : null, ), ], ), @@ -699,21 +614,16 @@ class _SettingState extends State { child: SizedBox( width: 24, height: 24, - child: IconButton( - key: key, - icon: Icon(icon, size: 14), - onPressed: onPressed, - ), + child: IconButton(key: key, icon: Icon(icon, size: 14), onPressed: onPressed), ), ); } Widget _buildSkillCard() { return SettingsCard( + padding: const .fromLTRB(8, 8, 8, 8), header: const Text('SKILL.md'), - description: const Text( - '生成 build.py 编写技能文档(SKILL.md),可放入 AI 插件的技能目录使用。', - ), + description: const Text('生成 build.py 编写技能文档(SKILL.md),可放入 AI 插件的技能目录使用。'), content: Button( key: const Key('settingGenerateSkillButton'), onPressed: _generateSkill, @@ -737,11 +647,8 @@ const String _skillFileName = 'SKILL.md'; const String _skillAssetPath = 'assets/build/SKILL.md'; Future _pickSkillSaveLocation(String suggestedName) async { - final FileSaveLocation? location = await getSaveLocation( - suggestedName: suggestedName, - ); + final FileSaveLocation? location = await getSaveLocation(suggestedName: suggestedName); return location?.path; } -Future _loadSkillTemplateAsset() => - rootBundle.loadString(_skillAssetPath); +Future _loadSkillTemplateAsset() => rootBundle.loadString(_skillAssetPath); diff --git a/lib/widgets/floating_toast.dart b/lib/widgets/floating_toast.dart index 9672619..2c7d6d5 100644 --- a/lib/widgets/floating_toast.dart +++ b/lib/widgets/floating_toast.dart @@ -62,7 +62,7 @@ class _FloatingToast extends StatefulWidget { class _FloatingToastState extends State<_FloatingToast> with SingleTickerProviderStateMixin { static const Duration _animationDuration = Duration(milliseconds: 180); - static const Offset _slideFrom = Offset(0.18, 0); + static const Offset _slideFrom = Offset(1, 0); late final AnimationController _controller; late final CurvedAnimation _curve; diff --git a/lib/widgets/library_card.dart b/lib/widgets/library_card.dart index 8ee322b..a808d0c 100644 --- a/lib/widgets/library_card.dart +++ b/lib/widgets/library_card.dart @@ -4,42 +4,25 @@ import 'package:fluent_ui/fluent_ui.dart'; import '../util/svgs.dart'; class LibraryItem extends PaneItem { - LibraryItem({ - super.key, - required Widget? icon, - required String title, - String? version, - Widget? badge, - required Widget body, - }) : super( - icon: icon ?? Svgs.cardboardBox, - title: Row( - mainAxisAlignment: .spaceBetween, - children: [ - Expanded( - child: Text( - title, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - const SizedBox(width: 8), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - version != null - ? Tag( - text: version, - fontSize: 10, - maxWidth: 96, - tooltip: version, - ) - : const SizedBox(width: 8), - if (badge != null) ...[const SizedBox(width: 4), badge], - ], - ), - ], - ), - body: body, - ); + LibraryItem( + {super.key, required Widget? icon, required String title, String? version, Widget? badge, required Widget body}) + : super( + icon: icon ?? Svgs.cardboardBox, + title: Row( + mainAxisAlignment: .spaceBetween, + children: [ + Expanded(child: Text(title, maxLines: 1, overflow: TextOverflow.ellipsis)), + const SizedBox(width: 8), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + version != null ? Tag(text: version, fontSize: 10, maxWidth: 96, tooltip: version) : const SizedBox( + width: 8), + if (badge != null) ...[const SizedBox(width: 4), badge], + ], + ), + ], + ), + body: body, + ); } diff --git a/lib/widgets/settings/settings_card.dart b/lib/widgets/settings/settings_card.dart index 1539fd0..1b85292 100644 --- a/lib/widgets/settings/settings_card.dart +++ b/lib/widgets/settings/settings_card.dart @@ -2,17 +2,14 @@ import 'package:cpp_nuget_pack/util/colors.dart'; import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/services.dart'; -/// CommunityToolkit(PowerToys)SettingsCard XAML token;组件与测试共用, -/// 避免魔法数在实现与断言间漂移。 abstract final class SettingsCardTokens { - static const double minHeight = 68; - static const double subItemMinHeight = 52; + static const double minHeight = 0; + static const double subItemMinHeight = 0; static const double minWidth = 148; static const double cornerRadius = 4; static const EdgeInsets padding = EdgeInsets.all(16); - /// 子项(SettingsExpander 内部)内边距:左 58 为展开层级缩进。 - static const EdgeInsets subItemPadding = EdgeInsets.fromLTRB(58, 8, 44, 8); + static const EdgeInsets subItemPadding = EdgeInsets.fromLTRB(48, 8, 44, 8); static const double headerIconSize = 20; static const double headerIconSpacing = 20; @@ -25,12 +22,6 @@ abstract final class SettingsCardTokens { static const Duration backgroundTransition = Duration(milliseconds: 83); } -/// 组设置卡:左侧头部(图标 + 标题 + 描述)与右侧内容区。 -/// -/// 严格照 Toolkit token:最小高 68(子项 52)、内边距 16(子项 58,8,44,8)、 -/// 1px 描边 + 圆角 4(子项无圆角、仅顶部 1px 分隔线);窄窗(< 476)内容换行到 -/// 头部下方,更窄(< 286)隐藏头部图标。悬停/按下背景过渡 83ms;仅 -/// [onPressed] 非空(且启用)的卡有 hover/按下态与焦点环。 class SettingsCard extends StatefulWidget { const SettingsCard({ super.key, @@ -62,7 +53,6 @@ class SettingsCard extends StatefulWidget { /// 无边框变体(SettingsExpander 头部:透明底、无描边、无圆角)。 final bool borderless; - /// 内边距覆盖(null 时按 token:16 全边 / 子项 58,8,44,8)。 final EdgeInsetsGeometry? padding; /// 可点击卡的尾部箭头(13px chevron_right,间距 14);[onPressed] 非空时生效。 @@ -99,10 +89,7 @@ class _SettingsCardState extends State { if (widget.borderless) { border = Border.all(color: Colors.transparent, width: 1); } else if (_focused && _clickable) { - border = Border.all( - color: theme.resources.focusStrokeColorOuter, - width: 2, - ); + border = Border.all(color: theme.resources.focusStrokeColorOuter, width: 2); } else if (widget.subItem) { border = Border(top: BorderSide(color: borderColor)); } else { @@ -119,20 +106,10 @@ class _SettingsCardState extends State { duration: SettingsCardTokens.backgroundTransition, constraints: BoxConstraints( minWidth: SettingsCardTokens.minWidth, - minHeight: widget.subItem - ? SettingsCardTokens.subItemMinHeight - : SettingsCardTokens.minHeight, - ), - padding: - widget.padding ?? - (widget.subItem - ? SettingsCardTokens.subItemPadding - : SettingsCardTokens.padding), - decoration: BoxDecoration( - color: background, - border: border, - borderRadius: radius, + minHeight: widget.subItem ? SettingsCardTokens.subItemMinHeight : SettingsCardTokens.minHeight, ), + padding: widget.padding ?? (widget.subItem ? SettingsCardTokens.subItemPadding : SettingsCardTokens.padding), + decoration: BoxDecoration(color: background, border: border, borderRadius: radius), child: card, ); @@ -206,29 +183,19 @@ class _SettingsCardState extends State { return AppColors.stroke(theme); } - Widget _buildBody( - BuildContext context, - BoxConstraints constraints, - FluentThemeData theme, - ) { + Widget _buildBody(BuildContext context, BoxConstraints constraints, FluentThemeData theme) { final bool wrap = constraints.maxWidth < SettingsCardTokens.wrapThreshold; - final bool hideIcon = - constraints.maxWidth < SettingsCardTokens.wrapNoIconThreshold; + final bool hideIcon = constraints.maxWidth < SettingsCardTokens.wrapNoIconThreshold; final Widget? icon = hideIcon ? null : widget.headerIcon; final Widget? iconView = icon == null ? null : Padding( - padding: const EdgeInsets.only( - right: SettingsCardTokens.headerIconSpacing, - ), + padding: const EdgeInsets.only(right: SettingsCardTokens.headerIconSpacing), child: SizedBox( width: SettingsCardTokens.headerIconSize, height: SettingsCardTokens.headerIconSize, child: IconTheme.merge( - data: IconThemeData( - size: SettingsCardTokens.headerIconSize, - color: _foregroundFor(theme), - ), + data: IconThemeData(size: SettingsCardTokens.headerIconSize, color: _foregroundFor(theme)), child: Center(child: icon), ), ), @@ -241,11 +208,7 @@ class _SettingsCardState extends State { children: [ if (widget.header != null) DefaultTextStyle.merge( - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w400, - color: _foregroundFor(theme), - ), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: _foregroundFor(theme)), child: widget.header!, ), if (widget.description != null) @@ -265,9 +228,7 @@ class _SettingsCardState extends State { final Widget? content = widget.content; final Widget? chevron = widget.showChevron && _clickable ? Padding( - padding: const EdgeInsets.only( - left: SettingsCardTokens.actionIconSpacing, - ), + padding: const EdgeInsets.only(left: SettingsCardTokens.actionIconSpacing), child: Icon( FluentIcons.chevron_right, size: SettingsCardTokens.actionIconSize, @@ -284,9 +245,7 @@ class _SettingsCardState extends State { Expanded( child: Padding( padding: EdgeInsets.only( - right: content == null && chevron == null - ? 0 - : SettingsCardTokens.headerContentSpacing, + right: content == null && chevron == null ? 0 : SettingsCardTokens.headerContentSpacing, ), child: headerColumn, ), @@ -307,10 +266,7 @@ class _SettingsCardState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ ?iconView, - if (headerColumn != null) - Expanded(child: headerColumn) - else - const Spacer(), + if (headerColumn != null) Expanded(child: headerColumn) else const Spacer(), ], ), if (content != null || chevron != null) ...[ @@ -319,7 +275,9 @@ class _SettingsCardState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ if (content != null) - Flexible(child: Align(alignment: Alignment.centerLeft, child: content)), + Flexible( + child: Align(alignment: Alignment.centerLeft, child: content), + ), ?chevron, ], ), @@ -366,15 +324,8 @@ class SettingsCardToggle extends StatelessWidget { return SizedBox( height: 36, child: ToggleSwitchTheme( - data: const ToggleSwitchThemeData( - padding: EdgeInsets.zero, - margin: EdgeInsets.zero, - ), - child: ToggleSwitch( - checked: checked, - onChanged: enabled ? onChanged : null, - semanticLabel: semanticLabel, - ), + data: const ToggleSwitchThemeData(padding: EdgeInsets.zero, margin: EdgeInsets.zero), + child: ToggleSwitch(checked: checked, onChanged: enabled ? onChanged : null, semanticLabel: semanticLabel), ), ); } diff --git a/lib/widgets/settings/settings_group.dart b/lib/widgets/settings/settings_group.dart index ae68711..34090a9 100644 --- a/lib/widgets/settings/settings_group.dart +++ b/lib/widgets/settings/settings_group.dart @@ -4,7 +4,7 @@ import 'package:fluent_ui/fluent_ui.dart'; /// PowerToys SettingsGroup token:组标题 14 Semibold、上边距 32(首个 8)、 /// 卡容器上距 8、卡间距 2。 abstract final class SettingsGroupTokens { - static const double headerSpacing = 32; + static const double headerSpacing = 8; static const double firstHeaderSpacing = 8; static const double containerSpacing = 8; static const double cardSpacing = 2; diff --git a/lib/widgets/settings/settings_page.dart b/lib/widgets/settings/settings_page.dart index 8148c1e..441cda1 100644 --- a/lib/widgets/settings/settings_page.dart +++ b/lib/widgets/settings/settings_page.dart @@ -4,13 +4,13 @@ import 'package:fluent_ui/fluent_ui.dart'; /// PowerToys SettingsPageControl token:标题 28 Semibold、模块描述 14 Secondary、 /// 内容最大宽 1000、水平内边距 16、底部滚动留白 48。 abstract final class SettingsPageTokens { - static const double titleFontSize = 28; + static const double titleFontSize = 24; static const double descriptionFontSize = 14; static const double contentMaxWidth = 1000; - static const double horizontalPadding = 16; - static const double bottomPadding = 48; + static const double horizontalPadding = 8; + static const double bottomPadding = 32; static const double descriptionSpacing = 8; - static const double contentSpacing = 24; + static const double contentSpacing = 0; } /// 设置页模板:标题 → 模块描述 → 内容(左对齐、最大宽 1000、可滚动)。 @@ -36,7 +36,6 @@ class SettingsPage extends StatelessWidget { return SizedBox.expand( child: Container( key: const Key('settingsPageSurface'), - decoration: BoxDecoration(color: theme.cardColor), child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB( SettingsPageTokens.horizontalPadding, @@ -52,9 +51,7 @@ class SettingsPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only( - top: SettingsPageTokens.horizontalPadding, - ), + padding: const EdgeInsets.only(top: SettingsPageTokens.horizontalPadding), child: Text( title, style: TextStyle( @@ -66,9 +63,7 @@ class SettingsPage extends StatelessWidget { ), if (description != null) Padding( - padding: const EdgeInsets.only( - top: SettingsPageTokens.descriptionSpacing, - ), + padding: const EdgeInsets.only(top: SettingsPageTokens.descriptionSpacing), child: DefaultTextStyle.merge( style: TextStyle( fontSize: SettingsPageTokens.descriptionFontSize, diff --git a/test/build/library_recipes/openvino/build.py b/test/build/library_recipes/openvino/build.py index 348c319..ab09881 100644 --- a/test/build/library_recipes/openvino/build.py +++ b/test/build/library_recipes/openvino/build.py @@ -1,6 +1,6 @@ # https://github.com/openvinotoolkit/openvino.git # source: none -# option: tbb = off | on +# checkbox: tbb = off | on # # OpenVINO 预构建配方(P3 L6) # From 04f9ac7bb2876e4a816b58006fec808a4652f09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=82=E6=B2=AB?= <1992724048@qq.com> Date: Thu, 17 Sep 2026 19:24:17 +0800 Subject: [PATCH 2/8] =?UTF-8?q?refactor(ui):=20=E5=85=A8=E6=96=B0=E7=9A=84?= =?UTF-8?q?logo=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 155 +---------------------------------- assets/icons/logo.png | Bin 0 -> 27476 bytes lib/pages/about.dart | 32 ++------ logo/c++_480px.png | Bin 0 -> 25500 bytes logo/c_programming_480px.png | Bin 0 -> 26565 bytes logo/dll_480px.png | Bin 0 -> 8174 bytes logo/empty_box_480px.png | Bin 0 -> 7183 bytes logo/logo.png | Bin 0 -> 27476 bytes logo/logo.psd | Bin 0 -> 241211 bytes 9 files changed, 6 insertions(+), 181 deletions(-) create mode 100644 assets/icons/logo.png create mode 100644 logo/c++_480px.png create mode 100644 logo/c_programming_480px.png create mode 100644 logo/dll_480px.png create mode 100644 logo/empty_box_480px.png create mode 100644 logo/logo.png create mode 100644 logo/logo.psd diff --git a/README.md b/README.md index 68da04c..5f28270 100644 --- a/README.md +++ b/README.md @@ -1,154 +1 @@ -# C++ NuGet 打包工具 - -把 C++ 头文件、源码与库可视化为原生 NuGet 包的 Windows 桌面工具。通过图形界面完成包信息编辑、目录映射、依赖与编译设置,并一键导出 Visual Studio C++ 工程可直接引用的 `.nupkg`,或供 CMake `find_package` 消费的配置包。 - -- 平台:仅 Windows 桌面 -- 界面:全中文、Win11 风格(fluent_ui)、Fluent 默认配色(浅色/深色两族,跟随系统) -- 数据:配置保存在程序目录下的 `config/`,便携、无需安装 - -## 功能特性 - -| 功能 | 说明 | -| ---- | ---- | -| 包管理 | 添加文件夹(自动扫描后填写包信息)、编辑版本/作者/许可证/描述(包 ID 不可改)、删除包、重新映射源目录 | -| 文件管理 | 目录树展示包内文件(目录大小按后代聚合);双击用系统默认程序打开;lib/dll/pdb/exe 按路径显示 Release/Debug 构建标签 | -| 构建 | 源目录根部含 `build.py` 时「文件管理」页显示「构建」按钮:自动拉取 git 源码到 `cache/`(二次构建原位硬重置,预构建包复用本地缓存不重复下载)并执行构建脚本(`SRC_PATH`/`BUILD_OUT` 环境变量;源码就绪后、执行构建脚本前清空包源目录产物(保留 `build.py`/`icon.*`/钩子脚本/根级 `.git` 与许可证)),成功后自动重新映射;构建前自动准备环境——检测本机编译器(默认优先 ICX > clang-cl > MSVC > MinGW,可在设置调整)、捕获编译器环境(vcvars/setvars)、按需下载 CMake/Ninja 到 `tools/`;`build.py` 头部可声明 `# tool`(需自动下载的环境工具,如 NASM/Perl)与 `# option`(构建选项,工具栏内随选随存、构建时经 `CNP_OPTION_*` 下发);分类辅助模块 `cnp_build_support.py` 随构建释放,脚本可经 `PYTHONPATH` import 完成 CMake 装配与产物分类;`build.py` 不进入打包产物;产物按 `release/`、`debug/` 分层分类(源码构建自动注入 AVX2、Release 最高优化与 LTO(可退化)、多线程构建参数);构建输出实时显示于进度对话框右侧面板(ERROR/WARNING/INFO 高亮);源目录根部 `pre.bat`/`post.bat` 与头部 `# depends` 自动注册为系统条目(编译前/后命令与依赖,界面禁改删);`# source: none` 支持预构建配方;含仓库的包在侧栏显示 git/更新徽标,文件管理页显示当前与最新版本号 | -| 依赖管理 | 从现有包选择依赖,自定义 NuGet 版本范围并实时校验;指向不存在包的依赖显示「缺失」 | -| 编译设置 | 宏定义、编译前/后命令(可从包内选择脚本、插入 MSBuild 常用宏)、附加库目录、附加库;条目可按 ALL/Release/Debug 分组;「节点脚本」分区提供可视化节点编辑器(节点图随包分发并自动执行,见「节点脚本」) | -| 打包设置 | 选择打包格式(NuGet / CMake);预览包内文件树与文本内容;按所选格式导出(缺失依赖时弹窗提醒,可继续;导出前校验节点脚本与包内可执行二进制,提示后仍可继续/取消) | -| 历史记录 | 时间线记录创建、版本变更、重新映射、打包导出四类事件(上限 100 条,可删除) | -| 依赖关系图 | 全部包的依赖关系可视化:可拖拽平移、滚轮缩放;缺失依赖红色标注,当前包高亮 | -| 设置 | 打包输出目录;编译器优先级(ICX/clang-cl/MSVC/MinGW,检测本机版本、可排序与重新检测;检测结果缓存至 `detectedCompilers`,有缓存时免检测直接显示、「重新检测」刷新并写回);SKILL.md 生成(内置模板写出,供分发给 AI 插件);主题模式(系统/深色/浅色),即时生效并持久化 | - -## 打包产物 - -导出文件命名为 `<包ID>.<版本>.nupkg`(版本去掉 `+build` 后缀),内部布局: - -| 内容 | 包内路径 | 说明 | -| ---- | -------- | ---- | -| 头文件 / 模块 | `build/native/include/<源目录名>/...` | 剥离开头 `include/` 后再套一层源目录名作命名空间(源目录已自带同名目录时不再叠加,避免重复层),消费者可写 `#include <源目录名/foo.h>` 防冲突;源目录缺失时回退包名 | -| lib / dll / pdb | `build/native/lib/...` | 剥离开头 `lib/`、`bin/` | -| 其余文件 | `build/native/files/...` | 保留原相对路径,全部入包(含 `.exe` 等可执行二进制,导出时提示随包分发) | -| 包清单 | `<包ID>.nuspec` | 许可证用 SPDX 表达式;依赖组 `native0.0`;恒定声明包图标 | -| MSBuild 集成 | `build/native/<包ID>.targets` | 为消费者工程提供编译集成,见下 | -| 节点脚本 | `build/native/files/scripts/.ps1` | 由节点编辑器生成(UTF-8 BOM);`` 形如 `script_1`;无节点脚本时不产生 | -| 包图标 | `images/icon.png` | 从包图标自动转换,等比缩放至最长边不超过 128;缺失时使用默认纸箱图标 | - -`<包ID>.targets` 为消费者工程提供: - -- 自动把 `build/native/include` 追加到包含路径 -- 写入宏定义、附加库目录与附加库(按 ALL/Release/Debug 条件分组;包内 `.lib` 按路径自动识别配置,同时补充库目录与库名) -- 编译前/后命令以自定义目标自动执行:`CnpPreBuild_<包ID清洗>_`(`BeforeTargets="ClCompile"`)/ `CnpPostBuild_<包ID清洗>_`(`AfterTargets="Build"`),每命令一条 `Exec`(工作目录 `$(ProjectDir)`,ALL/Release/Debug 条件在目标级,Release/Debug 组以 `_Release`/`_Debug` 后缀区分) -- 包内 dll/pdb 由 `DeployPkgRuntimeBinaries` 目标在构建后硬链接到 `$(OutDir)`(失败回退为拷贝,并登记 `FileWrites` 供清理) -- 包内包含 `.asm` 时条件导入 VS 的 `masm.props`/`masm.targets`,生成 `MASM` 项 -- 包内包含 `.rc` 时生成 `ResourceCompile` 项 -- 节点脚本以每个触发时机一个目标自动执行:`CnpScripts_<包ID清洗>__Pre` / `..._Post`(`hash8` 为包 ID 的 SHA-1 前 8 位,防跨包目标重名覆盖),见「节点脚本」 - -> 命令注入修复(自定义 `Exec` 目标)随导出生成于 `.targets`,不回溯既有包:已导出包需重新打包才会带上修复,旧包内仍为旧机制。 - -### 节点脚本 - -在「编译设置」→「节点脚本」分区打开可视化节点编辑器(内置 51 种节点);节点图随包分发,导出 NuGet 包时自动生成执行目标: - -- **生成脚本**:`build/native/files/scripts/.ps1`(`` 形如 `script_1`,ASCII 安全文件名),以 UTF-8 BOM 写入,保证 PowerShell 5.1 正确解析脚本中的中文;脚本入口先将 `PSModulePath` 全量归一为 `$PSHOME\Modules`(不保留继承的自定义模块路径),避免中间进程链(如 PowerShell 7)的模块路径遮蔽 5.1 自带模块 -- **执行目标**:每个触发时机一个目标——`CnpScripts_<包ID清洗>__Pre` 早于消费者 `PreBuildEvent` 与编译;`..._Post` 晚于运行时二进制部署(包内无 dll/pdb 时为构建之后)。`<包ID清洗>` 将包 ID 中非 `[A-Za-z0-9_]` 字符替换为 `_`;`hash8` 避免不同包的目标重名静默覆盖 -- **任务**:每个脚本一条 `Exec`,以 `powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File` 调用;顺序与编辑器脚本列表一致,失败即中止且只按退出码判定(不把 stderr 文本当失败);按脚本的 ALL/Release/Debug 标签生成构建条件 -- **节点语义**:`创建硬链接`仅支持同一卷上的文件——跨卷或目录目标会报错;`由十六进制写`的十六进制串忽略空白与连字符后,须为偶数长度且仅含十六进制字符,奇数长度或非法字符时脚本报错中断(十六进制串与字节数组整体驻留内存,不适用于大文件);`查找工具`用 `Get-Command -CommandType Application` 探测(防别名误中),未命中再按候选路径展开环境变量探测,结果分「是否找到」/「路径」两输出(每次输出各探测一次);`下载文件`/`上传文件`用 `Net.WebClient`(上传方法默认 PUT);`包内脚本文件`输出 `Join-Path $env:CNP_PackageRoot` 组合的包内路径;`运行包内脚本`按扩展名分派解释器(ps1 → `powershell.exe -File`、py → `python`、bat/cmd/exe 直调),参数按行拆分、工作目录临时切换、失败默认中止(可关) -- **变量系统**:`写入数值变量`/`读取数值变量`/`写入文本变量`/`读取文本变量` 四个节点读写脚本变量(发射为 `$var_<名称> = 值` / `$var_<名称>`);名称须以字母或下划线开头且仅含字母、数字、下划线;变量名大小写不敏感,同一名称只能用于一种类型,混用会报校验错误。脚本顶部自动为用到的变量注入初始化——数值 `0`、文本 `''`,按名称字典序;初始化收集口径为**生成路径上的变量**(不可达节点不参与生成),读取永不为 `$null`。变量为动态作用域(循环体内赋值对外可见),且每次脚本执行在独立 `powershell.exe` 进程中进行——变量不跨脚本共享。变量配合 `while`/`branch` 与算术、比较即可表达任意计算(图灵完备可达) -- **环境变量**:恒传 `CNP_PackageRoot`(包根 `build/native/`);节点中用到的 MSBuild 宏按白名单转成 `CNP_<宏名>`(如 `CNP_OutDir`);`$(SolutionDir)` 在单项目构建下为 `*Undefined*` -- **CMake 格式不接入节点脚本**:CMake 预览与导出产物均不包含脚本条目 - -> **安全声明**:节点脚本与手写编译前/后命令一样,会在**消费方构建机**上自动执行(供应链语义);「运行程序」节点即任意命令执行面,请仅消费可信来源的包。包内若含可执行二进制(`.exe`),导出时会提示其随包分发并被脚本在构建时调用,同样请确认来源可信。AES 加解密与代码签名节点的口令请优先使用「口令环境变量名」方式——直接填写的口令**字面量会随包分发**。 -> -> **执行策略提示**:脚本以 `-ExecutionPolicy Bypass` 启动,该参数**无法覆盖企业组策略(GPO)**强制的脚本执行限制;受管控环境请先确认策略允许。 - -### CMake 配置包 - -选择 CMake 格式导出时生成 `<包ID>-<版本>-cmake.zip`;解压后将目录加入 `CMAKE_PREFIX_PATH` 即可在 CMake 工程中消费: - -```cmake -find_package(<包名> CONFIG REQUIRED) -target_link_libraries(app PRIVATE <包名>::<包名>) -``` - -| 内容 | 包内路径 | 说明 | -| ---- | -------- | ---- | -| 头文件 / 模块 | `include/<源目录名>/...` | 与 NuGet 产物相同的命名空间策略(源目录已自带同名目录时不再叠加),`#include <源目录名/foo.h>` | -| lib / dll / pdb | `lib/...` | 剥离开头 `lib/`、`bin/`,保留 Release/Debug 子目录结构 | -| 其余文件 | `files/...` | 保留原相对路径 | -| CMake 配置 | `lib/cmake/<包名>/` | `Config.cmake`、`Targets.cmake`(`<包名>::<包名>` INTERFACE IMPORTED 目标、`.lib` 按 Debug/Release 分组条件链接)与 `ConfigVersion.cmake`(版本为数字点分时生成) | - -> DLL 不参与链接,需消费方自行拷贝到运行目录(例如 `$` 或手动复制)。 -> -> v1 不接入节点脚本:CMake 预览与导出产物均不包含节点脚本条目(仅 NuGet 格式支持)。 - -## 构建与运行 - -环境要求: - -- Windows 10/11 -- Flutter stable(建议 3.44.0 及以上,Dart SDK `^3.13.2`) -- Visual Studio C++ 工具链(含 Windows SDK,用于构建 Windows 桌面产物) - -```text -flutter pub get -flutter run -d windows # 本地运行 -flutter analyze # 静态检查(要求零问题) -flutter test # 运行测试 -flutter build windows --release # 产物位于 build/windows/x64/runner/Release/ -``` - -## 配置文件 - -配置保存在工作目录相对的 `config/`(便携,程序目录即数据目录): - -```text -config/ -├── config.yaml # 全局设置 -└── packs/ - └── <包 ID>.yaml # 每个包一个文件(同 ID 覆盖) -``` - -`config.yaml` 保存打包输出目录、编译器优先级、编译器检测结果缓存(`detectedCompilers`:设置页有缓存时免检测直接显示、「重新检测」刷新并写回;构建优先复用缓存,缺失/失效时自动重检并写回)与主题设置。包 YAML 字段: - -| 字段 | 说明 | -| ---- | ---- | -| `name` / `version` / `author` | 必填;`name` 同时决定配置文件名与 NuGet 包 ID | -| `description` / `license` / `iconPath` / `sourcePath` | 可选;`license` 为 SPDX 表达式 | -| `files` | 文件快照(`path`/`size`),由扫描与重新映射写入 | -| `dependencies` | 依赖列表(`name`/`version`,版本范围;`system: true` 为 `# depends` 自动注册) | -| `commands` | 编译前/后命令(`command`/`type`/`buildModel`;`system: true` 为 `pre.bat`/`post.bat` 自动注册) | -| `macros` | 宏定义(`value`/`buildModel`) | -| `libDirectories` | 附加库目录(`path`/`buildModel`) | -| `libraries` | 附加库(`name`/`buildModel`) | -| `buildOptions` | 构建选项(`{<名称>: <值>}`,由 `build.py` 头部 `# option` 声明;空省略) | -| `sourceVersion` | 上次构建记录的仓库版本(git tag 或短哈希;空省略) | -| `history` | 历史记录(`time`/`type`/`message`,上限 100 条) | -| `scripts` | 节点脚本(`id`/`name`/`trigger`/`buildModel` + 节点图 `nodes`/`edges`/视口;单条损坏仅丢弃该脚本) | - -其中 `buildModel` 取值为 ALL / Release / Debug。配置文件损坏或缺必填字段不会导致启动失败,启动后会以悬浮提示列出问题文件。 - -执行「构建」时下载的源码缓存在工作目录的 `cache/`(可随时删除;再次构建会按需重新下载);构建环境准备按需下载的工具缓存在 `tools/`(同为本地缓存;本机已有可用的 CMake(≥ 3.25)/Ninja/Python 时优先直接使用,否则自动解析官方最新版本下载最小版;编译器完全缺失时下载 LLVM clang 兜底;构建子进程使用受控 TMP 目录 `tools/.tmp/`);`build.py` 头部 `# tool` 声明的环境工具同样下载到 `tools/<名称>/`,构建前释放的 `cnp_build_support.py` 也在 `tools/`(均可随时删除)。 - -## 版本与发布 - -- 版本号采用「年份.年内发布数量」方案:`26.1` 表示 2026 年第 1 次发布,年内依次递增(`26.2`、`26.3`…),次年从 `27.1` 重新计数;更早的 `1.0.x` 为历史版本号。 -- 版本号唯一来源是 `pubspec.yaml` 的 `version:`(格式 `26.1.0+<构建号>`,第三段固定为 0);发布时同步更新 `lib/app_info.dart` 的 `appVersion`(去掉 `+build` 与末尾 `.0`,即 `26.1.0+1` → `26.1`),两者一致性由 `test/app_info_test.dart` 强制校验。 -- `dev` 分支:推送触发 CI(静态检查 → 测试 → Windows Release 构建),只验证不发布。 -- `master` 分支:验证通过后打包 `dist/cpp_nuget_pack-<版本>-win-x86_64.zip`,并创建 GitHub Release(tag `v<版本>`,如 `v26.1`)。 -- 因此修改版本号并推送到 `master` 即等于发布;没有发布意图时不要改动版本号。 - -## 技术栈 - -| 组件 | 用途 | -| ---- | ---- | -| Flutter / Dart | 应用框架(仅 Windows 桌面) | -| [fluent_ui](https://pub.dev/packages/fluent_ui) | Win11 风格控件 | -| [flutter_svg](https://pub.dev/packages/flutter_svg) | SVG 图标渲染 | -| [yaml](https://pub.dev/packages/yaml) / [yaml_edit](https://pub.dev/packages/yaml_edit) | YAML 配置解析与生成 | -| [archive](https://pub.dev/packages/archive) | `.nupkg` / CMake 配置包(ZIP)组装 | -| [file_selector](https://pub.dev/packages/file_selector) | 系统原生目录选择 / 保存位置对话框 | - -## 第三方声明 - -目录树图标来自 [Catppuccin Icons for VSCode](https://github.com/catppuccin/vscode-icons)(v1.26.0,MIT 许可)的图标子集;完整第三方组件许可声明见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。 + \ No newline at end of file diff --git a/assets/icons/logo.png b/assets/icons/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bda7d12b81fbf06df0f5f4c015cc9815948542ff GIT binary patch literal 27476 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 literal 0 HcmV?d00001 diff --git a/lib/pages/about.dart b/lib/pages/about.dart index eca12b2..c83d9fe 100644 --- a/lib/pages/about.dart +++ b/lib/pages/about.dart @@ -4,7 +4,6 @@ import 'package:cpp_nuget_pack/util/svgs.dart'; import 'package:cpp_nuget_pack/widgets/floating_toast.dart'; import 'package:cpp_nuget_pack/widgets/tag.dart'; import 'package:fluent_ui/fluent_ui.dart'; -import 'package:flutter_svg/flutter_svg.dart'; class About extends StatefulWidget { const About({super.key, this.openUrl = openExternalUrl}); @@ -19,12 +18,7 @@ class _AboutState extends State { Future _openRepository() async { final bool opened = await widget.openUrl(appRepositoryUrl); if (!opened && mounted) { - showFloatingToast( - context, - '无法打开链接', - type: FloatingToastType.error, - duration: const Duration(seconds: 5), - ); + showFloatingToast(context, '无法打开链接', type: FloatingToastType.error, duration: const Duration(seconds: 5)); } } @@ -39,18 +33,9 @@ class _AboutState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - SvgPicture.asset( - 'assets/icons/cardboard_box.svg', - width: 64, - height: 64, - ), + Image.asset('assets/icons/logo.png', width: 128, height: 128), const SizedBox(height: 16), - Text( - appName, - style: theme.typography.titleLarge?.copyWith( - fontWeight: FontWeight.w600, - ), - ), + Text(appName, style: theme.typography.titleLarge?.copyWith(fontWeight: FontWeight.w600)), const SizedBox(height: 8), Tag(text: 'v$appVersion', fontSize: 11), const SizedBox(height: 16), @@ -68,18 +53,11 @@ class _AboutState extends State { onPressed: _openRepository, child: Row( mainAxisSize: MainAxisSize.min, - children: [ - Svgs.openBox, - const SizedBox(width: 8), - const Text('项目主页'), - ], + children: [Svgs.openBox, const SizedBox(width: 8), const Text('项目主页')], ), ), const SizedBox(height: 24), - Text( - '第三方组件许可见仓库 THIRD_PARTY_NOTICES.md', - style: TextStyle(color: secondaryColor, fontSize: 12), - ), + Text('第三方组件许可见仓库 THIRD_PARTY_NOTICES.md', style: TextStyle(color: secondaryColor, fontSize: 12)), ], ), ), diff --git a/logo/c++_480px.png b/logo/c++_480px.png new file mode 100644 index 0000000000000000000000000000000000000000..668263d5155434fa7b82d00cc11b245c03cfba3d GIT binary patch literal 25500 zcmeEu^;eW(7cDakF?36JDbn48bc3LDcY|~fN_QyTD4?_;9Yc$hAl*oJhva?vzVH4A z_s6@C#agbJ#WUyGXPYJj9uK0`cT)LT?;-CqKl)XX-G%l zCja(_Vxn63VfLQqLa-FM=+2jFun+qdmyBG_E_nja#pAf$G8S`~hf_Q*Sq_F2ju!n7 z9~GPZj=*;eAOhO||L^}%1b(N&RSnMS)WD31JRua%4se49$*M(JIuFR{CC*kngiO6> z@>yX*1X7GduV{b6HC*FnI^YbCK@0p%FRYgNU|`04G7z)r@b7Uh=x5kU>L&|4$2MY) ztyS0NcLepHW#IMo7?1$YLg7a_F$wPUYHTmy?tXtnBCIa-if{-YePX47A%icUGMI$Ubv}9wz5bEvuv{}!mJ%a; zZ0=O-UDsBDhrI%?B%cbH5$_p@d8Lu71|MoGvr^eBK1S{bcD_2Po;`1(30x9Limd8x z>+sPiDz#08DA3}7Zx)W-(9H-5s)<6-rhPP)12D5kl+C;wc?kUd4fyBgMiGHp%OjD& zB21tdLQ`=4H45U`lR2MNVB!0<*o@mV%8`JawxdHeO?c|26?#Jsyd~&|^%bhvDdZxZc~8#t%Y{5%zcB?E`fz&^-+MWxfYNg}Mjb69mX!folc zz?-bGs&Dwzy_NIay2qr~8BxRt0}l|Gg4I$fZN$uw2|K!-QU8G&$OyP@3;k8$2twg{=s|BijYejRFrwcr5bR$4sajqOH7GkARWg{5O{ofAx-DYsqYa_p=hdJy$L$A+QdZCs@y}H0uOBj7@t>$Kp_)}&~T*KMewpujnNj>&E~AVj_4dNHHK@<;Fg%&G>wQ$_>HlG?c# zg(U`x9HzG#-u;yWGtvUb#zbFGK&nlni8WmjZZwoukY)f!7v}%?XT1qs8gL4SQWIu zUucBQ_Ja5+<0(uVZ0vSp`qmhJFTD*>IOZFY*e<#jsV0V|e*h>#xGzbwM|!26iG_i( zokmS3!6&meE*CN0GSyl0T(KemKL#uZbp4gDl`3*R2Uhv)W?}Y+L7ZcyvXm}`d`#fgMo53{6rn@L z6UZPjdV(Xq8OPRmCMsrCtFTu=kO1#4;V(pA>LZKWZL=YKv~p)A~48=>eZ^d>)yv;GFcwaWVjL>s`~|D6asnPm&}YhtIg0p+LiA!HXbF5V)V8!WxA;GLL=SU?xC%i!bPPq?IHY#) zOu{FBi$i-D5fDm3OkC@ah-?&;V^M1OA5U_}Y8!3L9EvO$>$WVd4}-O8vrcQz^FEyL z-C;R^4ILTm*L{>E-*p-LpzL2}_2gQuYm^%C03VUxR22EkZ997g&#xLT04JEZ?b-#) zt>@m=VVlu}MfgH0A?b0!y z`rL1ky+KFtI~GV9Yg;=X7Vwv7s!OKe_lsU-3a$S{bJlPP5<_6L8X(9ceEd1hFWLz5 zA$1@ScNW?I&|M4!h*y8}x{9D#8DkMA!dM_gZX;Vpk(8q&1oA|4}06R+B-$?bNrQVZl-|!R>G(H`+LGm-0`wZCTF_# zkMIL6h=C9tl>)SZu~0XvC5Q82Zi5~Hc{%Mvsufo_!{xA}SRFes7e2=GtS_WS`u6-p*u#yN|Q*DDk#_-oiULXBpZd;3MBJggA|nqxHEtrpzFo7A*pj4Ho<3om1;b84zN#>XjfESdNtl8CQaV z?m}>rvOF;=$=`f>`-jh(95_KS*)KlScUz}R$EY+BgTC3-zZ_&>D{^2(d<}ZD>%fE} z|Lu2%UU0$Z6#JI?;DE+VFWVIK{Uy%YvCP1j(i3BF%VI_-iWeP-AX1i=$o>OC6ZBW; zt%iL}kA0WL6o3)OHtuEdzX0t`k7MF#I!AOTb@(Gw1Fu)W3^A>KH6u(YsOqC0@UB(} zfJuxAQu>c`E}5>;$c@d;6&h$FTmk}a-*DZ?25yDpPd{DTPX&Nv`ZUL+{~QcP(Bb*u za7=^z8jElVXhV$9S)<>>T_jEyw*LNd<8R5{P{+gr1R8?&i0JRWtT-OxgKLvb7wWCr z*7XO70xTG;#29IMERny>{1NA5hZ9cCD+`ATX{}#e-mZ}2>d#e$n75F4waB|%oy&t6 zf1`xBmZIPrMs>vcQwn5_%R1x=fPh02VwsoFu|{LprrlBFZ%7Gci;Fl7rU1ezg9Y#0 zC44bZ#F_Gp``X4H2)8x$l0h0ZT;W(xXt8^klG%a*q(y)ZY5&menXJ&Wr$R>af#417 z6&Fp&ybg{W;z}rcgrVnk>c77hGK{9gK!v8oyUS`!c#Ir}#=V8kzi@kp>R6n_0U++O zetyN(kk(l@BIA|COGZ;Wuu@Ng#Z|sP|eeUQoH)H8G_+VG9cKG zMaPW_M2-~ls?%?V>e*^|4QH>=pfu{!#Z`mmRS&bR`Wf&@28ZL9T5{H&It+ILbkyl? zGf^tR*vExzkUqnUCz?BRQtqcG3LxjWYL~+fX$Ca<2=xqhF}wR0C&-FZTY*O&zV0%eViOgnkD0yT+sU>4BJ4C{Qqg}lIu z>~)kjYdg>cRqMB^o;8$9Qq7?vbe(k~)n4iPedv5X*U-QQ}`9MZ79{Hd1?Wi08 zSRcw77lUA3DSxh0_j&7Ji02Yly`S`$`o-;KTQPg+MI6Y{9)q4#Gw86J6O|b+>KZR< zAy%P#5s)%Gu8gTk)VFH&D%Ys!b=o!EP3w>OruDk^FSy|5N(&)yEymf^Fz49A)lRMx zVeLiPt~V)%aA!5mzQKKVQj)=RtKs?Nn#{y$K}hx6ePxIHu~EE~Gn^v3#Hv*dcE^zz zx9;r@GMO4HE9=X{hL@K@$a!t+8lm*+F&mo&ZkMLDSOnWyTRqptdi1l_X0Zy5MShlM zmQf|$WDclb`Zn})G^=KI`@iew&D`t0kO(flEcpH@rK}Ojx>=K}nn-Pw#`V6GhKD`u z!2)Pb;)j`PvZ{4l=RuY5*TfB_ zyo&jD2Z#Hfsym&*oL>Iw%5n+Lnbp$$9fAjdnHHCPSMMZfTi zAv>sw*jhWL^S$oPHzcwVMQ6eR1J^3CFcB^|T`zOxcOn|^>{y5v;@U`zQQ03!L(?~u zVJ2=kF5mw|`qoAFWU@78Bi}R7pDM(xmVdGS=cRQN`tKcdMVPe}>W0|LQS$QzxHt!p4@RF-xx0 zN#0T%24k(p!r$Vn<+{P1*9TNC>wU1i-|C))T2e=h(DuaPabNaV#aY~Muo^9 zaZhdUnx1UTv>b~hqMwYSC|wv!^S`5?r3tR)nOm2Sd`#i%b^c1Ifrr%^67#y(Mqx@ph>x)Bk=VlwR+B^#ViHH_||HA zR?h-_mrLO-DWF0TBGy2~lJFAYONde9a|J5z zoC98;r-dr)l=ADvLnEF|ttH7~Yjim5#`akdqK8ez*h~vI2A#{-P#oKS1Fm0-iL~qy z;Hc;?*(|FbYSEsV{dG)SO)dhJ>95}}A7+fsRo0jCH&Dm2UQh3mEL>c?4bT~Qqd6SX z{|*l$5UpWP#gNzDxBQP-su&>7*Jlrw&YrXyrUW3MU3wM26XTsP;83Nr5x8*2&oa<> zjZYJ{ZMMr$_uc(qZ!}>1J32Vee_wNXf zhN#0?j=!WsA2({r1FCC=k84Od;I56DFL{lk_xi+Gn5m*y&z0%Zp+d7E>9v3HAjs-n ztCYFr&`afbxc*w(zm;4edt2jos567wkOzj;Vr9vyUhq`p1P5$8RRs;uwl zJCy}I3panPV9Oq_y!TtUlx5ck*5!=1#tG&sC=ZwKR&1lIcWd^}KUm7PGm*`jfl^)vklMEwb?YnAtH9{gG$W zgDds0?RGcN3GO)?@-1*?hx$@!ckgB7ti1 znHJiHK7*;;S7^wUK;7Ri?-w=oA%o+YNQXnVLfY6Zd-R5ar*CE)18}1|qoG2mL<`O5 zNUW>C1z%&PFIcrY<{`}mlNS3Z6wXAg-)fm(`KGR30j!v6$gS7yw7 zwBygXbUA?B{bIu@Cv(FmvLe}!Ur@mfC%&iQ=ffSPoW^Z)|F>k(dorp$WHl_6EzkkZ zbKG8A;Iwf&6i7+@rI<6s)hEUW)#SZ{eA~Aw3*lD1qgg?~*5F>`Na*H(y9UOjPt%(lKFC=-uO6HR|LHL#?S4vW3XT<@(ZC2u~fl|{PD~qysZC| z0h1-a+8*P|lYS>Lrc2Fq0XcH;`yAd73fWnLsKvkGVu<0~=lo%Sdcg8KpY{1ZF246I z%M`Wk?9L>NlmTlT2RFLy^Jd;A_k{2h9On%BchmSi!|5kgY&1}liyw?{qCd$MX>Qpt zw?XvL9d~_~%YIx|@{z`0iv-js{7TmJ?+)vaj3B(BJh%&BawuIR&m72Fx2VMti~`E2 z)vF6B_UMxp(ZGbA893%!K>EWdkE1P?Zu+Zm>8l^XDE{+wfZX|2O`y6s&;KLWZp}S4 zlFa2=nR$5#yGK*{?0At(IwOEr5OSVP8xrVeBU?3Vf<2&I&5~6T2YWm6fNm9xEX#et zIMy20XrP1jO6WYN^xr9m(!3FV2i-+wlerQ!SEQcv-Qs4@XiOf40eKi)pGVlu5(H#s zKwGZ^(d_2<&bzD5EJ?MlXQQo-m57IDal(YIJMwCXGpg(nplANHd`_QuP`BpNagY$h zLfq}FrB!2`yAuH!mq*Z58hN7FcqF`RZK@|Oh)kAPtDE2t*dEh$I9QT3O zoi^OdyTmdgM-e6m-XjMKZGKYKHR2@r5DSj0d`^VAYmbzsiy$h)6%8ZAh$+uDdVh<< z^+p^Kp!k9`AbP;NL|G?|CIV-u_gM+H+394MK#t{m1dyWv{~`*6d|+zK3t7`PLg0zF z$Z7;8$P5eiTeV*a z&(3P)JwWE(oSCO5cl`-E7Ml z&{Fa1>`0_9eOF3z|jh=BTirhtuD)AFaZL))!$y#AQ0t>URnm4n04myT&mojrSkWh>|xy+PJthIY3g!ec&+V-*%;Ct zTA%VSAv9~8Arl$L4DuIJ8kVaiB!b(UI^^<6=+!^`=3mziR^+^lXwwi~yU`a=2YU$( z*Jf89@&EqPKqybLQd4wWy*bbHT%cM6h~g;mm69@Ttj=2j12lOp2E1c1N7^O#yyK4H z=#;Sw3-wS+ouk0T+!3R8u2MJxU;6ZT-|c>dcFFR%CIJOndKK+AszUYA;bD7z4*u&M zEdeB3gwfEfz}Kt?|bnVPA`&%P^9rC^R{X!Nms=3m# zCoMwx6peF0EL4yX7gwD@c-|a6>LT2r0+cEy{e8mi5T*L@P%W z(_m19Dz(T+iyxB2M1AL;8KNwFAUWw<;HcbAP{ZF$1a!a&rkNL#e%dCKVzey7Z|&kC z<*F;cLz;Y!bpm5i=#I5=rqhx{Tv*D7YEg$F3j=-Gnp zcseT2$9i>?)as{wvv_s4RG%ZQd02x5Ms)4Ioo|buy6zRU@m)x*F`9aU-HR`Ks>0U? zqNK{Xq*FzzvO~u!0rha85NG3R>n&(3)-JifsW;2LM5|H5gf8SL(0Z5kKuUio{1xo% zfclNCUh!R1ec)-wCZLY_Wd6lob;82yrg*2-MrS6#D zYYmcIIUx5n}-7R_rPHBmNkKjJ3?b0UCAs954A{yk{1B-rOP6k}+lWm2g@ z2Xy5L2&+B&{7MwAUR=6;3f>a(@}|w(~yh;jk(Ov*On*8EQf6_>lDIPv#tV zuB2j~17iy{Xx@nkjR=>{!oGMcOLnv(q6gwER*iPKmsXr+p5$FHW!^x^e*V{cKh#lKOA)O?oPMrz24VW{7CEk%G?Yry2L(amGq8@|p zG~)m60$8yCMiM*JFxV6~_T|a`zIne$6^p}```eqz-oNl94K5IcT^+&1H{%jq$}u!G zPb0R@cE_iIv@n>u26F$q>c)`}Z^?Me3G!X$?~k*ZHtg7wM|Z|J$#5z;*WK;Ir-~V| z<@+9pmod15^ka+(2}(!>0AU>8-q(7s0mP?tF$b3b4Qd0;lvYrIwgQ;3nj$0)TVg1{ z4MoCm8Pd4elGAVwlI2#tR{JB<1@oeJon1FSAM`%(h?QJtS;2g+`(~^ErVpX+kN2rU zYQnd>^jXWz4sL%C($~S%-dP;S`JC;PtsX#!VX=G2O3D-Y=hr9Yz4s)pzwT~4_@L^u z9fMJa#xR9qmh>|Nt}68VUiNRBeFp)doONYl<~@FZ!A`HB!Q6@T4_v@P(lwxg355yX zeXG}qNX+)42q$jlZjL~E%CwFk;q)0%ibXL)^gX;xH5U56IlBWcY;J?MSsG*O(*taa zmQQoXVtE+yBfuH2Dr0cpVE-<*e63o(tnI@c?1cGHTTeXLaFZ|Lqs5a6+e&mT9;uuR zT>7?YtDcm?T`W%mbhNnrxTF0a+l4g}WYtgeI3VpaGoi{$x)CTF?9JCjg#R0G*=h28 zRTogBev?RIz?Uo%lCR)LZrcAIro{Yl-;3)%-`fYs`^cy zO%#1otz_Etkh=4VdA98Q72%nuy;d02D-`^S4x^TGhsVWF)IR5G{NLWO5!qgAG0i>% zYzbCFN*z*7SYp5hRNyDQ!kxM|_2C*fdf2%JbLgIz4$Vjwkk5Sq2mO=j7qU(sb~l;# z%D+X^5|T(u3nK*huU(n;S~W@T8bm=$!Y#bq>q%KSyLJkTazu;Nu`5e1d#+c4p0=kH zCGA;iQ!hTCwU>3D{oPpmb+6>Q^V!@|xQVYV$IXE@)?j%#G@`u}{>%Q>Ehrfg52T9s zXS3f&yZheJrDJ5;?Piv2uXdJG1y{+rkzYFCM4K#-2bdYM_zV#%AA74Dgk|_YL;SK! z_cRtigkGpkbSGR&q{DyMls84N6@Ron?B2zhnm}{CG$6h%FJIhcHSg>A`aF{G@lAXa z;0i?*-I^!7@*eWCmiQ@Bl_9T_H3PhP^;^~?KqSX8QswvdC}QQTjgRww3)gnotp$;9 zomDKZid3CQZzn_+ylmAC`D#eLFjXS-w)lrP%KT|n5X}tgRo!J*Tl<1-GLJR~{UVZT zIVK?}pOzk})*CpWrTnAH%T-;=Z~0bx*KRF*l7wx#%g?-gpWFUHh_U?!ro5X3W4*g@ zXO8S@9YLc2z2Si~Wr~xns~2PYTjheYHIKk0r{ozV$j9%0NRcC9bdYNfGS`G~zWmnb z>EZ&DO)(J(B(kIgy#GG3vc-?a0!^eGY~?2hBu!pufF#epol4!_R~6-)s#(~^Tw4!L zTa$D!IBqP(-fG+r$I10Hmd4HV_?rR$LXmt8*=RZta(BGCCa-;C2oVrK;Xb$+*45sK zDHEsYRbTnC0rVU+h*m;W(|p~gsE!g!cD=1n7L05 zj$}^w+u>xt=1P| zTX&DnQdSP=f>aaI(LTCcpUg>LGQEe+n0DuE)UAF_LP6DH&s&&pFSk1VWUBk*ob;P@ z^WUafs$lQ6l1aPx_NyRJTOevPWfalhsel)!Ej%R(cHYEKre9t5mG_P0zRsc#buLMj zL=&Heo{_v+Yi zxwhuvnjvW)?3lm=FcQuZ{`Aj(?S`6X}yr9IhmtmpiBdn zpJ3(QX)0}ThcT)PtN8-$%R)n{BC^Mq(pCd<_#KchG@ z$IT4YhWA3U2QZ(5mIKeS(?uc&N1?Pa0&i#<``f;g8H}I96390sRiUMvD*f%>pKm;4 z{xKrDQ5EBQBl)%fh}&0da+VOwC(B!!9XYT#YL-(cj}R^RFu1|gEspafem_YQysUHU z`Vh>PGM+!>Yt!BcMiW03Z)bB*{Dmr-1gC~%`w0~!OhE6P)j1?tlul-u;(UC4wF(z! zj0wP;FCCtY4A;}r_l-nfJ(vE+ZY!_d4STTW6l%z{uMfXxz`bqg7n2V4Z~*NtFJi=l zsShMk-jb>_DwDh6+dp0p^9D~&F;H_wv5YFt+N(>+r#sp}8;16WiG=Du<>AV|PvZuh zqlv{dpYC30~uERt3O|;+BgY;lg#q^zMf{7d0w!D*s()a(M)$w=Qv3dPCINya4Kv&cAF~%OK)cwIX3drA*vb;AL#03A zv!Wn_%Jj^9^)!|Zu(lc~P0Un)5d!R-X{wqqcHeln!1S{MDE!9S%T}TSi63FoR4Yzf zuWLVdOY6-&E&ZgrC{5v#C1$-2X7hO11CIn@3y;{3S1e*+ z9%YfYYkt;>-&Cmef{j>rBTj!7B*&vykIdtfQ8zq|)fGA6+~Q)%FH)qZ3SZDn7~$}1 z0}XWDhymMft2w{?2N4&QJTV0@>eDL4j%nOsCz-2_^w|)>RFLRe%9wj6t%ep#qY+Ha zS?1XIC)VX^yd zb42YdI~OuH9}=z)G?A8SCdG8X=~gvx*w#|bFkRh(haA$r1P|0i_d1F&KsM5-=Zcj!<-ZU?xt(NeFDOvx{6^s6TW-0If9~SKS%0c zug89Z@G$|6*Yl;GxR!l^^P@hqDA~#Zn!c;aCEXGq6-;mltp;0a*5cnVE*2e3+&V>Y z6rqM=)KyX)THbjw_7D>Ht>?^;d&n2UqXvW4$n=uC6g9q`A3xegFhN#(V|&sK1oGT`CLzbtyU(x z8FfIUs7UBg^Mk@n0v^{OzRlyuvx>oYNs%j_jnO>3sv1XQz3sj)3fLzz9vyDu| z5nH*TQpWuKB_cUNU{&remWl)-E^MAC=MZ-PDhzUUR08ijb=g71&-Gpon1SO_Tmvm= zr_898LtzGN`OM4NhOqDJWkA-@Cv7hYEZ#Wk1QO_A?Oal%{eh5wF)#@*{0JfXwfGUL z`~Bp(8Me@7q$4ob9$>2c5F}asgZ#Kr_U~{^874&%64Vx0VAA#PgZi?X1Fwj=SWed! zktD_E4VzOMlMC2fk5qRC)-rgW)(-9XLQ@UXjPADT*+Rb6|E`R3K8NgWPqYCvqQO67q&WfXorRuu5&jj^PRIc-_pn#NM1}Of= zl`=ecSx})%BuA$$EFpo6y!h`Uw}j|HiSYkqslZzmL=D>Kv1d_%UAyuO=2rQD1Jq>0M0|*(I_@_D^r^799(FvE@#-I}5^6?)q=Yk`;VHfJ2OA7Cm56n7cjlMbC6AX@r!JKoOQ1iwT;fla; zSy`a^0nY|e6aHD3aYeU3E?6bDAybTvO(sV$QC~=EtfQFxr!z@ZBk8fv>)QS$05tzy z_;mT(hm3y$Q)|uI@&B044Jz|oI#q@F$BMYTVA#C?FP%E^t`^cGc9eR_Z<7H$${@Zb z8D**_!whIUH~JaxNh=Jh3<-_C0dAKH;}WxG$K*TOIsFEvt2;0^1BvnQ3$nG_(;dLvo_Hz{v~ zwX(Wc9k64bNB~go$Kx*@?!camN~v@+g)i9~#!in(UyJdmHB*_^8U6`mcJ_JeZr^`y z9_EDqv0}JD4vK=%dCw&cg0`V$E7uSy8^rFAR*Z-QqJgOmtIWA8~k$X+e4{GZ`)1wFvDMQ{aFz6LIDAWWRpaWY0$kxT{v-#+gS~% zgX-cp@AZsVij-j~JtWh9KCJu7iNQV$Z#FdkO{L-85?I1~Cj|s52;4e2KFY@w!+%f? z@`kv+s@jiNv$|}|Yz;C*bzDLsW&d}mpr+arhYkB@4U4nucfWfwp}c@rri9AQ9#xQ! z-0||Gek1fk0x+Cj9q_x9PiYPcf>i14><(4r(abbaXZ6|s+JiALLl(rSa{drQbt9h8 zZeg@U@QSq%Vb`Eo{POG_^VM+tJI#NV+HqsMtpi=JZO-^7VfDJX94}B8axK|wfHgQ6 z7Wk61--q=BWMcg_U9u}Glfs?|Fcxmi)yw!(fK=iZcel-?*M14IHfWiO<(@DmOsTaH5Rxl$fyeN1u zfc39W24`FzbDN-mTk078Oi{$9w}(>J8c4F*nZMc(<@Zu?94>?28=L##IM}Rpeod!H z8Il}1L#+e9rss&=WetycKvpJL?qfyFrea{NM)m~PL{JI@UQ z&8-F2-B$VHrMRaC zj^Boe=3;6w?5|ww<<}rj{``W+f}yY43jls7nOtW)7)@x}q-dGb|cF7%(On z%Udiy2x+Gk*Z}KfJazh8ZwQZ0dsW))sQhc%Vdb}LW*ES~hIo=zu^P9e&)r*zkf~tJTzLmo2u<$T;)>4cWV6TAV5#U6> z_*yI;I(cE$XZ!HqZS)kI@Fae-;L#0ny@)^k9;4M5O^bs6x=HVTlJnhkJrd4M zpldr4C=VOTUegc_bO`Um8V+G0Gfn~ny|0a*EbSPyc)ng)`pTQw!p~=F=mEx4O9Ohj zuc1Ufl#TC{YHo;+F^qvDEheb6&qtDO1q*$5Vm8!7E#wBsX7Ap1#?6lZ z&wIv;ysi4R@5uhOBWyd@j7)<^$S)d@Cf~p_Kc?_>sWH+D0sxNcXQBT#XY$6C1aB12 z=-oam)=mbEx>h|mLCB>*zTrz{mkN|FGlu6SZwa=O0b4gMl4pM9KCU8z*c9(bj|1&c z)FN7H;Oy)U%`-is1Jj7*UG%1v8q; z06{?|{oyU>Nle>U-b{#)_A*X_Rl zSybl&1EE2V9dFs2$I5?A9rbushA-r(P2&sER8)cl2^VvY{M*Q-niC4}p(8PF4*-p7eFJ*|wpK0oQxZ!Ff@ao?20S zjg%v4o1=z5+z(tNpcCpa`B8Bs@#bF1vSF`Tw+l1m>ch-|G4+I$1R;yK<{uNMyL>-= zI=+9OrB&KU61I4xYrMN2J4G){4n;S-&#JjTSeJrc%q}$w^%LhnIollRCo*a>hZ^$M zSfD>&0lz;rY5P@w>l;;c*^eChC+C%r&1@e0i1_`sJ+p_@Y(&!9?P`6>m8#yxaq_;c z({-7o8lqDg<8{3}GGn3|5Q&}7UkfUL23KNs$ZA^#UzEzL)#Jo$+aNu~R;PXxFXW-O z$>%a5!b9&$Rc7g9$l~!1%GyaESrK=+kZ4jR@MO||pO137!R}~neSR;;ZdzlaiL-P& zs0o0e9#+?fQ^Pg=!P`ZQpsmFrg)xCfFP2zGrE9^?zfgy|3eCcVy-#Np;+W4J5a`JZ zHsg?H;k9JA_3oFfx?>XKkmp&Pl}7{b&fM*NGci93TI9djd^h8|^ie|Bf7o)tqlXrN zGU)`7P@J~{T*o-Vc3pG~a7{nNIh{gzBMZCbE;=o?sF1RTY2ULm{^3B~h2kL3;^;&-0hyEK+zI~K)QX?y0OQQ!jOco zNt2A8?r^pi^IvuOxFMmCq_%flk3(ZVM+-Hi%YvM1eyoT)K=5D-^tC6xw@G_PlD%7P zblc+QbEqDH*jZsud@*QwTehF~ct+QF(_oRpU!d609r4V3wfFY#CoOq%SF==R3EPhl zZE(O%DG^q^WJ@Sih)Vi0LONn~2NTzvKn-mO;?&p^GwL2JB4jZ*Vl?n(u#>m%5^>7L zY&OCzt(my7{|$3A1=a-|gHSH@AC9s^;B{fE_}MF!d{~8OyMK2Q>rb~VT5^j}jqIaN zmIlfXDY$deex1S`qLmVkNK;0sRyZtAST8F zkN=fhaOVpNqOk3gT-F+I*h-)2TJC z>K;nPz2nue>xbmP|KZv|=BKJ8cyj=ug19l_x4Sw&?(&0lDa{?|&*uLz>wmh-f08us zoo6}NiWHRh7u^?q{{8JPRC!Zx$NeHHX-%HQqL(;@%X=<&JEMP3Hm`ttls5sYo5vw{-ghG}hMxk}awBkTF`v!k2ZZ+p*XV7&p~asvS_&7#K**t_JI3jEp_V9b zkBLtoB1V>QT@2lYw8Kv>dHq_%8j!!pWA*KpG0PKv?{?0WF*~nGdLwBvX-SnK5D+4XX9g9gI3){H5$LT*1r5!s=b$FZ~_y8#*JT57c>vFEO2Jf1zL~$r` zwtJXRws_ZURDw_`B|&EkbhT-EUi3nq8XOX0zFgNO;vxSq1=hxGIy#$oNe*(zes&*A zEV@3D-MS4(^rg3T6oYhHo2X;h{uNRptN)F74_bLJ$)NYnppV=}*B1hnodmzz#iQh* zmB0UGWC3nBCA}Ik32#}_jqVdT;rcz3H?)cAF5bA?VBxw`Q?%kHY?+#=>4eWM?&D;~ zUU@g_=V*Uyr5&@HgZ6YU`0QgZ;W6mm{kYdox{&o+od)dmfcJ2-Ox$?3 ztgN}bJKg`4(RgC+(32&$d$wbNu!*{a@!NXZ7%(;~;C$hF8<91(jyb@oD;M@;7e)6H zR*TRd&d0yU8CJ`pwxSgIP^cdNeKN57IV~UgD zc_8)V#~$96Q-)NhQ)e-}3@k*CdQ)=S2&ur`_i5t-eW+dW;UsaI``0^uKA2b4&u~=U z^WM|ohg&jTSxUqO0!2O^F@SaeYWR~&N4)9Y(mWMIu`~Mekc+dEKV8s0EI(k`eEeJl-0EDua3mEIR3tO-b@m7yjW8HF+ z#;VO>|E`ONiY>HwXT#zbhIo<nr z@Xw8`wNpWv`8NSh$s5Azo9fC+q;G5?KOddPJ5*>AvVuDjLXl+^a{#Gu`YoEd zyvmuxU)iI|@w~9Im&JY{WV^&fEHGI|Cq0ZmN z|K=}q|B;SW!Rp*RHgmTa8IQNN+Ph6UD#52MilrRL$wJ5@NavM?`s|>xl+WQ6h*Tb0 zyqUQ8dAt78TQx-WQmdW!hi+s>Q#^1PTNc;m_h5QF0?uh?K@DB3^>tF2HaVVdx|OAF z)fzvCX>|NydqvoUZ;c;WwVTnG~T^s65P;iiGV6%XWcB z+j?IX<#kfv-G9MJ{Hp*5Y|7uen19RVCFW0lb1e4`FV2BKrbXGjYV%=^WZE^-KQ4JH zwN}&&ZV3fJY}EnW`5dCM1RVoY+5&5vIvr`kO7_5Cj+hBUs6Jj(XW1Kg3zM&v+^E<( zA_=&lW@gFIzojAPp3B%x^esksX~o54yw_ZI2A2Cibbh37v3cNmX~;?7tMqmz1K2ac z1)Eetugg%an6+rUWmHRFDdHj)^lBA- zB|#|MR;h6WYS5gyf|B_VQ_MbH)ZdEq4hyyt{h+a`9#AM=j4U%qINMvH>9? zrO8ag`{7zJHuFlXiGHDV?GIGl8lfE#msYw3dizcQ5`UdWynxPMgg{qsEOOrXmadI@ za%21ZFk(s{7C4|@bupx?HIx!^kU^(Vr3nUZ_fz^O=Ov_4W%;oWbN3Es5nKm{xT~1a zv-SU{y{r6-`U}>wEDaJ%cXuNpxe_AX-MNai^dhi=NP~cMBPosa0*ewNozjgf4I(LV zzy9va`!C!#`|5noo-;FNX3jIunXjMwb3h&dfVBdpp6ctY2;rO)Pxy&HK1rAwOVRvP zq(j>;Q0Add`=k2k03WZ9oe)mj1Dc~ly8&qr_~Id2T(&`z-^1$uw<3|;_#*)LC<506 zt;Pus>ki=<6tC)P?oBC~8-=C|5tmOnWX&$gW}qikS_h!UPN@(t7Lg@0cjE zseB2##{B_2tYLfiW+dP;m*N_Wno``(SFK%97BkrT_GWU*9V~^pLKIDjqg)z48<>7$ zh^FXn@`RLW`C{!3tIDhRLOi;p-q+LMJy$GfC}e;sTtA+M>qBsIX^c!Zcw1cIoE57w zFZre(pK6BnfUC~lHW}nf7BscA9{hN8bv(e;9n&F42jGAo)5EfS?vGA{^cMFuYS)#k z1N&kFRIqd{Fv}Y^mH+N7%Qv2;e||ay&N0rBp*C3M{!xu>99zPXyN8r1|Mh3@rHw}~ z!#!E!Z*7Ycc0kLNV0ZW}4w5A;zo{;_RqOrC^q^v3CU;`AbUm5c5*W@7R6?Ze9Ibq! zA`l0@E2WWww6MEBzCuF19kG3j9zRQTG4MC#|S>N%;_qy%<7^-LGzAM}IPt7=Xc}dU0Zpc~f8GtI6{F6Yd>>K-vB(NsbR!NIM z`}HxT{37r3dO0Mzy&C#9gS4gTJI9oB9;-0KQ(CY(&3SFWX`|W;lZ5c&*P7e63 zaQO%YZs()+pi(iiI!X)=<~YdV^@FqO5C8}`rq<$sT=%breT1!Ole0LBIaGlt%)%Cek;+rRxV zv`P?MBymjRe{5AlLK+p)`{;Jif{+^@#~oDVY_K=JA(i9N8n~>!on@f&G{&CT}89_il8g-aFrw+wNU9yuYi6X zfJtLs6JN-4@a{{Yo5mysMc9vQztax7>0P_-4zB9N3~mh7$szS>kAF&6cyQ)BzPByd z`Gno08ZiHX;Sj2Lw+$@zK(T!_P#VYh_|Jh_mEX$?8;#iEVN3vWG;N64Qy^}yEus$L zSbNk-QQiKG9~b^MU;JDtesO5z%E*5$!+frHY#H$)ePoI1QC;p3y- zrmTG1E>Z7oY>oXdB^$I-wmFf{UAVwzF^kDk=(-rf=;S)Cc>s@dod(@bLu4)~vjQWWk*|4^N> zuR)ow#EE@(9G6|zRNn{Bu)F?Z(drHm$IB16AHaP(6#yx*;S@*)KuB<(+;4cj%by9aWdSfDA-d6OkL}T<#>-7nq*bf?#zTRk{LKMxG-=qqifH~h4d$+kL(N7EZJp} z*DrE$Z}t|oq}15g>!Q;_{qU0%o-wO{b_ptj5`om|RZN=ZoE*D%X*+xMXw(eHuAw3! z_OAYppn*+?roH|o*~3^K*Br{;UEJLk5MO$f^xLLAq!(GNME1qmQ_Jgp$%&&IK*4ol zh}irq?AmC!Bf9ve2?7xBdc|k{p`+-<9m6GsH|s~6?tFntWn0%9>FA42K3XRJ^U)S( z5k0|Ge(cr7K$*OFwY9?g8sKqP&^{8=wq@SFdHo4l9T|r2Pxw!^{PjMaA7(uJ)Anbv zTNXUYo*|M2b-12V8!c4$T~whCZ59jLY3X6@=cTG7gypXm=W+o8Ut|-iohdWe0TT1~ z7v$(Z%7E!6LVUe7y1vj1;I*tyF!_b?c4Jguk-Y~!t57}9|n|iATB?IlM zkH^8~d$S3K*!3JeY5Z_>b(zl(p{k!=j%X>^9(r(6%TDHRXTz|oA`MN%2nq|Xwf5~r zElmjcZTQLROm}U6Q)o_hbOI@@cI#iv0L=A2w58%eg(@s)N>fG6O?Ke0ru+6eQ`~{;!biI9?5jsLT2YY_fjCrF2;$*G! zyfyyk9to#?Uoxl5DHu`+7DTlqsdO;exX zz7qp}#3dZs<4k{@-jWe4&c!hGMBK86z#&iM^2xiNvw^hkjn#v>zdv5uHI9%FXttM6g~Cq|@n63J|13o+atBaJ+}wgYT}-@pG<@VaKsAW$N=>bFo2o+~0WuwvkMe zwi?oqpPDG%pC3G`zN~ax5z~cmg=D>|umW>#mU91#Vyd5nB5dLgF*|ZEo#?q-c5|S@ z^gR?~p|RO_C!OCga$B~|v~ZPe4er7M(a6$hU%a@i`$4JOLB0ozxo?`T94MZAZ`N8W z2A>MvV_~0tOVOe|OM<=wOUyRgFDx_JPF%M?Ts)2_1+#v+-p=qpzulPnoGqR_`KK%t zlUpcOZ<{qw!qN_0gSfh#aI9p?O+G20iE-n! zmf6eop-!2P3`{TZ|Jb#$s$f4|yGj)vlw_LhZ0D^iAsy^-@$UFHdJnkbdahY_+BWvT z%zx;(!R^|hz!aSnovNg%s@2#if6RA67sSZQG9klPfLABe~;BnIyi*$c(%wp=jvNo`HPL@(=pvYe~X|!v7Yla1FK^Vnj6arKNbdI{V6GZ z4S(c7{ZH)CrED0!G}lGNs_UauoIMAh_kLy8JhP?42o;X|WMdhIbKjBExZ?KA=dLz5 zGHTNs8S>L#S|+VOw+Z6uLrqRssvyo#H$tlLE+#iS0esG2{w7^eo*aHAFh0R&WtNKq zZgf&RcZv1Ls-9hLQPTUMlm1tD)-tdV&YYpG6uf}H&xZs0h#uK6JNHV)Dq#WZfgk{& z2LSR|1*N>f`@7SoT-`nnav)Nbp06IYy=S2oQIxgjexDh`37;;3v%MkX2YN_pv7{#q zlda8a#mbZ{-S8UfgmIgQ9D=?>a=g_Imx@6@c>F9bT_H(^MV}%gU@fMk>v}-U}nRQVf1KC*L}~ z_SF6|3k{WIGSN0a#PBVJ_noe83=$hF!5xA zLWk*Lhqoko++HQmSXm+}?=}AMTp*6^?l1WrF?EeJw&Rs#e9OyT6X5>q+BPRfTSo+R zmAUX9mO+Qd?ItY&&+=q34b5E!8ZgRYO8uicTjtt!l-G{yUwhrt7zn#S3$+<{`U$~l zZtf_Kv5;`$GU-|)Ky_yb+`NQsw zw+f$ke*GA)`IpmmLGpePXWu@Z^Gx{VP9-DBfJ=^sAE)m?jt7d*BfpMnnBZ(hdXXk@ z2V5R}XuX;_0$?A>ICltceAMrylsXxYo=;^a8O)4UN^1uE6iZWiS-3KXq*QAx6&ZG` zy||i;vux6I@-D&mz0wU$Ja{)SJsNeJD@KA@H*u$6GMqC!*Y`swyKMvI1WQ$$8We5Y>qFy$#G3He&_6FDbQTEAEec;fG@9OhqZG?Stfq zgJ}P>XGjf6Nk{caqubdS$z?iS>R{}|e5TL55kCEH8f792WMF4mGjLxBMS&%2NMP@% z78eL87{v31$YBrcPciw?3AyFg?QL+fiXPoyIkodrJoG(rX~I!A20Hqe3RiT4AGfk{L7`e#;44hzJB(q zTf3D@rdJEN^|%}IJmME8b*ZD{PR}o?J-VTLzw&A} z*h%nJkHSh$Z+Nw9aC)zvRO?UdxSB#wf}!&Bth(T-NB{9;;%TVrm{@$S=};xnpiP-7)|) z!dZYkr;PTOxLJQEd>{Pq%{j7|5rFEbeeV1>3|^D=YSpc~uFtaoJBJ*%(q~9G)jjKn z|2tgk-gCajwr>6iUGR}W1u8bbCU!LFwx_NM;V5`5OfHK><=($KwvzmqX7k19+FXizxG^z^hByUK{@4e@rDI?H}VvDJ@XVPlw2!` z`WUNuH=o+_;O~ckvnqu z0}%nv(d<3N@I6iL@BDVPWpiy#Kx+nmjU!1UPQs#pSO&{QpS+T~?Iy$2PB}Mz-Se-; z$hJDdQ>s+ElhUAwFYmSg9)ENPyYylOv$;qr#3yPfwFj0IKg2usnqeNi_1z`7wTjH+UN_-v zMj(?y`KW{J7^4}7q+z6|d(?I5j6D>V0MuB2&iNk(_Aeo#q&z4zrpjU>=>e);bG3)v z!-w<}1US*RC{j5QyJsT%ocXM(z2p~viF_~ZjfmuJj2M>r=oXylXm{tILJ@DM?1-1c zOvYA`2PF4H%3;KQnNQi$(q8E3Ahg;{a-^aAOYEHEs_a{MN-@GgP?ml|{x9Vi%OVY- z{$FR`-xh^*6d_56zSGvZzQRn4vC`@?inoqdMNAffT`v`@imW0{#;zo;v+q9wn^@S{9&L3yJP@{FDYc*3iS?Bf z%gNVm!pXsRCjh9;%^EjFIa)B?I^NC-r!V*w(kX9r(w>gyai!&cIKa8$;X(|r+Oz;v5pZn4)j}wLH(E__ zcWk#7;Vo|ZFb{0TF)rTKE;GGRAdk$_&0Y+j_&Tz}ylWmjx3G~IGOMD{cVWx~;L8&q zJ1UwfdOX<|^6m+>3e>7nm%%=8^4d{CYH2cpXc$Oh!#4j>3-}2-Uh$f#?~p`B65utx zB*TraV|p?dNN^VzlzTZk0{vHddt}<7c6$qfv$=L_&?^}4F9A?umCBkH_c`CmLguF` zisrx~Cy>NfQ*HRQXZ?*&BCb=_TpK_y%*aNOaW@a0ESMc-%V?ge!X!hZD5G>cNmbLe zNZ#iOp1ah)0suvzc@r<`uYhwzN#LzvQs4V6cJq!auhesU;1>@&MkY&F8 zF(x3H;rBg0`~lOj7gW?I1(KHuhMP{mbHkyNei*}rp+TxE5Aj_YI$oG3;HPNrd*cLZ z{vM_S{~a*rdJ*dhBujJviWCPXcgjuj<@pzMF1MV$L4GL%1INt}U61D$cPn)~=}}7Y z_UM1@B8d_GzdFt6SF#69@}5kXn+9RLL67zuq)w~S-4 zrHu^Ie(lUY{<0MC@30soVF*mNDZN~5ge*EBlF+*x0SFv*&P!iNcbs@?Y{BRLv?CWF zQ2LP>-{stG38`HA$4Z`@Y^3~KW+^z8$+poZ!DQ@O*Ff@-pd7|*SP4_ny~o(0!>9H= zsf5swG6C|)T=M&g=)`R4Na;DHpGwo*cVem=&xO8X&5l!MiUVSM7BhY zhPC&xXzsyn@-k6vV_>Nn87{N11mefOLteG?>U~l>-DsQ}cTGad10pHy4zq9O`ZzVZ z5{*x^&m{PdQmH`*XddYHw~K*pyV*`w`fp^~6oeUysg2@HtmvKY+S>}Jq}xnM1A}nm zo}q4)&BQA{otv;p=cbVH0Hd~=6N`RT&R%)Dmstgta3CIll<-?&`!y|kxlO8(!C5$@ z)XXT0SWICl`lkhrT^1iQ&1NI$_NzAkO^6iqy!mqU)M=GI>u8Ugo=6DAaC|H;E0c;k zfR}!1369^QJJ=ZnMygRr3AI^e`M7sa zlX2Ofp)58Jl7?!G+V8HwGg=i`$+e&Dt{ z_1e3#@ryb?9yms;V3iVS;gl&5^m#pk0fI|z7=~@BtBp;^p5&6x;gr3-JQAL_i2*L+ zUAws;zx)ssJm08i#k$8EfJ+WBTm)&a#!SM2NEfNjgi~)FPvDq^E zqT8(G?o;x8j6mH|GSs#RJUZXIxIOyXYNzAQVE_y&1jMaW>7wn53o?+8iBh@rz$GH-qY$XDz+kSbpo4)GpM4`@_ z9=M2&L>b0Y1xDC`rC%mK_Zy>^DenKx1PsN*@>YO|x0k{MNBo%y2J|S`9!h=h__`2D zY5L!(wQ$m@Y0j}%V>el=`p~6h@ICA78$;Pa2DIQg_&G|Y(TLwC3H9c+M>@gmP{m5# z<}$s~GhN5+naTp6#z}D@j&gVP`1inOo@Qsx=~ph)m=sXLpWG?i6D1qAPU)2FrMPzfW zBIEU$v2G(57F{#RQ3)uUeXAIw-SWLUh2&tLv_5qbY6T3*5G65D5Gh4Qw|^yP`jVT_ zpNj?jRYx_=9MsF%fR^3hd!=1>DKW1hTW9bWssfC69;0!3q|X>y73YVsAJ5DutMf-6 zgRi$|N=4l!9ehIxJj|UHng91xWASBjBd`u$QIz)`_R4c~eIdE*%CV^MIXL>75%-uR zsuEC1rOem%FI43&`7r;l9aW?@kh?9sjES9$hC@c*Sw=NzQ)(274j=3hfX&66M2@g@ zDBsU^@P`o@|Mt=-5(d>;3g_klM^%83ySP^=OlB=$pUsHeeC=FrYR00g|1gry?bl$M z@*N1xenI54bbCEInQ~<_N`c#J5r$2FbX(G1kN?rUHkG*9jIE}*@ba}t1ZhP24;HLU zUv(2KYDN#?g5FJGg{ot!}F`yTn-sCu3%uEM0s|Rr=^j1@=Ny z7iC){U>}I`}$z=_50K+$e+B`wHlbp@AD zH1{_wHBfKn2n2PMri$;qm(gAn0V3c3#+sBu5^DCk^4F!;H^z?zn$a=a7b8P^Nx^>A z?P;CQ_c%$Qw)EhbZ7e%_b=WhoBDrbZJvP?-68b9>vDd7g=5}bQs~QlPGuFi9&n6tn9W${)7 zz>x-UQ!pyovVtou6ddx2TfXgm-4yE#H5YuY-+r#TDJEac8U~dIJ(1^nB?u%D#Zc8- zJ*}}N=A*qTJOzu^%q1~z^UCjcbT7Kz8aT0o`+0#Zz!a;E5phED-!b=Ja`n&&JQ@%PwuzY=wd*YepB=~S1D+%-g2KfJf{;v$46`?{gPUp6tjzOgQ RfX{6_P*c%Xu2Hmo^FJ)UBNYGu literal 0 HcmV?d00001 diff --git a/logo/c_programming_480px.png b/logo/c_programming_480px.png new file mode 100644 index 0000000000000000000000000000000000000000..b8ac5fe07ccd0564ae8ec5bb3bcd49cb0ec9da0a GIT binary patch literal 26565 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 BzY+id literal 0 HcmV?d00001 diff --git a/logo/dll_480px.png b/logo/dll_480px.png new file mode 100644 index 0000000000000000000000000000000000000000..93fabd8ed2e1d0fb3d282163d0fd3b7a4d902e53 GIT binary patch literal 8174 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 m5`F$ta{v3jOgizFF!z>Kt0rj z=Sz7VSr7%MX)ombv~!u<;2ceLfmefW@Du*# zH>rf9qb4x2s1fU{U`1T~3e&u|e~dg#R{6%0Oy}ky>SYcU1{saV2i%c_(2>zieDYeX zr+M&S20%v(=(rM+)iCMyfqbJ{`qJXoa)@>lsl6K-GnH5j&5ouDAB1!8bCeqpEn2nq z?&bLw!Y!yJXit}GIH%3+)^`xC4xk5wLtU?7igTe|(cSsxy*EuYu*N||yHvO7X=e?= zwEhaaH+7bLRt-kpz~Q~$G=6ah>TX~}+?#K9`4NVZOGZ6cw)cDi>E<%#J+QUksAC_f z$NGkT;8q);aoJy=8%XVb@QWpp6abV}TD1h-J>i^knocm4sEc7tY=5|^Qy<+#bXobC zE4%Mo;7>&%CD1}kQ21Lo$LzdLAeBf4!0zYpQyi0*Q=L zglG}io-4BnnlL2?q{_5?pFRd|vaK+9_9spcHHG_AN3j2jR>uy04Ls1H7eXW0`@oom zjyEs{@=umrKqP8Tb#zy1tU8QzS^>>F#amF{LyU2&if@5rCy>xi;80(m|0z)g5}5uO zzJ^#d-NIC*C@Liuidf0<8Zd0}wM(*1Hh+8104DCw|s`vzC^C5t| zECv~V{*7mi##l0pj9F9|l)HV6X}0}|EBlFb4o@U)2B7>ChG<*`0MXuu0FW}av3xCo zL2E5NH1}Im44i1#b0u>0gR108SUAV-U_${!+YdskIll-~RP7n#2G@rVQXyI#ur;tP zXoU?CzB@GiQQyK*S=CHx$cN}+Z;raa+s5_4o%wXu<=fyQXJ!Mr<{@|iv0;qk5}JL0 zfnrdB!Ey~uy7qOhY>yM&mPkdXfKhyyhTzMDT6z&px)0odA)uTHtw$hp+RyXp$dyW9 z?K%#KIs+kdYHun568ZzK_yZU#asq{Otd_1zUAO@VBncdmwYI86XJ!EJb4f|wdKzuDp><0#*B8d{_YtQG@QfxSbQ3si2625Ctk>h88~eEV_sBN zu$~2x)C9B6`f?n={`E_hT{FN*w}Ye~7!w_O*y7B8h*^(aCv}Flfn@pZVp8^VkZ;2O=f0qHYKxaqE7$3+zoK#lSEnX4601m0atz8H4dCO#JnT zl6gx@sStgTHndquLD#&AP|;{v^*=!bh^?&!6`x%3#9PVHqgX6D>V~hf+1TbkBWVe* z+T~xmBQCona~*kSBCk@IUAXd6TP|nm)z`A$@H6AuJyZO?a5F!z zaJOZ7np!f?0~$O3nMz?KNgO_rIr%m()S)2LH78!Mwifg4Bu_6Y<5S_wv6R^-dAiMt zaN`#-%zLGI=uS{jI}2Z0UEV^Gp3=*bUuc)r=zKa_JAQIibxgLVFP-ICXD(;xjq~@5 zR))-INl18GY&q{;0I3mDFXD~J60VFhtMxdbB&(udw@ENZo_KjJzpWoK0y69udq%g9F>tY z_^~UwnaXk->9p%J#G-wKs3vzmLI0~4&4S5R)v^x3U$(<~AY$uH(I#!0&8uTf*^eR$ z=FIu#g3$ZBfsYw2$^OdTb>C${P5D5wuc|?L9Jv{PqDsr{YCmIm|8C$5LsomsKy~(M zQitg~ZUlPr0^X&y5R55ip2n}H>?Cyer9$$De$|o0fhk2}G5S5If$xL*B0~(Hu0`1K zr#ib~qwW+sDnXJz2hLBlhJ{4Y66<}3=OZ%4ofaqIl--;=5taPO&2S$M1mS+dJ^Z-f z&QfS|Z~QxC`{L?3Z_`q=TT5L~e!xm=W=8@)#eYHZBC@fvsHv76y!7$H&Xl7eL?~Du z8-Lb-W}aptoY`G9JV_7Kw0~V9zqPF|4Cw?H)r;g9ZqspE6OVmh^)FptdqYz*E(x!0 z&nOuSSi+r?ZK1scd%QG%tV6d=5I5wRH`Kh_k!yNz+~0Y%cggyPvGOx}J!s`dJ?XrU z*1w{b$o6K}n2-50vbAl}&Qso9ZtVRd+>v;~LeB1VF`YjmDn*aO1dRDTVZ%wyVP5v1 zZQ>$|Lc|)*90+s_EO`2(P70RYtqF6ac4tSw^!1iYq9+L3 zZa3`~s)!4oCbYy~=yd>W@(B1jt>0qFbnM9%K5q(-t(|^R6z1KF=RdB1SZR4-I6 z7t7w;(wtw5xFFN(?d`%gY)oN~-aoYrZhjpYUQpBKZ*kkn)V}^cNpkT3Anb}=0zS1W zdrC4d&4ztq8^eD(tXny*?QMOE@EOuPL)H6DOMt$)6l%Txvsy|7vT}^*|rI+7g zyt0`)jE+Rw3lpVc#>~>tdoQJVp3%bZ!rrIMm9Mp%vYp$4>Q~+xUJdh;h~u+%gsjhC zOE8Tc6|N zHSLAc4r}S}E+tGx19)i&eaz`}tULW-pe9qCr5w?iI<%UO-O^XQQi{=7Sv=%O*lNVX zEFWxAzH1Ok6xuVn<;3WcxTB5JqT<}`LM@Rq3|20SrtQ~6cSJnp3keSw){f_;NpQSV zsQgUi*(?oSMC-qUJQZ(nVBp`5PB=<<(nIMN9>?CMEph5t&RvT*$=v6UR^efjq9?|Y znOh?X@2!->XC|D56?rPA(#Y)netYI-R45mZT)my|DlA-hYxw;3$<>*4*k(9Q`io(U zdCMZ57rpRUr@@$)omP_~W=Z?v3ttQ+wM1-J26)Vfawh}*I4HcaFuHiG&!iPEP&v~; z*|)m0#d&*daMrI8HTAEQVIbeaHT8m(`D9OvbX}E2Bz^F&Md!5Jh2ngcR3^$Vs-32< zzx`6tNtjc2Dic3)jbl&P9!2J-ZL_qX77_O^{4s(T9=$3wFSL^$OB1!q>l+juk;8p0 z?4Q?tDP^HmBG2?Bz>HkYy#{TYwIfB2xozCk{Z4wAC}3oidmlmGw# literal 0 HcmV?d00001 diff --git a/logo/logo.png b/logo/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bda7d12b81fbf06df0f5f4c015cc9815948542ff GIT binary patch literal 27476 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 literal 0 HcmV?d00001 diff --git a/logo/logo.psd b/logo/logo.psd new file mode 100644 index 0000000000000000000000000000000000000000..4684b5fb5e21d1e557b82fe9ea8223c169a25ae3 GIT binary patch literal 241211 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 z zhsaFy}$jS{yQ+>0eme%_snbMmO;&V~| z?3>Yp@wG(^q+-o893clJ_w(|vHH2D-vJfnvQ2PN&gTn-TIM${ni%0LZu#7gqFk2dj zaF&uiT?X^khZS7hMWemI?29UGk#-o$P{ioexZ0|nh4e!@+3Uyr`bUpA4>eU2-k9xjn3^h7dOEcZLv<{jL0Cg=+TF(Ygn!#7A zwR4KR#Fp;R0Ky<@9tD~<4`e=QFHmVoQmUq*)?;dxM$4*e^)xPXpu%J@S{jpDtnj+nMChIEH1d(DLfq+B4b}xuoRfk0dVjy6>5oWjD z&b3)wJ#%Q_Gg*wKIgFL{)H;R!J+ltY090*CJ+FPuVt2JRK^QK=34^Htb$wGC8R_VC zqw!9kR=Y6LG)^p$XL@oH;4E5_JI-SAIW5;L4bB15N5T$wMM(W89Z3V$kSkSw$z~p0P;KM(7MO%D4b=G zw-3>1+%xVhdg>U&W%`*qO_BBmf;Ccdo!0spYt43NOVhVfHP{+I zK#+}DSvstLuhy&f)96%%m0h!F{xa91DbVVkX=?}O$@@s#0Q5N;vcP}T0z?x?^na|y@BB; zl-y_oP^-NQ53;8#VWYi8Ea$YJ*E49q3Z-=%O@S4SidJ}f^o2z_bwP=(wg`T}w^& + +CPPP (C++ PackTool) 是一个图形化带有低代码节点编辑器的包管理工具,用于从本地或远程仓库构建并生成 NuGet/Cmake 包,使用 SKILL 快速从远程仓库生成对应包 + +## 项目状态 + +**开发中** \ No newline at end of file diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 0000000..e69de29 From 9cb0cfc40d24719ec7cf6ca6ae868641bf179173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=82=E6=B2=AB?= <1992724048@qq.com> Date: Thu, 17 Sep 2026 21:29:04 +0800 Subject: [PATCH 5/8] =?UTF-8?q?fix(docs|ui):=20=E6=9B=B4=E6=94=B9=E4=BA=86?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- lib/app_info.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f73263b..ec57fcb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ 
HWOPT -# CPPP — C++ 包管理工具 +# CCPPP — C++ 包管理工具 [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) ![Status](https://img.shields.io/badge/Status-WIP-yellow) @@ -10,7 +10,7 @@
-CPPP (C++ PackTool) 是一个图形化带有低代码节点编辑器的包管理工具,用于从本地或远程仓库构建并生成 NuGet/Cmake 包,使用 SKILL 快速从远程仓库生成对应包 +CCPPP (C/C++ PackTool) 是一个图形化带有低代码节点编辑器的包管理工具,用于从本地或远程仓库构建并生成 NuGet/Cmake 包,使用 SKILL 快速从远程仓库生成对应包 ## 项目状态 diff --git a/lib/app_info.dart b/lib/app_info.dart index 3900d7b..2f6578a 100644 --- a/lib/app_info.dart +++ b/lib/app_info.dart @@ -1,4 +1,4 @@ -const String appName = 'CPPP'; +const String appName = 'CCPPP'; /// 与 pubspec.yaml 的 version 同步(去掉 +build 与末尾 .0,如 26.1.0+1 → 26.1);不一致时 test/app_info_test.dart 会失败。 const String appVersion = '26.3 WIP'; From ea63d8bfda4d8a3679cc29277abc27a65cc60348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=82=E6=B2=AB?= <1992724048@qq.com> Date: Thu, 17 Sep 2026 21:29:56 +0800 Subject: [PATCH 6/8] =?UTF-8?q?fix(docs):=20=E6=9B=B4=E6=96=B0README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec57fcb..de3d9b4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ 
HWOPT -# CCPPP — C++ 包管理工具 +# CCPPP — C/C++ 包管理工具 [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) ![Status](https://img.shields.io/badge/Status-WIP-yellow) From cf39c7830c92f1e6700eb8a2c61a797d985b7047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=82=E6=B2=AB?= <1992724048@qq.com> Date: Thu, 17 Sep 2026 21:59:47 +0800 Subject: [PATCH 7/8] =?UTF-8?q?fix(ui):=20=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E7=91=95=E7=96=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++- lib/main.dart | 66 ++++++++++++++++------------ lib/pages/pack_compile_settings.dart | 1 + 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index de3d9b4..d4c2980 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,12 @@ CCPPP (C/C++ PackTool) 是一个图形化带有低代码节点编辑器的包管理工具,用于从本地或远程仓库构建并生成 NuGet/Cmake 包,使用 SKILL 快速从远程仓库生成对应包 +*** +*~~**啊这个这个,0百万元以内最好用的包管理,遥遥领先**~~* + ## 项目状态 +**开发中** + +## 交流群 -**开发中** \ No newline at end of file +- QQ: 112986834 \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 694c65a..d8991ff 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1109,36 +1109,46 @@ class _MainLayoutState extends State { pane: NavigationPane( selected: _selected, onChanged: (int newIndex) => setState(() => _selected = newIndex), - header: Row( - mainAxisAlignment: MainAxisAlignment.start, + header: Column( + mainAxisSize: .min, + spacing: 0, children: [ - Tooltip( - message: '添加文件夹', - child: IconButton(icon: Svgs.addFolder, onPressed: _addFolder), - ), - Tooltip( - message: '删除文件夹', - child: IconButton(icon: Svgs.deleteFolder, onPressed: _hasSelectedPack ? _deleteSelectedPack : null), - ), - Tooltip( - message: '重新映射', - child: IconButton(icon: Svgs.mapAsDrive, onPressed: _hasSelectedPack ? _remapSelectedPack : null), - ), - Tooltip( - message: '打包文件夹', - child: IconButton(icon: Svgs.moveToFolder, onPressed: _hasSelectedPack ? _packSelectedPack : null), - ), - Tooltip( - message: '历史记录', - child: IconButton(icon: Svgs.historyFolder, onPressed: _hasSelectedPack ? _historySelectedPack : null), - ), - Tooltip( - message: '依赖关系图', - child: IconButton( - icon: Svgs.internetConnection, - onPressed: _hasSelectedPack ? _openDependencyGraph : null, - ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Tooltip( + message: '添加文件夹', + child: IconButton(icon: Svgs.addFolder, onPressed: _addFolder), + ), + Tooltip( + message: '删除文件夹', + child: IconButton(icon: Svgs.deleteFolder, onPressed: _hasSelectedPack ? _deleteSelectedPack : null), + ), + Tooltip( + message: '重新映射', + child: IconButton(icon: Svgs.mapAsDrive, onPressed: _hasSelectedPack ? _remapSelectedPack : null), + ), + Tooltip( + message: '打包文件夹', + child: IconButton(icon: Svgs.moveToFolder, onPressed: _hasSelectedPack ? _packSelectedPack : null), + ), + Tooltip( + message: '历史记录', + child: IconButton( + icon: Svgs.historyFolder, + onPressed: _hasSelectedPack ? _historySelectedPack : null, + ), + ), + Tooltip( + message: '依赖关系图', + child: IconButton( + icon: Svgs.internetConnection, + onPressed: _hasSelectedPack ? _openDependencyGraph : null, + ), + ), + ], ), + Divider(style: DividerThemeData(horizontalMargin: .fromLTRB(0, 4, 8, 0)),), ], ), displayMode: PaneDisplayMode.expanded, diff --git a/lib/pages/pack_compile_settings.dart b/lib/pages/pack_compile_settings.dart index 531995f..9a19725 100644 --- a/lib/pages/pack_compile_settings.dart +++ b/lib/pages/pack_compile_settings.dart @@ -565,6 +565,7 @@ class _PackCompileSettingsState extends State { final TextStyle style = _headerTextStyle(); return Card( margin: const .fromLTRB(0, 0, 0, 2), + padding: const .fromLTRB(8, 8, 8, 8), child: Row( children: [ Expanded(child: Text('名称', style: style)), From 97447595f0a655294ebc344fb6ffc17f24f5bbbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=82=E6=B2=AB?= <1992724048@qq.com> Date: Thu, 17 Sep 2026 22:24:44 +0800 Subject: [PATCH 8/8] =?UTF-8?q?fix(ui):=20=E4=BF=AE=E5=A4=8D=E4=BA=86TabVi?= =?UTF-8?q?ew=E9=80=89=E4=B8=AD=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/controls/pack_manage.dart | 125 +++++++++++++++++----------------- 1 file changed, 61 insertions(+), 64 deletions(-) diff --git a/lib/controls/pack_manage.dart b/lib/controls/pack_manage.dart index 084da2a..dc40df6 100644 --- a/lib/controls/pack_manage.dart +++ b/lib/controls/pack_manage.dart @@ -46,40 +46,12 @@ class _PackManageState extends State { int _index = 0; late final ValueNotifier _pack; late final ValueNotifier _packagingBuilder; - late final List _tabs; @override void initState() { super.initState(); _pack = ValueNotifier(widget.pack); _packagingBuilder = ValueNotifier(widget.packagingBuilder); - _tabs = [ - Tab( - icon: Svgs.showPermitCard, - text: const Text('包信息'), - body: _body(_packInfoBody()), - ), - Tab( - icon: Svgs.fileExplorer, - text: const Text('文件管理'), - body: _body(_packFilesBody()), - ), - Tab( - icon: Svgs.inventoryFlow, - text: const Text('依赖管理'), - body: _body(_packDependenciesBody()), - ), - Tab( - icon: Svgs.projectSetup, - text: const Text('编译设置'), - body: _body(_packCompileBody()), - ), - Tab( - icon: Svgs.boxSettings, - text: const Text('打包设置'), - body: _body(_packPackagingBody()), - ), - ]; } @override @@ -103,22 +75,20 @@ class _PackManageState extends State { Widget _packInfoBody() { return ValueListenableBuilder( valueListenable: _pack, - builder: (BuildContext context, PackModel pack, Widget? child) => - PackInfo(pack: pack, onSave: widget.onSave), + builder: (BuildContext context, PackModel pack, Widget? child) => PackInfo(pack: pack, onSave: widget.onSave), ); } Widget _packFilesBody() { return ValueListenableBuilder( valueListenable: _pack, - builder: (BuildContext context, PackModel pack, Widget? child) => - PackFiles( - pack: pack, - onBuildPack: widget.onBuildPack, - onSave: widget.onSave, - loadLatestVersion: widget.loadLatestVersion, - loadHeader: widget.loadHeader ?? loadBuildScriptHeader, - ), + builder: (BuildContext context, PackModel pack, Widget? child) => PackFiles( + pack: pack, + onBuildPack: widget.onBuildPack, + onSave: widget.onSave, + loadLatestVersion: widget.loadLatestVersion, + loadHeader: widget.loadHeader ?? loadBuildScriptHeader, + ), ); } @@ -126,11 +96,7 @@ class _PackManageState extends State { return ValueListenableBuilder( valueListenable: _pack, builder: (BuildContext context, PackModel pack, Widget? child) => - PackDependencies( - pack: pack, - allPacks: widget.allPacks, - onSave: widget.onSave, - ), + PackDependencies(pack: pack, allPacks: widget.allPacks, onSave: widget.onSave), ); } @@ -138,32 +104,22 @@ class _PackManageState extends State { return ValueListenableBuilder( valueListenable: _pack, builder: (BuildContext context, PackModel pack, Widget? child) => - PackCompileSettings( - pack: pack, - onSave: widget.onSave, - pickDirectory: widget.pickDirectory, - ), + PackCompileSettings(pack: pack, onSave: widget.onSave, pickDirectory: widget.pickDirectory), ); } Widget _packPackagingBody() { return ValueListenableBuilder( valueListenable: _pack, - builder: (BuildContext context, PackModel pack, Widget? child) => - ValueListenableBuilder( - valueListenable: _packagingBuilder, - builder: - ( - BuildContext context, - PackageBuilder? builder, - Widget? child, - ) => PackPackaging( - pack: pack, - selectedBuilder: builder, - onBuilderChanged: widget.onPackagingBuilderChanged, - onSave: widget.onSave, - ), - ), + builder: (BuildContext context, PackModel pack, Widget? child) => ValueListenableBuilder( + valueListenable: _packagingBuilder, + builder: (BuildContext context, PackageBuilder? builder, Widget? child) => PackPackaging( + pack: pack, + selectedBuilder: builder, + onBuilderChanged: widget.onPackagingBuilderChanged, + onSave: widget.onSave, + ), + ), ); } @@ -176,6 +132,47 @@ class _PackManageState extends State { ); } + List _buildTabs(BuildContext context) { + final accent = FluentTheme.of(context).accentColor; + return [ + Tab( + icon: Svgs.showPermitCard, + text: const Text('包信息'), + body: _body(_packInfoBody()), + selectedBackgroundColor: WidgetStateColor.resolveWith((states) => FluentTheme.of(context).selectionColor), + selectedForegroundColor: WidgetStateColor.resolveWith((states) => Colors.white), + ), + Tab( + icon: Svgs.fileExplorer, + text: const Text('文件管理'), + body: _body(_packFilesBody()), + selectedBackgroundColor: WidgetStateColor.resolveWith((states) => FluentTheme.of(context).selectionColor), + selectedForegroundColor: WidgetStateColor.resolveWith((states) => Colors.white), + ), + Tab( + icon: Svgs.inventoryFlow, + text: const Text('依赖管理'), + body: _body(_packDependenciesBody()), + selectedBackgroundColor: WidgetStateColor.resolveWith((states) => FluentTheme.of(context).selectionColor), + selectedForegroundColor: WidgetStateColor.resolveWith((states) => Colors.white), + ), + Tab( + icon: Svgs.projectSetup, + text: const Text('编译设置'), + body: _body(_packCompileBody()), + selectedBackgroundColor: WidgetStateColor.resolveWith((states) => FluentTheme.of(context).selectionColor), + selectedForegroundColor: WidgetStateColor.resolveWith((states) => Colors.white), + ), + Tab( + icon: Svgs.boxSettings, + text: const Text('打包设置'), + body: _body(_packPackagingBody()), + selectedBackgroundColor: WidgetStateColor.resolveWith((states) => FluentTheme.of(context).selectionColor), + selectedForegroundColor: WidgetStateColor.resolveWith((states) => Colors.white), + ), + ]; + } + @override Widget build(BuildContext context) { return Padding( @@ -183,7 +180,7 @@ class _PackManageState extends State { child: TabView( currentIndex: _index, onChanged: (int index) => setState(() => _index = index), - tabs: _tabs, + tabs: _buildTabs(context), ), ); }

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 Date: Thu, 17 Sep 2026 21:11:55 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix(ui):=20=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=B8=8A=E7=9A=84=E4=B8=80=E4=BA=9B=E5=B0=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 5 + lib/pages/pack_compile_settings.dart | 2 +- lib/pages/script_editor.dart | 172 ++++----------------------- 3 files changed, 28 insertions(+), 151 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5317633 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cmake.sourceDirectory": "D:/CODE/NuGet C++ Pack/cpp_nuget_pack/windows", + "terminal.integrated.stickyScroll.enabled": false, + "cmake.autoDetectSourceDirectory": false +} \ No newline at end of file diff --git a/lib/pages/pack_compile_settings.dart b/lib/pages/pack_compile_settings.dart index 0423121..531995f 100644 --- a/lib/pages/pack_compile_settings.dart +++ b/lib/pages/pack_compile_settings.dart @@ -690,7 +690,7 @@ class _PackCompileSettingsState extends State { const SizedBox(width: 5), Tag( text: '系统', - color: FluentTheme.of(context).resources.solidBackgroundFillColorQuarternary, + color: FluentTheme.of(context).resources.solidBackgroundFillColorBaseAlt, fontSize: 10, ), ], diff --git a/lib/pages/script_editor.dart b/lib/pages/script_editor.dart index 180617a..4fe6277 100644 --- a/lib/pages/script_editor.dart +++ b/lib/pages/script_editor.dart @@ -26,14 +26,6 @@ const double _nodeLibraryWidth = 232; const double _inspectorWidth = 280; const double _titleMaxWidth = 240; -/// 节点编辑器全屏页:顶栏(返回 / 标题 / 项目选择器与新建、重命名、删除 / -/// 保存状态 / 生成预览)、左侧节点库、中间画布、右侧检查器与底部输出面板。 -/// -/// 布局数值与分隔线取自视觉规范 §1/§3(顶栏 48、左 232、右 280、底部收起 34、 -/// 1px `surface2` 分隔)。无脚本项目时画布区为空态引导(§5.8,含「新建脚本项目」 -/// 按钮)、两侧面板整体禁用。项目 CRUD 见 §8.1-8.3,切换/排序见 §10.5/§10.6: -/// 切换前先收口视口防抖并 flush 保存队列;控制器变更与视口变化经 400ms 防抖保存 -/// 队列写回(§10.1/§10.4),返回按钮在队列清空后 pop,保存失败时弹确认对话框(§8.4)。 class ScriptEditorPage extends StatefulWidget { const ScriptEditorPage({ super.key, @@ -47,14 +39,10 @@ class ScriptEditorPage extends StatefulWidget { final PackModel pack; final Future Function(PackModel pack) onSave; - /// 代码生成器;null 时由生成预览(T9)回退 `PowerShell5Generator()`。 final ScriptCodeGenerator? generator; - /// 包内路径建议(检查器 T8 使用);null 时由检查器经 `NuGetPackageBuilder` - /// 计划条目转为 `build/native/` 相对路径。 final List? packagePaths; - /// 保存与视口写回的防抖时长(§10.1/§10.4,默认 400ms);测试注入更短值。 final Duration debounce; @override @@ -64,8 +52,7 @@ class ScriptEditorPage extends StatefulWidget { class _ScriptEditorPageState extends State { GraphEditorController? _controller; final TransformationController _transformation = TransformationController(); - final GlobalKey _outputPanelKey = - GlobalKey(); + final GlobalKey _outputPanelKey = GlobalKey(); Size? _canvasViewportSize; late final EditorSaveQueue _saveQueue; @@ -73,13 +60,10 @@ class _ScriptEditorPageState extends State { Object? _lastSaveError; bool _backing = false; - /// 免脏加载标记:控制器 `loadProject` 的选中清空/诊断重算通知不是编辑, - /// 不应进入保存队列(切换/重命名/元数据变更共用)。 bool _suppressSaveMark = false; bool get _hasProject => _controller != null; - /// 会话内的脚本项目工作列表(就地增删改);保存时经 `_buildUpdatedPack` 拷贝。 List get _scripts => widget.pack.scripts; @override @@ -111,7 +95,7 @@ class _ScriptEditorPageState extends State { Widget build(BuildContext context) { return Container( key: const Key('nodeEditorPage'), - color: FluentTheme.of(context).scaffoldBackgroundColor, + color: FluentTheme.of(context).menuColor, child: Column( children: [ _buildTopBar(), @@ -137,11 +121,7 @@ class _ScriptEditorPageState extends State { message: '返回包管理', child: IconButton( icon: _backing - ? const SizedBox( - width: 16, - height: 16, - child: ProgressRing(strokeWidth: 2), - ) + ? const SizedBox(width: 16, height: 16, child: ProgressRing(strokeWidth: 2)) : const Icon(FluentIcons.back, size: 16), onPressed: _backing ? null : _handleBack, ), @@ -192,7 +172,6 @@ class _ScriptEditorPageState extends State { ); } - /// 顶栏动作区(Spacer 之后,§3.1):保存状态在「生成预览」之前。 Widget _buildTopBarActions() { return Row( key: const Key('editorTopBarActions'), @@ -222,8 +201,6 @@ class _ScriptEditorPageState extends State { ); } - /// 顶栏项目选择器(§3.1/§3.2):宽 200、高 32;按钮态显示项目名, - /// 下拉项含项目名 + 触发时机与构建标签;无项目时禁用。 Widget _buildScriptProjectSelector() { final List scripts = _scripts; return SizedBox( @@ -298,11 +275,7 @@ class _ScriptEditorPageState extends State { child: SizedBox( width: 32, height: 32, - child: IconButton( - key: buttonKey, - icon: Icon(icon, size: 16), - onPressed: onPressed, - ), + child: IconButton(key: buttonKey, icon: Icon(icon, size: 16), onPressed: onPressed), ), ); } @@ -315,9 +288,7 @@ class _ScriptEditorPageState extends State { panelKey: const Key('nodeLibraryPanel'), width: _nodeLibraryWidth, border: Border(right: BorderSide(color: FluentTheme.of(context).resources.dividerStrokeColorDefault)), - child: NodeLibraryPanel( - onAddNode: _hasProject ? _addNodeFromLibrary : null, - ), + child: NodeLibraryPanel(onAddNode: _hasProject ? _addNodeFromLibrary : null), ), Expanded(child: _buildCanvasArea()), _buildSidePanel( @@ -354,10 +325,7 @@ class _ScriptEditorPageState extends State { child: IgnorePointer( ignoring: !_hasProject, child: DecoratedBox( - decoration: BoxDecoration( - color: FluentTheme.of(context).scaffoldBackgroundColor, - border: border, - ), + decoration: BoxDecoration(color: FluentTheme.of(context).scaffoldBackgroundColor, border: border), child: child, ), ), @@ -374,11 +342,7 @@ class _ScriptEditorPageState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Icon( - FluentIcons.power_shell, - size: 40, - color: FluentTheme.of(context).resources.textFillColorSecondary, - ), + Icon(FluentIcons.power_shell, size: 40, color: FluentTheme.of(context).resources.textFillColorSecondary), const SizedBox(height: 16), Text( '尚未创建脚本项目', @@ -418,7 +382,6 @@ class _ScriptEditorPageState extends State { ); } - /// 节点库点击添加(§4.2):落点基于画布可见视口中心的场景坐标。 void _addNodeFromLibrary(ScriptNodeTypeDescriptor descriptor) { final GraphEditorController? controller = _controller; if (controller == null) { @@ -434,7 +397,6 @@ class _ScriptEditorPageState extends State { ); } - /// 画布可见视口中心对应的场景坐标;与画布共用同一 [TransformationController]。 Offset _viewportCenterScene() { final Size? viewport = _canvasViewportSize; if (viewport == null) { @@ -443,11 +405,8 @@ class _ScriptEditorPageState extends State { return _transformation.toScene(viewport.center(Offset.zero)); } - /// 新建项目(§8.1):对话框收集名称与触发/构建配置;id 取 `script_N` - /// 最大序号 +1,自动放置入口节点 (40, 60),追加后选中并走保存队列。 Future _handleCreateScriptProject() async { - final NewScriptProjectRequest? request = - await showCreateScriptProjectDialog(context, existing: _scripts); + final NewScriptProjectRequest? request = await showCreateScriptProjectDialog(context, existing: _scripts); if (request == null || !mounted) { return; } @@ -466,37 +425,26 @@ class _ScriptEditorPageState extends State { showFloatingToast(context, '已创建'); } - /// 顶栏「重命名」(§8.2):对话框返回新名称后走 [_handleRenameScriptProject] - /// (检查器内联提交共用同一入口)。 Future _openRenameScriptProjectDialog() async { final GraphEditorController? controller = _controller; if (controller == null) { return; } final ScriptProjectModel project = controller.project; - final String? name = await showRenameScriptProjectDialog( - context, - project: project, - existing: _scripts, - ); + final String? name = await showRenameScriptProjectDialog(context, project: project, existing: _scripts); if (name == null || !mounted) { return; } _handleRenameScriptProject(project, name); } - /// 删除项目(§8.3):确认后移除;选择按「保持索引位 → 越界回退末项 → - /// 空列表回空态」调整(§8.3/§10.5)。 Future _handleDeleteScriptProject() async { final GraphEditorController? controller = _controller; if (controller == null) { return; } final ScriptProjectModel project = controller.project; - final bool confirmed = await showDeleteScriptProjectDialog( - context, - project: project, - ); + final bool confirmed = await showDeleteScriptProjectDialog(context, project: project); if (!confirmed || !mounted) { return; } @@ -511,7 +459,6 @@ class _ScriptEditorPageState extends State { showFloatingToast(context, '已删除'); } - /// 切换项目入口(顶栏下拉 / 执行顺序行):先 flush 视口与保存队列再加载新图。 void _handleSelectScriptProject(ScriptProjectModel project) { if (identical(project, _controller?.project)) { return; @@ -519,8 +466,6 @@ class _ScriptEditorPageState extends State { unawaited(_switchToScriptProject(project)); } - /// 切换项目(§10.5):保存队列 flush 后加载新图(画布恢复其 viewport、 - /// 清空选中、诊断与底部面板随新图重算);切换不写历史记录。 Future _switchToScriptProject(ScriptProjectModel next) async { final GraphEditorController? controller = _controller; if (controller == null || identical(controller.project, next)) { @@ -539,14 +484,11 @@ class _ScriptEditorPageState extends State { setState(() {}); } - /// 项目切换/替换前的焦点收口:让检查器字段失焦并等焦点变更微任务落地, - /// 未提交文本经失焦提交写回原项目(否则会残留或提交到新项目上)。 Future _settleFocusBeforeProjectChange() async { FocusManager.instance.primaryFocus?.unfocus(); await null; } - /// 重命名(检查器内联与顶栏对话框共用):写回列表、同步控制器并保存。 void _handleRenameScriptProject(ScriptProjectModel project, String name) { if (_replaceScriptProject(project, name: name) == null) { return; @@ -555,20 +497,14 @@ class _ScriptEditorPageState extends State { showFloatingToast(context, '已重命名'); } - void _handleTriggerChanged( - ScriptProjectModel project, - ScriptTrigger trigger, - ) { + void _handleTriggerChanged(ScriptProjectModel project, ScriptTrigger trigger) { if (_replaceScriptProject(project, trigger: trigger) == null) { return; } _saveQueue.markDirty(); } - void _handleBuildModelChanged( - ScriptProjectModel project, - BuildModel buildModel, - ) { + void _handleBuildModelChanged(ScriptProjectModel project, BuildModel buildModel) { if (_replaceScriptProject(project, buildModel: buildModel) == null) { return; } @@ -583,7 +519,6 @@ class _ScriptEditorPageState extends State { _moveScriptProject(project, 1); } - /// 执行顺序排序(§10.6):列表顺序即同组执行顺序;重排保持当前选中并即时保存。 void _moveScriptProject(ScriptProjectModel project, int delta) { final List scripts = _scripts; final int index = _indexOfScript(project); @@ -598,13 +533,7 @@ class _ScriptEditorPageState extends State { _saveQueue.markDirty(); } - /// 激活项目:无控制器时创建(含可选入口节点),否则免脏加载后追加入口节点。 - /// - /// 激活前先收口视口防抖,避免矩阵尾段变更(fling 惯性终点等)随切换丢失。 - Future _activateScriptProject( - ScriptProjectModel project, { - bool addEntryNode = false, - }) async { + Future _activateScriptProject(ScriptProjectModel project, {bool addEntryNode = false}) async { await _settleFocusBeforeProjectChange(); if (!mounted) { return; @@ -628,9 +557,6 @@ class _ScriptEditorPageState extends State { setState(() {}); } - /// 移除列表项并调整选择:保持索引位、越界回退末项、空列表回空态。 - /// - /// 移除前先收口视口防抖,删除/新建与切换统一收口(矩阵尾段变更不随操作丢失)。 Future _removeScriptAt(int index) async { await _settleFocusBeforeProjectChange(); if (!mounted) { @@ -650,7 +576,6 @@ class _ScriptEditorPageState extends State { _saveQueue.markDirty(); } - /// 回到无项目空态:注销监听并释放控制器(画布/检查器/输出面板随之为 null)。 void _detachController() { final GraphEditorController? controller = _controller; _controller = null; @@ -659,10 +584,6 @@ class _ScriptEditorPageState extends State { setState(() {}); } - /// 免脏加载:`loadProject` 的选中清空/诊断重算通知不视为编辑。 - /// - /// [preserveSelection] 为 true 时加载后恢复原选中(节点/连线仍在时): - /// 元数据变更(重命名/触发/构建标签)不改变图,不应打断编辑焦点。 void _loadScriptProject( GraphEditorController controller, ScriptProjectModel project, { @@ -685,12 +606,6 @@ class _ScriptEditorPageState extends State { } } - /// 替换列表中项目实例(名称/触发/构建配置不可变,需全字段拷贝); - /// 无实际变化或找不到时返回 null。当前项目同步免脏加载。 - /// - /// 替换前先收口视口防抖(同切换路径),避免矩阵领先模型时(fling 惯性期/ - /// T9 居中防抖窗)免脏加载把矩阵重置回陈旧模型造成回跳与尾段变更丢失; - /// 免脏加载恢复原选中,元数据变更不打断编辑焦点。 ScriptProjectModel? _replaceScriptProject( ScriptProjectModel project, { String? name, @@ -721,7 +636,6 @@ class _ScriptEditorPageState extends State { return updated; } - /// 全字段拷贝(节点/连线/视口保持引用与数值),仅替换可变元数据。 ScriptProjectModel _copyScriptProject( ScriptProjectModel source, { String? name, @@ -745,8 +659,7 @@ class _ScriptEditorPageState extends State { int _indexOfScript(ScriptProjectModel project) { final List scripts = _scripts; for (int index = 0; index < scripts.length; index++) { - if (identical(scripts[index], project) || - scripts[index].id == project.id) { + if (identical(scripts[index], project) || scripts[index].id == project.id) { return index; } } @@ -764,12 +677,10 @@ class _ScriptEditorPageState extends State { ); } - /// 顶栏「生成预览」(§10.8):交给底部面板编译并呈现。 void _generatePreview() { _outputPanelKey.currentState?.generatePreview(); } - /// 顶栏保存状态四态(§3.3):未保存 / 保存中 / 已保存 / 保存失败 + 重试。 Widget _buildSaveStatus() { final EditorSaveQueue queue = _saveQueue; final FluentThemeData theme = FluentTheme.of(context); @@ -784,38 +695,22 @@ class _ScriptEditorPageState extends State { mainAxisSize: MainAxisSize.min, children: switch (queue.status) { EditorSaveStatus.unsaved => [ - Icon( - FluentIcons.save, - size: 14, - color: theme.resources.textFillColorTertiary, - ), + Icon(FluentIcons.save, size: 14, color: theme.resources.textFillColorTertiary), const SizedBox(width: 6), Text('未保存', style: statusStyle), ], EditorSaveStatus.saving => [ - const SizedBox( - width: 14, - height: 14, - child: ProgressRing(strokeWidth: 2), - ), + const SizedBox(width: 14, height: 14, child: ProgressRing(strokeWidth: 2)), const SizedBox(width: 6), Text('保存中…', style: statusStyle), ], EditorSaveStatus.saved => [ - Icon( - FluentIcons.check_mark, - size: 14, - color: AppColors.success(theme.brightness), - ), + Icon(FluentIcons.check_mark, size: 14, color: AppColors.success(theme.brightness)), const SizedBox(width: 6), Text('已保存', style: statusStyle), ], EditorSaveStatus.failed => [ - Icon( - FluentIcons.error_badge, - size: 14, - color: AppColors.critical(theme.brightness), - ), + Icon(FluentIcons.error_badge, size: 14, color: AppColors.critical(theme.brightness)), const SizedBox(width: 6), Text('保存失败', style: statusStyle), const SizedBox(width: 8), @@ -838,8 +733,6 @@ class _ScriptEditorPageState extends State { } } - /// 控制器任意变更(参数/节点/选中/视口写回)统一进入防抖保存(§10.4); - /// 项目切换/重命名/元数据变更的免脏加载(见 `_suppressSaveMark`)除外。 void _handleControllerChanged() { if (_suppressSaveMark) { return; @@ -847,22 +740,14 @@ class _ScriptEditorPageState extends State { _saveQueue.markDirty(); } - /// 视口矩阵变化(平移/缩放/fling/T9 程序化居中)重置防抖计时(§10.1)。 void _handleTransformationChanged() { if (_controller == null) { return; } _viewportDebounceTimer?.cancel(); - _viewportDebounceTimer = Timer( - widget.debounce, - _persistViewportFromTransformation, - ); + _viewportDebounceTimer = Timer(widget.debounce, _persistViewportFromTransformation); } - /// 把变换矩阵的视口写回控制器,经控制器通知进入保存队列。 - /// - /// 与模型当前值(1e-9 容差)比较后再写:画布 `_lastSyncedViewport` 对账 - /// 会在模型被外部更新时回写同一矩阵,直接写入会自触发保存环路。 void _persistViewportFromTransformation() { _viewportDebounceTimer = null; final GraphEditorController? controller = _controller; @@ -874,9 +759,7 @@ class _ScriptEditorPageState extends State { final double y = matrix.storage[13]; final double scale = matrix.getMaxScaleOnAxis(); final ScriptProjectModel project = controller.project; - if (_sameViewport(x, project.viewX) && - _sameViewport(y, project.viewY) && - _sameViewport(scale, project.viewScale)) { + if (_sameViewport(x, project.viewX) && _sameViewport(y, project.viewY) && _sameViewport(scale, project.viewScale)) { return; } controller.setViewport(x: x, y: y, scale: scale); @@ -884,14 +767,11 @@ class _ScriptEditorPageState extends State { bool _sameViewport(double left, double right) => (left - right).abs() < 1e-9; - /// 立即收口视口:取消防抖计时并把当前矩阵写回项目(切换/返回前调用), - /// 避免 400ms 窗口内的矩阵尾段变更(fling 惯性终点等)随操作丢失。 void _flushViewportWriteBack() { _viewportDebounceTimer?.cancel(); _persistViewportFromTransformation(); } - /// 保存回调(队列串行调用):构造新包并交给 [ScriptEditorPage.onSave]。 Future _saveProject() async { try { final bool saved = await widget.onSave(_buildUpdatedPack()); @@ -903,13 +783,10 @@ class _ScriptEditorPageState extends State { } } - /// 跳过防抖立即 flush 保存队列(画布 `Ctrl+S` 与顶栏「重试」共用)。 void _flushSaveQueue() { _saveQueue.flush(); } - /// 返回(§8.4):先收口视口并 flush + 等待队列清空;失败未清时弹确认对话框 - /// (重试 / 仍返回),重试成功后照常返回。 Future _handleBack() async { if (_backing) { return; @@ -947,9 +824,7 @@ class _ScriptEditorPageState extends State { Future _showSaveFailedDialog() async { final String projectName = _controller?.project.name ?? widget.pack.name; final Object? error = _lastSaveError; - final String body = error == null - ? '脚本项目「$projectName」保存失败' - : '脚本项目「$projectName」保存失败:${formatError(error)}'; + final String body = error == null ? '脚本项目「$projectName」保存失败' : '脚本项目「$projectName」保存失败:${formatError(error)}'; final bool? retry = await showDialog( context: context, builder: (BuildContext dialogContext) => ContentDialog( @@ -974,7 +849,6 @@ class _ScriptEditorPageState extends State { return retry ?? false; } - /// 全字段拷贝 + 当前控制器项目替换 `scripts` 中所属项(其余列表原样引用)。 PackModel _buildUpdatedPack() { final ScriptProjectModel? current = _controller?.project; return PackModel( @@ -1008,9 +882,7 @@ class _ScriptEditorPageState extends State { if (index < 0) { return [...scripts, current]; } - final List updated = List.of( - scripts, - ); + final List updated = List.of(scripts); updated[index] = current; return updated; } From 5cc7571e0c2023d34c815c2f98622cbd32dac31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=82=E6=B2=AB?= <1992724048@qq.com> Date: Thu, 17 Sep 2026 21:26:37 +0800 Subject: [PATCH 4/8] =?UTF-8?q?refactor(docs):=20=E9=87=8D=E5=86=99?= =?UTF-8?q?=E4=BA=86README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 +++++++++++++++++- README_EN.md | 0 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 README_EN.md diff --git a/README.md b/README.md index 5f28270..f73263b 100644 --- a/README.md +++ b/README.md @@ -1 +1,17 @@ - \ No newline at end of file +