Esempio n. 1
0
        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();
        }