public static void Perform(Node container, FolderItemLocation location, IFolderItem item) { if (item is Node && !NodeCompositionValidator.Validate(container.GetType(), item.GetType())) { throw new InvalidOperationException($"Can't put {item.GetType()} into {container.GetType()}"); } DocumentHistory.Current.Perform(new InsertFolderItem(container, location, item)); }
private void CreateContextMenu(List <string> files) { var menu = new Menu(); foreach (var imageType in imageTypes) { if (NodeCompositionValidator.Validate(Document.Current.Container.GetType(), imageType)) { menu.Add(new Command($"Create {imageType.Name}", () => CreateImageTypeInstance(imageType, files))); } } menu.Add(new Command("Create sprite animated Image", () => CreateSpriteAnimatedImage(files))); menu.Popup(); }
private static void Validate(Node source, Type destType, Type commonParent) { foreach (var child in source.Nodes) { if (!NodeCompositionValidator.Validate(destType, child.GetType())) { throw new InvalidOperationException( $"Node {source} has child {child} that will be incompatible with {destType}" ); } } foreach (var component in source.Components) { if (!NodeCompositionValidator.ValidateComponentType(destType, component.GetType())) { throw new InvalidOperationException( $"Node {source} has component {component} that will be incompatible with {destType}" ); } } if (!(source.GetType().IsSubclassOf(commonParent) && destType.IsSubclassOf(commonParent))) { throw new InvalidOperationException( $"Node {source} type or/and destination {destType} type are not subclasses of {commonParent}" ); } foreach (var animator in source.Animators) { var prop = destType.GetProperty(animator.TargetPropertyPath); if ( prop == null || prop.PropertyType != source.GetType().GetProperty(animator.TargetPropertyPath).PropertyType ) { throw new InvalidOperationException( $"Node {source} has animator on property {animator.TargetPropertyPath}, which doesn't exist in {destType}" ); } } }
private void Handle(IEnumerable <string> files) { Handling?.Invoke(); using (Document.Current.History.BeginTransaction()) { pendingImages = new List <string>(); foreach (var file in files) { try { string assetPath, assetType; if (!Utils.ExtractAssetPathOrShowAlert(file, out assetPath, out assetType) || !Utils.AssertCurrentDocument(assetPath, assetType)) { continue; } var nodeCreatingEventArgs = new NodeCreatingEventArgs(assetPath, assetType); NodeCreating?.Invoke(nodeCreatingEventArgs); if (nodeCreatingEventArgs.Cancel) { continue; } var fileName = Path.GetFileNameWithoutExtension(assetPath); switch (assetType) { case ".png": pendingImages.Add(assetPath); break; case ".ogg": { var node = CreateNode.Perform(typeof(Audio)); var sample = new SerializableSample(assetPath); SetProperty.Perform(node, nameof(Audio.Sample), sample); SetProperty.Perform(node, nameof(Node.Id), fileName); SetProperty.Perform(node, nameof(Audio.Volume), 1); var key = new Keyframe <AudioAction> { Frame = Document.Current.AnimationFrame, Value = AudioAction.Play }; SetKeyframe.Perform(node, nameof(Audio.Action), Document.Current.AnimationId, key); OnNodeCreated(node); break; } case ".tan": case ".model": case ".scene": DropSceneContextMenu.Create(assetPath, assetType, NodeCreated); break; } } catch (System.Exception e) { AlertDialog.Show(e.Message); } } if (pendingImages.Count > 0) { var menu = new Menu(); foreach (var kv in imageDropCommands.Commands) { if (NodeCompositionValidator.Validate(Document.Current.Container.GetType(), kv.Value)) { menu.Add(kv.Key); } } menu.Popup(); } Document.Current.History.CommitTransaction(); } }