/// <summary> /// Adds object property editor. Selects proper <see cref="CustomEditor"/> based on overrides. /// </summary> /// <param name="label">The property label.</param> /// <param name="values">The values.</param> /// <param name="overrideEditor">The custom editor to use. If null will detect it by auto.</param> /// <param name="tooltip">The property label tooltip text.</param> /// <returns>The created element.</returns> public CustomEditor Property(PropertyNameLabel label, ValueContainer values, CustomEditor overrideEditor = null, string tooltip = null) { var editor = CustomEditorsUtil.CreateEditor(values, overrideEditor); var style = editor.Style; if (style == DisplayStyle.InlineIntoParent) { return(Object(values, editor)); } if (style == DisplayStyle.Group) { var group = Group(label.Text, true); group.Panel.Close(false); return(group.Object(values, editor)); } var property = AddPropertyItem(label, tooltip); return(property.Object(values, editor)); }
public override void Initialize(LayoutElementsContainer layout) { var proxy = (SkeletonPropertiesProxy)Values[0]; if (proxy.Asset == null || !proxy.Asset.IsLoaded) { layout.Label("Loading..."); return; } var lods = proxy.Asset.LODs; var loadedLODs = proxy.Asset.LoadedLODs; var nodes = proxy.Asset.Nodes; var bones = proxy.Asset.Bones; // Skeleton Bones { var group = layout.Group("Skeleton Bones"); var tree = group.Tree(); for (int i = 0; i < bones.Length; i++) { if (bones[i].ParentIndex == -1) { var node = tree.Node(nodes[bones[i].NodeIndex].Name); BuildSkeletonBonesTree(nodes, bones, node, i); node.TreeNode.ExpandAll(true); } } } // Skeleton Nodes { var group = layout.Group("Skeleton Nodes"); var tree = group.Tree(); for (int i = 0; i < nodes.Length; i++) { if (nodes[i].ParentIndex == -1) { var node = tree.Node(nodes[i].Name); BuildSkeletonNodesTree(nodes, node, i); node.TreeNode.ExpandAll(true); } } } // Blend Shapes var blendShapes = proxy.Asset.BlendShapes; if (blendShapes.Length != 0) { var group = layout.Group("Blend Shapes"); proxy.Window._preview.PreviewActor.ClearBlendShapeWeights(); for (int i = 0; i < blendShapes.Length; i++) { var blendShape = blendShapes[i]; var label = new PropertyNameLabel(blendShape); label.SetupContextMenu += (nameLabel, menu, linkedEditor) => { menu.AddButton("Copy name", () => Clipboard.Text = blendShape); }; var property = group.AddPropertyItem(label); var editor = property.FloatValue(); editor.FloatValue.Value = 0.0f; editor.FloatValue.MinValue = -1; editor.FloatValue.MaxValue = 1; editor.FloatValue.SlideSpeed = 0.01f; editor.FloatValue.ValueChanged += () => { proxy.Window._preview.PreviewActor.SetBlendShapeWeight(blendShape, editor.FloatValue.Value); }; } } }
internal void LinkLabel(PropertyNameLabel label) { LinkedLabel = label; }
/// <summary> /// Adds object(s) editor with name label. Selects proper <see cref="CustomEditor"/> based on overrides. /// </summary> /// <param name="label">The property label.</param> /// <param name="values">The values.</param> /// <param name="overrideEditor">The custom editor to use. If null will detect it by auto.</param> /// <param name="tooltip">The property label tooltip text.</param> /// <returns>The created element.</returns> public CustomEditor Object(PropertyNameLabel label, ValueContainer values, CustomEditor overrideEditor = null, string tooltip = null) { var property = AddPropertyItem(label, tooltip); return(property.Object(values, overrideEditor)); }
public override void Initialize(LayoutElementsContainer layout) { var proxy = (PropertiesProxy)Values[0]; proxy._materialSlotComboBoxes.Clear(); proxy._isolateCheckBoxes.Clear(); proxy._highlightCheckBoxes.Clear(); var lods = proxy.Asset.LODs; var loadedLODs = proxy.Asset.LoadedLODs; var nodes = proxy.Asset.Nodes; var bones = proxy.Asset.Bones; // General properties { var group = layout.Group("General"); group.Label("Nodes: " + nodes.Length); group.Label("Bones: " + bones.Length); var minScreenSize = group.FloatValue("Min Screen Size", "The minimum screen size to draw model (the bottom limit). Used to cull small models. Set to 0 to disable this feature."); minScreenSize.FloatValue.MinValue = 0.0f; minScreenSize.FloatValue.MaxValue = 1.0f; minScreenSize.FloatValue.Value = proxy.Asset.MinScreenSize; minScreenSize.FloatValue.ValueChanged += () => { proxy.Asset.MinScreenSize = minScreenSize.FloatValue.Value; proxy.Window.MarkAsEdited(); }; } // Group per LOD for (int lodIndex = 0; lodIndex < lods.Length; lodIndex++) { var group = layout.Group("LOD " + lodIndex); if (lodIndex < lods.Length - loadedLODs) { group.Label("Loading LOD..."); continue; } var lod = lods[lodIndex]; var meshes = lod.Meshes; int triangleCount = 0, vertexCount = 0; for (int meshIndex = 0; meshIndex < meshes.Length; meshIndex++) { var mesh = meshes[meshIndex]; triangleCount += mesh.TriangleCount; vertexCount += mesh.VertexCount; } group.Label(string.Format("Triangles: {0:N0} Vertices: {1:N0}", triangleCount, vertexCount)); group.Label("Size: " + lod.Box.Size); var screenSize = group.FloatValue("Screen Size", "The screen size to switch LODs. Bottom limit of the model screen size to render this LOD."); screenSize.FloatValue.MinValue = 0.0f; screenSize.FloatValue.MaxValue = 10.0f; screenSize.FloatValue.Value = lod.ScreenSize; screenSize.FloatValue.ValueChanged += () => { lod.ScreenSize = screenSize.FloatValue.Value; proxy.Window.MarkAsEdited(); }; // Every mesh properties for (int meshIndex = 0; meshIndex < meshes.Length; meshIndex++) { var mesh = meshes[meshIndex]; group.Label($"Mesh {meshIndex} (tris: {mesh.TriangleCount:N0}, verts: {mesh.VertexCount:N0})"); // Material Slot var materialSlot = group.ComboBox("Material Slot", "Material slot used by this mesh during rendering"); materialSlot.ComboBox.Tag = mesh; materialSlot.ComboBox.SelectedIndexChanged += comboBox => proxy.SetMaterialSlot((SkinnedMesh)comboBox.Tag, comboBox.SelectedIndex); proxy._materialSlotComboBoxes.Add(materialSlot.ComboBox); // Isolate var isolate = group.Checkbox("Isolate", "Shows only this mesh (and meshes using the same material slot)"); isolate.CheckBox.Tag = mesh; isolate.CheckBox.StateChanged += (box) => proxy.SetIsolate(box.Checked ? (SkinnedMesh)box.Tag : null); proxy._isolateCheckBoxes.Add(isolate.CheckBox); // Highlight var highlight = group.Checkbox("Highlight", "Highlights this mesh with a tint color (and meshes using the same material slot)"); highlight.CheckBox.Tag = mesh; highlight.CheckBox.StateChanged += (box) => proxy.SetHighlight(box.Checked ? (SkinnedMesh)box.Tag : null); proxy._highlightCheckBoxes.Add(highlight.CheckBox); } } // Skeleton Bones { var group = layout.Group("Skeleton Bones"); group.Panel.Close(false); var tree = group.Tree(); for (int i = 0; i < bones.Length; i++) { if (bones[i].ParentIndex == -1) { var node = tree.Node(nodes[bones[i].NodeIndex].Name); BuildSkeletonBonesTree(nodes, bones, node, i); node.TreeNode.ExpandAll(true); } } } // Skeleton Nodes { var group = layout.Group("Skeleton Nodes"); group.Panel.Close(false); var tree = group.Tree(); for (int i = 0; i < nodes.Length; i++) { if (nodes[i].ParentIndex == -1) { var node = tree.Node(nodes[i].Name); BuildSkeletonNodesTree(nodes, node, i); node.TreeNode.ExpandAll(true); } } } // Blend Shapes var blendShapes = proxy.Asset.BlendShapes; if (blendShapes.Length != 0) { var group = layout.Group("Blend Shapes"); group.Panel.Close(false); proxy.Window._preview.PreviewActor.ClearBlendShapeWeights(); for (int i = 0; i < blendShapes.Length; i++) { var blendShape = blendShapes[i]; var label = new PropertyNameLabel(blendShape); label.SetupContextMenu += (nameLabel, menu, linkedEditor) => { menu.AddButton("Copy name", () => Clipboard.Text = blendShape); }; var property = group.AddPropertyItem(label); var editor = property.FloatValue(); editor.FloatValue.Value = 0.0f; editor.FloatValue.MinValue = -1; editor.FloatValue.MaxValue = 1; editor.FloatValue.SlideSpeed = 0.01f; editor.FloatValue.ValueChanged += () => { proxy.Window._preview.PreviewActor.SetBlendShapeWeight(blendShape, editor.FloatValue.Value); }; } } // Import Settings { var group = layout.Group("Import Settings"); var importSettingsField = typeof(PropertiesProxy).GetField("ImportSettings", BindingFlags.NonPublic | BindingFlags.Instance); var importSettingsValues = new ValueContainer(importSettingsField) { proxy.ImportSettings }; group.Object(importSettingsValues); layout.Space(5); var reimportButton = group.Button("Reimport"); reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport(); } // Refresh UI proxy.UpdateMaterialSlotsUI(); }