예제 #1
0
        HitTestFilterBehavior HitTestFilter(DependencyObject potentialHit)
        {
            if (this.tabHitTesting)
            {
                TabItem item = potentialHit as TabItem;

                if (item != null && item.Visibility == Visibility.Visible && item.DataContext is LayoutDefinition)
                {
                    this.hitTestTabItem = item;
                    return(HitTestFilterBehavior.Stop);
                }

                return(HitTestFilterBehavior.Continue);
            }
            else
            {
                ViewDockSpot spot = potentialHit as ViewDockSpot;

                if (spot != null && spot.IsHitTestVisible)
                {
                    this.hitTestSpot = spot;
                    return(HitTestFilterBehavior.Stop);
                }

                return(HitTestFilterBehavior.Continue);
            }
        }
        HitTestFilterBehavior HitTestFilter(DependencyObject potentialHit)
        {
            if (this.tabHitTesting)
            {
                TabItem item = potentialHit as TabItem;

                if (item != null && item.Visibility == Visibility.Visible && item.DataContext is LayoutDefinition)
                {
                    this.hitTestTabItem = item;
                    return HitTestFilterBehavior.Stop;
                }

                return HitTestFilterBehavior.Continue;
            }
            else
            {
                ViewDockSpot spot = potentialHit as ViewDockSpot;

                if (spot != null && spot.IsHitTestVisible)
                {
                    this.hitTestSpot = spot;
                    return HitTestFilterBehavior.Stop;
                }

                return HitTestFilterBehavior.Continue;
            }
        }
        void UpdateHitState(Point pos)
        {
            LayoutControl targetLayout = this.CurrentLayout;
            bool ghostPositionSet = false;

            this.dockTargetSlot = null;
            this.dragGhostWindow.CancelReason = "To place the view, drag over an empty layout, an existing view, or a docking target.";

            if (targetLayout != null)
            {
                var posInLayout = Mouse.GetPosition(targetLayout);
                var rect = new Rect(0, 0, targetLayout.ActualWidth, targetLayout.ActualHeight);

                if (rect.Contains(posInLayout))
                {
                    this.dockTargetSlot = targetLayout.GetSlotUnderPoint(Mouse.GetPosition(targetLayout));
                }
                else
                {
                    targetLayout = null;
                }

                if (this.dockTargetSlot != null)
                {
                    if (this.creatorBeingDragged != null)
                    {
                        if (this.creatorBeingDragged.Category.DocumentFactoryName != null &&
                            targetLayout.LayoutInstance.LayoutDefinition.DocumentFactoryName != this.creatorBeingDragged.Category.DocumentFactoryName)
                        {
                            // The creator being dragged is affinitized with a particular document type which is not the same type as the active
                            // layout.  Disallow the drop.
                            this.dockTargetSlot = null;
                            this.dragGhostWindow.CancelReason = string.Format(CultureInfo.InvariantCulture, "This view can only be placed in a {0} layout.", this.creatorBeingDragged.Category.DisplayName);
                        }
                        else if (this.creatorBeingDragged.Command.IsSingleInstancePerLayout &&
                            (targetLayout.LayoutInstance.LayoutDefinition.ViewSources.Any(vs => vs.ViewCreator == this.creatorBeingDragged.Command)))
                        {
                            // This is a single-instance-per-layout view that already exists in the layout.  No dice.
                            this.dockTargetSlot = null;
                            this.dragGhostWindow.CancelReason = "Only one instance of this view type can exist in a layout.";
                        }
                        else if (this.creatorBeingDragged.Command.IsSingleInstance)
                        {
                            var existingSource = ToolsUIApplication.Instance.LayoutDefinitions.SelectMany(d => d.ViewSources).Where(vs => vs.ViewCreator == this.creatorBeingDragged.Command).FirstOrDefault();

                            if (existingSource != null)
                            {
                                // This is a single-instance view that already exists in a layout (perhaps not even this one).
                                this.dockTargetSlot = null;
                                this.dragGhostWindow.CancelReason = string.Format(CultureInfo.InvariantCulture,
                                    "This view already exists in the '{0}' layout.  Only one instance of this view type can be created.", existingSource.Parent.Header);
                            }
                        }
                    }
                }
            }

            if (this.dockTargetSlot != null)
            {
                this.layout = targetLayout;
                if (this.dockTargetWindow == null)
                {
                    this.dockTargetWindow = new ViewDropTargetWindow();
                }

                var rect = targetLayout.GetSlotScreenRect(this.dockTargetSlot);

                this.dockTargetWindow.Left = rect.X;
                this.dockTargetWindow.Top = rect.Y;
                this.dockTargetWindow.Width = rect.Width;
                this.dockTargetWindow.Height = rect.Height;
                this.dockTargetWindow.IsTabbedSpotVisible = true;
                this.dockTargetWindow.RootSlot = targetLayout.LayoutInstance.LayoutDefinition.SlotDefinition;
                this.dockTargetWindow.TargetSlot = this.dockTargetSlot;
                this.dockTargetWindow.AreDockSpotsVisible = targetLayout.LayoutInstance.LayoutDefinition.ViewSources.Count > 0;
                this.dockTargetWindow.Show();

                this.hitTestSpot = null;
                this.tabHitTesting = false;
                VisualTreeHelper.HitTest(this.dockTargetWindow, this.HitTestFilter, this.HitTestResult, new PointHitTestParameters(Mouse.GetPosition(this.dockTargetWindow)));
                if (this.hitTestSpot != null)
                {
                    var spot = this.hitTestSpot;

                    if (spot != null && spot.DestinationSlot != null)
                    {
                        rect = targetLayout.GetSlotScreenRect(spot.DestinationSlot);

                        this.dragGhostWindow.CancelMode = false;
                        this.dragGhostWindow.CancelReason = null;

                        if (spot.IsTabbed)
                        {
                            this.dragGhostWindow.Left = rect.X;
                            this.dragGhostWindow.Top = rect.Y;
                            this.dragGhostWindow.Width = rect.Width;
                            this.dragGhostWindow.Height = rect.Height;
                        }
                        else
                        {
                            switch (spot.Dock)
                            {
                                case Dock.Top:
                                    this.dragGhostWindow.Left = rect.X;
                                    this.dragGhostWindow.Top = rect.Y;
                                    this.dragGhostWindow.Width = rect.Width;
                                    this.dragGhostWindow.Height = rect.Height / 2;
                                    break;
                                case Dock.Bottom:
                                    this.dragGhostWindow.Width = rect.Width;
                                    this.dragGhostWindow.Height = rect.Height / 2;
                                    this.dragGhostWindow.Left = rect.X;
                                    this.dragGhostWindow.Top = rect.Y + this.dragGhostWindow.Height;
                                    break;
                                case Dock.Left:
                                    this.dragGhostWindow.Left = rect.X;
                                    this.dragGhostWindow.Top = rect.Y;
                                    this.dragGhostWindow.Width = rect.Width / 2;
                                    this.dragGhostWindow.Height = rect.Height;
                                    break;
                                case Dock.Right:
                                    this.dragGhostWindow.Width = rect.Width / 2;
                                    this.dragGhostWindow.Height = rect.Height;
                                    this.dragGhostWindow.Left = rect.X + this.dragGhostWindow.Width;
                                    this.dragGhostWindow.Top = rect.Y;
                                    break;
                            }
                        }

                        ghostPositionSet = true;
                    }
                }
                else
                {
                    // Didn't even hit the tabbed spot (the transparent rect covering the whole slot), so must be in
                    // the margin.  Tear down the dock target window.  (Won't flicker because it fades in...)
                    this.dockTargetWindow.Close();
                    this.dockTargetWindow = null;
                    this.dockTargetSlot = null;
                }
            }
            else
            {
                if (this.dockTargetWindow != null)
                {
                    this.dockTargetWindow.Close();
                    this.dockTargetWindow = null;
                }

                this.layout = null;

                // See if the mouse is over a layout tab.  If so, select it.
                this.tabHitTesting = true;
                this.hitTestTabItem = null;
                VisualTreeHelper.HitTest(this.tabControl, this.HitTestFilter, this.HitTestResult, new PointHitTestParameters(Mouse.GetPosition(this.tabControl)));

                if (this.hitTestTabItem != null)
                {
                    var layoutDef = this.hitTestTabItem.DataContext as LayoutDefinition;

                    if (layoutDef != null)
                    {
                        this.tabControl.SelectedItem = layoutDef;
                    }
                }
            }

            if (!ghostPositionSet)
            {
                this.dragGhostWindow.Width = 200;
                this.dragGhostWindow.Height = 200;
                this.dragGhostWindow.Left = pos.X;
                this.dragGhostWindow.Top = pos.Y;
                this.dragGhostWindow.CancelMode = true;
            }
        }
예제 #4
0
        void UpdateHitState(Point pos)
        {
            LayoutControl targetLayout     = this.CurrentLayout;
            bool          ghostPositionSet = false;

            this.dockTargetSlot = null;
            this.dragGhostWindow.CancelReason = "To place the view, drag over an empty layout, an existing view, or a docking target.";

            if (targetLayout != null)
            {
                var posInLayout = Mouse.GetPosition(targetLayout);
                var rect        = new Rect(0, 0, targetLayout.ActualWidth, targetLayout.ActualHeight);

                if (rect.Contains(posInLayout))
                {
                    this.dockTargetSlot = targetLayout.GetSlotUnderPoint(Mouse.GetPosition(targetLayout));
                }
                else
                {
                    targetLayout = null;
                }

                if (this.dockTargetSlot != null)
                {
                    if (this.creatorBeingDragged != null)
                    {
                        if (this.creatorBeingDragged.Category.DocumentFactoryName != null &&
                            targetLayout.LayoutInstance.LayoutDefinition.DocumentFactoryName != this.creatorBeingDragged.Category.DocumentFactoryName)
                        {
                            // The creator being dragged is affinitized with a particular document type which is not the same type as the active
                            // layout.  Disallow the drop.
                            this.dockTargetSlot = null;
                            this.dragGhostWindow.CancelReason = string.Format(CultureInfo.InvariantCulture, "This view can only be placed in a {0} layout.", this.creatorBeingDragged.Category.DisplayName);
                        }
                        else if (this.creatorBeingDragged.Command.IsSingleInstancePerLayout &&
                                 (targetLayout.LayoutInstance.LayoutDefinition.ViewSources.Any(vs => vs.ViewCreator == this.creatorBeingDragged.Command)))
                        {
                            // This is a single-instance-per-layout view that already exists in the layout.  No dice.
                            this.dockTargetSlot = null;
                            this.dragGhostWindow.CancelReason = "Only one instance of this view type can exist in a layout.";
                        }
                        else if (this.creatorBeingDragged.Command.IsSingleInstance)
                        {
                            var existingSource = ToolsUIApplication.Instance.LayoutDefinitions.SelectMany(d => d.ViewSources).Where(vs => vs.ViewCreator == this.creatorBeingDragged.Command).FirstOrDefault();

                            if (existingSource != null)
                            {
                                // This is a single-instance view that already exists in a layout (perhaps not even this one).
                                this.dockTargetSlot = null;
                                this.dragGhostWindow.CancelReason = string.Format(CultureInfo.InvariantCulture,
                                                                                  "This view already exists in the '{0}' layout.  Only one instance of this view type can be created.", existingSource.Parent.Header);
                            }
                        }
                    }
                }
            }

            if (this.dockTargetSlot != null)
            {
                this.layout = targetLayout;
                if (this.dockTargetWindow == null)
                {
                    this.dockTargetWindow = new ViewDropTargetWindow();
                }

                var rect = targetLayout.GetSlotScreenRect(this.dockTargetSlot);

                this.dockTargetWindow.Left   = rect.X;
                this.dockTargetWindow.Top    = rect.Y;
                this.dockTargetWindow.Width  = rect.Width;
                this.dockTargetWindow.Height = rect.Height;
                this.dockTargetWindow.IsTabbedSpotVisible = true;
                this.dockTargetWindow.RootSlot            = targetLayout.LayoutInstance.LayoutDefinition.SlotDefinition;
                this.dockTargetWindow.TargetSlot          = this.dockTargetSlot;
                this.dockTargetWindow.AreDockSpotsVisible = targetLayout.LayoutInstance.LayoutDefinition.ViewSources.Count > 0;
                this.dockTargetWindow.Show();

                this.hitTestSpot   = null;
                this.tabHitTesting = false;
                VisualTreeHelper.HitTest(this.dockTargetWindow, this.HitTestFilter, this.HitTestResult, new PointHitTestParameters(Mouse.GetPosition(this.dockTargetWindow)));
                if (this.hitTestSpot != null)
                {
                    var spot = this.hitTestSpot;

                    if (spot != null && spot.DestinationSlot != null)
                    {
                        rect = targetLayout.GetSlotScreenRect(spot.DestinationSlot);

                        this.dragGhostWindow.CancelMode   = false;
                        this.dragGhostWindow.CancelReason = null;

                        if (spot.IsTabbed)
                        {
                            this.dragGhostWindow.Left   = rect.X;
                            this.dragGhostWindow.Top    = rect.Y;
                            this.dragGhostWindow.Width  = rect.Width;
                            this.dragGhostWindow.Height = rect.Height;
                        }
                        else
                        {
                            switch (spot.Dock)
                            {
                            case Dock.Top:
                                this.dragGhostWindow.Left   = rect.X;
                                this.dragGhostWindow.Top    = rect.Y;
                                this.dragGhostWindow.Width  = rect.Width;
                                this.dragGhostWindow.Height = rect.Height / 2;
                                break;

                            case Dock.Bottom:
                                this.dragGhostWindow.Width  = rect.Width;
                                this.dragGhostWindow.Height = rect.Height / 2;
                                this.dragGhostWindow.Left   = rect.X;
                                this.dragGhostWindow.Top    = rect.Y + this.dragGhostWindow.Height;
                                break;

                            case Dock.Left:
                                this.dragGhostWindow.Left   = rect.X;
                                this.dragGhostWindow.Top    = rect.Y;
                                this.dragGhostWindow.Width  = rect.Width / 2;
                                this.dragGhostWindow.Height = rect.Height;
                                break;

                            case Dock.Right:
                                this.dragGhostWindow.Width  = rect.Width / 2;
                                this.dragGhostWindow.Height = rect.Height;
                                this.dragGhostWindow.Left   = rect.X + this.dragGhostWindow.Width;
                                this.dragGhostWindow.Top    = rect.Y;
                                break;
                            }
                        }

                        ghostPositionSet = true;
                    }
                }
                else
                {
                    // Didn't even hit the tabbed spot (the transparent rect covering the whole slot), so must be in
                    // the margin.  Tear down the dock target window.  (Won't flicker because it fades in...)
                    this.dockTargetWindow.Close();
                    this.dockTargetWindow = null;
                    this.dockTargetSlot   = null;
                }
            }
            else
            {
                if (this.dockTargetWindow != null)
                {
                    this.dockTargetWindow.Close();
                    this.dockTargetWindow = null;
                }

                this.layout = null;

                // See if the mouse is over a layout tab.  If so, select it.
                this.tabHitTesting  = true;
                this.hitTestTabItem = null;
                VisualTreeHelper.HitTest(this.tabControl, this.HitTestFilter, this.HitTestResult, new PointHitTestParameters(Mouse.GetPosition(this.tabControl)));

                if (this.hitTestTabItem != null)
                {
                    var layoutDef = this.hitTestTabItem.DataContext as LayoutDefinition;

                    if (layoutDef != null)
                    {
                        this.tabControl.SelectedItem = layoutDef;
                    }
                }
            }

            if (!ghostPositionSet)
            {
                this.dragGhostWindow.Width      = 200;
                this.dragGhostWindow.Height     = 200;
                this.dragGhostWindow.Left       = pos.X;
                this.dragGhostWindow.Top        = pos.Y;
                this.dragGhostWindow.CancelMode = true;
            }
        }