public override void Flatten(UndoBuffer undoBuffer) { if (Mesh == null) { Remove(undoBuffer); } else { // only keep the mesh and get rid of everything else using (RebuildLock()) { var meshOnlyItem = new Object3D() { Mesh = this.Mesh.Copy(CancellationToken.None) }; meshOnlyItem.CopyProperties(this, Object3DPropertyFlags.All); // and replace us with the children undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { meshOnlyItem })); } Invalidate(InvalidateType.Children); } }
public static void FlattenToPathObject(this IObject3D item, UndoBuffer undoBuffer) { if (item is IPathObject pathObject) { using (item.RebuildLock()) { var newPathObject = new PathObject3D(); newPathObject.VertexSource = new VertexStorage(pathObject.VertexSource); // and replace us with the children var replaceCommand = new ReplaceCommand(new[] { item }, new[] { newPathObject }); if (undoBuffer != null) { undoBuffer.AddAndDo(replaceCommand); } else { replaceCommand.Do(); } newPathObject.MakeNameNonColliding(); } } }
public override void Remove(UndoBuffer undoBuffer) { // Custom remove for ImageConverter if (this.ComponentID == imageConverterComponentID) { var parent = this.Parent; using (RebuildLock()) { if (this.Descendants <ImageObject3D>().FirstOrDefault() is ImageObject3D imageObject3D) { imageObject3D.Matrix = this.Matrix; if (undoBuffer != null) { undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { imageObject3D })); } else { parent.Children.Modify(list => { list.Remove(this); list.Add(imageObject3D); }); } } } parent.Invalidate(new InvalidateArgs(this, InvalidateType.Children)); } else { base.Remove(undoBuffer); } }
public override void Flatten(UndoBuffer undoBuffer) { // change this from a text object to a group var newContainer = new GroupObject3D(); newContainer.CopyProperties(this, Object3DPropertyFlags.All); foreach (var child in this.Children) { newContainer.Children.Add(child.Clone()); } undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { newContainer })); }
public virtual void WrapItems(IEnumerable <IObject3D> items, UndoBuffer undoBuffer = null) { var parent = items.First().Parent; RebuildLocks parentLock = (parent == null) ? null : parent.RebuilLockAll(); var firstChild = new Object3D(); this.Children.Add(firstChild); // if the items we are replacing are already in a list if (parent != null) { if (undoBuffer != null) { foreach (var item in items) { firstChild.Children.Add(item.Clone()); } var replace = new ReplaceCommand(items, new[] { this }); undoBuffer.AddAndDo(replace); } else { parent.Children.Modify(list => { foreach (var item in items) { list.Remove(item); firstChild.Children.Add(item); } list.Add(this); }); } } else // just add them { firstChild.Children.Modify(list => { list.AddRange(items); }); } parentLock?.Dispose(); parent?.Invalidate(new InvalidateArgs(parent, InvalidateType.Children)); }
public override void Flatten(UndoBuffer undoBuffer) { // we want to end up with just a group of all the visible mesh objects using (RebuildLock()) { var newChildren = new List <IObject3D>(); // push our matrix into a copy of our visible children foreach (var child in this.VisibleMeshes()) { var meshOnlyItem = new Object3D { Matrix = child.WorldMatrix(this), Color = child.WorldColor(this), MaterialIndex = child.WorldMaterialIndex(this), OutputType = child.WorldOutputType(this), Mesh = child.Mesh, Name = "Mesh".Localize() }; newChildren.Add(meshOnlyItem); } if (newChildren.Count > 1) { var group = new GroupObject3D { Name = this.Name }; group.Children.Modify(list => { list.AddRange(newChildren); }); newChildren.Clear(); newChildren.Add(group); } else if (newChildren.Count == 1) { newChildren[0].Name = this.Name; } // and replace us with the children undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, newChildren)); } Invalidate(InvalidateType.Children); }
public override void Flatten(UndoBuffer undoBuffer) { // change this from a text object to a group var newContainer = new GroupObject3D(); newContainer.CopyProperties(this, Object3DPropertyFlags.All); int index = 0; foreach (var child in this.Children) { var clone = child.Clone(); var newName = index < NameToWrite.Length ? NameToWrite[index++].ToString() : "Letter".Localize(); clone.Name = MapIfSymbol(newName); newContainer.Children.Add(clone); } undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { newContainer })); newContainer.Name = this.Name + " - " + "Flattened".Localize(); }
public void SetWidthDepthUndo(IObject3D selectedItem, UndoBuffer undoBuffer, Vector2 doWidthDepth, Matrix4X4 doMatrix, Vector2 undoWidthDepth, Matrix4X4 undoMatrix) { undoBuffer.AddAndDo(new UndoRedoActions(async() => { setWidth(undoWidthDepth.X); setDepth(undoWidthDepth.Y); await selectedItem.Rebuild(); selectedItem.Matrix = undoMatrix; selectedItem?.Invalidate(new InvalidateArgs(selectedItem, InvalidateType.DisplayValues)); }, async() => { setWidth(doWidthDepth.X); setDepth(doWidthDepth.Y); await selectedItem.Rebuild(); selectedItem.Matrix = doMatrix; selectedItem?.Invalidate(new InvalidateArgs(selectedItem, InvalidateType.DisplayValues)); })); }
public override void Remove(UndoBuffer undoBuffer) { using (RebuildLock()) { List <IObject3D> newChildren = new List <IObject3D>(); // push our matrix into a copy of our children foreach (var child in this.SourceContainer.Children) { var newChild = child.Clone(); newChildren.Add(newChild); newChild.Matrix *= this.Matrix; var flags = Object3DPropertyFlags.Visible; if (this.Color.alpha != 0) { flags |= Object3DPropertyFlags.Color; } if (this.OutputType != PrintOutputTypes.Default) { flags |= Object3DPropertyFlags.OutputType; } if (this.MaterialIndex != -1) { flags |= Object3DPropertyFlags.MaterialIndex; } newChild.CopyProperties(this, flags); } // and replace us with the children var replaceCommand = new ReplaceCommand(new[] { this }, newChildren, false); if (undoBuffer != null) { undoBuffer.AddAndDo(replaceCommand); } else { replaceCommand.Do(); } } Invalidate(InvalidateType.Children); }
public override void Remove(UndoBuffer undoBuffer) { using (RebuildLock()) { var thisClone = this.Clone(); using (thisClone.RebuildLock()) { // remove all the mesh wrappers that we own var meshWrappers = thisClone.Descendants().Where(o => o.OwnerID == thisClone.ID).ToArray(); foreach (var meshWrapper in meshWrappers) { meshWrapper.Remove(null); } foreach (var child in thisClone.Children) { child.OutputType = PrintOutputTypes.Default; // push our matrix into a copy of our children (so they don't jump away) using (child.RebuildLock()) { child.Matrix *= thisClone.Matrix; } } // collapse our children into our parent // and replace us with the children var replaceCommand = new ReplaceCommand(new[] { this }, thisClone.Children.ToList(), false); if (undoBuffer != null) { undoBuffer.AddAndDo(replaceCommand); } else { replaceCommand.Do(); } } } Invalidate(InvalidateType.Children); }
public override void Apply(UndoBuffer undoBuffer) { // only keep the mesh and get rid of everything else using (RebuildLock()) { var meshOnlyItem = new Object3D() { Mesh = this.Mesh.Copy(CancellationToken.None) }; meshOnlyItem.CopyProperties(this, Object3DPropertyFlags.All); // and replace us with the children undoBuffer.AddAndDo(new ReplaceCommand(new List <IObject3D> { this }, new List <IObject3D> { meshOnlyItem })); } Invalidate(new InvalidateArgs(this, InvalidateType.Content)); }
public static GuiWidget CreatePropertyEditor(EditableProperty property, UndoBuffer undoBuffer, PPEContext context, ThemeConfig theme) { var object3D = property.Item; var propertyGridModifier = property.Item as IPropertyGridModifier; GuiWidget rowContainer = null; // Get reflected property value once, then test for each case below var propertyValue = property.Value; void RegisterValueChanged(UIField field, Func <string, object> valueFromString, Func <object, string> valueToString = null) { field.ValueChanged += (s, e) => { var newValue = field.Value; var oldValue = property.Value.ToString(); if (valueToString != null) { oldValue = valueToString(property.Value); } // field.Content if (undoBuffer != null) { undoBuffer.AddAndDo(new UndoRedoActions(() => { property.SetValue(valueFromString(oldValue)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }, () => { property.SetValue(valueFromString(newValue)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); })); } else { property.SetValue(valueFromString(newValue)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); } }; } var readOnly = property.PropertyInfo.GetCustomAttributes(true).OfType <ReadOnlyAttribute>().FirstOrDefault() != null; // create a double editor if (propertyValue is double doubleValue) { if (readOnly) { var valueField = new TextWidget(string.Format("{0:n}", doubleValue), textColor: theme.TextColor, pointSize: 10) { AutoExpandBoundsToText = true }; rowContainer = new SettingsRow(property.DisplayName.Localize(), property.Description, valueField, theme); void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues)) { double newValue = (double)property.Value; valueField.Text = string.Format("{0:n}", newValue); } } object3D.Invalidated += RefreshField; valueField.Closed += (s, e) => object3D.Invalidated -= RefreshField; } else // normal edit row { var field = new DoubleField(theme); field.Initialize(0); field.DoubleValue = doubleValue; field.ClearUndoHistory(); RegisterValueChanged(field, (valueString) => { return(double.Parse(valueString)); }); void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues)) { double newValue = (double)property.Value; if (newValue != field.DoubleValue) { field.DoubleValue = newValue; } } } object3D.Invalidated += RefreshField; field.Content.Descendants <InternalTextEditWidget>().First().Name = property.DisplayName + " Edit"; field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; rowContainer = CreateSettingsRow(property, field, theme); } } else if (propertyValue is Color color) { var field = new ColorField(theme, object3D.Color); field.Initialize(0); field.ValueChanged += (s, e) => { property.SetValue(field.Color); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field, theme); } else if (propertyValue is Vector2 vector2) { var field = new Vector2Field(theme); field.Initialize(0); field.Vector2 = vector2; field.ClearUndoHistory(); RegisterValueChanged(field, (valueString) => Vector2.Parse(valueString), (value) => { var s = ((Vector2)value).ToString(); return(s.Substring(1, s.Length - 2)); }); rowContainer = CreateSettingsColumn(property, field); } else if (propertyValue is Vector3 vector3) { var field = new Vector3Field(theme); field.Initialize(0); field.Vector3 = vector3; field.ClearUndoHistory(); RegisterValueChanged( field, (valueString) => Vector3.Parse(valueString), (value) => { var s = ((Vector3)value).ToString(); return(s.Substring(1, s.Length - 2)); }); rowContainer = CreateSettingsColumn(property, field); } else if (propertyValue is DirectionVector directionVector) { var field = new DirectionVectorField(theme); field.Initialize(0); field.SetValue(directionVector); field.ClearUndoHistory(); field.ValueChanged += (s, e) => { property.SetValue(field.DirectionVector); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field, theme); } else if (propertyValue is DirectionAxis directionAxis) { rowContainer = CreateSettingsColumn(property); var field1 = new DirectionVectorField(theme); field1.Initialize(0); field1.ClearUndoHistory(); field1.SetValue(new DirectionVector() { Normal = directionAxis.Normal }); rowContainer.AddChild(new SettingsRow("Axis".Localize(), null, field1.Content, theme)); // the direction axis // the distance from the center of the part // create a double editor var field2 = new Vector3Field(theme); field2.Initialize(0); field2.Vector3 = directionAxis.Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center; field2.ClearUndoHistory(); var row2 = CreateSettingsColumn("Offset".Localize(), field2); // update this when changed void UpdateData(object s, InvalidateArgs e) { field2.Vector3 = ((DirectionAxis)property.Value).Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center; } property.Item.Invalidated += UpdateData; field2.Content.Closed += (s, e) => { property.Item.Invalidated -= UpdateData; }; // update functions field1.ValueChanged += (s, e) => { property.SetValue(new DirectionAxis() { Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; field2.ValueChanged += (s, e) => { property.SetValue(new DirectionAxis() { Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer.AddChild(row2); } else if (propertyValue is SelectedChildren childSelector) { var showAsList = property.PropertyInfo.GetCustomAttributes(true).OfType <ShowAsListAttribute>().FirstOrDefault() != null; if (showAsList) { UIField field = new ChildrenSelectorListField(property, theme); field.Initialize(0); RegisterValueChanged(field, (valueString) => { var childrenSelector = new SelectedChildren(); foreach (var child in valueString.Split(',')) { childrenSelector.Add(child); } return(childrenSelector); }); rowContainer = CreateSettingsRow(property, field, theme); } else // show the subtract editor for boolean subtract and subtract and replace { rowContainer = CreateSettingsColumn(property); if (property.Item is OperationSourceContainerObject3D sourceContainer) { Action selected = null; if (!(context.item.GetType().GetCustomAttributes(typeof(ShowUpdateButtonAttribute), true).FirstOrDefault() is ShowUpdateButtonAttribute showUpdate)) { selected = () => { object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); }; } rowContainer.AddChild(CreateSourceChildSelector(childSelector, sourceContainer, theme, selected)); } else { rowContainer.AddChild(CreateSelector(childSelector, property.Item, theme)); } } } else if (propertyValue is ImageBuffer imageBuffer) { rowContainer = CreateSettingsColumn(property); rowContainer.AddChild(new ImageWidget(imageBuffer) { HAnchor = HAnchor.Left, Margin = new BorderDouble(0, 3) }); } #if !__ANDROID__ else if (propertyValue is List <string> stringList) { var field = new SurfacedEditorsField(theme, property.Item); field.Initialize(0); field.ListValue = stringList; field.ValueChanged += (s, e) => { property.SetValue(field.ListValue); }; rowContainer = CreateSettingsColumn(property, field); rowContainer.Descendants <HorizontalSpacer>().FirstOrDefault()?.Close(); } #endif // create a int editor else if (propertyValue is int intValue) { if (readOnly) { var valueField = new TextWidget(string.Format("{0:n0}", intValue), textColor: theme.TextColor, pointSize: 10) { AutoExpandBoundsToText = true }; rowContainer = new SettingsRow(property.DisplayName.Localize(), property.Description, valueField, theme); void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues)) { int newValue = (int)property.Value; valueField.Text = string.Format("{0:n0}", newValue); } } object3D.Invalidated += RefreshField; valueField.Closed += (s, e) => object3D.Invalidated -= RefreshField; } else // normal edit row { var field = new IntField(theme); field.Initialize(0); field.IntValue = intValue; field.ClearUndoHistory(); RegisterValueChanged(field, (valueString) => { return(int.Parse(valueString)); }); void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues)) { int newValue = (int)property.Value; if (newValue != field.IntValue) { field.IntValue = newValue; } } } object3D.Invalidated += RefreshField; field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; rowContainer = CreateSettingsRow(property, field, theme); } } else if (propertyValue is bool boolValue) { // create a bool editor var field = new ToggleboxField(theme); field.Initialize(0); field.Checked = boolValue; RegisterValueChanged(field, (valueString) => { return(valueString == "1"); }, (value) => { return(((bool)value) ? "1" : "0"); }); rowContainer = CreateSettingsRow(property, field, theme); } else if (propertyValue is string stringValue) { if (readOnly) { rowContainer = new WrappedTextWidget(stringValue, textColor: theme.TextColor, pointSize: 10) { Margin = 5 }; } else // normal edit row { var multiLineEditAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType <MultiLineEditAttribute>().FirstOrDefault(); if (multiLineEditAttribute != null) { // create a a multi-line string editor var field = new MultilineStringField(theme); field.Initialize(0); field.SetValue(stringValue, false); field.ClearUndoHistory(); field.Content.HAnchor = HAnchor.Stretch; // field.Content.MinimumSize = new Vector2(0, 200 * GuiWidget.DeviceScale); RegisterValueChanged(field, (valueString) => valueString); rowContainer = CreateSettingsColumn(property, field, fullWidth: true); } else { // create a string editor var field = new TextField(theme); field.Initialize(0); field.SetValue(stringValue, false); field.ClearUndoHistory(); field.Content.HAnchor = HAnchor.Stretch; RegisterValueChanged(field, (valueString) => valueString); rowContainer = CreateSettingsRow(property, field, theme); var label = rowContainer.Children.First(); var spacer = rowContainer.Children.OfType <HorizontalSpacer>().FirstOrDefault(); spacer.HAnchor = HAnchor.Absolute; spacer.Width = Math.Max(0, 100 - label.Width); } } } else if (propertyValue is char charValue) { // create a char editor var field = new CharField(theme); field.Initialize(0); field.SetValue(charValue.ToString(), false); field.ClearUndoHistory(); field.ValueChanged += (s, e) => { property.SetValue(Convert.ToChar(field.Value)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field, theme); } else if (property.PropertyType.IsEnum) { // create an enum editor UIField field; var enumDisplayAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType <EnumDisplayAttribute>().FirstOrDefault(); var addToSettingsRow = true; if (enumDisplayAttribute != null) { field = new EnumDisplayField(property, enumDisplayAttribute, theme) { InitialValue = propertyValue.ToString(), }; if (enumDisplayAttribute.Mode == EnumDisplayAttribute.PresentationMode.Tabs) { addToSettingsRow = false; } } else { if (property.PropertyType == typeof(NamedTypeFace)) { field = new FontSelectorField(property, theme); } else { field = new EnumField(property, theme); } } field.Initialize(0); RegisterValueChanged(field, (valueString) => { return(Enum.Parse(property.PropertyType, valueString)); }); field.ValueChanged += (s, e) => { if (property.Value.ToString() != field.Value) { property.SetValue(Enum.Parse(property.PropertyType, field.Value)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); } }; if (addToSettingsRow) { rowContainer = CreateSettingsRow(property, field, theme); } else { // field.Content.Margin = new BorderDouble(3, 0); field.Content.HAnchor = HAnchor.Stretch; rowContainer = field.Content; } } else if (propertyValue is IObject3D item && ApplicationController.Instance.Extensions.GetEditorsForType(property.PropertyType)?.FirstOrDefault() is IObject3DEditor iObject3DEditor) { // Use known IObject3D editors rowContainer = iObject3DEditor.Create(item, undoBuffer, theme); } // remember the row name and widget context.editRows.Add(property.PropertyInfo.Name, rowContainer); return(rowContainer); }
public override void Flatten(UndoBuffer undoBuffer) { using (RebuildLock()) { List <IObject3D> newChildren = new List <IObject3D>(); // push our matrix into a copy of our children foreach (var child in this.Children) { if (!(child is OperationSourceObject3D)) { var newChild = child.Clone(); newChildren.Add(newChild); newChild.Matrix *= this.Matrix; var flags = Object3DPropertyFlags.Visible; if (this.Color.alpha != 0) { flags |= Object3DPropertyFlags.Color; } if (this.OutputType != PrintOutputTypes.Default) { flags |= Object3DPropertyFlags.OutputType; } if (this.MaterialIndex != -1) { flags |= Object3DPropertyFlags.MaterialIndex; } newChild.CopyProperties(this, flags); } } if (newChildren.Count > 1) { // wrap the children in an object so they remain a group var group = new Object3D(); group.Children.Modify((groupList) => { groupList.AddRange(newChildren); }); newChildren.Clear(); newChildren.Add(group); } if (newChildren.Count == 0) { newChildren = this.Children.Select(i => i.Clone()).ToList(); } // add flatten to the name to show what happened newChildren[0].Name = this.Name + " - " + "Flattened".Localize(); // and replace us with the children var replaceCommand = new ReplaceCommand(new[] { this }, newChildren); if (undoBuffer != null) { undoBuffer.AddAndDo(replaceCommand); } else { replaceCommand.Do(); } foreach (var child in newChildren[0].DescendantsAndSelf()) { child.MakeNameNonColliding(); } } Invalidate(InvalidateType.Children); }
public static GuiWidget CreatePropertyEditor(EditableProperty property, UndoBuffer undoBuffer, PPEContext context, ThemeConfig theme) { var object3D = property.Item; var propertyGridModifier = property.Item as IPropertyGridModifier; GuiWidget rowContainer = null; // Get reflected property value once, then test for each case below var propertyValue = property.Value; // create a double editor if (propertyValue is double doubleValue) { var field = new DoubleField(); field.Initialize(0); field.DoubleValue = doubleValue; field.ValueChanged += (s, e) => { undoBuffer.AddAndDo(new UndoRedoDoubleField(field.DoubleValue, property, object3D, context, undoBuffer)); }; void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType == InvalidateType.Properties) { double newValue = (double)property.Value; if (newValue != field.DoubleValue) { field.DoubleValue = newValue; } } } object3D.Invalidated += RefreshField; field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; rowContainer = CreateSettingsRow(property, field); } else if (propertyValue is Color color) { var field = new ColorField(theme, object3D.Color); field.Initialize(0); field.ValueChanged += (s, e) => { property.SetValue(field.Color); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } else if (propertyValue is Vector2 vector2) { var field = new Vector2Field(); field.Initialize(0); field.Vector2 = vector2; field.ValueChanged += (s, e) => { property.SetValue(field.Vector2); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsColumn(property, field); } else if (propertyValue is Vector3 vector3) { var field = new Vector3Field(); field.Initialize(0); field.Vector3 = vector3; field.ValueChanged += (s, e) => { property.SetValue(field.Vector3); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsColumn(property, field); } else if (propertyValue is DirectionVector directionVector) { var field = new DirectionVectorField(theme); field.Initialize(0); field.SetValue(directionVector); field.ValueChanged += (s, e) => { property.SetValue(field.DirectionVector); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } else if (propertyValue is DirectionAxis directionAxis) { rowContainer = CreateSettingsColumn(property); var newDirectionVector = new DirectionVector() { Normal = directionAxis.Normal }; var row1 = CreateSettingsRow("Axis".Localize()); var field1 = new DirectionVectorField(theme); field1.Initialize(0); field1.SetValue(newDirectionVector); row1.AddChild(field1.Content); rowContainer.AddChild(row1); // the direction axis // the distance from the center of the part // create a double editor var field2 = new Vector3Field(); field2.Initialize(0); field2.Vector3 = directionAxis.Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center; var row2 = CreateSettingsColumn("Offset", field2); // update this when changed EventHandler <InvalidateArgs> updateData = (s, e) => { field2.Vector3 = ((DirectionAxis)property.Value).Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center; }; property.Item.Invalidated += updateData; field2.Content.Closed += (s, e) => { property.Item.Invalidated -= updateData; }; // update functions field1.ValueChanged += (s, e) => { property.SetValue(new DirectionAxis() { Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; field2.ValueChanged += (s, e) => { property.SetValue(new DirectionAxis() { Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer.AddChild(row2); } else if (propertyValue is ChildrenSelector childSelector) { var showAsList = property.PropertyInfo.GetCustomAttributes(true).OfType <ShowAsListAttribute>().FirstOrDefault() != null; if (showAsList) { UIField field = new ChildrenSelectorListField(property, theme); field.Initialize(0); field.ValueChanged += (s, e) => { property.SetValue(new ChildrenSelector() { field.Value }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } else // show the subtarct editor for boolean subtract and subtract and replace { rowContainer = CreateSettingsColumn(property); rowContainer.AddChild(CreateSelector(childSelector, property.Item, theme)); } } else if (propertyValue is ImageBuffer imageBuffer) { rowContainer = CreateSettingsColumn(property); rowContainer.AddChild(CreateImageDisplay(imageBuffer, property.Item, theme)); } #if !__ANDROID__ else if (propertyValue is List <string> stringList) { var selectedItem = ApplicationController.Instance.DragDropData.SceneContext.Scene.SelectedItem; var field = new SurfacedEditorsField(theme, selectedItem); field.Initialize(0); field.ListValue = stringList; field.ValueChanged += (s, e) => { property.SetValue(field.ListValue); }; rowContainer = CreateSettingsColumn(property, field); rowContainer.Descendants <HorizontalSpacer>().FirstOrDefault()?.Close(); } #endif // create a int editor else if (propertyValue is int intValue) { var field = new IntField(); field.Initialize(0); field.IntValue = intValue; field.ValueChanged += (s, e) => { undoBuffer.AddAndDo(new UndoRedoIntField(field.IntValue, property, object3D, context, undoBuffer)); }; void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType == InvalidateType.Properties) { int newValue = (int)property.Value; if (newValue != field.IntValue) { field.IntValue = newValue; } } } object3D.Invalidated += RefreshField; field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; rowContainer = CreateSettingsRow(property, field); } // create a bool editor else if (propertyValue is bool boolValue) { var field = new ToggleboxField(theme); field.Initialize(0); field.Checked = boolValue; field.ValueChanged += (s, e) => { property.SetValue(field.Checked); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } // create a string editor else if (propertyValue is string stringValue) { var field = new TextField(); field.Initialize(0); field.SetValue(stringValue, false); field.Content.HAnchor = HAnchor.Stretch; field.ValueChanged += (s, e) => { property.SetValue(field.Value); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); var label = rowContainer.Children.First(); if (field is TextField) { var spacer = rowContainer.Children.OfType <HorizontalSpacer>().FirstOrDefault(); spacer.HAnchor = HAnchor.Absolute; spacer.Width = Math.Max(0, 100 - label.Width); } } // create a char editor else if (propertyValue is char charValue) { var field = new CharField(); field.Initialize(0); field.SetValue(charValue.ToString(), false); field.ValueChanged += (s, e) => { property.SetValue(Convert.ToChar(field.Value)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } // create an enum editor else if (property.PropertyType.IsEnum) { UIField field; var iconsAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType <IconsAttribute>().FirstOrDefault(); if (iconsAttribute != null) { field = new IconEnumField(property, iconsAttribute, theme) { InitialValue = propertyValue.ToString() }; } else { field = new EnumField(property, theme); } field.Initialize(0); field.ValueChanged += (s, e) => { property.SetValue(Enum.Parse(property.PropertyType, field.Value)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } // Use known IObject3D editors else if (propertyValue is IObject3D item && ApplicationController.Instance.GetEditorsForType(property.PropertyType)?.FirstOrDefault() is IObject3DEditor iObject3DEditor) { rowContainer = iObject3DEditor.Create(item, theme); } // remember the row name and widget context.editRows.Add(property.PropertyInfo.Name, rowContainer); return(rowContainer); }
public override void Flatten(UndoBuffer undoBuffer) { using (RebuildLock()) { var thisCopy = this.Clone(); using (thisCopy.RebuilLockAll()) { var ownedMeshWrappers = thisCopy.Descendants().Where(o => o.OwnerID == thisCopy.ID).ToList(); var newMeshObjects = new List <IObject3D>(); // remove all the meshWrappers (collapse the children) foreach (var ownedMeshWrapper in ownedMeshWrappers) { var wrapperParent = ownedMeshWrapper.Parent; if (ownedMeshWrapper.Visible) { var newMesh = new Object3D() { Mesh = ownedMeshWrapper.Mesh.Copy(CancellationToken.None) }; newMesh.CopyProperties(ownedMeshWrapper, Object3DPropertyFlags.All); // move the mesh to the actual new position var matrix = ownedMeshWrapper.WorldMatrix(thisCopy); newMesh.Mesh.Transform(matrix); // then set the matrix to identity newMesh.Matrix = Matrix4X4.Identity; newMesh.Name = thisCopy.Name; newMeshObjects.Add(newMesh); } // remove it wrapperParent.Children.Remove(ownedMeshWrapper); } thisCopy.Matrix = Matrix4X4.Identity; thisCopy.Children.Modify(children => { children.Clear(); children.AddRange(newMeshObjects); foreach (var child in children) { child.MakeNameNonColliding(); } }); List <IObject3D> newChildren = new List <IObject3D>(); // push our matrix into a copy of our children foreach (var child in thisCopy.Children) { var newChild = child.Clone(); newChildren.Add(newChild); newChild.Matrix *= thisCopy.Matrix; var flags = Object3DPropertyFlags.Visible; if (thisCopy.Color.alpha != 0) { flags |= Object3DPropertyFlags.Color; } if (thisCopy.OutputType != PrintOutputTypes.Default) { flags |= Object3DPropertyFlags.OutputType; } if (thisCopy.MaterialIndex != -1) { flags |= Object3DPropertyFlags.MaterialIndex; } newChild.CopyProperties(thisCopy, flags); } // and replace us with the children var replaceCommand = new ReplaceCommand(new List <IObject3D> { this }, newChildren, false); if (undoBuffer != null) { undoBuffer.AddAndDo(replaceCommand); } else { replaceCommand.Do(); } } } Invalidate(InvalidateType.Children); }
public override void Remove(UndoBuffer undoBuffer) { // Custom remove for ImageConverter if (this.ComponentID == ImageConverterComponentID) { var parent = this.Parent; using (RebuildLock()) { if (this.Descendants <ImageObject3D>().FirstOrDefault() is ImageObject3D imageObject3D) { imageObject3D.Matrix = this.Matrix; if (undoBuffer != null) { undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { imageObject3D })); } else { parent.Children.Modify(list => { list.Remove(this); list.Add(imageObject3D); }); } } } parent.Invalidate(new InvalidateArgs(this, InvalidateType.Children)); } else { if (ProOnly) { // just delete it var parent = this.Parent; using (RebuildLock()) { if (undoBuffer != null) { // and replace us with nothing undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new List <IObject3D>(), false)); } else { parent.Children.Modify(list => { list.Remove(this); }); } } parent.Invalidate(new InvalidateArgs(this, InvalidateType.Children)); } else { // remove the component and leave the inside parts base.Remove(undoBuffer); } } }