5 changed files with 312 additions and 151 deletions
@ -0,0 +1,73 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:win_text_editor/shared/components/tree_view.dart'; |
||||||
|
|
||||||
|
class TemplateNode implements TreeNode { |
||||||
|
@override |
||||||
|
final String id; // 使用路径或唯一标识作为ID |
||||||
|
@override |
||||||
|
final String name; |
||||||
|
@override |
||||||
|
final List<TemplateNode> children; |
||||||
|
final Map<String, String>? attributes; |
||||||
|
final String? text; |
||||||
|
|
||||||
|
@override |
||||||
|
final int depth; // 节点深度 |
||||||
|
@override |
||||||
|
bool isExpanded; // 是否展开 |
||||||
|
bool isRepeated; // 是否重复节点 |
||||||
|
|
||||||
|
@override |
||||||
|
bool get isDirectory => children.isNotEmpty; // 有子节点即为目录 |
||||||
|
|
||||||
|
@override |
||||||
|
IconData? get iconData { |
||||||
|
if (name.startsWith('@')) return Icons.code; // 属性节点 |
||||||
|
return isDirectory ? Icons.folder : Icons.insert_drive_file; // 元素节点 |
||||||
|
} |
||||||
|
|
||||||
|
TemplateNode({ |
||||||
|
required this.name, |
||||||
|
required this.children, |
||||||
|
this.attributes, |
||||||
|
this.text, |
||||||
|
this.depth = 0, |
||||||
|
this.isExpanded = false, |
||||||
|
this.isRepeated = false, |
||||||
|
String? id, |
||||||
|
}) : id = id ?? '${depth}_${name}'; // 默认ID生成逻辑 |
||||||
|
|
||||||
|
// 转换为属性节点 |
||||||
|
TemplateNode.attribute(String name, String value) |
||||||
|
: this(name: '@$name', children: const [], attributes: {name: value}, depth: 1); |
||||||
|
|
||||||
|
// 克隆方法用于生成子节点 |
||||||
|
TemplateNode copyWith({int? depth, bool? isExpanded}) { |
||||||
|
return TemplateNode( |
||||||
|
name: name, |
||||||
|
children: children, |
||||||
|
attributes: attributes, |
||||||
|
text: text, |
||||||
|
depth: depth ?? this.depth, |
||||||
|
isExpanded: isExpanded ?? this.isExpanded, |
||||||
|
id: id, |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TemplateItem { |
||||||
|
final int id; |
||||||
|
final String content; |
||||||
|
final String xPath; |
||||||
|
final String value; |
||||||
|
|
||||||
|
TemplateItem({required this.id, required this.content, required this.xPath, required this.value}); |
||||||
|
|
||||||
|
bool matches(TemplateNode node) { |
||||||
|
if (node.name.startsWith('@')) { |
||||||
|
final attrName = node.name.substring(1); |
||||||
|
return xPath.contains('@$attrName'); |
||||||
|
} |
||||||
|
return xPath.contains(node.name); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue