algorithm - GUI 在低级别检测哪个元素被点击的常见方法是什么?
问题描述
我一直在尝试到处寻找这个问题,但我发现的一切都与高级别的事情有关,比如“如何知道点击了哪个 HTML”。那不是我要找的东西。我正在寻找更底层的细节。
假设有人试图为给定系统编写 GUI 库。另外,假设这个程序员已经设法在屏幕上显示图形、文本、按钮等。现在他们想要实现用户与该界面交互的方式,更具体地说,使用鼠标点击(或者可能是触摸输入)。
运行他们的 GUI 引擎的系统能够告诉他们点击何时发生,以及点击发生在屏幕上的哪个 (x, y) 点。要查找屏幕上的哪些元素被点击,一种简单的方法是遍历每个元素并测试它们中的每一个。但这是在现有 GUI 中通常如何完成的吗?例如,浏览器在显示 HTML 页面时会这样做吗?这就是操作系统对其 GUI 和窗口所做的事情吗?他们是否使用更复杂的数据结构,如 R-Trees?他们如何处理移动元素?
这个问题不是特定于任何软件的,我只是想知道在 GUI 开发的背景下通常如何解决这个问题。
解决方案
有2种基本方法。一个你已经想出来的:
测试“每个”对象与鼠标位置
这可以通过使用空间细分结构(类似于 2D 中的 BVH 和八叉树)来加速。但是,这种方法总是会比较慢,并且会受到诸如GUI 元素数量之类的复杂
O(log(n))
性的限制。这是一个天真的例子:O(n)
n
O(n)
然而,一旦测试项目数量增加或它们的形状太复杂,这种方法就很麻烦。
使用索引缓冲区
这种方法是像素完美的,具有复杂性
O(1)
,并且在大多数实现中也几乎是免费的。这个想法是让索引缓冲区与屏幕保存测试元素的 ID(索引)而不是颜色具有相同的分辨率。因此,当您渲染您的 GUI 时,除了使用颜色设置元素的每个像素之外,您还在索引缓冲区中的相同位置设置渲染项目索引或 ID。
在此之后,检测只是在鼠标位置获取索引缓冲区值。这里举几个例子:
这种方法也可用于 2D 和投影 3D->2D 甚至更高的维度。
推荐阅读
- flutter - Flutter 照片管理的最佳方式
- react-navigation - React Native Stack Navigator 传递道具
- django - 在 django 测试中过滤警告
- jenkins-pipeline - 将 salt minion id 从平面文件传递给 Jenkins 管道
- python - 当使用python使用下拉菜单时,如何在excel中更改整个行的颜色
- excel - 根据标题值复制/粘贴单元格
- python - 将实时条形图与折线图一起绘制
- rest - Coldfusion 11 - 添加 Rest API 服务主机问题
- postgresql - 更改列会锁定 postgresql 中的表吗?
- oracle - 在 oracle 钱包中指定证书和密钥