docs: explain console, network and settings view projections

This commit is contained in:
2026-11-12 19:12:50 +08:00
parent 50571e156e
commit bb6e78ad04
3 changed files with 47 additions and 0 deletions
+13
View File
@@ -4,23 +4,27 @@
use super::*;
/// 将本进程 HTTP 活动投影为可筛选请求列表和独立滚动详情,并生成选择/分隔条命中区域。
// developer_tools::build 选择 Network 时调用,共享日志已在父入口克隆,过滤和文字测量不持活动日志锁。
pub(super) fn build(
p: &mut Painter,
state: &mut DeveloperToolsState,
records: &[Exchange],
viewport: Rect,
) {
// 工具页以 viewport 横向原点和宽度布局;底部状态栏高度留给父入口统一绘制。
let x = viewport.x;
let w = viewport.width;
let bottom = viewport.height - 22.0;
p.fill(Rect::new(x, 32.0, w, 30.0), BAR);
// 水位后存在记录才允许 Clear,Action::ClearNetwork 更新工具水位并清除选择,不删除 Console 共用日志。
p.enabled_button(
Rect::new(x + 3.0, 32.0, 62.0, 29.0),
"Clear",
Action::ClearNetwork,
records.iter().any(|r| r.id > state.network_after),
);
// 过滤框注册 Filter 焦点,按键编辑在 DeveloperToolsState 中处理;此处只展示当前文本与焦点。
let filter_area = Rect::new(x + 72.0, 35.0, (w - 85.0).max(100.0), 24.0);
p.ui.text_field(
filter_area,
@@ -33,6 +37,7 @@ pub(super) fn build(
&format!(
"Filter: {}{}",
state.filter,
// 竖线是焦点提示字符,不是 Console 那种按字节光标定位,也不修改过滤字符串本身。
if state.focus == Some(Focus::Filter) {
"│"
} else {
@@ -54,10 +59,12 @@ pub(super) fn build(
let divider = 92.0 + (bottom - 92.0) * state.network_fraction;
// 对方法、路径和状态的组合字符串做大小写不敏感子串匹配;未响应记录可用 pending 搜索。
let filter = state.filter.to_lowercase();
// 保留原记录顺序及引用,只建立本次展示候选,不复制/更改每条 Exchange 的响应状态。
let visible = records
.iter()
// 清屏按 ID 水位隐藏旧记录,不删除共享 ActivityLog,Console 仍可独立展示同一条请求。
.filter(|r| r.id > state.network_after)
// 方法、路径与状态合并后统一小写匹配,origin 和正文不在当前过滤范围内。
.filter(|r| {
format!(
"{} {} {}",
@@ -70,7 +77,9 @@ pub(super) fn build(
})
.collect::<Vec<_>>();
let mut lines = Vec::new();
// 逐匹配记录生成一行,pending 状态用省略号;耗时直接取日志快照,不在绘制时重新计时。
for r in &visible {
// 先创建带状态颜色的行,再附加稳定 Request 动作和选中标记,筛选改变行号也不会改变目标身份。
let mut l = Line::new(
format!(
"{:<7} {:<6} {:>5} ms {}",
@@ -97,6 +106,7 @@ pub(super) fn build(
MUTED,
));
}
// 列表使用 Requests Region 保存独立滚动,false 表示不因为新增请求自动跟随到底部。
p.lines(
Rect::new(x + 1.0, 92.0, w - 2.0, divider - 92.0),
Region::Requests,
@@ -104,12 +114,15 @@ pub(super) fn build(
state,
false,
);
// 只登记横向分隔条,父绘制入口最后覆盖绘制并注册 Split::Network 命中目标。
p.split(Rect::new(x + 1.0, divider, w - 2.0, 1.0), Split::Network);
// 详情从完整保留记录中查找,因此筛选隐藏某行后可继续查看已选详情;记录淘汰后才回提示。
let selected = records
.iter()
.find(|r| Some(r.id) == state.selected_request);
// 详情另建行列表,不依赖上面的 visible;筛选无匹配并不自动取消已选请求。
let mut details = Vec::new();
// 仍保留的已选记录交给 request_details;ID 已淘汰或从未选择则显示捕获范围说明。
if let Some(r) = selected {
request_details(&mut details, r);
} else {