private void folderView_DragDrop(object sender, DragEventArgs e) { this.folderView.BeginUpdate(); bool effectMove = (e.Effect & DragDropEffects.Move) != DragDropEffects.None; bool effectCopy = (e.Effect & DragDropEffects.Copy) != DragDropEffects.None; NodeBase baseTarget = this.DragDropGetTargetBaseNode(); ResourceNode targetResNode = baseTarget as ResourceNode; DirectoryNode targetDirNode = baseTarget as DirectoryNode; this.tempDropBasePath = this.GetInsertActionTargetBasePath(baseTarget); DataObject data = e.Data as DataObject; ConvertOperation.Operation convOp = data.GetAllowedConvertOp(); if (data != null) { // Dropping files if (data.ContainsFileDropList()) { IEnumerable<string> incomingFiles = data.GetFileDropList().OfType<string>(); // Handle file import operations and filter out files that have been handled that way. incomingFiles = this.HandleFileImport(this.tempDropBasePath, incomingFiles); // Filter out non-Resource files that might have been dropped accidentally into the data directory incomingFiles = incomingFiles.Where(path => Resource.IsResourceFile(path) || Directory.Exists(path)); // If there's anything left, proceed with a regular file drop operation if (incomingFiles.Any()) { this.tempFileDropList = incomingFiles.ToList(); // Display context menu if both moving and copying are availabled if (effectMove && effectCopy) this.contextMenuDragMoveCopy.Show(this, this.PointToClient(new Point(e.X, e.Y))); else if (effectCopy) this.copyHereToolStripMenuItem_Click(this, null); else if (effectMove) this.moveHereToolStripMenuItem_Click(this, null); } } // Dropping GameObject to Prefab else if ( e.Effect.HasFlag(DragDropEffects.Link) && data.ContainsGameObjectRefs() && targetResNode != null && targetResNode.ResLink.Is<Duality.Resources.Prefab>() && data.GetGameObjectRefs().Length == 1) { Prefab prefab = targetResNode.ResLink.Res as Prefab; if (prefab != null) { GameObject draggedObj = data.GetGameObjectRefs()[0]; UndoRedoManager.BeginMacro(); // Prevent recursion UndoRedoManager.Do(new BreakPrefabLinkAction(draggedObj.ChildrenDeep.Where(c => c.PrefabLink != null && c.PrefabLink.Prefab == prefab))); // Inject GameObject to Prefab & Establish PrefabLink UndoRedoManager.Do(new ApplyToPrefabAction(draggedObj, prefab)); UndoRedoManager.EndMacro(UndoRedoManager.MacroDeriveName.FromLast); } } // See if we can retrieve Resources from data else if ( (baseTarget == null || !baseTarget.ReadOnly) && (effectCopy || effectMove) && (convOp.HasFlag(ConvertOperation.Operation.CreateRes) || convOp.HasFlag(ConvertOperation.Operation.CreateObj))) { var resQuery = new ConvertOperation(data, ConvertOperation.Operation.All).Perform<IContentRef>(); if (resQuery != null) { // Save or move generated Resources List<Resource> resList = resQuery.Res().ToList(); this.folderView.ClearSelection(); foreach (Resource res in resList) { string desiredName = null; if (string.IsNullOrEmpty(desiredName)) desiredName = res.Name; if (string.IsNullOrEmpty(desiredName) && res.AssetInfo != null) desiredName = res.AssetInfo.NameHint; if (string.IsNullOrEmpty(desiredName)) desiredName = res.GetType().Name; bool pointsToFile = !res.IsDefaultContent && !res.IsRuntimeResource; string basePath = this.GetInsertActionTargetBasePath(targetDirNode); string nameExt = Resource.GetFileExtByType(res.GetType()); string resPath = Path.Combine(basePath, desiredName) + nameExt; if (!pointsToFile || Path.GetFullPath(resPath) != Path.GetFullPath(res.Path)) resPath = PathHelper.GetFreePath(Path.Combine(basePath, desiredName), nameExt); resPath = PathHelper.MakeFilePathRelative(resPath); if (pointsToFile && File.Exists(res.Path)) File.Move(res.Path, resPath); else res.Save(resPath); this.ScheduleSelect(resPath); } // If we happened to generate a Prefab, link possible existing GameObjects to it if (resList.OfType<Prefab>().Any()) { UndoRedoManager.Do(new ApplyToPrefabAction(data.GetGameObjectRefs(), resList.OfType<Prefab>().Ref())); } } } } this.folderView.EndUpdate(); }