示例#1
0
 public override int GetHashCode()
 {
     return(EntityTypes.Type1.GetHashCode() ^
            EntityTypes.Type2.GetHashCode() ^
            CustomName.GetHashCode() ^
            Level.GetHashCode() ^
            XP.GetHashCode());
 }
示例#2
0
        /// <summary>
        /// creates control user interface based on node type
        /// </summary>
        /// <param name="mainColor"></param>
        protected void InitializeControl(Type nodeType)
        {
            CustomNodeName.Visibility = Visibility.Collapsed;

            MainPanel.DataContext = NodeInstance;

            var ignoredProperties = nodeType.CustomAttributes
                                    .Where(a => a.AttributeType == typeof(IgnoredPropertyAttribute))
                                    .Select(ca => ca.NamedArguments.Single(na => na.MemberName == nameof(IgnoredPropertyAttribute.Name)).TypedValue.Value as string).ToArray();

            var inputProperties = nodeType.GetProperties()
                                  .Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(InputAttribute)))
                                  .Where(pi => ignoredProperties == null || !ignoredProperties.Contains(pi.Name))
                                  .OrderBy(p => p.CustomAttributes.Single(a => a.AttributeType == typeof(InputAttribute)).NamedArguments.Single(a => a.MemberName == nameof(InputAttribute.Order)).TypedValue.Value);

            var outputProperties = nodeType.GetProperties()
                                   .Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(OutputAttribute)))
                                   .Where(pi => ignoredProperties == null || !ignoredProperties.Contains(pi.Name));

            #region grid definition

            // add rows for all input properties
            for (var i = 0; i < inputProperties.Count(); i++)
            {
                MainPanel.RowDefinitions.Add(new RowDefinition {
                    Height = GridLength.Auto
                });
            }

            // number of input rows that have free output side
            var inputAnchorsOnly = inputProperties.Count(ip => AttributeHelper.GetValue <InputAttribute, bool>(ip, nameof(InputAttribute.AnchorOnly)) && !AttributeHelper.GetValue <InputAttribute, bool>(ip, nameof(InputAttribute.OutputAnchor)));
            // number of outputs that could be moved up next to inputs
            var outputAnchorsOnly = outputProperties.Count(op => AttributeHelper.GetValue <OutputAttribute, bool>(op, nameof(OutputAttribute.AnchorOnly)));
            // outputs that needs to be at bottom
            var outputLeft = outputProperties.Count() - outputAnchorsOnly;
            // number of output rows that should be added under input rows
            var outputRowsToAdd = outputLeft + Math.Max(0, outputAnchorsOnly - inputAnchorsOnly);

            // add rows for some output properties
            for (var i = 0; i < outputRowsToAdd; i++)
            {
                MainPanel.RowDefinitions.Add(new RowDefinition {
                    Height = GridLength.Auto
                });
            }

            MainPanel.RowDefinitions.Add(new RowDefinition {
                Height = new GridLength(AnchorSize / 2)
            });                                                                                                         // bottom

            #endregion

            #region header

            CustomName = AttributeHelper.GetValue <NodeInfoAttribute, string>(NodeInstance.GetType(), nameof(NodeInfoAttribute.DisplayName)) ?? NodeInstance.GetType().Name;
            var colorValues = BitConverter.GetBytes(CustomName.GetHashCode());
            CustomColor = Color.FromArgb(0xff, colorValues[1], colorValues[2], colorValues[3]);

            NodeHeader.Background = new LinearGradientBrush(CustomColor, Color.Multiply(CustomColor, (float)0.5), new Point(0, 1), new Point(1, 0));
            NodeTitle.Text        = CustomName;

            #endregion

            #region border

            var border = new Border
            {
                BorderBrush     = new SolidColorBrush(Colors.Black),
                BorderThickness = new Thickness(1, 0, 1, 1)
            };
            Grid.SetRow(border, 1);
            Grid.SetColumnSpan(border, MainPanel.ColumnDefinitions.Count);
            Grid.SetRowSpan(border, MainPanel.RowDefinitions.Count - 1);
            MainPanel.Children.Add(border);

            #endregion

            var firstRow   = 2;
            var inputRows  = new bool[MainPanel.RowDefinitions.Count - 3];
            var outputRows = new bool[MainPanel.RowDefinitions.Count - 3];

            foreach (var inputProperty in inputProperties)
            {
                var inputAttribute = inputProperty.CustomAttributes.Single(a => a.AttributeType == typeof(InputAttribute));

                var readOnly             = AttributeHelper.GetValue <InputAttribute, bool>(inputProperty, nameof(InputAttribute.ReadOnly));
                var anchorOnly           = AttributeHelper.GetValue <InputAttribute, bool>(inputProperty, nameof(InputAttribute.AnchorOnly));
                var inputAnchor          = AttributeHelper.GetValue <InputAttribute, bool>(inputProperty, nameof(InputAttribute.InputAnchor));
                var outputAnchor         = AttributeHelper.GetValue <InputAttribute, bool>(inputProperty, nameof(InputAttribute.OutputAnchor));
                var inputName            = AttributeHelper.GetValue <InputAttribute, string>(inputProperty, nameof(InputAttribute.InputName)) ?? inputProperty.Name;
                var inputDisplayName     = AttributeHelper.GetValue <InputAttribute, string>(inputProperty, nameof(InputAttribute.DisplayName)) ?? inputProperty.Name;
                var inputAnchorProperty  = AttributeHelper.GetValue <InputAttribute, string>(inputProperty, nameof(InputAttribute.InputAnchorProperty)) ?? inputProperty.Name;
                var outputAnchorProperty = AttributeHelper.GetValue <InputAttribute, string>(inputProperty, nameof(InputAttribute.OutputAnchorProperty)) ?? inputProperty.Name;

                // next free row
                var row = firstRow;
                for (var i = 0; i < outputRows.Length; i++)
                {
                    if (!inputRows[i])
                    {
                        row += i;
                        break;
                    }
                }

                if (inputAnchor)
                {
                    #region input anchor

                    var anchor = new Rectangle
                    {
                        Fill                = new SolidColorBrush(InputBackground),
                        Stroke              = new SolidColorBrush(Colors.Black),
                        VerticalAlignment   = VerticalAlignment.Center,
                        HorizontalAlignment = HorizontalAlignment.Left,
                        Margin              = new Thickness(-AnchorSize / 2, 0, 0, 0),
                        Width               = AnchorSize,
                        Height              = AnchorSize,
                        Name                = InputAnchorPrefix + inputAnchorProperty,
                        ToolTip             = inputProperty.PropertyType.Name,
                    };
                    anchor.MouseEnter += HilightInputAnchorOn;
                    anchor.MouseLeave += HilightInputAnchorOff;

                    Grid.SetRow(anchor, row);
                    Grid.SetColumn(anchor, 0);
                    MainPanel.Children.Add(anchor);

                    #endregion
                }

                #region label

                var label = new Label
                {
                    Foreground        = new SolidColorBrush(TextForeground),
                    VerticalAlignment = VerticalAlignment.Center,
                    Name       = LabelPrefix + inputAnchorProperty,
                    FontFamily = new FontFamily("Consolas"),
                    Effect     = LabelEffect,
                    Content    = inputDisplayName,
                };

                Grid.SetRow(label, row);
                Grid.SetColumn(label, 1);
                if (inputAnchor && anchorOnly && outputAnchor)
                {
                    label.HorizontalAlignment = HorizontalAlignment.Right;
                    Grid.SetColumnSpan(label, 3);
                }
                else
                {
                    label.HorizontalAlignment = HorizontalAlignment.Left;
                }
                MainPanel.Children.Add(label);

                #endregion

                if (!anchorOnly)
                {
                    #region input element

                    if (inputProperty.PropertyType == typeof(SolidColorBrush))
                    {
                        var colorElement = new TextBox
                        {
                            Background                 = new SolidColorBrush(Colors.Black),
                            Foreground                 = new SolidColorBrush(Colors.White),
                            BorderThickness            = new Thickness(1),
                            BorderBrush                = new SolidColorBrush(InputBorder),
                            Margin                     = new Thickness(0, 0, 0, 0),
                            Name                       = InputValuePrefix + inputName,
                            FontFamily                 = new FontFamily("Consolas"),
                            HorizontalContentAlignment = HorizontalAlignment.Center,
                            VerticalContentAlignment   = VerticalAlignment.Center,
                            VerticalAlignment          = VerticalAlignment.Stretch,
                            HorizontalAlignment        = HorizontalAlignment.Stretch,
                            IsReadOnly                 = true,
                            Width                      = 128,
                        };

                        var binding = new Binding(inputProperty.Name)
                        {
                            Mode = BindingMode.OneWay,
                        };
                        colorElement.SetBinding(TextBox.TextProperty, binding);
                        colorElement.SetBinding(TextBox.BackgroundProperty, binding);

                        Grid.SetRow(colorElement, row);
                        Grid.SetColumn(colorElement, 2);
                        MainPanel.Children.Add(colorElement);
                    }
                    // TODO UI INPUT CustomCheckBox
                    //else if (inputProperty.PropertyType == typeof(bool))
                    //{
                    //	var checkBox = new CheckBox
                    //	{
                    //		//Background = new SolidColorBrush(InputBackground),
                    //		//Foreground = new SolidColorBrush(TextForeground),
                    //		BorderThickness = new Thickness(1),
                    //		Name = InputValuePrefix + inputName,
                    //		FontFamily = new FontFamily("Consolas"),
                    //		HorizontalContentAlignment = HorizontalAlignment.Center,
                    //		VerticalContentAlignment = VerticalAlignment.Center,
                    //		VerticalAlignment = VerticalAlignment.Center,
                    //		HorizontalAlignment = HorizontalAlignment.Center,
                    //	};

                    //	var binding = new Binding(inputProperty.Name)
                    //	{
                    //		Mode = BindingMode.OneWay,
                    //	};
                    //	checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);

                    //	Grid.SetRow(checkBox, row);
                    //	Grid.SetColumn(checkBox, 2);
                    //	Grid.SetColumnSpan(checkBox, mainPanel.ColumnDefinitions.Count - 1);
                    //	mainPanel.Children.Add(checkBox);
                    //}
                    else
                    {
                        var textbox = new TextBox
                        {
                            Foreground        = new SolidColorBrush(TextForeground),
                            BorderBrush       = new SolidColorBrush(InputBorder),
                            Background        = new SolidColorBrush(InputBackground),
                            VerticalAlignment = VerticalAlignment.Center,
                            TextAlignment     = TextAlignment.Right,
                            Margin            = new Thickness(0, 0, 4, 0),
                            Name         = InputValuePrefix + inputName,
                            IsReadOnly   = readOnly,
                            FontFamily   = new FontFamily("Consolas"),
                            TextWrapping = TextWrapping.Wrap,
                            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                            MaxHeight = 128,
                            MaxWidth  = 256,
                        };

                        var binding = new Binding(inputProperty.Name)
                        {
                            Mode = readOnly ? BindingMode.OneWay : BindingMode.TwoWay,
                            ValidatesOnExceptions = true
                        };

                        if (inputProperty.PropertyType == typeof(double))
                        {
                            textbox.MinWidth     = 64;
                            binding.StringFormat = "{0:F" + DecimalPrecision + "}";
                        }
                        else if (inputProperty.PropertyType == typeof(int))
                        {
                            textbox.MinWidth = 64;
                        }
                        else if (inputProperty.PropertyType == typeof(string))
                        {
                            textbox.MinWidth      = 128;
                            textbox.TextAlignment = TextAlignment.Left;
                            textbox.TextWrapping  = TextWrapping.NoWrap;
                        }

                        textbox.SetBinding(TextBox.TextProperty, binding);

                        Grid.SetRow(textbox, row);
                        Grid.SetColumn(textbox, 2);
                        MainPanel.Children.Add(textbox);
                    }

                    #endregion

                    outputRows[row - firstRow] = true;
                }

                if (outputAnchor)
                {
                    #region output anchor

                    var anchor = new Rectangle
                    {
                        Fill                = new SolidColorBrush(CustomColor),
                        Stroke              = new SolidColorBrush(Colors.Black),
                        VerticalAlignment   = VerticalAlignment.Center,
                        HorizontalAlignment = HorizontalAlignment.Right,
                        Margin              = new Thickness(0, 0, -AnchorSize / 2, 0),
                        Width               = AnchorSize,
                        Height              = AnchorSize,
                        Name                = OutputAnchorPrefix + outputAnchorProperty,
                        ToolTip             = inputProperty.PropertyType.Name,
                    };
                    anchor.MouseEnter += HilightOutputAnchorOn;
                    anchor.MouseLeave += HilightOutputAnchorOff;

                    Grid.SetRow(anchor, row);
                    Grid.SetColumn(anchor, MainPanel.ColumnDefinitions.Count - 1);
                    MainPanel.Children.Add(anchor);

                    #endregion

                    outputRows[row - firstRow] = true;
                }

                inputRows[row - firstRow] = true;
            }

            foreach (var outputProperty in outputProperties)
            {
                var outputAttribute = outputProperty.CustomAttributes.Single(a => a.AttributeType == typeof(OutputAttribute));

                var readOnly             = AttributeHelper.GetValue <OutputAttribute, bool>(outputProperty, nameof(OutputAttribute.ReadOnly));
                var anchorOnly           = AttributeHelper.GetValue <OutputAttribute, bool>(outputProperty, nameof(OutputAttribute.AnchorOnly));
                var noAnchor             = AttributeHelper.GetValue <OutputAttribute, bool>(outputProperty, nameof(OutputAttribute.NoAnchor));
                var outputDisplayName    = AttributeHelper.GetValue <OutputAttribute, string>(outputProperty, nameof(OutputAttribute.DisplayName)) ?? outputProperty.Name;
                var outputAnchorProperty = AttributeHelper.GetValue <OutputAttribute, string>(outputProperty, nameof(OutputAttribute.OutputAnchorProperty)) ?? outputProperty.Name;

                // next free row
                var row = firstRow;
                for (var i = 0; i < outputRows.Length; i++)
                {
                    if (!outputRows[i] && (anchorOnly || !inputRows[i]))
                    {
                        row += i;
                        break;
                    }
                }

                if (!anchorOnly)
                {
                    #region output element

                    if (outputProperty.PropertyType == typeof(BitmapSource))
                    {
                        var imageBorder = new Border
                        {
                            BorderThickness = new Thickness(1),
                            BorderBrush     = new SolidColorBrush(InputBorder),
                        };
                        var image = new Image();
                        imageBorder.Child = image;

                        image.SetBinding(Image.SourceProperty, new Binding(outputProperty.Name)
                        {
                            Mode = BindingMode.OneWay
                        });

                        var widthBinding  = AttributeHelper.GetValue <ImageBindingsAttribute, string>(outputProperty, nameof(ImageBindingsAttribute.Width));
                        var heightBinding = AttributeHelper.GetValue <ImageBindingsAttribute, string>(outputProperty, nameof(ImageBindingsAttribute.Height));
                        if (!string.IsNullOrEmpty(widthBinding) && !string.IsNullOrEmpty(heightBinding))
                        {
                            image.SetBinding(Image.WidthProperty, new Binding(widthBinding)
                            {
                                Mode = BindingMode.OneWay
                            });
                            image.SetBinding(Image.HeightProperty, new Binding(heightBinding)
                            {
                                Mode = BindingMode.OneWay
                            });
                        }

                        Grid.SetRow(imageBorder, row);
                        Grid.SetColumn(imageBorder, 1);
                        Grid.SetColumnSpan(imageBorder, MainPanel.ColumnDefinitions.Count - 2);
                        MainPanel.Children.Add(imageBorder);
                    }
                    else
                    {
                        var textbox = new TextBox
                        {
                            Foreground        = new SolidColorBrush(TextForeground),
                            BorderBrush       = new SolidColorBrush(InputBorder),
                            Background        = new SolidColorBrush(InputBackground),
                            VerticalAlignment = VerticalAlignment.Center,
                            TextAlignment     = outputProperty.PropertyType == typeof(string) ? TextAlignment.Left : TextAlignment.Right,
                            Margin            = new Thickness(0, 0, 4, 0),
                            Name       = OutputValuePrefix + outputAnchorProperty,
                            FontFamily = new FontFamily("Consolas"),
                            IsReadOnly = readOnly,

                            TextWrapping = TextWrapping.Wrap,
                            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                            MaxHeight = 128,
                            MaxWidth  = 256,
                        };

                        var binding = new Binding(outputProperty.Name)
                        {
                            Mode = BindingMode.TwoWay,
                            ValidatesOnExceptions = true
                        };

                        if (outputProperty.PropertyType == typeof(double))
                        {
                            binding.StringFormat = "{0:F" + DecimalPrecision + "}";
                        }

                        textbox.SetBinding(TextBox.TextProperty, binding);

                        Grid.SetRow(textbox, row);
                        Grid.SetColumn(textbox, 2);
                        MainPanel.Children.Add(textbox);
                    }

                    #endregion
                }

                #region label

                var label = new Label
                {
                    Foreground          = new SolidColorBrush(TextForeground),
                    VerticalAlignment   = VerticalAlignment.Center,
                    HorizontalAlignment = HorizontalAlignment.Right,
                    Name       = LabelPrefix + outputAnchorProperty,
                    FontFamily = new FontFamily("Consolas"),
                    Effect     = LabelEffect,
                    Content    = outputDisplayName,
                };

                Grid.SetRow(label, row);
                if (anchorOnly)
                {
                    Grid.SetColumn(label, 0);
                    Grid.SetColumnSpan(label, MainPanel.ColumnDefinitions.Count - 1);
                }
                else
                {
                    Grid.SetColumn(label, MainPanel.ColumnDefinitions.Count - 2);
                }

                MainPanel.Children.Add(label);

                #endregion

                if (!noAnchor)
                {
                    #region output anchor

                    var anchor = new Rectangle
                    {
                        Fill                = new SolidColorBrush(CustomColor),
                        Stroke              = new SolidColorBrush(Colors.Black),
                        VerticalAlignment   = VerticalAlignment.Center,
                        HorizontalAlignment = HorizontalAlignment.Right,
                        Margin              = new Thickness(0, 0, -8, 0),
                        Width               = AnchorSize,
                        Height              = AnchorSize,
                        Name                = OutputAnchorPrefix + outputAnchorProperty,
                        ToolTip             = outputProperty.PropertyType.Name,
                    };
                    anchor.MouseEnter += HilightOutputAnchorOn;
                    anchor.MouseLeave += HilightOutputAnchorOff;

                    Grid.SetRow(anchor, row);
                    Grid.SetColumn(anchor, MainPanel.ColumnDefinitions.Count - 1);
                    MainPanel.Children.Add(anchor);

                    #endregion
                }

                outputRows[row - firstRow] = true;
            }

            //MainPanel.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
            //var customDouble = new CustomFloatingInput();
            //Grid.SetRow(customDouble, MainPanel.RowDefinitions.Count - 1);
            //Grid.SetColumn(customDouble, 1);
            //Grid.SetColumnSpan(customDouble, 2);
            //MainPanel.Children.Add(customDouble);

            //MainPanel.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
            //var customInteger = new CustomIntegerInput();
            //Grid.SetRow(customInteger, MainPanel.RowDefinitions.Count - 1);
            //Grid.SetColumn(customInteger, 1);
            //Grid.SetColumnSpan(customInteger, 2);
            //MainPanel.Children.Add(customInteger);

            //MainPanel.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto, MinHeight = 30 });
            //var customText = new CustomTextInput();
            //Grid.SetRow(customText, MainPanel.RowDefinitions.Count - 1);
            //Grid.SetColumn(customText, 1);
            //Grid.SetColumnSpan(customText, 2);
            //MainPanel.Children.Add(customText);
        }