diff --git a/win_text_editor/lib/framework/models/file_node.dart b/win_text_editor/lib/framework/models/file_node.dart index 642e90e..ace1fd4 100644 --- a/win_text_editor/lib/framework/models/file_node.dart +++ b/win_text_editor/lib/framework/models/file_node.dart @@ -19,6 +19,9 @@ class FileNode implements TreeNode { @override String get title => name; + @override + bool get isVisible => true; + FileNode({ required this.name, required this.path, diff --git a/win_text_editor/lib/modules/data_format/models/template_node.dart b/win_text_editor/lib/modules/data_format/models/template_node.dart index 9d61697..0648d9e 100644 --- a/win_text_editor/lib/modules/data_format/models/template_node.dart +++ b/win_text_editor/lib/modules/data_format/models/template_node.dart @@ -40,6 +40,9 @@ class TemplateNode implements TreeNode { @override String get id => path; + + @override + bool get isVisible => true; } enum NodeType { element, attribute, text } diff --git a/win_text_editor/lib/modules/outline/controllers/outline_provider.dart b/win_text_editor/lib/modules/outline/controllers/outline_provider.dart index 304279b..a054777 100644 --- a/win_text_editor/lib/modules/outline/controllers/outline_provider.dart +++ b/win_text_editor/lib/modules/outline/controllers/outline_provider.dart @@ -8,8 +8,8 @@ class OutlineProvider with ChangeNotifier { bool _isLoading = true; String? _currentRootPath; // 跟踪当前根路径 static OutlineNode rootNode = OutlineNode( - name: "所有", - title: "所有", + name: "所有Tag", + title: "所有Tag", value: 'UFTTable', frequency: 0, isDirectory: true, diff --git a/win_text_editor/lib/modules/outline/models/outline_node.dart b/win_text_editor/lib/modules/outline/models/outline_node.dart index b801607..4f1c03a 100644 --- a/win_text_editor/lib/modules/outline/models/outline_node.dart +++ b/win_text_editor/lib/modules/outline/models/outline_node.dart @@ -23,6 +23,11 @@ class OutlineNode implements TreeNode { bool isExpanded; final int frequency; + late String uuid; + + @override + bool isVisible; + final String value; String? wordClass; @@ -37,14 +42,16 @@ class OutlineNode implements TreeNode { this.wordClass, List? children, this.title = "", + this.isVisible = true, }) : _children = children ?? [] { + uuid = DateTime.now().microsecondsSinceEpoch.toRadixString(36); for (var child in _children) { child.parent = this; } } @override - String get id => '$depth-$name'; + String get id => uuid; // 获取文件图标数据 @override diff --git a/win_text_editor/lib/modules/outline/widgets/outline_explorer.dart b/win_text_editor/lib/modules/outline/widgets/outline_explorer.dart index 34f4627..1532047 100644 --- a/win_text_editor/lib/modules/outline/widgets/outline_explorer.dart +++ b/win_text_editor/lib/modules/outline/widgets/outline_explorer.dart @@ -48,31 +48,38 @@ class _OutlineExplorerState extends State { // 过滤节点方法 - 递归版本 List _filterNodes(List nodes) { - if (_searchQuery.isEmpty) { - return nodes; + void resetVisibility(List nodes) { + for (final node in nodes) { + node.isVisible = true; + if (node.isDirectory) { + resetVisibility(node.children); + } + } } - // 递归过滤函数 - List recursiveFilter(List nodesToFilter, int currentDepth) { - final List result = []; - - for (final node in nodesToFilter) { - // 如果是第一层子节点(假设根节点深度为0,第一层子节点深度为1) - if (node.title.toLowerCase().contains(_searchQuery.toLowerCase())) { - result.add(node); + void applySearchFilter(List nodes, String query) { + for (final node in nodes) { + // 递归处理子节点 + if (node.isDirectory && node.depth < 2) { + applySearchFilter(node.children, query); } - // 递归处理子节点,增加深度 - if (node.isDirectory && node.children.isNotEmpty) { - result.addAll(recursiveFilter(node.children, currentDepth + 1)); - } + // 设置可见性:自身匹配或子节点可见 + final bool isMatch = node.title.toLowerCase().contains(query.toLowerCase()); + final bool hasVisibleChild = + node.depth < 2 && node.isDirectory && node.children.any((child) => child.isVisible); + + node.isVisible = isMatch || hasVisibleChild; } + } - return result; + if (_searchQuery.isEmpty) { + resetVisibility(nodes); + return nodes; } - // 从深度0开始递归 - return recursiveFilter(nodes, 0); + applySearchFilter(nodes, _searchQuery); + return nodes; } @override @@ -94,7 +101,7 @@ class _OutlineExplorerState extends State { controller: _searchController, style: const TextStyle(fontSize: 12), // 输入文字大小为10 decoration: InputDecoration( - hintText: '搜索节点...', + hintText: '搜索Tag...', hintStyle: const TextStyle(fontSize: 12), // 提示文字大小为10 prefixIcon: const Icon( Icons.search, diff --git a/win_text_editor/lib/shared/components/tree_view.dart b/win_text_editor/lib/shared/components/tree_view.dart index ef9c67e..a6e9a81 100644 --- a/win_text_editor/lib/shared/components/tree_view.dart +++ b/win_text_editor/lib/shared/components/tree_view.dart @@ -10,6 +10,7 @@ abstract class TreeNode { List get children; int get depth; IconData? get iconData; + bool get isVisible; } /// 树视图配置 @@ -141,6 +142,7 @@ class _TreeViewState extends State { int _countVisibleNodes(List nodes) { int count = 0; for (final node in nodes) { + if (!node.isVisible) continue; // 跳过不可见节点 count++; if (node.isDirectory && node.isExpanded) { count += _countVisibleNodes(node.children); @@ -152,8 +154,11 @@ class _TreeViewState extends State { TreeNode _getVisibleNode(List nodes, int index) { int current = 0; for (final node in nodes) { + if (!node.isVisible) continue; // 跳过不可见节点 + if (current == index) return node; current++; + if (node.isDirectory && node.isExpanded) { final childCount = _countVisibleNodes(node.children); if (index - current < childCount) { @@ -187,6 +192,7 @@ class TreeNodeWidget extends StatelessWidget { @override Widget build(BuildContext context) { + if (!node.isVisible) return const SizedBox.shrink(); // 额外保护 return InkWell( onTap: onTap, onDoubleTap: onDoubleTap, diff --git a/win_text_editor/lib/shared/models/template_node.dart b/win_text_editor/lib/shared/models/template_node.dart index 7221508..ea738a9 100644 --- a/win_text_editor/lib/shared/models/template_node.dart +++ b/win_text_editor/lib/shared/models/template_node.dart @@ -21,6 +21,9 @@ class TemplateNode implements TreeNode { @override String get title => name; + @override + bool get isVisible => true; + TemplateNode({ required this.name, required this.children,