Ejemplo n.º 1
0
        public DoubleField AddDoubleField(string labelText, int doubleFieldHeight = -1)
        {
            var label = AddLabel(labelText);

            var doubleField = new DoubleField();

            doubleField.Initialize();
            container.AddDrawBox(doubleField);
            if (doubleFieldHeight == -1)
            {
                doubleField.Height = doubleField.Font.CharHeight + 4;
            }
            else
            {
                doubleField.Height = doubleFieldHeight;
            }
            Push.ToTheRightSideOf(doubleField, label, HorizontalMargin, Push.HorizontalAlign.Top);

            doubleField.Width = FieldWidth - doubleField.X;

            AddNewFieldList();
            lastField.Add(label);
            lastField.Add(doubleField);

            alignments.Add(doubleField, new DrawBoxAlignment(AlignTop, AlignBottom, true, true));

            return(doubleField);
        }
        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) =>
                {
                    property.SetValue(field.DoubleValue);
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };

                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 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) =>
                {
                    property.SetValue(field.IntValue);
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };

                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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        public GenerateSupportPanel(ThemeConfig theme, InteractiveScene scene, double minimumSupportHeight)
            : base(FlowDirection.TopToBottom)
        {
            supportGenerator = new SupportGenerator(scene, minimumSupportHeight);

            this.VAnchor         = VAnchor.Fit;
            this.HAnchor         = HAnchor.Absolute;
            this.Width           = 300 * GuiWidget.DeviceScale;
            this.BackgroundColor = theme.BackgroundColor;
            this.Padding         = theme.DefaultContainerPadding;

            // Add an editor field for the SupportGenerator.SupportType
            PropertyInfo propertyInfo = typeof(SupportGenerator).GetProperty(nameof(SupportGenerator.SupportType));

            var editor = PublicPropertyEditor.CreatePropertyEditor(
                new EditableProperty(propertyInfo, supportGenerator),
                null,
                new PPEContext(),
                theme);

            if (editor != null)
            {
                this.AddChild(editor);
            }

            // put in support pillar size
            var pillarSizeField = new DoubleField(theme);

            pillarSizeField.Initialize(0);
            pillarSizeField.DoubleValue   = supportGenerator.PillarSize;
            pillarSizeField.ValueChanged += (s, e) =>
            {
                supportGenerator.PillarSize = pillarSizeField.DoubleValue;
                // in case it was corrected set it back again
                if (pillarSizeField.DoubleValue != supportGenerator.PillarSize)
                {
                    pillarSizeField.DoubleValue = supportGenerator.PillarSize;
                }
            };

            // pillar rows
            this.AddChild(
                new SettingsRow(
                    "Pillar Size".Localize(),
                    "The width and depth of the support pillars".Localize(),
                    pillarSizeField.Content,
                    theme));

            // put in the angle setting
            var overHangField = new DoubleField(theme);

            overHangField.Initialize(0);
            overHangField.DoubleValue   = supportGenerator.MaxOverHangAngle;
            overHangField.ValueChanged += (s, e) =>
            {
                supportGenerator.MaxOverHangAngle = overHangField.DoubleValue;
                // in case it was corrected set it back again
                if (overHangField.DoubleValue != supportGenerator.MaxOverHangAngle)
                {
                    overHangField.DoubleValue = supportGenerator.MaxOverHangAngle;
                }
            };

            // overhang row
            this.AddChild(
                new SettingsRow(
                    "Overhang Angle".Localize(),
                    "The angle to generate support for".Localize(),
                    overHangField.Content,
                    theme));

            // Button Row
            var buttonRow = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Margin  = new BorderDouble(top: 5)
            };

            this.AddChild(buttonRow);

            buttonRow.AddChild(new HorizontalSpacer());

            // add 'Remove Auto Supports' button
            var removeButton = theme.CreateDialogButton("Remove".Localize());

            removeButton.ToolTipText = "Remove all auto generated supports".Localize();
            removeButton.Click      += (s, e) => supportGenerator.RemoveExisting();
            buttonRow.AddChild(removeButton);

            // add 'Generate Supports' button
            var generateButton = theme.CreateDialogButton("Generate".Localize());

            generateButton.Name        = "Generate Support Button";
            generateButton.ToolTipText = "Find and create supports where needed".Localize();
            generateButton.Click      += (s, e) => Rebuild();
            buttonRow.AddChild(generateButton);
            theme.ApplyPrimaryActionStyle(generateButton);
        }
Ejemplo n.º 5
0
        public void SetActiveItem(ISceneContext sceneContext)
        {
            var selectedItem = sceneContext?.Scene?.SelectedItem;

            if (this.item == selectedItem)
            {
                return;
            }

            this.item = selectedItem;
            editorPanel.CloseChildren();

            // Allow caller to clean up with passing null for selectedItem
            if (item == null)
            {
                editorSectionWidget.Text = editorTitle;
                return;
            }

            var selectedItemType = selectedItem.GetType();

            primaryActionsPanel.RemoveChildren();

            IEnumerable <SceneOperation> primaryActions;

            if ((primaryActions = SceneOperations.GetPrimaryOperations(selectedItemType)) == null)
            {
                primaryActions = new List <SceneOperation>();
            }
            else
            {
                // Loop over primary actions creating a button for each
                foreach (var primaryAction in primaryActions)
                {
                    // TODO: Run visible/enable rules on actions, conditionally add/enable as appropriate
                    var button = new IconButton(primaryAction.Icon(theme), theme)
                    {
                        // Name = namedAction.Title + " Button",
                        ToolTipText     = primaryAction.Title,
                        Margin          = theme.ButtonSpacing,
                        BackgroundColor = theme.ToolbarButtonBackground,
                        HoverColor      = theme.ToolbarButtonHover,
                        MouseDownColor  = theme.ToolbarButtonDown,
                    };

                    button.Click += (s, e) =>
                    {
                        primaryAction.Action.Invoke(sceneContext);
                    };

                    primaryActionsPanel.AddChild(button);
                }
            }

            if (primaryActionsPanel.Children.Any())
            {
                // add in a separator from the apply and cancel buttons
                primaryActionsPanel.AddChild(new ToolbarSeparator(theme.GetBorderColor(50), theme.SeparatorMargin));
            }

            editorSectionWidget.Text = selectedItem.Name ?? selectedItemType.Name;

            HashSet <IObject3DEditor> mappedEditors = ApplicationController.Instance.Extensions.GetEditorsForType(selectedItemType);

            var undoBuffer = sceneContext.Scene.UndoBuffer;

            if (!(selectedItem.GetType().GetCustomAttributes(typeof(HideMeterialAndColor), true).FirstOrDefault() is HideMeterialAndColor))
            {
                // put in a color edit field
                var colorField = new ColorField(theme, selectedItem.Color);
                colorField.Initialize(0);
                colorField.ValueChanged += (s, e) =>
                {
                    if (selectedItem.Color != colorField.Color)
                    {
                        undoBuffer.AddAndDo(new ChangeColor(selectedItem, colorField.Color));
                    }
                };

                colorField.Content.MouseDown += (s, e) =>
                {
                    // make sure the render mode is set to shaded or outline
                    if (sceneContext.ViewState.RenderType != RenderOpenGl.RenderTypes.Shaded &&
                        sceneContext.ViewState.RenderType != RenderOpenGl.RenderTypes.Outlines)
                    {
                        // make sure the render mode is set to outline
                        sceneContext.ViewState.RenderType = RenderOpenGl.RenderTypes.Outlines;
                    }
                };

                // color row
                var row = new SettingsRow("Color".Localize(), null, colorField.Content, theme);

                // Special top border style for first item in editor
                row.Border = new BorderDouble(0, 1);

                editorPanel.AddChild(row);

                // put in a material edit field
                var materialField = new MaterialIndexField(sceneContext.Printer, theme, selectedItem.MaterialIndex);
                materialField.Initialize(0);
                materialField.ValueChanged += (s, e) =>
                {
                    if (selectedItem.MaterialIndex != materialField.MaterialIndex)
                    {
                        undoBuffer.AddAndDo(new ChangeMaterial(selectedItem, materialField.MaterialIndex));
                    }
                };

                materialField.Content.MouseDown += (s, e) =>
                {
                    if (sceneContext.ViewState.RenderType != RenderOpenGl.RenderTypes.Materials)
                    {
                        // make sure the render mode is set to material
                        sceneContext.ViewState.RenderType = RenderOpenGl.RenderTypes.Materials;
                    }
                };

                // material row
                editorPanel.AddChild(
                    new SettingsRow("Material".Localize(), null, materialField.Content, theme));
            }

            var rows = new SafeList <SettingsRow>();

            // put in the normal editor
            if (selectedItem is ComponentObject3D componentObject &&
                componentObject.Finalized)
            {
                var context = new PPEContext();
                PublicPropertyEditor.AddUnlockLinkIfRequired(selectedItem, editorPanel, theme);
                foreach (var selector in componentObject.SurfacedEditors)
                {
                    // if it is a reference to a sheet cell
                    if (selector.StartsWith("!"))
                    {
                        var firtSheet = componentObject.Descendants <SheetObject3D>().FirstOrDefault();
                        if (firtSheet != null)
                        {
                            var cellId = selector.Substring(1);
                            var cell   = firtSheet.SheetData[cellId];
                            if (cell != null)
                            {
                                // add an editor for the cell
                                var field = new DoubleField(theme);
                                field.Initialize(0);
                                double.TryParse(firtSheet.SheetData.EvaluateExpression(cellId), out double value);
                                field.DoubleValue = value;
                                field.ClearUndoHistory();

                                field.Content.Descendants <InternalNumberEdit>().First().MaxDecimalsPlaces = 3;
                                field.ValueChanged += (s, e) =>
                                {
                                    cell.Expression = field.Value;
                                    firtSheet.SheetData.Recalculate();
                                };

                                var row = new SettingsRow(cell.Name == null ? cellId : cell.Name, null, field.Content, theme);

                                editorPanel.AddChild(row);
                            }
                        }
                    }
                    else                     // parse it as a path to an object
                    {
                        // Get the named property via reflection
                        // Selector example:            '$.Children<CylinderObject3D>'
                        var match = pathResolver.Select(componentObject, selector).ToList();

                        //// - Add editor row for each
                        foreach (var instance in match)
                        {
                            if (instance is IObject3D object3D)
                            {
                                if (ApplicationController.Instance.Extensions.GetEditorsForType(object3D.GetType())?.FirstOrDefault() is IObject3DEditor editor)
                                {
                                    ShowObjectEditor((editor, object3D, object3D.Name), selectedItem);
                                }
                            }
                            else if (JsonPathContext.ReflectionValueSystem.LastMemberValue is ReflectionTarget reflectionTarget)
                            {
                                if (reflectionTarget.Source is IObject3D editedChild)
                                {
                                    context.item = editedChild;
                                }
                                else
                                {
                                    context.item = item;
                                }

                                var editableProperty = new EditableProperty(reflectionTarget.PropertyInfo, reflectionTarget.Source);

                                var editor = PublicPropertyEditor.CreatePropertyEditor(rows, editableProperty, undoBuffer, context, theme);
                                if (editor != null)
                                {
                                    editorPanel.AddChild(editor);
                                }

                                // Init with custom 'UpdateControls' hooks
                                (context.item as IPropertyGridModifier)?.UpdateControls(new PublicPropertyChange(context, "Update_Button"));
                            }
                        }
                    }
                }

                // Enforce panel padding
                foreach (var sectionWidget in editorPanel.Descendants <SectionWidget>())
                {
                    sectionWidget.Margin = 0;
                }
            }