视图(Views)

14 Aug 2024

概述和背景

Windows 提供的用户界面构建工具非常原始。系统提供了一些基本的控件和原生窗口容器,但构建自定义用户界面相当困难。由于我们希望为 Chromium 提供与众不同的美学效果,因此我们必须在 Windows 上构建一个框架,以加速自定义 UI 的开发。这个系统称为 Views。

Views 是一个渲染系统,类似于 WebKit 或 Gecko 用于渲染网页的系统。用户界面由一棵称为 Views 的组件树构成。这些 Views 负责渲染、布局和事件处理。树中的每个 View 代表 UI 的不同组件,可以类比为 HTML 文档的层次结构。

在 View 层次结构的根部是一个 Widget,它是一个原生窗口。原生窗口从 Windows 接收消息,将其转换为 View 层次结构能够理解的内容,然后将其传递给 RootView。RootView 然后开始将事件传播到 View 层次结构中。

绘制和布局的过程类似。View 树中的一个 View 有其自己的边界(通常由其包含的 View 的布局方法赋予),因此当它被要求绘制时,它会在限制在其边界内的画布上绘制,并将渲染原点转换到 View 的左上角。整个 View 树的渲染在 Widget 接收到 Paint 消息时被设置和拥有的单个画布上完成。渲染本身使用 Skia 和 GDI 调用的组合完成——GDI 用于文本,Skia 用于其他所有内容。

然而,Chromium UI 中的几个 UI 控件并不使用 Views 渲染。相反,它们是托管在一种特殊的 View 中的原生 Windows 控件,这种 View 知道如何显示和调整原生控件的大小。这些控件用于按钮、表格、单选按钮、复选框、文本字段等。由于它们使用原生控件,因此这些 Views 在移植性方面并不强,除了 API 之外。

除平台特定的渲染代码、基于系统指标调整大小的代码等外,View 系统的其他部分具有较好的可移植性,因为大多数渲染是使用跨平台的 Skia 库完成的。出于历史原因,许多 View 的函数接受 Windows 或 ATL 类型,但我们已经在 ui/gfx/ 中增加了许多平台独立的类型,最终可以替换这些类型。

代码位置和信息

Views 提供的一组基本类和接口可以在 src/ui/views/ 目录中找到。所有基本 Views 类都在 “views” 命名空间中。

常见的 Widgets

在 Views 框架中:

有关使用 Window、CustomFrameWindow 等构建对话框和其他窗口化 UI 的更多信息,请参阅 Views 窗口化内容。

在 Chromium 浏览器前端:

其他方法

在项目开始时,我们开始使用原生窗口和许多 Windows 应用程序中使用的自绘制方法来构建 Chromium 浏览器。这证明是令人不满意的,因为原生窗口不支持透明性,并且处理事件需要繁琐的窗口子类化。某些早期的 UI 元素倾向于自定义绘制和事件处理(例如自动完成),但这通常是基于具体情况的临时做法。

现有的 Windows UI 工具包同样不令人满意,控件集有限,美学效果不自然,或编程模型不便。

限制/问题

总体来说,Views 使构建复杂的自定义 UI 相对容易。然而,它还有一些需要随着时间改善的粗糙边缘: