# 页面是怎么用的

> 两种页面模板、边编辑边保存的就地面板、命令栏和它那两种拒绝、右键菜单、工程锁定、停止的运行时、各种确认，以及每一个结果落在哪里。

Ganter Lab 的各个页面共用一小套约定，于是你配好了一样东西，就知道下一样该怎么配：两种页面模板、边编辑边保存的面板、放置一条命令的一种办法和拒绝它的两种办法、一个把命令栏重复一遍的右键菜单，以及结果落下来的那一个地方。这一页把它们说一次；各个区域的页面只讲它们自己特有的东西。

## 两种页面模板 {#two-page-templates}

### 主从页面 {#master-detail-pages}

Connector、Logic、Process 和用户是主从页面，而 View 是用手排成同样的样子的。在页面横幅（标题、一行说明、一条细线）下面，屏幕分成左边一栏和右边一张详情卡片。

| 部分 | 它是什么 | 你能做什么 |
|---|---|---|
| 这一栏的横幅 | 这一栏的名字（通信、地址空间、工作区、工作站访问、可视化）和一个折角箭头 | 折角箭头把这一栏收成一条窄条，名字竖着写在上面；按那条窄条就把栏带回来。 |
| 搜索或者筛选 | 每个页面自己的那一个，在树上面：Connector 有一个搜索框（“搜索驱动、线路、设备、点位”）和全部、正常、有问题、已禁用这几个状态筛选项；Logic 有“筛选…” | 不匹配的行被藏起来；那些给一组根命名的小标题（“在这里定义”、“来自其他页面”）跟着它们的行走。 |
| 树 | 这个页面的那些节点，凡是有子节点的行都带一个展开的折角箭头，选中的那一行高亮 | 一次点击就选中并在右边打开这个节点的面板。上和下移动选中项，右展开，左收起，回车选中。在用得上双击的挑选器里，双击就是激活。正在重命名的那一行变成它自己的名称字段：回车或者离开这个字段就提交，Esc 取消。 |
| 栏底 | 这一栏的命令，在每个页面上都在同一个角上：一个 **+**（提示文字“新建…”）、一个可选的重排组，以及**全部展开** / **全部收起** | **+** 打开一个挂在这个按钮上的菜单，写明可以创建什么、创建出来落在哪里。没有哪一行能打开时，全部展开和全部收起变灰。这个身份一条命令都用不了时，整个栏底都不画出来。 |
| 分隔条 | 栏和卡片之间的一条细线 | 在 260 到 600 像素之间拖动它，也可以用 Tab 走到它上面，再用键盘挪它：一次方向键挪 16 像素，Page Up 和 Page Down 挪 96，Home 和 End 把它送到两端。页面开着期间，宽度停在你放手的地方。 |
| 详情卡片 | 一个钉住的抬头，上面是选中节点的头部（一个单色图标、标题、可选的胶囊、一行副标题，有时还有一个靠右的动作），下面是命令栏；主体在它下面滚动 | 什么都没选中时，抬头留空，主体里放一句占位的话。有些屏幕把主体交给它们自己的界面（一个 Process 模型的那几个定义屏幕），它们有自己的分栏和自己可拖动的分隔线。 |

### 滚动页面 {#scrolling-pages}

设置、账户、代理和验证是一整条滚动。在横幅下面，左边有一份索引，把每一节列在它那个小标题分组下面（常规、数据，等等）；点一下就把那一节滚进视野，活动的那一项跟着你的滚动走，而一个链接可以直接打开某一节（`/settings#sec-updates`）。每一节带着它的标题，一组里的第一节还带着那个分组小标题。验证占满整个宽度，因为它那些行是句子。事件是唯一一个带标签页的页面：报警、事件条目、联锁和控制台，每一个都有自己的地址（`/events?view=…`）。

## 边编辑边保存的就地面板 {#inline-panels-with-autosave}

面板上没有确定、保存或者应用按钮：选中的那样东西就地编辑，你每改一处就保存一处。面板收不下的值会在你敲它的那个地方被拒绝，字段下面出现一条说明，而且绝不保存。

| 控件 | 什么时候保存 | 说明 |
|---|---|---|
| 开关 | 一拨动 | 变灰的开关保持它的状态，并在提示文字里说明它为什么改不了。 |
| 复选框 | 一勾上 | |
| 文本字段 | 每敲一键 | 名称、地址和连接字段是例外：它们在你离开字段或者按下回车时提交，而回车只提交一次。名称字段会在它自己下面显示这次提交会连带做什么（它会改写哪些引用），在你提交之前。 |
| 数字字段 | 离开字段时 | 不是数字的值，或者落在这个字段范围之外的值，会被拒绝并给出一条说明（“‘abc’不是数字。”、“请输入 1 到 65535 之间的数字。”），框里退回到正在生效的那个值。写法不同的同一个值（“007”、“7.0”）会被接受并按规范写法重写。 |
| 组合框 | 一选中 | 可编辑的组合框会提交它里面装着的东西，不管列表有没有给出过它（比如一个 Logic 地址）。 |
| 表格单元格 | 这个单元格被编辑时 | 先勾上若干行，这次编辑就应用到每一个勾上的行（点位表格）。 |
| 代码编辑器 | 按编辑器自己的提交方式 | 表达式、脚本和条件；见[表达式](logic-expressions)。 |

字段还带着另外两样东西：

- 字段下面有一条从不改变的**说明**，讲这个字段决定什么；另有一行单独的**效果**（自己的缩进、自己的记号），讲当前这个值产出什么。一条你可以当作解释来信任的说明，是那种不会因为你换个选择就自己改写的说明。
- 凡是一个选项会改变应用画出什么的地方（一个仪表盘预设、一种图表形状、一个判据窗口、一件图表工具），挑选器会在选项名字旁边给出结果的一个**标记**，它是从画真东西的那段代码里派生出来的。在那个尺寸上画出来分不出两个选项的地方，两个都不给标记。

一次保存的结果落到状态栏的操作记录条上，不落在面板上（见[结果落在哪里](app-conventions#where-results-land)）。

## 命令栏 {#the-command-bar}

一个动词属于它所作用的那样东西，而它待在哪里，是从它的目标读出来的，绝不是从它有多危险读出来的。三种目标，三个家：

| 目标 | 家 | 顺序 |
|---|---|---|
| 这一栏选中的那个节点 | 卡片钉住的抬头下面那条栏 | 前面那一组（左边）负责创建、复制、编辑、派生和启动。后面那一组（右边）负责结束：删除、移除，用危险色调，于是这一组读起来就是一句警告。没有什么可结束的那条栏不会把那个角空着：它接过目标是窗口的那些动词，**展开**和**全屏**，于是打开的那个界面能拿到多少地方，在每一个场合都在同一个角上找得到。 |
| 一张卡片装着的整张表 | 卡片自己的抬头，压在它所触及的那些行上面 | 先是让列表长大的那个，然后是重读它的那个，最后用危险色调的是结束这个页面选中那一行的那个。结束的那个动词写明它作用于什么，被拒绝时说明为什么，而不是在什么都没挑中时消失掉。 |
| 一行，别的都不管 | 那一行后面那一组动作：字形按钮，结束的那一个用危险色调 | 按其中一个绝不会改变选中项。一张卡片要么在抬头上结束它自己的行，要么在行上结束，绝不对同一张表两样都来。 |

分屏里一块围起来的区域就是一张卡片。共用的那个面板头部保留它的图标、标题、副标题和胶囊，而且从不带动词；一条就地通知里面的动作是这条通知的答复，不是头部的动词。

栏上有一种控件不是动词：**状态开关**，用于目标就是打开的这个界面本身、而且没有哪张卡片或者哪个字段是回答这件事的每个界面都有的那种决定（一个 Process 模型的仪表画面上的“在 View 上显示”）。它是应用自己那个带标签的开关，于是状态是从这个控件上读出来的，而不是从一个看起来被按下去的动词上读出来的；它的提示文字说明生效的这个状态意味着什么。一个本身就是模式的动词（编辑、完成编辑；一件图表工具）在打开着的时候显示成按下的样子。

## 两种拒绝 {#two-kinds-of-refusal}

每一条栏、每一个菜单和每一个开关，都用同一种办法把两种拒绝分开：

| 拒绝 | 怎么显示 | 为什么 |
|---|---|---|
| 登录的这个角色**永远**不会被允许运行它 | 这条命令根本不画出来 | 按下去也换不来这项权限，而一排这个角色永远够不着的灰动词只占地方，还让人觉得产品坏了。一个只能查看的角色读到的栏，就是它能做的那么大。 |
| 这条命令**此刻**被拒绝 | 这条命令照样画着，变灰；提示文字说明缺什么：什么都没选中、有单元在跑时工作站锁着、有一次运行正在进行、“运行时已停止” | 那是会变的，而你必须知道这条命令存在，也必须知道什么能把它带回来。 |

理由是一种情形时，结束什么东西的那个动词也不例外：它留在原处，变灰，照样写明它结束的是什么。菜单在悬停时说出同样的理由，状态开关把理由放在说明状态含义的那句话前面，而栏底的 **+** 以及它的全部展开 / 全部收起，也用同样的方式变灰。

## 右键映着命令栏 {#right-click-mirrors-the-toolbar}

在树的一行上右键单击，会先选中那一行，然后在光标处打开一个菜单，里面是同样的动词、同样的危险色调，也在同样的拒绝之下，所以这个菜单总是作用于光标底下那一行。除了命令栏上的动词，菜单还提供在那一行下面新建的东西，也就是这一栏的 **+** 菜单为它走到的那些同样的条目。会打开一串去处的那种行（移动到某个文件夹、一台设备可以加到哪些驱动下面）会在它旁边打开那一串，只深一层，悬停或者按下都行；按下一片叶子就执行它并关掉菜单。在外面点一下、改变大小，或者那一行滚走了，都会在什么都不执行的情况下关掉菜单。这一栏的 **+** 挂在按钮上打开同一种菜单，用键盘按和用鼠标按都一样。

## 工程锁定 {#the-engineering-lock}

配置和实时运行共用这台工作站。只要至少有一个单元在跑一个流程，配置就是只读的：页面显示提示条**工程已锁定**，“有一项单元操作正在进行。在每个单元结束之前，配置保持只读；运行控制和其他操作员动作仍然可用。”，而详情卡片，包括它钉住的头部，都不再响应。栏上的动词各自照样说明自己可不可用，因为有好几个在这把锁下面照样开着：运行、暂停、继续、停止或者中止一次运行的，确认一条报警的，写一个值的，都照样能用。最后一个单元结束时，编辑自己恢复。见[运行记录](process-runs)。

## 停止的运行时 {#the-stopped-runtime}

一台没有许可证、免费模式时长已经走完的工作站会停下运行时：除了账户之外的每一个页面都让位给同一条暂停通知，而每一条会改动工作站的命令，包括一次运行本来会留着开的那些，都以“运行时已停止”被拒绝。那条带子、暂停的页面和那次重启在[窗口](app-window#the-stopped-runtime-band-and-the-paused-page)下面讲；那些时长本身在[免费模式与许可证](app-free-mode)下面讲。

## 确认与各种窗口 {#confirmations-and-dialogs}

编辑从不打开窗口；窗口留给短暂的事和破坏性的事。

| 窗口 | 什么时候 | 它怎么表现 |
|---|---|---|
| 确认 | 在一次删除或者一次恢复之前：“要删除‘*名称*’吗？*什么会消失。* 此操作无法撤销。” | 两个按钮，取得焦点的是拒绝的那一个：回车、Esc 和在外面点一下，答的都是否；确认要有意地按一下 Tab 或者点一下。没有明确的“是”，破坏性的事一样都不会往下走。 |
| 消息 | 主管理员那把只显示一次的恢复密钥，在这个 PIN 被设置或更改的时候。工作站只为这一件事打开这个窗口：密钥只出现这一次，别处再也找不到，所以它得留在屏幕上，直到被抄下来。 | 一个**确定**。窗口一打开就接过焦点，它说的话因此会被读出来；Esc 或者在外面点一下就把它送走，Tab 一直待在窗口里面。它绝不是结果：跑完了的命令在操作记录条上说话。 |
| 短暂的编辑窗口 | 登录窗口、崩溃同意窗口、正在往 OPC UA 服务器上添加的那个客户端 | Esc 或者在外面点一下就取消；窗口有默认动作时回车就提交；Tab 一直待在窗口里面。 |

就地通知，也就是在页面上而不是压在页面上的那些，是提示条：一个标题、一段正文，有时还有一个动作，配一条与它严重程度同色调的细线（提示、警示、严重、成功）。只有当一种状况的后果已经在发生时（比如一次实时的外部停机），提示条才用满整片颜色；其余的都是对状态的一次陈述。

## 结果落在哪里 {#where-results-land}

你刚做的事，不管是什么，都在状态栏的操作记录条上报出结果，别的地方都不报：一次保存、一次删除、一次重命名、一次导入、一次打印、一次重扫、一次登录。两种结果都会报出，而一次失败大约十秒之后会自己消失，要是在这之前你把它关掉，或者有更新的结果把它顶替，它就在那时消失；关于 Connector 里某台设备、某条串行线路或某个 MQTT Broker 的拒绝，在那台设备、那条线路或那个 Broker 保存成功时也会消失。唯一的例外是从一个仪表画面组件里发出的命令，它在那个组件下面作答。通知（弹出消息）是给打断人的事用的，绝不用来答复一次按下。见[操作记录条](app-window#the-action-feed)。

## 主题与颜色 {#theme-and-colour}

颜色留给含义用。一个状态圆点在中性时是灰色，健康时是绿色，降级或者正在启动时是警示色调，故障或者离线时是红色，而在值得注意却又没有降级时（比如一条中优先级报警）是强调色。危险色调标出结束什么东西的那些；一条警示说明标出被拒绝或者被扣住的东西。浅色和深色外观用标题栏上那几个主题按键，或者在[设置的“外观”](settings-appearance)下面挑。在工作站的窗口上，这个选择属于工作站；每个浏览器都跟随它，直到有人在那个浏览器里挑了一个主题，此后那个浏览器保留自己的选择。

## 没有哪个页面会做的事 {#what-no-page-does}

- 没有哪个页面会为一台设备、一个点位、一个变量、一个模型、一位用户或者一个角色打开一个模态编辑窗口；每一样都在它自己的面板里编辑。
- 没有哪个页面会自己闪一下“已保存”、自己写一行状态，或者自己弹一条消息。
- 没有哪个页面会把这个角色永远跑不了的动词画成灰的，也没有哪个页面会把只是此刻被拒绝的动词藏起来。
- 运行时停止期间，没有哪个页面会一个控件一个控件地冻住；外壳把整个页面顶替掉。
- 没有哪个动词坐在面板头部上，也没有哪个页面会把它那条栏上的几组重新排过。
- 没有哪张表会让一个值读不全：栏里放不下的值用省略号截断，完整内容在它的悬停提示里。
