Exemplo n.º 1
0
        /// <inheritdoc />
        public override void Initialize(LayoutElementsContainer layout)
        {
            // No support for different collections for now
            if (HasDifferentValues || HasDifferentTypes)
            {
                return;
            }

            var type      = Values.Type;
            var size      = Count;
            var argTypes  = type.GetGenericArguments();
            var keyType   = argTypes[0];
            var valueType = argTypes[1];

            _canEditKeys  = keyType == typeof(string) || keyType.IsPrimitive || keyType.IsEnum;
            _background   = FlaxEngine.GUI.Style.Current.CollectionBackgroundColor;
            _readOnly     = false;
            _notNullItems = false;

            // Try get CollectionAttribute for collection editor meta
            var   attributes         = Values.GetAttributes();
            Type  overrideEditorType = null;
            float spacing            = 0.0f;
            var   collection         = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);

            if (collection != null)
            {
                _readOnly     = collection.ReadOnly;
                _notNullItems = collection.NotNullItems;
                if (collection.BackgroundColor.HasValue)
                {
                    _background = collection.BackgroundColor.Value;
                }
                overrideEditorType = TypeUtils.GetType(collection.OverrideEditorTypeName).Type;
                spacing            = collection.Spacing;
            }

            // Size
            if (_readOnly || !_canEditKeys)
            {
                layout.Label("Size", size.ToString());
            }
            else
            {
                _size = layout.IntegerValue("Size");
                _size.IntValue.MinValue      = 0;
                _size.IntValue.MaxValue      = _notNullItems ? size : ushort.MaxValue;
                _size.IntValue.Value         = size;
                _size.IntValue.ValueChanged += OnSizeChanged;
            }

            // Elements
            if (size > 0)
            {
                var panel = layout.VerticalPanel();
                panel.Panel.BackgroundColor = _background;
                var keysEnumerable = ((IDictionary)Values[0]).Keys.OfType <object>();
                var keys           = keysEnumerable as object[] ?? keysEnumerable.ToArray();
                var valuesType     = new ScriptType(valueType);

                // Use separate layout cells for each collection items to improve layout updates for them in separation
                var useSharedLayout = valueType.IsPrimitive || valueType.IsEnum;

                for (int i = 0; i < size; i++)
                {
                    if (i != 0 && spacing > 0f)
                    {
                        if (panel.Children.Count > 0 && panel.Children[panel.Children.Count - 1] is PropertiesListElement propertiesListElement)
                        {
                            if (propertiesListElement.Labels.Count > 0)
                            {
                                var label  = propertiesListElement.Labels[propertiesListElement.Labels.Count - 1];
                                var margin = label.Margin;
                                margin.Bottom += spacing;
                                label.Margin   = margin;
                            }
                            propertiesListElement.Space(spacing);
                        }
                        else
                        {
                            panel.Space(spacing);
                        }
                    }

                    var key            = keys.ElementAt(i);
                    var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
                    var property       = panel.AddPropertyItem(new DictionaryItemLabel(this, key));
                    var itemLayout     = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
                    itemLayout.Object(new DictionaryValueContainer(valuesType, key, Values), overrideEditor);
                }
            }
            _elementsCount = size;

            // Add/Remove buttons
            if (!_readOnly && _canEditKeys)
            {
                var area      = layout.Space(20);
                var addButton = new Button(area.ContainerControl.Width - (16 + 16 + 2 + 2), 2, 16, 16)
                {
                    Text         = "+",
                    TooltipText  = "Add new item",
                    AnchorPreset = AnchorPresets.TopRight,
                    Parent       = area.ContainerControl,
                    Enabled      = !_notNullItems,
                };
                addButton.Clicked += () =>
                {
                    if (IsSetBlocked)
                    {
                        return;
                    }

                    Resize(Count + 1);
                };
                var removeButton = new Button(addButton.Right + 2, addButton.Y, 16, 16)
                {
                    Text         = "-",
                    TooltipText  = "Remove last item",
                    AnchorPreset = AnchorPresets.TopRight,
                    Parent       = area.ContainerControl,
                    Enabled      = size > 0,
                };
                removeButton.Clicked += () =>
                {
                    if (IsSetBlocked)
                    {
                        return;
                    }

                    Resize(Count - 1);
                };
            }
        }