From 11c414d29d517edb1659e0022f308b73db9c730e Mon Sep 17 00:00:00 2001 From: hejl Date: Tue, 20 May 2025 16:55:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E9=80=89=E6=94=AF=E6=8C=81OK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../template_parser_controller.dart | 27 +++++++++++++++++++ .../template_parser/models/template_node.dart | 2 ++ .../widgets/template_tree_view.dart | 15 ++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart b/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart index 118db68..0021b6a 100644 --- a/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart +++ b/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart @@ -11,6 +11,7 @@ class TemplateParserController extends BaseContentController { List _templateItems = []; String? _errorMessage; TemplateNode? _selectedNode; + String? _currentParentPath; // 新增属性,用于记录当前选中节点的父节点路径 // Getters String get filePath => _filePath; @@ -40,12 +41,38 @@ class TemplateParserController extends BaseContentController { notifyListeners(); } + // 新增方法,用于处理节点的选中状态 + void toggleNodeCheck(TemplateNode node) { + final parentPath = node.path.substring(0, node.path.lastIndexOf('/')); + if (_currentParentPath != null && _currentParentPath != parentPath) { + // 如果最新选择的节点与之前选中的节点不在同一个父节点下,清除之前的选中状态 + clearAllChecked(); + } + node.isChecked = !node.isChecked; + _currentParentPath = parentPath; + notifyListeners(); + } + + // 新增方法,用于清除所有节点的选中状态 + void clearAllChecked() { + void traverse(TemplateNode node) { + node.isChecked = false; + for (var child in node.children) { + traverse(child); + } + } + for (var node in _treeNodes) { + traverse(node); + } + } + Future _loadTemplateData() async { try { _errorMessage = null; _treeNodes = []; _templateItems = []; _selectedNode = null; + _currentParentPath = null; // 加载数据时清空当前父节点路径 if (_filePath.isEmpty) return; diff --git a/win_text_editor/lib/modules/template_parser/models/template_node.dart b/win_text_editor/lib/modules/template_parser/models/template_node.dart index fa26d4d..a0be1bb 100644 --- a/win_text_editor/lib/modules/template_parser/models/template_node.dart +++ b/win_text_editor/lib/modules/template_parser/models/template_node.dart @@ -10,6 +10,7 @@ class TemplateNode implements TreeNode { bool isRepeated; bool isAttribute; int repreatCount; + bool isChecked; // 新增属性,用于记录节点是否被选中 TemplateNode({ required this.name, @@ -20,6 +21,7 @@ class TemplateNode implements TreeNode { this.isRepeated = false, this.isAttribute = false, this.repreatCount = 1, + this.isChecked = false, // 初始化默认未选中 }); @override diff --git a/win_text_editor/lib/modules/template_parser/widgets/template_tree_view.dart b/win_text_editor/lib/modules/template_parser/widgets/template_tree_view.dart index 84cd1ce..8e47e4d 100644 --- a/win_text_editor/lib/modules/template_parser/widgets/template_tree_view.dart +++ b/win_text_editor/lib/modules/template_parser/widgets/template_tree_view.dart @@ -57,10 +57,23 @@ class TemplateTreeView extends StatelessWidget { padding: EdgeInsets.only(left: 12.0 * node.depth), child: ListTile( dense: true, - leading: + leading: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (templateNode.children.isEmpty) // 仅在叶子节点显示复选框 + Checkbox( + value: templateNode.isChecked, + onChanged: (value) { + if (value != null) { + controller.toggleNodeCheck(templateNode); + } + }, + ), isAttribute ? const Icon(Icons.code, size: 16, color: Colors.grey) : const Icon(Icons.label_outline, size: 18, color: Colors.blue), + ], + ), title: Text( isAttribute ? templateNode.name.substring(1) : templateNode.name, style: TextStyle(