窗口系统
窗口系统
本章围绕画面(type:'window')与它最常用的窗口形态展开。编辑器底部页签条「+画面」新建的就是画面:一块独立于页面的画布实体(默认固定中央 600×400,连续编号「画面N」)。画面自己不直接上屏,而是被三种方式「使用」——最典型的一种,就是以窗口(弹窗 / 详情面板 / 启动闪屏)的形态浮在页面之上打开。
页面 · 画面 · 窗口:先分清三个词
- 页面(screen):主画布。运行时一次只显示一个页面,
switchScreen整屏切换。 - 画面(window):与页面平级的工程顶层画布实体(
project.windows[]),一处定义、多处使用。 - 窗口:画面以浮层形式打开时的形态——本章其余小节(固定 / 锚定、遮罩、标题栏、关闭方式)说的都是这个形态。
| 概念 | 是什么 | 怎么显示 / 打开 | 应用场景 |
|---|---|---|---|
页面 screen | 主画布(project.screens[]) | switchScreen 整屏替换 | 大屏的各主题页:总览页、告警页、分厂页…… |
画面 window | 独立画布实体(project.windows[]) | 不直接显示,被下面几种用法消费 | 详情卡、公共头部、任何要「一处定义、多处使用」的内容块 |
| 窗口 | 画面以浮层打开的运行形态(不是另一种实体) | switchWindow 开 / 关 / 切换,或随页面打开 / 启动打开 | 模态弹窗、确认框、启动画面、地图信息窗、悬浮卡片 |
画面组件 window-instance | 把画面作为整体组件嵌进页面的容器组件 | 随页面显示;引用式,画面改动即时同步到所有引用处 | 公共头部 / 侧栏 / KPI 卡在多个页面复用 |
页面内弹窗 group-popup | 页面组件树内的轻弹层(是组件,不是画面) | switchPopup 动作 | 跟随页面版面的局部小浮层 |
界面对照:底部页签条从左到右是页面组、背景、画面组;画面属性面板的选项组叫「画面设置」(
window-mode画面模式 /window-position画面位置 /size画面大小……)。交互动作switchWindow在界面上叫「打开画面」,画面自身的screenAppear触发器显示为「画面打开时」。
画面内的组件与页面组件同构:可放任意组件、可配事件交互、可绑数据、可用项目参数与条件样式。寻址路径以画面 uid 起头(["window_detail", "w_t1"])。画面独立编辑(一次只编辑一个画面,从根上避免多弹窗重叠)。
画面的三种用法
① 弹窗打开 —— 窗口形态
组件事件配 switchWindow(界面名「打开画面」)把画面以浮层打开:全局模态弹窗、详情面板、确认框、启动画面、地图信息窗。窗口形态的固定 / 锚定、遮罩、标题栏、关闭方式见本章其余小节与下方「在线演示」。
② 嵌入页面 —— 画面组件 window-instance
把画面作为一个整体组件放进页面(容器分类下的画面组件,options.window 选目标画面)。这是引用式复用:画面内容一改,所有引用它的画面组件即时同步;双击画面组件直接进入该画面编辑。子组件坐标相对画面左上角 (0,0),content-fit 决定画面按其设计尺寸(画面的 size)渲染后如何缩放进组件框(拉伸 / 等比适应 / 等比铺满 / 不缩放)。循环嵌入(画面嵌自身或成环)会被阻止。
{ "type": "window-instance", "uid": "inst_header", "options": {
"position": [0, 0], "size": [1920, 100],
"window": [{ "refType": "element", "targetPath": ["win_header"] }],
"content-fit": "contain", "show-window-bg": true } }③ 发布为组件 —— 跨工程复用
画面页签上的「发布」按钮把画面打包成自包含组合组件(内容子树 + 引用的连接 / 数据规则等依赖 + 嵌套画面内联为快照)存入「资产库 · 我的组件」,可在其它工程拖入使用。与 ② 的区别:② 是工程内引用(即时同步),③ 是跨工程快照(发布时定格)。
选型速记:不离开当前页看更多内容 → ①窗口;多个页面共用同一块内容且要同步改 → ②画面组件;换个工程也要用 → ③发布为组件。
在线演示:同一画面,嵌入 + 弹窗两用
下面「KPI 卡片」画面被两个画面组件嵌在页面里,同时还能点按钮以模态窗口打开——同一份内容,一处修改、三处生效:
两类窗口
| 类型 | 行为 | 适用 |
|---|---|---|
| 固定 Fixed | 显示在页面固定位置:中央 / 上 / 下 / 左 / 右 | 表单、详情、确认框、启动画面 |
| 锚定 Anchored | 自动贴着触发它的元素旁边显示(自动翻转 / 避让 / 带箭头) | 工具提示、要素说明、分步引导、地图点击信息窗 |
固定窗口的定位与大小:
- 中央窗口可设宽 + 高;上 / 下窗口只设高(宽 = 页面宽);左 / 右窗口只设宽。
- 支持
window-offset(偏移微调)与window-margin(贴边留白)。 - 大小单位可选
px或percent(相对舞台逻辑尺寸)。 - 窗口随舞台一起缩放,与页面内容视觉一致。
遮罩与「阻止页面」
固定窗口可设为模态(block-page,默认 true——新建固定窗口即模态):窗口激活期间禁止与页面其余部分交互,并用遮罩颜色(background-mask-color)填充窗口外空间。锚定窗口永不模态。
在线演示:模态固定窗口
点「查看设备详情」用 switchWindow 打开一个模态固定窗口(带标题栏 / 遮罩 / 关闭按钮),点遮罩、右上角 ×、Esc 或窗口内按钮都能关闭:
打开窗口的方式
| 方式 | 怎么配 | 行为 |
|---|---|---|
| 交互触发 | 组件事件配 switchWindow 动作 | 每次触发都打开 / 关闭 / 切换 |
| 随页面打开 | 页面设置 open-with-window 关联一个窗口(不限固定窗口,锚定窗口也可;启动 splash 窗口不在候选) | 进入该页面自动打开,一个会话只出现一次 |
| 启动 splash | 工程设置 splashWindowUid | 应用加载即打开,一个工程至多一个;已关联页面的窗口不能设为启动 |
| URL 参数(规划中) | ?dlg= 直达开窗 | 当前版本未实现,设计预留给后续版本 |
代码侧还可用 SDK 程序化开窗(ctx.openWindow(uid) 等,见文末延伸阅读)。
switchWindow 动作片段:
{ "action": { "name": "switchWindow", "options": {
"windowUid": { "refType": "element", "targetPath": ["window_detail"] },
"operate": "open" } } } // open | close | toggle关闭窗口
- 点击窗口外(
close-outside,默认开):固定窗口仅在block-page: true时可配,点击遮罩即关;锚定窗口也可配——没有遮罩,点击窗口外任意处即关(点击触发它的组件本身豁免,保证按钮的 toggle 语义); - 窗口体右上角关闭按钮(
close-btn-*选项族,默认显示); - 窗口内按钮配
switchWindow(operate: close); Esc关闭焦点窗口自身(窗口打开时自动获得焦点);且仅当该窗口提供了任一用户关闭途径——开了close-btn-show,或(模态 / 锚定)且开了close-outside——才响应 Esc。
多个窗口同开时按打开顺序形成 z 序(后开在上;再次打开已开的窗口会提到最顶层)。
标题栏
窗口可开启内置标题栏(titlebar-*):标题文字、高度、背景、颜色、字号;开启后关闭按钮移入栏内。固定窗口在播放态可按住标题栏拖动(titlebar-draggable,默认开;锚定窗口不可拖;拖动位置不持久化,关闭后再打开复位。窗口已打开时再次 openWindow({ keepPosition: true }) 只刷新内容、保留当前位置)。几何语义上「窗口大小 = 整窗(含标题栏)」,内容区 = 窗口体 − 标题栏。
锚定窗口与地图信息窗
锚定窗口贴着触发元素定位:anchor-placement: auto 时按候选序取第一个空间足够的一侧——地图点锚为 上→下→右→左(信息窗习惯),元素锚为 下→上→右→左(Popper 默认);指定朝向时其余侧作为翻转(flip)候选。各侧都不够则取空间最大侧,并把窗口钳入舞台(交叉轴同样钳入,shift);箭头始终指向锚点中心。锚不可得(splash / 随页面打开 / 触发组件未挂载)时回退为固定居中显示。
当触发元素是 2D 地图且点击了要素时,窗口会随地图平移 / 缩放跟随要素移动(等价地图 Popup),要素移出视域则隐藏。在地图图层属性的「要素弹窗」组配置:feature-panel-uid 选一个锚定窗口(点击要素即打开并贴着要素定位),feature-panel-offset 在锚点上追加像素偏移 [水平, 垂直]。
组件级悬浮弹层
基于锚定窗口机制,任意组件都能配「鼠标悬停 / 点击 → 旁边弹出内容」,在组件属性面板「悬浮弹层」组配置即可,运行态自动接线:
| 形态 | 内容 | 触发 | 特点 |
|---|---|---|---|
| 文字提示 tooltip | 文本 | 悬停 | 轻量浮层,离开即关 |
| 悬停卡片 hover card | 窗口 | 悬停 | 鼠标移入卡片不消失、可交互(悬停桥接) |
| 点击弹窗 popover | 窗口 | 点击 | 点击 toggle,点外 / Esc 关闭 |
content: window的目标窗口建议设为锚定模式,弹层才贴着组件定位。仅预览 / 运行态弹出,编辑态不弹。
悬浮弹层选项(组件属性「悬浮弹层」组,hover-popup-*):
| 选项 | 默认 | 说明 |
|---|---|---|
hover-popup-enable | false | 启用悬浮弹层 |
hover-popup-trigger | hover | hover / click / both |
hover-popup-content | text | text 文字提示 / window 弹出画面(可交互) |
| 文字系 | — | hover-popup-text / -bg / -color / -font-size(13)/ -max-width(280)/ -padding(8),仅 content: text |
hover-popup-window | — | 目标窗口(仅 content: window,建议锚定模式) |
hover-popup-placement / -gap / -arrow | auto / 8 / true | 弹出朝向 / 间距 / 箭头;仅对文字提示的定位生效,content: window 时定位取目标窗口自己的 anchor-* 选项 |
hover-popup-open-delay / -close-delay | 150 ms | 进入 / 离开延时(仅悬停触发时生效,抑制快速划过的闪烁) |
窗口 vs 页面内弹窗(group-popup)
平台保留了「页面内弹窗」组件(group-popup),两者适用场景不同:
| 页面内弹窗 | 窗口 | |
|---|---|---|
| 归属 | 页面组件树内 | 工程顶层实体 |
| 定位 | 页面坐标系内任意摆放 | 舞台锚点(中央 / 贴边)+ offset |
| 触发 | switchPopup 动作 | switchWindow / 随页面打开 / splash |
| 适用 | 页面内跟随版面的轻弹层 | 全局模态、启动页、确认框、跨页面复用弹层 |
画面不是物料、不能从组件库拖入画布,只在底部页签条「+画面」创建;要把画面「摆进」页面,用的是引用它的画面组件。
窗口选项速查
| 选项 | 默认 | 说明 |
|---|---|---|
window-mode | fixed | fixed 固定 / anchored 锚定 |
window-position | center | center / top / bottom / left / right(仅固定窗口) |
size | [600, 400] | [宽, 高];top / bottom 仅高度生效(宽 = 页面宽),left / right 仅宽度生效(高 = 页面高) |
size-unit | px | px / percent(percent 相对舞台逻辑尺寸) |
window-offset | [0, 0] | 位置偏移 [x, y] |
window-margin | [0,0,0,0] | [上, 下, 左, 右],仅贴边窗口的铺满轴生效 |
block-page | true | 模态:禁止页面交互并显示遮罩(仅固定窗口) |
background-mask-color | rgba(0,0,0,0.5) | 遮罩颜色(block-page 开启时可配) |
close-outside | true | 点击窗口外关闭(固定窗口需 block-page;锚定窗口点窗外任意处) |
show-scroll | false | 内容区可滚动 |
window-bg | #1b1f27 | 窗口体背景色 |
| 阴影组 | 关 | box-shadow-show(默认 false)+ -offset([0,8])/ -blur(24)/ -spread(0)/ -color |
| 标题栏组 | 关 | titlebar-show(默认 false)+ -text / -height(≥24,默认 36)/ -bg / -color / -font-size;titlebar-draggable(默认 true,仅固定 + 标题栏,播放态拖动不持久化) |
| 关闭按钮组 | 开 | close-btn-show(默认 true)+ -color / -size(18)/ -offsetX / -offsetY |
| 锚定组 | — | anchor-placement(auto / top / bottom / left / right,默认 auto)/ anchor-gap(默认 8)/ anchor-arrow(默认 true),仅锚定窗口 |
窗口没有独立的边框 / 圆角 / 动画选项;需要这类装饰可在窗口内容里用组件实现。
工程 JSON 速查
{
"windows": [{
"uid": "window_detail", "type": "window", "name": "详情窗口",
"options": {
"window-mode": "fixed", // fixed | anchored
"window-position": "center", // center | top | bottom | left | right
"size": [800, 520], "size-unit": "px",
"block-page": true, "background-mask-color": "rgba(0,0,0,0.5)",
"close-outside": true, "close-btn-show": true,
"titlebar-show": true, "titlebar-text": "设备详情",
"window-bg": "#1b1f27" // 窗口体背景(注意不是 background-color)
},
"widgets": [ /* 窗口内容,结构与页面 widgets 一致 */ ]
}],
"settings": { "splashWindowUid": "window_welcome" }
}页面关联「随窗口打开」写在页面节点:"options": { "open-with-window": "window_detail" }。
延伸阅读:画面组件 window-instance(画面嵌入页面复用)· 事件交互(switchWindow 动作与触发器)· 画布系统(窗口随舞台缩放的坐标系)· 2D 地图(地图要素点击 → 信息窗跟随)· SDK 与扩展开发(代码控窗:ctx.getWindow / openWindow / closeWindow / closeTopWindow 等窗口 API)。