编程自定义 GUI OPenGL

Programming custom GUI OPenGL

我正在 OpenTK 中创建自己的 GUI。

我想在光标位于某个 GUI 控件中时触发鼠标事件。我怎样才能做到这一点?因为现在我只是遍历主要 class 中的项目列表,而在 Opentk 的 window 的 MouseMove 事件中我只是检查鼠标坐标是否在“区域内” " 我正在绘制的组件。

这暂时可行,但我认为可以用更好的方式完成。这样我的代码是无序的并且在主要 class 中,我宁愿将它放在特定的组件 class.

我想要的是为我的 GUI 的每个组件附加一个事件,这样我就可以为一个组件定义许多事件。

我的意思是,我想要一个按钮组件,我可以在其中覆盖或只使用一个在事件发生时触发的方法。与 OpenGL 的 window 相同,您可以在其中覆盖事件。

这不是一个完整的答案,因为你的问题很宽泛,但希望对你有所帮助。

为了实现这样一个系统,这里是潜在设计的核心组件:

UI 组件: 某种标准接口,不同的组件类型可以在其中定义交互逻辑。根据语言的不同,最常见的方法可能是类似于父 class 组件的方法,其中包含要覆盖的方法。这些可能包括以下内容:

  • 鼠标悬停
  • 鼠标点击(按下/松开)
  • 点击拖动

它可能还需要一些额外的相关信息:

  • 一些确定组件位置的方法。可以提供边界框,或者可以提供一种方法来测试给定点是否在此组件内。
  • 绘制组件的信息或功能。
  • 显示和分层设置(它是可见还是隐藏,应该绘制在其他组件之上还是后面)。

UI 上下文:上下文是定义UI中存在的一组组件的结构。这可能类似于组件的列表结构。为了构建您的 UI,您需要将组件添加到此上下文中。上下文将定义一些行为:

  • 管理组件(添加/删除/修改)。
  • 如何绘制整个上下文(例如,遍历每个组件并为每个组件执行绘制功能)。
  • 事件处理(见下一节)

事件调度:为了使您的 UI 可用,您可以插入一个“适配器”层来处理来自您的 windowing 库的事件(OpenTK ) 然后将它们转换为您的组件可用的事件并分派它们。这是一个示例,说明它如何适用于“点击”事件(伪代码):

function TK_Event_ClickPressed(point) {
    for component in context {
        if component.ContainsPoint(point) {
            component.EventClickPressed()
        }
    }
}

在我看来,这实际上是设计中比较棘手的部分,因为围绕基于组件 UI 的工作方式存在一些棘手的约定。您不一定非要遵循它们,但了解它们很重要,至少因为人们可能希望您的 UI 工作:

  • 点击按下后,点击拖动继续发生,直到点击松开,即使光标离开组件区域。
  • 单击 释放 时发生“操作”。
  • 只有在 同一组件.
  • 上发生相应的点击按下时,点击释放才会生效
  • 如果光标不再在组件内(离开并重新进入),点击释放不采取任何行动不过,发布前的组件仍然执行此操作)。
  • 您一次只能主动单击 一个组件(显示在顶部的那个),即使多个组件在那个位置重叠也是如此。

假设您遵循这些约定,这意味着调度事件实际上比仅检查事件点是否在给定组件中要复杂一些。您需要维护某种状态以跟踪上下文当前是否处于点击状态,以及哪个组件(如果有)正在“消耗”当前点击。即如果发生点击释放和拖动事件应该给哪个组件。


有了这些系统,您只需创建一个 window,创建一个 UI 上下文,将适配器层注册到 window 以作用于该上下文,设置向上 window 在框架上绘制上下文,然后使用上下文添加/删除/修改程序中的组件。