Beispiel #1
0
        private void GenerateCells()
        {
            foreach (var cell in cells.Values)
            {
                cell.Clear();
                cellPool.Push(cell);
            }
            cells.Clear();
            foreach (var animator in node.Animators)
            {
                if (animator.IsZombie)
                {
                    continue;
                }
                for (var j = 0; j < animator.ReadonlyKeys.Count; j++)
                {
                    var key        = animator.ReadonlyKeys[j];
                    var colorIndex = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(animator.Animable.GetType(), animator.TargetPropertyPath)?.ColorIndex ?? 0;

                    if (!cells.TryGetValue(key.Frame, out var cell))
                    {
                        cell = cellPool.Count == 0 ? new Cell() : cellPool.Pop();
                        cells.Add(key.Frame, cell);
                    }
                    if (cell.StripCount == 0)
                    {
                        cell.Func1 = key.Function;
                    }
                    else if (cell.StripCount == 1)
                    {
                        var lastColorIndex = 0;
                        for (int i = 0; i < cell.Strips.Count; i++)
                        {
                            if (cell.Strips[i])
                            {
                                lastColorIndex = i;
                                break;
                            }
                        }
                        if (lastColorIndex < colorIndex)
                        {
                            cell.Func2 = key.Function;
                        }
                        else
                        {
                            var a = cell.Func1;
                            cell.Func1 = key.Function;
                            cell.Func2 = a;
                        }
                    }
                    cell.Strips[colorIndex] = true;
                    cell.StripCount++;
                    cells[key.Frame] = cell;
                }
            }
        }
 InspectorPropertyRegistry()
 {
     Items = new List <RegistryItem>();
     AddEditor(c => PropertyAttributes <TangerineDropDownListPropertyEditorAttribute> .Get(c.Type, c.PropertyName) != null,
               c => {
         var a = PropertyAttributes <TangerineDropDownListPropertyEditorAttribute> .Get(c.Type, c.PropertyName);
         Type specializedDropDownListPropertyEditorType = typeof(DropDownListPropertyEditor <>).MakeGenericType(c.PropertyInfo.PropertyType);
         return(Activator.CreateInstance(specializedDropDownListPropertyEditorType, new object[] { c, a.EnumerateItems(c.Objects.First()) }) as IPropertyEditor);
     }
               );
     AddEditor(c => PropertyAttributes <TangerineFilePropertyAttribute> .Get(c.Type, c.PropertyName) != null,
               c => {
         var a = PropertyAttributes <TangerineFilePropertyAttribute> .Get(c.Type, c.PropertyName);
         Type specializedCustomFilePropertyEditorType = typeof(CustomFilePropertyEditor <>).MakeGenericType(c.PropertyInfo.PropertyType);
         return(Activator.CreateInstance(specializedCustomFilePropertyEditorType, new object[] { c, a }) as IPropertyEditor);
     }
               );
     AddEditor(c => c.PropertyName == "ContentsPath" && c.Objects.All(o => o is Node), c => AllowChildren(c) ? new ContentsPathPropertyEditor(c) : null);
     AddEditor(c => c.PropertyName == "Trigger", c => AllowChildren(c) ? new TriggerPropertyEditor(c) : null);
     AddEditor(typeof(Vector2), c => new Vector2PropertyEditor(c));
     AddEditor(typeof(Vector3), c => new Vector3PropertyEditor(c));
     AddEditor(typeof(Quaternion), c => new QuaternionPropertyEditor(c));
     AddEditor(typeof(NumericRange), c => new NumericRangePropertyEditor(c));
     AddEditor(c => c.PropertyName == "Text", c => new TextPropertyEditor(c));
     AddEditor(c => c.PropertyName == "Id", c => new NodeIdPropertyEditor(c));
     AddEditor(typeof(string), c => new StringPropertyEditor(c));
     AddEditor(typeof(float), c => new FloatPropertyEditor(c));
     AddEditor(typeof(double), c => new DoublePropertyEditor(c));
     AddEditor(typeof(bool), c => new BooleanPropertyEditor(c));
     AddEditor(typeof(int), c => new IntPropertyEditor(c));
     AddEditor(typeof(sbyte), c => new SBytePropertyEditor(c));
     AddEditor(typeof(Color4), c => new Color4PropertyEditor(c));
     AddEditor(typeof(ColorGradient), c => new ColorGradientPropertyEditor(c));
     AddEditor(typeof(Anchors), c => new AnchorsPropertyEditor(c));
     AddEditor(typeof(Blending), c => new BlendingPropertyEditor(c));
     AddEditor(typeof(RenderTarget), c => new RenderTargetPropertyEditor(c));
     AddEditor(c => {
         return
         (!c.Objects.Skip(1).Any() &&
          c.PropertyInfo.PropertyType == typeof(ITexture) &&
          c.PropertyInfo.GetValue(c.Objects.First())?.GetType() == typeof(RenderTexture));
     }, c => new RenderTexturePropertyEditor(c));
     AddEditor(typeof(ITexture), c => new TexturePropertyEditor <ITexture>(c));
     AddEditor(typeof(SerializableTexture), c => new TexturePropertyEditor <SerializableTexture>(c));
     AddEditor(typeof(SerializableSample), c => new AudioSamplePropertyEditor(c));
     AddEditor(typeof(SerializableFont), c => new FontPropertyEditor(c));
     AddEditor(typeof(NodeReference <Camera3D>), c => new NodeReferencePropertyEditor <Camera3D>(c));
     AddEditor(typeof(NodeReference <Image>), c => new NodeReferencePropertyEditor <Image>(c));
     AddEditor(typeof(NodeReference <Spline>), c => new NodeReferencePropertyEditor <Spline>(c));
     AddEditor(typeof(NodeReference <Widget>), c => new NodeReferencePropertyEditor <Widget>(c));
     AddEditor(typeof(NodeReference <Node3D>), c => new NodeReferencePropertyEditor <Node3D>(c));
     AddEditor(typeof(NodeReference <Spline3D>), c => new NodeReferencePropertyEditor <Spline3D>(c));
     AddEditor(typeof(SkinningWeights), c => new SkinningWeightsPropertyEditor(c));
     AddEditor(typeof(Alignment), c => new AlignmentPropertyEditor(c));
     AddEditor(typeof(Thickness), c => new ThicknessPropertyEditor(c));
 }
Beispiel #3
0
        private IEnumerable <IPropertyEditor> PopulatePropertyEditors(Type type, IEnumerable <object> objects, IEnumerable <object> rootObjects, Widget widget, Dictionary <string, List <PropertyEditorParams> > editorParams)
        {
            foreach (var header in editorParams.Keys.OrderBy((s) => s))
            {
                AddGroupHeader(header, widget);
                foreach (var param in editorParams[header])
                {
                    bool            isPropertyRegistered = false;
                    IPropertyEditor editor = null;
                    foreach (var i in InspectorPropertyRegistry.Instance.Items)
                    {
                        if (i.Condition(param))
                        {
                            isPropertyRegistered = true;
                            editor = i.Builder(param);
                            break;
                        }
                    }

                    if (!isPropertyRegistered)
                    {
                        var propertyType   = param.PropertyInfo.PropertyType;
                        var iListInterface = propertyType.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList <>));
                        if (propertyType.IsEnum)
                        {
                            editor = CreateEditorForEnum(param);
                        }
                        else if (iListInterface != null)
                        {
                            editor = PopulateEditorsForListType(objects, rootObjects, param, iListInterface);
                        }
                        else if ((propertyType.IsClass || propertyType.IsInterface) && !propertyType.GetInterfaces().Contains(typeof(IEnumerable)))
                        {
                            editor = PopulateEditorsForInstanceType(objects, rootObjects, param);
                        }
                    }

                    if (editor != null)
                    {
                        DecoratePropertyEditor(editor, row++);
                        editors.Add(editor);
                        var showCondition = PropertyAttributes <TangerineIgnoreIfAttribute> .Get(type, param.PropertyInfo.Name);

                        if (showCondition != null)
                        {
                            editor.ContainerWidget.Updated += (delta) => {
                                editor.ContainerWidget.Visible = !showCondition.Check(param.Objects.First());
                            };
                        }
                        yield return(editor);
                    }
                }
            }
        }
Beispiel #4
0
        public PropertyEditorParams(Widget inspectorPane, List <object> objects, Type type, string propertyName)
        {
            InspectorPane      = inspectorPane;
            Objects            = objects;
            Type               = type;
            PropertyName       = propertyName;
            TangerineAttribute = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(Type, PropertyName) ?? new TangerineKeyframeColorAttribute(0);

            Group = PropertyAttributes <TangerineGroupAttribute> .Get(Type, PropertyName)?.Name ?? String.Empty;

            PropertyInfo          = Type.GetProperty(PropertyName);
            PropertySetter        = SetProperty;
            NumericEditBoxFactory = () => new ThemedNumericEditBox();
            DropDownListFactory   = () => new ThemedDropDownList();
            EditBoxFactory        = () => new ThemedEditBox();
        }
Beispiel #5
0
        private void Render(Widget widget)
        {
            widget.PrepareRendererState();
            Renderer.DrawRect(Vector2.Zero, widget.ContentSize, ColorTheme.Current.TimelineGrid.PropertyRowBackground);
            var colorIndex = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(animator.Animable.GetType(), animator.TargetPropertyPath)?.ColorIndex ?? 0;

            var color = KeyframePalette.Colors[colorIndex];

            for (int i = 0; i < animator.ReadonlyKeys.Count; i++)
            {
                var key = animator.ReadonlyKeys[i];
                var a   = new Vector2(key.Frame * TimelineMetrics.ColWidth + 1, 0);
                var b   = a + new Vector2(TimelineMetrics.ColWidth - 1, widget.Height);
                KeyframeFigure.Render(a, b, color, key.Function);
            }
        }
Beispiel #6
0
        protected virtual void Render(Widget widget)
        {
            var maxCol = Timeline.Instance.ColumnCount;

            widget.PrepareRendererState();
            if (maxCol > keyStrips.Length)
            {
                keyStrips = new BitSet32[maxCol];
            }
            for (int i = 0; i < maxCol; i++)
            {
                keyStrips[i] = BitSet32.Empty;
            }
            foreach (var a in node.Animators)
            {
                for (int j = 0; j < a.ReadonlyKeys.Count; j++)
                {
                    var key        = a.ReadonlyKeys[j];
                    var colorIndex = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(node.GetType(), a.TargetProperty)?.ColorIndex ?? 0;

                    keyStrips[key.Frame][colorIndex] = true;
                }
            }
            for (int i = 0; i < maxCol; i++)
            {
                if (keyStrips[i] != BitSet32.Empty)
                {
                    var s = keyStrips[i];
                    int c = 0;
                    for (int j = 0; j < 32; j++)
                    {
                        c += s[j] ? 1 : 0;
                    }
                    var a = new Vector2(i * TimelineMetrics.ColWidth + 1, 0);
                    var d = widget.Height / c;
                    for (int j = 0; j < 32; j++)
                    {
                        if (s[j])
                        {
                            var b = a + new Vector2(TimelineMetrics.ColWidth - 1, d);
                            Renderer.DrawRect(a, b, KeyframePalette.Colors[j]);
                            a.Y += d;
                        }
                    }
                }
            }
        }
Beispiel #7
0
        private void DecoratePropertyEditor(IPropertyEditor editor, int row)
        {
            var ctr = editor.ContainerWidget;

            if (!(editor is IExpandablePropertyEditor))
            {
                ctr.Nodes.Insert(0, new HSpacer(20));
            }

            var index = ctr.Nodes.Count() - 1;

            if (PropertyAttributes <TangerineStaticPropertyAttribute> .Get(editor.EditorParams.PropertyInfo) == null)
            {
                var keyFunctionButton = new KeyFunctionButton {
                    LayoutCell = new LayoutCell(Alignment.LeftCenter, stretchX: 0),
                };
                var keyframeButton = new KeyframeButton {
                    LayoutCell = new LayoutCell(Alignment.LeftCenter, stretchX: 0),
                    KeyColor   = KeyframePalette.Colors[editor.EditorParams.TangerineAttribute.ColorIndex],
                };
                keyFunctionButton.Clicked += editor.SetFocus;
                keyframeButton.Clicked    += editor.SetFocus;
                ctr.Nodes.Insert(index++, keyFunctionButton);
                ctr.Nodes.Insert(index++, keyframeButton);
                ctr.Nodes.Insert(index, new HSpacer(4));
                ctr.Tasks.Add(new KeyframeButtonBinding(editor.EditorParams, keyframeButton));
                ctr.Tasks.Add(new KeyFunctionButtonBinding(editor.EditorParams, keyFunctionButton));
            }
            else
            {
                ctr.Nodes.Insert(2, new HSpacer(42));
            }
            editor.ContainerWidget.Padding = new Thickness {
                Left = 4, Top = 1, Right = 12, Bottom = 1
            };
            editor.ContainerWidget.CompoundPresenter.Add(new WidgetFlatFillPresenter(
                                                             row % 2 == 0 ?
                                                             ColorTheme.Current.Inspector.StripeBackground1 :
                                                             ColorTheme.Current.Inspector.StripeBackground2
                                                             )
            {
                IgnorePadding = true
            });
        }
Beispiel #8
0
        private void Render(Widget widget)
        {
            var maxCol = Timeline.Instance.ColumnCount;

            widget.PrepareRendererState();
            Renderer.DrawRect(Vector2.Zero, widget.ContentSize, ColorTheme.Current.TimelineGrid.PropertyRowBackground);
            var colorIndex = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(animator.Animable.GetType(), animator.TargetPropertyPath)?.ColorIndex ?? 0;

            var color = KeyframePalette.Colors[colorIndex];

            for (int i = 0; i < animator.ReadonlyKeys.Count; i++)
            {
                var key = animator.ReadonlyKeys[i];
                Renderer.Transform1 =
                    Matrix32.RotationRough(Mathf.Pi / 4) *
                    Matrix32.Translation((key.Frame + 0.5f) * TimelineMetrics.ColWidth + 0.5f, widget.Height / 2 + 0.5f) *
                    widget.LocalToWorldTransform;
                var v = TimelineMetrics.ColWidth / 3 * Vector2.One;
                Renderer.DrawRect(-v, v, color);
            }
        }
Beispiel #9
0
        private bool ShouldInspectProperty(Type type, IEnumerable <object> objects, PropertyInfo property)
        {
            if (property.GetIndexParameters().Length > 0)
            {
                // we dont inspect indexers (they have "Item" name by default
                return(false);
            }
            var yuzuItem = Yuzu.Metadata.Meta.Get(type, Serialization.YuzuCommonOptions).Items.Find(i => i.PropInfo == property);
            var tang     = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(type, property.Name);

            var tangIgnore = PropertyAttributes <TangerineIgnoreAttribute> .Get(type, property.Name);

            var tangInspect = PropertyAttributes <TangerineInspectAttribute> .Get(type, property.Name);

            if (tangInspect == null && (yuzuItem == null && tang == null || tangIgnore != null))
            {
                return(false);
            }
            if (type.IsSubclassOf(typeof(Node)))
            {
                // Root must be always visible
                if (Document.Current.InspectRootNode && property.Name == nameof(Widget.Visible))
                {
                    return(false);
                }
                if (objects.Any(obj =>
                                obj is Node node &&
                                !string.IsNullOrEmpty(node.ContentsPath) &&
                                obj is IExternalScenePropertyOverrideChecker checker &&
                                !checker.IsPropertyOverridden(property)
                                ))
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #10
0
        private void PopulateContentForType(Type type, List <object> objects)
        {
            int row = 0;
            var categoryLabelAdded = false;
            var editorParams       = new Dictionary <string, List <PropertyEditorParams> >();

            foreach (var property in type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public))
            {
                if (property.Name == "Item")
                {
                    // WTF, Bug in Mono?
                    continue;
                }
                var yuzuField = PropertyAttributes <YuzuField> .Get(type, property.Name);

                var tang = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(type, property.Name);

                var tangIgnore = PropertyAttributes <TangerineIgnoreAttribute> .Get(type, property.Name);

                var tangInspect = PropertyAttributes <TangerineInspectAttribute> .Get(type, property.Name);

                if (tangInspect == null && (yuzuField == null && tang == null || tangIgnore != null))
                {
                    continue;
                }

                if (!categoryLabelAdded)
                {
                    categoryLabelAdded = true;
                    var text = type.Name;
                    if (text == "Node" && objects.Count == 1)
                    {
                        text += $" of type '{objects[0].GetType().Name}'";
                    }
                    var label = new Widget {
                        LayoutCell = new LayoutCell {
                            StretchY = 0
                        },
                        Layout    = new StackLayout(),
                        MinHeight = Theme.Metrics.DefaultButtonSize.Y,
                        Nodes     =
                        {
                            new ThemedSimpleText {
                                Text           = text,
                                Padding        = new Thickness(4, 0),
                                VAlignment     = VAlignment.Center,
                                ForceUncutText = false,
                            }
                        }
                    };
                    label.CompoundPresenter.Add(new WidgetFlatFillPresenter(ColorTheme.Current.Inspector.CategoryLabelBackground));
                    widget.AddNode(label);
                }
                var context = new PropertyEditorParams(widget, objects, type, property.Name)
                {
                    NumericEditBoxFactory = () => new TransactionalNumericEditBox(),
                    PropertySetter        = SetAnimableProperty,
                    DefaultValueGetter    = () => {
                        var ctr = type.GetConstructor(new Type[] {});
                        if (ctr != null)
                        {
                            var obj  = ctr.Invoke(null);
                            var prop = type.GetProperty(property.Name);
                            return(prop.GetValue(obj));
                        }
                        return(null);
                    }
                };

                if (!editorParams.Keys.Contains(context.Group))
                {
                    editorParams.Add(context.Group, new List <PropertyEditorParams>());
                }

                editorParams[context.Group].Add(context);
            }

            foreach (var header in editorParams.Keys.OrderBy((s) => s))
            {
                AddGroupHeader(header);
                foreach (var param in editorParams[header])
                {
                    foreach (var i in InspectorPropertyRegistry.Instance.Items)
                    {
                        if (i.Condition(param))
                        {
                            var propertyEditor = i.Builder(param);
                            if (propertyEditor != null)
                            {
                                DecoratePropertyEditor(propertyEditor, row++);
                                editors.Add(propertyEditor);

                                var showCondition = PropertyAttributes <TangerineIgnoreIfAttribute> .Get(type, param.PropertyInfo.Name);

                                if (showCondition != null)
                                {
                                    propertyEditor.ContainerWidget.Updated += (delta) => {
                                        propertyEditor.ContainerWidget.Visible = !showCondition.Check(param.Objects[0]);
                                    };
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }