docs: explain developer tool painting and source selection
This commit is contained in:
@@ -4,12 +4,14 @@
|
||||
use super::*;
|
||||
|
||||
/// 根据云文件/当前快照模式构建左右两栏,展示文件或 AST 选择,并生成只读源码行和跳转动作。
|
||||
// developer_tools::build 在 Sources 标签选中时调用,左侧生成可激活动作,右侧只读展示文本并供 SourceSelection 复制。
|
||||
pub(super) fn build(
|
||||
p: &mut Painter,
|
||||
state: &mut DeveloperToolsState,
|
||||
doc: &RenderDocument,
|
||||
viewport: Rect,
|
||||
) {
|
||||
// 横向原点/宽度来自工具画布,AST 或文件树与源码面板都使用这个局部坐标系。
|
||||
let x = viewport.x;
|
||||
let w = viewport.width;
|
||||
// width 在本函数表示右边界坐标,w 才是视口宽度;用于计算右侧源码区域和按钮位置。
|
||||
@@ -17,6 +19,7 @@ pub(super) fn build(
|
||||
let bottom = viewport.height - 22.0;
|
||||
|
||||
p.fill(Rect::new(x, 32.0, w, 30.0), BAR);
|
||||
// 两个切换按钮仅发出 Snapshot/Cloud 动作,改变当前展示模式,不替换文档或执行文件。
|
||||
p.button(
|
||||
Rect::new(x + 3.0, 32.0, 139.0, 29.0),
|
||||
"Current snapshot",
|
||||
@@ -39,8 +42,10 @@ pub(super) fn build(
|
||||
);
|
||||
// 树宽至少 120,通常为右侧内容保留 180;窄窗口仍保持树最小宽,交由绘制裁剪处理。
|
||||
let tree = state.tree_width.clamp(120.0, (w - 180.0).max(120.0));
|
||||
// 树右边界后预留分隔线间隙,再作为源码区左边界;width 是工具右边界坐标而非可用宽度。
|
||||
let code_x = x + tree + 2.0;
|
||||
p.label(x + 10.0, 69.0, "CLOUD FILES", MUTED, false);
|
||||
// 列表来自最近成功 provider 刷新,每行只携带显示路径和不透明 ID;这里不会同步调用外部服务。
|
||||
let file_lines = state
|
||||
.cloud_sources
|
||||
.files
|
||||
@@ -59,11 +64,14 @@ pub(super) fn build(
|
||||
state,
|
||||
false,
|
||||
);
|
||||
// 登记树/源码的竖向分隔线,真实覆盖绘制和命中由父入口最后完成。
|
||||
p.split(Rect::new(x + tree, 63.0, 1.0, bottom - 63.0), Split::Tree);
|
||||
// 云文本与 provider 错误组合成本帧行列表,旧打开内容可与新错误同时展示。
|
||||
let mut source_lines = Vec::new();
|
||||
// 成功打开的云文本逐行加显示行号;这里不替换 doc.source,也不触发程序热重载。
|
||||
if let Some(source) = &state.cloud_sources.opened {
|
||||
p.label(code_x + 10.0, 69.0, &source.path, MUTED, false);
|
||||
// 显示加一基行号和两空格前缀,复制时 Painter 按约定剥除前七字符;原始 code 不被改写。
|
||||
for (i, line) in source.code.split('\n').enumerate() {
|
||||
source_lines.push(Line::new(format!("{:>5} {}", i + 1, line), TEXT));
|
||||
}
|
||||
@@ -75,6 +83,7 @@ pub(super) fn build(
|
||||
);
|
||||
}
|
||||
// provider 错误附在当前源码下方;即使读取失败仍可展示上次成功打开的内容。
|
||||
// 错误作为追加行显示,不清掉文件列表或已打开文本;重绘不会重试失败请求。
|
||||
if !state.cloud_sources.error.is_empty() {
|
||||
source_lines.push(Line::new(&state.cloud_sources.error, ERROR));
|
||||
}
|
||||
@@ -86,6 +95,7 @@ pub(super) fn build(
|
||||
false,
|
||||
);
|
||||
} else {
|
||||
// 快照模式沿用同一个树宽状态,切换模式不另设隐藏的分隔条宽度。
|
||||
let tree = state.tree_width.clamp(120.0, (w - 180.0).max(120.0));
|
||||
let code_x = x + tree + 2.0;
|
||||
p.label(x + 10.0, 69.0, "ASTER AST", MUTED, false);
|
||||
@@ -109,11 +119,15 @@ pub(super) fn build(
|
||||
MUTED,
|
||||
false,
|
||||
);
|
||||
// AST 行与源码行分开收集,Tree/Source 两个 Region 各自维护滚动和宽度缓存。
|
||||
let mut tree_lines = Vec::new();
|
||||
// 只展开已发布文档中的 CodeNode 树,不从当前 Console 输入临时解析一棵新 AST。
|
||||
if let Some(root) = &doc.root {
|
||||
// flatten 保存深度及节点借用,不复制原树;显示文本和跳行动作在后面的循环构造。
|
||||
let mut flat = Vec::new();
|
||||
// 将发布 AST 展平成带深度的行;行动作保存节点稳定 ID 与起始行,用于选择并跳到对应代码。
|
||||
flatten(root, 0, &mut flat);
|
||||
// 深度只影响缩进,选中身份用稳定节点 ID,起始行号另给 Action::Node 用于源码定位。
|
||||
for (depth, n) in flat {
|
||||
let mut l = Line::new(format!("{}{} {}", " ".repeat(depth), n.kind, n.name), TEXT);
|
||||
l.selected = state.selected_node_id.as_deref() == Some(&n.id);
|
||||
@@ -136,6 +150,7 @@ pub(super) fn build(
|
||||
.selected_node_id
|
||||
.as_deref()
|
||||
.and_then(|id| doc.node(id));
|
||||
// 展示副本统一换行并展开 Tab,所以选择复制的是工具显示文本;原 doc.source 保持不变。
|
||||
let code_lines = doc
|
||||
.source
|
||||
// 仅显示投影统一 CRLF 并把 Tab 展开为四空格;原始文档文本保持不变。
|
||||
|
||||
Reference in New Issue
Block a user