private void Layout(int index, UIGraphData graph, NativeArray <NodeInfo> configLayout, NativeArray <UIPassState> stateLayout, UIContextData *context) { if (!graph.TryGetConfigBlock(index, UIConfigLayoutTable.DisplayConfig, out IntPtr displayConfig) || (((DisplayConfig *)displayConfig.ToPointer())->display == VisibilityStyle.Visible)) { var nodeInfo = configLayout[index]; var headerConfig = (HeaderConfig *)(graph.value + nodeInfo.nodeOffset).ToPointer(); var configSource = graph.value + nodeInfo.configOffset; var state = (UIPassState *)(((IntPtr)stateLayout.GetUnsafePtr()) + (UnsafeUtility.SizeOf <UIPassState>() * index)).ToPointer(); IntPtr boxConfig; bool hasBoxConfig = graph.TryGetConfigBlock(index, UIConfigLayoutTable.BoxModelConfig, out boxConfig); if (hasBoxConfig) { BoxModelConfig *boxConfigPtr = (BoxModelConfig *)boxConfig.ToPointer(); state->localBox += boxConfigPtr->margin.Normalize(*context); state->inner = boxConfigPtr->padding.Normalize(*context); } FunctionPointer <UILayoutPass> layout = headerConfig->schemaIndex >= 0 ? schema.Value.elements[headerConfig->schemaIndex].layout : default; for (int childIndex = 0; childIndex < headerConfig->childCount; childIndex++) { if (layout.IsCreated) { layout.Invoke( childIndex, graph.value, (NodeInfo *)UnsafeUtility.AddressOf(ref nodeInfo), (IntPtr)stateLayout.GetUnsafePtr(), context ); } Layout(UnsafeUtility.ReadArrayElement <int>((graph.value + nodeInfo.childrenOffset).ToPointer(), childIndex), graph, configLayout, stateLayout, context); } if (layout.IsCreated) { layout.Invoke( -1, graph.value, (NodeInfo *)UnsafeUtility.AddressOf(ref nodeInfo), (IntPtr)stateLayout.GetUnsafePtr(), context ); } if (graph.TryGetConfigBlock(index, UIConfigLayoutTable.SizeConfig, out IntPtr sizeConfig)) { var sizeConfigPtr = ((SizeConfig *)sizeConfig.ToPointer()); state->size = new float2( math.clamp(state->size.x, sizeConfigPtr->minWidth.Normalize(*context), sizeConfigPtr->maxWidth.Normalize(*context)), math.clamp(state->size.y, sizeConfigPtr->minHeight.Normalize(*context), sizeConfigPtr->maxHeight.Normalize(*context))); } if (hasBoxConfig) { state->size += new float2(state->inner.x + state->inner.z, state->inner.y + state->inner.w); } } }
public static int GetFirstSelectableIndex(this UIGraphData graph) { if (!graph.IsCreated) { return(-1); } //Index, priority ValueTuple <int, int> selectableIndex = (-1, int.MinValue); for (int currentIndex = 0; currentIndex < graph.GetNodeCount(); currentIndex++) { if (graph.TryGetConfigBlock(currentIndex, UIConfigLayoutTable.SelectableConfig, out IntPtr block)) { SelectableConfig *selectableConfig = (SelectableConfig *)block; if (selectableConfig->onSelect.IsCreated && selectableIndex.Item2.CompareTo(selectableConfig->priority) < 0) { selectableIndex = (currentIndex, selectableConfig->priority); } } } return(selectableIndex.Item1); }
private void RenderMesh( int startIndex, int parentIndex, int currentIndex, NativeArray <UIVertexData> vertexData, UIContextData *context, NativeArray <ushort> indices, UIGraphData graph, GraphInfo graphInfo, NativeArray <NodeInfo> nodeInfo, NativeArray <UIPassState> stateLayout, NativeArray <SubMeshInfo> subMeshes, bool renderNow, bool updateSubmeshCount, bool accumulate, ref int subMeshIndex, ref int renderIndex, ref float4 bounds ) { var info = nodeInfo[currentIndex]; HeaderConfig *headerConfig = (HeaderConfig *)(graph.value + info.nodeOffset).ToPointer(); var state = stateLayout[currentIndex]; if (accumulate) { state.globalBox += state.localBox; if (parentIndex >= 0) { state.globalBox += stateLayout[parentIndex].inner; } stateLayout[currentIndex] = state; } if (headerConfig->IsDedicatedNode) { if (updateSubmeshCount) { subMeshes[subMeshIndex] = new SubMeshInfo(++subMeshIndex, currentIndex); } renderNow = currentIndex == startIndex; } if (renderNow) { bool display = true; bool visible = true; if (graph.TryGetConfigBlock(currentIndex, UIConfigLayoutTable.DisplayConfig, out IntPtr displayConfig)) { var dc = ((DisplayConfig *)displayConfig.ToPointer()); display = dc->display == VisibilityStyle.Visible; visible = dc->visible == VisibilityStyle.Visible; } if (display) { FunctionPointer <UIRenderPass> render = headerConfig->schemaIndex >= 0 ? schema.Value.elements[headerConfig->schemaIndex].render : default; if (render.IsCreated) { render.Invoke( graph.value, (NodeInfo *)UnsafeUtility.AddressOf(ref info), (UIPassState *)UnsafeUtility.AddressOf(ref state), (UIVertexData *)(((IntPtr)vertexData.GetUnsafePtr()) + (renderIndex * UnsafeUtility.SizeOf <UIVertexData>() * 4)).ToPointer(), context ); } for (int j = 0; j < info.renderBoxCount; j++) { indices[(renderIndex + j) * 6] = (ushort)((renderIndex + j) * 4); indices[((renderIndex + j) * 6) + 1] = (ushort)(((renderIndex + j) * 4) + 2); indices[((renderIndex + j) * 6) + 2] = (ushort)(((renderIndex + j) * 4) + 1); indices[((renderIndex + j) * 6) + 3] = (ushort)(((renderIndex + j) * 4) + 2); indices[((renderIndex + j) * 6) + 4] = (ushort)(((renderIndex + j) * 4) + 3); indices[((renderIndex + j) * 6) + 5] = (ushort)(((renderIndex + j) * 4) + 1); UpdateBounds(vertexData, (renderIndex + j) * 4, ref bounds); } } if (!display || !visible) { UnsafeUtility.MemClear((((IntPtr)vertexData.GetUnsafePtr()) + (renderIndex * UnsafeUtility.SizeOf <UIVertexData>() * 4)).ToPointer(), UnsafeUtility.SizeOf <UIVertexData>() * info.renderBoxCount * 4); UnsafeUtility.MemClear((((IntPtr)indices.GetUnsafePtr()) + (renderIndex * UnsafeUtility.SizeOf <ushort>() * 6)).ToPointer(), UnsafeUtility.SizeOf <ushort>() * info.renderBoxCount * 6); } renderIndex += info.renderBoxCount; } for (int i = 0; i < headerConfig->childCount; i++) { RenderMesh(startIndex, currentIndex, UnsafeUtility.ReadArrayElement <int>((graph.value + info.childrenOffset).ToPointer(), i), vertexData, context, indices, graph, graphInfo, nodeInfo, stateLayout, subMeshes, renderNow, updateSubmeshCount, accumulate, ref subMeshIndex, ref renderIndex, ref bounds); } }