0

我一直在为 IMGUI(旧版和编辑器 GUI 系统)苦苦挣扎。问题是我无法理解这种即时方式和所有不同的事件。

我构建了一个简单的示例来演示我对这个系统的许多挫败感之一。

bool toggleValue;
void OnGUI()
{
    if (toggleValue = GUILayout.Toggle(toggleValue, "Toggle"))
    {
        EditorGUILayout.LabelField("This is a label");
    }
}

好的,所以,在这个非常简单的代码中,我有一个本机切换,根据它的状态显示或不显示标签。这完美地工作。

现在,我正在自己写一篇文章。

bool toggleValue;
void OnGUI()
{
    if (toggleValue = Toggle(toggleValue, "Toggle"))
    {
       EditorGUILayout.LabelField("This is a label");
    }
}

bool Toggle(bool state, string label)
{
    GUILayout.Label(label, state ? EditorStyles.boldLabel : GUIStyle.none);
    if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
        return !state;
    return state;
}

我的目标是手动重现切换的行为:我的可点击标签在活动时为粗体,在禁用时为正常。类似于原生切换的复选框图形。然后,如果我点击它的矩形,我会返回相反的状态。

在我看来,这应该是可行的。但是,我知道 OnGUI 函数会发生很多事情,比如事件Repaint,并且Layout布局需要在帧期间保持一致。这里的错误是

ArgumentException:在执行 MouseDown 时获取控件 1 在只有 1 个控件的组中的位置

但通常也会出现这样的错误

ArgumentException:GUILayout:不匹配的 LayoutGroup.MouseDown

我知道这些错误是在您更改 Layout 和 Repaint 之间的内容时发生的。但是我找不到我的简单控件的修复程序。所以这是我的问题。

使用与我的函数 Toggle 相同的参数,我需要注意什么才能使切换起作用?

我觉得如果我有这个答案,我也许能够理解这个系统的关键。

非常感谢

4

1 回答 1

1

哦,天哪,我简直不敢相信。我唯一缺少的是

Event.current.Use();

单击控件时。就这样!布局和重绘之间的布局没有任何变化或任何类似的事情。

因此,如果您遇到同样的问题,只需在事件成功时使用该事件。

于 2017-11-28T17:00:11.277 回答