示例#1
0
            private bool IsTileOnPageLeft(MetroStartPage targetPage, FrameworkElement tile)
            {
                var   target   = targetPage.MainContent != null ? targetPage.MainContent : targetPage;
                Point tileLeft = tile.TransformToAncestor(target).Transform(new Point(0, 0));

                return(tileLeft.X <= tile.Margin.Left);
            }
示例#2
0
            private bool IsTileOnPageRight(MetroStartPage targetPage, FrameworkElement tile)
            {
                var   target    = targetPage.MainContent != null ? targetPage.MainContent : targetPage;
                Point tileRight = tile.TransformToAncestor(target).Transform(new Point(tile.Width, tile.Height));

                return(tileRight.X >= target.ActualWidth - tile.Margin.Left);
            }
示例#3
0
            private bool IsTileOnPageBottom(MetroStartPage targetPage, FrameworkElement tile)
            {
                var   target     = targetPage.MainContent != null ? targetPage.MainContent : targetPage;
                Point tileBottom = tile.TransformToAncestor(target).Transform(new Point(tile.Width, tile.Height));

                return(tileBottom.Y >= target.ActualHeight - tile.Margin.Bottom);
            }
示例#4
0
        private void CleanUpAfterDrag()
        {
            var window = Window.GetWindow(_MetroControl);

            window.ClearValue(Window.AllowDropProperty);
            window.DragEnter    -= HandleDrag;
            window.DragOver     -= HandleDrag;
            window.DragLeave    -= HandleDrag;
            window.Drop         -= HandleDrop;
            window.GiveFeedback -= HandleGiveFeedback;

            VisualStateManager.GoToState(_DragTile, "IsNotDragSource", true);

            if (_DragAdorner != null)
            {
                _DragAdorner.Detach();
            }
            if (_ScrollHelper != null)
            {
                _ScrollHelper.Stop();
            }

            _DragAdorner    = null;
            _DragSourcePage = null;
            _DragTile       = null;
            _DragData       = null;
            _TileDropHelper = null;
            _ScrollHelper   = null;
            _NewPageHelper  = null;
        }
示例#5
0
 private void ClearSpreadPageStates()
 {
     if (_SpreadPageLeft != null)
     {
         VisualStateManager.GoToState(_SpreadPageLeft, "NoSpread", true);
         _SpreadPageLeft = null;
     }
     if (_SpreadPageRight != null)
     {
         VisualStateManager.GoToState(_SpreadPageRight, "NoSpread", true);
         _SpreadPageRight = null;
     }
 }
示例#6
0
            public bool UpdateView(Point hitPoint, bool clear)
            {
                if (clear)
                {
                    Clear();
                    return(false);
                }

                Point testPoint = _DragHelper.TranslateHitPoint(hitPoint, _DragHelper._MetroControlPanel);

                _DropPage = _DragHelper._MetroControlPanel.HitTestForOne <MetroStartPage>(testPoint);
                if (_DropPage == null)
                {
                    Clear();
                    return(false);
                }

                SetDropTargetTiles(_DragHelper.TranslateHitPoint(hitPoint, _DropPage), _DropPage);

                return(true);
            }
示例#7
0
 private Dock GetHitSide(MetroStartPage targetPage, MetroTile hitTile, MetroTile dragTile, Point pos)
 {
     // For vertically oriented pages, if dragging a small tile and the hit tile is also small,
     // treat as if horizontal oriented.
     if (targetPage.Orientation == Orientation.Vertical && !(hitTile.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Small))
     {
         double dY = (hitTile.RenderSize.Height / 2) - pos.Y;
         if (dY > 0)
         {
             return(Dock.Top);
         }
         return(Dock.Bottom);
     }
     else
     {
         double dX = (hitTile.RenderSize.Width / 2) - pos.X;
         if (dX > 0)
         {
             return(Dock.Left);
         }
         return(Dock.Right);
     }
 }
示例#8
0
        private void PrepareForDrag()
        {
            var window = Window.GetWindow(_MetroControl);

            window.AllowDrop     = true;
            window.DragEnter    += HandleDrag;
            window.DragOver     += HandleDrag;
            window.DragLeave    += HandleDrag;
            window.Drop         += HandleDrop;
            window.GiveFeedback += HandleGiveFeedback;

            if (_MetroControlPanel == null)
            {
                _MetroControlPanel = _MetroControl.GetItemsHost();
            }

            VisualStateManager.GoToState(_DragTile, "IsDragSource", true);
            _DragSourcePage = _DragTile.GetVisualParent <MetroStartPage>();
            _DragData       = _DragSourcePage != null?_DragSourcePage.ItemContainerGenerator.ItemFromContainer(_DragTile) : null;

            var adornerTemplate = (DataTemplate)_MetroControl.FindResource(MetroControl.DragAdornerDataTemplateKey);

            _DragAdorner = new TemplatedDragDropAdorner(_MetroControl, adornerTemplate, _DragData);

            _AdornerOffset = _MetroControl.TranslatePoint(_MouseDownPosition, _DragTile);

            _CenterOffset = new Point();
            _CenterOffset.Offset((_DragTile.RenderSize.Width / 2) - _AdornerOffset.X, (_DragTile.RenderSize.Height / 2) - _AdornerOffset.Y);

            _TileDropHelper = new TileDropHelper(this);
            _ScrollHelper   = new AutoScrollHelper(this);
            if (CanCreateNewPages())
            {
                _NewPageHelper = new DragTileIntoNewPageHelper(this);
            }
        }
示例#9
0
            private bool DoDrop()
            {
                if (_SpreadPageLeft == null && _SpreadPageRight == null)
                {
                    return(false);
                }

                // Can't rely on Parent Items.Count...
                int index = -1;

                if (_SpreadPageRight != null)
                {
                    index = _DragHelper._MetroControl.ItemContainerGenerator.IndexFromContainer(_SpreadPageRight);
                }

                object newPageItem = null;

                if (_DragHelper._MetroControl.ItemsSource == null)
                {
                    newPageItem = new MetroStartPage();
                    if (index >= 0)
                    {
                        _DragHelper._MetroControl.Items.Insert(index, newPageItem);
                    }
                    else
                    {
                        _DragHelper._MetroControl.Items.Add(newPageItem);
                    }
                }
                else
                {
                    // Can't insert into Items when ItemsSource is in use. Made check when setting up
                    // MetroControl as drop target to ensure that the data type used for ItemsSource
                    // has a default constructor.
                    var     pageDataType = _DragHelper._MetroControl.ItemContainerGenerator.ItemFromContainer(_DragHelper._DragSourcePage).GetType();
                    var     constructor  = pageDataType.GetConstructor(System.Type.EmptyTypes);
                    dynamic page         = constructor.Invoke(null);
                    // Also made check that ItemsSource is a list, but it might be generic and might not be generic,
                    // so use dynamic here so it won't matter when making call to insert.
                    dynamic list = _DragHelper._MetroControl.ItemsSource;
                    if (index >= 0)
                    {
                        list.Insert(index, page);
                    }
                    else
                    {
                        list.Add(page);
                    }

                    newPageItem = page;
                }

                _DragHelper._DragSourcePage.RemoveItem(_DragHelper._DragData);

                // Dispatch method call to add tile data to new page, so the new page has time to be created.
                _DragHelper._MetroControl.Dispatcher.BeginInvoke(
                    new Action <MetroControl, object, object, int>(AddDraggedDataToNewPageDispatcherCallback),
                    DispatcherPriority.ApplicationIdle,
                    _DragHelper._MetroControl, newPageItem, _DragHelper._DragData, 0);

                return(true);
            }
示例#10
0
            private bool SpreadPages(Point hitPoint)
            {
                MetroStartPage pageLeft = null, pageRight = null;
                bool           doSearch = true;

                var testPoint = _DragHelper.TranslateHitPoint(hitPoint, _DragHelper._MetroControlPanel);

                if (testPoint.Y < 0 || testPoint.Y > _DragHelper._MetroControlPanel.ActualHeight)
                {
                    doSearch = false;
                }

                var hitPage = _DragHelper._MetroControlPanel.HitTestForOne <MetroStartPage>(testPoint);

                if (hitPage != null)
                {
                    if (hitPage.MainContent != null)
                    {
                        var contentPos = _DragHelper.TranslateHitPoint(hitPoint, hitPage.MainContent);
                        if (contentPos.X < 0)
                        {
                            pageRight = hitPage;
                        }
                        else if (contentPos.X > hitPage.MainContent.ActualWidth)
                        {
                            pageLeft = hitPage;
                        }
                    }
                }

                if (doSearch)
                {
                    int leftIndex = 0;
                    if (pageLeft != null)
                    {
                        leftIndex = _DragHelper._MetroControl.ItemContainerGenerator.IndexFromContainer(pageLeft) + 1;
                    }
                    int rightIndex = _DragHelper._MetroControl.Items.Count;
                    if (pageRight != null)
                    {
                        rightIndex = _DragHelper._MetroControl.ItemContainerGenerator.IndexFromContainer(pageRight);
                    }

                    for (int i = leftIndex; i < rightIndex; i++)
                    {
                        var page = _DragHelper._MetroControlPanel.Children[i] as MetroStartPage;

                        // Pages are separated by margins on grids defined in their templates. The
                        // grids don't have background set so drag events make it through. Here we're
                        // getting the visible portion of the page against which to test mouse position.
                        var visible = page.MainContent;
                        if (visible == null)
                        {
                            visible = page;
                        }

                        var hitPos = _DragHelper.TranslateHitPoint(hitPoint, visible);
                        if (visible.IsPointWithin(hitPos))
                        {
                            pageLeft = pageRight = null;
                            break;
                        }
                        else if (hitPos.X < 0)
                        {
                            pageRight = page;
                            break;
                        }
                        else if (hitPos.X > visible.ActualWidth)
                        {
                            pageLeft = page;
                        }
                    }

                    if (_DragHelper._DragSourcePage.Items.Count == 1 && (pageLeft == _DragHelper._DragSourcePage || pageRight == _DragHelper._DragSourcePage))
                    {
                        pageRight = pageLeft = null;
                    }
                }

                if (pageLeft != _SpreadPageLeft)
                {
                    if (_SpreadPageLeft != null)
                    {
                        VisualStateManager.GoToState(_SpreadPageLeft, "NoSpread", true);
                    }
                    if (pageLeft != null)
                    {
                        VisualStateManager.GoToState(pageLeft, "SpreadLeft", true);
                    }
                    _SpreadPageLeft = pageLeft;
                }

                if (pageRight != _SpreadPageRight)
                {
                    if (_SpreadPageRight != null)
                    {
                        VisualStateManager.GoToState(_SpreadPageRight, "NoSpread", true);
                    }
                    if (pageRight != null)
                    {
                        VisualStateManager.GoToState(pageRight, "SpreadRight", true);
                    }
                    _SpreadPageRight = pageRight;
                }

                return(pageLeft != null || pageRight != null);
            }
示例#11
0
            private MetroTile FindSecondaryTargetTile(MetroStartPage targetPage, MetroTile targetTile, MetroTile dragTile, Dock hitSide, out int dropIndex)
            {
                int targetIndex = targetPage.ItemContainerGenerator.IndexFromContainer(targetTile);

                dropIndex = targetIndex;

                if (targetTile == _DragHelper._DragTile)
                {
                    return(null);
                }

                int sourceIndex = targetPage.ItemContainerGenerator.IndexFromContainer(dragTile);

                if (sourceIndex < 0)
                {
                    sourceIndex = int.MaxValue;
                }
                int secondaryIndex = -1;

                if (hitSide == Dock.Top)
                {
                    if (!IsTileOnPageTop(targetPage, targetTile))
                    {
                        secondaryIndex = targetIndex - 1;
                    }
                    if (sourceIndex < targetIndex)
                    {
                        dropIndex--;
                    }
                }
                else if (hitSide == Dock.Bottom)
                {
                    if (!IsTileOnPageBottom(targetPage, targetTile))
                    {
                        secondaryIndex = targetIndex + 1;
                    }
                    if (sourceIndex > targetIndex)
                    {
                        dropIndex++;
                    }
                }
                else if (hitSide == Dock.Left)
                {
                    if (!IsTileOnPageLeft(targetPage, targetTile))
                    {
                        secondaryIndex = targetIndex - 1;
                    }
                    if (sourceIndex < targetIndex)
                    {
                        dropIndex--;
                    }
                }
                else if (hitSide == Dock.Right)
                {
                    if (!IsTileOnPageRight(targetPage, targetTile))
                    {
                        secondaryIndex = targetIndex + 1;
                    }
                    if (sourceIndex > targetIndex)
                    {
                        dropIndex++;
                    }
                }

                MetroTile secondary = null;

                if (secondaryIndex >= 0 && secondaryIndex < targetPage.Items.Count)
                {
                    secondary = targetPage.ItemContainerGenerator.ContainerFromIndex(secondaryIndex) as MetroTile;
                    // special case handling for when dropping small tile into empty space beside another small tile,
                    // in this situation there should be no secondary.
                    if (secondary != null && secondary.Type != MetroTileType.Small && secondary != dragTile && targetTile.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Small)
                    {
                        secondary = null;
                    }
                }

                return(secondary);
            }
示例#12
0
            private void SetDropTargetTiles(Point position, MetroStartPage dropTargetPage)
            {
                var       dragTile = _DragHelper._DragTile;
                bool      suppressAnimation = false;
                MetroTile secondaryTarget = null, target2 = null, secondaryTarget2 = null;
                var       target = dropTargetPage.HitTestForOne <MetroTile>(position, _DragHelper._DragTile.Margin);

                if (target == null && dragTile.Type == MetroTileType.Small)
                {
                    target = dropTargetPage.HitTestForOne <MetroTile>(position, new Thickness(0, 0, dragTile.Width, 0));
                    if (target != null && target.Type == MetroTileType.Large)
                    {
                        target = null;
                    }
                    suppressAnimation = true;
                }

                Dock hitSide = Dock.Left;

                if (target != null)
                {
                    hitSide = GetHitSide(dropTargetPage, target, dragTile, dropTargetPage.TranslatePoint(position, target));

                    // If vertical orientation, and hitting a small tile, there might be another small tile beside it which also needs to be animated.
                    if (_DropPage.Orientation == Orientation.Vertical && target.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Large)
                    {
                        int index, adjacentIndex;
                        target2 = FindAdjacentSmallTile(target, out index, out adjacentIndex);
                        if (target2 != null)
                        {
                            // Might need to switch target and target2 because target defines the insertion index.
                            if ((hitSide == Dock.Top && adjacentIndex < index) || (hitSide == Dock.Bottom && adjacentIndex > index))
                            {
                                var temp = target;
                                target  = target2;
                                target2 = temp;
                            }
                        }
                    }

                    // Look for secondary drop target if not dropping onto self or not dropping one small tile onto another small tile.
                    secondaryTarget = FindSecondaryTargetTile(dropTargetPage, target, dragTile, hitSide, out _DropIndex);

                    if (secondaryTarget != null && _DropPage.Orientation == Orientation.Vertical && secondaryTarget.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Large)
                    {
                        int index, adjacentIndex;
                        secondaryTarget2 = FindAdjacentSmallTile(secondaryTarget, out index, out adjacentIndex);
                    }
                }
                else
                {
                    _DropIndex = _DropPage.Items.Count;
                    if (_DragHelper._DragSourcePage == _DropPage)
                    {
                        _DropIndex--;
                    }
                }

                if (!suppressAnimation)
                {
                    UpdateDropTargetTiles(target, target2, secondaryTarget, secondaryTarget2, hitSide);
                }
                else
                {
                    UpdateDropTargetTiles(null, null, null, null, Dock.Left);
                }
            }