void Traverse(DebugUI.IContainer container, Transform parentTransform, DebugUIHandlerWidget parentUIHandler, ref DebugUIHandlerWidget selectedHandler) { DebugUIHandlerWidget previousUIHandler = null; for (int i = 0; i < container.children.Count; i++) { var child = container.children[i]; if (child.isEditorOnly || child.isHidden) { continue; } Transform prefab; if (!m_PrefabsMap.TryGetValue(child.GetType(), out prefab)) { Debug.LogWarning("DebugUI widget doesn't have a prefab: " + child.GetType()); continue; } var go = Instantiate(prefab, parentTransform, false).gameObject; go.name = child.displayName; var uiHandler = go.GetComponent <DebugUIHandlerWidget>(); if (uiHandler == null) { Debug.LogWarning("DebugUI prefab is missing a DebugUIHandler for: " + child.GetType()); continue; } if (!string.IsNullOrEmpty(m_CurrentQueryPath) && child.queryPath.Equals(m_CurrentQueryPath)) { selectedHandler = uiHandler; } if (previousUIHandler != null) { previousUIHandler.nextUIHandler = uiHandler; } uiHandler.previousUIHandler = previousUIHandler; previousUIHandler = uiHandler; uiHandler.parentUIHandler = parentUIHandler; uiHandler.SetWidget(child); var childContainer = go.GetComponent <DebugUIHandlerContainer>(); if (childContainer != null && child is DebugUI.IContainer childAsContainer) { Traverse(childAsContainer, childContainer.contentHolder, uiHandler, ref selectedHandler); } } }
void UpdateWidgetStates(DebugUI.IContainer container) { // Skip runtime only containers, we won't draw them so no need to serialize them either var actualWidget = container as DebugUI.Widget; if (actualWidget != null && actualWidget.isRuntimeOnly) { return; } // Recursively update widget states foreach (var widget in container.children) { // Skip non-serializable widgets but still traverse them in case one of their // children needs serialization support var valueField = widget as DebugUI.IValueField; if (valueField != null) { // Skip runtime & readonly only items if (widget.isRuntimeOnly) { return; } var widgetType = widget.GetType(); string guid = widget.queryPath; Type stateType; s_WidgetStateMap.TryGetValue(widgetType, out stateType); // Create missing states & recreate the ones that are null if (stateType != null) { if (!m_WidgetStates.ContainsKey(guid) || m_WidgetStates[guid] == null) { var inst = (DebugState)CreateInstance(stateType); inst.queryPath = guid; inst.SetValue(valueField.GetValue(), valueField); m_WidgetStates[guid] = inst; } } } // Recurse if the widget is a container var containerField = widget as DebugUI.IContainer; if (containerField != null) { UpdateWidgetStates(containerField); } } }
void TraverseContainerGUI(DebugUI.IContainer container) { // /!\ SHAAAAAAAME ALERT /!\ // A container can change at runtime because of the way IMGUI works and how we handle // onValueChanged on widget so we have to take this into account while iterating try { foreach (var widget in container.children) { OnWidgetGUI(widget); } } catch (InvalidOperationException) { Repaint(); } }
DebugUI.Widget GetItem(string queryPath, DebugUI.IContainer container) { foreach (var child in container.children) { if (child.queryPath == queryPath) { return(child); } var containerChild = child as DebugUI.IContainer; if (containerChild != null) { var w = GetItem(queryPath, containerChild); if (w != null) { return(w); } } } return(null); }