protected override bool ProbeInternal(AnimationTrackRow component, Row row, RowLocation location) { var newIndex = location.Index > row.Index ? location.Index - 1 : location.Index; var track = component.Track; RemoveFromList <AnimationTrackList, AnimationTrack> .Perform(Document.Current.Animation.Tracks, row.Index); InsertIntoList <AnimationTrackList, AnimationTrack> .Perform(Document.Current.Animation.Tracks, newIndex, track); return(true); }
public ListPropertyEditor(IPropertyEditorParams editorParams, Func <PropertyEditorParams, Widget, IList, IEnumerable <IPropertyEditor> > onAdd) : base(editorParams) { this.onAdd = onAdd; if (EditorParams.Objects.Skip(1).Any()) { // Dont create editor interface if > 1 objects are selected EditorContainer.AddNode(new Widget() { Layout = new HBoxLayout(), Nodes = { new ThemedSimpleText { Text = "Edit of list properties isnt supported for multiple selection.", ForceUncutText = false } }, // TODO: move color to theme Presenter = new WidgetFlatFillPresenter(Theme.Colors.WarningBackground) }); return; } ExpandableContent.Padding = new Thickness(left: 4.0f, right: 0.0f, top: 4.0f, bottom: 4.0f); list = (IList)EditorParams.PropertyInfo.GetValue(EditorParams.Objects.First()); var addButton = new ThemedAddButton() { Clicked = () => { Expanded = true; if (list == null) { var pi = EditorParams.PropertyInfo; var o = EditorParams.Objects.First(); pi.SetValue(o, list = new TList()); } var newElement = typeof(TElement) == typeof(string) ? (TElement)(object)string.Empty : Activator.CreateInstance <TElement>(); using (Document.Current.History.BeginTransaction()) { int newIndex = list.Count; InsertIntoList.Perform(list, newIndex, newElement); Document.Current.History.CommitTransaction(); } } }; EditorContainer.AddNode(addButton); ContainerWidget.Updating += _ => removeCallback?.Invoke(); ContainerWidget.AddChangeWatcher(() => list?.Count ?? 0, Build); }
public ListPropertyEditor(IPropertyEditorParams editorParams, Func <PropertyEditorParams, Widget, IList, IEnumerable <IPropertyEditor> > onAdd) : base(editorParams) { this.onAdd = onAdd; pendingRemoval = new List <int>(); if (EditorParams.Objects.Skip(1).Any()) { // Dont create editor interface if > 1 objects are selected EditorContainer.AddNode(new Widget() { Layout = new HBoxLayout(), Nodes = { new ThemedSimpleText { Text = "Edit of list properties isnt supported for multiple selection.", ForceUncutText = false } }, Presenter = new WidgetFlatFillPresenter(Theme.Colors.WarningBackground) }); return; } ExpandableContent.Padding = new Thickness(left: 4.0f, right: 0.0f, top: 4.0f, bottom: 4.0f); list = PropertyValue(EditorParams.Objects.First()).GetValue(); Expanded = true; EditorContainer.AddNode(new ThemedAddButton() { Clicked = () => { Expanded = true; if (list == null) { var pi = EditorParams.PropertyInfo; var o = EditorParams.Objects.First(); pi.SetValue(o, list = Activator.CreateInstance <TList>()); } var newElement = typeof(TElement) == typeof(string) ? (TElement)(object)string.Empty : typeof(TElement).IsInterface || typeof(TElement).IsAbstract ? default : Activator.CreateInstance <TElement>(); using (Document.Current.History.BeginTransaction()) { int newIndex = list.Count; InsertIntoList.Perform(list, newIndex, newElement); Document.Current.History.CommitTransaction(); } } });
private void ShowContextMenu() { SelectAnimationBasedOnMousePosition(); var menu = new Menu(); var rootNode = Document.Current.RootNode; menu.Add(new Command("Add", () => AddAnimation(rootNode, false))); menu.Add(new Command("Add Compound", () => AddAnimation(rootNode, true))); menu.Add(new Command("Add ZeroPose", () => AddZeroPoseAnimation(rootNode)) { Enabled = !rootNode.Animations.TryFind(Animation.ZeroPoseId, out _) }); var path = GetNodePath(Document.Current.Container); if (!string.IsNullOrEmpty(path)) { var container = Document.Current.Container; menu.Add(new Command($"Add To '{path}'", () => AddAnimation(container, false))); menu.Add(new Command($"Add Compound To '{path}'", () => AddAnimation(container, true))); menu.Add(new Command($"Add ZeroPose To '{path}'", () => AddZeroPoseAnimation(container)) { Enabled = !container.Animations.TryFind(Animation.ZeroPoseId, out _) }); } menu.Add(Command.MenuSeparator); menu.Add(new Command("Rename", RenameAnimation)); menu.Add(new Command("Duplicate", DuplicateAnimation)); menu.Add(Command.Delete); menu.Popup(); void AddAnimation(Node node, bool compound) { Document.Current.History.DoTransaction(() => { var animation = new Animation { Id = GenerateAnimationId("NewAnimation"), IsCompound = compound }; Core.Operations.InsertIntoList.Perform(node.Animations, node.Animations.Count, animation); SelectAnimation(GetAnimations().IndexOf(animation)); if (compound) { var track = new AnimationTrack { Id = "Track1" }; Core.Operations.InsertIntoList <AnimationTrackList, AnimationTrack> .Perform(animation.Tracks, 0, track); } }); // Schedule animation rename on the next update, since the widgets are not built yet panelWidget.Tasks.Add(DelayedRenameAnimation()); } void AddZeroPoseAnimation(Node node) { Document.Current.History.DoTransaction(() => { var animation = new Animation { Id = Animation.ZeroPoseId }; InsertIntoList.Perform(node.Animations, node.Animations.Count, animation); foreach (var a in node.Descendants.SelectMany(n => n.Animators).ToList()) { var(propertyData, animable, index) = AnimationUtils.GetPropertyByPath(a.Owner, a.TargetPropertyPath); var zeroPoseKey = Keyframe.CreateForType(propertyData.Info.PropertyType); zeroPoseKey.Value = index == -1 ? propertyData.Info.GetValue(animable) : propertyData.Info.GetValue(animable, new object[] { index }); zeroPoseKey.Function = KeyFunction.Steep; SetKeyframe.Perform(a.Owner, a.TargetPropertyPath, Animation.ZeroPoseId, zeroPoseKey); } SelectAnimation(GetAnimations().IndexOf(animation)); }); } IEnumerator <object> DelayedRenameAnimation() { yield return(null); RenameAnimation(); } }