Manage a docking dragging operation.
Inheritance: DragManager, IFloatingMessages, IMessageFilter
Ejemplo n.º 1
0
        /// <summary>
        /// Generate an implementation of the IDragPageNotify class that will be used to handle the drag/drop operation.
        /// </summary>
        /// <param name="screenPoint">Screen point of the mouse for the drag operation.</param>
        /// <param name="elementOffset">Offset from top left of element causing the drag.</param>
        /// <param name="c">Control that started the drag operation.</param>
        /// <param name="pages">Set of pages requested to be dragged.</param>
        public virtual void DoDragDrop(Point screenPoint, Point elementOffset, Control c, KryptonPageCollection pages)
        {
            // Cannot drag a null reference
            if (pages == null)
                throw new ArgumentNullException("pages");

            // Cannot drag an empty collection
            if (pages.Count == 0)
                throw new ArgumentOutOfRangeException("pages", "collection cannot be empry");

            // Create docking specific drag manager for moving the pages around
            DockingDragManager dragManager = new DockingDragManager(this, c);
            dragManager.FloatingWindowOffset = elementOffset;

            bool atLeastOneFloating = false;
            KryptonPage firstFloatingPage = null;
            foreach (KryptonPage page in pages)
            {
                // You cannot drag a store page
                if (!(page is KryptonStorePage))
                {
                    // Cannot drag a null page reference
                    if (page == null)
                        throw new ArgumentNullException("pages collection contains a null page reference");

                    // Remember the first page that is allowed to be made floating
                    if (!atLeastOneFloating && page.AreFlagsSet(KryptonPageFlags.DockingAllowFloating))
                    {
                        // Use event to indicate the page is becoming floating and allow it to be cancelled
                        CancelUniqueNameEventArgs args = new CancelUniqueNameEventArgs(page.UniqueName, false);
                        OnPageFloatingRequest(args);

                        if (!args.Cancel)
                        {
                            firstFloatingPage = page;
                            atLeastOneFloating = true;
                        }
                    }
                }
            }

            // If we have at least one page that is allowed to be floating
            if (atLeastOneFloating)
            {
                // Can we find an existing floating store page...
                KryptonDockingFloatspace floatspace = FindStorePageElement(DockingLocation.Floating, firstFloatingPage) as KryptonDockingFloatspace;
                if (floatspace != null)
                {
                    KryptonDockingFloatingWindow floatingWindow = floatspace.GetParentType(typeof(KryptonDockingFloatingWindow)) as KryptonDockingFloatingWindow;
                    if (floatingWindow != null)
                    {
                        // If the floating window is not currently visible...
                        if (!floatingWindow.FloatingWindow.Visible)
                        {
                            using (DockingMultiUpdate update = new DockingMultiUpdate(this))
                            {
                                //...then we can use it for dragging. We want the floating window to become visible and show just the set of pages
                                // that are allowed to be floating from the set of pages passed into this function. As the window is not currently
                                // visible it means all the contained pages are hidden and so we can make only the pages we are interested in visible
                                // and it will have the appearance we need.
                                dragManager.FloatingWindow = floatingWindow.FloatingWindow;

                                // Convert the existing page loaction, if any, to store and restore it in this floating window
                                KryptonPage[] firstFloatingPages = new KryptonPage[] { firstFloatingPage };
                                PropogateAction(DockingPropogateAction.StorePages, firstFloatingPages);
                                floatingWindow.PropogateAction(DockingPropogateAction.RestorePages, firstFloatingPages);

                                // Make a list of all pages that should be appended to the floating window
                                List<string> appendUniqueNames = new List<string>();
                                List<KryptonPage> appendPages = new List<KryptonPage>();
                                foreach (KryptonPage page in pages)
                                    if (!(page is KryptonStorePage) && (page != firstFloatingPage) && page.AreFlagsSet(KryptonPageFlags.DockingAllowFloating))
                                    {
                                        appendUniqueNames.Add(page.UniqueName);
                                        appendPages.Add(page);
                                    }

                                // Set the window location before it is shown otherwise we see a brief flash as it appears at the
                                // existing location and then it moves to the correct location based on the screen mouse position
                                dragManager.FloatingWindow.Location = new Point(screenPoint.X - elementOffset.X, screenPoint.Y - elementOffset.Y);

                                // Convert the append pages to store pages and then append to the same cell as the just restore page above
                                PropogateAction(DockingPropogateAction.StorePages, appendUniqueNames.ToArray());
                                KryptonWorkspaceCell cell = floatingWindow.CellForPage(firstFloatingPage.UniqueName);
                                cell.Pages.AddRange(appendPages.ToArray());
                            }
                        }
                    }
                }

                // Do we need to create a new floating window?
                if (dragManager.FloatingWindow == null)
                {
                    // Get access to a floating element that allows a new floating window to be created
                    KryptonDockingFloating floating = FindDockingFloating(firstFloatingPage.UniqueName);
                    if (floating != null)
                    {
                        KryptonDockingFloatingWindow floatingWindow = floating.AddFloatingWindow();
                        if (floatingWindow != null)
                        {
                            using (DockingMultiUpdate update = new DockingMultiUpdate(this))
                            {
                                // This is the window that will be moved during the drag operation
                                dragManager.FloatingWindow = floatingWindow.FloatingWindow;

                                // Make a list of all pages that should be appended to the floating window
                                List<string> appendUniqueNames = new List<string>();
                                List<KryptonPage> appendPages = new List<KryptonPage>();
                                foreach (KryptonPage page in pages)
                                    if (!(page is KryptonStorePage) && page.AreFlagsSet(KryptonPageFlags.DockingAllowFloating))
                                    {
                                        appendUniqueNames.Add(page.UniqueName);
                                        appendPages.Add(page);
                                    }

                                // Set the window location before it is shown otherwise we see a brief flash as it appears at the
                                // existing location and then it moves to the correct location based on the screen mouse position
                                dragManager.FloatingWindow.Location = new Point(screenPoint.X - elementOffset.X, screenPoint.Y - elementOffset.Y);

                                // Append the pages inside the new window, storing the current locations for later use
                                PropogateAction(DockingPropogateAction.StorePages, appendUniqueNames.ToArray());
                                floatingWindow.FloatspaceElement.Append(appendPages.ToArray());
                                floatingWindow.FloatingWindow.Show();
                            }
                        }
                    }
                }
            }

            // Alow workspace controls to compact and update based on changes from above
            Application.DoEvents();

            // Add ourself as a source of drag targets and then begin the dragging process
            dragManager.DragTargetProviders.Add(new DockingDragTargetProvider(this, dragManager.FloatingWindow, pages));
            dragManager.DragStart(screenPoint, new PageDragEndData(this, pages));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generate an implementation of the IDragPageNotify class that will be used to handle the drag/drop operation.
        /// </summary>
        /// <param name="screenPoint">Screen point of the mouse for the drag operation.</param>
        /// <param name="elementOffset">Offset from top left of element causing the drag.</param>
        /// <param name="c">Control that started the drag operation.</param>
        /// <param name="window">Reference to floating window element that should be dragged.</param>
        public virtual void DoDragDrop(Point screenPoint, Point elementOffset, Control c, KryptonDockingFloatingWindow window)
        {
            // Cannot drag a null reference
            if (window == null)
                throw new ArgumentNullException("window");

            // Create a list of all the visible pages inside the floating window
            KryptonPageCollection pages = new KryptonPageCollection();
            KryptonWorkspaceCell cell = window.FloatspaceElement.FloatspaceControl.FirstVisibleCell();
            while (cell != null)
            {
                foreach (KryptonPage page in cell.Pages)
                    if (!(page is KryptonStorePage) && page.LastVisibleSet)
                        pages.Add(page);

                cell = window.FloatspaceElement.FloatspaceControl.NextVisibleCell(cell);
            }

            // If it actually has any visible contents to be moved
            if (pages.Count > 0)
            {
                // Create docking specific drag manager for moving the pages around
                DockingDragManager dragManager = new DockingDragManager(this, null);
                dragManager.FloatingWindow = window.FloatingWindow;
                dragManager.FloatingWindowOffset = elementOffset;

                // Set the window location before it is shown otherwise we see a brief flash as it appears at the
                // existing location and then it moves to the correct location based on the screen mouse position
                dragManager.FloatingWindow.Location = new Point(screenPoint.X - elementOffset.X, screenPoint.Y - elementOffset.Y);

                // Add ourself as a source of drag targets and then begin the dragging process
                dragManager.DragTargetProviders.Add(new DockingDragTargetProvider(this, dragManager.FloatingWindow, pages));
                dragManager.DragStart(screenPoint, new PageDragEndData(this, pages));
            }
        }