首页 > 解决方案 > GUI 在低级别检测哪个元素被点击的常见方法是什么?

问题描述

我一直在尝试到处寻找这个问题,但我发现的一切都与高级别的事情有关,比如“如何知道点击了哪个 HTML”。那不是我要找的东西。我正在寻找更底层的细节。

假设有人试图为给定系统编写 GUI 库。另外,假设这个程序员已经设法在屏幕上显示图形、文本、按钮等。现在他们想要实现用户与该界面交互的方式,更具体地说,使用鼠标点击(或者可能是触摸输入)。

运行他们的 GUI 引擎的系统能够告诉他们点击何时发生,以及点击发生在屏幕上的哪个 (x, y) 点。要查找屏幕上的哪些元素被点击,一种简单的方法是遍历每个元素并测试它们中的每一个。但这是在现有 GUI 中通常如何完成的吗?例如,浏览器在显示 HTML 页面时会这样做吗?这就是操作系统对其 GUI 和窗口所做的事情吗?他们是否使用更复杂的数据结构,如 R-Trees?他们如何处理移动元素?

这个问题不是特定于任何软件的,我只是想知道在 GUI 开发的背景下通常如何解决这个问题。

标签: algorithmuser-interfacedata-structureslanguage-agnostic

解决方案


有2种基本方法。一个你已经想出来的:

  1. 测试“每个”对象与鼠标位置

    这可以通过使用空间细分结构(类似于 2D 中的 BVH 和八叉树)来加速。但是,这种方法总是会比较慢,并且会受到诸如GUI 元素数量之类的复杂O(log(n))性的限制。这是一个天真的例子:O(n)nO(n)

    然而,一旦测试项目数量增加或它们的形状太复杂,这种方法就很麻烦。

  2. 使用索引缓冲区

    这种方法是像素完美的,具有复杂性O(1),并且在大多数实现中也几乎是免费的。

    这个想法是让索引缓冲区与屏幕保存测试元素的 ID(索引)而不是颜色具有相同的分辨率。因此,当您渲染您的 GUI 时,除了使用颜色设置元素的每个像素之外,您还在索引缓冲区中的相同位置设置渲染项目索引或 ID。

    在此之后,检测只是在鼠标位置获取索引缓冲区值。这里举几个例子:

    这种方法也可用于 2D 和投影 3D->2D 甚至更高的维度。


推荐阅读