Files
endorphin-tessera-gui/docs/page-surfaces.md
T

60 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Endorphin 页面空间与窗口边界
> 下文的 Page.mode 是前一阶段的兼容接口。当前默认页已迁移到普通 Page、Row/Column、滚动容器和独立 Scene2D / CanvasViewport / Camera2D。新代码请使用 [统一场景架构](scene-architecture.md),不要再把横纵排版或相机作为 Page 的固有模式。
本次按参考图的“左侧栏展开/收起”两种状态调整原生宿主。窗口保留系统关闭、最小化和缩放按钮;宿主管理入口集中在左侧栏。收起后只保留展开按钮及系统三键,页面从窗口左上角铺满,不再保留顶部标签条、左侧空轨或内容卡片边距。
页面内容、卡片、文字和操作按钮由 Endor 源码渲染。默认 [开始页](../src/bridge/ui_bridge/start_page.endor) 是真实的画布 Page,其操作创建另外三种 Page;不会把示例的静态截图当作可操作界面。
## 四种页面模式
| `page.mode` | 布局 | 浏览方式 |
| --- | --- | --- |
| `window`(默认) | 根 Page 等于可用区域,子组件按纵向流组织 | 应用自行安排内部布局或 ScrollBlock |
| `vertical` | 宽度跟随可用区域,高度至少一屏并随子组件增长 | 纵向滚动,偏移限制到内容范围 |
| `horizontal` | 高度跟随可用区域,宽度至少一屏并随子组件增长 | 横向滚动;普通纵向滚轮也可推进横向页面 |
| `canvas` | 直接子组件使用各自的 `x`、`y` 世界坐标 | 双向平移、缩放,视角不限制到内容边界 |
侧栏展开占用 256 个逻辑像素;收起归还全部宽度。`ui.viewport()`、`window.viewport()` 和 GET code 的 viewport headers 均报告实际可用页面区域。窗口变更重排同一个运行时,不重放源码。窗口模式保证根 Page 填满,但不会强迫每个子组件拉伸。
```endor
page = Page()
page.mode = "canvas"
page.title = "我的画布"
card = Button("一个真正的 Endor 组件")
card.x = -120
card.y = 90
page.render(card)
page.panX = -200
page.panY = 0
page.zoom = 1
```
`page.render(root)` 替换内容;`page.append(child)` 继续添加。直接画布子组件的 `x/y` 决定位置,内部 Row/Column 仍使用原来的流式布局;纵向、横向和窗口页面不使用子组件的 `x/y` 排列。共享 Block 可以有多个 Mount,不会为画布复制业务对象。
## 交互与坐标
- 滚轮或触控板平移;嵌套 ScrollBlock 优先处理其可滚动方向。
- 画布支持空格+左键拖动、鼠标中键拖动;已有按钮键盘焦点保留 Space 激活。
- 画布支持捏合、Cmd/Ctrl+滚轮缩放,以指针位置为锚点。
- Cmd/Ctrl+B 展开/收起侧栏;侧栏提供新建、切换和关闭页面及四个开发工具入口。
- Cmd/Ctrl+T 新建,Cmd/Ctrl+W 关闭,Ctrl+Tab / Ctrl+Shift+Tab 切换页面。
`panX/panY` 是可视区域左上角的世界坐标,`zoom` 为 0.1–4。变换是 `screen = (world - pan) * zoom`;绘制使用正变换,原生点击/滚动使用逆变换。VM 中 Mount 始终使用世界坐标,worker 根据同一视角重新检查可见性。Page 自己保存视角,切换后仍保留;有限页面在内容缩短或窗口变大时限制偏移。
画布没有内容边界裁剪,但保留现有运行预算:坐标为有限数且绝对值不超过 1,000,000,维度、对象数和绘制命令数仍有上限。“无限”指可以向内容以外导航,不代表无限内存或数值范围。
原生相机事件 `page-pan/page-zoom` 经过真实 HTTP worker,再由所属 VM 更新 Page;它们使用 `mount=0` 和当前 window/session/layout_version。平移 delta 使用可视区域像素;缩放 delta 为 `[factor,0]`,point 是可视区域内的锚点。普通点击与嵌套滚动的 point 使用世界坐标。过期事件返回 409;不适用于当前模式或参数非法的相机事件在执行前拒绝。
## 实现位置与验证边界
- [page.rs](../src/render/page.rs):模式约束、视角、正逆坐标变换和有限页面偏移限制。
- [sidebar.rs](../src/shell/sidebar.rs):唯一宿主管理栏及折叠后点击遮挡范围。
- [page_input.rs](../src/bridge/ui_bridge/page_input.rs):串行 VM 内的视角变更。
- [API 回归](../src/runtime/api/tests.rs):真实 HTTP 平移、指针锚定缩放、负世界坐标点击、过期/非法事件。
- [宿主回归](../src/runtime/endor_host/tests.rs):四种模式、实时内容增长、共享对象坐标、视角恢复和默认页真实按钮。
本地格式、153 项测试和 all-target Clippy 均通过;release app 已构建并实际启动。运行中平移与缩放事件返回 200,并读回 Page.panX=80、Page.zoom=2,随后恢复初始视角。最初 HTTP worker 漏接相机事件导致 400,现由完整链路回归覆盖。
macOS 当前未授予本次工具模拟输入和窗口截图权限。模拟滚轮未生效,无法据此声称真实鼠标/触控板、捏合或窗口外观验收通过。侧栏指针拖放、跨窗口拖放尚未迁移;原有 `moveTab/moveToWindow/detachToWindow` 与版本校验的 API 保留。没有修改 Aster 或引入新的 GUI/语言依赖。